00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "token.h"
00026
00027 #include <string.h>
00028 #include <ctype.h>
00029 #include <stdio.h>
00030 #include <iostream>
00031 #include "RioError.h"
00032
00033 token::token()
00034 {
00035 tk_flags = 0;
00036 tk_fname = NULL;
00037 tk_fp = NULL;
00038 tk_cerr = NULL;
00039 tk_strp = NULL;
00040 tk_stre = NULL;
00041 tk_tkp = NULL;
00042 tk_tkl = 0;
00043 tk_linecnt = 0;
00044 tk_orgp = NULL;
00045 tk_orge = NULL;
00046 tk_wstr = tk_wstrstr;
00047 memset( tk_wstrstr, 0, TK_WSTRL );
00048 memset( tk_line, 0, TK_LINEL );
00049 }
00050
00051 token::~token()
00052 {
00053 }
00054
00055 void token::setcerr( ostream *x )
00056 {
00057 tk_cerr = x;
00058 }
00059
00060 void token::setstring( char *s, int len )
00061 {
00062 tk_strp = s;
00063 tk_stre = s+len;
00064 tk_orgp = tk_strp;
00065 tk_orge = tk_stre;
00066 }
00067
00068 char *token::emsg( const char *s )
00069 {
00070 char *e;
00071 e = tk_wstr;
00072 if(tk_fname)
00073 e += sprintf(e, "in file %s ", tk_fname);
00074 if(tk_linecnt)
00075 e += sprintf(e, "in line %d ", tk_linecnt);
00076 if(tk_orgp)
00077 e += sprintf(e, "offset %ld ", ( long ) ( tk_strp-tk_orgp ) );
00078 e += sprintf(e, "%s\n", s);
00079 if(tk_cerr)
00080 {
00081 *tk_cerr << "token emsg: " << tk_wstr << endl;
00082 }
00083 return tk_wstr;
00084 }
00085
00086
00087
00088 void token::next()
00089 {
00090 char *t1, *te, *t2;
00091 char c;
00092 int len;
00093
00094 t1 = tk_strp;
00095 te = tk_stre;
00096
00097 while((t1 < te) && ((c = *t1) == ' ' || c == '\t'))
00098 t1++;
00099
00100 t2 = t1;
00101 while((t2 < te) && (c = *t2) != ' ' && c != '\t')
00102 t2++;
00103
00104 tk_strp = t2;
00105 tk_tkp = t1;
00106 tk_tkl = t2 - t1;
00107 if(tk_flags & TK_DEBUG_TOKEN)
00108 {
00109 len = TK_WSTRL - 30;
00110 if(tk_tkl < len) len = tk_tkl;
00111 memcpy(tk_wstr, tk_tkp, len);
00112 *(tk_wstr+len) = '\0';
00113 if(tk_cerr)
00114 {
00115 *tk_cerr << "token: >" << tk_wstr << "<" << endl;
00116 }
00117 }
00118 }
00119
00120
00121 int token::nextckend()
00122 {
00123 next();
00124 return(ckend());
00125 }
00126
00127
00128 int token::ckend()
00129 {
00130 if( tk_strp == tk_stre )
00131 return 0;
00132 emsg("extra tokens are invalid\n");
00133 return 1;
00134 }
00135
00136
00137
00138 int token::cmp( const char *s )
00139 {
00140 int len;
00141
00142 if( tk_tkl == 0 )
00143 return 1;
00144 len = strlen( s );
00145 if( len != tk_tkl )
00146 return 1;
00147 return memcmp( s, tk_tkp, tk_tkl );
00148 }
00149
00150
00151 int token::getstr( char *s, int maxlen )
00152 {
00153 if( tk_tkl == 0 ) return 1;
00154 if( tk_tkl > maxlen )
00155 {
00156 emsg("string too int");
00157 return 1;
00158 }
00159 memcpy( s, tk_tkp, tk_tkl );
00160 s[tk_tkl] = '\0';
00161 return 0;
00162 }
00163
00164
00165
00166 int token::getstrnew( char *s[] )
00167 {
00168 if( tk_tkl == 0 )
00169 return 1;
00170 *s = new char[tk_tkl+1];
00171 memcpy( *s, tk_tkp, tk_tkl );
00172 (*s)[tk_tkl] = '\0';
00173 return 0;
00174 }
00175
00176
00177
00178
00179
00180 int token::getnumber( int *num )
00181 {
00182 int len;
00183 char *p;
00184 int x;
00185
00186 x = 0;
00187 len = tk_tkl;
00188 p = tk_tkp;
00189 while( len-- > 0 )
00190 {
00191 if( isdigit( *p ) )
00192 {
00193 x *= 10;
00194 x += ( *p & 0x0f );
00195 }
00196 else return -1;
00197 p++;
00198 }
00199 *num = x;
00200 return 0;
00201 }
00202
00203
00204
00205
00206
00207
00208 int token::getdouble(double *num) {
00209 int len;
00210 char *p;
00211 double x;
00212 bool fraction = false;
00213 double divby = 0;
00214
00215 x = 0;
00216 len = tk_tkl;
00217 p = tk_tkp;
00218 while(len-- > 0)
00219 {
00220 if( (isdigit(*p)) && (fraction == false) )
00221 {
00222 x *= 10;
00223 x += (*p & 0x0f);
00224 }
00225 else if( (isdigit(*p)) && (fraction == true) )
00226 {
00227 x += (*p & 0x0f)/ divby;
00228 divby *= 10.0;
00229 }
00230 else if( ( *p == '.' ) || ( *p == ',' ) )
00231 {
00232 fraction = true;
00233 divby = 10.0;
00234 }
00235 else return -1;
00236 p++;
00237 }
00238 *num = x;
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246 int token::gethex( char *o, int ol )
00247 {
00248 int len;
00249 char *t1, *o1;
00250 int n0, n1;
00251
00252 o1 = o;
00253 t1 = tk_tkp;
00254 len = tk_tkl;
00255 while( len >= 2 )
00256 {
00257 if( (( n0 = ck_hex( *t1 )) < 0 ) || (( n1 = ck_hex(*( t1 + 1 )) ) < 0 ) )
00258 {
00259 emsg("invalid hex char");
00260 return 1;
00261 }
00262 if( o1 > ( o + ol ) )
00263 {
00264 emsg("hex value too int");
00265 return 1;
00266 }
00267 *o1++ = ( n0 << 4 ) | n1;
00268 len -= 2;
00269 t1 += 2;
00270
00271 if( ( len > 0 ) && ( *t1 == '-' ) )
00272 {
00273 t1++;
00274 len--;
00275 }
00276 }
00277 if( len != 0 )
00278 {
00279 emsg("odd number of nibbles in hex value");
00280 return 1;
00281 }
00282
00283 if( o1 != o + ol )
00284 {
00285 emsg("hex value too short");
00286 return 1;
00287 }
00288 return 0;
00289 }
00290
00291 int token::ck_hex( int c )
00292 {
00293 if( isdigit( c ) )
00294 {
00295 return(c - '0');
00296 }
00297 c = tolower( c );
00298 if( ( c >= 'a' ) && ( c <= 'f' ) )
00299 return( c - 'a' + 10 );
00300 return -1;
00301 }
00302
00303
00304
00305
00306 int token::nextline()
00307 {
00308 int len;
00309
00310 while( 1 )
00311 {
00312 tk_tkl = 0;
00313 if( fgets( tk_line, TK_LINEL, tk_fp) == NULL )
00314 {
00315 return 1;
00316 }
00317 tk_linecnt++;
00318 len = strlen( tk_line );
00319 if( tk_line[len-1] == '\n' )
00320 {
00321 len--;
00322 tk_line[len] = '\0';
00323 }
00324 if( tk_cerr )
00325 {
00326 *tk_cerr << ">" << tk_line << endl;
00327 }
00328 if( tk_line[0] == '#' )
00329 continue;
00330 setstring( tk_line, len );
00331 return 0;
00332 }
00333 return 1;
00334 }
00335
00336
00337
00338
00339 struct token_kw *token::findkw(struct token_kw *kp)
00340 {
00341 while( kp->kw_word )
00342 {
00343 if( !cmp( kp->kw_word ) )
00344 return( kp );
00345 kp++;
00346 }
00347 return NULL;
00348 }
00349
00350
00351
00352
00353 int token::parseline( struct token_kw *keys )
00354 {
00355 struct token_kw *kp;
00356
00357 do {
00358 if( nextline() )
00359 return END_TOKEN;
00360 next();
00361 } while( tk_tkl == 0 );
00362
00363 kp = findkw(keys);
00364 if( kp != NULL )
00365 {
00366 next();
00367 return kp->kw_value;
00368 }
00369
00370 emsg( "invalid keyword" );
00371 return ERROR_TOKEN;
00372 }
00373
00374
00375
00376
00377 int token::openfile( const char *fname )
00378 {
00379 tk_fname = fname;
00380 tk_fp = fopen( tk_fname, "r" );
00381 if(tk_fp == NULL && tk_cerr )
00382 {
00383 *tk_cerr << "Could not open file " << tk_fname << endl;
00384 return 1;
00385 }
00386 else if( tk_fp == NULL )
00387 {
00388
00389 RioErr << "Could not open file " << fname << endl;
00390 return 1;
00391 }
00392 return 0;
00393 }
00394
00395
00396 void token::closefile()
00397 {
00398 fclose( tk_fp );
00399 }