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