NAME

Image::Leptonica::Func::parseprotos

VERSION

version 0.04

parseprotos.c

parseprotos.c

      char             *parseForProtos()

   Static helpers
      static l_int32    getNextNonCommentLine()
      static l_int32    getNextNonBlankLine()
      static l_int32    getNextNonDoubleSlashLine()
      static l_int32    searchForProtoSignature()
      static char      *captureProtoSignature()
      static char      *cleanProtoSignature()
      static l_int32    skipToEndOfFunction()
      static l_int32    skipToMatchingBrace()
      static l_int32    skipToSemicolon()
      static l_int32    getOffsetForCharacter()
      static l_int32    getOffsetForMatchingRP()

FUNCTIONS

parseForProtos

char * parseForProtos ( const char *filein, const char *prestring )

parseForProtos()

    Input:  filein (output of cpp)
            prestring (<optional> string that prefaces each decl;
                      use NULL to omit)
    Return: parsestr (string of function prototypes), or NULL on error

Notes:
    (1) We parse the output of cpp:
            cpp -ansi <filein>
        Three plans were attempted, with success on the third.
    (2) Plan 1.  A cursory examination of the cpp output indicated that
        every function was preceeded by a cpp comment statement.
        So we just need to look at statements beginning after comments.
        Unfortunately, this is NOT the case.  Some functions start
        without cpp comment lines, typically when there are no
        comments in the source that immediately precede the function.
    (3) Plan 2.  Consider the keywords in the language that start
        parts of the cpp file.  Some, like 'typedef', 'enum',
        'union' and 'struct', are followed after a while by '{',
        and eventually end with '}, plus an optional token and a
        final ';'  Others, like 'extern' and 'static', are never
        the beginnings of global function definitions.   Function
        prototypes have one or more sets of '(' followed eventually
        by a ')', and end with ';'.  But function definitions have
        tokens, followed by '(', more tokens, ')' and then
        immediately a '{'.  We would generate a prototype from this
        by adding a ';' to all tokens up to the ')'.  So we use
        these special tokens to decide what we are parsing.  And
        whenever a function definition is found and the prototype
        extracted, we skip through the rest of the function
        past the corresponding '}'.  This token ends a line, and
        is often on a line of its own.  But as it turns out,
        the only keyword we need to consider is 'static'.
    (4) Plan 3.  Consider the parentheses and braces for various
        declarations.  A struct, enum, or union has a pair of
        braces followed by a semicolon.  They cannot have parentheses
        before the left brace, but a struct can have lots of parentheses
        within the brace set.  A function prototype has no braces.
        A function declaration can have sets of left and right
        parentheses, but these are followed by a left brace.
        So plan 3 looks at the way parentheses and braces are
        organized.  Once the beginning of a function definition
        is found, the prototype is extracted and we search for
        the ending right brace.
    (5) To find the ending right brace, it is necessary to do some
        careful parsing.  For example, in this file, we have
        left and right braces as characters, and these must not
        be counted.  Somewhat more tricky, the file fhmtauto.c
        generates code, and includes a right brace in a string.
        So we must not include braces that are in strings.  But how
        do we know if something is inside a string?  Keep state,
        starting with not-inside, and every time you hit a double quote
        that is not escaped, toggle the condition.  Any brace
        found in the state of being within a string is ignored.
    (6) When a prototype is extracted, it is put in a canonical
        form (i.e., cleaned up).  Finally, we check that it is
        not static and save it.  (If static, it is ignored).
    (7) The @prestring for unix is NULL; it is included here so that
        you can use Microsoft's declaration for importing or
        exporting to a dll.  See environ.h for examples of use.
        Here, we set: @prestring = "LEPT_DLL ".  Note in particular
        the space character that will separate 'LEPT_DLL' from
        the standard unix prototype that follows.

AUTHOR

Zakariyya Mughal <zmughal@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Zakariyya Mughal.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.