summaryrefslogtreecommitdiff
path: root/agen5/autogen.h
diff options
context:
space:
mode:
Diffstat (limited to 'agen5/autogen.h')
-rw-r--r--agen5/autogen.h570
1 files changed, 570 insertions, 0 deletions
diff --git a/agen5/autogen.h b/agen5/autogen.h
new file mode 100644
index 0000000..6e4551a
--- /dev/null
+++ b/agen5/autogen.h
@@ -0,0 +1,570 @@
+
+/**
+ * @file autogen.h
+ *
+ * Time-stamp: "2012-04-07 09:45:02 bkorb"
+ *
+ * Global header file for AutoGen
+ *
+ * This file is part of AutoGen.
+ * AutoGen Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
+ *
+ * AutoGen is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AutoGen is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef AUTOGEN_BUILD
+#define AUTOGEN_BUILD 1
+
+#include "compat/unlocked-io.h"
+
+#include REGEX_HEADER
+#include <libguile/scmconfig.h>
+#if GUILE_VERSION < 107000
+# include <guile/gh.h>
+#else
+# include <libguile.h>
+#endif
+
+#include "ag-text.h"
+#include "opts.h"
+#include "expr.h"
+#include "autoopts/autoopts.h"
+#include "directive.h"
+#include "snprintfv/printf.h"
+
+#define LOG10_2to32 10 /* rounded up */
+
+#if defined(SHELL_ENABLED) || defined(DAEMON_ENABLED)
+# ifndef HAVE_WORKING_FORK
+# error SHELL is enabled and fork() does not work
+ choke me
+# endif
+#endif
+
+#ifndef DIRCH
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define DIRCH '\\'
+# else
+# define DIRCH '/'
+# endif
+#endif
+
+#define YYSTYPE t_word
+
+#define ag_offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+
+/*
+ * Dual pipe opening of a child process
+ */
+typedef struct {
+ int fd_read;
+ int fd_write;
+} fd_pair_t;
+
+typedef struct {
+ FILE * fp_read; /* parent read fp */
+ FILE * fp_write; /* parent write fp */
+} fp_pair_t;
+
+#define NOPROCESS ((pid_t)-1)
+#define NULLPROCESS ((pid_t)0)
+#define NL '\n'
+#define TAB '\t'
+
+#include "cgi-fsm.h"
+#include "defParse-fsm.h"
+
+typedef union {
+ unsigned char * pzStr;
+ unsigned char ch;
+} def_token_u_t;
+
+#define STATE_TABLE /* set up `atexit' and load Guile */ \
+ _State_( INIT ) /* processing command line options */ \
+ _State_( OPTIONS ) /* Loading guile at option time */ \
+ _State_( GUILE_PRELOAD ) /* Loading value definitions */ \
+ _State_( LOAD_DEFS ) /* Loading library template */ \
+ _State_( LIB_LOAD ) /* Loading primary template */ \
+ _State_( LOAD_TPL ) /* processing templates */ \
+ _State_( EMITTING ) /* loading an included template */ \
+ _State_( INCLUDING ) /* end of processing before exit() */ \
+ _State_( CLEANUP ) /* Clean up code in error response */ \
+ _State_( ABORTING ) /* `exit' has been called */ \
+ _State_( DONE )
+
+#define _State_(n) PROC_STATE_ ## n,
+typedef enum { STATE_TABLE COUNT_PROC_STATE } proc_state_t;
+#undef _State_
+
+#define EXPORT
+
+typedef struct out_stack out_stack_t;
+typedef struct out_spec out_spec_t;
+typedef struct scan_context scan_ctx_t;
+typedef struct def_entry def_ent_t;
+typedef struct macro_desc macro_t;
+typedef struct template_desc templ_t;
+typedef struct for_state for_state_t;
+typedef struct tlib_mark tlib_mark_t;
+
+#define MAX_SUFFIX_LEN 8 /* maximum length of a file name suffix */
+#define MAX_HEREMARK_LEN 64 /* max length of a here mark */
+#define SCRIBBLE_SIZE 256 /* much larger than any short name */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Template Library Layout
+ *
+ * Procedure for loading a template function
+ */
+typedef macro_t * (load_proc_t)(templ_t*, macro_t*, char const** ppzScan);
+typedef load_proc_t * load_proc_p_t;
+
+typedef void (unload_proc_t)(macro_t*);
+typedef unload_proc_t* unload_proc_p_t;
+
+/*
+ * Procedure for handling a template function
+ * during the text emission phase.
+ */
+typedef macro_t* (hdlr_proc_t)(templ_t*, macro_t*);
+typedef hdlr_proc_t* hdlr_proc_p_t;
+
+/*
+ * This must be included after the function prototypes
+ * (the prototypes are used in the generated tables),
+ * but before the macro descriptor structure (the function
+ * enumeration is generated here).
+ */
+#include "functions.h"
+
+#define TEMPLATE_REVISION 1
+#define TEMPLATE_MAGIC_MARKER {{{'A', 'G', 'L', 'B'}}, \
+ TEMPLATE_REVISION, FUNCTION_CKSUM }
+
+struct tlib_mark {
+ union {
+ unsigned char str[4]; /* {'A', 'G', 'L', 'B'} */
+ unsigned int i[1];
+ } tlm_magic;
+ unsigned short tlm_revision; /* TEMPLATE_REVISION */
+ unsigned short tlm_cksum; /* FUNCTION_CKSUM */
+};
+
+/*
+ * Defines for conditional expressions.
+ * The first four are an enumeration that appear in the
+ * low four bits and the next-to-lowest four bits.
+ * "PRIMARY_TYPE" and "SECONDARY_TYPE" are masks for
+ * extracting this enumeration. The rest are flags.
+ */
+#define EMIT_VALUE 0x0000 /* emit value of variable */
+#define EMIT_EXPRESSION 0x0001 /* Emit Scheme result */
+#define EMIT_SHELL 0x0002 /* emit shell output */
+#define EMIT_STRING 0x0003 /* emit content of expr */
+#define EMIT_PRIMARY_TYPE 0x0007
+#define EMIT_SECONDARY_TYPE 0x0070
+#define EMIT_SECONDARY_SHIFT 4
+#define EMIT_IF_ABSENT 0x0100
+#define EMIT_ALWAYS 0x0200 /* emit one of two exprs */
+#define EMIT_FORMATTED 0x0400 /* format, if val present */
+#define EMIT_NO_DEFINE 0x0800 /* don't get defined value */
+
+struct macro_desc {
+ mac_func_t md_code; /* Macro function */
+ int md_line; /* of macro def */
+ int md_end_idx; /* End of block macro */
+ int md_sib_idx; /* Sibling macro (ELIF or SELECT) */
+
+ uintptr_t md_name_off; /* macro name (sometimes) */
+ uintptr_t md_txt_off; /* associated text */
+ uintptr_t md_res; /* some sort of result */
+ void * md_pvt;
+};
+
+struct template_desc {
+ tlib_mark_t td_magic; /* TEMPLATE_MAGIC_MARKER */
+ size_t td_size; /* Structure Size */
+ char * td_scan; /* Next Pointer */
+ int td_mac_ct; /* Count of Macros */
+ char const * td_file; /* Name of template file */
+ char * td_name; /* Defined Macro Name */
+ char * td_text; /* offset of the text */
+ char td_start_mac[MAX_SUFFIX_LEN];
+ char td_end_mac[ MAX_SUFFIX_LEN];
+ macro_t td_macros[1]; /* Array of Macros */
+/* char td_text[...]; * strings at end of macros */
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Name/Value Definitions Layout
+ */
+typedef enum {
+ VALTYP_UNKNOWN = 0,
+ VALTYP_TEXT,
+ VALTYP_BLOCK
+} val_typ_t;
+
+
+#define NO_INDEX ((short)0x80DEAD)
+
+typedef struct def_ctx def_ctx_t;
+struct def_ctx {
+ def_ent_t * dcx_defent; //!< ptr to current def set
+ def_ctx_t * dcx_prev; //!< ptr to previous def set
+};
+
+typedef union {
+ def_ent_t * dvu_entry;
+ char * dvu_text;
+} def_val_u;
+
+struct def_entry {
+ def_ent_t * de_next; //!< next member of same level
+ def_ent_t * de_twin; //!< next member with same name
+ def_ent_t * de_ptwin; //!< previous memb. of level
+ def_ent_t * de_etwin; //!< head of chain to end ptr
+ char * de_name; //!< name of this member
+ long de_index; //!< index among twins
+ def_val_u de_val; //!< string or list of children
+ char * de_file; //!< definition file name
+ int de_line; //!< def file source line
+ val_typ_t de_type; //!< text/block/not defined yet
+};
+
+struct scan_context {
+ scan_ctx_t * scx_next;
+ char * scx_scan;
+ char const * scx_fname;
+ char * scx_data;
+ int scx_line;
+};
+
+struct out_spec {
+ out_spec_t * os_next;
+ char const * os_file_fmt;
+ bool os_dealloc_fmt;
+ char os_sfx[ 1 ];
+};
+
+/**
+ * Output stack handling flags.
+ */
+#define FPF_FREE 0x0001 /*!< free the fp structure */
+#define FPF_UNLINK 0x0002 /*!< unlink file (temp file) */
+#define FPF_NOUNLINK 0x0004 /*!< do not unlink file */
+#define FPF_STATIC_NM 0x0008 /*!< name statically alloced */
+#define FPF_NOCHMOD 0x0010 /*!< do not chmod(2) file */
+#define FPF_TEMPFILE 0x0020 /*!< the file is a temp */
+
+struct out_stack {
+ int stk_flags;
+ out_stack_t * stk_prev;
+ FILE * stk_fp;
+ char const * stk_fname;
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * FOR loop processing state
+ */
+/**
+ * The current state of each active FOR loop.
+ */
+struct for_state {
+ bool for_loading; //!< the FOR macro is getting ready
+ int for_from; //!< the first index of loop
+ int for_to; //!< the last index of loop
+ int for_by; //!< the loop increment (usually 1)
+ int for_index; //!< the current index
+ char * for_sep_str; //!< inter-iteration string (allocated)
+ char * for_name; //!< name of iterator (not allocated)
+ bool for_islast; //!< true for last iteration
+ bool for_isfirst; //!< true for first iteration
+ jmp_buf for_env; //!< long jump buffer (BREAK, CONTINUE)
+};
+
+typedef enum {
+ LOOP_JMP_OKAY = 0,
+ LOOP_JMP_NEXT = 1,
+ LOOP_JMP_BREAK = 2
+} loop_jmp_type_t;
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Invocation of a defined macro processing state
+ */
+typedef struct ivk_info ivk_info_t;
+struct ivk_info {
+ ivk_info_t * ii_prev; //!< previous layer
+ int ii_depth; //!< Invocation nesting depth
+ jmp_buf ii_env; //!< long jump buffer (RETURN)
+ int ii_for_depth; //!< for depth for this invocation
+ int ii_for_alloc; //!< for state buffer allocation count
+ for_state_t * ii_for_data; //!< array of "for" macro states
+};
+#define IVK_INFO_INITIALIZER(_p) { \
+ .ii_prev = (_p), \
+ .ii_depth = curr_ivk_info->ii_depth + 1, \
+ .ii_for_depth = 0, \
+ .ii_for_alloc = 0, \
+ .ii_for_data = NULL \
+ }
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Parsing stuff
+ */
+#define _MkStr(_s) #_s
+#define MK_STR(_s) _MkStr(_s)
+
+#define SCM_EVAL_CONST(_s) \
+ do { static int const line = __LINE__ - 1; \
+ static char const file[] = __FILE__; \
+ static char const * text = _s; \
+ last_scm_cmd = text; \
+ ag_scm_c_eval_string_from_file_line(text, file, line); \
+ } while (false)
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * GLOBAL VARIABLES
+ *
+ * General Processing Globals
+ */
+#define ag_pname autogenOptions.pzProgName
+MODE proc_state_t processing_state VALUE( PROC_STATE_INIT );
+MODE unsigned int include_depth VALUE( 0 );
+MODE bool defining_macro VALUE( false );
+MODE templ_t * named_tpls VALUE( NULL );
+MODE char const * oops_pfx VALUE( "" );
+/*
+ * "eval_mac_expr" must be able to return a distinct empty string so that
+ * the "CASE" function can distinguish an empty string due to it being a
+ * value from an empty string due to an absent definition.
+ */
+MODE char const no_def_str[1] VALUE( "" );
+
+/*
+ * Template Processing Globals
+ */
+MODE char const * curr_sfx VALUE( NULL );
+/**
+ * The time to set for the modification times of the output files.
+ */
+MODE time_t outfile_time VALUE( 0 );
+/**
+ * The original time autogen started
+ */
+MODE time_t start_time VALUE( 0 );
+MODE out_stack_t * cur_fpstack VALUE( NULL );
+MODE out_spec_t * output_specs VALUE( NULL );
+MODE jmp_buf abort_jmp_buf;
+MODE ivk_info_t root_ivk_info VALUE( { 0 } );
+MODE ivk_info_t * curr_ivk_info VALUE( &root_ivk_info );
+MODE for_state_t * for_state VALUE( NULL );
+MODE FILE * trace_fp VALUE( NULL );
+/**
+ * temporary file name template
+ */
+MODE char const * pz_temp_tpl VALUE( NULL );
+/**
+ * Length of the template that is the temp directory
+ */
+MODE size_t temp_tpl_dir_len VALUE( 0 );
+/**
+ * dependency file file pointer.
+ */
+MODE FILE* dep_fp VALUE( NULL );
+/**
+ * name of target of rule
+ */
+MODE char const * dep_target VALUE( NULL );
+/**
+ * name of dependency file
+ */
+MODE char const * dep_file VALUE( NULL );
+/**
+ * base name of both source and derived files.
+ * Either "_TList" or "_SList" gets put on the end.
+ */
+MODE char const * pz_targ_base VALUE( NULL );
+/**
+ * The actual list of input (source) files.
+ */
+MODE char const * source_list VALUE( NULL );
+MODE size_t source_size VALUE( 0 );
+MODE size_t source_used VALUE( 0 );
+MODE bool dep_phonies VALUE( false );
+MODE char * cgi_stderr VALUE( NULL );
+
+MODE char const * server_args[2] VALUE( { NULL } );
+MODE char const * shell_program VALUE( MK_STR(CONFIG_SHELL) );
+
+/*
+ * AutoGen definiton and template context
+ *
+ * curr_def_ctx is the current, active list of name/value pairs.
+ * Points to its parent list for full search resolution.
+ *
+ * current_tpl the template (and DEFINE macro) from which
+ * the current set of macros is being extracted.
+ *
+ * These are set in exactly ONE place:
+ * On entry to the dispatch routine (gen_block). Two routines, however,
+ * must restore the values: mFunc_Define and mFunc_For. They are the only
+ * routines that dynamically push name/value pairs on the definition stack.
+ */
+MODE def_ctx_t curr_def_ctx VALUE( { NULL } );
+MODE def_ctx_t root_def_ctx VALUE( { NULL } );
+MODE templ_t * current_tpl VALUE( NULL );
+MODE char const * last_scm_cmd VALUE( NULL );
+#ifdef DAEMON_ENABLED
+/*
+ * When operating as a daemon, autogen can be told to reload
+ * its options the next time it wakes up (send it a SIGHUP).
+ */
+MODE bool redo_opts VALUE( true );
+#endif
+
+/*
+ * Current Macro
+ *
+ * This may be set in exactly three places:
+ * 1. The dispatch routine (gen_block) that steps through
+ * a list of macros
+ * 2. mFunc_If may transfer to one of its 'ELIF' or 'ELSE'
+ * alternation macros
+ * 3. mFunc_Case may transfer to one of its selection clauses.
+ */
+MODE macro_t * cur_macro VALUE( NULL );
+MODE tlib_mark_t const magic_marker VALUE( TEMPLATE_MAGIC_MARKER );
+
+/*
+ * Template Parsing Globals
+ */
+MODE int tpl_line VALUE( 1 );
+MODE scan_ctx_t * base_ctx VALUE( NULL );
+MODE scan_ctx_t * cctx VALUE( NULL );
+MODE scan_ctx_t * end_ctx VALUE( NULL );
+MODE size_t end_mac_len VALUE( 0 );
+MODE char end_mac_mark[8] VALUE( "" );
+MODE size_t st_mac_len VALUE( 0 );
+MODE char st_mac_mark[8] VALUE( "" );
+MODE out_stack_t out_root VALUE({ 0 });
+
+#define name_sep_ch '.'
+
+/*
+ * Definition Parsing Globals
+ */
+MODE char * token_str VALUE( NULL );
+MODE te_dp_event token_code VALUE( DP_EV_INVALID );
+
+MODE int ent_stack_depth VALUE( 0 );
+MODE int ent_stack_sz VALUE( 16 );
+MODE def_ent_t * dft_ent_stack[16] VALUE( { 0 } );
+MODE def_ent_t ** ent_stack VALUE( dft_ent_stack );
+MODE def_ent_t * curr_ent VALUE( NULL );
+
+MODE autogen_exit_code_t exit_code VALUE( AUTOGEN_EXIT_OPTION_ERROR );
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * IF we have fopencookie or funopen, then we also have our own fmemopen
+ */
+#ifdef ENABLE_FMEMOPEN
+extern FILE * ag_fmemopen(void *buf, ssize_t len, char const *mode);
+extern int ag_fmemioctl(FILE * fp, int req, ...);
+#endif
+
+typedef union {
+ const void* cp;
+ void* p;
+} v2c_t;
+MODE v2c_t p2p VALUE( { NULL } );
+
+#ifdef DEBUG_ENABLED
+# define AG_ABEND(s) ag_abend_at(s,__FILE__,__LINE__)
+#else
+# define AG_ABEND(s) ag_abend_at(s)
+#endif
+#define AG_CANT(_op, _wh) \
+ AG_ABEND(aprf(CANNOT_FMT, errno, _op, _wh, strerror(errno)))
+
+#ifdef DEBUG_FSM
+# define DEBUG
+#else
+# undef DEBUG
+#endif
+
+#define AG_ABEND_IN(t,m,s) \
+ STMTS( current_tpl=(t); cur_macro=(m); AG_ABEND(s);)
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ "<unknown>"
+# endif
+#endif
+
+/*
+ * Code variations based on the version of Guile:
+ */
+#include "guile-iface.h"
+
+#include "proto.h"
+
+static inline SCM ag_eval(char const * pzStr)
+{
+ SCM res;
+ char const * pzSaveScheme = last_scm_cmd; /* Watch for nested calls */
+ last_scm_cmd = pzStr;
+
+ res = ag_scm_c_eval_string_from_file_line(
+ pzStr, current_tpl->td_file, cur_macro->md_line);
+
+ last_scm_cmd = pzSaveScheme;
+ return res;
+}
+
+/*
+ * Extracted from guile-iface stuff. Seems to be stable since for at least
+ * 1.6.0 through 2.0.0. 1.4.x is thoroughly dead now (May, 2011).
+ */
+#define AG_SCM_DISPLAY(_s) \
+ scm_display(_s, scm_current_output_port())
+
+#define AG_SCM_BOOT_GUILE(_ac, _av, _im) \
+ scm_boot_guile((_ac), (_av), (_im), NULL)
+
+#define AG_SCM_APPLY2(_op, _f, _tst) \
+ scm_apply(_op, _f, scm_cons(_tst, AG_SCM_LISTOFNULL()))
+
+#define AG_SCM_CHAR_P(_c) SCM_CHARP(_c)
+
+/*
+ * Hide dummy functions from complexity measurement tools
+ */
+#define HIDE_FN(_t) _t
+
+#endif /* AUTOGEN_BUILD */
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of agen5/autogen.h */