summaryrefslogtreecommitdiff
path: root/troff/troff.d/ta.c
diff options
context:
space:
mode:
Diffstat (limited to 'troff/troff.d/ta.c')
-rw-r--r--troff/troff.d/ta.c886
1 files changed, 886 insertions, 0 deletions
diff --git a/troff/troff.d/ta.c b/troff/troff.d/ta.c
new file mode 100644
index 0000000000000..c3e9d92b41978
--- /dev/null
+++ b/troff/troff.d/ta.c
@@ -0,0 +1,886 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+
+/* from OpenSolaris "ta.c 1.10 05/06/08 SMI" */
+
+/*
+ * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
+ */
+#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
+#define USED __attribute__ ((used))
+#elif defined __GNUC__
+#define USED __attribute__ ((unused))
+#else
+#define USED
+#endif
+static const char sccsid[] USED = "@(#)/usr/ucb/ta.sl 1.8 (gritter) 12/25/06";
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+/*
+ * drive hp2621 terminal
+ * just to see stuff quickly. like troff -a
+ */
+
+/*
+output language from troff:
+all numbers are character strings
+
+sn size in points
+fn font as number from 1-n
+cx ascii character x
+Cxyz funny char xyz. terminated by white space
+Hn go to absolute horizontal position n
+Vn go to absolute vertical position n (down is positive)
+hn go n units horizontally (relative)
+vn ditto vertically
+nnc move right nn (exactly 2 digits!), then print c
+ (this wart is an optimization that shrinks output file size
+ about 35% and run-time about 15% while preserving ascii-ness)
+w paddable word space - no action needed
+nb a end of line (information only -- no action needed)
+ b = space before line, a = after
+pn begin page n
+#...\n comment
+Dt ...\n draw operation 't':
+ Dl x y line from here by x,y
+ Dc d circle of diameter d with left side here
+ De x y ellipse of axes x,y with left side here
+ Da x y u v arc counter-clockwise from here to u,v from center
+ with center x,y from here
+ D~ x y x y ... wiggly line by x,y then x,y ...
+x ...\n device control functions:
+ x i init
+ x T s name of device is s
+ x r n h v resolution is n/inch
+ h = min horizontal motion, v = min vert
+ x p pause (can restart)
+ x s stop -- done for ever
+ x t generate trailer
+ x f n s font position n contains font s
+ x H n set character height to n
+ x S n set character slant to n
+
+ Subcommands like "i" are often spelled out like "init".
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "dev.h"
+#define NFONT 10
+
+int output = 0; /* do we do output at all? */
+int nolist = 0; /* output page list if > 0 */
+int olist[20]; /* pairs of page numbers */
+
+int erase = 1;
+float aspect = 1.5; /* default aspect ratio */
+int wflag = 0; /* wait, looping, for new input if on */
+void (*sigint)(int);
+void (*sigquit)(int);
+void done(void);
+
+struct dev dev;
+struct font *fontbase[NFONT];
+short psizes[] ={ 11, 16, 22, 36, 0}; /* approx sizes available */
+short *pstab = psizes;
+int nsizes = 1;
+int nfonts;
+int smnt; /* index of first special font */
+int nchtab;
+char *chname;
+short *chtab;
+char *fitab[NFONT];
+char *widthtab[NFONT]; /* widtab would be a better name */
+char *codetab[NFONT]; /* device codes */
+
+#define FATAL 1
+#define BMASK 0377
+int dbg = 0;
+int res = 972; /* input assumed computed according to this resolution */
+ /* initial value to avoid 0 divide */
+FILE *tf; /* output file */
+char *fontdir = FNTDIR;
+#define devname troff_devname
+char devname[20] = "hp2621";
+
+FILE *fp; /* input file pointer */
+
+int nowait = 0; /* 0 => wait at bottom of each page */
+
+
+void drawline(int, int, char *);
+void drawwig(char *);
+void drawcirc(int);
+void drawarc(int, int, int, int);
+void drawellip(int, int);
+
+void outlist(char *);
+int in_olist(int);
+void conv(register FILE *);
+void devcntrl(FILE *);
+void fileinit(void);
+void fontprint(int);
+void loadcode(int, int);
+void loadfont(int, char *);
+void error(int, const char *, ...);
+void t_init(int);
+void t_push(void);
+void t_pop(void);
+void t_page(int);
+void putpage(void);
+void t_newline(void);
+int t_size(int);
+int t_font(char *);
+void t_text(char *);
+void t_reset(int);
+void t_trailer(void);
+void hgoto(int);
+void hmot(int);
+void hflush(void);
+void vgoto(int);
+void vmot(int);
+void put1s(char *);
+void put1(int);
+void setsize(double);
+void t_fp(int, char *);
+void setfont(int);
+void done(void);
+void callunix(char []);
+int readch(void);
+
+static int sget(char *, size_t, FILE *);
+
+int
+main(int argc, char **argv)
+{
+ char buf[BUFSIZ];
+
+ fp = stdin;
+ tf = stdout;
+ setbuf(stdout, buf);
+ while (argc > 1 && argv[1][0] == '-') {
+ switch (argv[1][1]) {
+ case 'a':
+ aspect = atof(&argv[1][2]);
+ break;
+ case 'e':
+ erase = 0;
+ break;
+ case 'o':
+ outlist(&argv[1][2]);
+ break;
+ case 'd':
+ dbg = atoi(&argv[1][2]);
+ if (dbg == 0) dbg = 1;
+ break;
+ case 'w': /* no wait at bottom of page */
+ nowait = 1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (argc <= 1)
+ conv(stdin);
+ else
+ while (--argc > 0) {
+ if (strcmp(*++argv, "-") == 0)
+ fp = stdin;
+ else if ((fp = fopen(*argv, "r")) == NULL)
+ error(FATAL, "can't open %s", *argv);
+ conv(fp);
+ fclose(fp);
+ }
+ done();
+ /*NOTREACHED*/
+ return 0;
+}
+
+void
+outlist(char *s) /* process list of page numbers to be printed */
+{
+ int n1, n2, i;
+
+ nolist = 0;
+ while (*s && nolist < sizeof olist/sizeof *olist - 1) {
+ n1 = 0;
+ if (isdigit((unsigned char)*s))
+ do
+ n1 = 10 * n1 + *s++ - '0';
+ while (isdigit((unsigned char)*s));
+ else
+ n1 = -9999;
+ n2 = n1;
+ if (*s == '-') {
+ s++;
+ n2 = 0;
+ if (isdigit((unsigned char)*s))
+ do
+ n2 = 10 * n2 + *s++ - '0';
+ while (isdigit((unsigned char)*s));
+ else
+ n2 = 9999;
+ }
+ olist[nolist++] = n1;
+ olist[nolist++] = n2;
+ if (*s != '\0')
+ s++;
+ }
+ olist[nolist] = 0;
+ if (dbg)
+ for (i=0; i<nolist; i += 2)
+ printf("%3d %3d\n", olist[i], olist[i+1]);
+}
+
+int
+in_olist(int n) /* is n in olist? */
+{
+ int i;
+
+ if (nolist == 0)
+ return(1); /* everything is included */
+ for (i = 0; i < nolist; i += 2)
+ if (n >= olist[i] && n <= olist[i+1])
+ return(1);
+ return(0);
+}
+
+void
+conv(register FILE *fp)
+{
+ register int c, k;
+ int m, n, n1, m1;
+ char str[4096], buf[4096];
+
+ while ((c = getc(fp)) != EOF) {
+ switch (c) {
+ case '\n': /* when input is text */
+ case ' ':
+ case 0: /* occasional noise creeps in */
+ break;
+ case '{': /* push down current environment */
+ t_push();
+ break;
+ case '}':
+ t_pop();
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* two motion digits plus a character */
+ hmot((c-'0')*10 + getc(fp)-'0');
+ put1(getc(fp));
+ break;
+ case 'c': /* single ascii character */
+ put1(getc(fp));
+ break;
+ case 'C':
+ sget(str, sizeof str, fp);
+ put1s(str);
+ break;
+ case 't': /* straight text */
+ fgets(buf, sizeof(buf), fp);
+ t_text(buf);
+ break;
+ case 'D': /* draw function */
+ fgets(buf, sizeof(buf), fp);
+ switch (buf[0]) {
+ case 'l': /* draw a line */
+ sscanf(buf+1, "%d %d", &n, &m);
+ drawline(n, m, ".");
+ break;
+ case 'c': /* circle */
+ sscanf(buf+1, "%d", &n);
+ drawcirc(n);
+ break;
+ case 'e': /* ellipse */
+ sscanf(buf+1, "%d %d", &m, &n);
+ drawellip(m, n);
+ break;
+ case 'a': /* arc */
+ sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
+ drawarc(n, m, n1, m1);
+ break;
+ case '~': /* wiggly line */
+ drawwig(buf+1);
+ break;
+ default:
+ error(FATAL, "unknown drawing function %s\n", buf);
+ break;
+ }
+ break;
+ case 's':
+ fscanf(fp, "%d", &n);
+ if (n == -23) {
+ float f;
+ fscanf(fp, "%f", &f);
+ setsize(f);
+ } else
+ setsize(t_size(n));/* ignore fractional sizes */
+ break;
+ case 'f':
+ sget(str, sizeof str, fp);
+ setfont(t_font(str));
+ break;
+ case 'H': /* absolute horizontal motion */
+ /* fscanf(fp, "%d", &n); */
+ while ((c = getc(fp)) == ' ')
+ ;
+ k = 0;
+ do {
+ k = 10 * k + c - '0';
+ } while (isdigit(c = getc(fp)));
+ ungetc(c, fp);
+ hgoto(k);
+ break;
+ case 'h': /* relative horizontal motion */
+ /* fscanf(fp, "%d", &n); */
+ while ((c = getc(fp)) == ' ')
+ ;
+ k = 0;
+ do {
+ k = 10 * k + c - '0';
+ } while (isdigit(c = getc(fp)));
+ ungetc(c, fp);
+ hmot(k);
+ break;
+ case 'w': /* word space */
+ putc(' ', stdout);
+ break;
+ case 'V':
+ fscanf(fp, "%d", &n);
+ vgoto(n);
+ break;
+ case 'v':
+ fscanf(fp, "%d", &n);
+ vmot(n);
+ break;
+ case 'p': /* new page */
+ fscanf(fp, "%d", &n);
+ t_page(n);
+ break;
+ case 'n': /* end of line */
+ while (getc(fp) != '\n')
+ ;
+ t_newline();
+ break;
+ case '#': /* comment */
+ while (getc(fp) != '\n')
+ ;
+ break;
+ case 'x': /* device control */
+ devcntrl(fp);
+ break;
+ default:
+ error(!FATAL, "unknown input character %o %c\n", c, c);
+ done();
+ }
+ }
+}
+
+void
+devcntrl(FILE *fp) /* interpret device control functions */
+{
+ char str[4096];
+ int n;
+
+ sget(str, sizeof str, fp);
+ switch (str[0]) { /* crude for now */
+ case 'i': /* initialize */
+ fileinit();
+ t_init(0);
+ break;
+ case 'T': /* device name */
+ sget(devname, sizeof devname, fp);
+ break;
+ case 't': /* trailer */
+ t_trailer();
+ break;
+ case 'p': /* pause -- can restart */
+ t_reset('p');
+ break;
+ case 's': /* stop */
+ t_reset('s');
+ break;
+ case 'r': /* resolution assumed when prepared */
+ fscanf(fp, "%d", &res);
+ break;
+ case 'f': /* font used */
+ fscanf(fp, "%d", &n);
+ sget(str, sizeof str, fp);
+ loadfont(n, str);
+ break;
+ }
+ while (getc(fp) != '\n') /* skip rest of input line */
+ ;
+}
+
+void
+fileinit(void) /* read in font and code files, etc. */
+{
+}
+
+void
+fontprint(int i) /* debugging print of font i (0,...) */
+{
+}
+
+void
+loadcode(int n, int nw) /* load codetab on position n (0...); #chars is nw */
+{
+}
+
+void
+loadfont(int n, char *s) /* load font info for font s on position n (1...) */
+{
+}
+
+void
+error(int f, const char *s, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "ta: ");
+ va_start(ap, s);
+ vfprintf(stderr, s, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ if (f)
+ exit(1);
+}
+
+
+/*
+ Here beginneth all the stuff that really depends
+ on the 202 (we hope).
+*/
+
+
+#define ESC 033
+#define HOME 'H'
+#define CLEAR 'J'
+#define FF 014
+
+int size = 1;
+int font = 1; /* current font */
+int hpos; /* horizontal position where we are supposed to be next (left = 0) */
+int vpos; /* current vertical position (down positive) */
+
+int horig; /* h origin of current block; hpos rel to this */
+int vorig; /* v origin of current block; vpos rel to this */
+
+int DX = 10; /* step size in x for drawing */
+int DY = 10; /* step size in y for drawing */
+int drawdot = '.'; /* draw with this character */
+int drawsize = 1; /* shrink by this factor when drawing */
+
+void
+t_init(int reinit) /* initialize device */
+{
+ fflush(stdout);
+ hpos = vpos = 0;
+}
+
+#define MAXSTATE 5
+
+struct state {
+ int ssize;
+ int sfont;
+ int shpos;
+ int svpos;
+ int shorig;
+ int svorig;
+};
+struct state state[MAXSTATE];
+struct state *statep = state;
+
+void
+t_push(void) /* begin a new block */
+{
+ hflush();
+ statep->ssize = size;
+ statep->sfont = font;
+ statep->shorig = horig;
+ statep->svorig = vorig;
+ statep->shpos = hpos;
+ statep->svpos = vpos;
+ horig = hpos;
+ vorig = vpos;
+ hpos = vpos = 0;
+ if (statep++ >= state+MAXSTATE)
+ error(FATAL, "{ nested too deep");
+ hpos = vpos = 0;
+}
+
+void
+t_pop(void) /* pop to previous state */
+{
+ if (--statep < state)
+ error(FATAL, "extra }");
+ size = statep->ssize;
+ font = statep->sfont;
+ hpos = statep->shpos;
+ vpos = statep->svpos;
+ horig = statep->shorig;
+ vorig = statep->svorig;
+}
+
+int np; /* number of pages seen */
+int npmax; /* high-water mark of np */
+int pgnum[40]; /* their actual numbers */
+long pgadr[40]; /* their seek addresses */
+
+void
+t_page(int n) /* do whatever new page functions */
+{
+ int m, i;
+ char buf[1024], *bp;
+
+ pgnum[np++] = n;
+ pgadr[np] = ftell(fp);
+ if (np > npmax)
+ npmax = np;
+ if (output == 0) {
+ output = in_olist(n);
+ t_init(1);
+ return;
+ }
+ /* have just printed something, and seen p<n> for next one */
+ putpage();
+ fflush(stdout);
+ if (nowait)
+ return;
+
+ next:
+ for (bp = buf; (*bp = readch()); )
+ if (*bp++ == '\n' || bp >= &buf[sizeof buf - 1])
+ break;
+ *bp = 0;
+ switch (buf[0]) {
+ case 0:
+ done();
+ break;
+ case '\n':
+ output = in_olist(n);
+ t_init(1);
+ return;
+ case '!':
+ callunix(&buf[1]);
+ fputs("!\n", stderr);
+ break;
+ case 'e':
+ erase = 1 - erase;
+ break;
+ case 'w':
+ wflag = 1 - wflag;
+ break;
+ case 'a':
+ aspect = atof(&buf[1]);
+ break;
+ case '-':
+ case 'p':
+ m = atoi(&buf[1]) + 1;
+ if (fp == stdin) {
+ fputs("you can't; it's not a file\n", stderr);
+ break;
+ }
+ if (np - m <= 0) {
+ fputs("too far back\n", stderr);
+ break;
+ }
+ np -= m;
+ fseek(fp, pgadr[np], 0);
+ output = 1;
+ t_init(1);
+ return;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ m = atoi(&buf[0]);
+ for (i = 0; i < npmax; i++)
+ if (m == pgnum[i])
+ break;
+ if (i >= npmax || fp == stdin) {
+ fputs("you can't\n", stderr);
+ break;
+ }
+ np = i + 1;
+ fseek(fp, pgadr[np], 0);
+ output = 1;
+ t_init(1);
+ return;
+ case 'o':
+ outlist(&buf[1]);
+ output = 0;
+ t_init(1);
+ return;
+ case '?':
+ fputs("!cmd unix cmd\n", stderr);
+ fputs("p print this page again\n", stderr);
+ fputs("-n go back n pages\n", stderr);
+ fputs("n print page n (previously printed)\n", stderr);
+ fputs("o... set the -o output list to ...\n", stderr);
+ fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr);
+ fputs("an sets aspect ratio to n\n", stderr);
+ break;
+ default:
+ fputs("?\n", stderr);
+ break;
+ }
+ goto next;
+}
+
+void
+putpage(void)
+{
+ fflush(stdout);
+}
+
+void
+t_newline(void) /* do whatever for the end of a line */
+{
+ printf("\n");
+ hpos = 0;
+}
+
+int
+t_size(int n) /* convert integer to internal size number*/
+{
+ return 0;
+}
+
+int
+t_font(char *s) /* convert string to internal font number */
+{
+ return 0;
+}
+
+void
+t_text(char *s) /* print string s as text */
+{
+ int c, w=0;
+ char str[100];
+
+ if (!output)
+ return;
+ while ((c = *s++) != '\n') {
+ if (c == '\\') {
+ switch (c = *s++) {
+ case '\\':
+ case 'e':
+ put1('\\');
+ break;
+ case '(':
+ str[0] = *s++;
+ str[1] = *s++;
+ str[2] = '\0';
+ put1s(str);
+ break;
+ }
+ } else {
+ put1(c);
+ }
+ hmot(w);
+ }
+}
+
+void
+t_reset(int c)
+{
+ output = 1;
+ fflush(stdout);
+ if (c == 's')
+ t_page(9999);
+}
+
+void
+t_trailer(void)
+{
+}
+
+void
+hgoto(int n)
+{
+ hpos = n; /* this is where we want to be */
+ /* before printing a character, */
+ /* have to make sure it's true */
+}
+
+void
+hmot(int n) /* generate n units of horizontal motion */
+{
+ hgoto(hpos + n);
+}
+
+void
+hflush(void) /* actual horizontal output occurs here */
+{
+}
+
+void
+vgoto(int n)
+{
+ vpos = n;
+}
+
+void
+vmot(int n) /* generate n units of vertical motion */
+{
+ vgoto(vpos + n); /* ignores rounding */
+}
+
+void
+put1s(char *s) /* s is a funny char name */
+{
+ int i;
+ char *p;
+ extern char *spectab[];
+ static char prev[10] = "";
+ static int previ;
+
+ if (!output)
+ return;
+ if (strcmp(s, prev) != 0) {
+ previ = -1;
+ for (i = 0; spectab[i] != 0; i += 2)
+ if (strcmp(spectab[i], s) == 0) {
+ n_strcpy(prev, s, sizeof(prev));
+ previ = i;
+ break;
+ }
+ }
+ if (previ >= 0) {
+ for (p = spectab[previ+1]; *p; p++)
+ putc(*p, stdout);
+ } else
+ prev[0] = 0;
+}
+
+void
+put1(int c) /* output char c */
+{
+ if (!output)
+ return;
+ putc(c, stdout);
+}
+
+void
+setsize(double n) /* set point size to n (internal) */
+{
+}
+
+void
+t_fp(int n, char *s) /* font position n now contains font s */
+{
+}
+
+void
+setfont(int n) /* set font to n */
+{
+}
+
+void done(void)
+{
+ output = 1;
+ putpage();
+ fflush(stdout);
+ exit(0);
+}
+
+void
+callunix(char line[])
+{
+ int rc, status, unixpid;
+ if( (unixpid=fork())==0 ) {
+ signal(SIGINT,sigint); signal(SIGQUIT,sigquit);
+ close(0); dup(2);
+ execl("/bin/sh", "-sh", "-c", line, NULL);
+ exit(255);
+ }
+ else if(unixpid == -1)
+ return;
+ else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
+ while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
+ signal(SIGINT,(void(*)(int))done); signal(SIGQUIT,(void(*)(int))sigquit);
+ }
+}
+
+int
+readch(void){
+ char c;
+ if (read(2,&c,1)<1) c=0;
+ return(c);
+}
+
+char *spectab[] ={
+ "em", "-",
+ "hy", "-",
+ "en", "-",
+ "ru", "_",
+ "l.", ".",
+ "br", "|",
+ "vr", "|",
+ "fm", "'",
+ "or", "|",
+ 0, 0,
+};
+
+static int
+sget(char *buf, size_t size, FILE *fp)
+{
+ int c, n = 0;
+
+ do
+ c = getc(fp);
+ while (isspace(c));
+ if (c != EOF) do {
+ if (n+1 < size)
+ buf[n++] = c;
+ c = getc(fp);
+ } while (c != EOF && !isspace(c));
+ ungetc(c, fp);
+ buf[n] = 0;
+ return n > 1 ? 1 : c == EOF ? EOF : 0;
+}