/* * file: pspages.c * * (c) Peter Kleiweg 1998 * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, * or (at your option) any later version. * */ #ifdef __MSDOS__ # ifndef __SMALL__ # error Memory model SMALL required # endif # include # include #else # include #endif #include #include #include #include #include #define BUFSIZE 4096 typedef enum { BOTH, EVEN, ODD } PAGES; char buffer [BUFSIZE + 1], *programname; void get_programname (char const *argv0), errit (char const *format, ...), syntax (void); char *get_arg (int argc, char *argv [], int *index); int main (int argc, char *argv []) { PAGES pages = BOTH; int first = 0, last = 0, i; FILE *fp; get_programname (argv [0]); for (i = 1; i < argc; i++) if (argv [i][0] == '-') { switch (argv [i][1]) { case 'f': first = atoi (get_arg (argc, argv, &i)); if (first < 1) errit ("Illegal value for first page: %i", first); break; case 'l': last = atoi (get_arg (argc, argv, &i)); if (last < 1) errit ("Illegal value for last page: %i", last); break; case 'p': first = last = atoi (get_arg (argc, argv, &i)); if (first < 1) errit ("Illegal value for page: %i", first); break; case 'e': pages = EVEN; break; case 'o': pages = ODD; break; default: errit ("Illegal option '%s'", *argv [i]); } } else break; if ((! first) && (! last) && (pages == BOTH)) syntax (); if (first && last && (first > last)) errit ("First page (%i) greater than last page (%i)", first, last); if (first && last && (first == last)) if (first % 2) { if (pages == EVEN) errit ("Page %i is not an even page", first); } else { if (pages == ODD) errit ("Page %i is not an odd page", first); } switch (argc - i) { case 0: if (isatty (fileno (stdin))) syntax (); fp = stdin; break; case 1: fp = fopen (argv [i], "r"); if (! fp) errit ("Opening file \"%s\": %s", argv [i], strerror (errno)); break; default: syntax (); } fputs ( "%!PS\n" "\n" "<<\n" " /EndPage {\n" " dup 0 eq {\n" " pop\n" "\n" " 1 add\n" " true\n", stdout ); if (pages == ODD) fputs ( " 1 index 2 mod 1 ne { pop false } if\n", stdout ); if (pages == EVEN) fputs ( " 1 index 2 mod 0 ne { pop false } if\n", stdout ); if (first) printf ( " 1 index %i lt { pop false } if\n", first ); if (last) printf ( " 1 index %i gt { pop false } if\n", last ); fputs ( " dup not { erasepage } if\n" "\n" " } {\n" " 1 eq\n" " } ifelse\n" " exch pop\n" " }\n" ">> setpagedevice\n" "\n", stdout ); while (fgets (buffer, BUFSIZE, fp)) if (memcmp (buffer, "%%Page", 6) && memcmp (buffer, "%!PS", 4)) fputs (buffer, stdout); if (fp != stdin) fclose (fp); return 0; } char *get_arg (int argc, char *argv [], int *index) { if (argv [*index][2]) return argv [*index] + 2; if (*index == argc - 1) errit ("Missing argument for '%s'", argv [*index]); return argv [++*index]; } void errit (char const *format, ...) { va_list list; fprintf (stderr, "\nError %s: ", programname); va_start (list, format); vfprintf (stderr, format, list); fprintf (stderr, "\n\n"); exit (1); } void get_programname (char const *argv0) { #ifdef __MSDOS__ char name [MAXFILE]; fnsplit (argv0, NULL, NULL, name, NULL); programname = strdup (name); #else /* unix */ char *p; p = strrchr (argv0, '/'); if (p) programname = strdup (p + 1); else programname = strdup (argv0); #endif } void syntax () { fprintf ( stderr, "\nPrinting selected pages from a PostScript document\n\n" "Useful for documents without page number comments\n" "Requires PostScript Level 2 (should understand setpagedevice operator)\n\n" "Usage: %s options [psfile]\n\n" "Options:\n" " -p # page number to print\n" " -f # first page number to print\n" " -l # last page number to print\n" " -e print even pages\n" " -o print odd pages\n\n" "(c) P. Kleiweg 1998\n\n", programname ); exit (1); }