|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 5415 (0x1527) Types: TextFile Names: »psspecial.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/mctex/postscript/psspecial.c«
/* * Copyright (c) 1989 University of Maryland * Department of Computer Science. All rights reserved. * Permission to copy for any purpose is hereby granted * so long as this copyright notice remains intact. */ #ifndef lint static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/postscript/RCS/psspecial.c,v 3.3 89/11/28 17:19:15 chris Exp $"; #endif #include <stdio.h> #include "types.h" #include "sdecode.h" #include "dvistate.h" #include "postscript.h" void Copy(), OutputFailed(); char *strsave(), *strncpy(); /* * \special decoding for postscript. */ static void ps_ps(), ps_file(), ps_set(); static struct sdecode sd_table[] = { { "hoffset", sda_f, ps_set }, { "hscale", sda_f, ps_set }, { "hsize", sda_f, ps_set }, { "ps", sda_rest, ps_ps }, { "psfile", sda_s, ps_file }, { "voffset", sda_f, ps_set }, { "vscale", sda_f, ps_set }, { "vsize", sda_f, ps_set }, }; /* * Remember what kind of special we are doing. * psfig specials and psfile=%s specials do not mix (alas!). */ static int ps_regular, ps_psfig; static int ps_complained; static char *psfile; /* file argument from psfile=%s */ static void cantmix() { if (!ps_complained) { error(0, 0, "cannot mix different kinds of \\special, sorry"); error(0, 0, "you must use separate \\special invocations"); ps_complained = 1; } } /* * This is disgusting, but that is what backwards * compatibility is all about. * * ps_ps() handles `ps::[begin]', `ps::[end]', `ps::', and `ps:' * all followed by raw PostScript text, and also takes care of * `ps: plotfile xxx' commands. The file name can be followed by * spaces, and must be truncated at the first space (if any); and * since we use the generic \special parsing code to extract these, * the first `:' in each of the above can be replaced with `=' or * white space (not that this bothers anyone, or that anyone makes * use of it). * * First we have a small function to handle `ps: plotfile' commands. */ static void ps_plotfile(s, l, l2) char *s; int l; i32 l2; { register char *p =s; p[l] = 0; /* guarantee stop */ while (*p && *p != ' ') p++; *p = 0; Copy(s, 0); if (l2) (void) fseek(ds.ds_fp, (long)l2, 1); } /* here we do the ugly stuff */ /* ARGSUSED */ static void ps_ps(self, l1, s, l2) char *self; i32 l1; char *s; i32 l2; { register char *p; register int i, b; char buf[BUFSIZ + 1]; /* +1 to allow trailing NUL (above) */ if (ps_regular) { cantmix(); if (l2) (void) fseek(ds.ds_fp, (long)l2, 1); return; } ps_psfig = 1; /* * Copy up to BUFSIZ bytes from s+ds.ds_fp to buf[]. * There are l1 bytes in s, and l2 bytes in ds.ds_fp. * If there are <= BUFSIZ bytes total, be sure buf[] is * NUL-terminated (to make strncmp() safe). */ p = buf; if (l1 > 0) { if (l1 < BUFSIZ) { i = l1; (void) strncpy(p, s, i); p += i; i = BUFSIZ - i; l1 = 0; } else { (void) strncpy(p, s, BUFSIZ); p += BUFSIZ; i = 0; l1 -= BUFSIZ; s += BUFSIZ; } } else i = BUFSIZ; if (i >= l2) { i = l2; p[i] = 0; } if (i > 0) { if (fread(p, 1, i, ds.ds_fp) != i) error(1, -1, "cannot read \\special string"); l2 -= i; p += i; } b = p - buf; /* remember how much is in buf */ p = buf; if (strncmp(p, " plotfile ", i = 10) == 0 || strncmp(p, "plotfile ", i = 9) == 0) { ps_plotfile(p + i, b - i, l2); return; } if (strncmp(p, ":[begin]", 8) == 0) i = 8; else if (strncmp(p, ":[end]", 6) == 0) i = 6; else if (*p == ':') i = 1; else i = 0; if ((b -= i) > 0) { if (fwrite(p + i, 1, b, stdout) != b) OutputFailed(); } if ((i = l1) > 0) { if (fwrite(s, 1, i, stdout) != i) OutputFailed(); } while (l2 > 0) { i = l2 > BUFSIZ ? BUFSIZ : l2; if (fread(p, 1, i, ds.ds_fp) != i) error(1, -1, "cannot read \\special string"); if (fwrite(p, 1, i, stdout) != i) OutputFailed(); } (void) putchar('\n'); } static int ps_setregular() { if (ps_psfig) { cantmix(); return (-1); } if (!ps_regular) { (void) fputs("@beginspecial\n", stdout); ps_regular = 1; } return (0); } /* * psfile=s */ static void ps_file(self, s) char *self; char *s; { if (ps_setregular()) return; if (psfile) error(0, 0, "extra %s argument: `%s' ignored", self, s); else psfile = strsave(s); } /* * hsize=%f * vsize=%f * hoffset=%f * voffset=%f * hscale=%f * vscale=%f */ static void ps_set(self, x) char *self; double x; { if (ps_setregular()) return; (void) printf("%f @%s\n", x, self); } /* * Perform a \special. Called only from pass 1. */ void P1DoSpecial(len) i32 len; /* length of the \special string */ { /* clear type flags; flags are set by decode routines */ ps_psfig = 0; ps_regular = 0; /* decode keywords and arguments, and call functions */ SDecode(ds.ds_fp, len, sd_table, SDsize(sd_table)); /* if it was a psfig special, we are done */ if (ps_psfig) return; /* if it was a regular special, finish setup, and include the file */ if (ps_regular) { (void) fputs("@setspecial\n", stdout); if (psfile == NULL) { error(0, 0, "missing psfile with hsize etc."); error(0, 0, "(did you forget something?)"); } else { Copy(psfile, 0); free(psfile); psfile = NULL; } (void) fputs("@endspecial\n", stdout); if (ferror(stdout)) OutputFailed(); return; } /* neither kind: give a warning */ error(0, 0, "warning: empty \\special (ignored)"); }