westes / flex

The Fast Lexical Analyzer - scanner generator for lexing in C and C++
Other
3.51k stars 528 forks source link

ECHO directive doesn't work when ECHO defined in included header #169

Open westes opened 7 years ago

westes commented 7 years ago

(imported from sourceforge)

tl;dr; If the lex input file includes header file which (recursively includes header file which) already defines ECHO macro, the generated ECHO directive won't work as expected (because it's actually not used). The generated code looks like:

ifndef ECHO

define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)

endif

Long story: I was debugging why I can't build lexer.cc generated from lexer.ll. Yes, I could have removed the -Werror, but that would just hide the problem and the lexer would probably not work as expected. First I was seeing:

lexer.ll:141:11: error: statement has no effect [-Werror=unused-value] %% ^

which is very confusing, but I eventually identified the culprit as the

ECHO;

line. When I commented the (above mentioned) #ifndef ECHO I got:

lexer.cc:799:0: error: "ECHO" redefined [-Werror]

define ECHO fwrite( yytext, yyleng, 1, yyout )

^ In file included from /usr/include/termios.h:40:0, from /usr/include/bits/ioctl-types.h:5, from /usr/include/sys/ioctl.h:29, from /usr/include/boost/asio/detail/socket_types.hpp:48, from /usr/include/boost/asio/ip/address_v4.hpp:21, from /usr/include/boost/asio/ip/address.hpp:21, from ../../../src/lib/asiolink/io_address.h:15, from ../../../src/lib/dhcp/pkt.h:10, from ../../../src/lib/eval/token.h:11, from parser.yy:18, from ../../../src/lib/eval/eval_context.h:11, from lexer.cc:643: /usr/include/bits/termios.h:191:0: note: this is the location of the previous definition

define ECHO 0x00000008

^

My work-around has been in renaming ECHO to YYECHO in generated lexer.cc.

jpopelka commented 7 years ago

FYI: I had submitted the issue on SF

jannick0 commented 6 years ago

What about the following (keeping the macro name ECHO)?

#ifdef ECHO
    #if FLEX_USE_EXTERNALLY_DEFINED_MACRO_ECHO
        #if FLEX_USE_EXTERNALLY_DEFINED_MACRO_ECHO == 1
            #warning Externally defined macro 'ECHO' overrides the default definition of the flex scanner.
            #warning '#define FLEX_USE_EXTERNALLY_DEFINED_MACRO_ECHO 2' to suppress this warning.
        #endif
    #else
        #undef ECHO
        #warning Flex overrides the externally defined macro 'ECHO';
        #warning '#define FLEX_USE_EXTERNALLY_DEFINED_MACRO_ECHO' to prevent the flex scanner doing so.
    #endif
#endif
#ifndef ECHO
    #define ECHO do { fwrite( yytext, yyleng, 1, yyout ); } while (0)
#endif

Note that I dropped the if in the default definition of ECHO, since obsolete.