]> granicus.if.org Git - flex/commitdiff
Use YY_CHAR macro instead of `char` type in places where processed text is stored
authorMariusz Pluciński <mplucinski@mplucinski.com>
Fri, 25 Jul 2014 13:35:36 +0000 (15:35 +0200)
committerWill Estes <westes575@gmail.com>
Mon, 1 Dec 2014 00:18:21 +0000 (19:18 -0500)
29 files changed:
src/FlexLexer.h
src/flex.skl
src/flexdef.h
src/gen.c
src/main.c
src/parse.y
src/scan.l
tests/bison_nr_main.c
tests/bison_nr_parser.y
tests/bison_nr_scanner.l
tests/bison_yylloc_main.c
tests/bison_yylloc_parser.y
tests/bison_yylloc_scanner.l
tests/bison_yylval_main.c
tests/bison_yylval_parser.y
tests/bison_yylval_scanner.l
tests/cxx_multiple_scanners_main.cc
tests/header_r_main.c
tests/include_by_buffer.direct.l
tests/include_by_push.direct.l
tests/include_by_reentrant.direct.l
tests/prefix_nr.l
tests/prefix_r.l
tests/string_nr.l
tests/string_r.l
tests/strutils.h [new file with mode: 0644]
tests/test-tests_strutils/Makefile.am [new file with mode: 0644]
tests/test-tests_strutils/test_strutils.c [new file with mode: 0644]
tests/top_main.c

index bad4ce03fb65bdcec983d91b7de3fa1265515170..ccda8ae58d2838d853518ed2c89e19276f479d81 100644 (file)
 #    define FLEX_STD std::
 #  endif
 
+#ifndef YY_CHAR_DEFINED
+#define YY_CHAR_DEFINED
+typedef unsigned char YY_CHAR;
+#endif
+
 extern "C++" {
 
 struct yy_buffer_state;
@@ -62,7 +67,7 @@ class FlexLexer {
 public:
        virtual ~FlexLexer()    { }
 
-       const char* YYText() const      { return yytext; }
+       const YY_CHAR* YYText() const   { return yytext; }
        int YYLeng()    const   { return yyleng; }
 
        virtual void
@@ -92,7 +97,7 @@ public:
        void set_debug( int flag )      { yy_flex_debug = flag; }
 
 protected:
-       char* yytext;
+       YY_CHAR* yytext;
        int yyleng;
        int yylineno;           // only maintained if you use %option yylineno
        int yy_flex_debug;      // only has effect with -d or "%option debug"
@@ -134,7 +139,7 @@ protected:
        virtual void LexerOutput( const char* buf, int size );
        virtual void LexerError( const char* msg );
 
-       void yyunput( int c, char* buf_ptr );
+       void yyunput( int c, YY_CHAR* buf_ptr );
        int yyinput();
 
        void yy_load_buffer_state();
@@ -157,13 +162,13 @@ protected:
        FLEX_STD ostream* yyout;        // output sink for default LexerOutput
 
        // yy_hold_char holds the character lost when yytext is formed.
-       char yy_hold_char;
+       YY_CHAR yy_hold_char;
 
        // Number of characters read into yy_ch_buf.
        int yy_n_chars;
 
        // Points to current character in buffer.
-       char* yy_c_buf_p;
+       YY_CHAR* yy_c_buf_p;
 
        int yy_init;            // whether we need to initialize
        int yy_start;           // start state number
@@ -182,12 +187,12 @@ protected:
        // on use of certain flex features (like REJECT or yymore()).
 
        yy_state_type yy_last_accepting_state;
-       char* yy_last_accepting_cpos;
+       YY_CHAR* yy_last_accepting_cpos;
 
        yy_state_type* yy_state_buf;
        yy_state_type* yy_state_ptr;
 
-       char* yy_full_match;
+       YY_CHAR* yy_full_match;
        int* yy_full_state;
        int yy_full_lp;
 
index a1f6db67a9be9297328559348645ba4b6585690b..65f88b438eb048c7cb75b1876ce2e8c5646bdb8f 100644 (file)
@@ -274,7 +274,7 @@ m4_ifdef( [[M4_YY_NO_ANSI_FUNC_PROTOS]],
  * we want to instead treat it as an 8-bit unsigned char, hence the
  * double cast.
  */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((unsigned int) (YY_CHAR)c)
 %ok-for-header
 
 
@@ -513,7 +513,7 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
             }while(0)
     #define YY_LINENO_REWIND_TO(dst) \
             do {\
-                const char *p;\
+                const YY_CHAR *p;\
                 for ( p = yy_cp-1; p >= (dst); --p)\
                     if ( *p == '\n' )\
                         --yylineno;\
@@ -547,6 +547,8 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 #define unput(c) yyunput( c, YY_G(yytext_ptr) M4_YY_CALL_LAST_ARG )
 ]])
 
+%% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here
+
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -560,8 +562,8 @@ struct yy_buffer_state
 %endif
 
 
-       char *yy_ch_buf;                /* input buffer */
-       char *yy_buf_pos;               /* current position in input buffer */
+       YY_CHAR *yy_ch_buf;     /* input buffer */
+       YY_CHAR *yy_buf_pos;    /* current position in input buffer */
 
        /* Size of input buffer in bytes, not including room for EOB
         * characters.
@@ -659,12 +661,12 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 %if-not-reentrant
 %not-for-header
 /* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
+static YY_CHAR yy_hold_char;
 static yy_size_t yy_n_chars;           /* number of characters read into yy_ch_buf */
 yy_size_t yyleng;
 
 /* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
+static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0;
 static int yy_init = 0;                /* whether we need to initialize */
 static int yy_start = 0;       /* start state number */
 
@@ -695,7 +697,7 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER M4_YY_CALL_LAST_ARG)
 ]])
 
-YY_BUFFER_STATE yy_scan_buffer M4_YY_PARAMS( char *base, yy_size_t size M4_YY_PROTO_LAST_ARG );
+YY_BUFFER_STATE yy_scan_buffer M4_YY_PARAMS( YY_CHAR *base, yy_size_t size M4_YY_PROTO_LAST_ARG );
 YY_BUFFER_STATE yy_scan_string M4_YY_PARAMS( yyconst char *yy_str M4_YY_PROTO_LAST_ARG );
 YY_BUFFER_STATE yy_scan_bytes M4_YY_PARAMS( yyconst char *bytes, yy_size_t len M4_YY_PROTO_LAST_ARG );
 
@@ -741,8 +743,6 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 ]])
 
-%% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here
-
 m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 [[
 %% [1.5] DFA
@@ -830,10 +830,10 @@ struct yyguts_t
     size_t yy_buffer_stack_top; /**< index of top of stack. */
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
-    char yy_hold_char;
+    YY_CHAR yy_hold_char;
     yy_size_t yy_n_chars;
     yy_size_t yyleng_r;
-    char *yy_c_buf_p;
+    YY_CHAR *yy_c_buf_p;
     int yy_init;
     int yy_start;
     int yy_did_buffer_switch_on_eof;
@@ -841,7 +841,7 @@ struct yyguts_t
     int yy_start_stack_depth;
     int *yy_start_stack;
     yy_state_type yy_last_accepting_state;
-    char* yy_last_accepting_cpos;
+    YY_CHAR* yy_last_accepting_cpos;
 
     int yylineno_r;
     int yy_flex_debug_r;
@@ -850,7 +850,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
 [[
     yy_state_type *yy_state_buf;
     yy_state_type *yy_state_ptr;
-    char *yy_full_match;
+    YY_CHAR *yy_full_match;
     int yy_lp;
 
     /* These are only needed for trailing context rules,
@@ -862,13 +862,13 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
 
 m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],
 [[
-    char yytext_r[YYLMAX];
-    char *yytext_ptr;
+    YY_CHAR yytext_r[YYLMAX];
+    YY_CHAR *yytext_ptr;
     int yy_more_offset;
     int yy_prev_more_offset;
 ]],
 [[
-    char *yytext_r;
+    YY_CHAR *yytext_r;
     int yy_more_flag;
     int yy_more_len;
 ]])
@@ -974,7 +974,7 @@ yy_size_t yyget_leng M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
 
 m4_ifdef( [[M4_YY_NO_GET_TEXT]],,
 [[
-char *yyget_text M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
+YY_CHAR *yyget_text M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
 ]])
 
 m4_ifdef( [[M4_YY_NO_GET_LINENO]],,
@@ -1048,7 +1048,7 @@ extern int yywrap M4_YY_PARAMS( M4_YY_PROTO_ONLY_ARG );
 %endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy M4_YY_PARAMS( char *, yyconst char *, int M4_YY_PROTO_LAST_ARG);
+static void yy_flex_strncpy M4_YY_PARAMS( YY_CHAR *, yyconst YY_CHAR *, int M4_YY_PROTO_LAST_ARG);
 #endif
 
 #ifdef YY_NEED_STRLEN
@@ -1128,7 +1128,7 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
 %endif
 %if-c++-only C++ definition
-#define ECHO LexerOutput( yytext, yyleng )
+#define ECHO LexerOutput( reinterpret_cast<char*>(yytext), yyleng )
 %endif
 #endif
 ]])
@@ -1287,7 +1287,7 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 YY_DECL
 {
        yy_state_type yy_current_state;
-       char *yy_cp, *yy_bp;
+       YY_CHAR *yy_cp, *yy_bp;
        int yy_act;
     M4_YY_DECL_GUTS_VAR();
 
@@ -1423,7 +1423,7 @@ do_action:        /* This label is used only to access EOF actions. */
                 * end-of-buffer state).  Contrast this with the test
                 * in input().
                 */
-               if ( YY_G(yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] )
+               if ( ((YY_CHAR*)(YY_G(yy_c_buf_p))) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)] )
                        { /* This was really a NUL. */
                        yy_state_type yy_next_state;
 
@@ -1501,8 +1501,9 @@ do_action:        /* This label is used only to access EOF actions. */
                                goto yy_match;
 
                        case EOB_ACT_LAST_MATCH:
-                               YY_G(yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)];
+                               YY_G(yy_c_buf_p) = ((YY_CHAR*)(
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars)]
+                               ));
 
                                yy_current_state = yy_get_previous_state( M4_YY_CALL_ONLY_ARG );
 
@@ -1638,12 +1639,12 @@ int yyFlexLexer::yy_get_next_buffer()
 %endif
 {
     M4_YY_DECL_GUTS_VAR();
-       char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       char *source = YY_G(yytext_ptr);
-       yy_size_t number_to_move, i;
+       YY_CHAR *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       YY_CHAR *source = YY_G(yytext_ptr);
+       int number_to_move, i;
        int ret_val;
 
-       if ( YY_G(yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1] )
+       if ( YY_G(yy_c_buf_p) > ((YY_CHAR*)( &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_G(yy_n_chars) + 1])) )
                YY_FATAL_ERROR(
                "fatal flex scanner internal error--end of buffer missed" );
 
@@ -1697,7 +1698,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
                        YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
                        int yy_c_buf_p_offset =
-                               (int) (YY_G(yy_c_buf_p) - b->yy_ch_buf);
+                               (int) (YY_G(yy_c_buf_p) - ((YY_CHAR*)(b->yy_ch_buf)) );
 
                        if ( b->yy_is_our_buffer )
                                {
@@ -1708,10 +1709,10 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
                                else
                                        b->yy_buf_size *= 2;
 
-                               b->yy_ch_buf = (char *)
+                               b->yy_ch_buf = (YY_CHAR *)
                                        /* Include room in for 2 EOB chars. */
                                        yyrealloc( (void *) b->yy_ch_buf,
-                                                        b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG );
+                                                        (b->yy_buf_size + 2)*sizeof(YY_CHAR) M4_YY_CALL_LAST_ARG );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1760,8 +1761,8 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
        if ((yy_size_t) (YY_G(yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
                /* Extend the array by 50%, plus the number we really need. */
                yy_size_t new_size = YY_G(yy_n_chars) + number_to_move + (YY_G(yy_n_chars) >> 1);
-               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
-                       (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size M4_YY_CALL_LAST_ARG );
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (YY_CHAR *) yyrealloc(
+                       (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size*sizeof(YY_CHAR) M4_YY_CALL_LAST_ARG );
                if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
                        YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
        }
@@ -1787,7 +1788,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
 %endif
 {
        yy_state_type yy_current_state;
-       char *yy_cp;
+       YY_CHAR *yy_cp;
     M4_YY_DECL_GUTS_VAR();
 
 %% [15.0] code to get the start state into yy_current_state goes here
@@ -1826,13 +1827,13 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
 %if-c-only
 m4_ifdef( [[M4_YY_NO_UNPUT]],,
 [[
-    static void yyunput YYFARGS2( int,c, char *,yy_bp)
+    static void yyunput YYFARGS2( int,c, YY_CHAR *,yy_bp)
 %endif
 %if-c++-only
-    void yyFlexLexer::yyunput( int c, char* yy_bp)
+    void yyFlexLexer::yyunput( int c, YY_CHAR* yy_bp)
 %endif
 {
-       char *yy_cp;
+       YY_CHAR *yy_cp;
     M4_YY_DECL_GUTS_VAR();
 
     yy_cp = YY_G(yy_c_buf_p);
@@ -1844,9 +1845,9 @@ m4_ifdef( [[M4_YY_NO_UNPUT]],,
                { /* need to shift things up to make room */
                /* +2 for EOB chars. */
                yy_size_t number_to_move = YY_G(yy_n_chars) + 2;
-               char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+               YY_CHAR *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
                                        YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-               char *source =
+               YY_CHAR *source =
                                &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
 
                while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
@@ -2069,7 +2070,7 @@ static void yy_load_buffer_state  YYFARGS0(void)
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) yyalloc( b->yy_buf_size + 2 M4_YY_CALL_LAST_ARG );
+       b->yy_ch_buf = (YY_CHAR *) yyalloc( (b->yy_buf_size + 2)*sizeof(YY_CHAR) M4_YY_CALL_LAST_ARG );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
@@ -2326,7 +2327,7 @@ m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],,
  * M4_YY_DOC_PARAM
  * @return the newly allocated buffer state object. 
  */
-YY_BUFFER_STATE yy_scan_buffer  YYFARGS2( char *,base, yy_size_t ,size)
+YY_BUFFER_STATE yy_scan_buffer  YYFARGS2( YY_CHAR *,base, yy_size_t ,size)
 {
        YY_BUFFER_STATE b;
     m4_dnl M4_YY_DECL_GUTS_VAR();
@@ -2393,14 +2394,14 @@ m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],,
 YY_BUFFER_STATE yy_scan_bytes  YYFARGS2( yyconst char *,yybytes, yy_size_t ,_yybytes_len)
 {
        YY_BUFFER_STATE b;
-       char *buf;
+       YY_CHAR *buf;
        yy_size_t n;
        yy_size_t i;
     m4_dnl M4_YY_DECL_GUTS_VAR();
 
        /* Get memory for full buffer, including space for trailing EOB's. */
        n = _yybytes_len + 2;
-       buf = (char *) yyalloc( n M4_YY_CALL_LAST_ARG );
+       buf = (YY_CHAR *) yyalloc( n*sizeof(YY_CHAR) M4_YY_CALL_LAST_ARG );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
@@ -2629,7 +2630,7 @@ yy_size_t yyget_leng  YYFARGS0(void)
  */
 m4_ifdef( [[M4_YY_NO_GET_TEXT]],,
 [[
-char *yyget_text  YYFARGS0(void)
+YY_CHAR *yyget_text  YYFARGS0(void)
 {
     M4_YY_DECL_GUTS_VAR();
     return yytext;
@@ -2883,7 +2884,7 @@ m4_ifdef( [[M4_YY_USE_LINENO]],
     YY_G(yy_buffer_stack) = 0;
     YY_G(yy_buffer_stack_top) = 0;
     YY_G(yy_buffer_stack_max) = 0;
-    YY_G(yy_c_buf_p) = (char *) 0;
+    YY_G(yy_c_buf_p) = (YY_CHAR *) 0;
     YY_G(yy_init) = 0;
     YY_G(yy_start) = 0;
 
@@ -2980,7 +2981,7 @@ m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 m4_ifdef( [[M4_YY_NOT_IN_HEADER]],
 [[
 #ifndef yytext_ptr
-static void yy_flex_strncpy YYFARGS3( char*,s1, yyconst char *,s2, int,n)
+static void yy_flex_strncpy YYFARGS3( YY_CHAR*,s1, yyconst YY_CHAR *,s2, int,n)
 {
        M4_YY_DECL_GUTS_VAR();
        M4_YY_NOOP_GUTS_VAR();
index 496e34c7291b6783cbcc503bc1e208983a35d150..506959a047fa19c46a22e7ae95523a1a2312d09a 100644 (file)
@@ -425,6 +425,7 @@ extern int trace_hex;
  * infilename - name of input file
  * outfilename - name of output file
  * headerfilename - name of the .h file to generate
+ * headercharfilename - name of the .h file to fill with character type defintion
  * did_outfilename - whether outfilename was explicitly set
  * prefix - the prefix used for externally visible names ("yy" by default)
  * yyclass - yyFlexLexer subclass to use for YY_DECL
@@ -448,7 +449,7 @@ extern int datapos, dataline, linenum;
 extern FILE *skelfile, *yyin, *backing_up_file;
 extern const char *skel[];
 extern int skel_ind;
-extern char *infilename, *outfilename, *headerfilename;
+extern char *infilename, *outfilename, *headerfilename, *headercharfilename;
 extern int did_outfilename;
 extern char *prefix, *yyclass, *extra_type;
 extern int do_stdinit, use_stdout;
index 049cbfe25c7f859e762d9cbd69b1969b2ea5a3bf..7e67a52d416809baf99205ec853ea021df90075e 100644 (file)
--- a/src/gen.c
+++ b/src/gen.c
@@ -960,7 +960,7 @@ void gen_NUL_trans (void)
                /* We're going to need yy_cp lying around for the call
                 * below to gen_backing_up().
                 */
-               indent_puts ("char *yy_cp = YY_G(yy_c_buf_p);");
+               indent_puts ("YY_CHAR *yy_cp = YY_G(yy_c_buf_p);");
 
        outc ('\n');
 
@@ -1709,7 +1709,7 @@ void make_tables (void)
                        indent_puts
                                ("static yy_state_type yy_last_accepting_state;");
                        indent_puts
-                               ("static char *yy_last_accepting_cpos;\n");
+                               ("static YY_CHAR *yy_last_accepting_cpos;\n");
                }
        }
 
@@ -1781,7 +1781,7 @@ void make_tables (void)
                /* Declare state buffer variables. */
                if (!C_plus_plus && !reentrant) {
                        outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
-                       outn ("static char *yy_full_match;");
+                       outn ("static YY_CHAR *yy_full_match;");
                        outn ("static int yy_lp;");
                }
 
@@ -1876,14 +1876,14 @@ void make_tables (void)
                        outn ("#define YYLMAX 8192");
                        outn ("#endif\n");
                        if (!reentrant){
-                outn ("char yytext[YYLMAX];");
-                outn ("char *yytext_ptr;");
+                outn ("YY_CHAR yytext[YYLMAX];");
+                outn ("YY_CHAR *yytext_ptr;");
             }
                }
 
                else {
                        if(! reentrant)
-                outn ("char *yytext;");
+                outn ("YY_CHAR *yytext;");
                }
        }
 
index 87107022804ce4e38e78fe1efee1d7b864546d8a..befbb3ce45badfadb6f9a97b0f695508c281e5a6 100644 (file)
@@ -64,7 +64,7 @@ int     skel_ind = 0;
 char   *action_array;
 int     action_size, defs1_offset, prolog_offset, action_offset,
        action_index;
-char   *infilename = NULL, *outfilename = NULL, *headerfilename = NULL;
+char   *infilename = NULL, *outfilename = NULL, *headerfilename = NULL, *headercharfilename = NULL;
 int     did_outfilename;
 char   *prefix, *yyclass, *extra_type = NULL;
 int     do_stdinit, use_stdout;
@@ -100,6 +100,7 @@ int     sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
 int     tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
 int     num_backing_up, bol_needed;
 FILE   *backing_up_file;
+FILE   *char_header_file = NULL;
 int     end_of_buffer_state;
 char  **input_files;
 int     num_input_files;
@@ -368,6 +369,42 @@ void check_options ()
     filter_create_ext(output_chain, m4, "-P", 0);
     filter_create_int(output_chain, filter_fix_linedirs, NULL);
 
+    if(headerfilename && !headercharfilename) {
+        char *suffix = ".h";
+        char *basesuffix = "_char";
+        size_t suffix_len = strlen(suffix);
+        size_t basesuffix_len = strlen(basesuffix);
+
+        size_t headerfilename_len = strlen(headerfilename);
+
+        char *p = strstr(headerfilename, suffix);
+        if(p && headerfilename+headerfilename_len-suffix_len == p)
+            headerfilename_len -= suffix_len; /* cut out suffix */
+
+        headercharfilename = malloc(headerfilename_len+basesuffix_len+suffix_len+1);
+        p = headercharfilename;
+
+        strncpy(p, headerfilename, headerfilename_len);
+        p += headerfilename_len;
+
+        strncpy(p, basesuffix, basesuffix_len);
+        p += basesuffix_len;
+
+        strncpy(p, suffix, suffix_len);
+    }
+
+    /* Setup char header file */
+    if(headercharfilename) {
+        char_header_file = fopen(headercharfilename, "w");
+        fprintf(char_header_file, "#pragma once\n");
+        fprintf(char_header_file, "\n");
+        fflush(char_header_file);
+
+        buf_strappend(&userdef_buf, "#include \"");
+        buf_strappend(&userdef_buf, headercharfilename);
+        buf_strappend(&userdef_buf, "\"\n");
+    }
+
     /* For debugging, only run the requested number of filters. */
     if (preproc_level > 0) {
         filter_truncate(output_chain, preproc_level);
@@ -500,6 +537,10 @@ void flexend (exit_status)
        if (++called_before)
                FLEX_EXIT (exit_status);
 
+       if(char_header_file && fclose (char_header_file))
+                       lerrsf (_("error closing char header file %s"),
+                               headercharfilename);
+
        if (skelfile != NULL) {
                if (ferror (skelfile))
                        lerr (_("input error reading skeleton file %s"),
@@ -1461,6 +1502,9 @@ void readin ()
        static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;";
        static char yy_nostdinit[] =
                "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
+       static char character_type_uchar[] = "typedef unsigned char YY_CHAR;";
+       static char character_type_char[] = "typedef char YY_CHAR;";
+       static char character_defined[] = "#define YY_CHAR_DEFINED";
 
        line_directive_out ((FILE *) 0, 1);
 
@@ -1590,10 +1634,22 @@ void readin ()
                outn ("\n#define FLEX_DEBUG");
 
        OUT_BEGIN_CODE ();
-       if (csize == 256)
-               outn ("typedef unsigned char YY_CHAR;");
-       else
-               outn ("typedef char YY_CHAR;");
+       outn("#ifndef YY_CHAR_DEFINED");
+       if (csize == 256) {
+               outn (character_type_uchar);
+               if(char_header_file)
+                       fprintf(char_header_file, "%s\n", character_type_uchar);
+       } else {
+               outn (character_type_char);
+               if(char_header_file)
+                       fprintf(char_header_file, "%s\n", character_type_char);
+       }
+       outn(character_defined);
+       outn("#endif");
+       if(char_header_file) {
+               fprintf(char_header_file, "%s\n", character_defined);
+               fflush(char_header_file);
+       }
        OUT_END_CODE ();
 
        if (C_plus_plus) {
@@ -1678,18 +1734,14 @@ void readin ()
                 */
                if (yytext_is_array) {
                        if (!reentrant)
-                               outn ("extern char yytext[];\n");
+                               outn ("extern YY_CHAR yytext[];\n");
                }
                else {
                        if (reentrant) {
                                outn ("#define yytext_ptr yytext_r");
                        }
                        else {
-                               outn ("extern char *yytext;");
-
-                               outn("#ifdef yytext_ptr");
-                               outn("#undef yytext_ptr");
-                               outn("#endif");
+                               outn ("extern YY_CHAR *yytext;");
                                outn ("#define yytext_ptr yytext");
                        }
                }
index 939cc05c02f06fc6f900f327c5bb56c0d53c9e75..30efb008e828fdadb6704ceef44fe0e08bc199be 100644 (file)
@@ -1,7 +1,7 @@
 /* parse.y - parser for flex input */
 
 %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP
-%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS OPT_HEADER OPT_EXTRA_TYPE
+%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS OPT_HEADER OPT_HEADER_CHAR OPT_EXTRA_TYPE
 %token OPT_TABLES
 
 %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH
@@ -204,6 +204,8 @@ option              :  OPT_OUTFILE '=' NAME
                        { yyclass = copy_string( nmstr ); }
                |  OPT_HEADER '=' NAME
                        { headerfilename = copy_string( nmstr ); }
+               |  OPT_HEADER_CHAR '=' NAME
+                       { headercharfilename = copy_string( nmstr ); }
            |  OPT_TABLES '=' NAME
             { tablesext = true; tablesfilename = copy_string( nmstr ); }
                ;
index 9eb857ac11e7b17a4a8188b690afac30074d9480..6cbefe6d04f76e7a026a6b366c366addae7bf702 100644 (file)
@@ -425,6 +425,7 @@ M4QEND      "]]"
        prefix          return OPT_PREFIX;
        yyclass         return OPT_YYCLASS;
        header(-file)?      return OPT_HEADER;
+       header-char(-file)? return OPT_HEADER_CHAR;
        tables-file         return OPT_TABLES;
        tables-verify   {
                     tablesverify = option_sense;
index f5dd98a943269487b34d71b5171d34b39f6b486a..70555fdbafff236519bcb51937dc7c92e7285e08 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "bison_nr_parser.h"
 #include "bison_nr_scanner.h"
+#include "bison_nr_scanner_char.h"
 
 extern int testparse(void);
 
index 30210489b6ce3434337b57a21471640feb66457e..0f92125af395d82342b3180c8cca82d2652cce18 100644 (file)
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "bison_nr_parser.h"
 #include "bison_nr_scanner.h"
+#include "bison_nr_scanner_char.h"
 
 #define YYERROR_VERBOSE 1
 /* #define YYPARSE_PARAM scanner */
@@ -42,7 +43,7 @@ extern int testget_lineno(void);
 
 
 /* A dummy function. A check against seg-faults in yylval->str. */
-int process_text(char* s) {
+int process_text(YY_CHAR* s) {
     int total =0;
     while(*s) {
         total += (int) *s;
@@ -58,7 +59,7 @@ int process_text(char* s) {
 
 %union  {
     int  lineno;
-    char * str;
+    YY_CHAR * str;
 }
 %token <str> IDENT
 %token <lineno> LINENO
index 4378e5aed30a3e2d5129af480074af1b18c5d63a..4140209ee9840ab16ed3f058e00276f06957c9fb 100644 (file)
@@ -26,8 +26,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "bison_nr_parser.h"
+#include "strutils.h"
 #include "config.h"
-static char* STRDUP(char* s1);
 #define YY_EXTRA_TYPE int
 %}
 
@@ -35,28 +35,23 @@ static char* STRDUP(char* s1);
 %option bison-locations yylineno
 %option prefix="test" header="bison_nr_scanner.h" yylineno
 %option nomain nounput noyy_top_state noyywrap nodefault noinput warn
+%option header-char="bison_nr_scanner_char.h"
 
 
 %%
 
 ^[[:digit:]]+  { 
         yylval->lineno = yylineno;
-        yylloc->first_line = (int)strtol(yytext,NULL,10);
+        yylloc->first_line = (int)yy_utils_strtol(yytext,NULL,10);
         return LINENO;
     }
 ":"  { return COLON; }
 " "  { return SPACE; }
 "="  { return EQUAL; }
-[[:alnum:]_]+ {  yylval->str = STRDUP(yytext); return IDENT;}
+[[:alnum:]_]+ {  yylval->str = yy_utils_strdup(yytext); return IDENT;}
 
 \r|\n { }
 .     { yyterminate();}
 %%
 
 
-static char* STRDUP(char* s1)
-{
-    char* s2 = (char*)malloc(strlen(s1)+1);
-    sprintf(s2,"%s",s1);
-    return s2;
-}
index 0274d397db07bf6bc961b28b1c3401f1425477e1..8650d7b2a0b801bdfc5eaa5a6a33342239a02d56 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "bison_yylloc_parser.h"
 #include "bison_yylloc_scanner.h"
+#include "bison_yylloc_scanner_char.h"
 
 int main ( int argc, char** argv )
 {
index 8737291f583efe0236282d21cd142a5c15105b0d..ad7be93d02d88aaf2f6adc95c263be61d630b535 100644 (file)
@@ -35,6 +35,7 @@
 #include "config.h"
 #include "bison_yylloc_parser.h"
 #include "bison_yylloc_scanner.h"
+#include "bison_yylloc_scanner_char.h"
 
 int yyerror(YYLTYPE *location, void* scanner, const char* msg);
 
@@ -44,7 +45,7 @@ extern int testget_lineno(void*);
 
 
 /* A dummy function. A check against seg-faults in yylval->str. */
-int process_text(char* s) {
+int process_text(YY_CHAR* s) {
     int total =0;
     while(*s) {
         total += (int) *s;
@@ -60,7 +61,7 @@ int process_text(char* s) {
 
 %union  {
     int  lineno;
-    char * str;
+    YY_CHAR * str;
 }
 %token <str> IDENT
 %token <lineno> LINENO
index 3708237553b418310ddaf7c67094dd9b82a2d9e2..f3bf2f16ed65960ec5c317b3b5fea771a356e537 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include "bison_yylloc_parser.h"
 #include "config.h"
-static char* STRDUP(char* s1);
+#include "strutils.h"
 #define YY_EXTRA_TYPE int
 %}
 
@@ -35,6 +35,8 @@ static char* STRDUP(char* s1);
 %option reentrant bison-bridge bison-locations yylineno
 %option header="bison_yylloc_scanner.h"
 %option nomain nounput noyy_top_state noyywrap nodefault noinput warn
+%option nomain nounput noyy_top_state noyywrap nodefault warn
+%option header-char="bison_yylloc_scanner_char.h"
 
 
 %%
@@ -44,22 +46,14 @@ static char* STRDUP(char* s1);
 
 ^[[:digit:]]+  { 
         yylval->lineno = yyextra++;
-        yylloc->first_line = (int)strtol(yytext,NULL,10);
+        yylloc->first_line = (int)yy_utils_strtol(yytext,NULL,10);
         return LINENO;
     }
 ":"  { return COLON; }
 " "  { return SPACE; }
 "="  { return EQUAL; }
-[[:alnum:]_]+ {  yylval->str = STRDUP(yytext); return IDENT;}
+[[:alnum:]_]+ {  yylval->str = yy_utils_strdup(yytext); return IDENT;}
 
 \r|\n { }
 .     { yyterminate();}
 %%
-
-
-static char* STRDUP(char* s1)
-{
-    char* s2 = (char*)malloc(strlen(s1)+1);
-    sprintf(s2,"%s",s1);
-    return s2;
-}
index fb0453816e96a75341f720259e48a0e9c6d0d08b..5221c62ab82190a57dc55f21ffd870b91491d478 100644 (file)
@@ -21,8 +21,9 @@
  * PURPOSE.
  */
 
-#include "bison_yylval_parser.h"
+<<<#include "bison_yylval_parser.h"
 #include "bison_yylval_scanner.h"
+#include "bison_yylval_scanner_char.h"
 
 int main ( int argc, char** argv )
 {
index 4159d7b78235758d5ffd6e413d0f7bc0f466c4bb..43f36c3da05fd5ee80fa6414eb47847d35dd2877 100644 (file)
 #include "config.h"
 #include "bison_yylval_parser.h"
 #include "bison_yylval_scanner.h"
+#include "bison_yylval_scanner_char.h"
 
 #define YYERROR_VERBOSE 1
 
 int yyerror(void* scanner, const char* msg);
 
 /* A dummy function. A check against seg-faults in yylval->str. */
-int process_text(char* s) {
+int process_text(YY_CHAR* s) {
     int total =0;
     while(*s) {
         total += (int) *s;
@@ -56,7 +57,7 @@ int process_text(char* s) {
 
 %union  {
     long unused;
-    char * str;
+    YY_CHAR * str;
 }
 
 %token <str> TAGNAME TEXT
index db99fa0bfd92fff8ec8ce0b22d3a322233e75d62..fdaf51f6f75cd154b0fe2a659c330ea18f4b3b37 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include "bison_yylval_parser.h"
 #include "config.h"
-static char* STRDUP(char* s1);
+#include "strutils.h"
 
 enum yesno_t { no=0, yes=1 };
 #define YY_EXTRA_TYPE  enum yesno_t
@@ -37,6 +37,8 @@ enum yesno_t { no=0, yes=1 };
 %option reentrant bison-bridge
 %option header="bison_yylval_scanner.h"
 %option noyywrap nomain nounput noyy_top_state noyywrap nodefault noinput warn
+%option noyywrap nomain nounput noyy_top_state noyywrap nodefault warn
+%option header-char="bison_yylval_scanner_char.h"
 %option stack
 
 
@@ -52,14 +54,14 @@ enum yesno_t { no=0, yes=1 };
 "</"       { NEED_TAG_NAME= yes; yy_push_state( IN_TAG, yyscanner); return LTSLASH;}
 "<"[^[:alpha:]]  { yy_push_state(DISCARD_THRU_GT,yyscanner); }
 "<"        { NEED_TAG_NAME= yes; yy_push_state( IN_TAG, yyscanner); return  LT; }
-[^<]{1,512} { yyget_lval(yyscanner)->str = STRDUP(yytext); return TEXT;}
+[^<]{1,512} { yyget_lval(yyscanner)->str = yy_utils_strdup(yytext); return TEXT;}
 }
 <IN_TAG>{
 ">"  { yy_pop_state( yyscanner ); return GT; }
 [[:alpha:]][[:alnum:]]* {
         if( NEED_TAG_NAME == yes){
             NEED_TAG_NAME=no;
-            yylval->str = STRDUP(yytext);
+            yylval->str = yy_utils_strdup(yytext);
             return TAGNAME;
         }
     }
@@ -71,11 +73,3 @@ enum yesno_t { no=0, yes=1 };
 ">"        { yy_pop_state(yyscanner);}
 }
 %%
-
-
-static char* STRDUP(char* s1)
-{
-    char* s2 = (char*)malloc(strlen(s1)+1);
-    sprintf(s2,"%s",s1);
-    return s2;
-}
index 08fe2c15fbf7b0cf9f3999b32accbfbe75e45847..52565ec704d77043ec56592961e00903967fe44c 100644 (file)
@@ -38,13 +38,17 @@ main ( int argc, char** argv )
     S1_FlexLexer* S1 = new S1_FlexLexer;
     S2_FlexLexer* S2 = new S2_FlexLexer;
 
-    // scan simultaneously. 
-    while(S1_ok || S2_ok)
-    {
-        if (S1_ok)
-            S1_ok = S1->yylex();
-        if (S2_ok)
-            S2_ok = S2->yylex();
+    while(testlex(scanner)) {
+        YY_CHAR * text;
+        int line;
+        line = testget_lineno(scanner);
+        text = testget_text(scanner);
+        
+        if( (char*)testget_extra(scanner) != extra)
+            break;
+        
+        if ( !text || line < 0)
+            continue;
     }
     printf("TEST RETURNING OK.\n");
     delete S1;
index 22b397dbfce132598878c1098c2d03810dbc9abe..e3f2d5c20934e7e4c1ef2afd5599fcd521d23739 100644 (file)
@@ -50,7 +50,7 @@ main ( int argc, char** argv )
     assert(fp == stdout);
 
     while(testlex(scanner)) {
-        char * text;
+        YY_CHAR * text;
         int line;
         line = testget_lineno(scanner);
         text = testget_text(scanner);
index f3b2d2a723f5851def12083474a397facbf5d2a1..5200f57b6d7bb4a166e96f220a6bbef34ccbcd0f 100644 (file)
@@ -54,7 +54,7 @@ int include_stack_ptr = 0;
      /* recurse */
     yytext[yyleng-1]='\0';
     include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
-    if((yyin=fopen(yytext,"r"))==NULL) {
+    if((yyin=fopen((char*)yytext,"r"))==NULL) {
         fprintf(stderr,"*** Error: Could not open include file \"%s\".\n",yytext);
         yyterminate();
     }
index 6b7a5fa050efc71a41135a3fde8c777dca288e6e..ebfdbe2a60db5e7baf9b6057bff42ed38bbc303b 100644 (file)
@@ -48,7 +48,7 @@
 [[:alnum:]_.-]+>  {
      /* recurse */
     yytext[yyleng-1]='\0';
-    if((yyin=fopen(yytext,"r"))==NULL) {
+    if((yyin=fopen((char*)yytext,"r"))==NULL) {
         fprintf(stderr,"*** Error: Could not open include file \"%s\".\n",yytext);
         yyterminate();
     }
index 8cd4900edf2a0f3de115fffd08a7469de2437aee..e70f5a11a1d7afbd6c261701e019f4f93a735698 100644 (file)
@@ -51,7 +51,7 @@
     yyscan_t  scanner;
     FILE * fp;
     yytext[yyleng-1]='\0';
-    if((fp=fopen(yytext,"r"))==NULL) {
+    if((fp=fopen((char*)yytext,"r"))==NULL) {
         fprintf(stderr,"*** Error: Could not open include file \"%s\".\n",
             yytext);
         yyterminate();
index c1665df4baf98bcc73e304bc2d8ab36d029b2929..bc2afc233ee7c8bb169cbb9d0e3f9770efdee8b3 100644 (file)
@@ -46,7 +46,7 @@
         FOO_flush_buffer((YY_BUFFER_STATE)0);
         FOO_init_buffer((YY_BUFFER_STATE)0,(FILE*)0);
         FOO_load_buffer_state();
-        FOO_scan_buffer((char*)0,(yy_size_t)0);
+        FOO_scan_buffer((YY_CHAR*)0,(yy_size_t)0);
         FOO_scan_bytes((yyconst char*)0, 0);
         FOO_scan_string((yyconst char*)0);
         FOO_switch_to_buffer((YY_BUFFER_STATE)0);
@@ -55,7 +55,7 @@
         yyleng = 0;
         yylex();
         yyrestart((FILE*)0);
-        yytext = (char*)0;
+        yytext = (YY_CHAR*)0;
     }
  }
 %%
index a2d4c1a77eeb6391341bb8e56369a8fda79d68bd..9e4b5617f8f2f0eb5ea2a8e18ae0d4c4d08322ec 100644 (file)
@@ -47,7 +47,7 @@
         FOO_flush_buffer( (YY_BUFFER_STATE)0, yyscanner);
         FOO_init_buffer( (YY_BUFFER_STATE)0, (FILE*)0, yyscanner);
         FOO_load_buffer_state( yyscanner);
-        FOO_scan_buffer( (char*)0, (yy_size_t)0, yyscanner);
+        FOO_scan_buffer( (YY_CHAR*)0, (yy_size_t)0, yyscanner);
         FOO_scan_bytes( (yyconst char*)0, 0, yyscanner);
         FOO_scan_string( (yyconst char*)0, yyscanner);
         FOO_switch_to_buffer( (YY_BUFFER_STATE)0, yyscanner);
index 3dd752a650a18b3c4b49774bc4b8a935e8e70027..1a6a9144b472fb5ae560f5ae0c0e8af196050d4d 100644 (file)
@@ -61,7 +61,7 @@ int main(void);
 int
 main ()
 {
-    char * buf;
+    YY_CHAR* buf;
     int len;
     YY_BUFFER_STATE state;
 
@@ -82,8 +82,8 @@ main ()
        We make a copy, since the buffer will be modified by flex.*/
     printf("Testing: yy_scan_buffer(%s): ",INPUT_STRING_1); fflush(stdout);
     len = strlen(INPUT_STRING_1) + 2;
-    buf = (char*)malloc( len );
-    strcpy( buf, INPUT_STRING_1);
+    buf = (YY_CHAR*)malloc( len*sizeof(YY_CHAR) );
+    strcpy( (char*)buf, INPUT_STRING_1);
     buf[ len -2 ]  = 0; /* Flex requires two NUL bytes at end of buffer. */
     buf[ len -1 ] =0;
 
index d98c98a61a326bce38628c91aae5dff12325c1b4..fe2d53202d2fb59334a0d95756c2649ca435142a 100644 (file)
@@ -61,7 +61,7 @@ int main(void);
 int
 main ()
 {
-    char * buf;
+    YY_CHAR * buf;
     int len;
     YY_BUFFER_STATE state;
     yyscan_t  scanner=NULL;
@@ -87,8 +87,8 @@ main ()
        We make a copy, since the buffer will be modified by flex.*/
     printf("Testing: yy_scan_buffer(%s): ",INPUT_STRING_1); fflush(stdout);
     len = strlen(INPUT_STRING_1) + 2;
-    buf = (char*)malloc( len );
-    strcpy( buf, INPUT_STRING_1);
+    buf = (YY_CHAR*)malloc( len*sizeof(YY_CHAR) );
+    strcpy( (char*)buf, INPUT_STRING_1);
     buf[ len -2 ]  = 0; /* Flex requires two NUL bytes at end of buffer. */
     buf[ len -1 ] =0;
 
diff --git a/tests/strutils.h b/tests/strutils.h
new file mode 100644 (file)
index 0000000..88d918c
--- /dev/null
@@ -0,0 +1,122 @@
+/* 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
+ */
+
+/*
+ * Those are utility functions that are reimplementations of some standard
+ * C functions for strings manipulation, but using YY_CHAR macro instead of
+ * raw char type.
+ *
+ * These functions are only used in some test suites, not in the flex itself.
+ */
+
+#pragma once
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "strutils.h"
+
+size_t yy_utils_strlen(YY_CHAR* str)
+{
+    YY_CHAR *ptr = str;
+    while(*ptr != 0) ptr++;
+    return ptr-str;
+}
+
+YY_CHAR* yy_utils_strcpy(YY_CHAR *destination, const YY_CHAR *source)
+{
+    YY_CHAR *ptr = destination;
+    while((*destination++ = *source++));
+    return ptr;
+}
+
+int yy_utils_strcmp(YY_CHAR *str1, YY_CHAR *str2)
+{
+    while(*str1 == *str2++)
+        if(*str1++ == 0)
+            return 0;
+    return *str1 - *(str2-1);
+}
+
+YY_CHAR* yy_utils_strdup(YY_CHAR* s1)
+{
+    YY_CHAR* s2 = (YY_CHAR*)malloc((yy_utils_strlen(s1)+1)*sizeof(YY_CHAR));
+    yy_utils_strcpy(s2, s1);
+    return s2;
+}
+
+bool yy_utils_isany(YY_CHAR ch, const YY_CHAR *set, size_t set_size) {
+    size_t i;
+    for(i = 0; i < set_size; ++i)
+        if(set[i] == ch)
+            return true;
+    return false;
+}
+
+bool yy_utils_isspace(YY_CHAR ch) {
+    static const YY_CHAR set[] = {' ', '\r', '\n', '\t'};
+    return yy_utils_isany(ch, set, sizeof(set)/sizeof(set[0]));
+}
+
+bool yy_utils_isupper(YY_CHAR ch) {
+    static const YY_CHAR set[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
+    return yy_utils_isany(ch, set, sizeof(set)/sizeof(set[0]));
+}
+
+bool yy_utils_islower(YY_CHAR ch) {
+    static const YY_CHAR set[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
+    return yy_utils_isany(ch, set, sizeof(set)/sizeof(set[0]));
+}
+
+bool yy_utils_isdigit(YY_CHAR ch) {
+    static const YY_CHAR set[] = {'0','1','2','3','4','5','6','7','8','9'};
+    return yy_utils_isany(ch, set, sizeof(set)/sizeof(set[0]));
+}
+
+long int yy_utils_strtol(const YY_CHAR *str, YY_CHAR **endptr, int base)
+{
+    while(yy_utils_isspace(*str)) str++;
+    bool neg = false;
+    if(*str == '-') neg = true, str++;
+    else if(*str == '+') str++;
+    YY_CHAR ch;
+    long int n = 0;
+    while((ch = *str++)) {
+        long int v = -1;
+        if(yy_utils_isdigit(ch))
+            v = ch-'0';
+        else if(yy_utils_isupper(ch))
+            v = ch-'A'+10;
+        else if(yy_utils_islower(ch))
+            v = ch-'a'+10;
+        else
+            break;
+        if(v >= base)
+            break;
+        n *= base;
+        n += v;
+    }
+    if(endptr)
+        *endptr = (YY_CHAR*)str-1;
+    if(neg)
+        n = -n;
+    return n;
+}
\ No newline at end of file
diff --git a/tests/test-tests_strutils/Makefile.am b/tests/test-tests_strutils/Makefile.am
new file mode 100644 (file)
index 0000000..56312a4
--- /dev/null
@@ -0,0 +1,35 @@
+# 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.
+
+testname = test-tests_strutils
+
+OBJS = test_strutils.o
+
+AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/tests
+
+$(testname)$(EXEEXT): $(OBJS)
+       $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(OBJS) $(LOADLIBES)
+
+test: $(testname)$(EXEEXT)
+       ./$(testname)$(EXEEXT)
+
+.c.o:
+       $(CC) -c -o $@ $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $<
diff --git a/tests/test-tests_strutils/test_strutils.c b/tests/test-tests_strutils/test_strutils.c
new file mode 100644 (file)
index 0000000..805667d
--- /dev/null
@@ -0,0 +1,81 @@
+/* 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
+ */
+
+/*
+ * This test verifies that utility functions in `tests/strutils.h` are working
+ * properly.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+
+#define YY_CHAR uint32_t
+#include "strutils.h"
+
+#define STR(x) (#x)
+
+#define CHECK(v) do{ \
+        if(!(v)) { \
+            fprintf(stderr, "Check failed: %s\n", STR(v)); \
+            return 1; \
+        } \
+    }while(0)
+
+int main(int argc, char **argv) {
+    fprintf(stderr, "Starting strutils tests\n");
+
+    (void)argc;
+    (void)argv;
+
+    YY_CHAR str[] = {'W', 'h', 'a', 't', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '!', 0};
+
+    /* yy_utils_strlen */
+    CHECK(yy_utils_strlen(str) == 14);
+
+    /* yy_utils_strcpy, yy_utils_strcmp */
+    YY_CHAR dst1[15];
+    yy_utils_strcpy(dst1, str);
+    CHECK(yy_utils_strcmp(dst1, str) == 0);
+
+    /* yy_utils_strdup */
+    YY_CHAR *dst2 = yy_utils_strdup(str);
+    CHECK(yy_utils_strcmp(dst2, str) == 0);
+    free(dst2);
+
+    /* yy_utils_strtol */
+    YY_CHAR i1s[] = {' ', '\t', '\r', '\n', '1', '2', '3', 'a', 's', 'd', 0};
+    YY_CHAR *endptr;
+    CHECK(yy_utils_strtol(i1s, &endptr, 10) == 123);
+    CHECK(endptr == i1s+7);
+    CHECK(yy_utils_strtol(i1s, &endptr, 16) == 0x123a);
+    CHECK(endptr == i1s+8);
+
+    YY_CHAR i2s[] = {' ', '\t', '\r', '\n', '-', '1', '2', '3', 'a', 's', 'd', 0};
+    CHECK(yy_utils_strtol(i2s, &endptr, 10) == -123);
+    CHECK(endptr == i2s+8);
+    CHECK(yy_utils_strtol(i2s, &endptr, 16) == -0x123a);
+    CHECK(endptr == i2s+9);
+
+    fprintf(stderr, "Tests succeeded\n");
+    return 0;
+}
\ No newline at end of file
index b2732145f72b9c5d3ea1bb85ed72da24a26363d1..0d890974c5c467576f93376a81c38520765943f6 100644 (file)
@@ -50,7 +50,7 @@ main ( int argc, char** argv )
     assert(fp == stdout);
 
     while(testlex(scanner)) {
-        char * text;
+        YY_CHAR * text;
         int line;
         line = testget_lineno(scanner);
         text = testget_text(scanner);