|
|
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)");
}