6a2c26c8e105c192550cd013e16bec9041e66ebe
[strongswan.git] / src / libstrongswan / utils / parser_helper.h
1 /*
2 * Copyright (C) 2014 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 /**
17 * @defgroup parser_helper parser_helper
18 * @{ @ingroup utils
19 */
20
21 #ifndef PARSER_HELPER_H_
22 #define PARSER_HELPER_H_
23
24 #include <collections/array.h>
25 #include <bio/bio_writer.h>
26
27 typedef struct parser_helper_t parser_helper_t;
28 typedef struct parser_helper_file_t parser_helper_file_t;
29
30 /**
31 * Helper class for flex/bison based parsers.
32 *
33 * <code>PREFIX</code> equals whatever is configure with
34 * <code>%option prefix</code> resp. <code>%name-prefix</code>.
35 */
36 struct parser_helper_t {
37
38 /**
39 * A user defined parser context object.
40 */
41 const void *context;
42
43 /**
44 * Opaque object allocated by the lexer, should be set with:
45 * @code
46 * PREFIXlex_init_extra(helper, &helper->scanner).
47 * @endcode
48 */
49 void *scanner;
50
51 /**
52 * Function to determine the current line number (defined by the lexer).
53 *
54 * Basically, this should be assigned to <code>PREFIXget_lineno</code>.
55 *
56 * @param scanner the lexer
57 * @return current line number
58 */
59 int (*get_lineno)(void *scanner);
60
61 /**
62 * Get the current file.
63 *
64 * @return current file, or NULL
65 */
66 parser_helper_file_t *(*file_current)(parser_helper_t *this);
67
68 /**
69 * Resolves the given include pattern, relative to the location of the
70 * current file.
71 *
72 * Call file_next() to open the next file.
73 *
74 * @param pattern file pattern
75 */
76 void (*file_include)(parser_helper_t *this, char *pattern);
77
78 /**
79 * Get the next file to process.
80 *
81 * This will return NULL if all files matching the most recent pattern
82 * have been handled. If there are other patterns the next call will then
83 * return the next file matching the previous pattern.
84 *
85 * When hitting <code>\<\<EOF\>\></code> first call
86 * @code
87 * PREFIXpop_buffer_state(yyscanner);
88 * @endcode
89 * then call this method to check if there are more files to include for
90 * the most recent call to file_include(), if so, call
91 * @code
92 * PREFIXset_in(file->file, helper->scanner);
93 * PREFIXpush_buffer_state(PREFIX_create_buffer(file->file, YY_BUF_SIZE,
94 * helper->scanner), helper->scanner);
95 * @endcode
96 *
97 * If there are no more files to process check
98 * <code>YY_CURRENT_BUFFER</code> and if it is FALSE call yyterminate().
99 *
100 * @return next file to process, or NULL (see comment)
101 */
102 parser_helper_file_t *(*file_next)(parser_helper_t *this);
103
104 /**
105 * Start parsing a string, discards any currently stored data.
106 */
107 void (*string_init)(parser_helper_t *this);
108
109 /**
110 * Append the given string.
111 *
112 * @param str string to append
113 */
114 void (*string_add)(parser_helper_t *this, char *str);
115
116 /**
117 * Extract the current string buffer as null-terminated string. Can only
118 * be called once per string.
119 *
120 * @return allocated string
121 */
122 char *(*string_get)(parser_helper_t *this);
123
124 /**
125 * Destroy this instance.
126 */
127 void (*destroy)(parser_helper_t *this);
128 };
129
130 struct parser_helper_file_t {
131
132 /**
133 * File name
134 */
135 char *name;
136
137 /**
138 * File stream
139 */
140 FILE *file;
141 };
142
143 /**
144 * Log the given message either as error or warning
145 *
146 * @param level log level
147 * @param ctx current parser context
148 * @param fmt error message format
149 * @param ... additional arguments
150 */
151 void parser_helper_log(int level, parser_helper_t *ctx, char *fmt, ...);
152
153 #define PARSER_DBG1(ctx, fmt, ...) parser_helper_log(1, ctx, fmt, ##__VA_ARGS__)
154 #define PARSER_DBG2(ctx, fmt, ...) parser_helper_log(2, ctx, fmt, ##__VA_ARGS__)
155 #define PARSER_DBG3(ctx, fmt, ...) parser_helper_log(3, ctx, fmt, ##__VA_ARGS__)
156
157 /**
158 * Create a parser helper object
159 *
160 * @param context user defined parser context
161 * @return parser helper
162 */
163 parser_helper_t *parser_helper_create(void *context);
164
165 #endif /** PARSER_HELPER_H_ @}*/