PageRenderTime 42ms CodeModel.GetById 1ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/utils/pfbtops/pfbtops.c

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