1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * University Copyright- Copyright (c) 1982, 1986, 1988 35 * The Regents of the University of California 36 * All Rights Reserved 37 * 38 * University Acknowledgment- Portions of this document are derived from 39 * software developed by the University of California, Berkeley, and its 40 * contributors. 41 */ 42 43 /* 44 * drive hp2621 terminal 45 * just to see stuff quickly. like troff -a 46 */ 47 48 /* 49 output language from troff: 50 all numbers are character strings 51 52 sn size in points 53 fn font as number from 1-n 54 cx ascii character x 55 Cxyz funny char xyz. terminated by white space 56 Hn go to absolute horizontal position n 57 Vn go to absolute vertical position n (down is positive) 58 hn go n units horizontally (relative) 59 vn ditto vertically 60 nnc move right nn (exactly 2 digits!), then print c 61 (this wart is an optimization that shrinks output file size 62 about 35% and run-time about 15% while preserving ascii-ness) 63 w paddable word space - no action needed 64 nb a end of line (information only -- no action needed) 65 b = space before line, a = after 66 pn begin page n 67 #...\n comment 68 Dt ...\n draw operation 't': 69 Dl x y line from here by x,y 70 Dc d circle of diameter d with left side here 71 De x y ellipse of axes x,y with left side here 72 Da x y u v arc counter-clockwise from here to u,v from center 73 with center x,y from here 74 D~ x y x y ... wiggly line by x,y then x,y ... 75 x ...\n device control functions: 76 x i init 77 x T s name of device is s 78 x r n h v resolution is n/inch 79 h = min horizontal motion, v = min vert 80 x p pause (can restart) 81 x s stop -- done for ever 82 x t generate trailer 83 x f n s font position n contains font s 84 x H n set character height to n 85 x S n set character slant to n 86 87 Subcommands like "i" are often spelled out like "init". 88 */ 89 90 #include <stdio.h> 91 #include <signal.h> 92 #include <ctype.h> 93 94 #include "dev.h" 95 #define NFONT 10 96 97 int output = 0; /* do we do output at all? */ 98 int nolist = 0; /* output page list if > 0 */ 99 int olist[20]; /* pairs of page numbers */ 100 101 int erase = 1; 102 float aspect = 1.5; /* default aspect ratio */ 103 int wflag = 0; /* wait, looping, for new input if on */ 104 void (*sigint)(); 105 void (*sigquit)(); 106 void done(); 107 108 struct dev dev; 109 struct font *fontbase[NFONT]; 110 short psizes[] ={ 11, 16, 22, 36, 0}; /* approx sizes available */ 111 short *pstab = psizes; 112 int nsizes = 1; 113 int nfonts; 114 int smnt; /* index of first special font */ 115 int nchtab; 116 char *chname; 117 short *chtab; 118 char *fitab[NFONT]; 119 char *widthtab[NFONT]; /* widtab would be a better name */ 120 char *codetab[NFONT]; /* device codes */ 121 122 #define FATAL 1 123 #define BMASK 0377 124 int dbg = 0; 125 int res = 972; /* input assumed computed according to this resolution */ 126 /* initial value to avoid 0 divide */ 127 FILE *tf = stdout; /* output file */ 128 char *fontdir = "/usr/lib/font"; 129 extern char devname[]; 130 131 FILE *fp = stdin; /* input file pointer */ 132 133 int nowait = 0; /* 0 => wait at bottom of each page */ 134 135 main(argc, argv) 136 char *argv[]; 137 { 138 char buf[BUFSIZ]; 139 140 setbuf(stdout, buf); 141 while (argc > 1 && argv[1][0] == '-') { 142 switch (argv[1][1]) { 143 case 'a': 144 aspect = atof(&argv[1][2]); 145 break; 146 case 'e': 147 erase = 0; 148 break; 149 case 'o': 150 outlist(&argv[1][2]); 151 break; 152 case 'd': 153 dbg = atoi(&argv[1][2]); 154 if (dbg == 0) dbg = 1; 155 break; 156 case 'w': /* no wait at bottom of page */ 157 nowait = 1; 158 break; 159 } 160 argc--; 161 argv++; 162 } 163 164 if (argc <= 1) 165 conv(stdin); 166 else 167 while (--argc > 0) { 168 if (strcmp(*++argv, "-") == 0) 169 fp = stdin; 170 else if ((fp = fopen(*argv, "r")) == NULL) 171 error(FATAL, "can't open %s", *argv); 172 conv(fp); 173 fclose(fp); 174 } 175 done(); 176 } 177 178 outlist(s) /* process list of page numbers to be printed */ 179 char *s; 180 { 181 int n1, n2, i; 182 183 nolist = 0; 184 while (*s) { 185 n1 = 0; 186 if (isdigit((unsigned char)*s)) 187 do 188 n1 = 10 * n1 + *s++ - '0'; 189 while (isdigit((unsigned char)*s)); 190 else 191 n1 = -9999; 192 n2 = n1; 193 if (*s == '-') { 194 s++; 195 n2 = 0; 196 if (isdigit((unsigned char)*s)) 197 do 198 n2 = 10 * n2 + *s++ - '0'; 199 while (isdigit((unsigned char)*s)); 200 else 201 n2 = 9999; 202 } 203 olist[nolist++] = n1; 204 olist[nolist++] = n2; 205 if (*s != '\0') 206 s++; 207 } 208 olist[nolist] = 0; 209 if (dbg) 210 for (i=0; i<nolist; i += 2) 211 printf("%3d %3d\n", olist[i], olist[i+1]); 212 } 213 214 in_olist(n) /* is n in olist? */ 215 int n; 216 { 217 int i; 218 219 if (nolist == 0) 220 return(1); /* everything is included */ 221 for (i = 0; i < nolist; i += 2) 222 if (n >= olist[i] && n <= olist[i+1]) 223 return(1); 224 return(0); 225 } 226 227 conv(fp) 228 register FILE *fp; 229 { 230 register int c, k; 231 int m, n, i, n1, m1; 232 char str[100], buf[300]; 233 234 while ((c = getc(fp)) != EOF) { 235 switch (c) { 236 case '\n': /* when input is text */ 237 case ' ': 238 case 0: /* occasional noise creeps in */ 239 break; 240 case '{': /* push down current environment */ 241 t_push(); 242 break; 243 case '}': 244 t_pop(); 245 break; 246 case '0': case '1': case '2': case '3': case '4': 247 case '5': case '6': case '7': case '8': case '9': 248 /* two motion digits plus a character */ 249 hmot((c-'0')*10 + getc(fp)-'0'); 250 put1(getc(fp)); 251 break; 252 case 'c': /* single ascii character */ 253 put1(getc(fp)); 254 break; 255 case 'C': 256 fscanf(fp, "%s", str); 257 put1s(str); 258 break; 259 case 't': /* straight text */ 260 fgets(buf, sizeof(buf), fp); 261 t_text(buf); 262 break; 263 case 'D': /* draw function */ 264 fgets(buf, sizeof(buf), fp); 265 switch (buf[0]) { 266 case 'l': /* draw a line */ 267 sscanf(buf+1, "%d %d", &n, &m); 268 drawline(n, m, "."); 269 break; 270 case 'c': /* circle */ 271 sscanf(buf+1, "%d", &n); 272 drawcirc(n); 273 break; 274 case 'e': /* ellipse */ 275 sscanf(buf+1, "%d %d", &m, &n); 276 drawellip(m, n); 277 break; 278 case 'a': /* arc */ 279 sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 280 drawarc(n, m, n1, m1); 281 break; 282 case '~': /* wiggly line */ 283 drawwig(buf+1); 284 break; 285 default: 286 error(FATAL, "unknown drawing function %s\n", buf); 287 break; 288 } 289 break; 290 case 's': 291 fscanf(fp, "%d", &n); /* ignore fractional sizes */ 292 setsize(t_size(n)); 293 break; 294 case 'f': 295 fscanf(fp, "%s", str); 296 setfont(t_font(str)); 297 break; 298 case 'H': /* absolute horizontal motion */ 299 /* fscanf(fp, "%d", &n); */ 300 while ((c = getc(fp)) == ' ') 301 ; 302 k = 0; 303 do { 304 k = 10 * k + c - '0'; 305 } while (isdigit(c = getc(fp))); 306 ungetc(c, fp); 307 hgoto(k); 308 break; 309 case 'h': /* relative horizontal motion */ 310 /* fscanf(fp, "%d", &n); */ 311 while ((c = getc(fp)) == ' ') 312 ; 313 k = 0; 314 do { 315 k = 10 * k + c - '0'; 316 } while (isdigit(c = getc(fp))); 317 ungetc(c, fp); 318 hmot(k); 319 break; 320 case 'w': /* word space */ 321 putc(' ', stdout); 322 break; 323 case 'V': 324 fscanf(fp, "%d", &n); 325 vgoto(n); 326 break; 327 case 'v': 328 fscanf(fp, "%d", &n); 329 vmot(n); 330 break; 331 case 'p': /* new page */ 332 fscanf(fp, "%d", &n); 333 t_page(n); 334 break; 335 case 'n': /* end of line */ 336 while (getc(fp) != '\n') 337 ; 338 t_newline(); 339 break; 340 case '#': /* comment */ 341 while (getc(fp) != '\n') 342 ; 343 break; 344 case 'x': /* device control */ 345 devcntrl(fp); 346 break; 347 default: 348 error(!FATAL, "unknown input character %o %c\n", c, c); 349 done(); 350 } 351 } 352 } 353 354 devcntrl(fp) /* interpret device control functions */ 355 FILE *fp; 356 { 357 char str[20]; 358 int c, n; 359 360 fscanf(fp, "%s", str); 361 switch (str[0]) { /* crude for now */ 362 case 'i': /* initialize */ 363 fileinit(); 364 t_init(0); 365 break; 366 case 'T': /* device name */ 367 fscanf(fp, "%s", devname); 368 break; 369 case 't': /* trailer */ 370 t_trailer(); 371 break; 372 case 'p': /* pause -- can restart */ 373 t_reset('p'); 374 break; 375 case 's': /* stop */ 376 t_reset('s'); 377 break; 378 case 'r': /* resolution assumed when prepared */ 379 fscanf(fp, "%d", &res); 380 break; 381 case 'f': /* font used */ 382 fscanf(fp, "%d %s", &n, str); 383 loadfont(n, str); 384 break; 385 } 386 while (getc(fp) != '\n') /* skip rest of input line */ 387 ; 388 } 389 390 fileinit() /* read in font and code files, etc. */ 391 { 392 } 393 394 fontprint(i) /* debugging print of font i (0,...) */ 395 { 396 } 397 398 loadcode(n, nw) /* load codetab on position n (0...); #chars is nw */ 399 int n, nw; 400 { 401 } 402 403 loadfont(n, s) /* load font info for font s on position n (1...) */ 404 int n; 405 char *s; 406 { 407 } 408 409 error(f, s, a1, a2, a3, a4, a5, a6, a7) 410 char *s; 411 { 412 fprintf(stderr, "ta: "); 413 fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 414 fprintf(stderr, "\n"); 415 if (f) 416 exit(1); 417 } 418 419 420 /* 421 Here beginneth all the stuff that really depends 422 on the 202 (we hope). 423 */ 424 425 426 char devname[20] = "hp2621"; 427 428 #define ESC 033 429 #define HOME 'H' 430 #define CLEAR 'J' 431 #define FF 014 432 433 int size = 1; 434 int font = 1; /* current font */ 435 int hpos; /* horizontal position where we are supposed to be next (left = 0) */ 436 int vpos; /* current vertical position (down positive) */ 437 438 int horig; /* h origin of current block; hpos rel to this */ 439 int vorig; /* v origin of current block; vpos rel to this */ 440 441 int DX = 10; /* step size in x for drawing */ 442 int DY = 10; /* step size in y for drawing */ 443 int drawdot = '.'; /* draw with this character */ 444 int drawsize = 1; /* shrink by this factor when drawing */ 445 446 t_init(reinit) /* initialize device */ 447 int reinit; 448 { 449 int i, j; 450 451 fflush(stdout); 452 hpos = vpos = 0; 453 } 454 455 #define MAXSTATE 5 456 457 struct state { 458 int ssize; 459 int sfont; 460 int shpos; 461 int svpos; 462 int shorig; 463 int svorig; 464 }; 465 struct state state[MAXSTATE]; 466 struct state *statep = state; 467 468 t_push() /* begin a new block */ 469 { 470 hflush(); 471 statep->ssize = size; 472 statep->sfont = font; 473 statep->shorig = horig; 474 statep->svorig = vorig; 475 statep->shpos = hpos; 476 statep->svpos = vpos; 477 horig = hpos; 478 vorig = vpos; 479 hpos = vpos = 0; 480 if (statep++ >= state+MAXSTATE) 481 error(FATAL, "{ nested too deep"); 482 hpos = vpos = 0; 483 } 484 485 t_pop() /* pop to previous state */ 486 { 487 if (--statep < state) 488 error(FATAL, "extra }"); 489 size = statep->ssize; 490 font = statep->sfont; 491 hpos = statep->shpos; 492 vpos = statep->svpos; 493 horig = statep->shorig; 494 vorig = statep->svorig; 495 } 496 497 int np; /* number of pages seen */ 498 int npmax; /* high-water mark of np */ 499 int pgnum[40]; /* their actual numbers */ 500 long pgadr[40]; /* their seek addresses */ 501 502 t_page(n) /* do whatever new page functions */ 503 { 504 long ftell(); 505 int c, m, i; 506 char buf[100], *bp; 507 508 pgnum[np++] = n; 509 pgadr[np] = ftell(fp); 510 if (np > npmax) 511 npmax = np; 512 if (output == 0) { 513 output = in_olist(n); 514 t_init(1); 515 return; 516 } 517 /* have just printed something, and seen p<n> for next one */ 518 putpage(); 519 fflush(stdout); 520 if (nowait) 521 return; 522 523 next: 524 for (bp = buf; (*bp = readch()); ) 525 if (*bp++ == '\n') 526 break; 527 *bp = 0; 528 switch (buf[0]) { 529 case 0: 530 done(); 531 break; 532 case '\n': 533 output = in_olist(n); 534 t_init(1); 535 return; 536 case '!': 537 callunix(&buf[1]); 538 fputs("!\n", stderr); 539 break; 540 case 'e': 541 erase = 1 - erase; 542 break; 543 case 'w': 544 wflag = 1 - wflag; 545 break; 546 case 'a': 547 aspect = atof(&buf[1]); 548 break; 549 case '-': 550 case 'p': 551 m = atoi(&buf[1]) + 1; 552 if (fp == stdin) { 553 fputs("you can't; it's not a file\n", stderr); 554 break; 555 } 556 if (np - m <= 0) { 557 fputs("too far back\n", stderr); 558 break; 559 } 560 np -= m; 561 fseek(fp, pgadr[np], 0); 562 output = 1; 563 t_init(1); 564 return; 565 case '0': case '1': case '2': case '3': case '4': 566 case '5': case '6': case '7': case '8': case '9': 567 m = atoi(&buf[0]); 568 for (i = 0; i < npmax; i++) 569 if (m == pgnum[i]) 570 break; 571 if (i >= npmax || fp == stdin) { 572 fputs("you can't\n", stderr); 573 break; 574 } 575 np = i + 1; 576 fseek(fp, pgadr[np], 0); 577 output = 1; 578 t_init(1); 579 return; 580 case 'o': 581 outlist(&buf[1]); 582 output = 0; 583 t_init(1); 584 return; 585 case '?': 586 fputs("!cmd unix cmd\n", stderr); 587 fputs("p print this page again\n", stderr); 588 fputs("-n go back n pages\n", stderr); 589 fputs("n print page n (previously printed)\n", stderr); 590 fputs("o... set the -o output list to ...\n", stderr); 591 fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr); 592 fputs("an sets aspect ratio to n\n", stderr); 593 break; 594 default: 595 fputs("?\n", stderr); 596 break; 597 } 598 goto next; 599 } 600 601 putpage() 602 { 603 int i, j, k; 604 605 fflush(stdout); 606 } 607 608 t_newline() /* do whatever for the end of a line */ 609 { 610 printf("\n"); 611 hpos = 0; 612 } 613 614 t_size(n) /* convert integer to internal size number*/ 615 int n; 616 { 617 } 618 619 t_font(s) /* convert string to internal font number */ 620 char *s; 621 { 622 } 623 624 t_text(s) /* print string s as text */ 625 char *s; 626 { 627 int c, w=0; 628 char str[100]; 629 630 if (!output) 631 return; 632 while ((c = *s++) != '\n') { 633 if (c == '\\') { 634 switch (c = *s++) { 635 case '\\': 636 case 'e': 637 put1('\\'); 638 break; 639 case '(': 640 str[0] = *s++; 641 str[1] = *s++; 642 str[2] = '\0'; 643 put1s(str); 644 break; 645 } 646 } else { 647 put1(c); 648 } 649 hmot(w); 650 } 651 } 652 653 t_reset(c) 654 { 655 int n; 656 657 output = 1; 658 fflush(stdout); 659 if (c == 's') 660 t_page(9999); 661 } 662 663 t_trailer() 664 { 665 } 666 667 hgoto(n) 668 { 669 hpos = n; /* this is where we want to be */ 670 /* before printing a character, */ 671 /* have to make sure it's true */ 672 } 673 674 hmot(n) /* generate n units of horizontal motion */ 675 int n; 676 { 677 hgoto(hpos + n); 678 } 679 680 hflush() /* actual horizontal output occurs here */ 681 { 682 } 683 684 vgoto(n) 685 { 686 vpos = n; 687 } 688 689 vmot(n) /* generate n units of vertical motion */ 690 int n; 691 { 692 vgoto(vpos + n); /* ignores rounding */ 693 } 694 695 put1s(s) /* s is a funny char name */ 696 char *s; 697 { 698 int i; 699 char *p; 700 extern char *spectab[]; 701 static char prev[10] = ""; 702 static int previ; 703 704 if (!output) 705 return; 706 if (strcmp(s, prev) != 0) { 707 previ = -1; 708 for (i = 0; spectab[i] != 0; i += 2) 709 if (strcmp(spectab[i], s) == 0) { 710 strcpy(prev, s); 711 previ = i; 712 break; 713 } 714 } 715 if (previ >= 0) { 716 for (p = spectab[previ+1]; *p; p++) 717 putc(*p, stdout); 718 } else 719 prev[0] = 0; 720 } 721 722 put1(c) /* output char c */ 723 int c; 724 { 725 if (!output) 726 return; 727 putc(c, stdout); 728 } 729 730 setsize(n) /* set point size to n (internal) */ 731 int n; 732 { 733 } 734 735 t_fp(n, s) /* font position n now contains font s */ 736 int n; 737 char *s; 738 { 739 } 740 741 setfont(n) /* set font to n */ 742 int n; 743 { 744 } 745 746 void done() 747 { 748 output = 1; 749 putpage(); 750 fflush(stdout); 751 exit(0); 752 } 753 754 callunix(line) 755 char line[]; 756 { 757 int rc, status, unixpid; 758 if( (unixpid=fork())==0 ) { 759 signal(SIGINT,sigint); signal(SIGQUIT,sigquit); 760 close(0); dup(2); 761 execl("/bin/sh", "-sh", "-c", line, 0); 762 exit(255); 763 } 764 else if(unixpid == -1) 765 return; 766 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); 767 while( (rc = wait(&status)) != unixpid && rc != -1 ) ; 768 signal(SIGINT,(void(*)())done); signal(SIGQUIT,(void(*)())sigquit); 769 } 770 } 771 772 readch(){ 773 char c; 774 if (read(2,&c,1)<1) c=0; 775 return(c); 776 } 777 778 char *spectab[] ={ 779 "em", "-", 780 "hy", "-", 781 "en", "-", 782 "ru", "_", 783 "l.", ".", 784 "br", "|", 785 "vr", "|", 786 "fm", "'", 787 "or", "|", 788 0, 0, 789 }; 790