|
|
1.1 ! root 1: /* ! 2: * Quick and dirty screen builder. ! 3: * by Charles Fiterman on 2-6-90 ! 4: * ! 5: * pass 1 count lines with data and field start chars. ! 6: * allocate tables. ! 7: * pass 2 build data. ! 8: * pass 3 output data to .c file. ! 9: */ ! 10: #include <misc.h> ! 11: #include <scn.h> ! 12: #include <ctype.h> ! 13: ! 14: extern char *strrchr(); ! 15: extern char *strchr(); ! 16: extern char *strcpy(); ! 17: ! 18: static char *fileName = NULL; ! 19: static char *outFile; ! 20: static char fieldDesig = '!'; ! 21: static int errCt = 0, line = 1; ! 22: static int backCnt, locCnt; ! 23: static loc *locTab; ! 24: static long filePos; ! 25: ! 26: static FILE *ifp, *ofp, *hfp; ! 27: ! 28: static char *buf; ! 29: ! 30: #define MAXTOKEN 5 ! 31: ! 32: /* ! 33: * Usage message documents program usage. ! 34: */ ! 35: void ! 36: Usage() ! 37: { ! 38: fprintf(stderr, "Usage: scn [-fc] filename\n"); ! 39: fprintf(stderr, "\t-fc sets field designator to c\n"); ! 40: exit(1); ! 41: } ! 42: ! 43: /* ! 44: * Read into buff. ! 45: */ ! 46: qread() ! 47: { ! 48: return (NULL != (buf = getline(ifp, &line))); ! 49: } ! 50: ! 51: /* ! 52: * this routine breaks command_string into individual tokens, putting ! 53: * pointers to these tokens into the array tokenlist. ! 54: * no more than maxtoken tokens will be found. ! 55: * Note that the string is modified to place '\0' over ! 56: * token separators. The tokenlist points into the string. ! 57: * Tokens are separated by spaces, tabs and commas. ! 58: */ ! 59: void ! 60: tokenize(s, tokenlist, maxtoken) ! 61: register char *s; ! 62: char *tokenlist[]; ! 63: int maxtoken; ! 64: { ! 65: register int state, i; ! 66: ! 67: for (i = 0; i < maxtoken; i++) ! 68: tokenlist[i] = NULL; ! 69: ! 70: for (i = state = 0; ; s++) { ! 71: switch (*s) { ! 72: case ' ': ! 73: case '\t': ! 74: *s = state = 0; ! 75: continue; ! 76: case ',': ! 77: *s = state = 0; ! 78: if (maxtoken > ++i) ! 79: continue; ! 80: fprintf(stderr, "Too many tokens in line %d\n", line); ! 81: errCt++; ! 82: case 0: ! 83: return; ! 84: } ! 85: if (!state) { /* was in whitespace */ ! 86: tokenlist[i] = s; ! 87: state = 1; /* in token */ ! 88: } ! 89: } ! 90: } ! 91: ! 92: /* ! 93: * Count lines and fields allocate space. ! 94: */ ! 95: void ! 96: pass1() ! 97: { ! 98: register char *p, c; ! 99: int sw, pos, nameCt, nlines, repits; ! 100: ! 101: fprintf(ofp, "/*\n"); ! 102: fprintf(ofp, " * This file generated by scn from %s\n", fileName); ! 103: fprintf(ofp, " */\n"); ! 104: ! 105: for (nlines = repits = nameCt = 0; qread(); ) { ! 106: char *token[MAXTOKEN]; /* name len default verifyProc */ ! 107: int len; ! 108: ! 109: if ('%' == buf[0]) { /* control statemnet */ ! 110: switch (buf[1]) { ! 111: case '%': /* done with preface */ ! 112: filePos = ftell(ifp); ! 113: break; ! 114: case 'h': /* help line */ ! 115: continue; ! 116: case ' ': /* group line */ ! 117: case 'g': ! 118: if (2 == sscanf(buf + 2, "%d %d", ! 119: &nlines, &repits)) ! 120: continue; ! 121: default: ! 122: fatal("Improper control line line %d", line); ! 123: } ! 124: break; ! 125: } ! 126: tokenize(buf, token, MAXTOKEN); ! 127: if (token[0] != NULL) { ! 128: if (!(len = abs(atoi(token[1])))) ! 129: len = abs(atoi(token[2])); ! 130: len++; ! 131: if (nlines) { ! 132: nlines--; ! 133: nameCt += repits; ! 134: fprintf(hfp, ! 135: "extern char %s[%d][%d];\n", ! 136: token[0], ! 137: repits, ! 138: len); ! 139: fprintf(ofp, ! 140: "char %s[%d][%d];\n", ! 141: token[0], ! 142: repits, ! 143: len); ! 144: } ! 145: else { ! 146: nameCt++; ! 147: fprintf(hfp, "extern char %s[%d];\n", ! 148: token[0], len); ! 149: fprintf(ofp, "char %s[%d];\n", ! 150: token[0], len); ! 151: } ! 152: } ! 153: else { ! 154: errCt++; ! 155: fprintf(stderr, "No field in line %d\n", line); ! 156: } ! 157: if (NULL != token[3]) ! 158: fprintf(ofp, "extern int (*%s)();\n", token[3]); ! 159: if ((NULL != token[2]) && (NULL != token[1]) && ! 160: ((len = atoi(token[1])) > 0) && ! 161: (strlen(token[2]) > len)) { ! 162: errCt++; ! 163: fprintf(stderr, "default %s greater then %d line %d\n", ! 164: token[2], len, line); ! 165: } ! 166: } ! 167: ! 168: fprintf(ofp, "/* C tables for the screen:\n"); ! 169: while (qread()) { ! 170: pos = sw = 0; ! 171: for (p = buf; c = *p; p++, pos++) { ! 172: if (c == fieldDesig) ! 173: locCnt++; ! 174: else if (!isspace(c)) ! 175: sw = 1; ! 176: else if ('\t' == c) ! 177: pos |= 7; ! 178: } ! 179: backCnt += sw; ! 180: if (pos > 80) { ! 181: errCt++; ! 182: fprintf(stderr, "Line %d too long", line); ! 183: continue; ! 184: } ! 185: for (p = buf; c = *p++; sw = c) { ! 186: if ((('/' == c) && ('*' == sw)) || ! 187: (('/' == sw) && ('*' == c))) ! 188: c = '?'; ! 189: fputc(c, ofp); ! 190: } ! 191: fputc('\n', ofp); ! 192: } ! 193: fprintf(ofp, " */\n\n"); ! 194: if (nameCt != locCnt) ! 195: fatal("%d field names but %d fileds", nameCt, locCnt); ! 196: if (errCt) ! 197: exit(1); ! 198: if (locCnt) ! 199: locTab = alloc(locCnt * sizeof(loc)); ! 200: } ! 201: ! 202: /* ! 203: * Put together tables. ! 204: */ ! 205: void ! 206: pass2() ! 207: { ! 208: int dataLine, row, lc; ! 209: ! 210: fseek(ifp, filePos, 0); /* pass %% */ ! 211: ! 212: fprintf(ofp, "/*\n"); ! 213: fprintf(ofp, " * Screen background data.\n"); ! 214: fprintf(ofp, " */\n"); ! 215: fprintf(ofp, "#include <scn.h>\n\n"); ! 216: fprintf(ofp, "struct backGrnd %s_data[] = {\n", fileName); ! 217: ! 218: for (lc = row = dataLine = 0; qread(); row++) { ! 219: register char *p, c, *p1; ! 220: int spos, pos; ! 221: ! 222: for ((p1 = NULL), (p = buf), (pos = 0); c = *p; pos++, p++) { ! 223: if (c == fieldDesig) { ! 224: locTab[lc].row = row; ! 225: locTab[lc].col = pos; ! 226: *p = ' '; ! 227: lc++; ! 228: continue; ! 229: } ! 230: switch (c) { ! 231: case '\t': ! 232: pos |= 7; ! 233: case ' ': ! 234: continue; ! 235: } ! 236: if (NULL == p1) { /* mark start of line */ ! 237: spos = pos; ! 238: p1 = p; ! 239: } ! 240: } ! 241: if (NULL == p1) /* no printable data on line */ ! 242: continue; ! 243: ! 244: for (p--; isspace(*p); p--) /* trim line */ ! 245: *p = '\0'; ! 246: ! 247: fputc('"', ofp); ! 248: for (pos = spos; c = *p1; p1++) { ! 249: switch (c) { ! 250: case '\t': /* raw mode ignores tabs */ ! 251: do { /* make them spaces */ ! 252: fputc(' ', ofp); ! 253: } while (++pos & 7); ! 254: continue; ! 255: case '\\': ! 256: case '"': ! 257: fputc('\\', ofp); ! 258: default: ! 259: fputc(c, ofp); ! 260: } ! 261: pos++; ! 262: } ! 263: fprintf(ofp, "\",\n\t %d, %d,\n", row, spos); ! 264: } ! 265: fprintf(ofp, "NULL\n"); ! 266: fprintf(ofp, "};\n\n"); ! 267: } ! 268: ! 269: #define nc(t, x) ((NULL != t) ? t : x) ! 270: void ! 271: pass3() ! 272: { ! 273: register int i; ! 274: int nlines, skipout; ! 275: ! 276: rewind(ifp); ! 277: ! 278: fprintf(ofp, "/*\n"); ! 279: fprintf(ofp, " * Screen data location table.\n"); ! 280: fprintf(ofp, " */\n"); ! 281: fprintf(ofp, "struct loc %s_locs[] = {\n", fileName); ! 282: for (skipout = nlines = i = 0; i < locCnt; i++) { ! 283: char *token[MAXTOKEN]; /* name len default verifyProc */ ! 284: char helpMsg[80]; ! 285: int skip, len, slines, j, repits; ! 286: ! 287: helpMsg[0] = 0; ! 288: for (qread(); '%' == buf[0]; qread()) { ! 289: switch (buf[1]) { ! 290: case ' ': ! 291: case 'g': ! 292: sscanf(buf + 2, "%d %d", &nlines, &repits); ! 293: j = 0; ! 294: slines = nlines; ! 295: skipout = nlines * repits; ! 296: filePos = ftell(ifp); ! 297: break; ! 298: case 'h': ! 299: strcpy(helpMsg, buf + 3); ! 300: } ! 301: } ! 302: tokenize(buf, token, MAXTOKEN); ! 303: if (NULL == token[1]) /* no length given */ ! 304: len = 79 - locTab[i].col; ! 305: else ! 306: len = atoi(token[1]); ! 307: ! 308: if (skipout) ! 309: skipout--; ! 310: skip = 0; ! 311: if (NULL != token[4]) { ! 312: if (strcmp(token[4], "group")) ! 313: skip = atoi(token[4]); ! 314: else ! 315: skip = skipout; ! 316: } ! 317: else if (!len) ! 318: skip = atoi(token[2]); ! 319: ! 320: if (nlines) { ! 321: if (len <= 0) ! 322: fprintf(ofp, /* field is default */ ! 323: "\t%s[%d], %d, %s[%d], %s, %d, %d, %d,", ! 324: token[0], j, ! 325: -len, ! 326: ((len && NULL != token[2]) ? ! 327: token[2] : token[0]), ! 328: j, ! 329: nc(token[3], "NULL"), ! 330: locTab[i].row, ! 331: locTab[i].col, ! 332: skip); ! 333: else ! 334: fprintf(ofp, ! 335: "\t%s[%d], %d, \"%s\", %s, %d, %d, %d,", ! 336: token[0], j, ! 337: len, ! 338: nc(token[2], ""), ! 339: nc(token[3], "NULL"), ! 340: locTab[i].row, ! 341: locTab[i].col, ! 342: skip); ! 343: ! 344: if (!--nlines && (++j != repits)) { ! 345: fseek(ifp, filePos, 0); ! 346: nlines = slines; ! 347: } ! 348: } ! 349: else { ! 350: if (len <= 0) ! 351: fprintf(ofp, ! 352: "\t%s, %d, %s, %s, %d, %d, %d,", ! 353: token[0], ! 354: -len, ! 355: ((len && NULL != token[2]) ? ! 356: token[2] : token[0]), ! 357: nc(token[3], "NULL"), ! 358: locTab[i].row, ! 359: locTab[i].col, ! 360: skip); ! 361: else ! 362: fprintf(ofp, ! 363: "\t%s, %d, \"%s\", %s, %d, %d, %d,", ! 364: token[0], ! 365: len, ! 366: nc(token[2], ""), ! 367: nc(token[3], "NULL"), ! 368: locTab[i].row, ! 369: locTab[i].col, ! 370: skip); ! 371: } ! 372: if (helpMsg[0]) ! 373: fprintf(ofp, "\n\t\"%s\",\n", helpMsg); ! 374: else ! 375: fprintf(ofp, " NULL,\n"); ! 376: } ! 377: fprintf(ofp, "\tNULL\n};\n"); ! 378: } ! 379: ! 380: /* ! 381: * Process args and call phases. ! 382: */ ! 383: main(argc, argv) ! 384: char **argv; ! 385: { ! 386: register char *arg; ! 387: ! 388: while (NULL != (arg = *++argv)) { ! 389: if ('-' == *arg) { ! 390: switch (*++arg) { ! 391: case 'f': ! 392: fieldDesig = *++arg; ! 393: break; ! 394: default: ! 395: Usage(); ! 396: } ! 397: continue; ! 398: } ! 399: fileName = arg; ! 400: } ! 401: if (NULL == fileName) ! 402: Usage(); ! 403: ! 404: ifp = xopen(fileName, "r"); ! 405: if (NULL != (arg = strrchr(fileName, '/'))) ! 406: fileName = arg + 1; ! 407: if (NULL != (arg = strrchr(fileName, '.'))) ! 408: *arg = '\0'; ! 409: outFile = alloc(strlen(fileName) + 3); ! 410: sprintf(outFile, "%s.c", fileName); ! 411: ofp = xopen(outFile, "w"); ! 412: sprintf(outFile, "%s.h", fileName); ! 413: hfp = xopen(outFile, "w"); ! 414: fprintf(hfp, "/*\n"); ! 415: fprintf(hfp, " * This file generated by scn from %s\n", fileName); ! 416: fprintf(hfp, " */\n"); ! 417: fprintf(hfp, "#include <scn.h>\n\n"); ! 418: fprintf(hfp, "extern loc %s_locs[];\n", fileName); ! 419: fprintf(hfp, "extern backGrnd %s_data[];\n", fileName); ! 420: pass1(); ! 421: pass2(); ! 422: pass3(); ! 423: exit(0); ! 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.