2 * Copyright (C) Angus J. C. Duggan 1991-1995
3 * See file LICENSE for details.
5 * utilities for PS programs
10 * Changed to using ftell() and fseek() only (no length calculations)
11 * Hunter Goatley 31-MAY-1993 23:33
13 * Hunter Goatley 2-MAR-1993 14:41
21 #include <sys/types.h>
24 #define iscomment(x,y) (strncmp(x,y,strlen(y)) == 0)
26 extern char *program
;
31 extern char pagelabel
[BUFSIZ
];
34 static char buffer
[BUFSIZ
];
35 static long bytes
= 0;
36 static long pagescmt
= 0;
37 static long headerpos
= 0;
38 static long endsetup
= 0;
39 static long beginprocset
= 0; /* start of pstops procset */
40 static long endprocset
= 0;
41 static int outputpage
= 0;
42 static int maxpages
= 100;
45 /* list of paper sizes supported */
46 static Paper papersizes
[] = {
47 { "a3", 842, 1191 }, /* 29.7cm * 42cm */
48 { "a4", 595, 842 }, /* 21cm * 29.7cm */
49 { "a5", 421, 595 }, /* 14.85cm * 21cm */
50 { "b5", 516, 729 }, /* 18.2cm * 25.72cm */
51 { "A3", 842, 1191 }, /* 29.7cm * 42cm */
52 { "A4", 595, 842 }, /* 21cm * 29.7cm */
53 { "A5", 421, 595 }, /* 14.85cm * 21cm */
54 { "B5", 516, 729 }, /* 18.2cm * 25.72cm */
55 { "letter", 612, 792 }, /* 8.5in * 11in */
56 { "legal", 612, 1008 }, /* 8.5in * 14in */
57 { "ledger", 1224, 792 }, /* 17in * 11in */
58 { "tabloid", 792, 1224 }, /* 11in * 17in */
59 { "statement", 396, 612 }, /* 5.5in * 8.5in */
60 { "executive", 540, 720 }, /* 7.6in * 10in */
61 { "folio", 612, 936 }, /* 8.5in * 13in */
62 { "quarto", 610, 780 }, /* 8.5in * 10.83in */
63 { "10x14", 720, 1008 }, /* 10in * 14in */
67 /* return pointer to paper size struct or NULL */
68 Paper
* findpaper(char *name
)
71 for (pp
= papersizes
; PaperName(pp
); pp
++) {
72 if (strcmp(PaperName(pp
), name
) == 0) {
79 /* Make a file seekable, using temporary files if necessary */
80 FILE *seekable(FILE *fp
)
95 if (_fstat(fileno(fp
), &fs
) == 0 && (fs
.st_mode
&_S_IFREG
) != 0)
98 if ((fpos
= ftell(fp
)) >= 0)
99 if (!fseek(fp
, 0L, SEEK_END
) && !fseek(fp
, fpos
, SEEK_SET
))
104 message(FATAL
, "input is not seekable\n");
107 if ((ft
= tmpfile()) == NULL
)
110 while ((r
= fread(p
= buffer
, sizeof(char), BUFSIZ
, fp
)) > 0) {
112 if ((w
= fwrite(p
, sizeof(char), r
, ft
)) == 0)
122 /* discard the input file, and rewind the temporary */
124 if (fseek(ft
, 0L, SEEK_SET
) != 0)
132 /* copy input file from current position upto new position to output file */
133 static int fcopy(long upto
)
135 long here
= ftell(infile
);
136 while (here
< upto
) {
137 if ((fgets(buffer
, BUFSIZ
, infile
) == NULL
) ||
138 (fputs(buffer
, outfile
) == EOF
))
140 here
= ftell(infile
);
141 bytes
+= strlen(buffer
);
146 /* build array of pointers to start/end of pages */
149 register char *comment
= buffer
+2;
150 register int nesting
= 0;
151 register long int record
;
153 if ((pageptr
= (long *)malloc(sizeof(long)*maxpages
)) == NULL
)
154 message(FATAL
, "out of memory\n");
156 fseek(infile
, 0L, SEEK_SET
);
157 while (record
= ftell(infile
), fgets(buffer
, BUFSIZ
, infile
) != NULL
)
158 if (*buffer
== '%') {
159 if (buffer
[1] == '%') {
160 if (nesting
== 0 && iscomment(comment
, "Page:")) {
161 if (pages
>= maxpages
-1) {
163 if ((pageptr
= (long *)realloc((char *)pageptr
,
164 sizeof(long)*maxpages
)) == NULL
)
165 message(FATAL
, "out of memory\n");
167 pageptr
[pages
++] = record
;
168 } else if (headerpos
== 0 && iscomment(comment
, "Pages:"))
170 else if (headerpos
== 0 && iscomment(comment
, "EndComments"))
171 headerpos
= ftell(infile
);
172 else if (iscomment(comment
, "BeginDocument") ||
173 iscomment(comment
, "BeginBinary") ||
174 iscomment(comment
, "BeginFile"))
176 else if (iscomment(comment
, "EndDocument") ||
177 iscomment(comment
, "EndBinary") ||
178 iscomment(comment
, "EndFile"))
180 else if (nesting
== 0 && iscomment(comment
, "EndSetup"))
182 else if (nesting
== 0 && iscomment(comment
, "BeginProlog"))
183 headerpos
= ftell(infile
);
184 else if (nesting
== 0 &&
185 iscomment(comment
, "BeginProcSet: PStoPS"))
186 beginprocset
= record
;
187 else if (beginprocset
&& !endprocset
&&
188 iscomment(comment
, "EndProcSet"))
189 endprocset
= ftell(infile
);
190 else if (nesting
== 0 && (iscomment(comment
, "Trailer") ||
191 iscomment(comment
, "EOF"))) {
192 fseek(infile
, record
, SEEK_SET
);
195 } else if (headerpos
== 0 && buffer
[1] != '!')
197 } else if (headerpos
== 0)
199 pageptr
[pages
] = ftell(infile
);
200 if (endsetup
== 0 || endsetup
> pageptr
[0])
201 endsetup
= pageptr
[0];
204 /* seek a particular page */
207 fseek(infile
, pageptr
[p
], SEEK_SET
);
208 if (fgets(buffer
, BUFSIZ
, infile
) != NULL
&&
209 iscomment(buffer
, "%%Page:")) {
211 for (start
= buffer
+7; isspace(*start
); start
++);
214 for (end
= start
+1; paren
> 0; end
++)
217 message(FATAL
, "Bad page label while seeking page %d\n", p
);
226 for (end
= start
; !isspace(*end
); end
++);
227 strncpy(pagelabel
, start
, end
-start
);
228 pagelabel
[end
-start
] = '\0';
231 message(FATAL
, "I/O error seeking page %d\n", p
);
234 /* Output routines. These all update the global variable bytes with the number
235 * of bytes written */
236 void writestring(char *s
)
242 /* write page comment */
243 void writepageheader(char *label
, int page
)
246 message(LOG
, "[%d] ", page
);
247 sprintf(buffer
, "%%%%Page: %s %d\n", label
, ++outputpage
);
251 /* search for page setup */
252 void writepagesetup(void)
257 if (fgets(buffer
, BUFSIZ
, infile
) == NULL
)
258 message(FATAL
, "I/O error reading page setup %d\n", outputpage
);
259 if (!strncmp(buffer
, "PStoPSxform", 11))
261 if (fputs(buffer
, outfile
) == EOF
)
262 message(FATAL
, "I/O error writing page setup %d\n", outputpage
);
263 bytes
+= strlen(buffer
);
268 /* write the body of a page */
269 void writepagebody(int p
)
271 if (!fcopy(pageptr
[p
+1]))
272 message(FATAL
, "I/O error writing page %d\n", outputpage
);
275 /* write a whole page */
276 void writepage(int p
)
279 writepageheader(pagelabel
, p
+1);
283 /* write from start of file to end of header comments */
284 void writeheader(int p
)
286 fseek(infile
, 0L, SEEK_SET
);
288 if (!fcopy(pagescmt
) || fgets(buffer
, BUFSIZ
, infile
) == NULL
)
289 message(FATAL
, "I/O error in header\n");
290 sprintf(buffer
, "%%%%Pages: %d 0\n", p
);
293 if (!fcopy(headerpos
))
294 message(FATAL
, "I/O error in header\n");
297 /* write prologue to end of setup section excluding PStoPS procset */
298 int writepartprolog(void)
300 if (beginprocset
&& !fcopy(beginprocset
))
301 message(FATAL
, "I/O error in prologue\n");
303 fseek(infile
, endprocset
, SEEK_SET
);
305 return !beginprocset
;
308 /* write prologue up to end of setup section */
309 void writeprolog(void)
311 if (!fcopy(endsetup
))
312 message(FATAL
, "I/O error in prologue\n");
315 /* write from end of setup to start of pages */
316 void writesetup(void)
318 if (!fcopy(pageptr
[0]))
319 message(FATAL
, "I/O error in prologue\n");
323 void writetrailer(void)
325 fseek(infile
, pageptr
[pages
], SEEK_SET
);
326 while (fgets(buffer
, BUFSIZ
, infile
) != NULL
) {
330 message(LOG
, "Wrote %d pages, %ld bytes\n", outputpage
, bytes
);
333 /* write a page with nothing on it */
334 void writeemptypage(void)
337 message(LOG
, "[*] ");
338 sprintf(buffer
, "%%%%Page: * %d\n", ++outputpage
);
341 writestring("PStoPSxform concat\n");
342 writestring("showpage\n");