1 
2 /**
3  * @file autogen.h
4  *
5  *  Global header file for AutoGen
6  */
7 /**
8  * @mainpage
9  * @section Introduction
10  * Autogen is a multi-component project.  There is the basic engine itself
11  * ("autogen"), a library ("libopts") and its support templates (collectively,
12  * "AutoOpts"), several support and utility programs ("columns", "getdefs" and
13  * "xml2ag"), *plus* several handy embedded utility templates.  They are all
14  * bundled together because they all require each other.
15  * They each do completely separate things, but they each are not useful
16  * without the other.  Thus, they are bundled together.
17  *
18  * @group autogen
19  * @{
20  */
21 /*  This file is part of AutoGen.
22  *  AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
23  *
24  * AutoGen is free software: you can redistribute it and/or modify it
25  * under the terms of the GNU General Public License as published by the
26  * Free Software Foundation, either version 3 of the License, or
27  * (at your option) any later version.
28  *
29  * AutoGen is distributed in the hope that it will be useful, but
30  * WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
32  * See the GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License along
35  * with this program.  If not, see <http://www.gnu.org/licenses/>.
36  */
37 #ifndef AUTOGEN_BUILD
38 #define AUTOGEN_BUILD 1
39 #include <stdnoreturn.h>
40 #include "compat/unlocked-io.h"
41 
42 #include REGEX_HEADER
43 #if !defined(__GNUC__)
44 #define GCC_VERSION 0
45 #elif ! defined(GCC_VERSION)
46 #define GCC_VERSION (__GNUC__ * 10000 \
47                     + __GNUC_MINOR__ * 100 \
48                     + __GNUC_PATCHLEVEL__)
49 #endif
50 
51 #if GCC_VERSION > 40400
52 #pragma  GCC diagnostic push
53 #pragma  GCC diagnostic ignored "-Wextra"
54 #pragma  GCC diagnostic ignored "-Wconversion"
55 #pragma  GCC diagnostic ignored "-Wsign-conversion"
56 #pragma  GCC diagnostic ignored "-Wstrict-overflow"
57 #endif
58 
59 #include <libguile/scmconfig.h>
60 #include <libguile.h>
61 
62 #if GCC_VERSION > 40400
63 #pragma  GCC diagnostic pop
64 #endif
65 
66 #define DEFINE_FSM
67 
68 #include "ag-text.h"
69 #include "opts.h"
70 #include "expr.h"
71 #include "autoopts/autoopts.h"
72 #include "directive.h"
73 #include "snprintfv/printf.h"
74 #include "scribble.h"
75 #include "pseudo-fsm.h"
76 
77 #define  LOG10_2to32  10  /* rounded up */
78 
79 #if defined(SHELL_ENABLED)
80 #  ifndef HAVE_WORKING_FORK
81 #    error SHELL is enabled and fork() does not work
82      choke me
83 #  endif
84 #endif
85 
86 #ifndef DIRCH
87 # if defined(_WIN32) && !defined(__CYGWIN__)
88 #  define DIRCH                  '\\'
89 # else
90 #  define DIRCH                  '/'
91 # endif
92 #endif
93 
94 #define YYSTYPE t_word
95 
96 #define ag_offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
97 
98 /*
99  *  Dual pipe opening of a child process
100  */
101 typedef struct {
102     int     fd_read;
103     int     fd_write;
104 }  fd_pair_t;
105 
106 typedef struct {
107     FILE *  fp_read;  /* parent read fp  */
108     FILE *  fp_write; /* parent write fp */
109 }  fp_pair_t;
110 
111 #define NOPROCESS   ((pid_t)-1)
112 #define NULLPROCESS ((pid_t)0)
113 #define NL          '\n'
114 #define TAB         '\t'
115 
116 #include "cgi-fsm.h"
117 #include "defParse-fsm.h"
118 
119 typedef union {
120     unsigned char * pzStr;
121     unsigned char   ch;
122 } def_token_u_t;
123 
124 #define STATE_TABLE           /* set up `atexit' and load Guile   */  \
125     _State_( INIT )           /* processing command line options  */  \
126     _State_( OPTIONS )        /* Loading guile at option time     */  \
127     _State_( GUILE_PRELOAD )  /* Loading value definitions        */  \
128     _State_( LOAD_DEFS )      /* Loading library template         */  \
129     _State_( LIB_LOAD )       /* Loading primary template         */  \
130     _State_( LOAD_TPL )       /* processing templates             */  \
131     _State_( EMITTING )       /* loading an included template     */  \
132     _State_( INCLUDING )      /* end of processing before exit()  */  \
133     _State_( CLEANUP )        /* Clean up code in error response  */  \
134     _State_( ABORTING )       /* `exit' has been called           */  \
135     _State_( DONE )
136 
137 #define _State_(n)  PROC_STATE_ ## n,
138 typedef enum { STATE_TABLE COUNT_PROC_STATE } proc_state_t;
139 #undef _State_
140 
141 #define EXPORT
142 
143 typedef struct out_stack        out_stack_t;
144 typedef struct out_spec         out_spec_t;
145 typedef struct scan_context     scan_ctx_t;
146 typedef struct def_entry        def_ent_t;
147 typedef struct macro_desc       macro_t;
148 typedef struct template_desc    templ_t;
149 typedef struct for_state        for_state_t;
150 typedef struct tlib_mark        tlib_mark_t;
151 
152 #define MAX_SUFFIX_LEN       8  /* maximum length of a file name suffix */
153 #define MAX_HEREMARK_LEN    64  /* max length of a here mark */
154 #define SCRIBBLE_SIZE      256  /* much larger than any short name */
155 
156 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
157  *
158  *  Template Library Layout
159  *
160  *  Procedure for loading a template function
161  */
162 typedef macro_t * (load_proc_t)(templ_t *, macro_t *, char const ** ppzScan);
163 typedef load_proc_t * load_proc_p_t;
164 
165 typedef void (unload_proc_t)(macro_t *);
166 typedef unload_proc_t * unload_proc_p_t;
167 
168 /*
169  *  Procedure for handling a template function
170  *  during the text emission phase.
171  */
172 typedef macro_t * (hdlr_proc_t)(templ_t *, macro_t *);
173 typedef hdlr_proc_t * hdlr_proc_p_t;
174 
175 /*
176  *  This must be included after the function prototypes
177  *  (the prototypes are used in the generated tables),
178  *  but before the macro descriptor structure (the function
179  *  enumeration is generated here).
180  */
181 #include "functions.h"
182 
183 #define TEMPLATE_REVISION     1
184 #define TEMPLATE_MAGIC_MARKER {{{'A', 'G', 'L', 'B'}}, \
185                                TEMPLATE_REVISION, FUNCTION_CKSUM }
186 
187 struct tlib_mark {
188     union {
189         unsigned char   str[4];  /* {'A', 'G', 'L', 'B'} */
190         unsigned int    i[1];
191     }           tlm_magic;
192     unsigned short  tlm_revision;   /* TEMPLATE_REVISION    */
193     unsigned short  tlm_cksum;      /* FUNCTION_CKSUM       */
194 };
195 
196 /**
197  *  Defines for conditional expressions.  The first four are an enumeration
198  *  that appear in the low four bits and the next-to-lowest four bits.
199  *  "PRIMARY_TYPE" and "SECONDARY_TYPE" are masks for extracting this
200  *  enumeration.  The rest are flags.
201  */
202 #define EMIT_VALUE          0x0000  //!< emit value of variable
203 #define EMIT_EXPRESSION     0x0001  //!< Emit Scheme result
204 #define EMIT_SHELL          0x0002  //!< emit shell output
205 #define EMIT_STRING         0x0003  //!< emit content of expr
206 #define EMIT_PRIMARY_TYPE   0x0007  //!< mask for primary emission type
207 #define EMIT_SECONDARY_TYPE 0x0070  //!< mask for secondary emission type
208 #define EMIT_SECONDARY_SHIFT     4  //!< bit offset for secondary type
209 #define EMIT_IF_ABSENT      0x0100  //!< emit text when value non-existant
210 #define EMIT_ALWAYS         0x0200  //!< emit one of two exprs
211 #define EMIT_FORMATTED      0x0400  //!< format, if val present
212 #define EMIT_NO_DEFINE      0x0800  //!< don't get defined value
213 
214 /**
215  * template macro descriptor.
216  */
217 struct macro_desc {
218     mac_func_t    md_code;      //!< Macro function
219     int           md_line;      //!< of macro def
220     int           md_end_idx;   //!< End of block macro
221     int           md_sib_idx;   //!< Sibling macro (ELIF or SELECT)
222 
223     uintptr_t     md_name_off;  //!< macro name (sometimes)
224     uintptr_t     md_txt_off;   //!< associated text
225     uintptr_t     md_res;       //!< some sort of result
226     void *        md_pvt;       //!< private data for particular macro
227 };
228 
229 /**
230  * AutoGen template descriptor.
231  * A full template or a defined macro is managed with this structure.
232  */
233 struct template_desc {
234     tlib_mark_t   td_magic;     //!< TEMPLATE_MAGIC_MARKER
235     size_t        td_size;      //!< Structure Size
236     char *        td_scan;      //!< Next Pointer
237     int           td_mac_ct;    //!< Count of Macros
238     char const *  td_file;      //!< Name of template file
239     char *        td_name;      //!< Defined Macro Name
240     char *        td_text;      //!< base address of the text
241     char          td_start_mac[MAX_SUFFIX_LEN];
242     char          td_end_mac[  MAX_SUFFIX_LEN];
243     macro_t       td_macros[1]; //!< Array of Macros
244 //  char          td_text[...];  * strings are at end of macros
245 };
246 
247 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
248  *
249  *  Name/Value Definitions Layout
250  */
251 typedef enum {
252     VALTYP_UNKNOWN = 0,
253     VALTYP_TEXT,
254     VALTYP_BLOCK
255 } val_typ_t;
256 
257 
258 #define NO_INDEX ((short)0x80DEAD)
259 
260 typedef struct def_ctx def_ctx_t;
261 struct def_ctx {
262     def_ent_t *   dcx_defent;   //!< ptr to current def set
263     def_ctx_t *   dcx_prev;     //!< ptr to previous def set
264 };
265 
266 typedef union {
267     def_ent_t *   dvu_entry;
268     char *        dvu_text;
269 } def_val_u;
270 
271 struct def_entry {
272     def_ent_t *   de_next;      //!< next member of same level
273     def_ent_t *   de_twin;      //!< next member with same name
274     def_ent_t *   de_ptwin;     //!< previous memb. of level
275     def_ent_t *   de_etwin;     //!< head of chain to end ptr
276     char *        de_name;      //!< name of this member
277     long          de_index;     //!< index among twins
278     def_val_u     de_val;       //!< string or list of children
279     char *        de_file;      //!< definition file name
280     int           de_line;      //!< def file source line
281     val_typ_t     de_type;      //!< text/block/not defined yet
282 };
283 
284 struct scan_context {
285     scan_ctx_t *  scx_next;
286     char *        scx_scan;
287     char const *  scx_fname;
288     char *        scx_data;
289     int           scx_line;
290 };
291 
292 struct out_spec {
293     out_spec_t *  os_next;
294     char const *  os_file_fmt;
295     bool          os_dealloc_fmt;
296     char          os_sfx[ 1 ];
297 };
298 
299 /**
300  * Output stack handling flags.
301  */
302 #define FPF_FREE        0x0001  /*!< free the fp structure   */
303 #define FPF_UNLINK      0x0002  /*!< unlink file (temp file) */
304 #define FPF_NOUNLINK    0x0004  /*!< do not unlink file      */
305 #define FPF_STATIC_NM   0x0008  /*!< name statically alloced */
306 #define FPF_NOCHMOD     0x0010  /*!< do not chmod(2) file    */
307 #define FPF_TEMPFILE    0x0020  /*!< the file is a temp      */
308 
309 struct out_stack {
310     int           stk_flags;
311     out_stack_t * stk_prev;
312     FILE *        stk_fp;
313     char const *  stk_fname;
314 };
315 
316 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
317  *
318  *  FOR loop processing state
319  */
320 /**
321  * The current state of each active FOR loop.
322  */
323 struct for_state {
324     def_ctx_t     for_ctx;      //!< saved def context for for loop
325     char *        for_sep_str;  //!< inter-iteration string (allocated)
326     char *        for_name;     //!< name of iterator (not allocated)
327     int           for_from;     //!< the first index of loop
328     int           for_to;       //!< the last index of loop
329     int           for_by;       //!< the loop increment (usually 1)
330     int           for_index;    //!< the current index
331     bool          for_loading;  //!< the FOR macro is getting ready
332     bool          for_islast;   //!< true for last iteration
333     bool          for_isfirst;  //!< true for first iteration
334     bool          for_not_found;//!< usually false, true with sparse arrays
335     jmp_buf       for_env;      //!< long jump buffer (BREAK, CONTINUE)
336 };
337 
338 typedef enum {
339     LOOP_JMP_OKAY    = 0,
340     LOOP_JMP_NEXT    = 1,
341     LOOP_JMP_BREAK   = 2
342 } loop_jmp_type_t;
343 
344 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
345 /**
346  *  Invocation of a defined macro processing state
347  */
348 typedef struct ivk_info ivk_info_t;
349 struct ivk_info {
350     ivk_info_t *  ii_prev;      //!< previous layer
351     int           ii_depth;     //!< Invocation nesting depth
352     jmp_buf       ii_env;       //!< long jump buffer (RETURN)
353     int           ii_for_depth; //!< for depth for this invocation
354     int           ii_for_alloc; //!< for state buffer allocation count
355     for_state_t * ii_for_data;  //!< array of "for" macro states
356 };
357 #define IVK_INFO_INITIALIZER(_p) {                      \
358         .ii_prev  = (_p),                               \
359         .ii_depth = curr_ivk_info->ii_depth + 1,        \
360         .ii_for_depth = 0,                              \
361         .ii_for_alloc = 0,                              \
362         .ii_for_data  = NULL                            \
363     }
364 
365 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
366  *
367  *  Parsing stuff
368  */
369 #define _MkStr(_s) #_s
370 #define MK_STR(_s) _MkStr(_s)
371 
372 #define SCM_EVAL_CONST(_s)                                      \
373     do { static int const line   = __LINE__ - 1;                \
374         static char const file[] = __FILE__;                    \
375         static char const * text = _s;                          \
376         last_scm_cmd = text;                                    \
377         ag_scm_c_eval_string_from_file_line(text, file, line);  \
378     } while (false)
379 
380 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
381  *
382  *  GLOBAL VARIABLES
383  *
384  *  General Processing Globals
385  */
386 #define ag_pname    autogenOptions.pzProgName
387 MODE proc_state_t    processing_state VALUE( PROC_STATE_INIT );
388 MODE unsigned int   include_depth    VALUE( 0 );
389 MODE bool           defining_macro   VALUE( false );
390 MODE templ_t *      named_tpls       VALUE( NULL );
391 MODE char const *   oops_pfx         VALUE( "" );
392 /*
393  *  "eval_mac_expr" must be able to return a distinct empty string so that
394  *  the "CASE" function can distinguish an empty string due to it being a
395  *  value from an empty string due to an absent definition.
396  */
397 MODE char const     no_def_str[1]    VALUE( "" );
398 
399 /*
400  *  Template Processing Globals
401  */
402 MODE char const *   curr_sfx         VALUE( NULL );
403 /**
404  * The time to set for the modification times of the output files.
405  */
406 #ifndef HAVE_CLOCK_GETTIME
407 #undef  HAVE_UTIMENSAT
408 #endif
409 
410 #ifndef HAVE_UTIMENSAT
411 MODE time_t             outfile_time     VALUE( 0 );
412 MODE time_t             maxfile_time     VALUE( 0 );
413 #define time_is_before(_f, _s) ((_f) < (_s))
414 
415 #else  // HAVE_UTIMENSAT
416 #ifdef DEFINING
417 MODE struct timespec    outfile_time     = {0, UTIME_OMIT};
418 MODE struct timespec    maxfile_time     = {0, UTIME_OMIT};
419 #else
420 MODE struct timespec    outfile_time, maxfile_time;
421 #endif
422 
423 #define time_is_before(_f, _s) (                \
424     ((_f).tv_sec < (_s).tv_sec)                 \
425     || (  (((_f).tv_sec == (_s).tv_sec))        \
426        && (((_f).tv_nsec < (_s).tv_nsec)) )     \
427     )
428 #undef  st_atime
429 #define st_atime st_atim
430 #undef  st_mtime
431 #define st_mtime st_mtim
432 #undef  st_ctime
433 #define st_ctime st_ctim
434 #endif // HAVE_UTIMENSAT
435 
436 /**
437  * The original time autogen started
438  */
439 MODE time_t         start_time       VALUE( 0 );
440 MODE out_stack_t *  cur_fpstack      VALUE( NULL );
441 MODE out_spec_t *   output_specs     VALUE( NULL );
442 MODE jmp_buf        abort_jmp_buf;
443 MODE ivk_info_t     root_ivk_info    VALUE( { 0 } );
444 MODE ivk_info_t *   curr_ivk_info    VALUE( &root_ivk_info );
445 MODE for_state_t *  for_state        VALUE( NULL );
446 MODE FILE *         trace_fp         VALUE( NULL );
447 /**
448  * temporary file name template
449  */
450 MODE char const *   pz_temp_tpl      VALUE( NULL );
451 /**
452  * Length of the template that is the temp directory
453  */
454 MODE size_t         temp_tpl_dir_len VALUE( 0 );
455 /**
456  * dependency file file pointer.
457  */
458 MODE FILE *         dep_fp           VALUE( NULL );
459 /**
460  * name of target of rule
461  */
462 MODE char const *   dep_target       VALUE( NULL );
463 /**
464  * name of dependency file
465  */
466 MODE char const *   dep_file         VALUE( NULL );
467 /**
468  * base name of both source and derived files.
469  * Either "_TList" or "_SList" gets put on the end.
470  */
471 MODE char const *   pz_targ_base     VALUE( NULL );
472 /**
473  * The actual list of input (source) files.
474  */
475 MODE char const *   source_list      VALUE( NULL );
476 MODE size_t         source_size      VALUE( 0 );
477 MODE size_t         source_used      VALUE( 0 );
478 MODE bool           dep_phonies      VALUE( false );
479 MODE char *         cgi_stderr       VALUE( NULL );
480 
481 MODE char const *   server_args[2]   VALUE( { NULL } );
482 MODE char const *   shell_program    VALUE( MK_STR(CONFIG_SHELL) );
483 MODE char const *   libguile_ver     VALUE( NULL );
484 
485 /*
486  *  AutoGen definiton and template context
487  *
488  *  curr_def_ctx is the current, active list of name/value pairs.
489  *  Points to its parent list for full search resolution.
490  *
491  *  current_tpl the template (and DEFINE macro) from which
492  *  the current set of macros is being extracted.
493  *
494  *  These are set in exactly ONE place:
495  *  On entry to the dispatch routine (gen_block).  Two routines, however,
496  *  must restore the values: mFunc_Define and mFunc_For.  They are the only
497  *  routines that dynamically push name/value pairs on the definition stack.
498  */
499 MODE def_ctx_t      curr_def_ctx     VALUE( { NULL } );
500 MODE def_ctx_t      root_def_ctx     VALUE( { NULL } );
501 MODE templ_t *      current_tpl      VALUE( NULL );
502 MODE char const *   last_scm_cmd     VALUE( NULL );
503 
504 /*
505  *  Current Macro
506  *
507  *  This may be set in exactly three places:
508  *  1.  The dispatch routine (gen_block) that steps through
509  *      a list of macros
510  *  2.  mFunc_If may transfer to one of its 'ELIF' or 'ELSE'
511  *      alternation macros
512  *  3.  mFunc_Case may transfer to one of its selection clauses.
513  */
514 MODE macro_t *       cur_macro        VALUE( NULL );
515 MODE tlib_mark_t const magic_marker   VALUE( TEMPLATE_MAGIC_MARKER );
516 
517 /*
518  *  Template Parsing Globals
519  */
520 MODE int            tpl_line         VALUE( 1 );
521 MODE scan_ctx_t *   base_ctx         VALUE( NULL );
522 MODE scan_ctx_t *   cctx             VALUE( NULL );
523 MODE scan_ctx_t *   end_ctx          VALUE( NULL );
524 MODE size_t         end_mac_len      VALUE( 0  );
525 MODE char           end_mac_mark[8]  VALUE( "" );
526 MODE size_t         st_mac_len       VALUE( 0  );
527 MODE char           st_mac_mark[8]   VALUE( "" );
528 MODE out_stack_t    out_root         VALUE({ 0 });
529 
530 #define name_sep_ch '.'
531 
532 /*
533  *  Definition Parsing Globals
534  */
535 MODE char *         token_str        VALUE( NULL );
536 MODE te_dp_event    token_code       VALUE( DP_EV_INVALID );
537 
538 MODE int            ent_stack_depth  VALUE( 0 );
539 MODE int            ent_stack_sz     VALUE( 16 );
540 MODE def_ent_t *    dft_ent_stack[16] VALUE( { 0 } );
541 MODE def_ent_t **   ent_stack        VALUE( dft_ent_stack );
542 MODE def_ent_t *    curr_ent         VALUE( NULL );
543 
544 MODE autogen_exit_code_t ag_exit_code VALUE( AUTOGEN_EXIT_OPTION_ERROR );
545 
546 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
547  *
548  *  IF we have fopencookie or funopen, then we also have our own fmemopen
549  */
550 #ifdef ENABLE_FMEMOPEN
551 extern FILE * ag_fmemopen(void *buf, ssize_t len, char const *mode);
552 extern int    ag_fmemioctl(FILE * fp, int req, ...);
553 #endif
554 
555 typedef union {
556     const void * cp;
557     void *       p;
558 } v2c_t;
559 MODE v2c_t p2p VALUE( { NULL } );
560 
561 #ifdef DEBUG_ENABLED
562 # define AG_ABEND(s)  ag_abend_at(s,__FILE__,__LINE__)
563 #else
564 # define AG_ABEND(s)  ag_abend_at(s)
565 #endif
566 #define  AG_CANT(_op, _wh) \
567     AG_ABEND(aprf(CANNOT_FMT, errno, _op, _wh, strerror(errno)))
568 
569 #ifdef DEBUG_FSM
570 # define DEBUG
571 #else
572 # undef  DEBUG
573 #endif
574 
575 #define AG_ABEND_IN(t,m,s) \
576     STMTS( current_tpl=(t); cur_macro=(m); AG_ABEND(s);)
577 
578 #if __STDC_VERSION__ < 199901L
579 # if __GNUC__ >= 2
580 #  define __func__ __FUNCTION__
581 # else
582 #  define __func__ "<unknown>"
583 # endif
584 #endif
585 
586 /*
587  *  Code variations based on the version of Guile:
588  */
589 #include "guile-iface.h"
590 #include "proto.h"
591 
592 /**
593  * Evaluate a scheme expression, setting the file and line number from
594  * the file and line of the currently active macro.
595  *
596  * @param[in] str  the scheme expression
597  * @returns the SCM result.  That may be SCM_UNDEFINED.
598  */
ag_eval(char const * str)599 static inline SCM ag_eval(char const * str)
600 {
601     SCM res;
602     char const * sv = last_scm_cmd; /* Watch for nested calls */
603     last_scm_cmd = str;
604 
605     res = ag_scm_c_eval_string_from_file_line(
606         str, current_tpl->td_file, cur_macro->md_line);
607 
608     last_scm_cmd = sv;
609     return res;
610 }
611 
612 /**
613  *  Extracted from guile-iface stuff.  Seems to be stable since for at least
614  *  1.6.0 through 2.0.0.  1.4.x is thoroughly dead now (May, 2011).
615  */
616 #define AG_SCM_DISPLAY(_s) \
617     scm_display(_s, scm_current_output_port())
618 
619 #define AG_SCM_BOOT_GUILE(_ac, _av, _im) \
620     scm_boot_guile((_ac), (_av), (_im), NULL)
621 
622 #define AG_SCM_APPLY2(_op, _f, _tst) \
623     scm_apply(_op, _f, scm_cons(_tst, scm_list_1(SCM_EOL)))
624 
625 #define AG_SCM_CHAR_P(_c)            SCM_CHARP(_c)
626 
627 /**
628  * Hide dummy functions from complexity measurement tools
629  */
630 #define HIDE_FN(_t)  _t
631 
632 #endif /* AUTOGEN_BUILD */
633 /** @}
634  *
635  * Local Variables:
636  * mode: C
637  * c-file-style: "stroustrup"
638  * indent-tabs-mode: nil
639  * End:
640  * end of agen5/autogen.h */
641