home *** CD-ROM | disk | FTP | other *** search
- /* psrev.c */
-
- #ifndef lint
- static char rcsid[] = "$Header: /usr/jjc/lprps/RCS/psrev.c,v 1.2 90/12/18 09:58:35 jjc Rel $";
- #endif
-
- #include <stdio.h>
- #include <ctype.h>
-
- char *malloc();
- char *realloc();
-
- char *xmalloc();
- char *xrealloc();
- char *prog;
-
- typedef struct line_buf {
- char *buf;
- int len;
- int size;
- } line_buf;
-
- int get_line(lb, fp)
- line_buf *lb;
- FILE *fp;
- {
- int left;
- char *ptr;
- if (lb->buf == NULL) {
- lb->size = 16;
- lb->buf = xmalloc(16);
- }
- ptr = lb->buf;
- left = lb->size - 1;
- for (;;) {
- int c = getc(fp);
- if (c == EOF) {
- if (ferror(fp))
- return 0;
- if (ptr == lb->buf)
- return 0;
- lb->len = ptr - lb->buf;
- *ptr++ = '\0';
- return 1;
- }
- if (left <= 0) {
- int n = ptr - lb->buf;
- lb->size *= 2;
- lb->buf = xrealloc(lb->buf, lb->size);
- left = lb->size - n - 1;
- ptr = lb->buf + n;
- }
- *ptr++ = c;
- left -= 1;
- if (c == '\n') {
- lb->len = ptr - lb->buf;
- *ptr++ = '\0';
- return 1;
- }
- }
- }
-
- void put_line(lb, fp)
- line_buf *lb;
- FILE *fp;
- {
- fwrite(lb->buf, 1, lb->len, fp);
- }
-
- /* is s2 a prefix of s1? */
- int strprefix(s1, s2)
- char *s1, *s2;
- {
- for (; *s1 != '\0' && *s1 == *s2; s1++, s2++)
- ;
- return *s2 == '\0';
- }
-
- void copy_and_exit(fp)
- FILE *fp;
- {
- int c;
- while ((c = getc(fp)) != EOF)
- putchar(c);
- exit(0);
- }
-
- typedef struct page_list {
- long pos;
- struct page_list *next;
- } page_list;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int dont_reverse = 0;
- int pageno;
- int pending_line = 0;
- int had_pages_comment = 0;
- int pages_comment_atend = 0;
- int npages = -1;
- int page_order;
- int had_page_order;
- FILE *tempfp = NULL;
- page_list *pl = 0;
- long trailer_pos = -1;
- long prev_pos;
- int level = 0;
- line_buf lb;
- prog = argv[0];
- lb.buf = 0;
- if (!get_line(&lb, stdin))
- exit(0);
- put_line(&lb, stdout);
- if (!strprefix(lb.buf, "%!PS-Adobe-"))
- copy_and_exit(stdin);
-
- /* process the header section */
- while (get_line(&lb, stdin)) {
- int suppress = 0;
- if (!strprefix(lb.buf, "%%")) {
- pending_line = 1;
- break;
- }
- else if (strprefix(lb.buf, "%%Pages:")) {
- suppress = 1; /* don't print it yet */
- /* the first %%Pages comment is the significant one */
- if (!had_pages_comment) {
- char *ptr = lb.buf + 8;
- while (*ptr == ' ')
- ptr++;
- had_pages_comment = 1;
- if (strprefix(ptr, "(atend)"))
- pages_comment_atend = 1;
- else {
- if (sscanf(ptr, "%d %d", &npages, &page_order) == 2)
- had_page_order = 1;
- }
- }
- }
- if (strprefix(lb.buf, "%%EndComments"))
- break;
- if (!suppress)
- put_line(&lb, stdout);
- }
-
- if (had_pages_comment) {
- if (pages_comment_atend)
- printf("%%%%Pages: (atend)\n");
- else if (had_page_order) {
- switch (page_order) {
- case 1:
- printf("%%%%Pages: %d -1\n", npages);
- break;
- case -1:
- dont_reverse = 1;
- printf("%%%%Pages: %d -1\n", npages);
- break;
- case 0:
- /* what should we do here? */
- default:
- printf("%%%%Pages: %d %d\n", npages, page_order);
- break;
- }
- }
- else if (npages >= 0)
- printf("%%%%Pages: %d\n", npages);
- }
- else
- dont_reverse = 1;
-
- printf("%%%%EndComments\n");
-
- if (dont_reverse)
- copy_and_exit(stdin);
-
- /* process the prologue */
- while (pending_line || get_line(&lb, stdin)) {
- pending_line = 0;
- if (strprefix(lb.buf, "%%BeginDocument"))
- ++level;
- else if (strprefix(lb.buf, "%%EndDocument")) {
- if (level > 0)
- --level;
- }
- else if (level == 0 && strprefix(lb.buf, "%%Page:")) {
- pending_line = 1;
- break;
- }
- put_line(&lb, stdout);
- }
-
- /* if we didn't find any %%Page comments, we're done */
- if (!pending_line)
- exit(0);
-
- /* open a temporary file if necessary */
- if (ftell(stdin) == -1) {
- tempfp = tmpfile();
- clearerr(stdin);
- }
-
- /* process the body */
- while (pending_line || get_line(&lb, stdin)) {
- pending_line = 0;
- if (strprefix(lb.buf, "%%BeginDocument"))
- ++level;
- else if (strprefix(lb.buf, "%%EndDocument")) {
- if (level > 0)
- --level;
- }
- else if (level == 0) {
- if (strprefix(lb.buf, "%%Page:")) {
- page_list *tem = (page_list *)xmalloc(sizeof(page_list));
- tem->next = pl;
- tem->pos = tempfp ? ftell(tempfp) : ftell(stdin) - lb.len;
- pl = tem;
- }
- else if (strprefix(lb.buf, "%%Trailer")) {
- pending_line = 1;
- break;
- }
- }
- if (tempfp != NULL)
- put_line(&lb, tempfp);
- }
-
- /* process the trailer */
- if (pending_line) {
- trailer_pos = tempfp ? ftell(tempfp) : ftell(stdin) - lb.len;
- while (pending_line || get_line(&lb, stdin)) {
- pending_line = 0;
- if (pages_comment_atend && strprefix(lb.buf, "%%Pages:")) {
- int npages, page_order;
- if (sscanf(lb.buf + 8, "%d %d", &npages, &page_order) == 2
- && page_order == -1)
- dont_reverse = 1;
- else
- dont_reverse = 0;
- }
- if (tempfp != NULL)
- put_line(&lb, tempfp);
- }
- }
-
- if (tempfp == NULL)
- tempfp = stdin;
-
- if (dont_reverse) {
- long first_page_pos;
- if (pl == NULL)
- abort();
- /* find the position of the first page */
- while (pl != NULL) {
- page_list *tem = pl;
- first_page_pos = pl->pos;
- pl = pl->next;
- free((char *)tem);
- }
- fseek(tempfp, first_page_pos, 0);
- copy_and_exit(tempfp);
- }
-
- /* output each page */
- prev_pos = trailer_pos == -1 ? ftell(tempfp) : trailer_pos;
- pageno = 1;
- while (pl != NULL) {
- char *ptr, *label;
- int count = prev_pos - pl->pos;
- fseek(tempfp, pl->pos, 0);
- if (!get_line(&lb, tempfp))
- abort();
- if (!strprefix(lb.buf, "%%Page:"))
- abort();
- ptr = lb.buf + 7;
- while (*ptr == ' ')
- ptr++;
- label = ptr;
- while (*ptr != '\0' && !(isascii(*ptr) && isspace(*ptr)))
- ptr++;
- *ptr = '\0';
- if (*label == '\0')
- label = "?";
- printf("%%%%Page: %s %d\n", label, pageno);
- pageno += 1;
- count -= lb.len;
- while (--count >= 0) {
- int c = getc(tempfp);
- if (c == EOF)
- abort();
- putc(c, stdout);
- }
- prev_pos = pl->pos;
- pl = pl->next;
- }
-
- /* output the trailer if there is one */
- if (trailer_pos != -1) {
- fseek(tempfp, trailer_pos, 0);
- copy_and_exit(tempfp);
- }
-
- exit(0);
- }
-
- char *xmalloc(size)
- int size;
- {
- char *tem;
- if ((tem = malloc(size)) == NULL) {
- fprintf(stderr, "%s: out of memory\n", prog);
- exit(1);
- }
- return tem;
- }
-
- char *xrealloc(ptr, size)
- char *ptr;
- int size;
- {
- char *tem;
- if ((tem = realloc(ptr, size)) == NULL) {
- fprintf(stderr, "%s: out of memory\n", prog);
- exit(1);
- }
- return tem;
- }
-