pfbtops.c revision 75584
1/* This translates ps fonts in .pfb format to ASCII ps files. */
2
3#include <stdio.h>
4#include <getopt.h>
5#include <limits.h>
6
7#include "nonposix.h"
8
9/* Binary bytes per output line. */
10#define BYTES_PER_LINE (64/2)
11#define HEX_DIGITS "0123456789abcdef"
12
13static char *program_name;
14
15static void error(s)
16     char *s;
17{
18  fprintf(stderr, "%s: %s\n", program_name, s);
19  exit(2);
20}
21
22static void usage(FILE *stream)
23{
24  fprintf(stream, "usage: %s [-v] [pfb_file]\n", program_name);
25}
26
27int main(argc, argv)
28     int argc;
29     char **argv;
30{
31  int opt;
32  extern int optind;
33  static const struct option long_options[] = {
34    { "help", no_argument, 0, CHAR_MAX + 1 },
35    { "version", no_argument, 0, 'v' },
36    { NULL, 0, 0, 0 }
37  };
38
39  program_name = argv[0];
40
41  while ((opt = getopt_long(argc, argv, "v", long_options, NULL)) != EOF) {
42    switch (opt) {
43    case 'v':
44      {
45	extern char *Version_string;
46	printf("GNU pfbtops (groff) version %s\n", Version_string);
47	exit(0);
48	break;
49      }
50    case CHAR_MAX + 1: // --help
51      usage(stdout);
52      exit(0);
53      break;
54    case '?':
55      usage(stderr);
56      exit(1);
57      break;
58    }
59  }
60
61  if (argc - optind > 1) {
62    usage(stderr);
63    exit(1);
64  }
65  if (argc > optind && !freopen(argv[optind], "r", stdin))
66    {
67      perror(argv[optind]);
68      exit(1);
69    }
70#ifdef SET_BINARY
71  SET_BINARY(fileno(stdin));
72#endif
73  for (;;)
74    {
75      int type, c, i;
76      long n;
77
78      c = getchar();
79      if (c != 0x80)
80	error("first byte of packet not 0x80");
81      type = getchar();
82      if (type == 3)
83	break;
84      if (type != 1 && type != 2)
85	error("bad packet type");
86      n = 0;
87      for (i = 0; i < 4; i++)
88	{
89	  c = getchar();
90	  if (c == EOF)
91	    error("end of file in packet header");
92	  n |= (long)c << (i << 3);
93	}
94      if (n < 0)
95	error("negative packet length");
96      if (type == 1)
97	{
98	  while (--n >= 0)
99	    {
100	      c = getchar();
101	      if (c == EOF)
102		error("end of file in text packet");
103	      if (c == '\r')
104		c = '\n';
105	      putchar(c);
106	    }
107	  if (c != '\n')
108	    putchar('\n');
109	}
110      else
111	{
112	  int count = 0;
113	  while (--n >= 0)
114	    {
115	      c = getchar();
116	      if (c == EOF)
117		error("end of file in binary packet");
118	      if (count >= BYTES_PER_LINE)
119		{
120		  putchar('\n');
121		  count = 0;
122		}
123	      count++;
124	      putchar(HEX_DIGITS[(c >> 4) & 0xf]);
125	      putchar(HEX_DIGITS[c & 0xf]);
126	    }
127	  putchar('\n');
128	}
129    }
130  exit(0);
131}
132