home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1985, 1986, 1987, 1988 Chris Lewis
- All Rights Reserved
-
- Permission to copy and further distribute is freely given provided
- this copyright notice remains intact and that this software is not
- sold for profit.
-
- Project: Generic Troff drivers
- Module: psxlate.c
- Author: Chris Lewis
- Specs: Generic Postscript filter (page reversal etc.)
- */
- #ifndef SVR3
- #ifndef lint
- static char SCCSid[] = "@(#)psxlate.c: 1.4 Copyright 89/04/21 11:48:27 Chris Lewis";
- #endif
- #else
- #ident "@(#)psxlate.c: 1.4 Copyright 89/04/21 11:48:27 Chris Lewis"
- #endif
- #include <stdio.h>
-
- int xlate = 0;
- #define MAXPAGE 1000
-
- struct headers {
- char *hptr;
- struct headers *next;
- };
-
- struct pagedesc {
- unsigned long start;
- unsigned long end;
- char *type;
- struct headers *comments;
- } pageidx[MAXPAGE];
-
- char *tmp = "/tmp/psxXXXXXX";
- int page = 0;
- char *progname;
- int debug;
-
- main(argc, argv)
- int argc; char **argv; {
- extern int optind;
- int c;
- progname = argv[0];
- while ((c = getopt(argc, argv, "drx")) != EOF)
- switch(c) {
- case 'r': xlate = 0; break;
- case 'x': xlate = 1; break;
- case 'd': debug = 1; break;
- default:
- usage();
- exit(1);
- }
- mktemp(tmp);
- scan(stdin, tmp);
- transform();
- emit(tmp);
- if (!debug)
- cleanup();
- exit(0);
- }
-
- scan(f, file)
- FILE *f; char *file; {
- FILE *t;
- extern char *malloc();
- int state = 1;
- long ind = 0;
- int c;
- char buf[100];
- if ((t = fopen(file, "w")) == NULL) {
- fprintf(stderr, "Cannot open temporary file %s\n", file);
- exit(1);
- }
- page = 0;
- while((c = getc(f)) != EOF) {
- putc(c, t);
- ind++;
- switch(state) {
- case 0:
- if (c == '\n') {
- state = 1;
- }
- break;
- case 1: /* seen \n */
- if (c == '%') {
- fgets(buf, sizeof(buf), f);
- fputs(buf, t);
- if (0 == strncmp(buf, "!PS-Adobe", 9) ||
- 0 == strncmp(buf, "%Page:", 6) ||
- 0 == strncmp(buf, "%Trailer", 8)) {
- if (page)
- pageidx[page-1].end = ind - 2;
- pageidx[page].start = ind - 1;
- strcpy(pageidx[page].type = malloc(strlen(buf)+1), buf);
- add(page, buf);
- page++;
- } else
- add(page, buf);
- ind += strlen(buf);
- break;
- }
- state = 0;
- break;
- }
- }
- if (page)
- pageidx[page-1].end = ind - 1;
- fclose(t);
- }
-
- cleanup() {
- unlink(tmp);
- }
-
- emit(file)
- char *file; {
- FILE *t;
- register int i;
- if ((t = fopen(file, "r")) == NULL) {
- fprintf(stderr, "Panic\n");
- exit(1);
- }
- for(i = 0; i < page; i++) {
- register long start, end, cnt;
- register int c;
-
- start = pageidx[i].start;
- end = pageidx[i].end;
- cnt = end - start + 1;
- fseek(t, start, 0);
- while(cnt--)
- putchar(getc(t));
- }
- }
-
-
- usage() {
- fprintf(stderr, "Usage: %s [-r|-x] < file > file\n", progname);
- }
-
- dumppg() {
- register int i;
- register struct headers *h;
- if (debug) {
- for (i = 0; i < page; i++) {
- fprintf(stderr, "%d %d %d %s\n", i, pageidx[i].start,
- pageidx[i].end, pageidx[i].type);
- for (h = pageidx[i].comments; h; h=h->next)
- fprintf(stderr, "%s", h->hptr);
- }
- }
- }
-
- transform() {
- dumppg();
- switch(xlate) {
- case 0:
- revpages();
- break;
- case 1:
- xpages();
- break;
- }
- dumppg();
- }
-
- fstart() {
- register int i;
- for (i = 0; i < page; i++)
- if (0 == strncmp(pageidx[i].type, "%Page:", 6))
- break;
- return(i);
- }
- fend() {
- register int i;
- for (i = page-1; i >= 0; i--)
- if (0 == strncmp(pageidx[i].type, "%Page:", 6))
- break;
- return(i);
- }
-
- revpages() {
- register int i, j;
- struct pagedesc t;
- i = fstart();
-
- if (i == page)
- return;
-
- j = fend();
-
- while(i < j) {
- t = pageidx[i];
- pageidx[i] = pageidx[j];
- pageidx[j] = t;
- i++;j--;
- }
- }
-
- xpages() {
- register int i, j, mid, first, last;
- struct pagedesc t;
- struct pagedesc *p =
- (struct pagedesc *) malloc(sizeof(struct pagedesc) * page);
- revpages();
- first = fstart();
-
- if (first == page)
- return;
-
- last = fend();
-
- if (debug)
- fprintf(stderr, "first: %d, last: %d, page: %d\n", first, last, page);
- if ((last - first + 1) < 3)
- return;
-
- if (first)
- memcpy(p, pageidx, sizeof(struct pagedesc) * first); /* prolog */
- if (page - last) /* copy epilog */
- memcpy(p+last+1,
- &pageidx[last+1], sizeof(struct pagedesc) * (page - last - 1));
- mid = (last + first + 1) / 2 ; /* offset of middle */
- for (i = first; i < mid; i++)
- p[first + (i - first) * 2] = pageidx[i];
- for (i = mid; i <= last; i++)
- p[first + (i - mid) * 2 + 1] = pageidx[i];
- memcpy(pageidx, p, sizeof(struct pagedesc) * page);
- free(p);
- }
-
- add(page, buf)
- int page; char *buf; {
- struct headers *hdr, *hp, *ohp;
- char *p;
- if (debug)
- fprintf(stderr, "Adding %s\n", buf);
- hdr = (struct headers *) malloc(sizeof(struct headers));
- if (hdr == 0 || !(hdr->hptr = malloc(strlen(buf) + 2))) {
- fprintf(stderr, "psxlate: Out of space\n");
- exit(1);
- }
- strcpy(hdr->hptr, "%");
- strcat(hdr->hptr, buf);
- hdr->next = NULL;
- for (ohp = hp = pageidx[page].comments; ; hp = hp->next) {
- if (!hp) {
- if (ohp == pageidx[page].comments)
- pageidx[page].comments = hdr;
- else
- ohp->next = hdr;
- break;
- }
- ohp = hp;
- }
- return;
- }
-