⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 LTris a tetris clone for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
            return 0;        if ( skip ) {            if ( token[0] == skip[0] )                file_skip_section( file, skip[1] );            else                break;        }        else            break;    }    return 1;}/*====================================================================Remove quotes if any and return result as newly allocated string.====================================================================*/static char* parser_remove_quotes( char *string ){    char *new;    if ( string[0] != '"' )         return strdup( string );    new = calloc( strlen( string ) - 1, sizeof( char ) );    strncpy( new, string + 1, strlen( string ) - 2 );    new[strlen( string ) - 2] = 0;    return new;}/*====================================================================Proceed in the given string until it ends or non-whitespace occursand return the new position.====================================================================*/static char* string_ignore_whitespace( char *string ){    int i = 0;    while ( string[i] != 0 && string[i] <= 32 ) i++;    return string + i;}/*====================================================================This function searches file from the current position for the nextpdata entry.====================================================================*/static PData* parser_parse_file( FILE *file ){    char token[PARSER_MAX_TOKEN_LENGTH];    PData *pd = 0, *sub = 0;        /* get name */    if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )        return 0;    if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {        sprintf( parser_sub_error, "parse error before '%s'", token );        return 0;    }    pd = calloc( 1, sizeof( PData ) );    pd->name = parser_remove_quotes( token );    /* check type */    if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )        goto failure;    switch ( token[0] ) {        case PARSER_SET:            /* assign single value or list */            pd->values = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );            if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )                 goto failure;            if ( token[0] != PARSER_LIST_BEGIN ) {                if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {                    sprintf( parser_sub_error, "parse error before '%s'", token );                    goto failure;                }                else                    list_add( pd->values, parser_remove_quotes( token ) );            }            else {                if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )                    goto failure;                while ( token[0] != PARSER_LIST_END ) {                    if ( is_symbol( token[0], PARSER_SYMBOLS ) ) {                        sprintf( parser_sub_error, "parse error before '%s'", token );                        goto failure;                    }                    else                        list_add( pd->values, parser_remove_quotes( token ) );                    if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )                        goto failure;                }            }            break;        case PARSER_GROUP_BEGIN:            /* check all entries until PARSER_GROUP_END */            pd->entries = list_create( LIST_NO_AUTO_DELETE, LIST_NO_CALLBACK );            while ( 1 ) {                if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) )                     goto failure;                if ( token[0] == PARSER_GROUP_END )                    break;                fseek( file, -strlen( token ), SEEK_CUR );                sub = parser_parse_file( file );                if ( sub )                     list_add( pd->entries, sub );                else                    goto failure;            }            break;        default:            sprintf( parser_sub_error, "parse error before '%s'", token );            goto failure;    }    return pd;failure:    parser_free( &pd );    return 0;}/*====================================================================Publics====================================================================*//*====================================================================This function splits a string into tokens using the charactersfound in symbols as breakpoints. If the first symbol is ' ' allwhitespaces are used as breakpoints though NOT added as a token (thus removed from string).====================================================================*/List* parser_split_string( char *string, char *symbols ){    int pos;    char *token = 0;    List *list = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );    while ( string[0] != 0 ) {        if ( symbols[0] == ' ' )            string = string_ignore_whitespace( string );         if ( string[0] == 0 ) break;        pos = 1; /* 'read in' first character */        while ( string[pos - 1] != 0 && !is_symbol( string[pos - 1], symbols ) && string[pos - 1] != '"' ) pos++;        if ( pos > 1 )             pos--;        else            if ( string[pos - 1] == '"' ) {                /* read a string */                string = string + 1; pos = 0;                while ( string[pos] != 0 && string[pos] != '"' ) pos++;                token = calloc( pos + 1, sizeof( char ) );                strncpy( token, string, pos ); token[pos] = 0;                list_add( list, token );                string = string + pos + (string[pos] != 0);                continue;            }        token = calloc( pos + 1, sizeof( char ) );        strncpy( token, string, pos); token[pos] = 0;        list_add( list, token );        string = string + pos;    }    return list;}/*====================================================================This is the light version of parser_split_string which checks forjust one character and does not add this glue characters to the list. It's about 2% faster. Wow.====================================================================*/List *parser_explode_string( char *string, char c ){    List *list = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );    char *next_slash = 0;    char buffer[64];    while ( string[0] != 0 && ( next_slash = strchr( string, c ) ) != 0 ) {        if ( next_slash != string ) {            strcpy_lt( buffer, string, (next_slash-string>63)?63:(next_slash-string) );            list_add( list, strdup( buffer ) );        }        string += next_slash - string + 1;    }    if ( string[0] != 0 )        list_add( list, strdup( string ) );    return list;}/*====================================================================This function reads in a whole file and converts it into aPData tree struct. If an error occurs NULL is returned and parser_error is set.====================================================================*/static int parser_read_file_full( FILE *file, PData *top ){    PData *sub = 0;    char token[1024];    /* parse file */    while ( !feof( file ) ) {        if ( ( sub = parser_parse_file( file ) ) != 0 )            list_add( top->entries, sub );        else            return 0;         /* skip comments and whitespaces */        if ( !file_read_token( file, PARSER_SYMBOLS, PARSER_SKIP_SYMBOLS, token ) ) {            if ( token[0] != 0 )                return 0;            break;        }        else            fseek( file, -strlen( token ), SEEK_CUR );    }    return 1;}static int parser_read_file_compact( PData *section ){    /* section is the parent pdata that needs some        entries */    PData *pd = 0;    char *line, *cur;    while ( ( line = parser_get_next_line() ) ) {        switch ( line[0] ) {            case '>':                /* this section is finished */                return 1;            case '<':                /* add a whole subsection */                pd = calloc( 1, sizeof( PData ) );                pd->name = strdup( line + 1 );                pd->entries = list_create( LIST_NO_AUTO_DELETE, LIST_NO_CALLBACK );                parser_read_file_compact( pd );                /* add to section */                list_add( section->entries, pd );                break;            default:                /* read values as subsection */                pd = calloc( 1, sizeof( PData ) );                /* check name */                if ( ( cur = strchr( line, '

⌨️ 快捷键说明

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