scanc.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 673 行 · 第 1/2 页

C
673
字号
 */
static bool doCUSE( int ch )
{
    char        buff[MAX_STR];
    char        *buffptr;

    /*
     * scan out white space
     */
    while( isspace( ch ) ) {
        ch = GetChar();
        if( ch == EOF ) {
            return( FALSE );
        }
    }
    /*
     * check for a '{'.  If we have one, this is a defn with no name.
     */
    if( ch == '{' ) {
        return( TRUE );
    }

    /*
     * get struct name
     */
    buffptr = buff;
    while( 1 ) {
        *buffptr++ = ch;
        ch = GetChar();
        if( ch == EOF ) {
            return( FALSE );
        }
        if( ch == '\n' ) {
            NewFileLine();
        }
        if( !IsTokenChar( ch ) ) {
            break;
        }
    }

    /*
     * We have a struct name.  Now, look for an opening '{'.
     * If we don't find one, then this is not a struct defn.
     */
    if( ch == '{' ) {
        buffptr--;
    } else {
        while( 1 ) {
            ch = GetChar();
            if( ch == EOF ) {
                break;
            }
            if( isspace( ch ) ) {
                continue;
            }
            if( ch != '{' ) {
                if( eatStuffBeforeOpenBrace( ch ) ) {
                    continue;
                }
                UnGetChar( ch );
                return( FALSE );
            } else {
                break;
            }
        }
    }
    *buffptr = 0;
    AddTag( buff );
    return( TRUE );

} /* doCUSE */

#define CHANGE_STATE( a ) goto a;
#define STATE( a ) a:

/*
 * ScanC - scan c files for tags
 */
void ScanC( void )
{
    char        *buffptr;
    char        buff[MAX_STR];
    int         brace_level;
    int         typedef_level;
    int         paren_level;
    bool        have_token;
    bool        have_typedef;
    bool        have_cuse;
    bool        have_struct;
    bool        have_enum;
    bool        doit;
    tag_type    type;
    int         ch;

    buffptr = buff;
    brace_level = 0;
    typedef_level = -1;
    have_token = FALSE;
    have_typedef = FALSE;
    have_enum = FALSE;
    acceptOnlyEndif = FALSE;
    structStackDepth = 0;

    while( 1 ) {
        ch = GetChar();
        if( ch == EOF ) {
            break;
        }
        switch( ch ) {
        case '{':
            if( !acceptOnlyEndif ) {
                brace_level++;
            }
            CHANGE_STATE( end_token );

        case '}':
            if( !acceptOnlyEndif ) {
                if( structStackDepth > 1 ) {
                    if( structStack[ structStackDepth-1] == brace_level ) {
                        structStackDepth--;
                    }
                }
                brace_level--;
                if( brace_level < 0 ) {
                    brace_level = 0;
                }
                have_enum = FALSE;
            }
            CHANGE_STATE( end_token );

        case '\n':
            NewFileLine();
            CHANGE_STATE( end_token );

        STATE( end_token );
            have_token = FALSE;
            if( buffptr > buff ) {
                have_token = TRUE;
                *buffptr = 0;
                buffptr = buff;
            }
            continue;

        case '"': case '\'':
            eatUntilChar( ch );
            break;

        case '/':
            ch = GetChar();
            if( ch == '*' ) {
                eatComment();
                continue;
            } else if( ch == '/' ) {
                eatUntilChar( '\n' );
                continue;
            }
            UnGetChar( ch );
            ch = '/';
            CHANGE_STATE( save_char );

        case '(':
            if( !acceptOnlyEndif ) {
                if( have_typedef && brace_level == typedef_level ) {
                    paren_level++;
                } else if( have_token ) {
                    doit = FALSE;
                    if( brace_level == 0 ) {
                        doit = TRUE;
                    } else if( structStackDepth > 1 ) {
                        if( structStack[ structStackDepth-1 ] == brace_level ) {
                            doit = TRUE;
                        }
                    }
                    if( doit ) {
#ifdef __ENABLE_FNAME_PROCESSING__
                        if (!strnicmp(buff, "__F_NAME", 8)) {
                            *buffptr++ = '(';

                            do {
                                ch = GetChar();
                                if (ch == EOF) {
                                    break;
                                }
                                *buffptr++ = ch;
                            } while (ch != ')');

                            if (ch == EOF) {
                                break;
                            }

                            eatWhiteSpace();
                        }
#endif //__ENABLE_FNAME_PROCESSING__

                        if( buffptr != buff ) {
                            *buffptr = 0;
                        }
                        RecordCurrentLineData();
                        type = doFunction( &brace_level );
                        if( type != TAG_NOTHING ) {
                            AddTag( buff );
                            break;
                        }
                    }
                }
                if( structStackDepth > 1 ) {
                    if( structStack[ structStackDepth-1] == brace_level ) {
                        structStackDepth--;
                    }
                }
            }
            CHANGE_STATE( save_char );

        case ')':
            if( !acceptOnlyEndif ) {
                if( have_typedef && brace_level == typedef_level ) {
                    paren_level--;
                    if( paren_level == 0 ) {
                        typedef_level = -1;
                        have_typedef = FALSE;
                        if( buffptr != buff ) {
                            *buffptr = 0;
                        }
                        RecordCurrentLineData();
                        AddTag( buff );
                        eatUntilChar( ';' );
                        break;
                    }
                }
            }
            CHANGE_STATE( save_char );

        case '#':
            if( buffptr == buff ) {
                doPreProcessorDirective();
                break;
            }
            CHANGE_STATE( save_char );

        case ',':
            if( !acceptOnlyEndif ) {
                if( ( have_typedef && brace_level == typedef_level ) ||
                    ( WantEnums && have_token && have_enum ) ) {
                    RecordCurrentLineData();
                    if( buffptr != buff ) {
                        *buffptr = 0;
                    }
                    AddTag( buff );
                    break;
                }
            }
            CHANGE_STATE( save_char );

        case ';':
            if( !acceptOnlyEndif && have_typedef && brace_level == typedef_level ) {
                have_typedef = FALSE;
                typedef_level = -1;
                RecordCurrentLineData();
                if( buffptr != buff ) {
                    *buffptr = 0;
                }
                AddTag( buff );
                break;
            }
            CHANGE_STATE( save_char );

        default:
        STATE( save_char );
            if( !IsTokenChar( ch ) ) {
                if( buffptr == buff ) {
                    break;
                }
                *buffptr = 0;
                if( !acceptOnlyEndif ) {
                    if( WantTypedefs && !have_typedef &&
                                !stricmp( buff, "typedef" ) ) {
                        have_typedef = TRUE;
                        typedef_level = brace_level;
                        paren_level = 0;
                        break;
                    }
                    if( WantEnums && have_token && have_enum ) {
                        RecordCurrentLineData();
                        *buffptr = 0;
                        AddTag( buff );
                    }
                    if( WantUSE || WantClasses ) {
                        if( !have_typedef ) {
                            have_struct = FALSE;
                            have_cuse = FALSE;
                            if( WantClasses && !stricmp( buff,"class" ) ) {
                                have_struct = TRUE;
                                have_cuse = TRUE;
                            } else if( WantUSE ) {
                                if( !stricmp( buff,"struct" ) ) {
                                    have_struct = TRUE;
                                    have_cuse = TRUE;
                                } else if( !stricmp( buff, "union" ) ){
                                    have_cuse = TRUE;
                                } else if( !stricmp( buff, "enum" ) ) {
                                    have_cuse = TRUE;
                                    have_enum = TRUE;
                                }
                            }
                            if( have_cuse ) {
                                RecordCurrentLineData();
                                if( doCUSE( ch ) ) {
                                    brace_level++;
                                    if( structStackDepth < MAX_STRUCT_DEPTH &&
                                                have_struct ) {
                                        structStack[ structStackDepth ] = brace_level;
                                        structStackDepth++;
                                    }
                                }
                                break;
                            }
                        } else {
                            if( !strcmp( buff, "enum" ) ) {
                                have_enum = TRUE;
                            }
                        }
                    }
                }
                buffptr = buff;
            } else if( buffptr != buff || (isalpha( ch ) || ch == '_') ) {
                *buffptr++ = ch;
                have_token = TRUE;
            }
            continue;
        }
        buffptr = buff;
        have_token = FALSE;
    }

} /* ScanC */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?