1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989-1994, 1999-2000, 2003-2010, 2013-2014 Free
3 Software Foundation, Inc.
5 This file is part of GNU M4.
7 GNU M4 is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU M4 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <m4/system.h>
31 /* --- MODULE AUTHOR DECLARATIONS --- */
34 typedef struct m4_builtin m4_builtin
;
35 typedef struct m4_call_info m4_call_info
;
36 typedef struct m4_macro m4_macro
;
37 typedef struct m4_macro_args m4_macro_args
;
38 typedef struct m4_module m4_module
;
39 typedef struct obstack m4_obstack
;
40 typedef struct m4_string m4_string
;
41 typedef struct m4_string_pair m4_string_pair
;
42 typedef struct m4_symbol m4_symbol
;
43 typedef struct m4_symbol_value m4_symbol_value
;
45 typedef void m4_builtin_func (m4
*, m4_obstack
*, size_t, m4_macro_args
*);
47 /* The value of m4_builtin flags is built from these: */
49 /* Set if macro flattens non-text tokens, such as builtin macro
50 tokens, to the empty string prior to invoking the builtin; if
51 clear, non-text tokens must be transparently handled by the
52 builtin. May only be set if max_args is nonzero. */
53 M4_BUILTIN_FLATTEN_ARGS
= (1 << 0),
54 /* Set if macro should only be recognized with arguments; may only
55 be set if min_args is nonzero. */
56 M4_BUILTIN_BLIND
= (1 << 1),
57 /* Set if macro has side effects even when there are too few
58 arguments; may only be set if min_args is nonzero. */
59 M4_BUILTIN_SIDE_EFFECT
= (1 << 2),
61 /* Mask of valid flag bits. Any other bits must be set to 0. */
62 M4_BUILTIN_FLAGS_MASK
= (1 << 3) - 1
67 m4_builtin_func
* func
; /* implementation of the builtin */
68 const char * name
; /* name found by builtin, printed by dumpdef */
69 int flags
; /* bitwise OR of M4_BUILTIN_* bits */
70 size_t min_args
; /* 0-based minimum number of arguments */
71 /* max arguments, SIZE_MAX if unlimited; must be >= min_args */
79 size_t min_args
; /* 0-based minimum number of arguments */
80 /* max arguments, SIZE_MAX if unlimited; must be >= min_args */
84 /* Describe a single string, such as a macro name. */
87 char *str
; /* Array of characters, possibly including NUL. */
88 size_t len
; /* Length of string. */
91 /* Describe a pair of strings, such as begin and end quotes. */
94 char *str1
; /* First string. */
95 size_t len1
; /* First length. */
96 char *str2
; /* Second string. */
97 size_t len2
; /* Second length. */
100 /* Declare a prototype for the function "builtin_<NAME>". Note that
101 the function name includes any macro expansion of NAME. */
102 #define M4BUILTIN(name) \
103 static void CONC (builtin_, name) \
104 (m4 *, m4_obstack *, size_t, m4_macro_args *);
106 /* Begin the implementation of the function "builtin_<NAME>",
107 declaring parameter names that can be used by other helper macros
108 in this file. Note that the function name includes any macro
109 expansion of NAME. */
110 #define M4BUILTIN_HANDLER(name) \
111 static void CONC (builtin_, name) \
112 (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv)
114 /* Declare a variable S of type "<S>_func" to be a pointer to the
115 function named S imported from the module M, or NULL if the import
116 fails. Note that M and S are intentionally used literally rather
117 than subjected to macro expansion, in all but the variable name. */
118 #define M4_MODULE_IMPORT(M, S) \
119 S ## _func *S = (S ## _func *) m4_module_import (context, #M, #S, obs)
121 /* Build an entry in a builtin table, for the builtin N implemented by
122 the function "builtin_<N>" with name NAME. Build the flags from
123 the appropriate combination of M4_BUILTIN_FLAG_* based on M if the
124 builtin transparently supports macro tokens, B if it is blind, and
125 S if it has side effects. Specify that the builtin takes MIN and
126 MAX arguments. Note that N is subject to macro expansion, and that
127 NAME is generally used as #N to avoid clashes with builtins named
128 after a standard function that is defined as a macro. */
129 #define M4BUILTIN_ENTRY(N, NAME, M, B, S, MIN, MAX) \
131 CONC (builtin_, N), NAME, \
132 (((!(M) && (MAX)) ? M4_BUILTIN_FLATTEN_ARGS : 0) \
133 | (((B) && (MIN)) ? M4_BUILTIN_BLIND : 0) \
134 | (((S) && (MIN)) ? M4_BUILTIN_SIDE_EFFECT : 0)), \
138 /* Grab the text contents of argument I, or abort if the argument is
139 not text. Assumes that `m4 *context' and `m4_macro_args *argv' are
141 #define M4ARG(i) m4_arg_text (context, argv, i, false)
143 /* Grab the length of the text contents of argument I, or abort if the
144 argument is not text. Assumes that `m4 *context' and
145 `m4_macro_args *argv' are in scope. */
146 #define M4ARGLEN(i) m4_arg_len (context, argv, i, false)
148 extern bool m4_bad_argc (m4
*, size_t, const m4_call_info
*, size_t,
150 extern bool m4_numeric_arg (m4
*, const m4_call_info
*, const char *,
152 extern bool m4_parse_truth_arg (m4
*, const m4_call_info
*, const char *,
154 extern m4_symbol
*m4_symbol_value_lookup (m4
*, m4_macro_args
*, size_t, bool);
155 extern const char *m4_info_name (const m4_call_info
*);
157 /* Error handling. */
158 extern void m4_error (m4
*, int, int, const m4_call_info
*, const char *, ...)
159 M4_GNUC_PRINTF (5, 6);
160 extern void m4_warn (m4
*, int, const m4_call_info
*, const char *, ...)
161 M4_GNUC_PRINTF (4, 5);
163 extern const char * m4_get_program_name (void);
164 extern void m4_set_program_name (const char *);
165 extern void m4_set_exit_failure (int);
168 /* --- CONTEXT MANAGEMENT --- */
170 typedef struct m4_syntax_table m4_syntax_table
;
171 typedef struct m4_symbol_table m4_symbol_table
;
173 extern m4
* m4_create (void);
174 extern void m4_delete (m4
*);
176 #define m4_context_field_table \
177 M4FIELD(m4_symbol_table *, symbol_table, symtab) \
178 M4FIELD(m4_syntax_table *, syntax_table, syntax) \
179 M4FIELD(const char *, current_file, current_file) \
180 M4FIELD(int, current_line, current_line) \
181 M4FIELD(int, output_line, output_line) \
182 M4FIELD(FILE *, debug_file, debug_file) \
183 M4FIELD(m4_obstack, trace_messages, trace_messages) \
184 M4FIELD(int, exit_status, exit_status) \
185 M4FIELD(int, current_diversion, current_diversion) \
186 M4FIELD(size_t, nesting_limit_opt, nesting_limit) \
187 M4FIELD(int, debug_level_opt, debug_level) \
188 M4FIELD(size_t, max_debug_arg_length_opt, max_debug_arg_length)\
189 M4FIELD(int, regexp_syntax_opt, regexp_syntax) \
192 #define m4_context_opt_bit_table \
193 M4OPT_BIT(M4_OPT_PREFIX_BUILTINS_BIT, prefix_builtins_opt) \
194 M4OPT_BIT(M4_OPT_SUPPRESS_WARN_BIT, suppress_warnings_opt) \
195 M4OPT_BIT(M4_OPT_DISCARD_COMMENTS_BIT, discard_comments_opt) \
196 M4OPT_BIT(M4_OPT_INTERACTIVE_BIT, interactive_opt) \
197 M4OPT_BIT(M4_OPT_SYNCOUTPUT_BIT, syncoutput_opt) \
198 M4OPT_BIT(M4_OPT_POSIXLY_CORRECT_BIT, posixly_correct_opt) \
199 M4OPT_BIT(M4_OPT_FATAL_WARN_BIT, fatal_warnings_opt) \
200 M4OPT_BIT(M4_OPT_WARN_EXIT_BIT, warnings_exit_opt) \
201 M4OPT_BIT(M4_OPT_SAFER_BIT, safer_opt) \
204 #define M4FIELD(type, base, field) \
205 extern type CONC (m4_get_, base) (m4 *context); \
206 extern type CONC (m4_set_, base) (m4 *context, type value);
207 m4_context_field_table
210 #define M4OPT_BIT(bit, base) \
211 extern bool CONC (m4_get_, base) (m4 *context); \
212 extern bool CONC (m4_set_, base) (m4 *context, bool value);
213 m4_context_opt_bit_table
216 #define M4SYMTAB (m4_get_symbol_table (context))
217 #define M4SYNTAX (m4_get_syntax_table (context))
221 /* --- MODULE MANAGEMENT --- */
223 typedef void m4_module_init_func (m4
*, m4_module
*, m4_obstack
*);
225 extern m4_module
* m4_module_load (m4
*, const char *, m4_obstack
*);
226 extern void * m4_module_import (m4
*, const char *, const char *,
229 extern void m4_install_builtins (m4
*, m4_module
*, const m4_builtin
*);
230 extern void m4_install_macros (m4
*, m4_module
*, const m4_macro
*);
232 extern const char * m4_get_module_name (const m4_module
*);
233 extern m4_module
* m4_module_next (m4
*, m4_module
*);
237 /* --- SYMBOL TABLE MANAGEMENT --- */
240 typedef void *m4_symtab_apply_func (m4_symbol_table
*, const char *, size_t,
241 m4_symbol
*, void *);
243 extern m4_symbol_table
*m4_symtab_create (size_t);
244 extern void m4_symtab_delete (m4_symbol_table
*);
245 extern void * m4_symtab_apply (m4_symbol_table
*, bool,
246 m4_symtab_apply_func
*, void *);
248 extern m4_symbol
*m4_symbol_lookup (m4_symbol_table
*, const char *, size_t);
249 extern m4_symbol
*m4_symbol_pushdef (m4_symbol_table
*, const char *, size_t,
251 extern m4_symbol
*m4_symbol_define (m4_symbol_table
*, const char *, size_t,
253 extern void m4_symbol_popdef (m4_symbol_table
*, const char *, size_t);
254 extern m4_symbol
*m4_symbol_rename (m4_symbol_table
*, const char *, size_t,
255 const char *, size_t);
257 extern void m4_symbol_delete (m4_symbol_table
*, const char *, size_t);
259 #define m4_symbol_delete(symtab, name, len) M4_STMT_START \
261 while (m4_symbol_lookup (symtab, name, len)) \
262 m4_symbol_popdef (symtab, name, len); \
265 extern m4_symbol_value
*m4_get_symbol_value (m4_symbol
*);
266 extern bool m4_get_symbol_traced (m4_symbol
*);
267 extern bool m4_set_symbol_name_traced (m4_symbol_table
*,
268 const char *, size_t, bool);
269 extern void m4_symbol_print (m4
*, m4_symbol
*, m4_obstack
*,
270 const m4_string_pair
*, bool, size_t,
272 extern bool m4_symbol_value_flatten_args (m4_symbol_value
*);
274 #define m4_is_symbol_void(symbol) \
275 (m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
276 #define m4_is_symbol_text(symbol) \
277 (m4_is_symbol_value_text (m4_get_symbol_value (symbol)))
278 #define m4_is_symbol_func(symbol) \
279 (m4_is_symbol_value_func (m4_get_symbol_value (symbol)))
280 #define m4_is_symbol_placeholder(symbol) \
281 (m4_is_symbol_value_placeholder (m4_get_symbol_value (symbol)))
282 #define m4_get_symbol_text(symbol) \
283 (m4_get_symbol_value_text (m4_get_symbol_value (symbol)))
284 #define m4_get_symbol_len(symbol) \
285 (m4_get_symbol_value_len (m4_get_symbol_value (symbol)))
286 #define m4_get_symbol_func(symbol) \
287 (m4_get_symbol_value_func (m4_get_symbol_value (symbol)))
288 #define m4_get_symbol_builtin(symbol) \
289 (m4_get_symbol_value_builtin (m4_get_symbol_value (symbol)))
290 #define m4_get_symbol_placeholder(symbol) \
291 (m4_get_symbol_value_placeholder (m4_get_symbol_value (symbol)))
292 #define m4_symbol_flatten_args(symbol) \
293 (m4_symbol_value_flatten_args (m4_get_symbol_value (symbol)))
295 extern m4_symbol_value
*m4_symbol_value_create (void);
296 extern void m4_symbol_value_delete (m4_symbol_value
*);
297 extern bool m4_symbol_value_copy (m4
*, m4_symbol_value
*,
299 extern bool m4_is_symbol_value_text (m4_symbol_value
*);
300 extern bool m4_is_symbol_value_func (m4_symbol_value
*);
301 extern bool m4_is_symbol_value_placeholder (m4_symbol_value
*);
302 extern bool m4_is_symbol_value_void (m4_symbol_value
*);
304 extern const char * m4_get_symbol_value_text (m4_symbol_value
*);
305 extern size_t m4_get_symbol_value_len (m4_symbol_value
*);
306 extern unsigned int m4_get_symbol_value_quote_age (m4_symbol_value
*);
308 extern m4_builtin_func
*m4_get_symbol_value_func (m4_symbol_value
*);
309 extern const m4_builtin
*m4_get_symbol_value_builtin (m4_symbol_value
*);
310 extern const char * m4_get_symbol_value_placeholder (m4_symbol_value
*);
312 extern void m4_set_symbol_value_text (m4_symbol_value
*,
313 const char *, size_t,
315 extern void m4_set_symbol_value_placeholder (m4_symbol_value
*,
320 /* --- BUILTIN MANAGEMENT --- */
322 extern m4_symbol_value
*m4_builtin_find_by_name (m4
*, m4_module
*, const char *);
323 extern m4_symbol_value
*m4_builtin_find_by_func (m4
*, m4_module
*,
328 /* --- MACRO MANAGEMENT --- */
330 extern void m4_macro_expand_input (m4
*);
331 extern void m4_macro_call (m4
*, m4_symbol_value
*, m4_obstack
*,
333 extern size_t m4_arg_argc (m4_macro_args
*);
334 extern const m4_call_info
*m4_arg_info (m4_macro_args
*);
335 extern m4_symbol_value
*m4_arg_symbol (m4_macro_args
*, size_t);
336 extern bool m4_is_arg_text (m4_macro_args
*, size_t);
337 extern bool m4_is_arg_func (m4_macro_args
*, size_t);
338 extern bool m4_is_arg_composite (m4_macro_args
*, size_t);
339 extern const char *m4_arg_text (m4
*, m4_macro_args
*, size_t, bool);
340 extern bool m4_arg_equal (m4
*, m4_macro_args
*, size_t,
342 extern bool m4_arg_empty (m4_macro_args
*, size_t);
343 extern size_t m4_arg_len (m4
*, m4_macro_args
*, size_t, bool);
344 extern m4_builtin_func
*m4_arg_func (m4_macro_args
*, size_t);
345 extern m4_obstack
*m4_arg_scratch (m4
*);
346 extern m4_macro_args
*m4_make_argv_ref (m4
*, m4_macro_args
*, const char *,
348 extern void m4_push_arg (m4
*, m4_obstack
*, m4_macro_args
*,
350 extern void m4_push_args (m4
*, m4_obstack
*, m4_macro_args
*,
352 extern void m4_wrap_args (m4
*, m4_macro_args
*);
355 /* --- RUNTIME DEBUGGING --- */
357 /* The value of debug_level is a bitmask of the following: */
359 /* a: show arglist in trace output */
360 M4_DEBUG_TRACE_ARGS
= (1 << 0),
361 /* e: show expansion in trace output */
362 M4_DEBUG_TRACE_EXPANSION
= (1 << 1),
363 /* q: quote args and expansion in trace output */
364 M4_DEBUG_TRACE_QUOTE
= (1 << 2),
365 /* t: trace all macros -- overrides trace{on,off} */
366 M4_DEBUG_TRACE_ALL
= (1 << 3),
367 /* l: add line numbers to trace output */
368 M4_DEBUG_TRACE_LINE
= (1 << 4),
369 /* f: add file name to trace output */
370 M4_DEBUG_TRACE_FILE
= (1 << 5),
371 /* p: trace path search of include files */
372 M4_DEBUG_TRACE_PATH
= (1 << 6),
373 /* c: show macro call before args collection */
374 M4_DEBUG_TRACE_CALL
= (1 << 7),
375 /* i: trace changes of input files */
376 M4_DEBUG_TRACE_INPUT
= (1 << 8),
377 /* x: add call id to trace output */
378 M4_DEBUG_TRACE_CALLID
= (1 << 9),
379 /* m: trace module actions */
380 M4_DEBUG_TRACE_MODULE
= (1 << 10),
381 /* s: trace pushdef stacks */
382 M4_DEBUG_TRACE_STACK
= (1 << 11),
383 /* d: warn if dereferencing undefined macro */
384 M4_DEBUG_TRACE_DEREF
= (1 << 12),
385 /* o: output dumpdef to stderr, not debug file */
386 M4_DEBUG_TRACE_OUTPUT_DUMPDEF
= (1 << 13),
388 /* V: very verbose -- print everything */
389 M4_DEBUG_TRACE_VERBOSE
= ((1 << 14) - 1)
392 /* initial flags, used if no -d or -E -- equiv: d */
393 #define M4_DEBUG_TRACE_INITIAL M4_DEBUG_TRACE_DEREF
395 /* default flags, used by debugmode() -- equiv: +adeq */
396 #define M4_DEBUG_TRACE_DEFAULT \
397 (M4_DEBUG_TRACE_ARGS | M4_DEBUG_TRACE_EXPANSION \
398 | M4_DEBUG_TRACE_QUOTE | M4_DEBUG_TRACE_DEREF)
400 #define m4_is_debug_bit(C,B) ((m4_get_debug_level_opt (C) & (B)) != 0)
402 extern int m4_debug_decode (m4
*, const char *, size_t);
403 extern bool m4_debug_set_output (m4
*, const m4_call_info
*,
405 extern void m4_debug_message_prefix (m4
*);
406 extern void m4_debug_message (m4
*, int, const char *, ...)
407 M4_GNUC_PRINTF (3, 4);
409 extern void m4_trace_prepare (m4
*, const m4_call_info
*,
413 /* --- REGEXP SYNTAX --- */
415 extern const char * m4_regexp_syntax_decode (int);
416 extern int m4_regexp_syntax_encode (const char *);
420 /* --- SYNTAX TABLE DEFINITIONS --- */
422 extern m4_syntax_table
*m4_syntax_create (void);
423 extern void m4_syntax_delete (m4_syntax_table
*syntax
);
424 extern int m4_syntax_code (char ch
);
426 extern const char * m4_get_syntax_lquote (m4_syntax_table
*syntax
);
427 extern const char * m4_get_syntax_rquote (m4_syntax_table
*syntax
);
428 extern const char * m4_get_syntax_bcomm (m4_syntax_table
*syntax
);
429 extern const char * m4_get_syntax_ecomm (m4_syntax_table
*syntax
);
430 extern const m4_string_pair
*m4_get_syntax_quotes (m4_syntax_table
*);
431 extern const m4_string_pair
*m4_get_syntax_comments (m4_syntax_table
*);
433 extern bool m4_is_syntax_single_quotes (m4_syntax_table
*);
434 extern bool m4_is_syntax_single_comments (m4_syntax_table
*);
435 extern bool m4_is_syntax_single_dollar (m4_syntax_table
*);
436 extern bool m4_is_syntax_macro_escaped (m4_syntax_table
*);
438 /* These are values to be assigned to syntax table entries. Although
439 they are bit masks for fast categorization in m4__next_token(),
440 only one value per syntax table entry is allowed. The enumeration
441 is currently sorted in order of parsing precedence. */
443 M4_SYNTAX_IGNORE
= 0,
444 M4_SYNTAX_ESCAPE
= 1 << 0,
445 M4_SYNTAX_ALPHA
= 1 << 1,
446 M4_SYNTAX_LQUOTE
= 1 << 2,
447 M4_SYNTAX_BCOMM
= 1 << 3,
448 M4_SYNTAX_ACTIVE
= 1 << 4,
449 M4_SYNTAX_NUM
= 1 << 5,
450 M4_SYNTAX_SPACE
= 1 << 6,
451 M4_SYNTAX_OPEN
= 1 << 7,
452 M4_SYNTAX_CLOSE
= 1 << 8,
453 M4_SYNTAX_COMMA
= 1 << 9,
454 M4_SYNTAX_OTHER
= 1 << 10,
456 /* These values are bit masks to OR with categories above, a syntax entry
457 may have any number of these in addition to a maximum of one of the
459 M4_SYNTAX_DOLLAR
= 1 << 11,
460 M4_SYNTAX_LBRACE
= 1 << 12,
461 M4_SYNTAX_RBRACE
= 1 << 13,
462 M4_SYNTAX_RQUOTE
= 1 << 14,
463 M4_SYNTAX_ECOMM
= 1 << 15
466 /* Mask of attribute syntax categories. */
467 #define M4_SYNTAX_MASKS (M4_SYNTAX_RQUOTE | M4_SYNTAX_ECOMM \
468 | M4_SYNTAX_DOLLAR | M4_SYNTAX_LBRACE \
470 /* Mask of basic syntax categories where any change requires a
471 recomputation of the overall syntax characteristics. */
472 #define M4_SYNTAX_SUSPECT (M4_SYNTAX_LQUOTE | M4_SYNTAX_BCOMM \
475 #define m4_syntab(S, C) ((S)->table[(C)])
476 /* Determine if character C matches any of the bitwise-or'd syntax
477 categories T for the given syntax table S. C can be either an
478 unsigned int (including special values such as CHAR_BUILTIN) or a
479 char which will be interpreted as an unsigned char. */
480 #define m4_has_syntax(S, C, T) \
481 ((m4_syntab ((S), sizeof (C) == 1 ? to_uchar (C) : (C)) & (T)) > 0)
483 extern void m4_set_quotes (m4_syntax_table
*, const char *, size_t,
484 const char *, size_t);
485 extern void m4_set_comment (m4_syntax_table
*, const char *, size_t,
486 const char *, size_t);
487 extern int m4_set_syntax (m4_syntax_table
*, char, char, const char *,
489 extern void m4_reset_syntax (m4_syntax_table
*);
493 /* --- INPUT TOKENIZATION --- */
495 extern void m4_input_init (m4
*context
);
496 extern void m4_input_exit (void);
497 extern void m4_skip_line (m4
*context
, const m4_call_info
*);
499 /* push back input */
501 extern void m4_push_file (m4
*, FILE *, const char *, bool);
502 extern void m4_push_builtin (m4
*, m4_obstack
*, m4_symbol_value
*);
503 extern m4_obstack
*m4_push_string_init (m4
*, const char *, int);
504 extern void m4_push_string_finish (void);
505 extern bool m4_pop_wrapup (m4
*);
506 extern void m4_input_print (m4
*, m4_obstack
*, int);
510 /* --- OUTPUT MANAGEMENT --- */
512 extern void m4_output_init (m4
*);
513 extern void m4_output_exit (void);
514 extern void m4_output_text (m4
*, const char *, size_t);
515 extern void m4_divert_text (m4
*, m4_obstack
*, const char *,
517 extern void m4_shipout_int (m4_obstack
*, int);
518 extern void m4_shipout_string (m4
*, m4_obstack
*, const char *,
520 extern bool m4_shipout_string_trunc (m4_obstack
*, const char *, size_t,
521 const m4_string_pair
*, size_t *);
523 extern void m4_make_diversion (m4
*, int);
524 extern void m4_insert_diversion (m4
*, int);
525 extern void m4_insert_file (m4
*, FILE *);
526 extern void m4_freeze_diversions (m4
*, FILE *);
527 extern void m4_undivert_all (m4
*);
531 /* --- PATH MANAGEMENT --- */
533 extern void m4_add_include_directory (m4
*, const char *, bool);
534 extern bool m4_load_filename (m4
*, const m4_call_info
*,
535 const char *, m4_obstack
*, bool);
536 extern char * m4_path_search (m4
*, const char *, const char **);
537 extern FILE * m4_fopen (m4
*, const char *, const char *);
541 #define obstack_chunk_alloc xmalloc
542 #define obstack_chunk_free free
545 /* Convert a possibly-signed character to an unsigned character. This is
546 a bit safer than casting to unsigned char, since it catches some type
547 errors that the cast doesn't. */
549 static inline unsigned char to_uchar (char ch
) { return ch
; }
551 # define to_uchar(C) ((unsigned char) (C))
556 #endif /* !M4MODULE_H */