|
|
1.1 ! root 1: /* ! 2: * Lexer and mainline for new screen builder. ! 3: */ ! 4: #include <scnbld.h> ! 5: #include <y.tab.h> ! 6: #include <string.h> ! 7: #include <ctype.h> ! 8: ! 9: FILE *ifp, *ofp, *ohp; ! 10: int line = 1; ! 11: int fieldDesig = '!'; ! 12: static int errors; ! 13: static char *name; ! 14: ! 15: #ifdef TRACE ! 16: #define RET(val) { printf("%d: trace %d\n", __LINE__, val); return(val); } ! 17: #else ! 18: #define RET(val) return(val); ! 19: #endif ! 20: #define POINT printf("%d: trace point\n", __LINE__); ! 21: ! 22: /* ! 23: * Fatal error. ! 24: */ ! 25: void ! 26: fatal(s) ! 27: char *s; ! 28: { ! 29: printf("%d: %r\n%d error%s detected\n", ! 30: line, &s, (errors + 1), (errors ? "s": "")); ! 31: exit(1); ! 32: } ! 33: ! 34: /* ! 35: * Nonfatal error. ! 36: */ ! 37: yyerror(s) ! 38: char *s; ! 39: { ! 40: printf("%d: %r\n", line, &s); ! 41: errors++; ! 42: } ! 43: ! 44: main(argc, argv) ! 45: char *argv[]; ! 46: { ! 47: char *p, *q, *fileName; ! 48: char file[20]; ! 49: ! 50: if (NULL == (fileName = argv[1])) ! 51: fatal("No work."); ! 52: ! 53: ifp = xopen(fileName, "r"); ! 54: ! 55: /* Turn file name into .c and .h version in current dir */ ! 56: if (NULL == (p = strrchr(fileName, '/'))) ! 57: p = fileName; ! 58: else ! 59: p++; ! 60: ! 61: if (NULL != (q = strrchr(p, '.'))) ! 62: *q = '\0'; ! 63: ! 64: sprintf(file, "%s.c", p); ! 65: ofp = xopen(file, "w"); ! 66: ! 67: sprintf(file, "%s.h", p); ! 68: ohp = xopen(file, "w"); ! 69: ! 70: name = newcpy(p); ! 71: ! 72: if(NULL != q) ! 73: *q = '.'; ! 74: ! 75: fprintf(ofp, "/*\n"); ! 76: fprintf(ofp, " * Screen definition file\n"); ! 77: fprintf(ofp, " * This file generated from %s\n", fileName); ! 78: fprintf(ofp, " */\n"); ! 79: fprintf(ofp, "#include <%s>\n\n", file); ! 80: ! 81: fprintf(ohp, "/*\n"); ! 82: fprintf(ohp, " * Screen definition header\n"); ! 83: fprintf(ohp, " * This file generated from %s\n", fileName); ! 84: fprintf(ohp, " */\n"); ! 85: fprintf(ohp, "#include <scn.h>\n\n"); ! 86: fprintf(ohp, "extern backGrnd %s_data[];\n", name); ! 87: fprintf(ohp, "extern loc %s_locs[];\n", name); ! 88: ! 89: yyparse(); ! 90: ! 91: finish(); ! 92: } ! 93: ! 94: typedef enum state state; ! 95: enum state { start, inname, innum, instr, bsl, incomm, pct, pctEnd }; ! 96: ! 97: struct sym { ! 98: char *name; ! 99: int ytype; ! 100: } table[] = { ! 101: "external", EXT, ! 102: "readonly", RONLY, ! 103: "long", LONG, ! 104: "default", DEFAULT, ! 105: "skip", SKIP, ! 106: "group", GROUP, ! 107: "help", HELP, ! 108: "verify", VERIFY, ! 109: "designator", DESIG, ! 110: "do", DO, ! 111: "done", DONE, ! 112: NULL ! 113: }; ! 114: ! 115: yylex() ! 116: { ! 117: register int c; ! 118: register struct sym *tp; ! 119: state st, pst; ! 120: char buf[80], *p; ! 121: ! 122: for (pst = st = start; ; ) { ! 123: if (EOF == (c = fgetc(ifp))) ! 124: fatal("unexpected EOF"); ! 125: ! 126: switch (st) { ! 127: case pctEnd: ! 128: if ('\n' == c) { ! 129: line++; ! 130: RET(EOF) ! 131: } ! 132: continue; ! 133: ! 134: case pct: ! 135: if ('%' != c) { ! 136: yyerror("Lex error %%%c", c); ! 137: st = start; ! 138: continue; ! 139: } ! 140: st = pctEnd; ! 141: continue; ! 142: ! 143: case bsl: ! 144: if (start == pst) { ! 145: if ('\n' == c) { ! 146: line++; ! 147: st = start; ! 148: continue; ! 149: } ! 150: yyerror("%c after \\ outside of string"); ! 151: st = start; ! 152: continue; ! 153: } ! 154: *p++ = c; ! 155: st = pst; ! 156: continue; ! 157: ! 158: case instr: ! 159: switch (c) { ! 160: case '\\': ! 161: pst = st; ! 162: st = bsl; ! 163: *p++ = c; ! 164: continue; ! 165: case '\n': ! 166: yyerror("new line in string"); ! 167: case '"': ! 168: *p++ = '"'; ! 169: *p = 0; ! 170: yylval.string = newcpy(buf); ! 171: RET(STRING) ! 172: default: ! 173: *p++ = c; ! 174: continue; ! 175: } ! 176: case inname: ! 177: if (isalnum(c)) { ! 178: *p++ = c; ! 179: continue; ! 180: } ! 181: st = start; ! 182: ungetc(c, ifp); ! 183: *p = '\0'; ! 184: ! 185: for (tp = table; tp->name != NULL; tp++) ! 186: if (!strcmp(tp->name, buf)) ! 187: RET(tp->ytype) ! 188: ! 189: yylval.string = newcpy(buf); ! 190: RET(NAME) ! 191: ! 192: case innum: ! 193: if (isdigit(c)) { ! 194: *p++ = c; ! 195: continue; ! 196: } ! 197: st = start; ! 198: ungetc(c, ifp); ! 199: *p = '\0'; ! 200: yylval.val = atoi(buf); ! 201: RET(NUMBER) ! 202: ! 203: case incomm: ! 204: switch (c) { ! 205: case '\\': ! 206: pst = start; ! 207: break; ! 208: case '\n': ! 209: line++; ! 210: st = start; ! 211: } ! 212: continue; ! 213: ! 214: case start: ! 215: switch (c) { ! 216: case '#': ! 217: st = incomm; ! 218: continue; ! 219: case '%': ! 220: st = pct; ! 221: continue; ! 222: case '\n': ! 223: line++; ! 224: RET(NL) ! 225: case '\\': ! 226: pst = st; ! 227: st = bsl; ! 228: continue; ! 229: case '"': ! 230: st = instr; ! 231: p = buf; ! 232: *p++ = c; ! 233: continue; ! 234: default: ! 235: if (isspace(c)) ! 236: continue; ! 237: ! 238: if (isdigit(c)) { ! 239: st = innum; ! 240: p = buf; ! 241: *p++ = c; ! 242: continue; ! 243: } ! 244: ! 245: if (isalpha(c)) { ! 246: st = inname; ! 247: p = buf; ! 248: *p++ = c; ! 249: continue; ! 250: } ! 251: yyerror("Lexical error %c", c); ! 252: } ! 253: } ! 254: } ! 255: } ! 256: ! 257: typedef struct namelist namelist; ! 258: struct namelist { ! 259: namelist *next; ! 260: char *name; ! 261: }; ! 262: ! 263: /* ! 264: * output extern for verify routine. ! 265: */ ! 266: void ! 267: outExtern(n) ! 268: char *n; ! 269: { ! 270: static namelist *root = NULL; ! 271: register namelist *p; ! 272: ! 273: for (p = root; p != NULL; p = p->next) ! 274: if (!strcmp(p->name, n)) ! 275: return; ! 276: ! 277: p = alloc(sizeof(*p)); ! 278: p->next = root; ! 279: p->name = n; ! 280: root = p; ! 281: fprintf(ohp, "extern int %s();\n", n); ! 282: } ! 283: ! 284: /* ! 285: * finish processing the scn tables. ! 286: */ ! 287: finish() ! 288: { ! 289: int c; ! 290: clump *cp; ! 291: loc *lp; ! 292: int times, count, toOut; ! 293: int row, col, started; ! 294: char *p, buf[80]; ! 295: ! 296: fprintf(ofp, "backGrnd %s_data[] = {\n", name); ! 297: ! 298: for (row = col = started = times = count = 0, lp = locs, cp = clumps; ! 299: EOF != (c = fgetc(ifp)); ) { ! 300: if (c == fieldDesig) { ! 301: c = ' '; ! 302: if (NULL == lp) { ! 303: yyerror("To few fields defined"); ! 304: break; ! 305: } ! 306: ! 307: if (NULL != cp && (cp->from == lp) && !times) { ! 308: times = cp->times; ! 309: count = cp->count; ! 310: } ! 311: if (count) { ! 312: if (NULL == lp->these) ! 313: lp->these = alloc(sizeof(pair) * times); ! 314: lp->these[times - 1].row = row; ! 315: lp->these[times - 1].col = col; ! 316: } ! 317: else { ! 318: lp->row = row; ! 319: lp->col = col; ! 320: } ! 321: lp = lp->next; ! 322: if (count && !--count) { /* last in group */ ! 323: if (--times) { /* go around again */ ! 324: count = cp->count; ! 325: lp = cp->from; ! 326: } ! 327: else /* next group */ ! 328: cp = cp->next; ! 329: } ! 330: } ! 331: if (!started) { /* No chars output for this line yet */ ! 332: switch (c) { ! 333: case '\n': ! 334: row++; ! 335: col = 0; ! 336: continue; ! 337: case '\t': ! 338: col |= 7; ! 339: case ' ': ! 340: col++; ! 341: continue; ! 342: } ! 343: started++; ! 344: toOut = col; ! 345: p = buf; ! 346: fputc('"', ofp); ! 347: } ! 348: switch (c) { ! 349: case '\t': ! 350: col |= 7; ! 351: col++; ! 352: *p++ = '\\'; ! 353: *p++ = 't'; ! 354: continue; ! 355: case '\n': ! 356: fprintf(ofp, "\",\n\t%d, %d,\n", row, toOut); ! 357: row++; ! 358: col = 0; ! 359: started = 0; ! 360: continue; ! 361: case ' ': ! 362: *p++ = c; ! 363: col++; ! 364: continue; ! 365: } ! 366: col++; ! 367: if (buf != p) { /* we have saved some whitespace */ ! 368: *p = 0; ! 369: fprintf(ofp, "%s", buf); ! 370: p = buf; ! 371: } ! 372: switch (c) { /* we are putting stuff into c strings */ ! 373: case '\\': ! 374: case '"': ! 375: fputc('\\', ofp); ! 376: } ! 377: fputc(c, ofp); ! 378: } ! 379: fprintf(ofp, "\tNULL\n};\n"); ! 380: if (NULL != lp) ! 381: yyerror("To many fields defined"); ! 382: ! 383: /* ! 384: * Output field descriptors. ! 385: */ ! 386: for (times = count = 0, cp = clumps, lp = locs; ! 387: lp != NULL; ! 388: lp = lp->next) { ! 389: if (NULL != cp && (cp->from == lp)) { ! 390: count = cp->count; ! 391: times = cp->times; ! 392: } ! 393: if (count) { ! 394: if(lp->flags & LONGFIELD) { ! 395: if (!(lp->flags & EXTERNAL)) ! 396: fprintf(ofp, "char *%s[%d];\n", ! 397: lp->field, times); ! 398: fprintf(ohp, "extern char *%s[%d];\n", ! 399: lp->field, times); ! 400: } ! 401: else { ! 402: if (!(lp->flags & EXTERNAL)) ! 403: fprintf(ofp, "char %s[%d][%d];\n", ! 404: lp->field, times, lp->len + 1); ! 405: fprintf(ohp, "extern char %s[%d][%d];\n", ! 406: lp->field, times, lp->len + 1); ! 407: } ! 408: if(!--count) ! 409: cp = cp->next; ! 410: } ! 411: else { ! 412: if(lp->flags & LONGFIELD) { ! 413: if (!(lp->flags & EXTERNAL)) ! 414: fprintf(ofp, "char *%s;\n", lp->field); ! 415: fprintf(ohp, "extern char *%s;\n", lp->field); ! 416: } ! 417: else { ! 418: if (!(lp->flags & EXTERNAL)) ! 419: fprintf(ofp, "char %s[%d];\n", ! 420: lp->field, lp->len + 1); ! 421: fprintf(ohp, "extern char %s[%d];\n", ! 422: lp->field, lp->len + 1); ! 423: } ! 424: } ! 425: if (NULL == lp->verify) ! 426: lp->verify = "noVerify"; ! 427: outExtern(lp->verify); ! 428: } ! 429: fprintf(ofp, "\n"); ! 430: ! 431: /* ! 432: * Output loc table. ! 433: */ ! 434: fprintf(ofp, "loc %s_locs[] = {\n", name); ! 435: ! 436: for (times = count = 0, cp = clumps, lp = locs; lp != NULL;) { ! 437: if (NULL != cp && (cp->from == lp) && !times) { ! 438: times = cp->times; ! 439: count = cp->count; ! 440: toOut = (times * count); ! 441: } ! 442: ! 443: if (count) { ! 444: toOut--; ! 445: lp->row = lp->these[times - 1].row; ! 446: lp->col = lp->these[times - 1].col; ! 447: ! 448: if(lp->flags & LONGFIELD) ! 449: sprintf(buf, "%s + %d", ! 450: lp->field, cp->times - times); ! 451: else ! 452: sprintf(buf, "%s[%d]", ! 453: lp->field, cp->times - times); ! 454: } ! 455: else { ! 456: if(lp->flags & LONGFIELD) ! 457: sprintf(buf, "&%s", lp->field); ! 458: else ! 459: sprintf(buf, "%s", lp->field); ! 460: } ! 461: ! 462: fprintf(ofp, "\t{ %s, %d, %s, %s, %d, %d, %d, %d, %s },\n", ! 463: buf, ! 464: lp->len, ! 465: ((NULL == lp->Default) ? buf : lp->Default), ! 466: lp->verify, ! 467: lp->flags & (LONGFIELD|READONLY), ! 468: lp->row, ! 469: lp->col, ! 470: ((255 == lp->skipf) ? toOut : lp->skipf), ! 471: ((NULL == lp->help) ? "NULL" : lp->help)); ! 472: ! 473: lp = lp->next; ! 474: if (count && !--count) { /* last in group */ ! 475: if (--times) { /* go around again */ ! 476: count = cp->count; ! 477: lp = cp->from; ! 478: } ! 479: else ! 480: cp = cp->next; /* next group */ ! 481: } ! 482: } ! 483: fprintf(ofp, "\tNULL\n};\n"); ! 484: if(errors) { ! 485: printf("%d error%s detected\n", ! 486: errors, ((1 == errors) ? "s": "")); ! 487: exit(1); ! 488: } ! 489: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.