1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1999, 2000, 2003,
4 2004, 2005 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include <m4/system.h>
33 /* --- MODULE AUTHOR DECLARATIONS --- */
36 typedef struct m4_builtin m4_builtin
;
37 typedef struct m4_macro m4_macro
;
38 typedef struct m4_symbol_value m4_symbol_value
;
40 typedef struct obstack m4_obstack
;
41 typedef lt_dlsymlist m4_export
;
43 typedef void m4_builtin_func (m4
*, m4_obstack
*, int, m4_symbol_value
**);
48 m4_builtin_func
* func
;
49 bool groks_macro_args
, blind_if_no_args
;
50 int min_args
, max_args
;
60 #define M4BUILTIN(name) \
61 static void CONC(builtin_, name) \
62 (m4 *context, m4_obstack *obs, int argc, m4_symbol_value **argv);
64 #define M4BUILTIN_HANDLER(name) \
65 static void CONC(builtin_, name) \
66 (m4 *context, m4_obstack *obs, int argc, m4_symbol_value **argv)
68 #define M4INIT_HANDLER(name) \
69 void CONC(name, CONC(_LTX_, m4_init_module)) \
70 (m4 *context, lt_dlhandle handle, m4_obstack *obs); \
71 void CONC(name, CONC(_LTX_, m4_init_module)) \
72 (m4 *context, lt_dlhandle handle, m4_obstack *obs)
74 #define M4FINISH_HANDLER(name) \
75 void CONC(name, CONC(_LTX_, m4_finish_module)) \
76 (m4 *context, lt_dlhandle handle, m4_obstack *obs); \
77 void CONC(name, CONC(_LTX_, m4_finish_module)) \
78 (m4 *context, lt_dlhandle handle, m4_obstack *obs)
80 #define M4_MODULE_IMPORT(M, S) \
81 CONC(S, _func) *S = (CONC(S, _func) *) \
82 m4_module_import (context, STR(M), STR(S), obs)
84 #define M4ARG(i) (argc > (i) ? m4_get_symbol_value_text (argv[i]) : "")
86 extern bool m4_bad_argc (m4
*, int, m4_symbol_value
**,
88 extern bool m4_numeric_arg (m4
*, int, m4_symbol_value
**,
90 extern void m4_dump_args (m4
*, m4_obstack
*, int,
91 m4_symbol_value
**, const char *,
95 #define M4ERROR(Arglist) (error Arglist)
96 #define M4WARN(Arglist) M4_STMT_START { \
97 if (!m4_get_suppress_warnings_opt (context)) M4ERROR (Arglist); \
102 /* --- CONTEXT MANAGEMENT --- */
104 typedef struct m4_syntax_table m4_syntax_table
;
105 typedef struct m4_symbol_table m4_symbol_table
;
106 typedef struct m4_symbol m4_symbol
;
108 extern m4
* m4_create (void);
109 extern void m4_delete (m4
*);
111 #define m4_context_field_table \
112 M4FIELD(m4_symbol_table *, symbol_table, symtab) \
113 M4FIELD(m4_syntax_table *, syntax_table, syntax) \
114 M4FIELD(FILE *, debug_file, debug_file) \
115 M4FIELD(m4_obstack, trace_messages, trace_messages) \
116 M4FIELD(int, warning_status_opt, warning_status) \
117 M4FIELD(bool, no_gnu_extensions_opt, no_gnu_extensions) \
118 M4FIELD(int, nesting_limit_opt, nesting_limit) \
119 M4FIELD(int, debug_level_opt, debug_level) \
120 M4FIELD(int, max_debug_arg_length_opt, max_debug_arg_length)\
123 #define m4_context_opt_bit_table \
124 M4OPT_BIT(M4_OPT_PREFIX_BUILTINS_BIT, prefix_builtins_opt) \
125 M4OPT_BIT(M4_OPT_SUPPRESS_WARN_BIT, suppress_warnings_opt) \
126 M4OPT_BIT(M4_OPT_DISCARD_COMMENTS_BIT, discard_comments_opt) \
127 M4OPT_BIT(M4_OPT_INTERACTIVE_BIT, interactive_opt) \
128 M4OPT_BIT(M4_OPT_SYNC_OUTPUT_BIT, sync_output_opt) \
129 M4OPT_BIT(M4_OPT_POSIXLY_CORRECT_BIT, posixly_correct_opt) \
132 #define M4FIELD(type, base, field) \
133 extern type CONC(m4_get_, base) (m4 *context); \
134 extern type CONC(m4_set_, base) (m4 *context, type value);
135 m4_context_field_table
138 #define M4OPT_BIT(bit, base) \
139 extern bool CONC(m4_get_, base) (m4 *context); \
140 extern bool CONC(m4_set_, base) (m4 *context, bool value);
141 m4_context_opt_bit_table
144 #define M4SYMTAB (m4_get_symbol_table (context))
145 #define M4SYNTAX (m4_get_syntax_table (context))
149 /* --- MODULE MANAGEMENT --- */
151 typedef void m4_module_init_func (m4
*, lt_dlhandle
, m4_obstack
*);
152 typedef void m4_module_finish_func (m4
*, lt_dlhandle
, m4_obstack
*);
154 extern lt_dlhandle
m4_module_load (m4
*, const char*, m4_obstack
*);
155 extern void m4_module_unload (m4
*, const char*, m4_obstack
*);
156 extern void * m4_module_import (m4
*, const char*, const char*,
159 extern const char * m4_get_module_name (lt_dlhandle
);
160 extern void m4__module_exit (m4
*context
);
164 /* --- SYMBOL TABLE MANAGEMENT --- */
167 typedef void *m4_symtab_apply_func (m4_symbol_table
*symtab
, const char *key
,
168 m4_symbol
*symbol
, void *userdata
);
170 extern m4_symbol_table
*m4_symtab_create (size_t, bool *);
171 extern void m4_symtab_delete (m4_symbol_table
*);
172 extern void * m4_symtab_apply (m4_symbol_table
*, m4_symtab_apply_func
*,
175 extern m4_symbol
*m4_symbol_lookup (m4_symbol_table
*, const char *);
176 extern m4_symbol
*m4_symbol_pushdef (m4_symbol_table
*,
177 const char *, m4_symbol_value
*);
178 extern m4_symbol
*m4_symbol_define (m4_symbol_table
*,
179 const char *, m4_symbol_value
*);
180 extern void m4_symbol_popdef (m4_symbol_table
*, const char *);
181 extern m4_symbol
*m4_symbol_rename (m4_symbol_table
*, const char *,
184 extern void m4_symbol_delete (m4_symbol_table
*, const char *);
186 #define m4_symbol_delete(symtab, name) M4_STMT_START { \
187 while (m4_symbol_lookup ((symtab), (name))) \
188 m4_symbol_popdef ((symtab), (name)); } M4_STMT_END
190 extern m4_symbol_value
*m4_get_symbol_value (m4_symbol
*);
191 extern bool m4_get_symbol_traced (m4_symbol
*);
192 extern bool m4_set_symbol_traced (m4_symbol
*, bool);
193 extern bool m4_set_symbol_name_traced (m4_symbol_table
*,
196 #define m4_is_symbol_text(symbol) \
197 (m4_is_symbol_value_text (m4_get_symbol_value (symbol)))
198 #define m4_is_symbol_func(symbol) \
199 (m4_is_symbol_value_func (m4_get_symbol_value (symbol)))
200 #define m4_get_symbol_text(symbol) \
201 (m4_get_symbol_value_text (m4_get_symbol_value (symbol)))
202 #define m4_get_symbol_func(symbol) \
203 (m4_get_symbol_value_func (m4_get_symbol_value (symbol)))
205 extern m4_symbol_value
*m4_symbol_value_create (void);
206 extern void m4_symbol_value_delete (m4_symbol_value
*);
207 extern void m4_symbol_value_copy (m4_symbol_value
*,
209 extern bool m4_is_symbol_value_text (m4_symbol_value
*);
210 extern bool m4_is_symbol_value_func (m4_symbol_value
*);
211 extern bool m4_is_symbol_value_void (m4_symbol_value
*);
212 extern char *m4_get_symbol_value_text (m4_symbol_value
*);
213 extern m4_builtin_func
*m4_get_symbol_value_func (m4_symbol_value
*);
214 extern void m4_set_symbol_value_text (m4_symbol_value
*, char *);
215 extern void m4_set_symbol_value_func (m4_symbol_value
*,
220 /* --- BUILTIN MANAGEMENT --- */
222 extern const m4_builtin
*m4_builtin_find_by_name (lt_dlhandle
, const char *);
223 extern const m4_builtin
*m4_builtin_find_by_func (lt_dlhandle
,
228 /* --- MACRO MANAGEMENT --- */
230 extern void m4_macro_expand_input (m4
*);
231 extern void m4_macro_call (m4
*, m4_symbol
*, m4_obstack
*,
232 int, m4_symbol_value
**);
236 /* --- RUNTIME DEBUGGING --- */
238 /* The value of debug_level is a bitmask of the following: */
240 /* a: show arglist in trace output */
241 M4_DEBUG_TRACE_ARGS
= (1 << 0),
242 /* e: show expansion in trace output */
243 M4_DEBUG_TRACE_EXPANSION
= (1 << 1),
244 /* q: quote args and expansion in trace output */
245 M4_DEBUG_TRACE_QUOTE
= (1 << 2),
246 /* t: trace all macros -- overrides trace{on,off} */
247 M4_DEBUG_TRACE_ALL
= (1 << 3),
248 /* l: add line numbers to trace output */
249 M4_DEBUG_TRACE_LINE
= (1 << 4),
250 /* f: add file name to trace output */
251 M4_DEBUG_TRACE_FILE
= (1 << 5),
252 /* p: trace path search of include files */
253 M4_DEBUG_TRACE_PATH
= (1 << 6),
254 /* c: show macro call before args collection */
255 M4_DEBUG_TRACE_CALL
= (1 << 7),
256 /* i: trace changes of input files */
257 M4_DEBUG_TRACE_INPUT
= (1 << 8),
258 /* x: add call id to trace output */
259 M4_DEBUG_TRACE_CALLID
= (1 << 9),
261 /* V: very verbose -- print everything */
262 M4_DEBUG_TRACE_VERBOSE
= (~0)
265 /* default flags -- equiv: aeq */
266 #define M4_DEBUG_TRACE_DEFAULT \
267 (M4_DEBUG_TRACE_ARGS|M4_DEBUG_TRACE_EXPANSION|M4_DEBUG_TRACE_QUOTE)
269 #define m4_is_debug_bit(C,B) (BIT_TEST (m4_get_debug_level_opt (C), (B)))
271 extern int m4_debug_decode (m4
*, const char *);
272 extern bool m4_debug_set_output (m4
*, const char *);
273 extern void m4_debug_message_prefix (m4
*);
277 /* --- SYNTAX TABLE DEFINITIONS --- */
279 extern m4_syntax_table
*m4_syntax_create (void);
280 extern void m4_syntax_delete (m4_syntax_table
*syntax
);
281 extern int m4_syntax_code (char ch
);
283 extern const char * m4_get_syntax_lquote (m4_syntax_table
*syntax
);
284 extern const char * m4_get_syntax_rquote (m4_syntax_table
*syntax
);
285 extern const char * m4_get_syntax_bcomm (m4_syntax_table
*syntax
);
286 extern const char * m4_get_syntax_ecomm (m4_syntax_table
*syntax
);
288 extern bool m4_is_syntax_single_quotes (m4_syntax_table
*);
289 extern bool m4_is_syntax_single_comments (m4_syntax_table
*);
290 extern bool m4_is_syntax_macro_escaped (m4_syntax_table
*);
292 /* These are values to be assigned to syntax table entries, although they
293 are bit masks for fast categorisation in m4__next_token(), only one
294 value per syntax table entry is allowed. */
296 M4_SYNTAX_OTHER
= (1 << 0),
297 M4_SYNTAX_IGNORE
= (1 << 1),
298 M4_SYNTAX_SPACE
= (1 << 2),
299 M4_SYNTAX_OPEN
= (1 << 3),
300 M4_SYNTAX_CLOSE
= (1 << 4),
301 M4_SYNTAX_COMMA
= (1 << 5),
302 M4_SYNTAX_DOLLAR
= (1 << 6),
303 M4_SYNTAX_ACTIVE
= (1 << 7),
304 M4_SYNTAX_ESCAPE
= (1 << 8),
305 M4_SYNTAX_ASSIGN
= (1 << 9),
306 M4_SYNTAX_ALPHA
= (1 << 10),
307 M4_SYNTAX_NUM
= (1 << 11),
309 /* These values are bit masks to AND with categories above, a syntax entry
310 may have any number of these in addition to a maximum of one of the
312 M4_SYNTAX_LQUOTE
= (1 << 12),
313 M4_SYNTAX_RQUOTE
= (1 << 13),
314 M4_SYNTAX_BCOMM
= (1 << 14),
315 M4_SYNTAX_ECOMM
= (1 << 15),
318 #define M4_SYNTAX_MASKS (M4_SYNTAX_LQUOTE|M4_SYNTAX_RQUOTE|M4_SYNTAX_BCOMM|M4_SYNTAX_ECOMM)
319 #define M4_SYNTAX_VALUE (~(M4_SYNTAX_RQUOTE|M4_SYNTAX_ECOMM))
321 #define m4_syntab(S,C) ((S)->table[(int)(C)])
322 #define m4_has_syntax(S,C,T) ((m4_syntab((S),(C)) & (T)) > 0)
323 #define m4_is_syntax(S,C,T) ((m4_syntab((S),(C)) & M4_SYNTAX_VALUE) == (T))
325 extern void m4_set_quotes (m4_syntax_table
*, const char*, const char*);
326 extern void m4_set_comment (m4_syntax_table
*, const char*, const char*);
327 extern int m4_set_syntax (m4_syntax_table
*, char, const unsigned char*);
331 /* --- INPUT TOKENISATION --- */
333 /* current input file, and line */
334 extern const char *m4_current_file
;
335 extern int m4_current_line
;
337 extern void m4_input_init (void);
338 extern void m4_input_exit (void);
339 extern int m4_peek_input (m4
*context
);
340 extern void m4_skip_line (m4
*context
);
342 /* push back input */
344 extern void m4_push_file (m4
*context
, FILE *, const char *);
345 extern void m4_push_single (int ch
);
346 extern void m4_push_builtin (m4_symbol_value
*);
347 extern m4_obstack
*m4_push_string_init (m4
*context
);
348 extern const char *m4_push_string_finish (void);
349 extern void m4_push_wrapup (const char *);
350 extern bool m4_pop_wrapup (void);
354 /* --- OUTPUT MANAGEMENT --- */
356 extern int m4_current_diversion
;
357 extern int m4_output_current_line
;
359 extern void m4_output_init (void);
360 extern void m4_output_exit (void);
361 extern void m4_shipout_text (m4
*, m4_obstack
*, const char *, int);
362 extern void m4_shipout_int (m4_obstack
*, int);
363 extern void m4_shipout_string (m4
*, m4_obstack
*, const char *,
366 extern void m4_make_diversion (int);
367 extern void m4_insert_diversion (int);
368 extern void m4_insert_file (FILE *);
369 extern void m4_freeze_diversions (FILE *);
370 extern void m4_undivert_all (void);
374 /* --- PATH MANAGEMENT --- */
376 extern void m4_include_env_init (m4
*);
377 extern void m4_add_include_directory (m4
*, const char *);
378 extern FILE * m4_path_search (m4
*, const char *, char **);
382 #define obstack_chunk_alloc xmalloc
383 #define obstack_chunk_free free
387 #endif /* !M4MODULE_H */