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

📄 parser.c

📁 LTris a tetris clone for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                          parser.c  -  description                             -------------------    begin                : Sat Mar 9 2002    copyright            : (C) 2001 by Michael Speck    email                : kulkanie@gmx.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include <stdlib.h>#include <string.h>#include "parser.h"/*====================================================================Error string.====================================================================*/static char parser_sub_error[1024];static char parser_error[1024];/*====================================================================This buffer is used to fully load resource files when the compact format is used.====================================================================*/enum { CBUFFER_SIZE = 131072 }; /* 128 KB */static char cbuffer[CBUFFER_SIZE];static char* cbuffer_pos = 0; /* position in cbuffer *//*====================================================================As we need constant strings sometimes we have to define a maximumlength for tokens.====================================================================*/enum { PARSER_MAX_TOKEN_LENGTH = 1024 };/*====================================================================Locals====================================================================*//*====================================================================Macro to shorten the fread call for a single character.====================================================================*/#define FILE_READCHAR( file, c ) fread( &c, sizeof( char ), 1, file )/*====================================================================Copy source to dest and at maximum limit chars. Terminate with 0.====================================================================*/void strcpy_lt( char *dest, char *src, int limit ){    int len = strlen( src );    if ( len > limit ) {        strncpy( dest, src, limit );        dest[limit] = 0;    }    else        strcpy( dest, src );}/*====================================================================Find next newline in cbuffer and replace it with \0 and return the pointer to the current line.====================================================================*/static char* parser_get_next_line(){    char *line = cbuffer_pos;    char *newpos;    if ( cbuffer_pos[0] == 0 )        return 0; /* completely read. no more lines. */    if ( ( newpos = strchr( cbuffer_pos, 10 ) ) == 0 )        cbuffer_pos += strlen( cbuffer_pos ); /* last line */    else {        cbuffer_pos = newpos + 1; /* set pointer to next line */        newpos[0] = 0; /* terminate current line */    }    return line;}/*====================================================================Set parse error string: "file:line: error"====================================================================*/static void parser_set_parse_error( char *fname, FILE *file, char *error ){    int end, pos;    int line_count = 1;    char c;    end = ftell( file ); pos = 0;    fseek( file, 0, SEEK_SET );    while ( pos < end ) {        FILE_READCHAR( file, c ); pos++;        if ( c == 10 ) line_count++;    }    sprintf( parser_error, "%s: %i: %s",              fname, line_count, error ); }/*====================================================================Check if the given character occurs in the symbol list.If the first symbol is ' ' it is used as wildcard for allwhite-spaces.====================================================================*/static int is_symbol( int c, char *symbols ){    int i = 0;    if ( symbols[0] == ' ' && c <= 32 ) return 1;    while ( symbols[i] != 0 )        if ( c == symbols[i++] )             return 1;    return 0;}/*====================================================================Move file position forward until reading in the given character.If stop is ' ' whitespaces will be ignored.====================================================================*/static void file_skip( FILE *file, char stop ){    char c = 0;    FILE_READCHAR( file, c );    while ( ( ( stop == ' ' && c <= 32 ) || ( stop != ' ' && c != stop ) ) && !feof( file ) )        FILE_READCHAR( file, c );    if ( !feof( file ) )        fseek( file, -1, SEEK_CUR );}/*====================================================================Read next token from current file position where symbols is alist of characters used to break up the tokens. The symbols themself are returned as tokens. If ' ' occurs in the symbol listit will be ignored and whitespaces are removed automatically.The token does not exceed PARSER_MAX_TOKEN_LENGTH.Enclosing ".." are kept at the token. Use file_compare_token()to test it's contents.Returns False on EoF.====================================================================*/static int file_read_token_intern( FILE *file, char *symbols, char *token ){    int pos = 0;    char c;    token[0] = 0;    file_skip( file, ' ' );    FILE_READCHAR( file, c );    if ( feof( file ) ) {         sprintf( parser_sub_error, "unexpected end of file" );         return 0;    }    /* string? */    if ( c == '"' ) {        token[pos++] = '"';        FILE_READCHAR( file, c );        while ( ( !feof( file ) && c != '"' ) ) {            token[pos++] = c;            if ( pos == PARSER_MAX_TOKEN_LENGTH - 2 ) {                token[pos++] = '"';                token[pos] = 0;                sprintf( parser_sub_error, "token exceeds limit" );                return 0;            }            FILE_READCHAR( file, c );        }        token[pos++] = '"';        token[pos] = 0;        if ( feof( file ) ) {             sprintf( parser_sub_error, "unexpected end of file" );             token[0] = 0;             return 0;        }        return 1;    }    /* symbol? */    if ( is_symbol( c, symbols ) ) {        token[0] = c; token[1] = 0;        return 1;    }    /* other token */    while ( !is_symbol( c, symbols ) && !feof( file ) ) {        token[pos++] = c;        if ( pos == PARSER_MAX_TOKEN_LENGTH - 1 ) {            token[pos] = 0;            sprintf( parser_sub_error, "token exceeds limit" );            return 0;        }        FILE_READCHAR( file, c );    }    token[pos] = 0;    if ( feof( file ) )         return 1;    fseek( file, -1, SEEK_CUR );    return 1;}/*====================================================================Skip all tokens until one begins with character 'stop'. Thistoken is also ignored.====================================================================*/static void file_skip_section( FILE *file, char stop ){    char token[PARSER_MAX_TOKEN_LENGTH];    do {        file_read_token_intern( file, PARSER_SYMBOLS, token );    } while ( !feof( file ) && token[0] != stop );}/*====================================================================Read next token and skip comments enclosed in tokensskip[0], skip[1] (if skip is not NULL).Return 0 if EoF.====================================================================*/static int file_read_token( FILE *file, char *symbols, char *skip, char *token ){    while ( 1 ) {        if ( !file_read_token_intern( file, symbols, token ) )

⌨️ 快捷键说明

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