LCOV - code coverage report
Current view: top level - preproc/pic - main.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 197 392 50.3 %
Date: 2026-01-16 17:51:41 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2025 Free Software Foundation, Inc.
       2             :      Written by James Clark (jjc@jclark.com)
       3             : 
       4             : This file is part of groff, the GNU roff typesetting system.
       5             : 
       6             : groff is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation, either version 3 of the License, or
       9             : (at your option) any later version.
      10             : 
      11             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : #include <config.h>
      21             : #endif
      22             : 
      23             : #include <assert.h>
      24             : #include <errno.h>
      25             : #include <locale.h> // setlocale()
      26             : #include <stdio.h> // EOF, FILE, fclose(), ferror(), fflush(), fopen(),
      27             :                    // fprintf(), fputs(), getc(), printf(), setbuf(),
      28             :                    // stderr, stdin, stdout, ungetc()
      29             : #include <stdlib.h> // exit(), EXIT_FAILURE, EXIT_SUCCESS, free()
      30             : #include <string.h> // strerror()
      31             : 
      32             : #include <getopt.h> // getopt_long()
      33             : 
      34             : #include "pic.h"
      35             : 
      36             : extern int yyparse();
      37             : extern "C" const char *Version_string;
      38             : 
      39             : output *out;
      40             : char *graphname;                // the picture box name in TeX mode
      41             : 
      42             : bool want_flyback = false;
      43             : // groff pic supports '.PY' to work around mm package stepping on 'PF'.
      44             : bool want_alternate_flyback = false;
      45             : int zero_length_line_flag = 0;
      46             : // Non-zero means we're using a groff driver.
      47             : int driver_extension_flag = 1;
      48             : int compatible_flag = 0;
      49             : bool want_unsafe_mode = false;
      50             : int command_char = '.';         // the character that introduces lines
      51             :                                 // that should be passed through transparently
      52             : static int lf_flag = 1;         // non-zero if we should attempt to understand
      53             :                                 // lines beginning with '.lf'
      54             : 
      55             : // Non-zero means a parse error was encountered.
      56             : static int had_parse_error = 0;
      57             : 
      58             : void do_file(const char *filename);
      59             : 
      60             : class top_input : public input {
      61             :   FILE *fp;
      62             :   int bol;
      63             :   int eof;
      64             :   int push_back[3];
      65             :   int start_lineno;
      66             : public:
      67             :   top_input(FILE *);
      68             :   int get();
      69             :   int peek();
      70             :   int get_location(const char **, int *);
      71             : };
      72             : 
      73         114 : top_input::top_input(FILE *p) : fp(p), bol(1), eof(0)
      74             : {
      75         114 :   push_back[0] = push_back[1] = push_back[2] = EOF;
      76         114 :   start_lineno = current_lineno;
      77         114 : }
      78             : 
      79       30270 : int top_input::get()
      80             : {
      81       30270 :   if (eof)
      82         114 :     return EOF;
      83       30156 :   if (push_back[2] != EOF) {
      84           0 :     int c = push_back[2];
      85           0 :     push_back[2] = EOF;
      86           0 :     return c;
      87             :   }
      88       30156 :   else if (push_back[1] != EOF) {
      89           0 :     int c = push_back[1];
      90           0 :     push_back[1] = EOF;
      91           0 :     return c;
      92             :   }
      93       30156 :   else if (push_back[0] != EOF) {
      94           0 :     int c = push_back[0];
      95           0 :     push_back[0] = EOF;
      96           0 :     return c;
      97             :   }
      98       30156 :   int c = getc(fp);
      99       30156 :   if (bol && c == '.') {
     100         138 :     c = getc(fp);
     101         138 :     if (c == 'P') {
     102         114 :       c = getc(fp);
     103         114 :       if (c == 'E' || c == 'F' || c == 'Y') {
     104         114 :         int d = getc(fp);
     105         114 :         if (d != EOF)
     106         114 :           ungetc(d, fp);
     107         114 :         if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {
     108         114 :           eof = 1;
     109         114 :           want_flyback = (c == 'F');
     110         114 :           want_alternate_flyback = (c == 'Y');
     111         114 :           return EOF;
     112             :         }
     113           0 :         push_back[0] = c;
     114           0 :         push_back[1] = 'P';
     115           0 :         return '.';
     116             :       }
     117           0 :       if (c == 'S') {
     118           0 :         c = getc(fp);
     119           0 :         if (c != EOF)
     120           0 :           ungetc(c, fp);
     121           0 :         if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {
     122           0 :           error("nested .PS");
     123           0 :           eof = 1;
     124           0 :           return EOF;
     125             :         }
     126           0 :         push_back[0] = 'S';
     127           0 :         push_back[1] = 'P';
     128           0 :         return '.';
     129             :       }
     130           0 :       if (c != EOF)
     131           0 :         ungetc(c, fp);
     132           0 :       push_back[0] = 'P';
     133           0 :       return '.';
     134             :     }
     135             :     else {
     136          24 :       if (c != EOF)
     137          24 :         ungetc(c, fp);
     138          24 :       return '.';
     139             :     }
     140             :   }
     141       30018 :   if (c == '\n') {
     142        1151 :     bol = 1;
     143        1151 :     current_lineno++;
     144        1151 :     return '\n';
     145             :   }
     146       28867 :   bol = 0;
     147       28867 :   if (c == EOF) {
     148           0 :     eof = 1;
     149           0 :     error("end of file before .PE, .PF, or .PY");
     150           0 :     error_with_file_and_line(current_filename, start_lineno - 1,
     151             :                              ".PS was here");
     152             :   }
     153       28867 :   return c;
     154             : }
     155             : 
     156       11238 : int top_input::peek()
     157             : {
     158       11238 :   if (eof)
     159           0 :     return EOF;
     160       11238 :   if (push_back[2] != EOF)
     161           0 :     return push_back[2];
     162       11238 :   if (push_back[1] != EOF)
     163           0 :     return push_back[1];
     164       11238 :   if (push_back[0] != EOF)
     165           0 :     return push_back[0];
     166       11238 :   int c = getc(fp);
     167       11238 :   if (bol && c == '.') {
     168           0 :     c = getc(fp);
     169           0 :     if (c == 'P') {
     170           0 :       c = getc(fp);
     171           0 :       if (c == 'E' || c == 'F' || c == 'Y') {
     172           0 :         int d = getc(fp);
     173           0 :         if (d != EOF)
     174           0 :           ungetc(d, fp);
     175           0 :         if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {
     176           0 :           eof = 1;
     177           0 :           want_flyback = (c == 'F');
     178           0 :           want_alternate_flyback = (c == 'Y');
     179           0 :           return EOF;
     180             :         }
     181           0 :         push_back[0] = c;
     182           0 :         push_back[1] = 'P';
     183           0 :         push_back[2] = '.';
     184           0 :         return '.';
     185             :       }
     186           0 :       if (c == 'S') {
     187           0 :         c = getc(fp);
     188           0 :         if (c != EOF)
     189           0 :           ungetc(c, fp);
     190           0 :         if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {
     191           0 :           error("nested .PS");
     192           0 :           eof = 1;
     193           0 :           return EOF;
     194             :         }
     195           0 :         push_back[0] = 'S';
     196           0 :         push_back[1] = 'P';
     197           0 :         push_back[2] = '.';
     198           0 :         return '.';
     199             :       }
     200           0 :       if (c != EOF)
     201           0 :         ungetc(c, fp);
     202           0 :       push_back[0] = 'P';
     203           0 :       push_back[1] = '.';
     204           0 :       return '.';
     205             :     }
     206             :     else {
     207           0 :       if (c != EOF)
     208           0 :         ungetc(c, fp);
     209           0 :       push_back[0] = '.';
     210           0 :       return '.';
     211             :     }
     212             :   }
     213       11238 :   if (c != EOF)
     214       11238 :     ungetc(c, fp);
     215       11238 :   if (c == '\n')
     216         100 :     return '\n';
     217       11138 :   return c;
     218             : }
     219             : 
     220         937 : int top_input::get_location(const char **filenamep, int *linenop)
     221             : {
     222         937 :   *filenamep = current_filename;
     223         937 :   *linenop = current_lineno;
     224         937 :   return 1;
     225             : }
     226             : 
     227         114 : void do_picture(FILE *fp)
     228             : {
     229         114 :   want_flyback = false;
     230             :   int c;
     231         114 :   if (!graphname)
     232          13 :     free(graphname);
     233         114 :   graphname = strsave("graph");               // default picture name in TeX mode
     234         117 :   while ((c = getc(fp)) == ' ')
     235             :     ;
     236         114 :   if (c == '<') {
     237           0 :     string filename;
     238           0 :     while ((c = getc(fp)) == ' ')
     239             :       ;
     240           0 :     while (c != EOF && c != ' ' && c != '\n') {
     241           0 :       filename += char(c);
     242           0 :       c = getc(fp);
     243             :     }
     244           0 :     if (c == ' ') {
     245           0 :       do {
     246           0 :         c = getc(fp);
     247           0 :       } while (c != EOF && c != '\n');
     248             :     }
     249           0 :     if (c == '\n') 
     250           0 :       current_lineno++;
     251           0 :     if (filename.length() == 0)
     252           0 :       error("missing filename after '<'");
     253             :     else {
     254           0 :       filename += '\0';
     255           0 :       const char *old_filename = current_filename;
     256           0 :       int old_lineno = current_lineno;
     257             :       // filenames must be permanent
     258           0 :       do_file(strsave(filename.contents()));
     259           0 :       current_filename = old_filename;
     260           0 :       current_lineno = old_lineno;
     261             :     }
     262           0 :     out->set_location(current_filename, current_lineno);
     263             :   }
     264             :   else {
     265         114 :     out->set_location(current_filename, current_lineno);
     266         114 :     string start_line;
     267         132 :     while (c != EOF) {
     268         132 :       if (c == '\n') {
     269         114 :         current_lineno++;
     270         114 :         break;
     271             :       }
     272          18 :       start_line += c;
     273          18 :       c = getc(fp);
     274             :     }
     275         114 :     if (c == EOF)
     276           0 :       return;
     277         114 :     start_line += '\0';
     278             :     double wid, ht;
     279         114 :     switch (sscanf(&start_line[0], "%lf %lf", &wid, &ht)) {
     280           3 :     case 1:
     281           3 :       ht = 0.0;
     282           3 :       break;
     283           0 :     case 2:
     284           0 :       break;
     285         111 :     default:
     286         111 :       ht = wid = 0.0;
     287         111 :       break;
     288             :     }
     289         114 :     out->set_desired_width_height(wid, ht);
     290         114 :     out->set_args(start_line.contents());
     291         114 :     lex_init(new top_input(fp));
     292         114 :     if (yyparse()) {
     293           0 :       had_parse_error = 1;
     294           0 :       lex_error("giving up on this picture");
     295             :     }
     296         114 :     parse_cleanup();
     297         114 :     lex_cleanup();
     298             : 
     299             :     // skip the rest of the .PE/.PF/.PY line
     300         114 :     while ((c = getc(fp)) != EOF && c != '\n')
     301             :       ;
     302         114 :     if (c == '\n')
     303         114 :       current_lineno++;
     304         114 :     out->set_location(current_filename, current_lineno);
     305             :   }
     306             : }
     307             : 
     308          48 : void do_file(const char *filename)
     309             : {
     310             :   FILE *fp;
     311          48 :   if (strcmp(filename, "-") == 0)
     312          37 :     fp = stdin;
     313             :   else {
     314          11 :     errno = 0;
     315          11 :     fp = fopen(filename, "r");
     316          11 :     if (fp == 0) {
     317           0 :       delete out;
     318           0 :       fatal("cannot open '%1': %2", filename, strerror(errno));
     319             :     }
     320             :   }
     321          96 :   string fn(filename);
     322          48 :   fn += '\0';
     323          48 :   normalize_file_name_for_lf_request(fn);
     324          48 :   current_filename = fn.contents();
     325          48 :   out->set_location(current_filename, 1);
     326          48 :   current_lineno = 1;
     327          48 :   enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state
     328             :     = START;
     329             :   for (;;) {
     330     5627081 :     int c = getc(fp);
     331     5627081 :     if (c == EOF)
     332          48 :       break;
     333     5627033 :     switch (state) {
     334      282808 :     case START:
     335      282808 :       if (c == '.')
     336      167807 :         state = HAD_DOT;
     337             :       else {
     338      115001 :         putchar(c);
     339      115001 :         if (c == '\n') {
     340         140 :           current_lineno++;
     341         140 :           state = START;
     342             :         }
     343             :         else
     344      114861 :           state = MIDDLE;
     345             :       }
     346      282808 :       break;
     347     5169287 :     case MIDDLE:
     348     5169287 :       putchar(c);
     349     5169287 :       if (c == '\n') {
     350      226862 :         current_lineno++;
     351      226862 :         state = START;
     352             :       }
     353     5169287 :       break;
     354      167807 :     case HAD_DOT:
     355      167807 :       if (c == 'P')
     356        6549 :         state = HAD_P;
     357      161258 :       else if (lf_flag && c == 'l')
     358         234 :         state = HAD_l;
     359             :       else {
     360      161024 :         putchar('.');
     361      161024 :         putchar(c);
     362      161024 :         if (c == '\n') {
     363       51879 :           current_lineno++;
     364       51879 :           state = START;
     365             :         }
     366             :         else
     367      109145 :           state = MIDDLE;
     368             :       }
     369      167807 :       break;
     370        6549 :     case HAD_P:
     371        6549 :       if (c == 'S')
     372         114 :         state = HAD_PS;
     373             :       else  {
     374        6435 :         putchar('.');
     375        6435 :         putchar('P');
     376        6435 :         putchar(c);
     377        6435 :         if (c == '\n') {
     378        3579 :           current_lineno++;
     379        3579 :           state = START;
     380             :         }
     381             :         else
     382        2856 :           state = MIDDLE;
     383             :       }
     384        6549 :       break;
     385         114 :     case HAD_PS:
     386         114 :       if (c == ' ' || c == '\n' || compatible_flag) {
     387         114 :         ungetc(c, fp);
     388         114 :         do_picture(fp);
     389         114 :         state = START;
     390             :       }
     391             :       else {
     392           0 :         fputs(".PS", stdout);
     393           0 :         putchar(c);
     394           0 :         state = MIDDLE;
     395             :       }
     396         114 :       break;
     397         234 :     case HAD_l:
     398         234 :       if (c == 'f')
     399         234 :         state = HAD_lf;
     400             :       else {
     401           0 :         putchar('.');
     402           0 :         putchar('l');
     403           0 :         putchar(c);
     404           0 :         if (c == '\n') {
     405           0 :           current_lineno++;
     406           0 :           state = START;
     407             :         }
     408             :         else
     409           0 :           state = MIDDLE;
     410             :       }
     411         234 :       break;
     412         234 :     case HAD_lf:
     413         234 :       if (c == ' ' || c == '\n' || compatible_flag) {
     414         234 :         string line;
     415        7127 :         while (c != EOF) {
     416        7127 :           line += c;
     417        7127 :           if (c == '\n') {
     418         234 :             current_lineno++;
     419         234 :             break;
     420             :           }
     421        6893 :           c = getc(fp);
     422             :         }
     423         234 :         line += '\0';
     424         234 :         interpret_lf_request_arguments(line.contents());
     425         234 :         printf(".lf%s", line.contents());
     426         234 :         state = START;
     427             :       }
     428             :       else {
     429           0 :         fputs(".lf", stdout);
     430           0 :         putchar(c);
     431           0 :         state = MIDDLE;
     432             :       }
     433         234 :       break;
     434           0 :     default:
     435           0 :       assert(0 == "unhandled parser state");
     436             :     }
     437     5627033 :   }
     438          48 :   switch (state) {
     439          48 :   case START:
     440          48 :     break;
     441           0 :   case MIDDLE:
     442           0 :     putchar('\n');
     443           0 :     break;
     444           0 :   case HAD_DOT:
     445           0 :     fputs(".\n", stdout);
     446           0 :     break;
     447           0 :   case HAD_P:
     448           0 :     fputs(".P\n", stdout);
     449           0 :     break;
     450           0 :   case HAD_PS:
     451           0 :     fputs(".PS\n", stdout);
     452           0 :     break;
     453           0 :   case HAD_l:
     454           0 :     fputs(".l\n", stdout);
     455           0 :     break;
     456           0 :   case HAD_lf:
     457           0 :     fputs(".lf\n", stdout);
     458           0 :     break;
     459             :   }
     460          48 :   if (fp != stdin)
     461          11 :     fclose(fp);
     462          48 : }
     463             : 
     464             : #ifdef FIG_SUPPORT
     465             : void do_whole_file(const char *filename)
     466             : {
     467             :   // Do not set current_filename.
     468             :   FILE *fp;
     469             :   if (strcmp(filename, "-") == 0)
     470             :     fp = stdin;
     471             :   else {
     472             :     errno = 0;
     473             :     fp = fopen(filename, "r");
     474             :     if (fp == 0)
     475             :       fatal("cannot open '%1': %2", filename, strerror(errno));
     476             :   }
     477             :   lex_init(new file_input(fp, filename));
     478             :   if (yyparse())
     479             :     had_parse_error = 1;
     480             :   parse_cleanup();
     481             :   lex_cleanup();
     482             : }
     483             : #endif
     484             : 
     485           0 : void usage(FILE *stream)
     486             : {
     487           0 :   fprintf(stream, "usage: %s [-CnSU] [file ...]\n", program_name);
     488             : #ifdef TEX_SUPPORT
     489           0 :   fprintf(stream, "usage: %s -t [-cCSUz] [file ...]\n", program_name);
     490             : #endif
     491             : #ifdef FIG_SUPPORT
     492             :   fprintf(stream, "usage: %s -f [-v] [file]\n", program_name);
     493             : #endif
     494           0 :   fprintf(stream, "usage: %s {-v | --version}\n", program_name);
     495           0 :   fprintf(stream, "usage: %s --help\n", program_name);
     496           0 :   if (stdout == stream) {
     497           0 :     fputs(
     498             : "\n"
     499             : "GNU pic is a troff(1) preprocessor that translates descriptions of\n"
     500             : "diagrammatic pictures embedded in roff(7)"
     501             : #ifdef TEX_SUPPORT
     502             : " or TeX"
     503             : #endif
     504             : " input into the language\n"
     505             : "understood by"
     506             : #ifdef TEX_SUPPORT
     507             : " TeX or"
     508             : #endif
     509             : " troff.  See the pic(1) manual page.\n",
     510             :           stream);
     511             :   }
     512           0 : }
     513             : 
     514             : #if defined(__MSDOS__) || defined(__EMX__)
     515             : static char *fix_program_name(char *arg, char *dflt)
     516             : {
     517             :   if (!arg)
     518             :     return dflt;
     519             :   char *prog = strchr(arg, '\0');
     520             :   for (;;) {
     521             :     if (prog == arg)
     522             :       break;
     523             :     --prog;
     524             :     if (strchr("\\/:", *prog)) {
     525             :       prog++;
     526             :       break;
     527             :     }
     528             :   }     
     529             :   char *ext = strchr(prog, '.');
     530             :   if (ext)
     531             :     *ext = '\0';
     532             :   for (char *p = prog; *p; p++)
     533             :     if ('A' <= *p && *p <= 'Z')
     534             :       *p = 'a' + (*p - 'A');
     535             :   return prog;
     536             : }
     537             : #endif /* __MSDOS__ || __EMX__ */
     538             : 
     539          48 : int main(int argc, char **argv)
     540             : {
     541          48 :   setlocale(LC_NUMERIC, "C");
     542             : #if defined(__MSDOS__) || defined(__EMX__)
     543             :   argv[0] = fix_program_name(argv[0], "pic");
     544             : #endif /* __MSDOS__ || __EMX__ */
     545          48 :   program_name = argv[0];
     546             :   static char stderr_buf[BUFSIZ];
     547          48 :   setbuf(stderr, stderr_buf);
     548             :   int opt;
     549          48 :   bool is_safer_mode_locked = false;
     550             : #ifdef TEX_SUPPORT
     551          48 :   int tex_flag = 0;
     552          48 :   int tpic_flag = 0;
     553             : #endif
     554             : #ifdef FIG_SUPPORT
     555             :   int whole_file_flag = 0;
     556             :   int fig_flag = 0;
     557             : #endif
     558             :   static const struct option long_options[] = {
     559             :     { "help", no_argument, 0 /* nullptr */, CHAR_MAX + 1 },
     560             :     { "version", no_argument, 0 /* nullptr */, 'v' },
     561             :     { 0 /* nullptr */, 0, 0 /* nullptr */, 0 }
     562             :   };
     563          59 :   while ((opt = getopt_long(argc, argv, ":cCDfnpStT:Uvxz", long_options,
     564             :                             0 /* nullptr */))
     565          59 :          != EOF)
     566          11 :     switch (opt) {
     567           0 :     case 'C':
     568           0 :       compatible_flag = 1;
     569           0 :       break;
     570           0 :     case 'D':
     571             :     case 'T':
     572           0 :       break;
     573           0 :     case 'S':
     574           0 :       want_unsafe_mode = false;
     575           0 :       is_safer_mode_locked = true;
     576           0 :       break;
     577          11 :     case 'U':
     578          11 :       if (is_safer_mode_locked)
     579           0 :         error("ignoring '-U' option; '-S' already specified");
     580             :       else
     581          11 :         want_unsafe_mode = true;
     582          11 :       break;
     583           0 :     case 'f':
     584             : #ifdef FIG_SUPPORT
     585             :       whole_file_flag++;
     586             :       fig_flag++;
     587             : #else
     588           0 :       fatal("fig support is not built into this configuration");
     589             : #endif
     590           0 :       break;
     591           0 :     case 'n':
     592           0 :       driver_extension_flag = 0;
     593           0 :       break;
     594           0 :     case 'p':
     595             :     case 'x':
     596           0 :       warning("command-line option '-%1' is obsolete; ignoring",
     597           0 :               char(opt));
     598           0 :       break;
     599           0 :     case 't':
     600             : #ifdef TEX_SUPPORT
     601           0 :       tex_flag++;
     602             : #else
     603             :       fatal("TeX support is not built into this configuration");
     604             : #endif
     605           0 :       break;
     606           0 :     case 'c':
     607             : #ifdef TEX_SUPPORT
     608           0 :       tpic_flag++;
     609             : #else
     610             :       fatal("TeX support is not built into this configuration");
     611             : #endif
     612           0 :       break;
     613           0 :     case 'v':
     614             :       {
     615           0 :         printf("GNU pic (groff) version %s\n", Version_string);
     616           0 :         exit(EXIT_SUCCESS);
     617             :         break;
     618             :       }
     619           0 :     case 'z':
     620             :       // zero length lines will be printed as dots
     621           0 :       zero_length_line_flag++;
     622           0 :       break;
     623           0 :     case CHAR_MAX + 1: // --help
     624           0 :       usage(stdout);
     625           0 :       exit(EXIT_SUCCESS);
     626             :       break;
     627           0 :     case '?':
     628           0 :       if (optopt != 0)
     629           0 :         error("unrecognized command-line option '%1'", char(optopt));
     630             :       else
     631           0 :         error("unrecognized command-line option '%1'",
     632           0 :               argv[(optind - 1)]);
     633           0 :       usage(stderr);
     634           0 :       exit(2);
     635             :       break;
     636           0 :     case ':':
     637           0 :       error("command-line option '%1' requires an argument",
     638           0 :            char(optopt));
     639           0 :       usage(stderr);
     640           0 :       exit(2);
     641             :       break;
     642           0 :     default:
     643           0 :       assert(0 == "unhandled getopt_long return value");
     644             :     }
     645          48 :   parse_init();
     646             : #ifdef TEX_SUPPORT
     647          48 :   if (tpic_flag) {
     648           0 :     out = make_tpic_output();
     649           0 :     lf_flag = 0;
     650             :   }
     651          48 :   else if (tex_flag) {
     652           0 :     out = make_tex_output();
     653           0 :     command_char = '\\';
     654           0 :     lf_flag = 0;
     655             :   }
     656             :   else
     657             : #endif
     658             : #ifdef FIG_SUPPORT
     659             :   if (fig_flag)
     660             :     out = make_fig_output();
     661             :   else
     662             : #endif
     663             :   {
     664          48 :     out = make_troff_output();
     665          48 :     printf(".do if !dPS .ds PS\n"
     666             :            ".do if !dPE .ds PE\n"
     667             :            ".do if !dPF .ds PF\n"
     668             :            ".do if !dPY .ds PY\n");
     669             :   }
     670             : #ifdef FIG_SUPPORT
     671             :   if (whole_file_flag) {
     672             :     if (optind >= argc)
     673             :       do_whole_file("-");
     674             :     else if (argc - optind > 1) {
     675             :       usage(stderr);
     676             :       exit(EXIT_FAILURE);
     677             :     }
     678             :     else
     679             :       do_whole_file(argv[optind]);
     680             :   }
     681             :   else {
     682             : #endif
     683          48 :     if (optind >= argc)
     684          37 :       do_file("-");
     685             :     else
     686          22 :       for (int i = optind; i < argc; i++)
     687          11 :         do_file(argv[i]);
     688             : #ifdef FIG_SUPPORT
     689             :   }
     690             : #endif
     691          48 :   delete out;
     692          48 :   if (ferror(stdout))
     693           0 :     fatal("error status on standard output stream");
     694          48 :   if (fflush(stdout) < 0)
     695           0 :     fatal("cannot flush standard output stream: %1", strerror(errno));
     696          48 :   return had_parse_error;
     697             : }
     698             : 
     699             : // Local Variables:
     700             : // fill-column: 72
     701             : // mode: C++
     702             : // End:
     703             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14