pfbtops.c revision 75584
178556Sobrien/* This translates ps fonts in .pfb format to ASCII ps files. */ 278556Sobrien 378556Sobrien#include <stdio.h> 478556Sobrien#include <getopt.h> 578556Sobrien#include <limits.h> 678556Sobrien 778556Sobrien#include "nonposix.h" 878556Sobrien 978556Sobrien/* Binary bytes per output line. */ 10146293Sobrien#define BYTES_PER_LINE (64/2) 1178556Sobrien#define HEX_DIGITS "0123456789abcdef" 1278556Sobrien 1378556Sobrienstatic char *program_name; 1478556Sobrien 1578556Sobrienstatic void error(s) 1678556Sobrien char *s; 1778556Sobrien{ 1878556Sobrien fprintf(stderr, "%s: %s\n", program_name, s); 1978556Sobrien exit(2); 2078556Sobrien} 2178556Sobrien 2278556Sobrienstatic void usage(FILE *stream) 2378556Sobrien{ 2478556Sobrien fprintf(stream, "usage: %s [-v] [pfb_file]\n", program_name); 2578556Sobrien} 2678556Sobrien 2778556Sobrienint main(argc, argv) 2878556Sobrien int argc; 2978556Sobrien char **argv; 3078556Sobrien{ 3178556Sobrien int opt; 3278556Sobrien extern int optind; 3378556Sobrien static const struct option long_options[] = { 3478556Sobrien { "help", no_argument, 0, CHAR_MAX + 1 }, 3578556Sobrien { "version", no_argument, 0, 'v' }, 3678556Sobrien { NULL, 0, 0, 0 } 3778556Sobrien }; 3878556Sobrien 3978556Sobrien program_name = argv[0]; 4078556Sobrien 4178556Sobrien while ((opt = getopt_long(argc, argv, "v", long_options, NULL)) != EOF) { 4278556Sobrien switch (opt) { 4378556Sobrien case 'v': 44146293Sobrien { 4578556Sobrien extern char *Version_string; 4678556Sobrien printf("GNU pfbtops (groff) version %s\n", Version_string); 4778556Sobrien exit(0); 4878556Sobrien break; 4978556Sobrien } 5078556Sobrien case CHAR_MAX + 1: // --help 5178556Sobrien usage(stdout); 5278556Sobrien exit(0); 5378556Sobrien break; 5478556Sobrien case '?': 5578556Sobrien usage(stderr); 5678556Sobrien exit(1); 5778556Sobrien break; 5878556Sobrien } 5978556Sobrien } 6078556Sobrien 6178556Sobrien if (argc - optind > 1) { 6278556Sobrien usage(stderr); 6378556Sobrien exit(1); 6478556Sobrien } 6578556Sobrien if (argc > optind && !freopen(argv[optind], "r", stdin)) 6678556Sobrien { 6778556Sobrien perror(argv[optind]); 6878556Sobrien exit(1); 6978556Sobrien } 7078556Sobrien#ifdef SET_BINARY 7178556Sobrien SET_BINARY(fileno(stdin)); 7278556Sobrien#endif 7378556Sobrien for (;;) 7478556Sobrien { 7578556Sobrien int type, c, i; 7678556Sobrien long n; 7778556Sobrien 7878556Sobrien c = getchar(); 7978556Sobrien if (c != 0x80) 8078556Sobrien error("first byte of packet not 0x80"); 8178556Sobrien type = getchar(); 8278556Sobrien if (type == 3) 8378556Sobrien break; 8478556Sobrien if (type != 1 && type != 2) 8578556Sobrien error("bad packet type"); 8678556Sobrien n = 0; 8778556Sobrien for (i = 0; i < 4; i++) 8878556Sobrien { 8978556Sobrien c = getchar(); 9078556Sobrien if (c == EOF) 9178556Sobrien error("end of file in packet header"); 9278556Sobrien n |= (long)c << (i << 3); 9378556Sobrien } 9478556Sobrien if (n < 0) 9578556Sobrien error("negative packet length"); 9678556Sobrien if (type == 1) 9778556Sobrien { 9878556Sobrien while (--n >= 0) 9978556Sobrien { 10078556Sobrien c = getchar(); 10178556Sobrien if (c == EOF) 102147666Ssimon error("end of file in text packet"); 10378556Sobrien if (c == '\r') 10478556Sobrien c = '\n'; 10578556Sobrien putchar(c); 10678556Sobrien } 10778556Sobrien if (c != '\n') 10878556Sobrien putchar('\n'); 10978556Sobrien } 11078556Sobrien else 11178556Sobrien { 11278556Sobrien int count = 0; 11378556Sobrien while (--n >= 0) 11478556Sobrien { 11578556Sobrien c = getchar(); 11678556Sobrien if (c == EOF) 11790067Ssobomax error("end of file in binary packet"); 11878556Sobrien if (count >= BYTES_PER_LINE) 11978556Sobrien { 12078556Sobrien putchar('\n'); 12178556Sobrien count = 0; 12278556Sobrien } 12378556Sobrien count++; 12490067Ssobomax putchar(HEX_DIGITS[(c >> 4) & 0xf]); 12590067Ssobomax putchar(HEX_DIGITS[c & 0xf]); 12690067Ssobomax } 12778556Sobrien putchar('\n'); 12878556Sobrien } 12978556Sobrien } 13078556Sobrien exit(0); 13178556Sobrien} 13278556Sobrien