1 /*************************************************************************/
2 /* Copyright (c) 2004                                                    */
3 /* Daniel Sleator, David Temperley, and John Lafferty                    */
4 /* Copyright (c) 2009 Linas Vepstas                                      */
5 /* All rights reserved                                                   */
6 /*                                                                       */
7 /* Use of the link grammar parsing system is subject to the terms of the */
8 /* license set forth in the LICENSE file included with this software.    */
9 /* This license allows free redistribution and use in source and binary  */
10 /* forms, with or without modification, subject to certain conditions.   */
11 /*                                                                       */
12 /*************************************************************************/
13 #ifndef _LINK_GRAMMAR_ERROR_H_
14 #define _LINK_GRAMMAR_ERROR_H_
15 
16 #include "link-includes.h"
17 #include "externs.h" // Needed for verbosity
18 
19 /* User verbosity levels are 1-4, to be used for user info/debug.
20  * For now hard-coded numbers are still used instead of D_USER_BASIC/TIMES. */
21 #define D_USER_BASIC 1   /* Basic verbosity level. */
22 #define D_USER_TIMES 2   /* Display step times. */
23 #define D_USER_INFO  3   /* Display some Info messages. */
24 #define D_USER_FILES 4   /* Display data file search and locale setup. */
25 #define D_USER_MAX   4   /* Maximum user verbosity level. */
26 #define D_DICT      10   /* Base of dictionary debug levels. */
27 #define D_SPEC     100   /* Base of special stand-alone levels. */
28 
29 typedef struct
30 {
31 	Sentence sent;
32 } err_ctxt;
33 
34 void err_msgc(err_ctxt *, lg_error_severity, const char *fmt, ...) GNUC_PRINTF(3,4);
35 #define err_msg(...) err_msgc(NULL, __VA_ARGS__)
36 const char *feature_enabled(const char *, ...);
37 
38 /**
39  * Print a debug message according to their level.
40  * Print the messages at levels <= the specified verbosity, with the
41  * following restrictions:
42  * - Level numbers 2 to D_USER_MAX are not printed on verbosity>D_USER_MAX,
43  *   because they are designed only for extended user information.
44  * - When verbosity > D_SPEC, print messages only when level==verbosity.
45  * - The !debug variable can be set to a comma-separated list of functions
46  *   or source filenames in order to restrict the debug messages to these
47  *   functions or filenames only.
48  *
49  * Invoking lgdebug() with a level number preceded by a + (+level) adds
50  * printing of the function name.
51  * FIXME: The level is then Trace and if the message starts with a level
52  * it is ignored.
53  */
54 #define lgdebug(level, ...) \
55 	(( \
56 	(((D_SPEC>=verbosity) && (verbosity>=(level))) || (verbosity==(level))) && \
57 	(((level)<=1) || !(((level)<=D_USER_MAX) && (verbosity>D_USER_MAX))) && \
58 	(('\0' == debug[0]) || \
59 	feature_enabled(debug, __func__, __FILE__, NULL))) ? \
60 	( \
61 		(STRINGIFY(level)[0] == '+' ? \
62 			(void)err_msg(lg_Trace, "%s: ", __func__) : \
63 			(void)0), \
64 		(void)err_msg(lg_Trace,  __VA_ARGS__) \
65 	) : \
66 	(void)0)
67 
68 /**
69  * Wrap-up a debug-messages block.
70  * Preceding the level number by a + (+level) adds printing of the
71  * function name.
72  * The !debug variable can be set to a comma-separated list of functions
73  * in order to restrict the debug messages to these functions only.
74  *
75  * Return true if the debug-messages block should be executed, else false.
76  *
77  * Usage example, for debug messages at verbosity V:
78  * if (verbosity_level(V))
79  * {
80  *    print_disjunct(d);
81  * }
82  *
83  * The optional printing of the function name is done here by prt_error()
84  * and not err_msg(), in order to not specify the message severity.
85  * Also note there is no trailing newline in that case. These things
86  * ensured the message severity will be taken from a following message
87  * which includes a newline. So verbosity_level(V) can be used for any
88  * desired message severity.
89  * The optional argument is used for additional names that can be used
90  * in the "debug" option (in addition to the current function and file names).
91  */
92 #define verbosity_level(level, ...) \
93 	(( \
94 	(((D_SPEC>=verbosity) && (verbosity>=(level))) || (verbosity==(level))) && \
95 	(((level)<=1) || !(((level)<=D_USER_MAX) && (verbosity>D_USER_MAX))) && \
96 	(('\0' == debug[0]) || \
97 	feature_enabled(debug, __func__, __FILE__, (__VA_ARGS__ ""), NULL))) \
98 	? ((STRINGIFY(level)[0] == '+' ? prt_error("%s: ", __func__) : 0), true) \
99 	: false)
100 
101 /**
102  * Return TRUE if the given feature (a string) is set in the !test variable
103  * (a comma-separated feature list).
104  */
105 #define test_enabled(feature) \
106 	(('\0' != test[0]) ? feature_enabled(test, feature, NULL) : NULL)
107 
108 #endif
109