diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/pssplit/pspages.c |
Initial commit
Diffstat (limited to 'support/pssplit/pspages.c')
-rw-r--r-- | support/pssplit/pspages.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/support/pssplit/pspages.c b/support/pssplit/pspages.c new file mode 100644 index 0000000000..6c43889cd0 --- /dev/null +++ b/support/pssplit/pspages.c @@ -0,0 +1,235 @@ +/* + * 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 <dir.h> +# include <io.h> +#else +# include <unistd.h> +#endif +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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); +} |