home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / groff / eqn / main.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-30  |  6.5 KB  |  280 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.uucp)
  4.  
  5. This file is part of groff.
  6.  
  7. groff is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 1, or (at your option) any later
  10. version.
  11.  
  12. groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License along
  18. with groff; see the file LICENSE.  If not, write to the Free Software
  19. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include "eqn.h"
  22. #include "stringclass.h"
  23.  
  24. #ifndef DEVICE
  25. #define DEVICE "ps"
  26. #endif
  27.  
  28. extern int yyparse();
  29.  
  30. char start_delim = '\0';
  31. char end_delim = '\0';
  32. int non_empty_flag;
  33. int inline_flag;
  34. int draw_flag = 0;
  35. int one_size_reduction_flag = 0;
  36. int compatible_flag = 0;
  37. int no_newline_in_delim_flag = 0;
  38.  
  39. int read_line(FILE *fp, string *p)
  40. {
  41.   p->clear();
  42.   int c = -1;
  43.   while ((c = getc(fp)) != EOF) {
  44.     if (!illegal_input_char(c))
  45.       *p += char(c);
  46.     else
  47.       error("illegal input character code `%1'", c);
  48.     if (c == '\n')
  49.       break;
  50.   }
  51.   current_lineno++;
  52.   return p->length() > 0;
  53. }
  54.  
  55. void do_file(const char *filename)
  56. {
  57.   string linebuf;
  58.   string str;
  59.   FILE *fp;
  60.   if (strcmp(filename, "-") == 0)
  61.     fp = stdin;
  62.   else {
  63.     fp = fopen(filename, "r");
  64.     if (fp == 0)
  65.       fatal("can't open `%1': %2", filename, strerror(errno));
  66.   }
  67.   printf(".lf 1 %s\n", filename);
  68.   current_filename = filename;
  69.   current_lineno = 0;
  70.   while (read_line(fp, &linebuf)) {
  71.     int i;
  72.     if (linebuf.length() >= 4
  73.     && linebuf[0] == '.' && linebuf[1] == 'l' && linebuf[2] == 'f'
  74.     && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) {
  75.       put_string(linebuf, stdout);
  76.       linebuf += '\0';
  77.       if (interpret_lf_args(linebuf.contents() + 3))
  78.     current_lineno--;
  79.     }
  80.     else if (linebuf.length() >= 4
  81.          && linebuf[0] == '.'
  82.          && linebuf[1] == 'E'
  83.          && linebuf[2] == 'Q'
  84.          && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) {
  85.       put_string(linebuf, stdout);
  86.       int start_lineno = current_lineno + 1;
  87.       str.clear();
  88.       for (;;) {
  89.     if (!read_line(fp, &linebuf))
  90.       fatal("end of file before .EN");
  91.     if (linebuf.length() >= 3 && linebuf[0] == '.' && linebuf[1] == 'E') {
  92.       if (linebuf[2] == 'N'
  93.           && (linebuf.length() == 3 || linebuf[3] == ' '
  94.           || linebuf[3] == '\n' || compatible_flag))
  95.         break;
  96.       else if (linebuf[2] == 'Q' && linebuf.length() > 3
  97.            && (linebuf[3] == ' ' || linebuf[3] == '\n'
  98.                || compatible_flag))
  99.         fatal("nested .EQ");
  100.     }
  101.     str += linebuf;
  102.       }
  103.       str += '\0';
  104.       start_string();
  105.       init_lex(str.contents(), current_filename, start_lineno);
  106.       non_empty_flag = 0;
  107.       inline_flag = 0;
  108.       yyparse();
  109.       if (non_empty_flag) {
  110.     printf(".lf %d\n", current_lineno - 1);
  111.     output_string();
  112.       }
  113.       restore_compatibility();
  114.       printf(".lf %d\n", current_lineno);
  115.       put_string(linebuf, stdout);
  116.     }
  117.     else if (start_delim != '\0' && (i = linebuf.search(start_delim)) >= 0
  118.          && (i == 0 || linebuf[i - 1] != '\\')) {
  119.       start_string();
  120.       linebuf += '\0';
  121.       char *ptr = &linebuf[0];
  122.       inline_flag = 1;
  123.       for (;;) {
  124.     char *start = strchr(ptr, start_delim);
  125.     if (start == 0) {
  126.       char *nl = strchr(ptr, '\n');
  127.       if (nl != 0)
  128.         *nl = '\0';
  129.           do_text(ptr);
  130.       break;
  131.         }
  132.     if (no_newline_in_delim_flag && strchr(start + 1, end_delim) == 0) {
  133.       error("missing `%1'", end_delim);
  134.       char *nl = strchr(start + 1, '\n');
  135.       if (nl != 0)
  136.         *nl = '\0';
  137.       do_text(ptr);
  138.       break;
  139.     }
  140.     int start_lineno = current_lineno;
  141.     *start = '\0';
  142.     do_text(ptr);
  143.     ptr = start + 1;
  144.     str.clear();
  145.     for (;;) {
  146.       char *end = strchr(ptr, end_delim);
  147.       if (end != 0) {
  148.         *end = '\0';
  149.         str += ptr;
  150.         ptr = end + 1;
  151.         break;
  152.       }
  153.       str += ptr;
  154.       if (!read_line(fp, &linebuf))
  155.         fatal("end of file before `%1'", end_delim);
  156.       linebuf += '\0';
  157.       ptr = &linebuf[0];
  158.     }
  159.     str += '\0';
  160.     init_lex(str.contents(), current_filename, start_lineno);
  161.     yyparse();
  162.       }
  163.       printf(".lf %d\n", current_lineno);
  164.       output_string();
  165.       restore_compatibility();
  166.       printf(".lf %d\n", current_lineno + 1);
  167.     }
  168.     else {
  169.       put_string(linebuf, stdout);
  170.     }
  171.   }
  172.   if (fp != stdin)
  173.     fclose(fp);
  174.   current_filename = 0;
  175.   current_lineno = 0;
  176. }
  177.  
  178. void usage()
  179. {
  180.   fprintf(stderr, "usage: %s [ -vrDCN ] -dxx -fn -sn -pn -mn -Ts [ files ... ]\n",
  181.       program_name);
  182.   exit(1);
  183. }
  184.  
  185. int main(int argc, char **argv)
  186. {
  187.   program_name = argv[0];
  188.   static char stderr_buf[BUFSIZ];
  189.   setbuf(stderr, stderr_buf);
  190.   int opt;
  191.   const char *device = DEVICE;
  192.   const char *tem = getenv("GROFF_TYPESETTER");
  193.   if (tem)
  194.     device = tem;
  195.   while ((opt = getopt(argc, argv, "DCvd:f:p:s:m:T:rN")) != EOF)
  196.     switch (opt) {
  197.     case 'C':
  198.       compatible_flag = 1;
  199.       break;
  200.     case 'v':
  201.       {
  202.     extern const char *version_string;
  203.     fprintf(stderr, "GNU eqn version %s\n", version_string);
  204.     fflush(stderr);
  205.     break;
  206.       }
  207.     case 'd':
  208.       if (optarg[0] == '\0' || optarg[1] == '\0')
  209.     error("-d requires two character argument");
  210.       else if (illegal_input_char(optarg[0]))
  211.     error("bad delimiter `%1'", optarg[0]);
  212.       else if (illegal_input_char(optarg[1]))
  213.     error("bad delimiter `%1'", optarg[1]);
  214.       else {
  215.     start_delim = optarg[0];
  216.     end_delim = optarg[1];
  217.       }
  218.       break;
  219.     case 'f':
  220.       set_gfont(optarg);
  221.       break;
  222.     case 'T':
  223.       device = optarg;
  224.       break;
  225.     case 's':
  226.       {
  227.     int n;
  228.     if (sscanf(optarg, "%d", &n) == 1)
  229.       set_gsize(n);
  230.     else
  231.       error("bad size `%1'", optarg);
  232.       }
  233.       break;
  234.     case 'p':
  235.       {
  236.     int n;
  237.     if (sscanf(optarg, "%d", &n) == 1)
  238.       set_script_reduction(n);
  239.     else
  240.       error("bad size `%1'", optarg);
  241.       }
  242.       break;
  243.     case 'm':
  244.       {
  245.     int n;
  246.     if (sscanf(optarg, "%d", &n) == 1)
  247.       set_minimum_size(n);
  248.     else
  249.       error("bad size `%1'", optarg);
  250.       }
  251.       break;
  252.     case 'r':
  253.       one_size_reduction_flag = 1;
  254.       break;
  255.     case 'D':
  256.       draw_flag = 1;
  257.       break;
  258.     case 'N':
  259.       no_newline_in_delim_flag = 1;
  260.       break;
  261.     case '?':
  262.       usage();
  263.       break;
  264.     default:
  265.       assert(0);
  266.     }
  267.   init_table(device);
  268.   init_char_table();
  269.   if (optind >= argc)
  270.     do_file("-");
  271.   else
  272.     for (int i = optind; i < argc; i++)
  273.       do_file(argv[i]);
  274.   if (ferror(stdout) || fflush(stdout) < 0)
  275.     fatal("output error");
  276.   exit(0);
  277. }
  278.  
  279.  
  280.