diff options
author | John Millaway <john43@users.sourceforge.net> | 2003-03-27 18:02:58 +0000 |
---|---|---|
committer | John Millaway <john43@users.sourceforge.net> | 2003-03-27 18:02:58 +0000 |
commit | 17551916f3f63d31562c1c6c15ea8749b4a9279b (patch) | |
tree | e815f489a1aa347b4f19acfaafbde5f3bb75a61b | |
parent | 6fe6068dee3020caf4bd93c2c7d71c675df3201d (diff) |
Added %top block syntax.
Added test for %top block.
Documented %top block.
-rw-r--r-- | buf.c | 39 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | doc/flex.texi | 23 | ||||
-rw-r--r-- | flexdef.h | 17 | ||||
-rw-r--r-- | main.c | 10 | ||||
-rw-r--r-- | scan.l | 43 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/descriptions | 1 | ||||
-rw-r--r-- | tests/test-top/.cvsignore | 6 | ||||
-rw-r--r-- | tests/test-top/Makefile.am | 54 | ||||
-rw-r--r-- | tests/test-top/main.c | 63 | ||||
-rw-r--r-- | tests/test-top/scanner.l | 53 | ||||
-rw-r--r-- | tests/test-top/test.input | 3 |
13 files changed, 298 insertions, 17 deletions
@@ -33,11 +33,24 @@ #include "flexdef.h" +/* Take note: The buffer object is sometimes used as a String buffer (one + * continuous string), and sometimes used as a list of strings, usually line by + * line. + * + * The type is specified in buf_init by the elt_size. If the elt_size is + * sizeof(char), then the buffer should be treated as string buffer. If the + * elt_size is sizeof(char*), then the buffer should be treated as a list of + * strings. + * + * Certain functions are only appropriate for one type or the other. + */ + /* global buffers. */ -struct Buf userdef_buf; /* for user #definitions triggered by cmd-line. */ -struct Buf defs_buf; /* for #define's autogenerated. List of strings. */ -struct Buf yydmap_buf; /* string buffer to hold yydmap elements */ -struct Buf m4defs_buf; /**< Holds m4 definitions. List of strings. */ +struct Buf userdef_buf; /**< for user #definitions triggered by cmd-line. */ +struct Buf defs_buf; /**< for #define's autogenerated. List of strings. */ +struct Buf yydmap_buf; /**< string buffer to hold yydmap elements */ +struct Buf m4defs_buf; /**< m4 definitions. List of strings. */ +struct Buf top_buf; /**< contains %top code. String buffer. */ struct Buf *buf_print_strings(struct Buf * buf, FILE* out) { @@ -66,6 +79,24 @@ struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s) return buf; } +/** Append a line directive to the string buffer. + * @param buf A string buffer. + * @param filename file name + * @param lineno line number + * @return buf + */ +struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno) +{ + char *t, *fmt = "#line %d \"%s\"\n"; + + t = flex_alloc (strlen (fmt) + strlen (filename) + (int)(1 + log(lineno>=0?lineno:-lineno)/log(10)) + 1); + sprintf (t, fmt, lineno, filename); + buf = buf_strappend (buf, t); + flex_free (t); + return buf; +} + + /** Append the contents of @a src to @a dest. * @param @a dest the destination buffer * @param @a dest the source buffer diff --git a/configure.in b/configure.in index 63ce572..768ede9 100644 --- a/configure.in +++ b/configure.in @@ -126,6 +126,7 @@ tests/test-c++-basic/Makefile tests/test-bison-nr/Makefile tests/test-reject/Makefile tests/test-c++-multiple-scanners/Makefile +tests/test-top/Makefile dnl --new-test-here-- This line is processed by tests/create-test. ) diff --git a/doc/flex.texi b/doc/flex.texi index f299338..64d9767 100644 --- a/doc/flex.texi +++ b/doc/flex.texi @@ -531,6 +531,29 @@ is also copied verbatim to the output (with the %@{ and %@} symbols removed). The %@{ and %@} symbols must appear unindented on lines by themselves. +@cindex %top + +A @code{%top} block is similar to a @samp{%@{} ... @samp{%@}} block, except +that the code in a @code{%top} block is relocated to the @emph{top} of the +generated file, before any flex definitions @footnote{Actually, +@code{yyIN_HEADER} is defined before the @samp{%top} block.}. +The @code{%top} block is useful when you want certain preprocessor macros to be +defined or certain files to be included before the generated code. +The single characters, @samp{@{} and @samp{@}} are used to delimit the +@code{%top} block, as show in the example below: + +@example +@verbatim + %top{ + /* This code goes at the "top" of the generated file. */ + #include <stdint.h> + #include <inttypes.h> + } +@end verbatim +@end example + +Multiple @code{%top} blocks are allowed, and their order is preserved. + @node Rules Section, User Code Section, Definitions Section, Format @section Format of the Rules Section @@ -1094,18 +1094,13 @@ extern struct Buf *buf_prints PROTO((struct Buf *buf, const char *fmt, const cha extern struct Buf *buf_m4_define PROTO((struct Buf *buf, const char* def, const char* val)); extern struct Buf *buf_m4_undefine PROTO((struct Buf *buf, const char* def)); extern struct Buf *buf_print_strings PROTO((struct Buf * buf, FILE* out)); +extern struct Buf *buf_linedir PROTO((struct Buf *buf, const char* filename, int lineno)); -/* a string buffer for #define's generated by user-options on cmd line. */ -extern struct Buf userdef_buf; - -/* a char* buffer to save #define'd some symbols generated by flex. */ -extern struct Buf defs_buf; - -/* a string buffer to hold yydmap elements */ -extern struct Buf yydmap_buf; - -/* Holds m4 definitions. */ -extern struct Buf m4defs_buf; +extern struct Buf userdef_buf; /* a string buffer for #define's generated by user-options on cmd line. */ +extern struct Buf defs_buf; /* a char* buffer to save #define'd some symbols generated by flex. */ +extern struct Buf yydmap_buf; /* a string buffer to hold yydmap elements */ +extern struct Buf m4defs_buf; /* Holds m4 definitions. */ +extern struct Buf top_buf; /* contains %top code. String buffer. */ /* For blocking out code from the header file. */ #define OUT_BEGIN_CODE() outn("m4_ifdef( [[M4_YY_IN_HEADER]],,[[") @@ -441,9 +441,18 @@ void check_options () buf_destroy(&tmpbuf); } + /* This is where we begin writing to the file. */ + + /* Dump the %top code. */ + if( top_buf.elts) + outn((char*) top_buf.elts); + /* Dump the m4 definitions. */ buf_print_strings(&m4defs_buf, stdout); m4defs_buf.nelts = 0; /* memory leak here. */ + + /* Place a bogus line directive, it will be fixed in the filter. */ + outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); /* Dump the user defined preproc directives. */ if (userdef_buf.elts) @@ -935,6 +944,7 @@ void flexinit (argc, argv) 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 (&top_buf, sizeof (char)); /* one long string */ { const char * m4defs_init_str[] = {"m4_changequote\n", @@ -95,7 +95,7 @@ extern bool tablesverify, tablesext; %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION -%x OPTION LINEDIR +%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE WS [[:blank:]]+ OPTWS [[:blank:]]* @@ -122,7 +122,7 @@ LEXOPT [aceknopr] static int option_sense; int doing_codeblock = false; - int i; + int i, brace_depth=0, brace_start_line=0; Char nmdef[MAXLINE]; @@ -138,6 +138,15 @@ LEXOPT [aceknopr] indented_code = false; BEGIN(CODEBLOCK); } + ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL} { + brace_start_line = linenum; + ++linenum; + buf_linedir( &top_buf, infilename?infilename:"<stdin>", linenum); + brace_depth = 1; + yy_push_state(CODEBLOCK_MATCH_BRACE); + } + + ^"%top".* synerr( _("malformed '%top' directive") ); {WS} /* discard */ @@ -214,6 +223,36 @@ LEXOPT [aceknopr] } } +<CODEBLOCK_MATCH_BRACE>{ + "}" { + if( --brace_depth == 0){ + /* TODO: Matched. */ + yy_pop_state(); + }else + buf_strnappend(&top_buf, yytext, yyleng); + } + + "{" { + brace_depth++; + buf_strnappend(&top_buf, yytext, yyleng); + } + + {NL} { + ++linenum; + buf_strnappend(&top_buf, yytext, yyleng); + } + + [^{}\r\n]+ { + buf_strnappend(&top_buf, yytext, yyleng); + } + + <<EOF>> { + linenum = brace_start_line; + synerr(_("Unmatched '{'")); + yyterminate(); + } +} + <PICKUPDEF>{ {WS} /* separates name and definition */ diff --git a/tests/Makefile.am b/tests/Makefile.am index b5c96c3..f3b78ef 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -48,6 +48,7 @@ DIST_SUBDIRS = \ test-lineno-nr \ test-linedir-r \ TEMPLATE \ + test-top \ test-array-nr \ test-array-r \ test-c-cpp-nr \ @@ -102,6 +103,7 @@ SUBDIRS = \ test-yyextra \ test-noansi-nr \ test-noansi-r \ + test-top \ test-table-opts # clean up before running the test suite so we dont test old builds of test code diff --git a/tests/descriptions b/tests/descriptions index 4b45b74..6dc76c4 100644 --- a/tests/descriptions +++ b/tests/descriptions @@ -37,4 +37,5 @@ reject - Check REJECT code. string-nr - Scan strings, non-reentrant. string-r - Scan strings, reentrant. table-opts - Try every table compression option. +top - Test %top directive. yyextra - Test yyextra. diff --git a/tests/test-top/.cvsignore b/tests/test-top/.cvsignore new file mode 100644 index 0000000..b095dd2 --- /dev/null +++ b/tests/test-top/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +scanner.c +scanner.h +test-top +OUTPUT diff --git a/tests/test-top/Makefile.am b/tests/test-top/Makefile.am new file mode 100644 index 0000000..51e6d6b --- /dev/null +++ b/tests/test-top/Makefile.am @@ -0,0 +1,54 @@ +# This file is part of flex. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: + +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE. + + +FLEX = $(top_builddir)/flex + +builddir = @builddir@ + +EXTRA_DIST = scanner.l test.input main.c +CLEANFILES = scanner.c scanner.h test-top OUTPUT $(OBJS) +OBJS = scanner.o main.o + +AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_builddir) -I$(builddir) +#LDFLAGS = $(top_srcdir)/libfl.a +LFLAGS = --header="scanner.h" +#YFLAGS = --defines --output=parser.c + +testname = test-top + +scanner.c: $(srcdir)/scanner.l + $(FLEX) $(LFLAGS) $< + +parser.c: $(srcdir)/parser.y + $(BISON) $(YFLAGS) $< + +$(testname)$(EXEEXT): $(OBJS) + $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LOADLIBES) + +test: $(testname)$(EXEEXT) + ./$(testname)$(EXEEXT) < $(srcdir)/test.input + +.c.o: + $(CC) -c -o $@ $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $< + +scanner.h: scanner.c +main.o: scanner.h diff --git a/tests/test-top/main.c b/tests/test-top/main.c new file mode 100644 index 0000000..353a63e --- /dev/null +++ b/tests/test-top/main.c @@ -0,0 +1,63 @@ +/* + * This file is part of flex. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include "scanner.h" + +/* The scanner itself is not important here. + * We simply try to use all the functions that are exported in the + * header, to see if we get any compiler warnings. + */ +int +main ( int argc, char** argv ) +{ + yyscan_t scanner; + FILE *fp; + char * extra = "EXTRA"; + + testlex_init(&scanner); + testset_in(stdin,scanner); + testset_out(stdout,scanner); + testset_extra(extra,scanner); + + fp = testget_in(scanner); + fp = testget_out(scanner); + + while(testlex(scanner)) { + char * text; + int line; + line = testget_lineno(scanner); + text = testget_text(scanner); + + if( (char*)testget_extra(scanner) != extra) + break; + + if ( !text || line < 0) + continue; + } + testlex_destroy(scanner); + printf("TEST RETURNING OK.\n"); + return 0; +} + + +/* vim:set tabstop=8 softtabstop=4 shiftwidth=4: */ diff --git a/tests/test-top/scanner.l b/tests/test-top/scanner.l new file mode 100644 index 0000000..be329b0 --- /dev/null +++ b/tests/test-top/scanner.l @@ -0,0 +1,53 @@ +/* + * This file is part of flex. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +%{ +/* Build "scanner.c". + The scanner is not important. + This test is really about compilation. See "main.c". +*/ +#include <stdio.h> +#include <stdlib.h> +#include "config.h" + +#ifndef DEFINE_ME +#error "DEFINE_ME undefined!" +#endif +%} + +%top{ +#define DEFINE_ME 1 +} + +%option reentrant +%option 8bit outfile="scanner.c" prefix="test" +%option nounput nomain noyywrap +%option warn + + +%% + +.|\n { } + +%% + diff --git a/tests/test-top/test.input b/tests/test-top/test.input new file mode 100644 index 0000000..2ce5001 --- /dev/null +++ b/tests/test-top/test.input @@ -0,0 +1,3 @@ +Any input is ok for this scanner. +We only care if it links. + |