home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume39 / psutils / part02 < prev    next >
Encoding:
Text File  |  1993-09-20  |  49.3 KB  |  1,961 lines

  1. Newsgroups: comp.sources.misc
  2. From: ajcd@dcs.ed.ac.uk (Angus Duggan)
  3. Subject: v39i094:  psutils - Postscript document manipulation tools, v1.12, Part02/04
  4. Message-ID: <1993Sep20.171855.18099@sparky.sterling.com>
  5. X-Md4-Signature: 362d7c4a18abf960a82998b19fedd53a
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Mon, 20 Sep 1993 17:18:55 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: ajcd@dcs.ed.ac.uk (Angus Duggan)
  12. Posting-number: Volume 39, Issue 94
  13. Archive-name: psutils/part02
  14. Environment: UNIX, VMS, msdos
  15. Supersedes: psutils: Volume 35, Issue 8-11
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 2 (of 4)."
  24. # Contents:  epsffit.c getafm psnup.c psselect.c psspec.c pstops.c
  25. #   psutil.c
  26. # Wrapped by ajcd@fivla on Fri Sep 17 14:10:22 1993
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f epsffit.c -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"epsffit.c\"
  30. else
  31. echo shar: Extracting \"epsffit.c\" \(4661 characters\)
  32. sed "s/^X//" >epsffit.c <<'END_OF_epsffit.c'
  33. X/* epsffit.c
  34. X * AJCD 6 Dec 90
  35. X * fit epsf file into constrained size
  36. X * Usage:
  37. X *       epsffit [-c] [-r] [-a] [-s] llx lly urx ury [file]
  38. X *               -c centres the image in the bounding box given
  39. X *               -r rotates the image by 90 degrees anti-clockwise
  40. X *               -a alters the aspect ratio to fit the bounding box
  41. X *               -s adds a showpage at the end of the image
  42. X *
  43. X * Added filename spec (from Larry Weissman) 5 Feb 93
  44. X * Accepts double %%BoundingBox input, outputs proper BB, 4 Jun 93. (I don't
  45. X * like this; developers should read the Big Red Book before writing code which
  46. X * outputs PostScript.
  47. X */
  48. X
  49. X#include <stdio.h>
  50. X#include <ctype.h>
  51. X#include "patchlevel.h"
  52. X
  53. X#define min(x,y) ((x) > (y) ? (y) : (x))
  54. X#define max(x,y) ((x) > (y) ? (x) : (y))
  55. X
  56. Xstatic char *prog;
  57. X
  58. Xvoid usage()
  59. X{
  60. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  61. X   fprintf(stderr, "Usage: %s [-c] [-r] [-a] [-s] llx lly urx ury [file]\n",
  62. X       prog);
  63. X   exit(1);
  64. X}
  65. X
  66. Xmain(argc, argv)
  67. X     int argc;
  68. X     char **argv;
  69. X{
  70. X   int bbfound = 0;              /* %%BoundingBox: found */
  71. X   int urx, ury, llx, lly;
  72. X   int furx, fury, fllx, flly;
  73. X   int showpage = 0, centre = 0, rotate = 0, aspect = 0, maximise = 0;
  74. X   char buf[BUFSIZ];
  75. X   FILE *input = stdin;
  76. X
  77. X   prog = *argv++; argc--;
  78. X
  79. X   while (argc > 0 && argv[0][0] == '-') {
  80. X      switch (argv[0][1]) {
  81. X      case 'c': centre = 1; break;
  82. X      case 's': showpage = 1; break;
  83. X      case 'r': rotate = 1; break;
  84. X      case 'a': aspect = 1; break;
  85. X      case 'm': maximise = 1; break;
  86. X      case 'v':
  87. X      default:  usage();
  88. X      }
  89. X      argc--;
  90. X      argv++;
  91. X   }
  92. X
  93. X   if (argc < 4) usage();
  94. X   fllx = atoi(argv[0]);
  95. X   flly = atoi(argv[1]);
  96. X   furx = atoi(argv[2]);
  97. X   fury = atoi(argv[3]);
  98. X
  99. X   if (argc > 4) {
  100. X      if(!(input = fopen(argv[4],"r"))) {
  101. X     fprintf(stderr, "%s: Cannot open %s\n", prog, argv[4]);
  102. X     exit(1);
  103. X      }
  104. X   }
  105. X
  106. X   while (fgets(buf, BUFSIZ, input)) {
  107. X      if (buf[0] == '%' && (buf[1] == '%' || buf[1] == '!')) {
  108. X     /* still in comment section */
  109. X     if (!strncmp(buf, "%%BoundingBox:", 14)) {
  110. X        double illx, illy, iurx, iury;    /* input bbox parameters */
  111. X        if (sscanf(buf, "%%%%BoundingBox:%lf %lf %lf %lf\n",
  112. X               &illx, &illy, &iurx, &iury) == 4) {
  113. X           bbfound = 1;
  114. X           llx = (int)illx;    /* accept doubles, but convert to int */
  115. X           lly = (int)illy;
  116. X           urx = (int)(iurx+0.5);
  117. X           ury = (int)(iury+0.5);
  118. X        }
  119. X     } else if (!strncmp(buf, "%%EndComments", 13)) {
  120. X        strcpy(buf, "\n"); /* don't repeat %%EndComments */
  121. X        break;
  122. X     } else fputs(buf,stdout);
  123. X      } else break;
  124. X   }
  125. X
  126. X   if (bbfound) { /* put BB, followed by scale&translate */
  127. X      int fwidth, fheight;
  128. X      double xscale, yscale;
  129. X      double xoffset = fllx, yoffset = flly;
  130. X      double width = urx-llx, height = ury-lly;
  131. X
  132. X      if (maximise)
  133. X     if ((width > height && fury-flly > furx-fllx) ||
  134. X         (width < height && fury-flly < furx-fllx)) 
  135. X        rotate = 1;
  136. X
  137. X      if (rotate) {
  138. X     fwidth = fury - flly;
  139. X     fheight = furx - fllx;
  140. X      } else {
  141. X     fwidth = furx - fllx;
  142. X     fheight = fury - flly;
  143. X      }
  144. X
  145. X      xscale = fwidth/width;
  146. X      yscale = fheight/height;
  147. X
  148. X      if (!aspect) {       /* preserve aspect ratio ? */
  149. X     xscale = yscale = min(xscale,yscale);
  150. X      }
  151. X      width *= xscale;     /* actual width and height after scaling */
  152. X      height *= yscale;
  153. X      if (centre) {
  154. X     if (rotate) {
  155. X        xoffset += (fheight - height)/2;
  156. X        yoffset += (fwidth - width)/2;
  157. X     } else {
  158. X        xoffset += (fwidth - width)/2;
  159. X        yoffset += (fheight - height)/2;
  160. X     }
  161. X      }
  162. X      printf("%%%%BoundingBox: %d %d %d %d\n", (int)xoffset, (int)yoffset,
  163. X         (int)(xoffset+(rotate ? height : width)),
  164. X         (int)(yoffset+(rotate ? width : height)));
  165. X      if (rotate) {  /* compensate for original image shift */
  166. X     xoffset += height + lly * yscale;  /* displacement for rotation */
  167. X     yoffset -= llx * xscale;
  168. X      } else {
  169. X     xoffset -= llx * xscale;
  170. X     yoffset -= lly * yscale;
  171. X      }
  172. X      puts("%%EndComments");
  173. X      if (showpage)
  174. X     puts("save /showpage{}def /copypage{}def /erasepage{}def");
  175. X      else
  176. X     puts("%%BeginProcSet: epsffit 1 0");
  177. X      puts("gsave");
  178. X      printf("%.3lf %.3lf translate\n", xoffset, yoffset);
  179. X      if (rotate)
  180. X     puts("90 rotate");
  181. X      printf("%.3lf %.3lf scale\n", xscale, yscale);
  182. X      if (!showpage)
  183. X     puts("%%EndProcSet");
  184. X   }
  185. X   do {
  186. X      fputs(buf,stdout);
  187. X   } while (fgets(buf, BUFSIZ, input));
  188. X   if (bbfound) {
  189. X      puts("grestore");
  190. X      if (showpage)
  191. X     puts("restore showpage"); /* just in case */
  192. X   } else {
  193. X      fprintf(stderr, "%s: no %%%%BoundingBox:\n", prog);
  194. X      exit(1);
  195. X   }
  196. X   exit(0);
  197. X}
  198. END_OF_epsffit.c
  199. if test 4661 -ne `wc -c <epsffit.c`; then
  200.     echo shar: \"epsffit.c\" unpacked with wrong size!
  201. fi
  202. # end of overwriting check
  203. fi
  204. if test -f getafm -a "${1}" != "-c" ; then 
  205.   echo shar: Will not over-write existing file \"getafm\"
  206. else
  207. echo shar: Extracting \"getafm\" \(6124 characters\)
  208. sed "s/^X//" >getafm <<'END_OF_getafm'
  209. X#!/bin/sh
  210. X
  211. Xif [ $# -ne 1 ]; then
  212. X  echo "usage: $0 font-name | gsnd - >font-name.afm" >&2
  213. X  exit 1
  214. Xfi
  215. X
  216. Xcat << EOF
  217. X%!
  218. X% produce .afm for $1
  219. X% (c) 1993 by Robert Joop <rj@rainbow.in-berlin.de>
  220. X% inspired by two other versions of this theme which are
  221. X%    getafm 1.00 (c) AJCD
  222. X% and getafm.ps by an unknown author,
  223. X%    modified by J. Daniel Smith <dsmith@mailhost.aa.cad.slb.com>
  224. X
  225. X% Metrics dictionary code added by AJCD, 7/6/93
  226. X
  227. X/getafmdict 100 dict dup begin
  228. X
  229. X  /buf 256 string def
  230. X  /buf2 16 string def
  231. X
  232. X  /prany    % dict dictname printname -> dict
  233. X  {
  234. X    2 index 2 index cvn known
  235. X    {
  236. X      print % printname
  237. X      ( ) print
  238. X      1 index exch cvn get =
  239. X    }
  240. X    {
  241. X      (Comment /FontInfo contains no /) print
  242. X      2 copy eq
  243. X      {
  244. X        = % printname
  245. X    pop % dictname
  246. X      }
  247. X      {
  248. X    exch
  249. X    print % dictname
  250. X    (, therefore no ) print
  251. X    = % printname
  252. X      }
  253. X      ifelse
  254. X    }
  255. X    ifelse
  256. X  }
  257. X  bind def
  258. X
  259. X  /printfontname
  260. X  {
  261. X    (FontName)dup prany
  262. X  }
  263. X  bind def
  264. X
  265. X  /printfontinfo
  266. X  {
  267. X    dup /FontInfo known
  268. X    {
  269. X      dup /FontInfo get
  270. X    (FullName)dup prany
  271. X    (FamilyName)dup prany
  272. X    (Weight)dup prany
  273. X    (ItalicAngle)dup prany
  274. X    (isFixedPitch)(IsFixedPitch) prany
  275. X    (UnderlinePosition)dup prany
  276. X    (UnderlineThickness)dup prany
  277. X    (Version)(version) prany
  278. X    (Notice)dup prany
  279. X      pop
  280. X    }
  281. X    {
  282. X      (Comment Font lacks a /FontInfo!)=
  283. X    }
  284. X    ifelse
  285. X  }
  286. X  bind def
  287. X
  288. X  /prbbox % llx lly urx ury -> -
  289. X  {
  290. X    4 1 roll 3 1 roll exch % swap top 4 elements
  291. X    4 { ( ) print buf cvs print } repeat
  292. X  }
  293. X  bind def
  294. X
  295. X  /getbbox % fontdict chardict character -> fontdict chardict llx lly urx ury
  296. X  {
  297. X    gsave
  298. X      2 index setfont 0 0 moveto
  299. X      false charpath flattenpath pathbbox
  300. X    grestore
  301. X  }
  302. X  bind def
  303. X
  304. X  /printmiscinfo
  305. X  {
  306. X    dup /FontBBox known
  307. X    {
  308. X      (FontBBox) print
  309. X      dup /FontBBox get aload pop prbbox ()=
  310. X    }
  311. X    {
  312. X      (Comment missing required /FontBBox)=
  313. X      quit
  314. X    }
  315. X    ifelse
  316. X    2 copy exch get
  317. X      dup /H known
  318. X      1 index /x known and
  319. X      1 index /d known and
  320. X      1 index /p known and
  321. X      dup /looksRoman exch def
  322. X      {
  323. X    (CapHeight ) print
  324. X    (H) getbbox
  325. X    ceiling cvi = pop pop pop
  326. X    (XHeight ) print
  327. X    (x) getbbox
  328. X    ceiling cvi = pop pop pop
  329. X    (Ascender ) print
  330. X    (d) getbbox
  331. X    ceiling cvi = pop pop pop
  332. X    (Descender ) print
  333. X    (p) getbbox
  334. X    pop pop floor cvi = pop
  335. X      }
  336. X      {
  337. X    (Comment font doesn't contain H, x, d and p; therefore no CapHeight, XHeight, Ascender and Descender)=
  338. X      }
  339. X      ifelse
  340. X    pop
  341. X    dup /Encoding get
  342. X      [
  343. X    [ (ISOLatin1Encoding) /ISOLatin1Encoding ]
  344. X    [ (AdobeStandardEncoding) /StandardEncoding ]
  345. X      ]
  346. X      {
  347. X    aload pop dup where
  348. X    {
  349. X      exch get 2 index eq
  350. X      {
  351. X        (EncodingScheme ) print
  352. X        buf cvs =
  353. X      }
  354. X      {
  355. X        pop
  356. X      }
  357. X      ifelse
  358. X    }
  359. X    {
  360. X      pop pop
  361. X    }
  362. X    ifelse
  363. X      }
  364. X      forall
  365. X    pop
  366. X  }
  367. X  bind def
  368. X
  369. X  /printcharmetric
  370. X  {
  371. X    % chardictname fontdict charnamedict encoding charindex charname
  372. X
  373. X    4 index dup length dict dup begin exch
  374. X      {
  375. X    1 index /FID ne
  376. X    2 index /UniqueID ne
  377. X    and
  378. X    {
  379. X      1 index /Encoding eq { 256 array copy } if
  380. X      def
  381. X    }
  382. X    { pop pop }
  383. X    ifelse
  384. X      }
  385. X      forall
  386. X    end
  387. X    dup /Encoding get 32 3 index put
  388. X    /f2 exch definefont
  389. X    setfont
  390. X
  391. X    (C ) print
  392. X    1 index buf cvs print
  393. X
  394. X    ( ; WX ) print
  395. X% Metrics entries are:
  396. X%       1 number:               which is the character width
  397. X%       an array of 2 numbers:  which are the left sidebearing and width
  398. X%       an array of 4 numbers:  x & y left sidebearing, width and height
  399. X    dup 5 index         % /charname fontdict
  400. X    dup /Metrics known {
  401. X       /Metrics get exch 2 copy known {
  402. X          get dup type /arraytype eq {
  403. X             dup length 2 eq
  404. X             {1 get} {2 get} ifelse
  405. X          } if
  406. X          round cvi buf cvs print
  407. X       } {
  408. X          pop pop ( ) stringwidth pop round cvi buf cvs print
  409. X       } ifelse
  410. X    } {
  411. X       pop pop ( ) stringwidth pop round cvi buf cvs print
  412. X    } ifelse
  413. X
  414. X    ( ; N ) print
  415. X    dup buf cvs print
  416. X
  417. X    ( ; B) print
  418. X    gsave
  419. X      newpath 0 0 moveto
  420. X      ( ) true charpath flattenpath pathbbox
  421. X    grestore
  422. X    2 { ceiling cvi 4 1 roll } repeat
  423. X    2 { floor cvi 4 1 roll } repeat
  424. X    prbbox
  425. X
  426. X    looksRoman
  427. X    {
  428. X      [
  429. X    [ /f [ /i /f /l ] ]
  430. X    [ /ff [ /i /l ] ]
  431. X      ]
  432. X      {
  433. X    aload pop 1 index 3 index eq
  434. X    {
  435. X      { 
  436. X        1 index buf cvs
  437. X        length
  438. X        1 index buf2 cvs dup length
  439. X        2 index add
  440. X        buf
  441. X        4 2 roll putinterval
  442. X        buf 0
  443. X        3 -1 roll getinterval
  444. X        dup cvn
  445. X        7 index
  446. X        exch known
  447. X        {
  448. X          exch
  449. X          ( ; L ) print
  450. X          buf2 cvs print
  451. X          ( ) print
  452. X          print
  453. X        }
  454. X        {
  455. X          pop pop
  456. X        }
  457. X        ifelse
  458. X      }
  459. X      forall
  460. X      pop 
  461. X    }
  462. X    {
  463. X      pop pop
  464. X    }
  465. X    ifelse
  466. X      }
  467. X      forall
  468. X    }
  469. X    if
  470. X    pop
  471. X
  472. X    ( ;)=
  473. X  }
  474. X  bind def
  475. X
  476. X  /printcharmetrics
  477. X  {
  478. X    (StartCharMetrics ) print
  479. X    2 copy exch get length 1 sub buf cvs =
  480. X
  481. X    256 dict dup begin
  482. X      1 index /Encoding get
  483. X      { null def }
  484. X      forall
  485. X    end
  486. X    % chardictname fontdict charnamedict
  487. X    1 index /Encoding get
  488. X    0 1 255
  489. X    {
  490. X      % encoding index
  491. X      2 copy get
  492. X      dup /.notdef eq { pop } { printcharmetric } ifelse
  493. X      pop % index
  494. X    } for
  495. X
  496. X    -1
  497. X    3 index 5 index get
  498. X    {
  499. X      pop
  500. X      dup /.notdef eq
  501. X      { pop }
  502. X      {
  503. X    % chardictname fontdict charnamedict encoding charindex charname
  504. X    dup 4 index exch known
  505. X    { pop }
  506. X    { printcharmetric }
  507. X    ifelse
  508. X      }
  509. X      ifelse
  510. X    }
  511. X    forall
  512. X    % charnamedict encoding index
  513. X    pop pop pop
  514. X
  515. X    (EndCharMetrics)=
  516. X  }
  517. X  bind def
  518. X
  519. X  /printfontmetrics
  520. X  {
  521. X    (StartFontMetrics 3.0)=
  522. X    (Comment Produced by getafm 3.0 (which is by rj@rainbow.in-berlin.de))=
  523. X
  524. X    printfontname
  525. X    printfontinfo
  526. X    printmiscinfo
  527. X    printcharmetrics
  528. X
  529. X    (EndFontMetrics)=
  530. X  }
  531. X  bind def
  532. X
  533. Xend def
  534. X
  535. X/getafm
  536. X{
  537. X  getafmdict begin
  538. X    save exch
  539. X      findfont 1000 scalefont 
  540. X
  541. X      null
  542. X      [ /CharDefs /CharData /CharProcs /CharStrings ]
  543. X      {
  544. X    2 index 1 index known { exch } if
  545. X    pop
  546. X      }
  547. X      forall
  548. X      dup null eq
  549. X      {
  550. X    (can't find dictionary with character data!)=
  551. X    quit
  552. X      }
  553. X      if
  554. X      exch % dictname fontdict
  555. X
  556. X      printfontmetrics
  557. X
  558. X      pop pop
  559. X    restore
  560. X  end
  561. X}
  562. Xbind def
  563. X
  564. X/$1 getafm
  565. X
  566. XEOF
  567. END_OF_getafm
  568. if test 6124 -ne `wc -c <getafm`; then
  569.     echo shar: \"getafm\" unpacked with wrong size!
  570. fi
  571. chmod +x getafm
  572. # end of overwriting check
  573. fi
  574. if test -f psnup.c -a "${1}" != "-c" ; then 
  575.   echo shar: Will not over-write existing file \"psnup.c\"
  576. else
  577. echo shar: Extracting \"psnup.c\" \(8785 characters\)
  578. sed "s/^X//" >psnup.c <<'END_OF_psnup.c'
  579. X/* psnup.c
  580. X * AJCD 4/6/93
  581. X * put multiple pages onto one physical sheet of paper
  582. X *
  583. X * Usage:
  584. X *      psnup [-q] [-w<dim>] [-h<dim>] [-ppaper] [-b<dim>] [-m<dim>]
  585. X *            [-l] [-c] [-f] [-sscale] [-d] [-nup] [in [out]]
  586. X *              -w<dim> sets the paper width
  587. X *              -h<dim> sets the paper height
  588. X *              -ppaper sets the paper size (width and height) by name
  589. X *              -m<dim> sets the margin around the paper
  590. X *              -b<dim> sets the border around each page
  591. X *              -sscale alters the scale at which the pages are displayed
  592. X *              -l      used if pages are in landscape orientation (rot left)
  593. X *              -r      used if pages are in seascape orientation (rot right)
  594. X *         -c    for column-major layout
  595. X *        -f    for flipped (wider than tall) pages
  596. X *         -d    to draw the page boundaries
  597. X */
  598. X
  599. X#include "psutil.h"
  600. X#include "psspec.h"
  601. X#include "patchlevel.h"
  602. X
  603. Xvoid usage()
  604. X{
  605. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  606. X   fprintf(stderr, "Usage: %s [-q] [-wwidth] [-hheight] [-ppaper] [-l] [-r] [-c] [-f] [-mmargin] [-bborder] [-dlwidth] [-sscale] [-nup] [infile [outfile]]\n",
  607. X       prog);
  608. X   fflush(stderr);
  609. X   exit(1);
  610. X}
  611. X
  612. Xvoid argerror()
  613. X{
  614. X   fprintf(stderr, "%s: bad dimension\n", prog);
  615. X   fflush(stderr);
  616. X   exit(1);
  617. X}
  618. X
  619. X#define min(x,y) ((x) > (y) ? (y) : (x))
  620. X#define max(x,y) ((x) > (y) ? (x) : (y))
  621. X
  622. X/* return next larger exact divisor of number, or 0 if none. There is probably
  623. X * a much more efficient method of doing this, but the numbers involved are
  624. X * small, so it's not a big loss. */
  625. Xint nextdiv(n, m)
  626. X     int n, m;
  627. X{
  628. X   while (++n <= m) {
  629. X      if (m%n == 0)
  630. X     return (n);
  631. X   }
  632. X   return (0);
  633. X}
  634. X
  635. Xmain(argc, argv)
  636. X     int argc;
  637. X     char *argv[];
  638. X{
  639. X   int horiz, vert, rotate, column, flip, leftright, topbottom;
  640. X   int nup = 1;
  641. X   double draw = 0;                /* draw page borders */
  642. X   double scale;                /* page scale */
  643. X   double uscale = 0;                /* user supplied scale */
  644. X   double ppwid, pphgt;                /* paper dimensions */
  645. X   double margin, border;            /* paper & page margins */
  646. X   double vshift, hshift;            /* page centring shifts */
  647. X   double tolerance = 100000;            /* layout tolerance */
  648. X   struct papersize *paper;
  649. X
  650. X#ifdef PAPER
  651. X   if (paper = findpaper(PAPER)) {
  652. X      width = (double)paper->width;
  653. X      height = (double)paper->height;
  654. X   }
  655. X#endif
  656. X
  657. X   margin = border = vshift = hshift = column = flip = 0;
  658. X   leftright = topbottom = 1;
  659. X
  660. X   infile = stdin;
  661. X   outfile = stdout;
  662. X   verbose = 1;
  663. X   for (prog = *argv++; --argc; argv++) {
  664. X      if (argv[0][0] == '-') {
  665. X     switch (argv[0][1]) {
  666. X     case 'q':    /* quiet */
  667. X        verbose = 0;
  668. X        break;
  669. X     case 'd':    /* draw borders */
  670. X        if (argv[0][2])
  671. X           draw = singledimen(*argv+2);
  672. X        else
  673. X           draw = 1;
  674. X        break;
  675. X     case 'l':    /* landscape (rotated left) */
  676. X        column = !column;
  677. X        topbottom = !topbottom;
  678. X        break;
  679. X     case 'r':    /* seascape (rotated right) */
  680. X        column = !column;
  681. X        leftright = !leftright;
  682. X        break;
  683. X     case 'f':    /* flipped */
  684. X        flip = 1;
  685. X        break;
  686. X     case 'c':    /* column major layout */
  687. X        column = !column;
  688. X        break;
  689. X     case 'w':    /* page width */
  690. X        width = singledimen(*argv+2);
  691. X        break;
  692. X     case 'h':    /* page height */
  693. X        height = singledimen(*argv+2);
  694. X        break;
  695. X     case 'm':    /* margins around whole page */
  696. X        margin = singledimen(*argv+2);
  697. X        break;
  698. X     case 'b':    /* border around individual pages */
  699. X        border = singledimen(*argv+2);
  700. X        break;
  701. X     case 't':    /* layout tolerance */
  702. X        tolerance = atof(*argv+2);
  703. X        break;
  704. X     case 's':    /* override scale */
  705. X        uscale = atof(*argv+2);
  706. X        break;
  707. X     case 'p':    /* paper type */
  708. X        if (paper = findpaper(*argv+2)) {
  709. X           width = (double)paper->width;
  710. X           height = (double)paper->height;
  711. X        } else {
  712. X           fprintf(stderr, "%s: paper size '%s' not recognised\n",
  713. X               prog, *argv+2);
  714. X           fflush(stderr);
  715. X           exit(1);
  716. X        }
  717. X        break;
  718. X     case 'n':    /* n-up, for compatibility with other psnups */
  719. X        if (argc >= 2) {
  720. X           argv++;
  721. X           argc--;
  722. X           if ((nup = atoi(*argv)) < 1) {
  723. X          fprintf(stderr, "%s: -n %d too small\n", prog, nup);
  724. X          fflush(stderr);
  725. X          exit(1);
  726. X           }
  727. X        } else {
  728. X           fprintf(stderr, "%s: argument expected for -n\n", prog);
  729. X           fflush(stderr);
  730. X           exit(1);
  731. X        }
  732. X        break;
  733. X     case '1':
  734. X     case '2':
  735. X     case '3':
  736. X     case '4':
  737. X     case '5':
  738. X     case '6':
  739. X     case '7':
  740. X     case '8':
  741. X     case '9':
  742. X        nup = atoi(*argv+1);
  743. X        break;
  744. X     case 'v':    /* version */
  745. X     default:
  746. X        usage();
  747. X     }
  748. X      } else if (infile == stdin) {
  749. X     if ((infile = fopen(*argv, "r")) == NULL) {
  750. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  751. X        fflush(stderr);
  752. X        exit(1);
  753. X     }
  754. X      } else if (outfile == stdout) {
  755. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  756. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  757. X        fflush(stderr);
  758. X        exit(1);
  759. X     }
  760. X      } else usage();
  761. X   }
  762. X   if ((infile=seekable(infile))==NULL) {
  763. X      fprintf(stderr, "%s: can't seek input\n", prog);
  764. X      fflush(stderr);
  765. X      exit(1);
  766. X   }
  767. X
  768. X   if (width <= 0 || height <= 0) {
  769. X      fprintf(stderr, "%s: page width and height must be set\n", prog);
  770. X      fflush(stderr);
  771. X      exit(1);
  772. X   }
  773. X
  774. X   /* subtract paper margins from height & width */
  775. X   ppwid = width - margin*2;
  776. X   pphgt = height - margin*2;
  777. X
  778. X   if (ppwid <= 0 || pphgt <= 0) {
  779. X      fprintf(stderr, "%s: paper margins are too large\n", prog);
  780. X      fflush(stderr);
  781. X      exit(1);
  782. X   }
  783. X
  784. X   /* Finding the best layout is an optimisation problem. We try all of the
  785. X    * combinations of width*height in both normal and rotated form, and
  786. X    * minimise the wasted space. */
  787. X   {
  788. X      double best = tolerance;
  789. X      int hor;
  790. X      for (hor = 1; hor; hor = nextdiv(hor, nup)) {
  791. X     int ver = nup/hor;
  792. X     /* try normal orientation first */
  793. X     double scl = min(pphgt/(height*ver), ppwid/(width*hor));
  794. X     double optim = (ppwid-scl*width*hor)*(ppwid-scl*width*hor) +
  795. X        (pphgt-scl*height*ver)*(pphgt-scl*height*ver);
  796. X     if (optim < best) {
  797. X        best = optim;
  798. X        /* recalculate scale to allow for internal borders */
  799. X        scale = min((pphgt-2*border*ver)/(height*ver),
  800. X            (ppwid-2*border*hor)/(width*hor));
  801. X        hshift = (ppwid/hor - width*scale)/2;
  802. X        vshift = (pphgt/ver - height*scale)/2;
  803. X        horiz = hor; vert = ver;
  804. X        rotate = flip;
  805. X     }
  806. X     /* try rotated orientation */
  807. X     scl = min(pphgt/(width*hor), ppwid/(height*ver));
  808. X     optim = (pphgt-scl*width*hor)*(pphgt-scl*width*hor) +
  809. X        (ppwid-scl*height*ver)*(ppwid-scl*height*ver);
  810. X     if (optim < best) {
  811. X        best = optim;
  812. X        /* recalculate scale to allow for internal borders */
  813. X        scale = min((pphgt-2*border*hor)/(width*hor),
  814. X            (ppwid-2*border*ver)/(height*ver));
  815. X        hshift = (ppwid/ver - height*scale)/2;
  816. X        vshift = (pphgt/hor - width*scale)/2;
  817. X        horiz = ver; vert = hor;
  818. X        rotate = !flip;
  819. X     }
  820. X      }
  821. X
  822. X      /* fail if nothing better than worst tolerance was found */
  823. X      if (best == tolerance) {
  824. X     fprintf(stderr, "%s: can't find acceptable layout for %d-up\n",
  825. X         prog, nup);
  826. X     fflush(stderr);
  827. X     exit(1);
  828. X      }
  829. X   }
  830. X
  831. X   if (flip) {    /* swap width & height for clipping */
  832. X      double tmp = width;
  833. X      width = height;
  834. X      height = tmp;
  835. X   }
  836. X
  837. X   if (rotate) {    /* rotate leftright and topbottom orders */
  838. X      int tmp = topbottom;
  839. X      topbottom = !leftright;
  840. X      leftright = tmp;
  841. X      column = !column;
  842. X   }
  843. X
  844. X   /* now construct specification list and run page rearrangement procedure */
  845. X   {
  846. X      int page = 0;
  847. X      struct pagespec *specs, *tail;
  848. X
  849. X      tail = specs = newspec();
  850. X
  851. X      while (page < nup) {
  852. X     int up, across;        /* page index */
  853. X
  854. X     if (column) {
  855. X        if (leftright)        /* left to right */
  856. X           across = page/vert;
  857. X        else            /* right to left */
  858. X           across = horiz-1-page/vert;
  859. X        if (topbottom)        /* top to bottom */
  860. X           up = vert-1-page%vert;
  861. X        else            /* bottom to top */
  862. X           up = page%vert;
  863. X     } else {
  864. X        if (leftright)        /* left to right */
  865. X           across = page%horiz;
  866. X        else            /* right to left */
  867. X           across = horiz-1-page%horiz;
  868. X        if (topbottom)        /* top to bottom */
  869. X           up = vert-1-page/horiz;
  870. X        else            /* bottom to top */
  871. X           up = page/horiz;
  872. X     }
  873. X     if (rotate) {
  874. X        tail->xoff = margin + (across+1)*ppwid/horiz - hshift;
  875. X        tail->rotate = 90;
  876. X        tail->flags |= ROTATE;
  877. X     } else {
  878. X        tail->xoff = margin + across*ppwid/horiz + hshift;
  879. X     }
  880. X     tail->pageno = page;
  881. X     if (uscale > 0)
  882. X        tail->scale = uscale;
  883. X     else
  884. X        tail->scale = scale;
  885. X     tail->flags |= SCALE;
  886. X     tail->yoff = margin + up*pphgt/vert + vshift;
  887. X     tail->flags |= OFFSET;
  888. X     if (++page < nup) {
  889. X        tail->flags |= ADD_NEXT;
  890. X        tail->next = newspec();
  891. X        tail = tail->next;
  892. X     }
  893. X      }
  894. X      
  895. X      pstops(nup, 1, 0, specs, draw);        /* do page rearrangement */
  896. X   }
  897. X
  898. X   exit(0);
  899. X}
  900. X
  901. END_OF_psnup.c
  902. if test 8785 -ne `wc -c <psnup.c`; then
  903.     echo shar: \"psnup.c\" unpacked with wrong size!
  904. fi
  905. # end of overwriting check
  906. fi
  907. if test -f psselect.c -a "${1}" != "-c" ; then 
  908.   echo shar: Will not over-write existing file \"psselect.c\"
  909. else
  910. echo shar: Extracting \"psselect.c\" \(5298 characters\)
  911. sed "s/^X//" >psselect.c <<'END_OF_psselect.c'
  912. X/* psselect.c
  913. X * AJCD 27/1/91
  914. X * rearrange pages in conforming PS file for printing in signatures
  915. X *
  916. X * Usage:
  917. X *       psselect [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]
  918. X */
  919. X
  920. X#include "psutil.h"
  921. X#include "patchlevel.h"
  922. X
  923. Xvoid usage()
  924. X{
  925. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  926. X   fprintf(stderr,
  927. X       "Usage: %s [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]\n",
  928. X       prog);
  929. X   fflush(stderr);
  930. X   exit(1);
  931. X}
  932. X
  933. Xstruct pgrange {
  934. X   int first, last;
  935. X   struct pgrange *next;
  936. X};
  937. X
  938. Xtypedef struct pgrange range;
  939. X
  940. Xrange * makerange(beg, end, next)
  941. X     int beg, end;
  942. X     range *next;
  943. X{
  944. X   range *new;
  945. X   if ((new = (range *)malloc(sizeof(range))) == NULL) {
  946. X      fprintf(stderr, "%s: out of memory\n", prog);
  947. X      fflush(stderr);
  948. X      exit(1);
  949. X   }
  950. X   new->first = beg;
  951. X   new->last = end;
  952. X   new->next = next;
  953. X   return (new);
  954. X}
  955. X
  956. X
  957. Xrange * addrange(str, rp)
  958. X     char *str;
  959. X     range *rp;
  960. X{
  961. X   int first=0;
  962. X   int sign;
  963. X   sign = (*str == '_' && ++str) ? -1 : 1;
  964. X   if (isdigit(*str)) {
  965. X      first = sign*atoi(str);
  966. X      while (isdigit(*str)) str++;
  967. X   }
  968. X   switch (*str) {
  969. X   case '\0':
  970. X      if (first)
  971. X     return (makerange(first, first, rp));
  972. X      break;
  973. X   case ',':
  974. X      if (first)
  975. X     return (addrange(str+1, makerange(first, first, rp)));
  976. X      break;
  977. X   case '-':
  978. X   case ':':
  979. X      str++;
  980. X      sign = (*str == '_' && ++str) ? -1 : 1;
  981. X      if (isdigit(*str)) {
  982. X     int last = sign*atoi(str);
  983. X     while (isdigit(*str)) str++;
  984. X     if (!first)
  985. X        first = 1;
  986. X     if (last >= first) 
  987. X        switch (*str) {
  988. X        case '\0':
  989. X           return (makerange(first, last, rp));
  990. X        case ',':
  991. X           return (addrange(str+1, makerange(first, last, rp)));
  992. X        }
  993. X      } else if (*str == '\0')
  994. X     return (makerange(first, -1, rp));
  995. X      else if (*str == ',')
  996. X     return (addrange(str+1, makerange(first, -1, rp)));
  997. X   }
  998. X   fprintf(stderr, "%s: invalid page range\n", prog);
  999. X   fflush(stderr);
  1000. X   exit(1);
  1001. X}
  1002. X
  1003. X
  1004. Xmain(argc, argv)
  1005. X     int argc;
  1006. X     char *argv[];
  1007. X{
  1008. X   int currentpg, maxpage = 0;
  1009. X   int even = 0, odd = 0, reverse = 0;
  1010. X   int pass, all;
  1011. X   range *pagerange = NULL;
  1012. X
  1013. X   infile = stdin;
  1014. X   outfile = stdout;
  1015. X   verbose = 1;
  1016. X   for (prog = *argv++; --argc; argv++) {
  1017. X      if (argv[0][0] == '-') {
  1018. X     switch (argv[0][1]) {
  1019. X     case 'e':    /* even pages */
  1020. X        even = 1;
  1021. X        break;
  1022. X     case 'o':    /* odd pages */
  1023. X        odd = 1;
  1024. X        break;
  1025. X     case 'r':    /* reverse */
  1026. X        reverse = 1;
  1027. X        break;
  1028. X     case 'p':    /* page spec */
  1029. X        pagerange = addrange(*argv+2, pagerange);
  1030. X        break;
  1031. X     case 'q':    /* quiet */
  1032. X        verbose = 0;
  1033. X        break;
  1034. X     case 'v':    /* version */
  1035. X     default:
  1036. X        usage();
  1037. X     }
  1038. X      } else if (pagerange == NULL && !reverse && !even && !odd) {
  1039. X     pagerange = addrange(*argv, NULL);
  1040. X      } else if (infile == stdin) {
  1041. X     if ((infile = fopen(*argv, "r")) == NULL) {
  1042. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  1043. X        fflush(stderr);
  1044. X        exit(1);
  1045. X     }
  1046. X      } else if (outfile == stdout) {
  1047. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  1048. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  1049. X        fflush(stderr);
  1050. X        exit(1);
  1051. X     }
  1052. X      } else usage();
  1053. X   }
  1054. X   if ((infile=seekable(infile))==NULL) {
  1055. X      fprintf(stderr, "%s: can't seek input\n", prog);
  1056. X      fflush(stderr);
  1057. X      exit(1);
  1058. X   }
  1059. X   scanpages();
  1060. X
  1061. X   /* reverse page list if not reversing pages (list constructed bottom up) */
  1062. X   if (!reverse) {
  1063. X      range *revlist = NULL;
  1064. X      range *next = NULL;
  1065. X      while (pagerange) {
  1066. X     next = pagerange->next;
  1067. X     pagerange->next = revlist;
  1068. X     revlist = pagerange;
  1069. X     pagerange = next;
  1070. X      }
  1071. X      pagerange = revlist;
  1072. X   }
  1073. X
  1074. X   /* select all pages or all in range if odd or even not set */
  1075. X   all = !(odd || even);
  1076. X
  1077. X   /* count pages on first pass, select pages on second pass */
  1078. X   for (pass = 0; pass < 2; pass++) {
  1079. X      if (pass) {                           /* write header on second pass */
  1080. X     writeheader(maxpage);
  1081. X     writeprolog("");
  1082. X      }
  1083. X      if (pagerange) {
  1084. X     range *r;
  1085. X     for (r = pagerange; r; r = r->next) {
  1086. X        if (pagerange->first < 0) {
  1087. X           pagerange->first += pages + 1;
  1088. X           if (pagerange->first < 0)
  1089. X          pagerange->first = 0;
  1090. X        }
  1091. X        if (pagerange->last < 0) {
  1092. X           pagerange->last += pages + 1;
  1093. X           if (pagerange->last < 0)
  1094. X          pagerange->last = 0;
  1095. X        }
  1096. X        if (reverse) {
  1097. X           for (currentpg = r->last; currentpg >= r->first; currentpg--) {
  1098. X          if (currentpg <= pages &&
  1099. X              ((currentpg&1) ? (odd || all) : (even || all))) {
  1100. X             if (pass)
  1101. X            writepage(currentpg-1);
  1102. X             else
  1103. X            maxpage++;
  1104. X          }
  1105. X           }
  1106. X        } else {
  1107. X           for (currentpg = r->first; currentpg <= r->last; currentpg++) {
  1108. X          if (currentpg <= pages &&
  1109. X              ((currentpg&1) ? (odd || all) : (even || all))) {
  1110. X             if (pass)
  1111. X            writepage(currentpg-1);
  1112. X             else
  1113. X            maxpage++;
  1114. X          }
  1115. X           }
  1116. X        }
  1117. X     }
  1118. X      } else if (reverse) {
  1119. X     for (currentpg = pages; currentpg > 0; currentpg--)
  1120. X        if ((currentpg&1) ? (odd || all) : (even || all)) {
  1121. X           if (pass)
  1122. X          writepage(currentpg-1);
  1123. X           else
  1124. X          maxpage++;
  1125. X        }
  1126. X      } else {
  1127. X     for (currentpg = 1; currentpg <= pages; currentpg++)
  1128. X        if ((currentpg&1) ? (odd || all) : (even || all)) {
  1129. X           if (pass)
  1130. X          writepage(currentpg-1);
  1131. X           else
  1132. X          maxpage++;
  1133. X        }
  1134. X      }
  1135. X   }
  1136. X   writetrailer();
  1137. X
  1138. X   exit(0);
  1139. X}
  1140. END_OF_psselect.c
  1141. if test 5298 -ne `wc -c <psselect.c`; then
  1142.     echo shar: \"psselect.c\" unpacked with wrong size!
  1143. fi
  1144. # end of overwriting check
  1145. fi
  1146. if test -f psspec.c -a "${1}" != "-c" ; then 
  1147.   echo shar: Will not over-write existing file \"psspec.c\"
  1148. else
  1149. echo shar: Extracting \"psspec.c\" \(7082 characters\)
  1150. sed "s/^X//" >psspec.c <<'END_OF_psspec.c'
  1151. X/* psspec.c
  1152. X * AJCD 5/6/93
  1153. X * page spec routines for page rearrangement
  1154. X */
  1155. X
  1156. X#include "psutil.h"
  1157. X#include "psspec.h"
  1158. X#include "patchlevel.h"
  1159. X
  1160. Xdouble width = -1;
  1161. Xdouble height = -1;
  1162. X
  1163. X/* create a new page spec */
  1164. Xstruct pagespec *newspec()
  1165. X{
  1166. X   struct pagespec *temp = (struct pagespec *)malloc(sizeof(struct pagespec));
  1167. X   if (temp == NULL) {
  1168. X      fprintf(stderr, "%s: out of memory\n", prog);
  1169. X      fflush(stderr);
  1170. X      exit(1);
  1171. X   }
  1172. X   temp->reversed = temp->pageno = temp->flags = temp->rotate = 0;
  1173. X   temp->scale = 1;
  1174. X   temp->xoff = temp->yoff = 0;
  1175. X   temp->next = NULL;
  1176. X   return (temp);
  1177. X}
  1178. X
  1179. X/* dimension parsing routines */
  1180. Xint parseint(sp)
  1181. X     char **sp;
  1182. X{
  1183. X   char *s = *sp;
  1184. X   int num = atoi(s);
  1185. X
  1186. X   while (isdigit(*s))
  1187. X      s++;
  1188. X   if (*sp == s) argerror();
  1189. X   *sp = s;
  1190. X   return (num);
  1191. X}
  1192. X
  1193. Xdouble parsedouble(sp)
  1194. X     char **sp;
  1195. X{
  1196. X   char *s = *sp;
  1197. X   double num = atof(s);
  1198. X
  1199. X   while (isdigit(*s) || *s == '-' || *s == '.')
  1200. X      s++;
  1201. X   if (*sp == s) argerror();
  1202. X   *sp = s;
  1203. X   return (num);
  1204. X}
  1205. X
  1206. Xdouble parsedimen(sp)
  1207. X     char **sp;
  1208. X{
  1209. X   double num = parsedouble(sp);
  1210. X   char *s = *sp;
  1211. X
  1212. X   if (strncmp(s, "pt", 2) == 0) {
  1213. X      s += 2;
  1214. X   } else if (strncmp(s, "in", 2) == 0) {
  1215. X      num *= 72;
  1216. X      s += 2;
  1217. X   } else if (strncmp(s, "cm", 2) == 0) {
  1218. X      num *= 28.346456692913385211;
  1219. X      s += 2;
  1220. X   } else if (strncmp(s, "mm", 2) == 0) {
  1221. X      num *= 2.8346456692913385211;
  1222. X      s += 2;
  1223. X   } else if (*s == 'w') {
  1224. X      if (width < 0) {
  1225. X     fprintf(stderr, "%s: width not initialised\n", prog);
  1226. X     fflush(stderr);
  1227. X     exit(1);
  1228. X      }
  1229. X      num *= width;
  1230. X      s++;
  1231. X   } else if (*s == 'h') {
  1232. X      if (height < 0) {
  1233. X     fprintf(stderr, "%s: height not initialised\n", prog);
  1234. X     fflush(stderr);
  1235. X     exit(1);
  1236. X      }
  1237. X      num *= height;
  1238. X      s++;
  1239. X   }
  1240. X   *sp = s;
  1241. X   return (num);
  1242. X}
  1243. X
  1244. Xdouble singledimen(str)
  1245. X     char *str;
  1246. X{
  1247. X   double num = parsedimen(&str);
  1248. X   if (*str) usage();
  1249. X   return (num);
  1250. X}
  1251. X
  1252. Xvoid pstops(modulo, pps, nobind, specs, draw)
  1253. X     int modulo, pps, nobind;
  1254. X     double draw;
  1255. X     struct pagespec *specs;
  1256. X{
  1257. X   int thispg, maxpage;
  1258. X   int pageindex = 0;
  1259. X
  1260. X   scanpages();
  1261. X
  1262. X   maxpage = ((pages+modulo-1)/modulo)*modulo;
  1263. X
  1264. X   /* rearrange pages: doesn't cope properly with loaded definitions */
  1265. X   writeheader((maxpage/modulo)*pps);
  1266. X   writestring("%%BeginProcSet: pstops");
  1267. X   if (width > 0 && height > 0)
  1268. X      writestring("-clip");
  1269. X   if (nobind)
  1270. X      writestring("-nobind");
  1271. X#ifdef SHOWPAGE_LOAD
  1272. X   writestring("-spload");
  1273. X#endif
  1274. X   writestring(" 1 0\n");
  1275. X#ifndef SHOWPAGE_LOAD
  1276. X   writestring("[/showpage/erasepage/copypage]{dup where{pop dup load\n");
  1277. X   writestring(" type/operatortype eq{1 array cvx dup 0 3 index cvx put\n");
  1278. X   writestring(" bind def}{pop}ifelse}{pop}ifelse}forall\n");
  1279. X#else
  1280. X   writestring("[/showpage/copypage/erasepage]{dup 10 string cvs dup\n");
  1281. X   writestring(" length 6 add string dup 0 (pstops) putinterval dup\n");
  1282. X   writestring(" 6 4 -1 roll putinterval 2 copy cvn dup where\n");
  1283. X   writestring(" {pop pop pop}{exch load def}ifelse cvx cvn 1 array cvx\n");
  1284. X   writestring(" dup 0 4 -1 roll put def}forall\n");
  1285. X#endif
  1286. X   writestring("[/letter/legal/executivepage/a4/a4small/b5/com10envelope\n");
  1287. X   writestring(" /monarchenvelope/c5envelope/dlenvelope/lettersmall/note\n");
  1288. X   writestring(" /folio/quarto/a5]{dup where{dup wcheck{exch{}put}\n");
  1289. X   writestring(" {pop{}def}ifelse}{pop}ifelse}forall\n");
  1290. X   writestring("/lcvx{dup load dup type dup/operatortype eq{pop exch pop}\n");
  1291. X   writestring(" {/arraytype eq{dup xcheck{exch pop aload pop}\n");
  1292. X   writestring(" {pop cvx}ifelse}{pop cvx}ifelse}ifelse}bind def\n");
  1293. X   writestring("/pstopsmatrix matrix currentmatrix def\n");
  1294. X   writestring("/pstopsxform matrix def\n");
  1295. X   writestring("/defaultmatrix{pstopsmatrix exch pstopsxform exch concatmatrix}bind def\n");
  1296. X   writestring("/initmatrix{matrix defaultmatrix setmatrix}bind def\n");
  1297. X   writestring("/pathtoproc{[{currentpoint}stopped{$error/newerror false\n");
  1298. X   writestring(" put{newpath}}{/newpath cvx 3 1 roll/moveto cvx 4 array\n");
  1299. X   writestring(" astore cvx}ifelse]{[/newpath cvx{/moveto cvx}{/lineto cvx}\n");
  1300. X   writestring(" {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}\n");
  1301. X   writestring(" stopped{$error/errorname get/invalidaccess eq{cleartomark\n");
  1302. X   writestring(" $error/newerror false put cvx exec}{stop}ifelse}if}def\n");
  1303. X   if (width > 0 && height > 0) {
  1304. X      char buffer[BUFSIZ];
  1305. X      writestring("/initclip[/matrix lcvx/currentmatrix lcvx/pstopsmatrix cvx/setmatrix lcvx\n");
  1306. X      writestring(" /pathtoproc lcvx/initclip lcvx/newpath lcvx\n");
  1307. X      writestring(" 0 0 /moveto lcvx");
  1308. X      sprintf(buffer,
  1309. X          " %lf 0/rlineto lcvx\n 0 %lf/rlineto lcvx -%lf 0/rlineto lcvx\n",
  1310. X          width, height, width);
  1311. X      writestring(buffer);
  1312. X      writestring(" /closepath lcvx/clip lcvx\n");
  1313. X      writestring(" /newpath lcvx/exec lcvx/setmatrix lcvx]cvx def\n");
  1314. X   }
  1315. X   writestring("/initgraphics{initmatrix newpath initclip 1 setlinewidth\n");
  1316. X   writestring(" 0 setlinecap 0 setlinejoin []0 setdash 0 setgray\n");
  1317. X   writestring(" 10 setmiterlimit}bind def\n");
  1318. X   if (nobind) /* desperation measures */
  1319. X      writestring("/bind{}def\n");
  1320. X   writestring("%%EndProcSet\n");
  1321. X   /* save transformation from original to current matrix */
  1322. X   writeprolog("/pstopsxform pstopsmatrix matrix currentmatrix matrix invertmatrix matrix concatmatrix matrix invertmatrix store\n");
  1323. X   for (thispg = 0; thispg < maxpage; thispg += modulo) {
  1324. X      int add_last = 0;
  1325. X      struct pagespec *ps;
  1326. X      for (ps = specs; ps != NULL; ps = ps->next) {
  1327. X     int actualpg;
  1328. X     int add_next = ((ps->flags & ADD_NEXT) != 0);
  1329. X     if (ps->reversed)
  1330. X        actualpg = maxpage-thispg-modulo+ps->pageno;
  1331. X     else
  1332. X        actualpg = thispg+ps->pageno;
  1333. X     if (actualpg < pages)
  1334. X        seekpage(actualpg);
  1335. X     if (!add_last) {
  1336. X        writepageheader("pstops", ++pageindex);
  1337. X     }
  1338. X     writestring("/pstopssaved save def\n");
  1339. X     if (ps->flags & GSAVE) {
  1340. X        char buffer[BUFSIZ];
  1341. X        writestring("pstopsmatrix setmatrix\n");
  1342. X        if (ps->flags & OFFSET) {
  1343. X           sprintf(buffer, "%lf %lf translate\n", ps->xoff, ps->yoff);
  1344. X           writestring(buffer);
  1345. X        }
  1346. X        if (ps->flags & ROTATE) {
  1347. X           sprintf(buffer, "%d rotate\n", ps->rotate);
  1348. X           writestring(buffer);
  1349. X        }
  1350. X        if (ps->flags & SCALE) {
  1351. X           sprintf(buffer, "%lf dup scale\n", ps->scale);
  1352. X           writestring(buffer);
  1353. X        }
  1354. X        if (width > 0 && height > 0) {
  1355. X           writestring("/pstopsmatrix matrix currentmatrix def\n");
  1356. X           writestring("initclip\n");
  1357. X           if (draw > 0) {
  1358. X          sprintf(buffer, "gsave clippath 0 setgray %lf setlinewidth stroke grestore\n", draw);
  1359. X          writestring(buffer);
  1360. X           }
  1361. X        }
  1362. X        writestring("pstopsxform concat\n");
  1363. X     }
  1364. X     if (add_next) {
  1365. X#ifndef SHOWPAGE_LOAD
  1366. X        writestring("/showpage{}def/copypage{}def/erasepage{}def\n");
  1367. X#else
  1368. X        writestring("/pstopsshowpage{}def/pstopscopypage{}def/pstopserasepage{}def\n");
  1369. X#endif
  1370. X     }
  1371. X     if (actualpg < pages)
  1372. X        writepagebody(actualpg);
  1373. X     else
  1374. X        writestring("showpage\n");
  1375. X     writestring("pstopssaved restore\n");
  1376. X     add_last = add_next;
  1377. X      }
  1378. X   }
  1379. X   writetrailer();
  1380. X}
  1381. END_OF_psspec.c
  1382. if test 7082 -ne `wc -c <psspec.c`; then
  1383.     echo shar: \"psspec.c\" unpacked with wrong size!
  1384. fi
  1385. # end of overwriting check
  1386. fi
  1387. if test -f pstops.c -a "${1}" != "-c" ; then 
  1388.   echo shar: Will not over-write existing file \"pstops.c\"
  1389. else
  1390. echo shar: Extracting \"pstops.c\" \(4388 characters\)
  1391. sed "s/^X//" >pstops.c <<'END_OF_pstops.c'
  1392. X/* pstops.c
  1393. X * AJCD 27/1/91
  1394. X * rearrange pages in conforming PS file for printing in signatures
  1395. X *
  1396. X * Usage:
  1397. X *       pstops [-q] [-b] [-d] [-w<dim>] [-h<dim>] [-ppaper] <pagespecs> [infile [outfile]]
  1398. X */
  1399. X
  1400. X#include "psutil.h"
  1401. X#include "psspec.h"
  1402. X#include "patchlevel.h"
  1403. X
  1404. Xvoid usage()
  1405. X{
  1406. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  1407. X   fprintf(stderr, "Usage: %s [-q] [-b] [-wwidth] [-hheight] [-dlwidth] [-ppaper] <pagespecs> [infile [outfile]]\n",
  1408. X       prog);
  1409. X   fflush(stderr);
  1410. X   exit(1);
  1411. X}
  1412. X
  1413. Xvoid argerror()
  1414. X{
  1415. X   fprintf(stderr, "%s: page specification error:\n", prog);
  1416. X   fprintf(stderr, "  <pagespecs> = [modulo:]<spec>\n");
  1417. X   fprintf(stderr, "  <spec>      = [-]pageno[@scale][L|R|U][(xoff,yoff)][,spec|+spec]\n");
  1418. X   fprintf(stderr, "                modulo>=1, 0<=pageno<modulo\n");
  1419. X   fflush(stderr);
  1420. X   exit(1);
  1421. X}
  1422. X
  1423. Xstatic int modulo = 1;
  1424. Xstatic int pagesperspec = 1;
  1425. X
  1426. Xstruct pagespec *parsespecs(str)
  1427. X     char *str;
  1428. X{
  1429. X   char *t;
  1430. X   struct pagespec *head, *tail;
  1431. X   int other = 0;
  1432. X   int num = -1;
  1433. X
  1434. X   head = tail = newspec();
  1435. X   while (*str) {
  1436. X      if (isdigit(*str)) {
  1437. X     num = parseint(&str);
  1438. X      } else {
  1439. X     switch (*str++) {
  1440. X     case ':':
  1441. X        if (other || head != tail || num < 1) argerror();
  1442. X        modulo = num;
  1443. X        num = -1;
  1444. X        break;
  1445. X     case '-':
  1446. X        tail->reversed = !tail->reversed;
  1447. X        break;
  1448. X     case '@':
  1449. X        if (num < 0) argerror();
  1450. X        tail->scale *= parsedouble(&str);
  1451. X        tail->flags |= SCALE;
  1452. X        break;
  1453. X     case 'l': case 'L':
  1454. X        tail->rotate += 90;
  1455. X        tail->flags |= ROTATE;
  1456. X        break;
  1457. X     case 'r': case 'R':
  1458. X        tail->rotate -= 90;
  1459. X        tail->flags |= ROTATE;
  1460. X        break;
  1461. X     case 'u': case 'U':
  1462. X        tail->rotate += 180;
  1463. X        tail->flags |= ROTATE;
  1464. X        break;
  1465. X     case '(':
  1466. X        tail->xoff += parsedimen(&str);
  1467. X        if (*str++ != ',') argerror();
  1468. X        tail->yoff += parsedimen(&str);
  1469. X        if (*str++ != ')') argerror();
  1470. X        tail->flags |= OFFSET;
  1471. X        break;
  1472. X     case '+':
  1473. X        tail->flags |= ADD_NEXT;
  1474. X     case ',':
  1475. X        if (num < 0 || num >= modulo) argerror();
  1476. X        if ((tail->flags & ADD_NEXT) == 0)
  1477. X           pagesperspec++;
  1478. X        tail->pageno = num;
  1479. X        tail->next = newspec();
  1480. X        tail = tail->next;
  1481. X        num = -1;
  1482. X        break;
  1483. X     default:
  1484. X        argerror();
  1485. X     }
  1486. X     other = 1;
  1487. X      }
  1488. X   }
  1489. X   if (num >= modulo)
  1490. X      argerror();
  1491. X   else if (num >= 0)
  1492. X      tail->pageno = num;
  1493. X   return (head);
  1494. X}
  1495. X
  1496. Xmain(argc, argv)
  1497. X     int argc;
  1498. X     char *argv[];
  1499. X{
  1500. X   struct pagespec *specs = NULL;
  1501. X   int nobinding = 0;
  1502. X   double draw = 0;
  1503. X   struct papersize *paper;
  1504. X
  1505. X#ifdef PAPER
  1506. X   if (paper = findpaper(PAPER)) {
  1507. X      width = (double)paper->width;
  1508. X      height = (double)paper->height;
  1509. X   }
  1510. X#endif
  1511. X
  1512. X   infile = stdin;
  1513. X   outfile = stdout;
  1514. X   verbose = 1;
  1515. X   for (prog = *argv++; --argc; argv++) {
  1516. X      if (argv[0][0] == '-') {
  1517. X     switch (argv[0][1]) {
  1518. X     case 'q':    /* quiet */
  1519. X        verbose = 0;
  1520. X        break;
  1521. X     case 'd':    /* draw borders */
  1522. X        if (argv[0][2])
  1523. X           draw = singledimen(*argv+2);
  1524. X        else
  1525. X           draw = 1;
  1526. X        break;
  1527. X     case 'b':    /* no bind operator */
  1528. X        nobinding = 1;
  1529. X        break;
  1530. X     case 'w':    /* page width */
  1531. X        width = singledimen(*argv+2);
  1532. X        break;
  1533. X     case 'h':    /* page height */
  1534. X        height = singledimen(*argv+2);
  1535. X        break;
  1536. X     case 'p':    /* paper type */
  1537. X        if (paper = findpaper(*argv+2)) {
  1538. X           width = (double)paper->width;
  1539. X           height = (double)paper->height;
  1540. X        } else {
  1541. X           fprintf(stderr, "%s: paper size '%s' not recognised\n",
  1542. X               prog, *argv+2);
  1543. X           fflush(stderr);
  1544. X           exit(1);
  1545. X        }
  1546. X        break;
  1547. X     case 'v':    /* version */
  1548. X        usage();
  1549. X     default:
  1550. X        if (specs == NULL)
  1551. X           specs = parsespecs(*argv);
  1552. X        else
  1553. X           usage();
  1554. X     }
  1555. X      } else if (specs == NULL)
  1556. X     specs = parsespecs(*argv);
  1557. X      else if (infile == stdin) {
  1558. X     if ((infile = fopen(*argv, "r")) == NULL) {
  1559. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  1560. X        fflush(stderr);
  1561. X        exit(1);
  1562. X     }
  1563. X      } else if (outfile == stdout) {
  1564. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  1565. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  1566. X        fflush(stderr);
  1567. X        exit(1);
  1568. X     }
  1569. X      } else usage();
  1570. X   }
  1571. X   if (specs == NULL)
  1572. X      usage();
  1573. X   if ((infile=seekable(infile))==NULL) {
  1574. X      fprintf(stderr, "%s: can't seek input\n", prog);
  1575. X      fflush(stderr);
  1576. X      exit(1);
  1577. X   }
  1578. X
  1579. X   pstops(modulo, pagesperspec, nobinding, specs, draw);
  1580. X
  1581. X   exit(0);
  1582. X}
  1583. END_OF_pstops.c
  1584. if test 4388 -ne `wc -c <pstops.c`; then
  1585.     echo shar: \"pstops.c\" unpacked with wrong size!
  1586. fi
  1587. # end of overwriting check
  1588. fi
  1589. if test -f psutil.c -a "${1}" != "-c" ; then 
  1590.   echo shar: Will not over-write existing file \"psutil.c\"
  1591. else
  1592. echo shar: Extracting \"psutil.c\" \(8195 characters\)
  1593. sed "s/^X//" >psutil.c <<'END_OF_psutil.c'
  1594. X/* psutil.c
  1595. X * AJCD 29/1/91
  1596. X * utilities for PS programs
  1597. X */
  1598. X
  1599. X/*
  1600. X *  AJCD 6/4/93
  1601. X *    Changed to using ftell() and fseek() only (no length calculations)
  1602. X *  Hunter Goatley    31-MAY-1993 23:33
  1603. X *    Fixed VMS support.
  1604. X *  Hunter Goatley     2-MAR-1993 14:41
  1605. X *    Added VMS support.
  1606. X */
  1607. X#define LOCAL
  1608. X#include "psutil.h"
  1609. X#include "patchlevel.h"
  1610. X
  1611. X#ifdef VMS
  1612. X#include <file.h>
  1613. X#else
  1614. X#include <fcntl.h>
  1615. X#endif
  1616. X#include <string.h>
  1617. X
  1618. X#define iscomment(x,y) (strncmp(x,y,strlen(y)) == 0)
  1619. X
  1620. Xextern void argerror();
  1621. X
  1622. Xstatic char buffer[BUFSIZ];
  1623. Xstatic long bytes = 0;
  1624. Xstatic long pagescmt = 0;
  1625. Xstatic long headerpos = 0;
  1626. Xstatic long endsetup = 0;
  1627. Xstatic int outputpage = 0;
  1628. Xstatic int maxpages = 100;
  1629. Xstatic long *pageptr;
  1630. X
  1631. X/* list of paper sizes supported */
  1632. Xstatic struct papersize papersizes[] = {
  1633. X   { "a3", 842, 1191 },        /* 29.7cm * 42cm */
  1634. X   { "a4", 595, 842 },        /* 21cm * 29.7cm */
  1635. X   { "a5", 421, 595 },        /* 14.85cm * 21cm */
  1636. X   { "b5", 516, 729 },        /* 18.2cm * 25.72cm */
  1637. X   { "A3", 842, 1191 },        /* 29.7cm * 42cm */
  1638. X   { "A4", 595, 842 },        /* 21cm * 29.7cm */
  1639. X   { "A5", 421, 595 },        /* 14.85cm * 21cm */
  1640. X   { "B5", 516, 729 },        /* 18.2cm * 25.72cm */
  1641. X   { "letter", 612, 792 },    /* 8.5in * 11in */
  1642. X   { "legal", 612, 1008 },    /* 8.5in * 14in */
  1643. X   { "ledger", 1224, 792 },    /* 17in * 11in */
  1644. X   { "tabloid", 792, 1224 },    /* 11in * 17in */
  1645. X   { "statement", 396, 612 },    /* 5.5in * 8.5in */
  1646. X   { "executive", 540, 720 },    /* 7.6in * 10in */
  1647. X   { "folio", 612, 936 },    /* 8.5in * 13in */
  1648. X   { "quarto", 610, 780 },    /* 8.5in * 10.83in */
  1649. X   { "10x14", 720, 1008 },    /* 10in * 14in */
  1650. X   { NULL, 0, 0 }
  1651. X};
  1652. X
  1653. X/* return pointer to paper size struct or NULL */
  1654. Xstruct papersize* findpaper(name)
  1655. X     char *name;
  1656. X{
  1657. X   struct papersize *pp;
  1658. X   for (pp = papersizes; pp->name; pp++) {
  1659. X      if (strcmp(pp->name, name) == 0) {
  1660. X     return pp;
  1661. X      }
  1662. X   }
  1663. X   return NULL;
  1664. X}
  1665. X
  1666. X/* make a file seekable; trick stolen from Chris Torek's libdvi */
  1667. XFILE *seekable(fp)
  1668. X     FILE *fp;
  1669. X{
  1670. X   int fd, tf, n, w;
  1671. X   char *tmpdir, *p;
  1672. X
  1673. X   fd = fileno(fp);
  1674. X   if (lseek(fd, 0L, 1) >= 0 && !isatty(fd))
  1675. X      return (fp);
  1676. X
  1677. X#ifdef MSDOS
  1678. X   fprintf(stderr, "%s: input is not seekable\n", prog);
  1679. X   fflush(stderr);
  1680. X   exit(1);
  1681. X#else
  1682. X   if ((tmpdir = getenv("TMPDIR")) == NULL)
  1683. X      tmpdir = TMPDIR;
  1684. X   (void) sprintf(buffer, "%s/#%d", tmpdir, getpid());
  1685. X   if ((tf = open(buffer, O_RDWR | O_CREAT | O_EXCL, 0666)) == -1)
  1686. X      return (NULL);
  1687. X   (void) unlink(buffer);
  1688. X
  1689. X   while ((n = read(fd, p = buffer, BUFSIZ)) > 0) {
  1690. X      do {
  1691. X     if ((w = write(tf, p, n)) < 0) {
  1692. X        (void) close(tf);
  1693. X        (void) fclose(fp);
  1694. X        return (NULL);
  1695. X     }
  1696. X     p += w;
  1697. X      } while ((n -= w) > 0);
  1698. X   }
  1699. X   if (n < 0) {
  1700. X      (void) close(tf);
  1701. X      (void) fclose(fp);
  1702. X      return (NULL);
  1703. X   }
  1704. X
  1705. X   /* discard the input file, and rewind and open the temporary */
  1706. X   (void) fclose(fp);
  1707. X   (void) lseek(tf, 0L, 0);
  1708. X   if ((fp = fdopen(tf, "r")) == NULL) {
  1709. X      (void) close(tf);
  1710. X   }
  1711. X   return (fp);
  1712. X#endif
  1713. X}
  1714. X
  1715. X/* copy input file from current position upto new position to output file */
  1716. Xstatic int fcopy(upto)
  1717. X     long upto;
  1718. X{
  1719. X   long here = ftell(infile);
  1720. X   while (here < upto) {
  1721. X      if ((fgets(buffer, BUFSIZ, infile) == NULL) ||
  1722. X      (fputs(buffer, outfile) == EOF))
  1723. X     return(0);
  1724. X      here = ftell(infile);
  1725. X      bytes += strlen(buffer);
  1726. X   }
  1727. X   return (1);
  1728. X}
  1729. X
  1730. X/* build array of pointers to start/end of pages */
  1731. Xvoid scanpages()
  1732. X{
  1733. X   register char *comment = buffer+2;
  1734. X   register int nesting = 0;
  1735. X   register long int record;
  1736. X
  1737. X   if ((pageptr = (long *)malloc(sizeof(long)*maxpages)) == NULL) {
  1738. X      fprintf(stderr, "%s: out of memory\n", prog);
  1739. X      fflush(stderr);
  1740. X      exit(1);
  1741. X   }
  1742. X   pages = 0;
  1743. X   fseek(infile, 0L, 0);
  1744. X   while (record = ftell(infile), fgets(buffer, BUFSIZ, infile) != NULL)
  1745. X      if (*buffer == '%') {
  1746. X     if (buffer[1] == '%') {
  1747. X        if (nesting == 0 && iscomment(comment, "Page:")) {
  1748. X           if (pages >= maxpages-1) {
  1749. X          maxpages *= 2;
  1750. X          if ((pageptr = (long *)realloc((char *)pageptr,
  1751. X                         sizeof(long)*maxpages)) == NULL) {
  1752. X             fprintf(stderr, "%s: out of memory\n", prog);
  1753. X             fflush(stderr);
  1754. X             exit(1);
  1755. X          }
  1756. X           }
  1757. X           pageptr[pages++] = record;
  1758. X        } else if (headerpos == 0 && iscomment(comment, "Pages:"))
  1759. X           pagescmt = record;
  1760. X        else if (headerpos == 0 && iscomment(comment, "EndComments"))
  1761. X           headerpos = ftell(infile);
  1762. X        else if (iscomment(comment, "BeginDocument") ||
  1763. X             iscomment(comment, "BeginBinary") ||
  1764. X             iscomment(comment, "BeginFile"))
  1765. X           nesting++;
  1766. X        else if (iscomment(comment, "EndDocument") ||
  1767. X             iscomment(comment, "EndBinary") ||
  1768. X             iscomment(comment, "EndFile"))
  1769. X           nesting--;
  1770. X        else if (nesting == 0 && iscomment(comment, "EndSetup"))
  1771. X           endsetup = record;
  1772. X        else if (nesting == 0 && iscomment(comment, "Trailer")) {
  1773. X           fseek(infile, record, 0);
  1774. X           break;
  1775. X        }
  1776. X     } else if (headerpos == 0 && buffer[1] != '!')
  1777. X        headerpos = record;
  1778. X      } else if (headerpos == 0)
  1779. X     headerpos = record;
  1780. X   pageptr[pages] = ftell(infile);
  1781. X   if (endsetup == 0)
  1782. X      endsetup = pageptr[0];
  1783. X}
  1784. X
  1785. X/* seek a particular page */
  1786. Xvoid seekpage(p)
  1787. X     int p;
  1788. X{
  1789. X   fseek(infile, pageptr[p], 0);
  1790. X   if (fgets(buffer, BUFSIZ, infile) != NULL &&
  1791. X       iscomment(buffer, "%%Page:")) {
  1792. X      char *start, *end;
  1793. X      for (start = buffer+7; isspace(*start); start++);
  1794. X      if (*start == '(') {
  1795. X     int paren = 1;
  1796. X     for (end = start+1; paren > 0; end++)
  1797. X        switch (*end) {
  1798. X        case '\0':
  1799. X           fprintf(stderr,
  1800. X               "%s: Bad page label while seeking page %d\n", prog, p);
  1801. X           fflush(stderr);
  1802. X           exit(1);
  1803. X        case '(':
  1804. X           paren++;
  1805. X           break;
  1806. X        case ')':
  1807. X           paren--;
  1808. X           break;
  1809. X        }
  1810. X      } else
  1811. X     for (end = start; !isspace(*end); end++);
  1812. X      strncpy(pagelabel, start, end-start);
  1813. X      pageno = atoi(end);
  1814. X   } else {
  1815. X      fprintf(stderr, "%s: I/O error seeking page %d\n", prog, p);
  1816. X      fflush(stderr);
  1817. X      exit(1);
  1818. X   }
  1819. X}
  1820. X
  1821. X/* Output routines. These all update the global variable bytes with the number
  1822. X * of bytes written */
  1823. Xvoid writestring(s)
  1824. X     char *s;
  1825. X{
  1826. X   fputs(s, outfile);
  1827. X   bytes += strlen(s);
  1828. X}
  1829. X
  1830. Xvoid writepageheader(label, page)
  1831. X     char *label;
  1832. X     int page;
  1833. X{
  1834. X   if (verbose) {
  1835. X      sprintf(buffer, "[%d] ", page);
  1836. X      message(buffer);
  1837. X   }
  1838. X   sprintf(buffer, "%%%%Page: %s %d\n", label, ++outputpage);
  1839. X   writestring(buffer);
  1840. X}
  1841. X
  1842. Xvoid writepagebody(p)
  1843. X     int p;
  1844. X{
  1845. X   if (!fcopy(pageptr[p+1])) {
  1846. X      fprintf(stderr, "%s: I/O error writing page %d\n", prog, outputpage);
  1847. X      fflush(stderr);
  1848. X      exit(1);
  1849. X   }
  1850. X}
  1851. X
  1852. Xvoid writepage(p)
  1853. X     int p;
  1854. X{
  1855. X   seekpage(p);
  1856. X   writepageheader(pagelabel, p+1);
  1857. X   writepagebody(p);
  1858. X}
  1859. X
  1860. Xvoid writeheader(p)
  1861. X     int p;
  1862. X{
  1863. X   fseek(infile, 0L, 0);
  1864. X   if (pagescmt) {
  1865. X      if (!fcopy(pagescmt) || fgets(buffer, BUFSIZ, infile) == NULL) {
  1866. X     fprintf(stderr, "%s: I/O error in header\n", prog);
  1867. X     fflush(stderr);
  1868. X     exit(1);
  1869. X      }
  1870. X      sprintf(buffer, "%%%%Pages: %d 0\n", p);
  1871. X      writestring(buffer);
  1872. X   }
  1873. X   if (!fcopy(headerpos)) {
  1874. X      fprintf(stderr, "%s: I/O error in header\n", prog);
  1875. X      fflush(stderr);
  1876. X      exit(1);
  1877. X   }
  1878. X}
  1879. X
  1880. X
  1881. Xvoid writeprolog(setup)
  1882. X     char *setup;
  1883. X{
  1884. X   if (!fcopy(endsetup)) {
  1885. X      fprintf(stderr, "%s: I/O error in prologue\n", prog);
  1886. X      fflush(stderr);
  1887. X      exit(1);
  1888. X   }
  1889. X   writestring(setup);
  1890. X   if (!fcopy(pageptr[0])) {
  1891. X      fprintf(stderr, "%s: I/O error in prologue\n", prog);
  1892. X      fflush(stderr);
  1893. X      exit(1);
  1894. X   }
  1895. X}
  1896. X
  1897. X/* write trailer */
  1898. Xvoid writetrailer()
  1899. X{
  1900. X   fseek(infile, pageptr[pages], 0);
  1901. X   while (fgets(buffer, BUFSIZ, infile) != NULL) {
  1902. X      writestring(buffer);
  1903. X   }
  1904. X   if (verbose) {
  1905. X      sprintf(buffer, "Wrote %d pages, %ld bytes\n", outputpage, bytes);
  1906. X      message(buffer);
  1907. X   }
  1908. X}
  1909. X
  1910. X/* write message to stderr */
  1911. Xvoid message(s)
  1912. X     char *s;
  1913. X{
  1914. X   static int pos = 0;
  1915. X   char *nl = strchr(s, '\n');
  1916. X   int len = nl ? (nl-s) : strlen(s);
  1917. X
  1918. X   if (pos+len > 79 && (pos > 79 || len < 80)) {
  1919. X      fputc('\n', stderr);
  1920. X      pos = 0;
  1921. X   }
  1922. X   fputs(s, stderr);
  1923. X   fflush(stderr);
  1924. X   pos += len;
  1925. X}
  1926. X
  1927. X
  1928. Xvoid writeemptypage()
  1929. X{
  1930. X   if (verbose)
  1931. X      message("[*] ");
  1932. X   sprintf(buffer, "%%%%Page: * %d\nshowpage\n", ++outputpage);
  1933. X   writestring(buffer);
  1934. X}
  1935. X
  1936. END_OF_psutil.c
  1937. if test 8195 -ne `wc -c <psutil.c`; then
  1938.     echo shar: \"psutil.c\" unpacked with wrong size!
  1939. fi
  1940. # end of overwriting check
  1941. fi
  1942. echo shar: End of archive 2 \(of 4\).
  1943. cp /dev/null ark2isdone
  1944. MISSING=""
  1945. for I in 1 2 3 4 ; do
  1946.     if test ! -f ark${I}isdone ; then
  1947.     MISSING="${MISSING} ${I}"
  1948.     fi
  1949. done
  1950. if test "${MISSING}" = "" ; then
  1951.     echo You have unpacked all 4 archives.
  1952.     rm -f ark[1-9]isdone
  1953. else
  1954.     echo You still need to unpack the following archives:
  1955.     echo "        " ${MISSING}
  1956. fi
  1957. ##  End of shell archive.
  1958. exit 0
  1959.  
  1960. exit 0 # Just in case...
  1961.