DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦87503a681⟧ TextFile

    Length: 5415 (0x1527)
    Types: TextFile
    Names: »psspecial.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/laser-setters/mctex/postscript/psspecial.c« 

TextFile

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