blob: 920cd9e62e0bd4ff90673796b9813b44c189a532 [file] [log] [blame]
Radek Krejci5aeea3a2018-09-05 13:29:36 +02001/**
2 * @file log.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Logger manipulation routines and error definitions.
5 *
6 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#ifndef LY_LOG_H_
16#define LY_LOG_H_
17
Radek Krejci5aeea3a2018-09-05 13:29:36 +020018#ifdef __cplusplus
19extern "C" {
20#endif
21
Radek Krejciad573502018-09-07 15:26:55 +020022/* dummy context structure */
23struct ly_ctx;
24
Radek Krejci5aeea3a2018-09-05 13:29:36 +020025/**
26 * @defgroup log Logger
27 * @{
28 *
29 * Publicly visible functions and values of the libyang logger. For more
30 * information, see \ref howtologger.
31 */
32
33/**
34 * @typedef LY_LOG_LEVEL
35 * @brief Verbosity levels of the libyang logger.
36 */
37typedef enum
38{
39 LY_LLERR = 0, /**< Print only error messages, default value. */
40 LY_LLWRN = 1, /**< Print error and warning messages. */
41 LY_LLVRB = 2, /**< Besides errors and warnings, print some other verbose messages. */
42 LY_LLDBG = 3 /**< Print all messages including some development debug messages (be careful,
43 without subsequently calling ly_verb_dbg() no debug messages will be printed!). */
44} LY_LOG_LEVEL;
45
46/**
47 * @brief Set logger verbosity level.
48 * @param[in] level Verbosity level.
49 * @return Previous verbosity level.
50 */
51LY_LOG_LEVEL ly_verb (LY_LOG_LEVEL level);
52
53/**
54 * @defgroup logopts Logging options
55 * @ingroup logger
56 *
57 * Logging option bits of libyang.
58 *
59 * @{
60 */
61#define LY_LOLOG 0x01 /**< Log messages normally, using callback if set. If not set, messages will
62 not be printed by libyang. */
63#define LY_LOSTORE 0x02 /**< Store any generated errors or warnings, never verbose or debug messages.
64 Note that if #LY_LOLOG is not set then verbose and debug messages are always lost. */
65#define LY_LOSTORE_LAST 0x06 /**< Store any generated errors or warnings but only the last message, always overwrite
66 the previous one. */
67
68/**
69 * @}
70 */
71
72/**
73 * @brief Set additional logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
74 *
75 * @param[in] opts Bitfield of @ref logopts.
76 * @return Previous logger options.
77 */
78int ly_log_options (int opts);
79
80#ifndef NDEBUG
81
82/**
83 * @defgroup dbggroup Debug message groups
84 * @ingroup log
85 *
86 * Selected displayed debug message groups.
87 *
88 * @{
89 */
90
91#define LY_LDGDICT 0x01 /**< Dictionary additions and deletions. */
92#define LY_LDGYANG 0x02 /**< YANG parser messages. */
93#define LY_LDGYIN 0x04 /**< YIN parser messages. */
94#define LY_LDGXPATH 0x08 /**< XPath parsing end evaluation. */
95#define LY_LDGDIFF 0x10 /**< Diff processing and creation. */
96
97/**
98 * @}
99 */
100
101/**
102 * @brief Enable specific debugging messages (independent of log level).
103 * @param[in] dbg_groups Bitfield of enabled debug message groups (see @ref dbggroup).
104 */
105void ly_verb_dbg (int dbg_groups);
106
107#endif
108
109/**
110 * @brief Set logger callback.
111 *
112 * !IMPORTANT! If an error has a specific error-app-tag defined in the model, it will NOT be set
113 * at the time of calling this callback. It will be set right after, so to retrieve it
114 * it must be checked afterwards with ly_errapptag().
115 *
116 * @param[in] clb Logging callback.
117 * @param[in] path flag to resolve and provide path as the third parameter of the callback function. In case of
118 * validation and some other errors, it can be useful to get the path to the problematic element. Note,
119 * that according to the tree type and the specific situation, the path can slightly differs (keys
120 * presence) or it can be NULL, so consider it as an optional parameter. If the flag is 0, libyang will
121 * not bother with resolving the path.
122 */
123void ly_set_log_clb (void(*clb) (LY_LOG_LEVEL level, const char *msg, const char *path), int path);
124
125/**
126 * @brief Get logger callback.
127 * @return Logger callback (can be NULL).
128 */
129void (*ly_get_log_clb (void)) (LY_LOG_LEVEL, const char *, const char *);
130
131/** @} log */
132
133/**
134 * @defgroup errors Error information
135 * @{
136 */
137
138/**
139 * @typedef LY_ERR
140 * @brief libyang's error codes returned by the libyang functions.
141 */
142typedef enum
143{
144 LY_SUCCESS = 0, /**< no error, not set by functions, included just to complete #LY_ERR enumeration */
145 LY_EMEM, /**< Memory allocation failure */
Radek Krejcidc1c7e72018-09-07 14:58:20 +0200146 LY_ESYS, /**< System call failure */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200147 LY_EINVAL, /**< Invalid value */
148 LY_EEXIST, /**< Item already exists */
Radek Krejcid33273d2018-10-25 14:55:52 +0200149 LY_ENOTFOUND, /**< Item does not exists */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200150 LY_EINT, /**< Internal error */
151 LY_EVALID, /**< Validation failure */
Radek Krejci151a5b72018-10-19 14:21:44 +0200152 LY_EPLUGIN, /**< Error reported by a plugin */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200153 LY_EDENIED, /**< Operation is not allowed */
154 LY_EOTHER /**< Unknown error */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200155} LY_ERR;
156
157/**
158 * @typedef LY_VECODE
159 * @brief libyang's codes of validation error. Whenever ly_errno is set to LY_EVALID, the ly_vecode is also set
160 * to the appropriate LY_VECODE value.
161 * @ingroup logger
162 */
163typedef enum {
164 LYVE_SUCCESS = 0, /**< no error */
Radek Krejci94aa9942018-09-07 17:12:17 +0200165 LYVE_SYNTAX, /**< generic syntax error */
166 LYVE_SYNTAX_YANG, /**< YANG-related syntax error */
Radek Krejci70853c52018-10-15 14:46:16 +0200167 LYVE_REFERENCE, /**< invalid referencing or using an item */
Radek Krejcib1646a92018-11-02 16:08:26 +0100168 LYVE_XPATH, /**< invalid XPath expression */
Radek Krejcie7b95092019-05-15 11:03:07 +0200169 LYVE_SEMANTICS, /**< generic semantic error */
170 LYVE_SYNTAX_XML, /**< XML-related syntax error */
171 LYVE_RESTRICTION /**< YANG data does not reflect some of the module restrictions */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200172} LY_VECODE;
173
174/**
175 * @brief Libyang full error structure.
176 */
177struct ly_err_item {
178 LY_LOG_LEVEL level;
179 LY_ERR no;
180 LY_VECODE vecode;
181 char *msg;
182 char *path;
183 char *apptag;
184 struct ly_err_item *next;
185 struct ly_err_item *prev; /* first item's prev points to the last item */
186};
187
188/**
189 * @brief Get the last (thread, context-specific) validation error code.
190 *
191 * This value is set only if ly_errno is #LY_EVALID.
192 *
193 * @param[in] ctx Relative context.
194 * @return Validation error code.
195 */
196LY_VECODE ly_vecode(const struct ly_ctx *ctx);
197
198/**
Radek Krejcid33273d2018-10-25 14:55:52 +0200199 * @brief Get the last (thread, context-specific) error code.
200 *
201 * @param[in] ctx Relative context.
202 * @return LY_ERR value of the last error code.
203 */
204LY_ERR ly_errcode(const struct ly_ctx *ctx);
205
206/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200207 * @brief Get the last (thread, context-specific) error message. If the coresponding module defined
208 * a specific error message, it will be used instead the default one.
209 *
210 * Sometimes, the error message is extended with path of the element where the problem is.
211 * The path is available via ly_errpath().
212 *
213 * @param[in] ctx Relative context.
214 * @return Text of the last error message, empty string if there is no error.
215 */
216const char *ly_errmsg(const struct ly_ctx *ctx);
217
218/**
219 * @brief Get the last (thread, context-specific) path of the element where was an error.
220 *
221 * The path always corresponds to the error message available via ly_errmsg(), so
222 * whenever a subsequent error message is printed, the path is erased or rewritten.
223 * The path reflects the type of the processed tree - data path for data tree functions
224 * and schema path in case of schema tree functions. In case of processing YIN schema
225 * or XML data, the path can be just XML path. In such a case, the corresponding
226 * ly_vecode (value 1-3) is set.
227 *
228 * @param[in] ctx Relative context.
229 * @return Path of the error element, empty string if error path does not apply to the last error.
230 */
231const char *ly_errpath(const struct ly_ctx *ctx);
232
233/**
234 * @brief Get the last (thread, context-specific) error-app-tag if there was a specific one defined
235 * in the module for the last error.
236 *
237 * The app-tag always corresponds to the error message available via ly_errmsg(), so
238 * whenever a subsequent error message is printed, the app-tag is erased or rewritten.
239 *
240 * @param[in] ctx Relative context.
241 * @return Error-app-tag of the last error, empty string if the error-app-tag does not apply to the last error.
242 */
243const char *ly_errapptag(const struct ly_ctx *ctx);
244
245/**
246 * @brief Get the first (thread, context-specific) generated error structure.
247 *
248 * @param[in] ctx Relative context.
249 * @return First error structure (can be NULL), do not modify!
250 */
251struct ly_err_item *ly_err_first(const struct ly_ctx *ctx);
252
253/**
254 * @brief Print the error structure as if just generated.
255 *
256 * @param[in] eitem Error item structure to print.
257 */
258void ly_err_print(struct ly_err_item *eitem);
259
260/**
261 * @brief Free error structures from a context.
262 *
263 * If \p eitem is not set, free all the error structures.
264 *
265 * @param[in] ctx Relative context.
266 * @param[in] eitem Oldest error structure to remove, optional.
267 */
268void ly_err_clean(struct ly_ctx *ctx, struct ly_err_item *eitem);
269
270/** @} errors */
271
272#ifdef __cplusplus
273}
274#endif
275
276#endif /* LY_LOG_H_ */