PageRenderTime 81ms CodeModel.GetById 43ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/utils/addftinfo/addftinfo.cpp

https://bitbucket.org/freebsd/freebsd-head/
C++ | 218 lines | 183 code | 14 blank | 21 comment | 60 complexity | 9dae4401307d9cfcce6faaf7cde39057 MD5 | raw file
  1// -*- C++ -*-
  2/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc.
  3     Written by James Clark (jjc@jclark.com)
  4
  5This file is part of groff.
  6
  7groff is free software; you can redistribute it and/or modify it under
  8the terms of the GNU General Public License as published by the Free
  9Software Foundation; either version 2, or (at your option) any later
 10version.
 11
 12groff is distributed in the hope that it will be useful, but WITHOUT ANY
 13WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15for more details.
 16
 17You should have received a copy of the GNU General Public License along
 18with groff; see the file COPYING.  If not, write to the Free Software
 19Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
 20
 21#include "lib.h"
 22
 23#include <ctype.h>
 24#include <assert.h>
 25#include <stdlib.h>
 26#include <errno.h>
 27#include "errarg.h"
 28#include "error.h"
 29#include "stringclass.h"
 30#include "cset.h"
 31#include "guess.h"
 32
 33extern "C" const char *Version_string;
 34
 35static void usage(FILE *stream);
 36static void usage();
 37static void version();
 38static void convert_font(const font_params &, FILE *, FILE *);
 39
 40typedef int font_params::*param_t;
 41
 42static struct {
 43  const char *name;
 44  param_t par;
 45} param_table[] = {
 46  { "x-height", &font_params::x_height },
 47  { "fig-height", &font_params::fig_height },
 48  { "asc-height", &font_params::asc_height },
 49  { "body-height", &font_params::body_height },
 50  { "cap-height", &font_params::cap_height },
 51  { "comma-depth", &font_params::comma_depth },
 52  { "desc-depth", &font_params::desc_depth },
 53  { "body-depth", &font_params::body_depth },
 54};
 55
 56// These are all in thousandths of an em.
 57// These values are correct for PostScript Times Roman.
 58
 59#define DEFAULT_X_HEIGHT 448
 60#define DEFAULT_FIG_HEIGHT 676
 61#define DEFAULT_ASC_HEIGHT 682
 62#define DEFAULT_BODY_HEIGHT 676
 63#define DEFAULT_CAP_HEIGHT 662
 64#define DEFAULT_COMMA_DEPTH 143
 65#define DEFAULT_DESC_DEPTH 217
 66#define DEFAULT_BODY_DEPTH 177
 67
 68int main(int argc, char **argv)
 69{
 70  program_name = argv[0];
 71  int i;
 72  for (i = 1; i < argc; i++) {
 73    if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version"))
 74      version();
 75    if (!strcmp(argv[i],"--help")) {
 76      usage(stdout);
 77      exit(0);
 78    }
 79  }
 80  if (argc < 4)
 81    usage();
 82  int resolution;
 83  if (sscanf(argv[argc-3], "%d", &resolution) != 1)
 84    usage();
 85  if (resolution <= 0)
 86    fatal("resolution must be > 0");
 87  int unitwidth;
 88  if (sscanf(argv[argc-2], "%d", &unitwidth) != 1)
 89    usage();
 90  if (unitwidth <= 0)
 91    fatal("unitwidth must be > 0");
 92  font_params param;
 93  const char *font = argv[argc-1];
 94  param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I');
 95  param.em = (resolution*unitwidth)/72;
 96  param.x_height = DEFAULT_X_HEIGHT;
 97  param.fig_height = DEFAULT_FIG_HEIGHT;
 98  param.asc_height = DEFAULT_ASC_HEIGHT;
 99  param.body_height = DEFAULT_BODY_HEIGHT;
100  param.cap_height = DEFAULT_CAP_HEIGHT;
101  param.comma_depth = DEFAULT_COMMA_DEPTH;
102  param.desc_depth = DEFAULT_DESC_DEPTH;
103  param.body_depth = DEFAULT_BODY_DEPTH;
104  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
105    if (argv[i][1] == '-' && argv[i][2] == '\0') {
106      i++;
107      break;
108    }
109    if (i + 1 >= argc)
110      usage();
111    size_t j;
112    for (j = 0;; j++) {
113      if (j >= sizeof(param_table)/sizeof(param_table[0]))
114	fatal("parameter `%1' not recognized", argv[i] + 1);
115      if (strcmp(param_table[j].name, argv[i] + 1) == 0)
116	break;
117    }
118    if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1)
119      fatal("invalid argument `%1'", argv[i+1]);
120    i++;
121  }    
122  if (argc - i != 3)
123    usage();
124  errno = 0;
125  FILE *infp = fopen(font, "r");
126  if (infp == 0)
127    fatal("can't open `%1': %2", font, strerror(errno));
128  convert_font(param, infp, stdout);
129  return 0;
130}
131
132static void usage(FILE *stream)
133{
134  fprintf(stream, "usage: %s [-v] [-param value] ... "
135		  "resolution unitwidth font\n",
136	  program_name);
137}
138static void usage()
139{
140  usage(stderr);
141  exit(1);
142}
143
144static void version()
145{
146  printf("GNU addftinfo (groff) version %s\n", Version_string);
147  exit(0);
148}
149
150static int get_line(FILE *fp, string *p)
151{
152  int c;
153  p->clear();
154  while ((c = getc(fp)) != EOF) {
155    *p += char(c);
156    if (c == '\n')
157      break;
158  }
159  return p->length() > 0;
160}
161  
162static void convert_font(const font_params &param, FILE *infp, FILE *outfp)
163{
164  string s;
165  while (get_line(infp, &s)) {
166    put_string(s, outfp);
167    if (s.length() >= 8
168	&& strncmp(&s[0], "charset", 7))
169      break;
170  }
171  while (get_line(infp, &s)) {
172    s += '\0';
173    string name;
174    const char *p = s.contents();
175    while (csspace(*p))
176      p++;
177    while (*p != '\0' && !csspace(*p))
178      name += *p++;
179    while (csspace(*p))
180      p++;
181    for (const char *q = s.contents(); q < p; q++)
182      putc(*q, outfp);
183    char *next;
184    char_metric metric;
185    metric.width = (int)strtol(p, &next, 10);
186    if (next != p) {
187      printf("%d", metric.width);
188      p = next;
189      metric.type = (int)strtol(p, &next, 10);
190      if (next != p) {
191	name += '\0';
192	guess(name.contents(), param, &metric);
193	if (metric.sk == 0) {
194	  if (metric.left_ic == 0) {
195	    if (metric.ic == 0) {
196	      if (metric.depth == 0) {
197		if (metric.height != 0)
198		  printf(",%d", metric.height);
199	      }
200	      else
201		printf(",%d,%d", metric.height, metric.depth);
202	    }
203	    else
204	      printf(",%d,%d,%d", metric.height, metric.depth, metric.ic);
205	  }
206	  else
207	    printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
208		   metric.left_ic);
209	}
210	else
211	  printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
212		 metric.left_ic, metric.sk);
213      }
214    }
215    fputs(p, outfp);
216  }
217}
218