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
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef lint
00034 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/lex.c,v 14.10 2006/08/31 23:16:38 lbutler Exp $ (ARL)";
00035 #endif
00036
00037 #include "common.h"
00038
00039
00040
00041 #include <stdio.h>
00042 #include <ctype.h>
00043 #include <string.h>
00044 #include "machine.h"
00045 #include "bu.h"
00046
00047 static int bu_lex_reading_comment = 0;
00048
00049
00050
00051
00052 static char *
00053 bu_lex_getone(int *used, struct bu_vls *rtstr)
00054 {
00055 register char *cp;
00056 register char *sp;
00057 register char *unit;
00058 int number;
00059
00060 number = 1;
00061 *used = 0;
00062
00063 BU_CK_VLS(rtstr);
00064 cp = bu_vls_addr(rtstr);
00065 top:
00066 if (bu_lex_reading_comment) {
00067 for(;;) {
00068 register char tc;
00069 tc = *cp; cp++;
00070 if (!tc) {
00071 return 0;
00072 }
00073 if (tc != '*') continue;
00074 if (*cp != '/') continue;
00075 cp++;
00076 break;
00077 }
00078 bu_lex_reading_comment = 0;
00079 }
00080
00081
00082
00083
00084 for (; *cp && isspace(*cp); cp++);
00085
00086
00087
00088 if (!*cp || *cp == '#') {
00089 return 0;
00090 }
00091
00092
00093
00094 if (*cp == '/' && *(cp+1)=='*') {
00095 cp += 2;
00096 bu_lex_reading_comment = 1;
00097 goto top;
00098 }
00099
00100
00101
00102 sp = cp;
00103 while (*cp) {
00104 register char tc;
00105
00106 tc = *cp; cp++;
00107
00108
00109
00110
00111
00112
00113 if (number) {
00114
00115
00116
00117
00118 if (isdigit(tc)) {
00119 if (number == 5 || number == 6) number = 7;
00120 if (number == 3) number = 4;
00121 if (number == 1) number = 2;
00122 continue;
00123 }
00124 if (number==2 && tc == '.') {
00125
00126
00127
00128 number = 3;
00129 continue;
00130 }
00131 if (number == 4 && (tc == 'e' || tc == 'E')) {
00132
00133
00134
00135 number = 5;
00136 continue;
00137 }
00138 if (number == 5 && (tc == '+' || tc == '-')) {
00139
00140
00141
00142 number = 6;
00143 continue;
00144 }
00145 if (number == 3) break;
00146 number = 0;
00147 }
00148 if (!isalnum(tc) && tc != '.' && tc != '_') break;
00149 }
00150 if (number == 6) --cp;
00151 if (number == 3) --cp;
00152
00153
00154
00155
00156 *used = cp - sp -1;
00157 if (*used == 0) *used = 1;
00158 unit = (char *)bu_malloc(*used+1, "unit token");
00159 strncpy(unit,sp,*used);
00160 unit[*used] = '\0';
00161 *used = sp-bu_vls_addr(rtstr) + *used;
00162 if (*used == 0) *used = 1;
00163 return unit;
00164 }
00165
00166
00167
00168
00169 int
00170 bu_lex(
00171 union bu_lex_token *token,
00172 struct bu_vls *rtstr,
00173 struct bu_lex_key *keywords,
00174 struct bu_lex_key *symbols)
00175 {
00176 char *unit;
00177 char *cp;
00178 int used;
00179
00180
00181
00182
00183 used = 0;
00184 unit = bu_lex_getone(&used, rtstr);
00185
00186
00187
00188
00189 if (!unit) {
00190 if (used) bu_bomb("bu_lex: Null unit, and something used.\n");
00191 return BU_LEX_NEED_MORE;
00192 }
00193
00194
00195
00196
00197 if (isdigit(*unit)) {
00198
00199
00200
00201
00202
00203
00204
00205 if (*unit == '0') {
00206
00207
00208
00209 for (cp=unit; *cp && *cp>='0' && *cp <='7'; cp++);
00210 if (!*cp) {
00211 token->type = BU_LEX_INT;
00212 sscanf(unit,"%o", (unsigned int *)&token->t_int.value);
00213 bu_free(unit,"unit token");
00214 return used;
00215 }
00216
00217
00218
00219
00220
00221 cp=unit+1;
00222 if (*cp == 'x' || *cp == 'X') {
00223 for(;*cp && isxdigit(*cp);cp++);
00224 if (!*cp) {
00225 token->type = BU_LEX_INT;
00226 sscanf(unit,"%x",(unsigned int *)&token->t_int.value);
00227 bu_free(unit, "unit token");
00228 return used;
00229 }
00230 }
00231 }
00232
00233
00234
00235
00236 for (cp=unit; *cp && isdigit(*cp); cp++);
00237 if (!*cp) {
00238 token->type = BU_LEX_INT;
00239 sscanf(unit,"%d", &token->t_int.value);
00240 bu_free(unit, "unit token");
00241 return used;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250 if (*cp == '.') {
00251 for(cp++;*cp &&isdigit(*cp);cp++);
00252 if (*cp == 'e' || *cp == 'E') cp++;
00253 if (*cp == '+' || *cp == '-') cp++;
00254 for(;*cp &&isdigit(*cp);cp++);
00255 if (!*cp) {
00256 token->type = BU_LEX_DOUBLE;
00257 sscanf(unit, "%lg", &token->t_dbl.value);
00258 bu_free(unit, "unit token");
00259 return used;
00260 }
00261 }
00262
00263
00264
00265
00266 }
00267
00268
00269
00270 if (symbols) {
00271 if (!*(unit+1) ) {
00272 register struct bu_lex_key *sp;
00273 for (sp=symbols;sp->tok_val;sp++) {
00274 if (*sp->string == *unit) {
00275 token->type = BU_LEX_SYMBOL;
00276 token->t_key.value = sp->tok_val;
00277 bu_free(unit, "unit token");
00278 return used;
00279 }
00280 }
00281 }
00282 }
00283 if (keywords) {
00284 register struct bu_lex_key *kp;
00285 for (kp=keywords;kp->tok_val; kp++) {
00286 if (strcmp(kp->string, unit) == 0) {
00287 token->type = BU_LEX_KEYWORD;
00288 token->t_key.value = kp->tok_val;
00289 bu_free(unit, "unit token");
00290 return used;
00291 }
00292 }
00293 }
00294 token->type = BU_LEX_IDENT;
00295 token->t_id.value = unit;
00296 return used;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309