/*
* 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);
}