Search code examples
cparsingflex-lexerlex

Adding a code to be compiled in lex first


I'm looking for a way to insert an #undef to the lex generated source code that will appear before the built in lines lex generates.

When compiling a file.l with lex, I generate a lex.yy.c file. In my file.l I have written :

#include "y.tab.h"
#undef __STRICT_ANSI__
#include <string.h>

The #undef helps me compile the code under the flag -std=c99 So it needs to be done before including string.h. But the generated file includes string.h before copying my undef.

Without the #undef I am getting a lot of warnings due to the use of strdup. I have seen the normal fixes using flags, but like I said I can't access the makefile.

Adding 'manually' the line

#undef __STRICT_ANSI__

into lex.yy.c before fixes everything. But i prefer not to touch any of the generated code and have it done by lex.

I have read this, strdup(): Confused about warnings ('implicit declaration', 'makes pointer...without a cast', memory leak) And like i said it does solve it. But only if I can somehow force the generated file to run the undef first.


Solution

  • To start with, #undef __STRICT_ASCII__ is not the correct way to enable the declaration of Posix functions like strdup.

    Posix extensions which are declared in standard C library header files are made conditional on "feature test macros". You can read a summary in man feature_test_macros but in any case, the documentation for any function which requires a feature test macro includes a description of which macros are required. In the case of strdup, we can read in man strdup:

    Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       strdup():
           _XOPEN_SOURCE >= 500
    

    (Followed by more possibilities.)

    Personally, I always use

    #define _XOPEN_SOURCE 700
    

    which requests declarations for all functions in the latest version of Posix.

    One way to insert the feature test macro before any include of a standard library function is to do so on the compile command line:

    -D_XOPEN_SOURCE=700
    

    I like doing it this way, because I can add it to my Makefile and then it applies to every compilation (which is basically what I want). Usually, makefiles include a feature which allows you to add this option to your compiler flags without modifying the file. For example, the following will often work:

    make file CPPFLAGS="-D_XOPEN_SOURCE=700"
    

    (CPPFLAGS is a common makefile variable used to set preprocessor flags.)

    But if you want to put it into your flex file, you can use a %top block:

    %top {
    #define _XOPEN_SOURCE 700
    }
    

    %top is like %{ but it puts the inserted code right at the beginning of the generated code.


    If nothing else works, you can always just insert the declaration for strdup, (also taken from man strdup) into your flex prologue.

    %{
      char *strdup(const char *s);
      #include "y.tab.h"
    %}
    

    Both the C standard and the Posix standard allow explicit declaration of library functions (but not macros) as an alternative to including relevant headers.