summaryrefslogtreecommitdiffstats
path: root/src/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.h')
-rw-r--r--src/common.h113
1 files changed, 88 insertions, 25 deletions
diff --git a/src/common.h b/src/common.h
index 264fe81..0fedeae 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,9 +1,10 @@
/**
* @file common.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief common internal definitions for libyang
*
- * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -23,7 +24,7 @@
#include "compat.h"
#include "config.h"
#include "context.h"
-#include "hash_table.h"
+#include "hash_table_internal.h"
#include "log.h"
#include "schema_compile.h"
#include "set.h"
@@ -45,17 +46,28 @@ struct lysc_node;
# error "Cannot define THREAD_LOCAL"
#endif
+/** platform-specific environment variable path separator */
+#ifndef _WIN32
+# define PATH_SEPARATOR ":"
+#else
+# define PATH_SEPARATOR ";"
+#endif
+
#define GETMACRO1(_1, NAME, ...) NAME
#define GETMACRO2(_1, _2, NAME, ...) NAME
#define GETMACRO3(_1, _2, _3, NAME, ...) NAME
#define GETMACRO4(_1, _2, _3, _4, NAME, ...) NAME
#define GETMACRO5(_1, _2, _3, _4, _5, NAME, ...) NAME
#define GETMACRO6(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
+#define GETMACRO7(_1, _2, _3, _4, _5, _6, _7, NAME, ...) NAME
/******************************************************************************
* Logger
*****************************************************************************/
+/** size of the last message buffer */
+#define LY_LAST_MSG_SIZE 512
+
extern ATOMIC_T ly_ll;
extern ATOMIC_T ly_log_opts;
@@ -75,7 +87,16 @@ struct ly_log_location_s {
* @param[in] no Error type code.
* @param[in] format Format string to print.
*/
-void ly_log(const struct ly_ctx *ctx, LY_LOG_LEVEL level, LY_ERR no, const char *format, ...);
+void ly_log(const struct ly_ctx *ctx, LY_LOG_LEVEL level, LY_ERR no, const char *format, ...) _FORMAT_PRINTF(4, 5);
+
+/**
+ * @brief Generate data path based on the data and schema nodes stored in the log location.
+ *
+ * @param[in] ctx Context for logging.
+ * @param[out] path Generated data path.
+ * @return LY_ERR value.
+ */
+LY_ERR ly_vlog_build_data_path(const struct ly_ctx *ctx, char **path);
/**
* @brief Print Validation error and store it into the context (if provided).
@@ -85,7 +106,15 @@ void ly_log(const struct ly_ctx *ctx, LY_LOG_LEVEL level, LY_ERR no, const char
* @param[in] code Validation error code.
* @param[in] format Format string to print.
*/
-void ly_vlog(const struct ly_ctx *ctx, const char *apptag, LY_VECODE code, const char *format, ...);
+void ly_vlog(const struct ly_ctx *ctx, const char *apptag, LY_VECODE code, const char *format, ...) _FORMAT_PRINTF(4, 5);
+
+/**
+ * @brief Move error items from source to target context replacing any previous ones.
+ *
+ * @param[in] src_ctx Source context to read errors from.
+ * @param[in] trg_ctx Target context to set the errors for.
+ */
+void ly_err_move(struct ly_ctx *src_ctx, struct ly_ctx *trg_ctx);
/**
* @brief Logger's location data setter.
@@ -110,6 +139,21 @@ void ly_log_location(const struct lysc_node *scnode, const struct lyd_node *dnod
void ly_log_location_revert(uint32_t scnode_steps, uint32_t dnode_steps, uint32_t path_steps, uint32_t in_steps);
/**
+ * @brief Get the stored data node for logging at the index.
+ *
+ * @param[in] idx Index of the data node.
+ * @return Logged data node, NULL if out of range.
+ */
+const struct lyd_node *ly_log_location_dnode(uint32_t idx);
+
+/**
+ * @brief Get the count of stored data nodes for logging.
+ *
+ * @return Count of the data nodes.
+ */
+uint32_t ly_log_location_dnode_count(void);
+
+/**
* @brief Update location data for logger, not provided arguments (NULLs) are kept (does not override).
*
* @param[in] SCNODE Compiled schema node.
@@ -201,8 +245,10 @@ void ly_log_dbg(uint32_t group, const char *format, ...);
LY_CHECK_ARG_RET1(CTX, ARG4, RETVAL)
#define LY_CHECK_ARG_RET5(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, RETVAL) LY_CHECK_ARG_RET4(CTX, ARG1, ARG2, ARG3, ARG4, RETVAL);\
LY_CHECK_ARG_RET1(CTX, ARG5, RETVAL)
-#define LY_CHECK_ARG_RET(CTX, ...) GETMACRO6(__VA_ARGS__, LY_CHECK_ARG_RET5, LY_CHECK_ARG_RET4, LY_CHECK_ARG_RET3, \
- LY_CHECK_ARG_RET2, LY_CHECK_ARG_RET1, DUMMY) (CTX, __VA_ARGS__)
+#define LY_CHECK_ARG_RET6(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, RETVAL) LY_CHECK_ARG_RET5(CTX, ARG1, ARG2, ARG3, ARG4, ARG5, RETVAL);\
+ LY_CHECK_ARG_RET1(CTX, ARG6, RETVAL)
+#define LY_CHECK_ARG_RET(CTX, ...) GETMACRO7(__VA_ARGS__, LY_CHECK_ARG_RET6, LY_CHECK_ARG_RET5, LY_CHECK_ARG_RET4, \
+ LY_CHECK_ARG_RET3, LY_CHECK_ARG_RET2, LY_CHECK_ARG_RET1, DUMMY) (CTX, __VA_ARGS__)
#define LY_CHECK_CTX_EQUAL_RET2(CTX1, CTX2, RETVAL) if ((CTX1) && (CTX2) && ((CTX1) != (CTX2))) \
{LOGERR(CTX1, LY_EINVAL, "Different contexts mixed in a single function call."); return RETVAL;}
@@ -212,11 +258,12 @@ void ly_log_dbg(uint32_t group, const char *format, ...);
DUMMY) (CTX, __VA_ARGS__)
/* count sequence size for LY_VCODE_INCHILDSTMT validation error code */
-size_t LY_VCODE_INSTREXP_len(const char *str);
+int LY_VCODE_INSTREXP_len(const char *str);
+
/* default maximum characters to print in LY_VCODE_INCHILDSTMT */
#define LY_VCODE_INSTREXP_MAXLEN 20
-#define LY_VCODE_INCHAR LYVE_SYNTAX, "Invalid character 0x%x."
+#define LY_VCODE_INCHAR LYVE_SYNTAX, "Invalid character 0x%hhx."
#define LY_VCODE_INSTREXP LYVE_SYNTAX, "Invalid character sequence \"%.*s\", expected %s."
#define LY_VCODE_EOF LYVE_SYNTAX, "Unexpected end-of-input."
#define LY_VCODE_NTERM LYVE_SYNTAX, "%s not terminated."
@@ -300,10 +347,18 @@ size_t LY_VCODE_INSTREXP_len(const char *str);
*****************************************************************************/
/**
+ * @brief Context error hash table record.
+ */
+struct ly_ctx_err_rec {
+ struct ly_err_item *err; /** pointer to the error items, if any */
+ pthread_t tid; /** pthread thread ID */
+};
+
+/**
* @brief Context of the YANG schemas
*/
struct ly_ctx {
- struct dict_table dict; /**< dictionary to effectively store strings used in the context related structures */
+ struct ly_dict dict; /**< dictionary to effectively store strings used in the context related structures */
struct ly_set search_paths; /**< set of directories where to search for schema's imports/includes */
struct ly_set list; /**< set of loaded YANG schemas */
ly_module_imp_clb imp_clb; /**< optional callback for retrieving missing included or imported models */
@@ -316,7 +371,7 @@ struct ly_ctx {
ly_ext_data_clb ext_clb; /**< optional callback for providing extension-specific run-time data for extensions */
void *ext_clb_data; /**< optional private data for ::ly_ctx.ext_clb */
- pthread_key_t errlist_key; /**< key for the thread-specific list of errors related to the context */
+ struct ly_ht *err_ht; /**< hash table of thread-specific list of errors related to the context */
pthread_mutex_t lyb_hash_lock; /**< lock for storing LYB schema hashes in schema nodes */
};
@@ -359,7 +414,6 @@ struct lys_module *ly_ctx_get_module_implemented2(const struct ly_ctx *ctx, cons
*
* @param[in] ptr Memory to reallocate.
* @param[in] size New size of the memory block.
- *
* @return Pointer to the new memory, NULL on error.
*/
void *ly_realloc(void *ptr, size_t size);
@@ -428,7 +482,8 @@ LY_ERR ly_strntou8(const char *nptr, size_t len, uint8_t *ret);
* If no string remains, it is set to NULL.
* @return LY_ERR value.
*/
-LY_ERR ly_value_prefix_next(const char *str_begin, const char *str_end, uint32_t *len, ly_bool *is_prefix, const char **str_next);
+LY_ERR ly_value_prefix_next(const char *str_begin, const char *str_end, uint32_t *len, ly_bool *is_prefix,
+ const char **str_next);
/**
* @brief Wrapper around strlen() to handle NULL strings.
@@ -485,7 +540,18 @@ LY_ERR ly_value_prefix_next(const char *str_begin, const char *str_end, uint32_t
LY_ERR ly_getutf8(const char **input, uint32_t *utf8_char, size_t *bytes_read);
/**
- * Store UTF-8 character specified as 4byte integer into the dst buffer.
+ * @brief Check an UTF-8 character is valid.
+ *
+ * @param[in] input Input string to process.
+ * @param[in] in_len Bytes left to read in @p input.
+ * @param[out] utf8_len Length of a valid UTF-8 character.
+ * @return LY_SUCCESS on success
+ * @return LY_EINVAL in case of invalid UTF-8 character.
+ */
+LY_ERR ly_checkutf8(const char *input, size_t in_len, size_t *utf8_len);
+
+/**
+ * @brief Store UTF-8 character specified as 4byte integer into the dst buffer.
*
* UTF-8 mapping:
* 00000000 -- 0000007F: 0xxxxxxx
@@ -495,7 +561,7 @@ LY_ERR ly_getutf8(const char **input, uint32_t *utf8_char, size_t *bytes_read);
*
* Includes checking for valid characters (following RFC 7950, sec 9.4)
*
- * @param[in, out] dst Destination buffer to store the UTF-8 character, must provide enough space (up to 4 bytes) for storing the UTF-8 character.
+ * @param[in,out] dst Destination buffer to store the UTF-8 character, must provide enough space (up to 4 bytes) for storing the UTF-8 character.
* @param[in] value 32b value of the UTF-8 character to store.
* @param[out] bytes_written Number of bytes written into @p dst (size of the written UTF-8 character).
* @return LY_SUCCESS on success
@@ -505,6 +571,7 @@ LY_ERR ly_pututf8(char *dst, uint32_t value, size_t *bytes_written);
/**
* @brief Get number of characters in the @p str, taking multibyte characters into account.
+ *
* @param[in] str String to examine.
* @param[in] bytes Number of valid bytes that are supposed to be taken into account in @p str.
* This parameter is useful mainly for non NULL-terminated strings. In case of NULL-terminated
@@ -515,6 +582,7 @@ size_t ly_utf8len(const char *str, size_t bytes);
/**
* @brief Parse signed integer with possible limitation.
+ *
* @param[in] val_str String value containing signed integer, note that
* nothing else than whitespaces are expected after the value itself.
* @param[in] val_len Length of the @p val_str string.
@@ -533,6 +601,7 @@ LY_ERR ly_parse_int(const char *val_str, size_t val_len, int64_t min, int64_t ma
/**
* @brief Parse unsigned integer with possible limitation.
+ *
* @param[in] val_str String value containing unsigned integer, note that
* nothing else than whitespaces are expected after the value itself.
* @param[in] val_len Length of the @p val_str string.
@@ -553,7 +622,7 @@ LY_ERR ly_parse_uint(const char *val_str, size_t val_len, uint64_t max, int base
*
* node-identifier = [prefix ":"] identifier
*
- * @param[in, out] id Identifier to parse. When returned, it points to the first character which is not part of the identifier.
+ * @param[in,out] id Identifier to parse. When returned, it points to the first character which is not part of the identifier.
* @param[out] prefix Node's prefix, NULL if there is not any.
* @param[out] prefix_len Length of the node's prefix, 0 if there is not any.
* @param[out] name Node's name.
@@ -565,7 +634,7 @@ LY_ERR ly_parse_nodeid(const char **id, const char **prefix, size_t *prefix_len,
/**
* @brief parse instance-identifier's predicate, supports key-predicate, leaf-list-predicate and pos rules from YANG ABNF Grammar.
*
- * @param[in, out] pred Predicate string (including the leading '[') to parse. The string is updated according to what was parsed
+ * @param[in,out] pred Predicate string (including the leading '[') to parse. The string is updated according to what was parsed
* (even for error case, so it can be used to determine which substring caused failure).
* @param[in] limit Limiting length of the @p pred. Function expects NULL terminated string which is not overread.
* The limit value is not checked with each character, so it can be overread and the failure is detected later.
@@ -610,17 +679,11 @@ LY_ERR ly_munmap(void *addr, size_t length);
/**
* @brief Concatenate formating string to the @p dest.
*
- * @param[in, out] dest String to be concatenated by @p format.
- * Note that the input string can be reallocated during concatenation.
+ * @param[in,out] dest String to be concatenated by @p format.
+ * Note that the input string can be reallocated during concatenation.
* @param[in] format Formating string (as for printf) which is supposed to be added after @p dest.
* @return LY_SUCCESS or LY_EMEM.
*/
-LY_ERR ly_strcat(char **dest, const char *format, ...);
-
-#ifndef _WIN32
-# define PATH_SEPARATOR ":"
-#else
-# define PATH_SEPARATOR ";"
-#endif
+LY_ERR ly_strcat(char **dest, const char *format, ...) _FORMAT_PRINTF(2, 3);
#endif /* LY_COMMON_H_ */