This is dospecial.c in view mode; [Download] [Up]
/* * This is dvips, a freely redistributable PostScript driver * for dvi files. It is (C) Copyright 1987 by Tomas Rokicki. * You may modify and use this program to your heart's content, * so long as you send modifications to Tomas Rokicki. It can * be included in any distribution, commercial or otherwise, so * long as the banner string defined in structures.h is not * modified (except for the version number) and this banner is * printed on program invocation, or can be printed on program * invocation with the -? option. */ #define COLOR /* * dospecial of dvisw package. (C) 1986 Radical Eye Software. * This routine handles special commands. Currently the only * special command handled is the landscape special. */ #include "structures.h" #include <kpathsea/tex-file.h> #include <dpsclient/dpsclient.h> #include "paths.h" #include <string.h> /* * These are the external routines called: */ #ifdef TPIC extern void setPenSize(); extern void flushPath(); extern void flushDashed(); extern void flushDashed(); extern void addPath(); extern void arc(); extern void flushSpline(); extern void shadeLast(); extern void whitenLast(); extern void blackenLast(); #endif #ifdef COLOR extern void pushcolor() ; extern void popcolor() ; extern void resetcolorstack() ; extern void background() ; static Boolean usescolor ; #endif extern void pswrite(), error(), tolandscape(), add_header(), hvpos() ; extern void copyfile(), figcopyfile() ; extern void handlepapersize(), newpapersize() ; extern int dvibyte() ; extern char *malloc(), *newstring() ; int GetKeyVal(), IsSame() ; extern FILE *search() ; extern void texflush() ; extern Boolean prescan; extern void writeconsole() ; extern Boolean firstpage ; extern Boolean mocked ; extern Boolean landscape, orientationset ; extern int debugon ; extern void TPSbop(), TPSeop() ; char nextstring[8192] ; extern char temperrorbuf[] ; char *maxstring = nextstring + 8100 ; static integer hpapersize, vpapersize ; /* * These definitions are used by the \special command. */ typedef enum {None, String, Integer, Number, Dimension} ValTyp; typedef struct { char *Key; /* the keyword string */ char *Val; /* the value string */ ValTyp vt; /* the value type */ union { /* the decoded value */ long i; float n; } v; } KeyWord; typedef struct { char *Entry; ValTyp Type; } KeyDesc; /* * Now our routine. We get the number of bytes specified and place them * into the string buffer, and then parse it for alpha. Interpret a * \special command, made up of keyword=value pairs. */ #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0])) KeyDesc KeyTab[] = {{"psfile", String}, {"ifffile", String}, {"tekfile", String}, {"hsize", Number}, {"vsize", Number}, {"hoffset", Number}, {"voffset", Number}, {"hscale", Number}, {"vscale", Number}, {"angle", Number}, {"llx", Number}, {"lly", Number}, {"urx", Number}, {"ury", Number}, {"rwi", Number}, {"rhi", Number}, {"clip", None}}; char *GetKeyStr(); void fil2ps(); char task[7] = "\0"; struct bangspecial { struct bangspecial *next ; char actualstuff[4] ; } *bangspecials = NULL ; #define spswrite trytobreakout static void trytobreakout(p) register char *p ; { pswrite(" ") ; pswrite(p) ; pswrite(" ") ; } static void dobs(q) register struct bangspecial *q ; { if (q) { dobs(q->next) ; trytobreakout(q->actualstuff) ; } } void special_header() { static int sent = 0 ; if (! sent) { texflush() ; #ifdef POPRESTORE TPSeop() ; #endif add_header("special.pro") ; #ifdef POPRESTORE TPSbop() ; #endif hvpos() ; sent = 1 ; } } void outbangspecials() { if (bangspecials) { special_header() ; pswrite(" @defspecial ") ; dobs(bangspecials) ; pswrite(" @fedspecial ") ; } } #define TRUE (1) #define FALSE (0) void dospecial(numbytes) integer numbytes ; { register char *p = nextstring ; register int i = 0 ; int j ; Boolean ps = TRUE ; char spbuf[400] ; char fbuf[400] ; char *sf = NULL ; char *f = NULL ; KeyWord k ; temperrorbuf[0] = 0 ; if (nextstring + i > maxstring) error("! out of string space in dospecial") ; for (i=numbytes; i>0; i--) *p++ = dvibyte() ; *p = 0 ; p = nextstring ; #ifdef DEBUG if (debugon > 3) { printf("{%s}[%d]", p, prescan) ; fflush(stdout) ; } #endif while (*p <= ' ' && *p) p++ ; if (strncmp(p, "landscape", 9)==0) { if (prescan && firstpage) tolandscape() ; return ; } else if (strncmp(p, "papersize", 9)==0) { p += 9 ; while (*p == '=' || *p == ' ') p++ ; handlepapersize(p, &hpapersize, &vpapersize) ; if (prescan && firstpage) newpapersize(hpapersize, vpapersize) ; return ; } /* ignore this special for now */ if (strncmp(p, "hp:", 3)==0) return ; if (! prescan) special_header() ; if (strncmp(p, "header", 6)==0) { if (prescan) { char *q ; p += 6 ; while ((*p <= ' ' || *p == '=' || *p == ')') && *p != 0) p++ ; q = p ; p = p + strlen(p) - 1 ; if (*p == ')') { p-- ; while (*p <= ' ') p-- ; p[1] = 0 ; } add_header(q) ; } return ; #ifdef COLOR } if (strncmp(p, "background", 10) == 0) { if (usescolor == 0) { add_header("color.pro") ; usescolor = 1 ; } p +=11 ; while ( *p <= ' ' ) p++ ; background(p) ; return ; } if (strncmp(p, "color", 5) == 0) { if (usescolor == 0) { add_header("color.pro") ; usescolor = 1 ; } p += 6 ; while ( *p <= ' ' ) p++ ; if (strncmp(p, "push", 4) == 0 ) { p += 4 ; while (*p && *p <= ' ' ) p++ ; pushcolor(p,!prescan) ; } else if (strncmp(p, "pop", 3) == 0 ) { popcolor(!prescan) ; } else { resetcolorstack(p,!prescan) ; } return ; #endif } else if (strncmp(p, "ps:", 3)==0) { if (! prescan) { hvpos() ; texflush() ; if (strncmp(p, "ps::[begin]", 11) == 0) spswrite(&p[11]); else if (strncmp(p, "ps::[end]", 9) == 0) spswrite(&p[9]); else if (strncmp(p, "ps: plotfile ", 13) == 0) { char *sfp ; p += 13; while (*p == ' ') p++ ; if (*p == '"') { p++ ; for (sfp = p; *sfp && *sfp != '"'; sfp++) ; } else { for (sfp = p; *sfp && *sfp != ' '; sfp++) ; } *sfp = 0 ; if (*p == '`') figcopyfile (p+1, 1); else figcopyfile (p, 0); } else if (strncmp(p, "ps::", 4) == 0) spswrite(&p[4]); else spswrite(&p[3]); return; } } #ifdef TPIC else if (strncmp(p, "pn ", 3) == 0) {if (!prescan) setPenSize(p+2);} else if (strncmp(p, "fp",2) == 0) {if (!prescan) flushPath();} else if (strncmp(p, "da ", 3) == 0) {if (!prescan) flushDashed(p+2, 0);} else if (strncmp(p, "dt ", 3) == 0) {if (!prescan) flushDashed(p+2, 1);} else if (strncmp(p, "pa ", 3) == 0) {if (!prescan) addPath(p+2);} else if (strncmp(p, "ar ", 3) == 0) {if (!prescan) arc(p+2);} else if (strncmp(p, "sp", 2) == 0) {if (!prescan) flushSpline();} else if (strncmp(p, "sh", 2) == 0) {if (!prescan) shadeLast();} else if (strncmp(p, "wh", 2) == 0) {if (!prescan) whitenLast();} else if (strncmp(p, "bk", 2) == 0) {if (!prescan) blackenLast();} else if (strncmp(p, "tx ", 3) == 0) {error("\\special texture command -- ignored");} #endif else { if (prescan && *p == '!' && firstpage) { struct bangspecial *q ; void *mymalloc() ; p++ ; q = (struct bangspecial *)mymalloc(sizeof(struct bangspecial) + strlen(p)) ; strcpy(q->actualstuff, p) ; q->next = bangspecials ; bangspecials = q ; return ; } if (! prescan) { if (*p == '"') { hvpos(); pswrite(" @beginspecial @setspecial ") ; trytobreakout(p+1) ; pswrite(" @endspecial ") ; return ; } else if (*p == '!') return ; spbuf[0] = '\0'; hvpos(); pswrite(" @beginspecial "); /* get all keyword-value pairs; for compatibility, single words are taken as file names */ while( (p=GetKeyStr(p,&k)) != NULL ) { if( GetKeyVal( &k, KeyTab, NKEYS, &j ) && j != -1 ) { if( j >= 0 && j <= 2 ) { if( sf ) { fprintf(stderr, " more than one \\special file name given: %s ignored.", sf ); } strcpy(fbuf, k.Key); strcpy(spbuf, k.Val); f = fbuf; sf = spbuf; if( j == 1 || j == 2) ps = FALSE; } else { /* keywords are output as PS procedure calls */ if(k.vt == Integer) sprintf(temperrorbuf, "%ld @%s ", k.v.i, KeyTab[j].Entry); else if (k.vt == None) sprintf(temperrorbuf, " @%s ", KeyTab[j].Entry); else sprintf(temperrorbuf, "%f @%s ", k.v.n, KeyTab[j].Entry); pswrite(temperrorbuf) ; } } else { fprintf(stderr, " invalid keyword or value in \\special: \"%s\" ignored.", k.Key ); } } pswrite(" @setspecial "); if( sf ) { if (*sf == '`') figcopyfile(sf+1, 1); else figcopyfile(sf, 0); } else fprintf(stderr, " no special file name provided."); pswrite(" @endspecial "); } } } /* * extract first keyword-value pair from string (value part may be null) * return pointer to remainder of string return NULL if none found */ char KeyStr[500]; char ValStr[500]; char *GetKeyStr( str, kw ) char *str; KeyWord *kw; { char *s, *k, *v, t; if( !str ) return( NULL ); for( s=str; *s == ' '; s++ ) /* skip over blanks */ ; if( *s == '\0' ) return( NULL ); /* extract keyword portion */ for( k=KeyStr; *s != ' ' && *s != '\0' && *s != '='; *k++ = *s++ ) ; *k = '\0'; kw->Key = KeyStr; kw->Val = v = NULL; kw->vt = None; for( ; *s && *s == ' '; s++ ) /* skip over blanks */ ; if( *s != '=' ) /* look for "=" */ return( s ); for( s++ ; *s && *s == ' '; s++ ) /* skip over blanks */ ; if( *s == '\'' || *s == '\"' ) /* get string delimiter */ t = *s++; else t = ' '; /* copy value portion up to delimiter */ for( v=ValStr; *s != t && *s != '\0'; *v++ = *s++ ) ; if( t != ' ' && *s == t ) s++; *v = '\0'; kw->Val = ValStr; kw->vt = String; return( s ); } /* * get next keyword-value pair decode value according to table entry */ int GetKeyVal( kw, tab, nt, tno) KeyWord *kw; KeyDesc tab[]; int nt; int *tno; { int i; char c = '\0'; *tno = -1; for(i=0; i<nt; i++) if( IsSame(kw->Key, tab[i].Entry) ) { *tno = i; switch( tab[i].Type ) { case None: if( kw->vt != None ) return( 0 ); break; case String: if( kw->vt != String ) return( 0 ); break; case Integer: if( kw->vt != String ) return( 0 ); if( sscanf(kw->Val,"%ld%c", &(kw->v.i), &c) != 1 || c != '\0' ) return( 0 ); break; case Number: case Dimension: if( kw->vt != String ) return( 0 ); if( sscanf(kw->Val,"%f%c", &(kw->v.n), &c) != 1 || c != '\0' ) return( 0 ); break; } kw->vt = tab[i].Type; return( 1 ); } return( 1 ); } /* * compare strings, ignore case */ int Tolower(c) register int c ; { if ('A' <= c && c <= 'Z') return(c+32) ; else return(c) ; } int IsSame(a, b) char *a, *b; { for( ; *a != '\0'; ) if( Tolower(*a++) != Tolower(*b++) ) return( 0 ); return( *a == *b ? 1 : 0 ); } void pswrite(s) char *s ; { DPSWritePostScript(DPSGetCurrentContext(), s, strlen(s)) ; } void qstatus() ; /* * This routine copies a file down the pipe. Search path uses the * header path. * * We add code to handle the case of MS-DOS font files. * * Format: 80 {01,02} four byte length in littleendian order data * repeated possibly multiple times. */ static char *hxdata = "0123456789ABCDEF" ; static int infigure ; void copyfile(s) char *s ; { FILE *f = NULL ; int c, prevc = '\n' ; long len ; char nextstring[2000] ; switch (infigure) { case 1: f = search(inputspath, s, "r") ; (void)sprintf(temperrorbuf, "Couldn't open figure file %s", s) ; break ; default: f = search(headerpath, s, "r") ; (void)sprintf(temperrorbuf, "Couldn't open header file %s", s) ; break ; case 2: #ifdef SECURE (void)sprintf(temperrorbuf, "<%s>: Tick filename execution disabled", s) ; #else writeconsole(s) ; f = popen(s, "r") ; (void)sprintf(temperrorbuf, "Failure to execute %s; continuing", s) ; #endif break; } if (f==NULL) { if (infigure == 1 || infigure == 2) pswrite(" MockPic ") ; /* error(temperrorbuf) ; can't do this; will crash window server to run an alert here; no idea why. */ } else { sprintf(temperrorbuf, "Inserting %s", s) ; qstatus(temperrorbuf) ; c = getc(f) ; if (c == 0x80) { while (1) { char *p = nextstring ; c = getc(f) ; switch(c) { case 1: case 2: len = getc(f) ; len += getc(f) * 256L ; len += getc(f) * 65536L ; len += getc(f) * 256L * 65536 ; if (c == 1) { while (len > 0) { c = getc(f) ; if (c == EOF) { error("premature EOF in MS-DOS font file") ; len = 0 ; } else if (c == 10 || c == 13) { *p++ = 10 ; *p++ = 0 ; pswrite(nextstring) ; p = nextstring ; len-- ; } else { *p++ = c ; len-- ; } } } else { if (p > nextstring) { *p++ = 10 ; *p++ = 0 ; pswrite(nextstring) ; p = nextstring ; } prevc = 0 ; while (len > 0) { c = getc(f) ; if (c == EOF) { error("premature EOF in MS-DOS font file") ; len = 0 ; } else { *p++ = hxdata[c >> 4] ; *p++ = hxdata[c & 15] ; len-- ; prevc += 2 ; if (prevc >= 76) { *p++ = 10 ; *p = 0 ; pswrite(nextstring) ; p = nextstring ; prevc = 0 ; } } } if (prevc) { *p++ = 10 ; *p = 0 ; pswrite(nextstring) ; p = nextstring ; prevc = 0 ; } } break ; case 3: goto msdosdone ; default: error("saw type other than 1, 2, or 3 in MS-DOS font file") ; break ; } c = getc(f) ; if (c == EOF) break ; if (c != 0x80) { error("saw non-MSDOS header in MSDOS font file") ; break ; } } msdosdone: ; } else { ungetc(c, f) ; while (fgets(nextstring, 1900, f)) pswrite(nextstring) ; } if (infigure == 2) (void)pclose(f) ; else (void)fclose(f) ; } } /* * For included PostScript graphics, we use the above routine, but * with no fatal error message. */ void figcopyfile(s, systemtype) char *s ; int systemtype ; { infigure = (systemtype ? 2 : 1) ; if (mocked) pswrite(" MockPic "); else copyfile(s) ; infigure = 0 ; } void cleartheair() { outbangspecials() ; } struct header_list { char *name ; struct header_list *next ; } *header_head ; /* * The external routines we use. */ extern void copyfile() ; #ifdef DEBUG extern integer debug_flag ; #endif /* * This more general routine adds a name to a list of unique * names. */ int add_name(s, what) char *s ; struct header_list **what ; { struct header_list *p, *q ; for (p = *what ; p != NULL; p = p->next) if (strcmp(p->name, s)==0) return 0 ; q = (struct header_list *)malloc((unsigned)sizeof(struct header_list)) ; if (q==NULL) error("! out of memory") ; q->next = NULL ; q->name = newstring(s) ; if (*what == NULL) *what = q ; else { for (p = *what; p->next != NULL; p = p->next) ; p->next = q ; } return 1 ; } /* * This routine is responsible for adding a header file. */ void add_header(s) char *s ; { if (add_name(s, &header_head)) copyfile(s) ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.