📄 scanner.c
字号:
/******************************************************************************* author : Frank N黚el filename : ghmm/ghmm/scanner.c created : TIME: 11:40:33 DATE: Tue 27. August 1996 $Id: scanner.c,v 1.4 2002/02/27 15:55:46 pipenb Exp $Copyright (C) 1998-2001, ZAIK/ZPR, Universit鋞 zu K鰈nThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*******************************************************************************/#include <string.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "mprintf.h"#include "mes.h"#include "scanner.h"#define SCANNER_TYPE_CHAR 1#define SCANNER_TYPE_INT 2#define SCANNER_TYPE_DOUBLE 3#define SCANNER_TYPE_EDOUBLE 4#define SCANNER_TYPE_STRING 5#define SCANNER_TYPE_CSTRING 6#define m_scanner_isdigit( c ) ( (c)>= '0' && (c) <= '9' )#define m_scanner_isxdigit( c ) \ ( m_scanner_isdigit(c) || ((c) >= 'a' && (c) <= 'f') || ((c)>='A' && (c)<= 'F') )#define m_scanner_isalpha( c ) \ ( ((c)>='a' && (c)<='z') || ((c)>='A' && (c)<='Z') )#define m_scanner_isxalpha( c )\ (m_scanner_isalpha(c)||((c)&0x80 || (c)=='_')) /*----------------------------------------------------------------------------*/static int scanner_type( char* type, int* size ) { if( !strcmp( type, "char" ) ) { *size = sizeof(char); return(SCANNER_TYPE_CHAR); } if( !strcmp( type, "int" ) ) { *size = sizeof(int); return(SCANNER_TYPE_INT); } if( !strcmp( type, "double" ) ) { *size = sizeof(double); return(SCANNER_TYPE_DOUBLE); } if( !strcmp( type, "edouble" ) ) { *size = sizeof(double); return(SCANNER_TYPE_EDOUBLE); } if( !strcmp( type, "string" ) ) { *size = sizeof(char*); return(SCANNER_TYPE_STRING); } if( !strcmp( type, "cstring" ) ) { *size = sizeof(char*); return(SCANNER_TYPE_CSTRING); } *size = 0; return(0); } /* scanner_type */ /*----------------------------------------------------------------------------*/static int scanner_digit( int* val, scanner_t* s, int radix, int expect ) { switch( radix ) { case 10 : if( '0' <= s->c && s->c <= '9' ) *val = *val*10 + s->c - '0'; else if( expect ) { scanner_error( s, "decimal digit expected" ); return(-1); } else return(1); break; case 16 : if( s->c >= '0' && s->c <= '9' ) *val = *val*16 + s->c - '0'; else if( 'A' <= s->c && s->c <= 'F' ) *val = *val*16 + s->c - 'A' + 10; else if( 'a' <= s->c && s->c <= 'f' ) *val = *val*16 + s->c - 'a' + 10; else if( expect ) { scanner_error( s, "decimal digit expected" ); return(-1); } else return(1); break; case 2 : if( s->c >= '0' && s->c <= '1' ) *val = *val*2 + s->c - '0'; else if( expect ) { scanner_error( s, "binary digit expected" ); return(-1); } else return(1); break; case 8 : if( s->c >= '0' && s->c <= '7' ) *val = *val*8 + s->c - '0'; else if( expect ) { scanner_error( s, "octal digit expected" ); return(-1); } else return(1); break; default: return(1); } return(0);} /* scanner_digit *//*----------------------------------------------------------------------------*/static int scanner_virtual_fgetc( scanner_t* s ) { int c; if( !s ) return(EOF); c = fgetc( s->fp ); /* Don't use the mes-functions here */ if( c == EOF ) return(c); ungetc( c, s->fp ); return(c);} /* scanner_virtual_fgetc *//*----------------------------------------------------------------------------*/static void scanner_fgetc( scanner_t* s ) { int c; if( !s ) return; c = fgetc( s->fp ); /* Don't use the mes-functions here */ if( c == EOF ) { s->c = 0; s->eof = 1; } else s->c = c;} /* scanner_fgetc *//*----------------------------------------------------------------------------*/static int scanner_nextchar( scanner_t* s, int expect ) { if( !s || s->err || s->eof ) return(0); while( s->pos + 1 >= s->txtlen ){ int mes_stat = mes_ability( 0 ); int err = m_realloc( s->txt, s->txtlen+256 ); mes_ability( mes_stat ); if( err ) { scanner_error( s, "line too long" ); return(-1); } else s->txtlen += 256; } s->txt[s->pos] = s->c; if( s->c == '\n' ) { s->pos = 0; s->line++; } else s->pos++; s->txt[s->pos] = 0; scanner_fgetc( s ); if( s->eof && expect ) { scanner_error( s, "unexpected end of file" ); return(-1); } return(0);} /* scanner_nextchar *//*----------------------------------------------------------------------------*/static int scanner_nextcchar( scanner_t* s ){ if( !s || s->eof || s->err ) return(0); if( s ) s->esc = 0; if( scanner_nextchar( s, 1 ) ) return(-1); if( s->c - '\\' ) return(0); else { int radix = 0; int digits = 0; int val = 0; if( scanner_nextchar( s , 1 ) ) return(-1); s->esc = 1; if( '0' <= s->c && s->c <= '7' ) { radix = 8; val = s->c - '0'; digits = 2; } else { switch( s->c ) { case 'a' : s->c = '\a'; break; case 'b' : s->c = '\b'; break; case 'f' : s->c = '\f'; break; case 'n' : s->c = '\n'; break; case 'r' : s->c = '\r'; break; case 't' : s->c = '\t'; break; case 'v' : s->c = '\v'; break; case '\\' : s->c = '\\'; break; case '\'' : s->c = '\''; break; case '"' : s->c = '\"'; break; case '?' : s->c = '\?'; break; case 'd' : radix = 10; digits = 3; break; case 'x' : radix = 16; digits = 2; break; case '_' : radix = 2; digits = 8; break; default: return(0); } if( !radix ) return(0); } while( digits-- ) { if( scanner_nextchar( s, 1 ) ) return(-1); if( scanner_digit( &val, s, radix, 1 ) ) return(-1); } s->c = val; } return(0);} /* scanner_nextcchar *//*----------------------------------------------------------------------------*/static int scanner_skipspace(scanner_t* s) { if( s->eof || s->err ) return(0); while( !s->eof ) { if( s->c == '#' ) { /* skip comment */ do { if( scanner_nextchar( s, 0 ) ) return(-1); } while( !s->eof && s->c - '\n' ); } /* New : C-Comment allowed */ else if( s->c == '/' && scanner_virtual_fgetc( s ) == '*' ) { do { if( scanner_nextchar( s, 0 ) ) return(-1); } while( !s->eof && (s->c - '*' || scanner_virtual_fgetc( s )- '/' )); if( !s->eof && scanner_nextchar( s, 0 ) ) return(-1); if( !s->eof && scanner_nextchar( s, 0 ) ) return(-1); } /* FN: 22.10.97 */ else if( strchr( " \n\r\t\f\v\b\a" ,s->c ) ) { if( scanner_nextchar( s, 0 ) ) return(-1); } else break; } return(0); } /* scanner_skipspace */ /*----------------------------------------------------------------------------*/static double scanner_get_length(scanner_t* s, double resolution) { double val = scanner_get_double(s); if( !s || s->err ) return(0); if( s->eof ) { scanner_error( s, "length expected" ); return(0); } if( s->c - ';' ) { if( resolution <= 0.0 ) {scanner_error( s, "resolution not set" ); return(0);} s->resolution_used = 1; if( scanner_get_id(s) ) return(0); if( !strcmp(s->id,"INCH") ) val *= resolution; else if( !strcmp(s->id,"CM") ) val*=(resolution/2.54); else if( !strcmp(s->id,"MM") ) val*=(resolution/25.4); else { scanner_error(s,"unknown length unit"); return(0); } } return val;} /* scanner_get_length *//*============================================================================*//*============================================================================*//*============================================================================*/int scanner_free(scanner_t** s){# define CUR_PROC "scanner_free" mes_check_ptr(s, return(-1)); if( !*s ) return(0); m_free((*s)->filename); m_free((*s)->id); m_free((*s)->txt); m_fclose((*s)->fp); m_free(*s); return(0); # undef CUR_PROC} /* scanner_free *//*============================================================================*/scanner_t* scanner_alloc(const char* filename){#define CUR_PROC "scanner_alloc" scanner_t* s = NULL; mes_check_ptr( filename, return(NULL) ); if( !m_calloc( s, 1 ) ) {mes_proc();goto STOP;} s->txtlen = 256; s->idlen = 256; if( !(s->fp = mes_fopen( filename, "rt" )) ) {mes_proc();goto STOP;} if( !(s->txt = mes_malloc(s->txtlen)) ) {mes_proc(); goto STOP;} if( !(s->id = mes_malloc(s->txtlen)) ) {mes_proc(); goto STOP;} if( !(s->filename = mes_calloc( strlen(filename)+1 )) ) {mes_proc(); goto STOP;} memcpy( s->filename, filename, strlen(filename)+1 ); s->line = 1; s->pos = 0; s->c = ' '; s->err = 0; /****************/ s->resolution_used = 0; s->x_resolution = 0.0; s->y_resolution = 0.0; s->x_scale = 1.0; s->y_scale = 1.0; scanner_fgetc( s ); if( scanner_skipspace( s ) ) goto STOP; return( s );STOP: scanner_free( &s ); return(NULL); #undef CUR_PROC} /* scanner_alloc *//*============================================================================*/int scanner_error(scanner_t* s, char* message) { int i, j; if( !s || s->err ) return(0); j = s->pos; while ( !s->eof && s->c - '\n' && !scanner_nextchar( s, 0 ) ); mes_time(); mes_file_win( s->txt ); mes_file_win( "\n" ); for( i = 0; i < j; i++) { if(s->txt[i] - '\t') s->txt[i] = ' '; } s->txt[j] = 0; mes_file_win( s->txt ); mes_file_win( "^\n" ); if( message ) { mes( MES_FILE_WIN, "Error in file %s, line %d : %s\n", s->filename,s->line + 1,message); } else { mes( MES_FILE_WIN, "Syntax error in file %s, line %d\n", s->filename,s->line + 1,message); } s->err = 1; s->c = 0; return(0); } /* scanner_error *//*============================================================================*/int scanner_consume( scanner_t* s, char ch ){ if( s->err ) return(0); if( s->eof || ch - s->c ) { char txt[] = "' ' expected!"; txt[1] = ch; scanner_error( s, txt ); return(-1); } else if( scanner_nextchar( s, 0 ) ) return(-1); if( scanner_skipspace(s) ) return(-1); return(0);} /* scanner_consume *//*============================================================================*//* Reads over a block, that's enclosed in '{' and '}'. Other blocks, lying within this one will be skipped */int scanner_consume_block(scanner_t *s) { int open_brackets = 0; if( s->err ) return(0); scanner_consume(s, '{'); if (s->err) return(-1); open_brackets++; while(!s->eof && open_brackets) { if(!('{' - s->c)) open_brackets++; else if(!('}' - s->c)) open_brackets--; if( scanner_nextchar( s, 0 ) ) return(-1); if( scanner_skipspace(s) ) return(-1); } if (open_brackets) { scanner_error( s, "Unexpected EOF! '}'expected" ); return(-1); } return(0);} /* scanner_consume_block *//*============================================================================*/int scanner_get_name( scanner_t* s ){ int pos=0; if( !s || s->err ) return(0); while( m_scanner_isxalpha(s->c) || m_scanner_isdigit(s->c) ) { while( pos+1 >= s->idlen ){ int mes_stat = mes_ability( 0 ); int err = m_realloc( s->txt, s->txtlen+256 ); mes_ability( mes_stat ); if( err ) { scanner_error( s, "identifier too long" ); return(-1); } else s->idlen += 256; } s->id[pos++] = s->c; if( scanner_nextchar( s, 0 ) ) return(-1); } if( !pos || m_scanner_isdigit(s->id[0]) ) scanner_error( s, "identifier expected" ); s->id[pos] = 0; if( scanner_skipspace( s ) ) return(-1); return(0); } /* scanner_get_name *//*============================================================================*/int scanner_get_id( scanner_t* s ) { char* str; if( !s || s->err ) return(0); if( scanner_get_name( s ) ) return(0); str = s->id; while( *str ) { if( 'a' <= *str && *str <= 'z' ) *str += 'A' - 'a'; str++; } return(0);} /* scanner_get_id *//*============================================================================*/char* scanner_get_str( scanner_t* s, int* len, int cmode ){# define CUR_PROC "scanner_get_string" int i = 0; int maxlen = 128; char* val = NULL; if( !s || s->err ) return(NULL); if( s->eof || s->c - '"' ) { scanner_error( s, "string expected" ); goto STOP; } if( !m_malloc( val, maxlen ) ){ scanner_error( s, "Not enough memory to read string" ); goto STOP; } while( !s->eof && s->c == '"' ) { if( cmode ) { if( scanner_nextcchar( s ) ) goto STOP; } else { if( scanner_nextchar( s, 1 ) ) goto STOP; } while ( s->c - '"' || s->esc ) { if( s->eof || ((!s->c || s->c == '\n') && !s->esc ) ) { scanner_error( s, "String not closed" ); goto STOP; } if( i+1 == maxlen ) { if( m_realloc( val, maxlen+128 ) ) { scanner_error( s, "Not enough memory to read string" ); goto STOP; } maxlen += 128; } if( s->c || len ) val[i++] = s->c; if( cmode ) { if( scanner_nextcchar( s ) ) goto STOP; } else { if( scanner_nextchar( s, 1 ) ) goto STOP; } } if( scanner_consume( s, '"' ) ) goto STOP; if( scanner_skipspace( s ) ) goto STOP; } val[i++]=0; if( m_realloc( val, i ) ) { mes_proc(); goto STOP; } if( len ) *len = i; return( val );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -