|
|
1.1 ! root 1: /* Copyright (c) 1988 AT&T */ ! 2: /* All Rights Reserved */ ! 3: ! 4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 5: /* The copyright notice above does not evidence any */ ! 6: /* actual or intended publication of such source code. */ ! 7: ! 8: /* @(#)picasso:main.c 1.0 */ ! 9: ! 10: #include <ctype.h> ! 11: #include <signal.h> ! 12: #include <sys/types.h> ! 13: #include <sys/stat.h> ! 14: #include "picasso.h" ! 15: #include "y.tab.h" ! 16: ! 17: extern int yydebug; ! 18: ! 19: YYSTYPE origin; ! 20: obj *objhead = NULL; ! 21: obj *objtail = NULL; ! 22: ! 23: Attr *attr = NULL; /* attributes stored here as collected */ ! 24: int nattrlist = 0; ! 25: int nattr = 0; /* number of entries in attr_list */ ! 26: ! 27: Text *text = NULL; /* text strings stored here as collected */ ! 28: int ntextlist = 0; /* size of text[] array */ ! 29: int ntext = 0; ! 30: int ntext1 = 0; /* record ntext here on entry to each figure */ ! 31: ! 32: float *exprlist = NULL; ! 33: int nexprlist = 0; ! 34: int nexpr = 0; ! 35: float curx = 0; ! 36: float cury = 0; ! 37: ! 38: rgb *rgbtable = NULL; ! 39: int nrgbtable = 0; ! 40: int nrgb = 0; ! 41: ! 42: int hvmode = R_DIR; /* R => left->right, D => top->bottom, etc. */ ! 43: int codegen = 0; /* 1=>output for this picture; 0=>no output */ ! 44: int PEseen = 0; /* 1=> PE seen during parsing */ ! 45: int pass_thru = 0; /* 1=> prepare output to go through troff */ ! 46: int nosqueeze = 0; /* 0=> translate/scale to fit page */ ! 47: int objbuf = 0; /* >0 => print out objects as buffer fills */ ! 48: int pic_compat = 0; /* !0 => interpret input PIC-style */ ! 49: int parsing = 0; /* controls entrance to eqn pipeline */ ! 50: int draftlayer= 0; ! 51: int margin = 1; /* margin (in points) around a picture */ ! 52: float magnification = 1.0; ! 53: float eqn_move = .03; /* vertical adjustment for eqn stuff */ ! 54: int verbose = 0; ! 55: int lineno = 0; ! 56: int batch = 0; ! 57: char *filename = "-"; ! 58: int synerr = 0; ! 59: int anyerr = 0; /* becomes 1 if synerr ever 1 */ ! 60: char *cmdname; ! 61: float Gbox[4] = { 32767, 32767, -32767, -32767 }; ! 62: double pght = 11, ! 63: pgwid = 8.5; ! 64: valtype cur_xform[6]; ! 65: FILE *textfp = stdout; ! 66: char *gwblib = GWBFILES; ! 67: char *fontdir = FONTDIR; ! 68: ! 69: main(argc, argv) ! 70: int argc; ! 71: char *argv[]; ! 72: { ! 73: extern int fpecatch(); ! 74: extern double atof(); ! 75: extern char *strchr(); ! 76: extern FILE *tmpfile(); ! 77: extern char *optarg; ! 78: extern int optind; ! 79: int n; ! 80: char *str, buf[20]; ! 81: ! 82: signal(SIGFPE, fpecatch); ! 83: cmdname = argv[0]; ! 84: while ((n = getopt(argc, argv, "b:F:I:l:m:M:p:e:tvx")) != EOF) { ! 85: switch (n) { ! 86: case 'I': ! 87: gwblib = optarg; ! 88: break; ! 89: case 'F': ! 90: fontdir = optarg; ! 91: break; ! 92: case 'b': ! 93: objbuf = atoi(optarg); ! 94: break; ! 95: case 'l': ! 96: draftlayer = -atoi(optarg); ! 97: break; ! 98: case 'm': ! 99: margin = atoi(optarg); ! 100: break; ! 101: case 'M': ! 102: magnification = atof(optarg); ! 103: break; ! 104: case 'e': ! 105: eqn_move = atof(optarg); ! 106: case 'p': ! 107: if ((str=strchr(optarg,'x')) == NULL) { ! 108: if ((pght=atof(optarg)) <= 0) ! 109: pght = 11; ! 110: } ! 111: else { ! 112: if ((pgwid=atof(optarg)) <= 0) ! 113: pgwid = 8.5; ! 114: if ((pght=atof(str+1)) <= 0) ! 115: pght = 11; ! 116: } ! 117: break; ! 118: case 't': ! 119: pass_thru = 1; ! 120: break; ! 121: case 'v': ! 122: verbose = 1; ! 123: break; ! 124: case 'x': ! 125: nosqueeze = 1; ! 126: break; ! 127: } ! 128: } ! 129: batch = (! Xokay()) || pass_thru || nosqueeze; ! 130: if (!batch) { /* if otherwise interactive but stdin is a pipe, ! 131: assume we should batch process the input */ ! 132: struct stat statbuf; ! 133: ! 134: /* ! 135: if (fstat(fileno(stdin), &statbuf) == 0) ! 136: if ((statbuf.st_mode & S_IFMT) == S_IFIFO || ! 137: (statbuf.st_mode & S_IFMT) == S_IFREG) ! 138: */ ! 139: batch = 1; ! 140: } ! 141: if (batch && optind >= argc && isatty(fileno(stdin)) == 1) { ! 142: fprintf(stderr, "usage: %s -t file | troff-pipeline\n\ ! 143: or: %s file > postscript-file\n\ ! 144: or: other-command file | %s options ...\n", argv[0], argv[0], argv[0]); ! 145: exit(1); ! 146: } ! 147: argc -= --optind; ! 148: argv += optind; ! 149: if (pass_thru && (textfp = tmpfile()) == NULL) { ! 150: fprintf(stderr, "%s: can't open internal temporary file\n", ! 151: cmdname); ! 152: exit(1); ! 153: } ! 154: text = (Text *) grow((char *)text, "text", ntextlist += 1000, ! 155: sizeof(Text)); ! 156: attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, ! 157: sizeof(Attr)); ! 158: exprlist = (float *) grow((char *)exprlist, "exprlist", ! 159: nexprlist += 256, sizeof(float)); ! 160: devinit("post"); ! 161: sprintf(buf, "/%d/", getpid()); ! 162: pushsrc(pString, buf); ! 163: definition("pid"); ! 164: origin.o = objhead = (obj *) calloc(1, sizeof(obj)); ! 165: objtail = (obj *) calloc(1, sizeof(obj)); ! 166: objhead->o_next = objtail; ! 167: objtail->o_prev = objhead; ! 168: objhead->o_type = PLACE; ! 169: makevar(tostring("O"),PLACENAME,origin); ! 170: primaries(); ! 171: setdefaults(); ! 172: ! 173: pushsrc(File, curfile = infile); ! 174: if (argc <= 1) { ! 175: curfile->fin = batch ? stdin : NULL; ! 176: curfile->fname = tostring("-"); ! 177: getdata(curfile); ! 178: } else { ! 179: batch = 1; /* because file names specified */ ! 180: while (argc-- > 1) { ! 181: if ((curfile->fin = fopen(*++argv, "r")) == NULL) { ! 182: fprintf(stderr, "%s: can't open %s\n", ! 183: cmdname, *argv); ! 184: exit(1); ! 185: } ! 186: curfile->fname = tostring(*argv); ! 187: getdata(curfile); ! 188: fclose(curfile->fin); ! 189: free(curfile->fname); ! 190: } ! 191: } ! 192: if (!batch) ! 193: Xloop(); ! 194: if (pass_thru) { ! 195: fflush(textfp); ! 196: rewind(textfp); ! 197: while(fgets(buf, BUFSIZ, textfp) != NULL) ! 198: fputs(buf, stdout); ! 199: fclose(textfp); ! 200: } ! 201: else ! 202: if (batch) ! 203: endpl(); ! 204: else ! 205: Xendpl(); ! 206: exit(anyerr); ! 207: } ! 208: ! 209: struct clor { ! 210: char *c_name; ! 211: float c_red; ! 212: float c_green; ! 213: float c_blue; ! 214: unsigned long c_pixel; ! 215: } dfcols[] = { ! 216: { "black", 0., 0., 0., 0 }, /* Indexes 0 and 1 correspond */ ! 217: { "white", 1., 1., 1., 0 }, /* to grayscale values 0 and 1*/ ! 218: { "red", 1., 0., 0., 0 }, /* This "pun" is deliberate; */ ! 219: { "green", 0., 1., 0., 0 }, /* gray output depends on it. */ ! 220: { "blue", 0., 0., 1., 0 }, ! 221: { "yellow", 1., 1., 0., 0 }, ! 222: { "magenta", 1., 0., 1., 0 }, ! 223: { "cyan", 0., 1., 1., 0 }, ! 224: { "lightgrey", 0.6588, 0.6588, 0.6588, 0 }, ! 225: { "navy", 0.1372, 0.1372, 0.5568, 0 }, ! 226: { "skyblue", 0.196, 0.6, 0.8, 0 }, ! 227: { "orange", 0.8, 0.2, 0.2, 0 }, ! 228: { "sienna", 0.5568, 0.4196, 0.1372, 0 }, ! 229: { "palegreen", 0.5607, 0.7372, 0.5607, 0 }, ! 230: { "darkgreen", 0.1843, 0.3098, 0.1843, 0 }, ! 231: { "blueviolet",0.6235, 0.3725, 0.6235, 0 }, ! 232: { NULL, 0., 0., 0., 0 } ! 233: }; ! 234: ! 235: primaries () /* set up initial 8-color color table */ ! 236: { ! 237: int i; ! 238: char *s; ! 239: ! 240: for (i = 0; (s = dfcols[i].c_name) != NULL; i++) ! 241: makeindex(s, dfcols[i].c_red, dfcols[i].c_green, ! 242: dfcols[i].c_blue); ! 243: } ! 244: ! 245: makeindex (s, r, g, b) /* simulate user color definition for s */ ! 246: char *s; ! 247: double r, g, b; ! 248: { ! 249: YYSTYPE v; ! 250: ! 251: exprlist[0] = r; exprlist[1] = g; exprlist[2] = b; nexpr = 3; ! 252: v.f = setrgbindex(); ! 253: makevar(tostring(s), VARNAME, v); ! 254: } ! 255: ! 256: fpecatch() ! 257: { ! 258: fatal("floating point exception"); ! 259: } ! 260: ! 261: char *grow(ptr, name, num, size) /* make array bigger */ ! 262: char *ptr, *name; ! 263: int num, size; ! 264: { ! 265: char *p; ! 266: ! 267: if (ptr == NULL) ! 268: p = malloc(num * size); ! 269: else ! 270: p = realloc(ptr, num * size); ! 271: if (p == NULL) ! 272: fatal("can't grow %s to %d", name, num * size); ! 273: return p; ! 274: } ! 275: ! 276: struct { ! 277: char *name; ! 278: float val; ! 279: short scalable; /* 1 => adjust when scale changes */ ! 280: } defaults[] ={ ! 281: "flatness", 0, 0, ! 282: "miterlimit", 0, 0, ! 283: "linecap", -1, 0, ! 284: "linejoin", -1, 0, ! 285: "textsize", 10, 0, ! 286: "textspace", 12, 0, ! 287: "textcolor", 0, 0, ! 288: "textfont", 0, 0, ! 289: "moveht", HT, 1, ! 290: "movewid", HT, 1, ! 291: "arrowht", HT5, 1, ! 292: "arrowwid", HT10, 1, ! 293: "arrowend", 0, 0, ! 294: "arrowfill", 1, 0, /* arrowhead style */ ! 295: "lineht", HT, 1, ! 296: "linewid", HT, 1, ! 297: "linerad", 0, 1, ! 298: "dashwid", HT10, 1, ! 299: "boxht", HT, 1, ! 300: "boxwid", WID, 1, ! 301: "boxrad", 0, 1, ! 302: "ellipseht", HT, 1, ! 303: "ellipsewid", WID, 1, ! 304: "arcrad", HT2, 1, ! 305: "circlerad", HT2, 1, ! 306: "fillcolor", 0, 0, ! 307: "linecolor", 0, 0, ! 308: "lineweight", 0, 1, ! 309: "curlayer", 0, 0, /* current drawing layer */ ! 310: NULL, 0 ! 311: }; ! 312: ! 313: int top_layer = 0; /* high-water mark */ ! 314: ! 315: setdefaults() /* set default sizes for variables like boxht */ ! 316: { ! 317: int i; ! 318: YYSTYPE v; ! 319: ! 320: for (i = 0; defaults[i].name != NULL; i++) { ! 321: v.f = defaults[i].val; ! 322: makevar(tostring(defaults[i].name), VARNAME, v); ! 323: } ! 324: } ! 325: ! 326: resetvar() /* reset variables listed */ ! 327: { ! 328: int i, j; ! 329: ! 330: if (nattr == 0) { /* none listed, so do all */ ! 331: setdefaults(); ! 332: pic_compat = 0; ! 333: return; ! 334: } ! 335: for (i = 0; i < nattr; i++) { ! 336: if (strcmp(attr[i].a_val.p, "p_i_c") == 0) ! 337: pic_compat = 1; ! 338: else for (j = 0; defaults[j].name != NULL; j++) ! 339: if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) { ! 340: setfval(defaults[j].name, defaults[j].val); ! 341: break; ! 342: } ! 343: } ! 344: } ! 345: ! 346: static float savevars[sizeof defaults / sizeof defaults[0]]; ! 347: ! 348: savepicvars() /* save current values, restore original values */ ! 349: { ! 350: int i; ! 351: char *s; ! 352: ! 353: for (i = 0; (s = defaults[i].name) != NULL; i++) { ! 354: savevars[i] = getfval(s); ! 355: setfval(s, defaults[i].val); ! 356: } ! 357: } ! 358: ! 359: restorepicvars() /* restore values saved above */ ! 360: { ! 361: int i; ! 362: char *s; ! 363: ! 364: for (i = 0; (s = defaults[i].name) != NULL; i++) ! 365: setfval(s, savevars[i]); ! 366: } ! 367: ! 368: checkscale(v) /* adjust default variables dependent on scale */ ! 369: double v; ! 370: { ! 371: int i; ! 372: ! 373: for (i = 1; defaults[i].name != NULL; i++) { ! 374: if (defaults[i].scalable) ! 375: setfval(defaults[i].name, ! 376: defaults[i].val * v); ! 377: } ! 378: } ! 379: ! 380: getdata() ! 381: { ! 382: char *p, buf[1000], buf1[100]; ! 383: int ln; ! 384: int ineqn = 0; ! 385: ! 386: if (curfile->fin == NULL) { /* only happens in interactive mode */ ! 387: batch = 1; ! 388: reset(); ! 389: batch = 0; ! 390: ln = nosqueeze; ! 391: nosqueeze = 1; ! 392: Xopenpl(""); ! 393: Xprint('E'); ! 394: Xallexpose(); ! 395: nosqueeze = ln; ! 396: return; ! 397: } ! 398: curfile->lineno = 0; ! 399: while (fgets(buf, sizeof buf, curfile->fin) != NULL) { ! 400: curfile->lineno++; ! 401: if (*buf == '.' && buf[1] == 'P' && buf[2] == 'S') { ! 402: for (p = &buf[3]; *p == ' '; p++) ! 403: ; ! 404: if (*p++ == '<') { ! 405: Infile svfile; ! 406: svfile = *curfile; ! 407: sscanf(p, "%s", buf1); ! 408: if ((curfile->fin=fopen(buf1, "r")) == NULL) ! 409: fatal("can't open %s", buf1); ! 410: curfile->fname = tostring(buf1); ! 411: getdata(); ! 412: fclose(curfile->fin); ! 413: free(curfile->fname); ! 414: *curfile = svfile; ! 415: if (batch) ! 416: continue; ! 417: else ! 418: break; ! 419: } ! 420: reset(); ! 421: parsing = 1; ! 422: yyparse(); ! 423: parsing = 0; ! 424: anyerr += synerr; ! 425: /* added for PIC compatibility -- 4/18/90 -- DBK */ ! 426: scale_pic(); ! 427: /* end of PIC compatibility addition */ ! 428: /* yylval.i now contains 'E', 'F' or 'N' from .PE etc.*/ ! 429: ! 430: #if 0 ! 431: if (codegen && !synerr) { ! 432: if (batch) { ! 433: openpl(buf+3); ! 434: print(yylval.i); ! 435: closepl(buf+3); /* assumes \n at end */ ! 436: } ! 437: else { ! 438: ln = nosqueeze; ! 439: nosqueeze = 1; ! 440: Xopenpl(buf+3); ! 441: Xprint(yylval.i); ! 442: Xallexpose(); ! 443: nosqueeze = ln; ! 444: } ! 445: break; ! 446: } ! 447: #else ! 448: /* this is a change made 2/20/90 by DBK */ ! 449: /* and a further change 4/13/90 */ ! 450: /* if batch mode ! 451: if some objects and no errors, print page ! 452: read rest of file ! 453: if interactive mode ! 454: if any objects ! 455: display objects ! 456: abandon file ! 457: else ! 458: read more of file */ ! 459: /* behaves same way in batch mode */ ! 460: /* tries to display data up to this point in interactive, but ! 461: throws away rest of file */ ! 462: if (codegen && !synerr && batch) { ! 463: openpl(buf+3); ! 464: print(yylval.i); ! 465: closepl(buf+3); /* assumes \n at end */ ! 466: } ! 467: /* else if (codegen && !batch) { */ ! 468: else if (!batch) { /* no codegen for config */ ! 469: ln = nosqueeze; ! 470: nosqueeze = 1; ! 471: Xopenpl(buf+3); ! 472: Xprint(yylval.i); ! 473: Xallexpose(); ! 474: nosqueeze = ln; ! 475: break; ! 476: } ! 477: #endif ! 478: } ! 479: else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { ! 480: if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { ! 481: free(curfile->fname); ! 482: curfile->fname = tostring(buf1); ! 483: curfile->lineno = ln; /* off by one?? */ ! 484: } ! 485: } ! 486: else if (pass_thru) { ! 487: fputs(buf, textfp); ! 488: if (*buf == '.') /* track .ps, .ft, .vs, .ec */ ! 489: troff(buf); ! 490: else { ! 491: int dumft = 0, dumps = 0; ! 492: while (parse_text(buf, &dumft, &dumps)) ! 493: ; ! 494: } ! 495: } ! 496: if (buf[0] == '.' && buf[1] == 'E' && buf[2] == 'Q') ! 497: ineqn = 1; ! 498: else if (buf[0] == '.' && buf[1] == 'E' && buf[2] == 'N') ! 499: ineqn = 0; ! 500: else if (ineqn == 1) ! 501: scan_delim(buf); ! 502: /* should also check no_eqn--DBK--3/29/90 */ ! 503: } ! 504: } ! 505: ! 506: reset() ! 507: { ! 508: extern int nstack, errno; ! 509: obj *op, *op1; ! 510: int i; ! 511: ! 512: ! 513: if (batch) { ! 514: for (op = objhead->o_next; op != objtail; ) { ! 515: if (op->o_type == BLOCK) ! 516: freesymtab(op->o_val[N_VAL+1].s); ! 517: op1 = op; ! 518: op = op->o_next; ! 519: free(op1); ! 520: } ! 521: for (i = 0; i < ntext; i++) { ! 522: if (text[i].t_val) ! 523: free(text[i].t_val); ! 524: text[i].t_line = 0; ! 525: } ! 526: ntextlines = ntext = ntext1 = 0; ! 527: nstack = 0; ! 528: Gbox[0] = Gbox[1] = 32767; ! 529: Gbox[2] = Gbox[3] = -32767; ! 530: } ! 531: objhead->o_next = objtail; ! 532: objtail->o_prev = objhead; ! 533: nattr = 0; ! 534: objcount = top_layer = 0; ! 535: errno = codegen = synerr = 0; ! 536: curx = cury = 0; ! 537: PEseen = 0; ! 538: hvmode = R_DIR; ! 539: cur_xform[0].f = cur_xform[3].f = 1; ! 540: cur_xform[1].f = cur_xform[2].f = ! 541: cur_xform[4].f = cur_xform[5].f = 0; ! 542: if (!batch) ! 543: Xclosepl(""); ! 544: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.