📄 postreverse.c
字号:
/* * * postreverse - reverse the page order in certain PostScript files. * * Page reversal relies on being able to locate sections of a document using file * structuring comments defined by Adobe (ie. the 1.0 and now 2.0 conventions) and * a few I've added. Among other things a minimally conforming document, according * to the 1.0 conventions, * * 1) Marks the end of the prologue with an %%EndProlog comment. * * 2) Starts each page with a %%Page: comment. * * 3) Marks the end of all the pages %%Trailer comment. * * 4) Obeys page independence (ie. pages can be arbitrarily rearranged). * * The most important change (at least for this program) that Adobe made in going * from the 1.0 to the 2.0 structuring conventions was in the prologue. They now * say the prologue should only define things, and the global initialization that * was in the prologue (1.0 conventions) should now come after the %%EndProlog * comment but before the first %%Page: comment and be bracketed by %%BeginSetup * and %%EndSetup comments. So a document that conforms to Adobe's 2.0 conventions, * * 1) Marks the end of the prologue (only definitions) with %%EndProlog. * * 2) Brackets global initialization with %%BeginSetup and %%EndSetup comments * which come after the prologue but before the first %Page: comment. * * 3) Starts each page with a %%Page: comment. * * 4) Marks the end of all the pages with a %%Trailer comment. * * 5) Obeys page independence. * * postreverse can handle documents that follow the 1.0 or 2.0 conventions, but has * also been extended slightly so it works properly with the translators (primarily * dpost) supplied with this package. The page independence requirement has been * relaxed some. In particular definitions exported to the global environment from * within a page should be bracketed by %%BeginGlobal and %%EndGlobal comments. * postreverse pulls them out of each page and inserts them in the setup section * of the document, immediately before it writes the %%EndProlog (for version 1.0) * or %%EndSetup (for version 2.0) comments. * * In addition postreverse accepts documents that choose to mark the end of each * page with a %%EndPage: comment, which from a translator's point of view is often * a more natural approach. Both page boundary comments (ie. Page: and %%EndPage:) * are also accepted, but be warned that everything between consecutive %%EndPage: * and %%Page: comments will be ignored. * * So a document that will reverse properly with postreverse, * * 1) Marks the end of the prologue with %%EndProlog. * * 2) May have a %%BeginSetup/%%EndSetup comment pair before the first %%Page: * comment that brackets any global initialization. * * 3) Marks the start of each page with a %%Page: comment, or the end of each * page with a %%EndPage: comment. Both page boundary comments are allowed. * * 4) Marks the end of all the pages with a %%Trailer comment. * * 5) Obeys page independence or violates it to a rather limited extent and * marks the violations with %%BeginGlobal and %%EndGlobal comments. * * If no file arguments are given postreverse copies stdin to a temporary file and * then processes that file. That means the input is read three times (rather than * two) whenever we handle stdin. That's expensive, and shouldn't be too difficult * to fix, but I haven't gotten around to it yet. * */#include <stdio.h>#include <signal.h>#include <sys/types.h>#include <fcntl.h>#include "comments.h" /* PostScript file structuring comments */#include "gen.h" /* general purpose definitions */#include "path.h" /* for temporary directory */#include "ext.h" /* external variable declarations */#include "postreverse.h" /* a few special definitions */int page = 1; /* current page number */int forms = 1; /* forms per page in the input file */char *temp_dir = TEMPDIR; /* temp directory for copying stdin */Pages pages[1000]; /* byte offsets for all pages */int next_page = 0; /* next page goes here */long start; /* starting offset for next page */long endoff = -1; /* offset where TRAILER was found */int noreverse = FALSE; /* don't reverse pages if TRUE */char *endprolog = ENDPROLOG; /* occasionally changed to ENDSETUP */double version = 3.3; /* of the input file */int ignoreversion = FALSE; /* ignore possible forms.ps problems */char buf[2048]; /* line buffer for input file */FILE *fp_in; /* stuff is read from this file */FILE *fp_out = stdout; /* and written here *//*****************************************************************************/main(agc, agv) int agc; char *agv[];{/* * * A simple program that reverses the pages in specially formatted PostScript * files. Will work with all the translators in this package, and should handle * any document that conforms to Adobe's version 1.0 or 2.0 file structuring * conventions. Only one input file is allowed, and it can either be a named (on * the command line) file or stdin. * */ argc = agc; /* other routines may want them */ argv = agv; prog_name = argv[0]; /* just for error messages */ init_signals(); /* sets up interrupt handling */ options(); /* first get command line options */ arguments(); /* then process non-option arguments */ done(); /* and clean things up */ exit(x_stat); /* not much could be wrong */} /* End of main *//*****************************************************************************/init_signals(){/* * * Makes sure we handle interrupts properly. * */ if ( signal(SIGINT, interrupt) == SIG_IGN ) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); } else { signal(SIGHUP, interrupt); signal(SIGQUIT, interrupt); } /* End else */ signal(SIGTERM, interrupt);} /* End of init_signals *//*****************************************************************************/options(){ int ch; /* return value from getopt() */ char *optnames = "n:o:rvT:DI"; extern char *optarg; /* used by getopt() */ extern int optind;/* * * Reads and processes the command line options. The -r option (ie. the one that * turns page reversal off) is really only useful if you want to take dpost output * and produce a page independent output file. In that case global definitions * made within pages and bracketed by %%BeginGlobal/%%EndGlobal comments will be * moved into the prologue or setup section of the document. * */ while ( (ch = getopt(argc, argv, optnames)) != EOF ) { switch ( ch ) { case 'n': /* forms per page */ if ( (forms = atoi(optarg)) <= 0 ) error(FATAL, "illegal forms request %s", optarg); break; case 'o': /* output page list */ out_list(optarg); break; case 'r': /* don't reverse the pages */ noreverse = TRUE; break; case 'v': /* ignore possible forms.ps problems */ ignoreversion = TRUE; break; case 'T': /* temporary file directory */ temp_dir = optarg; break; case 'D': /* debug flag */ debug = ON; break; case 'I': /* ignore FATAL errors */ ignore = ON; break; case '?': /* don't understand the option */ error(FATAL, ""); break; default: /* don't know what to do for ch */ error(FATAL, "missing case for option %c\n", ch); break; } /* End switch */ } /* End while */ argc -= optind; /* get ready for non-option args */ argv += optind;} /* End of options *//*****************************************************************************/arguments(){ char *name; /* name of the input file *//* * * postreverse only handles one input file at a time, so if there's more than one * argument left when we get here we'll quit. If none remain we copy stdin to a * temporary file and process that file. * */ if ( argc > 1 ) /* can't handle more than one file */ error(FATAL, "too many arguments"); if ( argc == 0 ) /* copy stdin to a temporary file */ name = copystdin(); else name = *argv; if ( (fp_in = fopen(name, "r")) == NULL ) error(FATAL, "can't open %s", name); reverse();} /* End of arguments *//*****************************************************************************/done(){/* * * Cleans things up after we've finished reversing the pages in the input file. * All that's really left to do is remove the temp file, provided we used one. * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -