Adapt src/ute-lookbib (src/utils/lookbib)
[s-roff.git] / src / utils / pfbtops / pfbtops.c
blob6d6ab8d652a1f3750829df9b737b5eff8efae4ae
1 /* Copyright (C) 1992, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
2 Written by James Clark (jjc@jclark.com)
4 This file is part of groff.
6 groff is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License along
17 with groff; see the file COPYING. If not, write to the Free Software
18 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20 /* This translates ps fonts in .pfb format to ASCII ps files. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #define __GETOPT_PREFIX groff_
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <limits.h>
32 #include <getopt.h>
34 #include "nonposix.h"
36 /* Binary bytes per output line. */
37 #define BYTES_PER_LINE (64/2)
38 #define MAX_LINE_LENGTH 78
39 #define HEX_DIGITS "0123456789abcdef"
41 extern const char *Version_string;
43 static char *program_name;
45 static void error(const char *s)
47 fprintf(stderr, "%s: %s\n", program_name, s);
48 exit(2);
51 static void usage(FILE *stream)
53 fprintf(stream, "usage: %s [-v] [pfb_file]\n", program_name);
56 static void get_text(int n)
58 int c = 0, c1;
59 int in_string = 0;
60 int is_comment = 0;
61 int count = 0;
63 while (--n >= 0) {
64 c = getchar();
65 if (c == '(' && !is_comment)
66 in_string++;
67 else if (c == ')' && !is_comment)
68 in_string--;
69 else if (c == '%' && !in_string)
70 is_comment = 1;
71 else if (c == '\\' && in_string) {
72 count++;
73 putchar(c);
74 if (n-- == 0)
75 break;
76 c = getchar();
77 /* don't split octal character representations */
78 if (c >= '0' && c <= '7') {
79 count++;
80 putchar(c);
81 if (n-- == 0)
82 break;
83 c = getchar();
84 if (c >= '0' && c <= '7') {
85 count++;
86 putchar(c);
87 if (n-- == 0)
88 break;
89 c = getchar();
90 if (c >= '0' && c <= '7') {
91 count++;
92 putchar(c);
93 if (n-- == 0)
94 break;
95 c = getchar();
100 if (c == EOF)
101 error("end of file in text packet");
102 else if (c == '\r') {
103 if (n-- == 0)
104 break;
105 c1 = getchar();
106 if (c1 != '\n') {
107 ungetc(c1, stdin);
108 n++;
110 c = '\n';
112 if (c == '\n') {
113 count = 0;
114 is_comment = 0;
116 else if (count >= MAX_LINE_LENGTH) {
117 if (in_string > 0) {
118 count = 1;
119 putchar('\\');
120 putchar('\n');
122 else if (is_comment) {
123 count = 2;
124 putchar('\n');
125 putchar('%');
127 else {
128 /* split at the next whitespace character */
129 while (c != ' ' && c != '\t' && c != '\f') {
130 putchar(c);
131 if (n-- == 0)
132 break;
133 c = getchar();
135 count = 0;
136 putchar('\n');
137 continue;
140 count++;
141 putchar(c);
143 if (c != '\n')
144 putchar('\n');
147 static void get_binary(int n)
149 int c;
150 int count = 0;
152 while (--n >= 0) {
153 c = getchar();
154 if (c == EOF)
155 error("end of file in binary packet");
156 if (count >= BYTES_PER_LINE) {
157 putchar('\n');
158 count = 0;
160 count++;
161 putchar(HEX_DIGITS[(c >> 4) & 0xf]);
162 putchar(HEX_DIGITS[c & 0xf]);
164 putchar('\n');
167 int main(int argc, char **argv)
169 int opt;
170 static const struct option long_options[] = {
171 { "help", no_argument, 0, CHAR_MAX + 1 },
172 { "version", no_argument, 0, 'v' },
173 { NULL, 0, 0, 0 }
176 program_name = argv[0];
178 while ((opt = getopt_long(argc, argv, "v", long_options, NULL)) != EOF) {
179 switch (opt) {
180 case 'v':
181 printf("GNU pfbtops (groff) version %s\n", Version_string);
182 exit(0);
183 break;
184 case CHAR_MAX + 1: /* --help */
185 usage(stdout);
186 exit(0);
187 break;
188 case '?':
189 usage(stderr);
190 exit(1);
191 break;
195 if (argc - optind > 1) {
196 usage(stderr);
197 exit(1);
199 if (argc > optind && !freopen(argv[optind], "r", stdin)) {
200 perror(argv[optind]);
201 exit(1);
203 SET_BINARY(fileno(stdin));
204 for (;;) {
205 int type, c, i;
206 long n;
208 c = getchar();
209 if (c != 0x80)
210 error("first byte of packet not 0x80");
211 type = getchar();
212 if (type == 3)
213 break;
214 if (type != 1 && type != 2)
215 error("bad packet type");
216 n = 0;
217 for (i = 0; i < 4; i++) {
218 c = getchar();
219 if (c == EOF)
220 error("end of file in packet header");
221 n |= (long)c << (i << 3);
223 if (n < 0)
224 error("negative packet length");
225 if (type == 1)
226 get_text(n);
227 else
228 get_binary(n);
230 exit(0);