lkml.org 
[lkml]   [1999]   [Jun]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 2.x.x mkdep incorrectly handles serial.c (and probably others)
    Hi Michael.

    >> Changing CONFIG_SERIAL_SHARE_IRQ with no other changes does
    >> *not* recompile serial.c but it should.

    > Good bug report. Ok, I believe I see the problem. Here is the
    > structure of drivers/char/serial.c:

    > #if 0
    > #define CONFIG_SERIAL_MANY_PORTS
    > ...
    > #endif

    > ... uses of CONFIG_SERIAL_MANY_PORTS ...

    > mkdep.c sees the definition of CONFIG_SERIAL_MANY_PORTS and says
    > "oh this is not an autoconfig variable; serial.c explicitly
    > defines it". This is why your patch to serial.c avoids the
    > problem. It's really a bug in mkdep.c: it doesn't understand
    > the effects of #if lines.

    Can I offer the enclosed patch to deal with this problem?

    Basically, the patch does three things:

    1. Inserts a slight optimisation into mkdep's state machine whereby
    the checks for space/tab are combined, and in the process also
    checks for other whitespace characters at that point.

    2. Modifies mkdep's state machine to include partial #if-#endif
    parsing to deal with the above problem. Basically, the mods
    result in it treating the contents of a "#if 0"-#endif block
    as a comment, and not acting on any definitions therein.

    3. Documenting the resulting state machine - this is the 100-odd
    line comment at the beginning of the patch. Discard it if you
    prefer, that doesn't worry me.

    Note that the patch is against the 2.2.10 source tree, but as mkdep.c
    carries a timestamp prior to the release of 2.2.0, it should patch
    unchanged against 2.2.0 and all subsequent kernel source trees.

    Also note that some of the lines in the patch are just reformatting
    the existing code. I found that reformatting necessary to work out
    how the state machine worked, and included them as a result.

    Best wishes from Riley.

    +----------------------------------------------------------------------+
    | There is something frustrating about the quality and speed of Linux |
    | development, ie., the quality is too high and the speed is too high, |
    | in other words, I can implement this XXXX feature, but I bet someone |
    | else has already done so and is just about to release their patch. |
    +----------------------------------------------------------------------+
    * ftp://ftp.MemAlpha.cx/pub/rhw/Linux
    * http://www.MemAlpha.cx/kernel.versions.html
    --- linux-2.2.10/scripts/mkdep.c~ Fri Jan 8 19:10:11 1999
    +++ linux-2.2.10/scripts/mkdep.c Tue Jun 15 15:17:15 1999
    @@ -8,6 +8,104 @@
    * I make simple dependency lines for #include <*.h> and #include "*.h".
    * I also find instances of CONFIG_FOO and generate dependencies
    * like include/config/foo.h.
    + *
    + * There is also sufficient handling of #if-#endif blocks to enable
    + * this program to ignore the contents of '#if 0'-'#endif' blocks
    + * with any level of internal #if-#endif nesting.
    + *
    + **********************************************************************
    + *
    + * The state machine used by this program starts in state 0 with the
    + * variable ifdepth set to 0. It uses the term "Space" to refer to the
    + * case where the isspace() function returns true, and is as follows:
    + *
    + * 0. Read a character, and change state as follows:
    + *
    + * "'" '"' '/' 'C' '_' '#' Other
    + * --- --- --- --- --- --- -----
    + * 1 2 3 4 6 8 0
    + *
    + * 1. Read in a string bounded by single quotes and handle it, then
    + * change to state 0.
    + *
    + * 2. Read in a string bounded by double quotes and handle it, then
    + * change to state 0.
    + *
    + * 3. Read in the following character. If this is a '*' (producing
    + * the sequence "/*"), read in more characters until the sequence
    + * "*/" is found, and handle them. Either way, change to state 0.
    + *
    + * 4. If the variable ifdepth has a value greater than zero, change
    + * to state 0, otherwise change to state 5.
    + *
    + * 5. Determine if this is the start of a sequence reading "CONFIG_"
    + * and, if so, handle it. Either way, change to state 0.
    + *
    + * 6. If the variable ifdepth has a value greater than zero, change
    + * to state 0, otherwise change to state 7.
    + *
    + * 7. Determine if this is the start of a sequence reading "__SMP__"
    + * and, if so, handle it. Either way, change to state 0.
    + *
    + * 8. Read a character, and change state as follows:
    + *
    + * 'd' 'u' 'e' 'i' Space Other
    + * --- --- --- --- ----- -----
    + * 9 11 13 15 8 0
    + *
    + * 9. If the variable ifdepth has a value greater than zero, change
    + * to state 0, otherwise change to state 10.
    + *
    + * 10. Determine if the characters so far are the start of a sequence
    + * reading "#define" and, if so, handle it. Either way, change to
    + * state 0.
    + *
    + * 11. If the variable ifdepth has a value greater than zero, change
    + * to state 0, otherwise change to state 10.
    + *
    + * 12. Determine if the characters so far are the start of a sequence
    + * reading "#undef" and, if so, handle it. Either way, change to
    + * state 0.
    + *
    + * 13. If the variable ifdepth has a value greater than zero, change
    + * to state 14, otherwise change to state 0.
    + *
    + * 14. Determine if the characters so far are the start of a sequence
    + * reading "#endif" and, if so, decrement the variable ifdepth.
    + * Either way, change to state 0.
    + *
    + * 15. Read a character, and change state as follows:
    + *
    + * 'f' 'n' Other
    + * --- --- -----
    + * 16 19 0
    + *
    + * 16. If the variable ifdepth has a value greater than zero, increment
    + * it and change to state 0, otherwise change to state 17.
    + *
    + * 17. Read a character. If it is a Space, change to state 18, otherwise
    + * change to state 0.
    + *
    + * 18. Read a character. If it is a '0' (thus producing the sequence
    + * "#if 0"), increment the variable ifdepth. Either way, change to
    + * state 0.
    + *
    + * 19. If the variable ifdepth has a value greater than zero, change
    + * to state 0, otherwise change to state 20.
    + *
    + * 20. Determine if the characters so far are the start of a sequence
    + * reading "#include" and, if so, change to state 21, else change
    + * to state 0.
    + *
    + * 21. Read a character, and change state as follows:
    + *
    + * '<' '"' Space Other
    + * --- --- ----- -----
    + * 22 23 21 0
    + *
    + * 22. Handle a '#include <header.h>' line, then change to state 0.
    + *
    + * 23. Handle a '#include "header.h"' line, then change to state 0.
    */

    #include <ctype.h>
    @@ -221,6 +319,9 @@
    #define CASE(c,label) if (current == c) goto label
    #define NOTCASE(c,label) if (current != c) goto label

    +#define SPACE(label) if (isspace(current)) goto label
    +#define NOTSPACE(label) if (!isspace(current)) goto label
    +
    /*
    * Yet another state machine speedup.
    */
    @@ -254,6 +355,7 @@
    const char * next = map;
    const char * map_dot;
    unsigned long __buf = 0;
    + unsigned int ifdepth = 0;

    for (;;) {
    start:
    @@ -265,51 +367,64 @@
    CASE('\'', squote);
    CASE('"', dquote);
    CASE('#', pound);
    + if (ifdepth > 0)
    + goto start;
    CASE('C', cee);
    CASE('_', underscore);
    goto start;

    /* / */
    slash:
    - GETNEXT
    - NOTCASE('*', __start);
    + GETNEXT NOTCASE('*', __start);
    slash_star_dot_star:
    GETNEXT
    __slash_star_dot_star:
    - NOTCASE('*', slash_star_dot_star);
    + NOTCASE('*', slash_star_dot_star);
    - GETNEXT
    - NOTCASE('/', __slash_star_dot_star);
    + GETNEXT NOTCASE('/', __slash_star_dot_star);
    goto start;

    /* '.*?' */
    squote:
    - GETNEXT
    - CASE('\'', start);
    + GETNEXT CASE('\'', start);
    - NOTCASE('\\', squote);
    + NOTCASE('\\', squote);
    GETNEXT
    goto squote;

    /* ".*?" */
    dquote:
    - GETNEXT
    - CASE('"', start);
    + GETNEXT CASE('"', start);
    - NOTCASE('\\', dquote);
    + NOTCASE('\\', dquote);
    GETNEXT
    goto dquote;

    /* #\s* */
    pound:
    - GETNEXT
    - CASE(' ', pound);
    - CASE('\t', pound);
    + GETNEXT SPACE(pound);
    - CASE('i', pound_i);
    + CASE('i', pound_i);
    + if (ifdepth > 0) {
    + CASE('e', pound_e);
    + goto __start;
    + }
    - CASE('d', pound_d);
    + CASE('d', pound_d);
    - CASE('u', pound_u);
    + CASE('u', pound_u);
    + goto __start;
    +
    +/* #\s*e */
    +pound_e:
    + GETNEXT NOTCASE('n', __start);
    + GETNEXT NOTCASE('d', __start);
    + GETNEXT NOTCASE('i', __start);
    + GETNEXT NOTCASE('f', __start);
    + ifdepth--;
    goto __start;

    /* #\s*i */
    pound_i:
    - GETNEXT NOTCASE('n', __start);
    + GETNEXT CASE('f', pound_if);
    + if (ifdepth > 0)
    + goto __start;
    +
    + NOTCASE('n', __start);
    GETNEXT NOTCASE('c', __start);
    GETNEXT NOTCASE('l', __start);
    GETNEXT NOTCASE('u', __start);
    @@ -317,29 +432,36 @@
    GETNEXT NOTCASE('e', __start);
    goto pound_include;

    +/* #\s*if */
    +pound_if:
    + if (ifdepth > 0) {
    + ifdepth++;
    + goto __start;
    + }
    + GETNEXT NOTSPACE( __start);
    + GETNEXT NOTCASE('0', __start);
    + ifdepth++;
    + goto __start;
    +
    /* #\s*include\s* */
    pound_include:
    - GETNEXT
    - CASE(' ', pound_include);
    - CASE('\t', pound_include);
    + GETNEXT SPACE( pound_include);
    map_dot = next;
    - CASE('"', pound_include_dquote);
    + CASE('"', pound_include_dquote);
    - CASE('<', pound_include_langle);
    + CASE('<', pound_include_langle);
    goto __start;

    /* #\s*include\s*"(.*)" */
    pound_include_dquote:
    - GETNEXT
    - CASE('\n', start);
    + GETNEXT CASE('\n', start);
    - NOTCASE('"', pound_include_dquote);
    + NOTCASE('"', pound_include_dquote);
    handle_include(1, map_dot, next - map_dot - 1);
    goto start;

    /* #\s*include\s*<(.*)> */
    pound_include_langle:
    - GETNEXT
    - CASE('\n', start);
    + GETNEXT CASE('\n', start);
    - NOTCASE('>', pound_include_langle);
    + NOTCASE('>', pound_include_langle);
    handle_include(0, map_dot, next - map_dot - 1);
    goto start;

    @@ -362,10 +484,7 @@

    /* #\s*(define|undef)\s*CONFIG_(\w*) */
    pound_define_undef:
    - GETNEXT
    - CASE(' ', pound_define_undef);
    - CASE('\t', pound_define_undef);
    -
    + GETNEXT SPACE( pound_define_undef);
    NOTCASE('C', __start);
    GETNEXT NOTCASE('O', __start);
    GETNEXT NOTCASE('N', __start);
    \
     
     \ /
      Last update: 2005-03-22 13:52    [W:0.038 / U:0.484 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site