Added debugging option --preproc-level=NUM.
val = val?val:"";
str = (char*)flex_alloc(strlen(fmt) + strlen(def) + strlen(val) + 2);
-
+
sprintf(str, fmt, def, val);
- buf_append(buf, str, 1);
+ buf_append(buf, &str, 1);
}
/* create buf with 0 elements, each of size elem_size. */
return true;
}
+/** Truncate the chain to max_len number of filters.
+ * @param chain the current chain.
+ * @param max_len the maximum length of the chain.
+ * @return the resulting length of the chain.
+ */
+int filter_truncate (struct filter *chain, int max_len)
+{
+ int len = 1;
+
+ if (!chain)
+ return 0;
+
+ while (chain->next && len < max_len) {
+ chain = chain->next;
+ ++len;
+ }
+
+ chain->next = NULL;
+ return len;
+}
+
/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */
%# Macros for runtime processing stage.
m4_changecom
+m4_changequote
m4_changequote([[, ]])
%#
%# For use in function definitions to append the additional argument.
m4_ifdef( [[M4_YY_TRADITIONAL_FUNC_DEFS]],
+[[
m4_define( [[YY_DEF_LAST_ARG]], [[, yyscanner]])
m4_define( [[YY_DEF_ONLY_ARG]], [[yyscanner]])
-,
+]],
+[[
m4_define( [[YY_DEF_LAST_ARG]], [[, yyscan_t yyscanner]])
m4_define( [[YY_DEF_ONLY_ARG]], [[yyscan_t yyscanner]])
-)
+]])
m4_define( [[YY_DECL_LAST_ARG]], [[yyscan_t yyscanner;]])
%# For use in function calls to pass the additional argument.
m4_define( [[YY_DEF_LAST_ARG]])
m4_ifdef( [[M4_YY_TRADITIONAL_FUNC_DEFS]],
+[[
m4_define( [[YY_DEF_ONLY_ARG]])
-,
+]],
+[[
m4_define( [[YY_DEF_ONLY_ARG]], [[void]])
-)
+]])
m4_define([[YY_DECL_LAST_ARG]])
m4_define([[YY_CALL_LAST_ARG]])
m4_define([[YY_CALL_ONLY_ARG]])
* yyscan_t yyscanner;
*/
m4_ifdef( [[YY_TRADITIONAL_FUNC_DEFS]],
+[[
%# Generate traditional function defs
#define YYFARGS0(v) (YY_DEF_ONLY_ARG) YY_DECL_LAST_ARG
#define YYFARGS1(t1,n1) (n1 YY_DEF_LAST_ARG) t1 n1; YY_DECL_LAST_ARG
#define YYFARGS2(t1,n1,t2,n2) (n1,n2 YY_DEF_LAST_ARG) t1 n1; t2 n2; YY_DECL_LAST_ARG
#define YYFARGS3(t1,n1,t2,n2,t3,n3) (n1,n2,n3 YY_DEF_LAST_ARG) t1 n1; t2 n2; t3 n3; YY_DECL_LAST_ARG
-,
+]],
+[[
%# Generate C99 function defs.
m4_define( [[YYFARGS0]], [[(YY_DEF_ONLY_ARG)]])
m4_define( [[YYFARGS1]], [[($1 $2 YY_DEF_LAST_ARG)]])
m4_define( [[YYFARGS2]], [[($1 $2, $3 $4 YY_DEF_LAST_ARG)]])
m4_define( [[YYFARGS3]], [[($1 $2, $3 $4, $5 $6 YY_DEF_LAST_ARG)]])
-)
+]])
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
%if-c-only
-#if YY_STACK_USED
+%# TODO: This is messy.
+m4_ifdef( [[M4_YY_STACK_USED]],
+[[
%if-not-reentrant
%not-for-header
static int yy_start_stack_ptr = 0;
static int yy_top_state YY_PARAMS(( YY_PROTO_ONLY_ARG ));
]])
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
+]],
+[[
+m4_define( [[M4_YY_NO_PUSH_STATE]])
+m4_define( [[M4_YY_NO_POP_STATE]])
+m4_define( [[M4_YY_NO_TOP_STATE]])
+]])
%endif
/* Amount of stuff to slurp up with each read. */
m4_ifdef( [[M4_YY_USES_REJECT]],
[[
yy_state_buf = new yy_state_type[YY_BUF_SIZE + 2];
-,
+]],
+[[
yy_state_buf = 0;
]])
}
[[
YY_FATAL_ERROR(
"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-,
-
+]],
+[[
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
yyfree(YY_G(yy_buffer_stack) YY_CALL_LAST_ARG);
YY_G(yy_buffer_stack) = NULL;
-#if defined(YY_STACK_USED) || defined(YY_REENTRANT)
+%# This is the m4 way to say "if (stack_used || is_reentrant){ destroy_stack }"
+m4_ifdef( [[M4_YY_STACK_USED]], [[m4_define([[M4_YY_DESTROY_START_STACK]])]])
+m4_ifdef( [[M4_YY_REENTRANT]], [[m4_define([[M4_YY_DESTROY_START_STACK]])]])
+m4_ifdef( [[M4_YY_DESTROY_START_STACK]],
+[[
/* Destroy the start condition stack. */
yyfree( YY_G(yy_start_stack) YY_CALL_LAST_ARG );
YY_G(yy_start_stack) = NULL;
-#endif
+]])
m4_ifdef( [[M4_YY_USES_REJECT]],
[[
extern void out_str_dec PROTO ((const char *, const char *, int));
extern void outc PROTO ((int));
extern void outn PROTO ((const char *));
+extern void out_m4_define (const char* def, const char* val);
/* Return a printable version of the given character, which might be
* 8-bit.
* not including argv[0].
* @return newest filter in chain
*/
-struct filter *filter_create PROTO((struct filter * chain, const char *cmd, ...));
+extern struct filter *filter_create PROTO((struct filter * chain, const char *cmd, ...));
/* Fork and exec entire filter chain.
* @param chain The head of the chain.
* @return true on success.
*/
-bool filter_apply_chain PROTO((struct filter * chain));
+extern bool filter_apply_chain PROTO((struct filter * chain));
+extern int filter_truncate (struct filter * chain, int max_len);
#endif /* not defined FLEXDEF_H */
static int outfile_created = 0;
static char *skelname = NULL;
+/* For debugging. The max number of filters to apply to skeleton. */
+static int preproc_level = 1000;
+
int flex_main PROTO ((int argc, char *argv[]));
int main PROTO ((int argc, char *argv[]));
void fix_line_dirs PROTO ((char *, char *, char *, int));
/* Setup the filter chain. */
output_chain = filter_create(NULL,"m4","-P",0);
/* filter_create(output_chain,"cat",0); */
- filter_apply_chain(output_chain);
+
+ /* For debugging, only run the requested number of filters. */
+ if (preproc_level > 0) {
+ filter_truncate(output_chain, preproc_level);
+ filter_apply_chain(output_chain);
+ }
yyout = stdout;
-
+
/* always generate the tablesverify flag. */
buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0");
/* Dump the m4 definitions. */
buf_print_strings(&m4defs_buf, stdout);
+ m4defs_buf.nelts = 0; /* memory leak here. */
/* Dump the user defined preproc directives. */
if (userdef_buf.elts)
"YY_RULE_SETUP",
"YY_SC_TO_UI",
"YY_SKIP_YYWRAP",
- "YY_STACK_USED",
"YY_START",
"YY_START_STACK_INCR",
"YY_STATE_EOF",
buf_init (&userdef_buf, sizeof (char)); /* one long string */
buf_init (&defs_buf, sizeof (char *)); /* list of strings */
buf_init (&yydmap_buf, sizeof (char)); /* one long string */
- buf_init (&m4defs_buf, sizeof (char *)); /* list of strings */
+
+ {
+ const char * m4defs_init_str[] = {"m4_changequote\n",
+ "m4_changequote([[, ]])\n"};
+ buf_init (&m4defs_buf, sizeof (char *));
+ buf_append (&m4defs_buf, &m4defs_init_str, 2);
+ }
/* Enable C++ if program name ends with '+'. */
posix_compat = true;
break;
+ case OPT_PREPROC_LEVEL:
+ preproc_level = strtol(arg,NULL,0);
+ break;
+
case OPT_MAIN:
buf_strdefine (&userdef_buf, "YY_MAIN", "1");
do_yywrap = false;
break;
case OPT_STACK:
- buf_strdefine (&userdef_buf, "YY_STACK_USED", "1");
+ //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1");
+ buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0);
break;
case OPT_STDINIT:
}
if (reject){
- buf_m4_define( &m4defs_buf, "M4_YY_USES_REJECT", NULL);
+ out_m4_define( "M4_YY_USES_REJECT", NULL);
//outn ("\n#define YY_USES_REJECT");
}
++out_linenum;
}
+/** Print "m4_define( [[def]], [[val]])m4_dnl\n".
+ * @param def The m4 symbol to define.
+ * @param val The definition; may be NULL.
+ * @return buf
+ */
+void out_m4_define (const char* def, const char* val)
+{
+ const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n";
+ fprintf(stdout, fmt, def, val?val:"");
+}
+
/* readable_form - return the the human-readable form of a character
*
,
{"--posix-compat", OPT_POSIX_COMPAT, 0}
, /* Maximal compatibility with POSIX lex. */
+ {"--preproc=NUM", OPT_PREPROC_LEVEL, 0}
+ ,
{"-L", OPT_NO_LINE, 0}
, /* Suppress #line directives in scanner. */
{"--noline", OPT_NO_LINE, 0}
OPT_POINTER,
OPT_PREFIX,
OPT_PREPROCDEFINE,
+ OPT_PREPROC_LEVEL,
OPT_READ,
OPT_REENTRANT,
OPT_REJECT,
read use_read = option_sense;
reentrant reentrant = option_sense;
reject reject_really_used = option_sense;
- stack action_define( "YY_STACK_USED", option_sense );
+ stack ACTION_M4_IFDEF( "M4_YY_STACK_USED", option_sense );
stdinit do_stdinit = option_sense;
stdout use_stdout = option_sense;
unistd ACTION_IFDEF("YY_NO_UNISTD_H", ! option_sense);
if(yytables_fload(fp YY_CALL_LAST_ARG) < 0)
yy_fatal_error("yytables_fload returned < 0" YY_CALL_LAST_ARG);
- if(YY_TABLES_VERIFY)
+ if(M4_YY_TABLES_VERIFY)
exit(0);
#endif