⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cc

📁 早期freebsd实现
💻 CC
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "pic.h"extern int yyparse();output *out;int flyback_flag;int zero_length_line_flag = 0;// Non-zero means we're using a groff driver.int driver_extension_flag = 1;int compatible_flag = 0;int command_char = '.';		// the character that introduces lines				// that should be passed through tranparentlystatic int lf_flag = 1;		// non-zero if we should attempt to understand				// lines beginning with `.lf'void do_file(const char *filename);class top_input : public input {  FILE *fp;  int bol;  int eof;  int push_back[3];  int start_lineno;public:  top_input(FILE *);  int get();  int peek();  int get_location(const char **, int *);};top_input::top_input(FILE *p) : fp(p), bol(1), eof(0){  push_back[0] = push_back[1] = push_back[2] = EOF;  start_lineno = current_lineno;}int top_input::get(){  if (eof)    return EOF;  if (push_back[2] != EOF) {    int c = push_back[2];    push_back[2] = EOF;    return c;  }  else if (push_back[1] != EOF) {    int c = push_back[1];    push_back[1] = EOF;    return c;  }  else if (push_back[0] != EOF) {    int c = push_back[0];    push_back[0] = EOF;    return c;  }  int c = getc(fp);  while (illegal_input_char(c)) {    error("illegal input character code %1", int(c));    c = getc(fp);    bol = 0;  }  if (bol && c == '.') {    c = getc(fp);    if (c == 'P') {      c = getc(fp);      if (c == 'F' || c == 'E') {	int d = getc(fp);	if (d != EOF)	  ungetc(d, fp);	if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {	  eof = 1;	  flyback_flag = c == 'F';	  return EOF;	}	push_back[0] = c;	push_back[1] = 'P';	return '.';      }      if (c == 'S') {	c = getc(fp);	if (c != EOF)	  ungetc(c, fp);	if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {	  error("nested .PS");	  eof = 1;	  return EOF;	}	push_back[0] = 'S';	push_back[1] = 'P';	return '.';      }      if (c != EOF)	ungetc(c, fp);      push_back[0] = 'P';      return '.';    }    else {      if (c != EOF)	ungetc(c, fp);      return '.';    }  }  if (c == '\n') {    bol = 1;    current_lineno++;    return '\n';  }  bol = 0;  if (c == EOF) {    eof = 1;    error("end of file before .PE or .PF");    error_with_file_and_line(current_filename, start_lineno - 1,			     ".PS was here");  }  return c;}int top_input::peek(){  if (eof)    return EOF;  if (push_back[2] != EOF)    return push_back[2];  if (push_back[1] != EOF)    return push_back[1];  if (push_back[0] != EOF)    return push_back[0];  int c = getc(fp);  while (illegal_input_char(c)) {    error("illegal input character code %1", int(c));    c = getc(fp);    bol = 0;  }  if (bol && c == '.') {    c = getc(fp);    if (c == 'P') {      c = getc(fp);      if (c == 'F' || c == 'E') {	int d = getc(fp);	if (d != EOF)	  ungetc(d, fp);	if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {	  eof = 1;	  flyback_flag = c == 'F';	  return EOF;	}	push_back[0] = c;	push_back[1] = 'P';	push_back[2] = '.';	return '.';      }      if (c == 'S') {	c = getc(fp);	if (c != EOF)	  ungetc(c, fp);	if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {	  error("nested .PS");	  eof = 1;	  return EOF;	}	push_back[0] = 'S';	push_back[1] = 'P';	push_back[2] = '.';	return '.';      }      if (c != EOF)	ungetc(c, fp);      push_back[0] = 'P';      push_back[1] = '.';      return '.';    }    else {      if (c != EOF)	ungetc(c, fp);      push_back[0] = '.';      return '.';    }  }  if (c != EOF)    ungetc(c, fp);  if (c == '\n')    return '\n';  return c;}int top_input::get_location(const char **filenamep, int *linenop){  *filenamep = current_filename;  *linenop = current_lineno;  return 1;}void do_picture(FILE *fp){  flyback_flag = 0;  int c;  while ((c = getc(fp)) == ' ')    ;  if (c == '<') {    string filename;    while ((c = getc(fp)) == ' ')      ;    while (c != EOF && c != ' ' && c != '\n') {      filename += char(c);      c = getc(fp);    }    if (c == ' ') {      do {	c = getc(fp);      } while (c != EOF && c != '\n');    }    if (c == '\n')       current_lineno++;    if (filename.length() == 0)      error("missing filename after `<'");    else {      filename += '\0';      const char *old_filename = current_filename;      int old_lineno = current_lineno;      // filenames must be permanent      do_file(strsave(filename.contents()));      current_filename = old_filename;      current_lineno = old_lineno;    }    out->set_location(current_filename, current_lineno);  }  else {    out->set_location(current_filename, current_lineno);    string start_line;    while (c != EOF) {      if (c == '\n') {	current_lineno++;	break;      }      start_line += c;      c = getc(fp);    }    if (c == EOF)      return;    start_line += '\0';    double wid, ht;    switch (sscanf(&start_line[0], "%lf %lf", &wid, &ht)) {    case 1:      ht = 0.0;      break;    case 2:      break;    default:      ht = wid = 0.0;      break;    }    out->set_desired_width_height(wid, ht);    out->set_args(start_line.contents());    lex_init(new top_input(fp));    if (yyparse())      lex_error("giving up on this picture");    parse_cleanup();    lex_cleanup();    // skip the rest of the .PF/.PE line    while ((c = getc(fp)) != EOF && c != '\n')      ;    if (c == '\n')      current_lineno++;    out->set_location(current_filename, current_lineno);  }}void do_file(const char *filename){  FILE *fp;  if (strcmp(filename, "-") == 0)    fp = stdin;  else {    errno = 0;    fp = fopen(filename, "r");    if (fp == 0)      fatal("can't open `%1': %2", filename, strerror(errno));  }  out->set_location(filename, 1);  current_filename = filename;  current_lineno = 1;  enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START;  for (;;) {    int c = getc(fp);    if (c == EOF)      break;    switch (state) {    case START:      if (c == '.')	state = HAD_DOT;      else {	putchar(c);	if (c == '\n') {	  current_lineno++;	  state = START;	}	else	  state = MIDDLE;      }      break;    case MIDDLE:      putchar(c);      if (c == '\n') {	current_lineno++;	state = START;      }      break;    case HAD_DOT:      if (c == 'P')	state = HAD_P;      else if (lf_flag && c == 'l')	state = HAD_l;      else {	putchar('.');	putchar(c);	if (c == '\n') {	  current_lineno++;	  state = START;	}	else	  state = MIDDLE;      }      break;    case HAD_P:      if (c == 'S')	state = HAD_PS;      else  {	putchar('.');	putchar('P');	putchar(c);	if (c == '\n') {	  current_lineno++;	  state = START;	}	else	  state = MIDDLE;      }      break;    case HAD_PS:      if (c == ' ' || c == '\n' || compatible_flag) {	ungetc(c, fp);	do_picture(fp);	state = START;      }      else {	fputs(".PS", stdout);	putchar(c);	state = MIDDLE;      }      break;    case HAD_l:      if (c == 'f')	state = HAD_lf;      else {	putchar('.');	putchar('l');	putchar(c);	if (c == '\n') {	  current_lineno++;	  state = START;	}	else	  state = MIDDLE;      }      break;    case HAD_lf:      if (c == ' ' || c == '\n' || compatible_flag) {	string line;	while (c != EOF) {	  line += c;	  if (c == '\n') {	    current_lineno++;	    break;	  }	  c = getc(fp);	}	line += '\0';	interpret_lf_args(line.contents());	printf(".lf%s", line.contents());	state = START;      }      else {	fputs(".lf", stdout);	putchar(c);	state = MIDDLE;      }      break;    default:      assert(0);    }  }  switch (state) {  case START:    break;  case MIDDLE:    putchar('\n');    break;  case HAD_DOT:    fputs(".\n", stdout);    break;  case HAD_P:    fputs(".P\n", stdout);    break;  case HAD_PS:    fputs(".PS\n", stdout);    break;  case HAD_l:    fputs(".l\n", stdout);    break;  case HAD_lf:    fputs(".lf\n", stdout);    break;  }  if (fp != stdin)    fclose(fp);}#ifdef FIG_SUPPORTvoid do_whole_file(const char *filename){  // Do not set current_filename.  FILE *fp;  if (strcmp(filename, "-") == 0)    fp = stdin;  else {    errno = 0;    fp = fopen(filename, "r");    if (fp == 0)      fatal("can't open `%1': %2", filename, strerror(errno));  }  lex_init(new file_input(fp, filename));  yyparse();  parse_cleanup();  lex_cleanup();}#endifvoid usage(){  fprintf(stderr, "usage: %s [ -nvC ] [ filename ... ]\n", program_name);#ifdef TEX_SUPPORT  fprintf(stderr, "       %s -t [ -cvzC ] [ filename ... ]\n", program_name);#endif#ifdef FIG_SUPPORT  fprintf(stderr, "       %s -f [ -v ] [ filename ]\n", program_name);#endif  exit(1);}#ifdef __MSDOS__static char *fix_program_name(char *arg, char *dflt){  if (!arg)    return dflt;  char *prog = strchr(arg, '\0');  for (;;) {    if (prog == arg)      break;    --prog;    if (strchr("\\/:", *prog)) {      prog++;      break;    }  }	  char *ext = strchr(prog, '.');  if (ext)    *ext = '\0';  for (char *p = prog; *p; p++)    if ('A' <= *p && *p <= 'Z')      *p = 'a' + (*p - 'A');  return prog;}#endif /* __MSDOS__ */int main(int argc, char **argv){#ifdef __MSDOS__  argv[0] = fix_program_name(argv[0], "pic");#endif /* __MSDOS__ */  program_name = argv[0];  static char stderr_buf[BUFSIZ];  setbuf(stderr, stderr_buf);  int opt;#ifdef TEX_SUPPORT  int tex_flag = 0;  int tpic_flag = 0;#endif#ifdef FIG_SUPPORT  int whole_file_flag = 0;  int fig_flag = 0;#endif  while ((opt = getopt(argc, argv, "T:CDtcvnxzpf")) != EOF)    switch (opt) {    case 'C':      compatible_flag = 1;      break;    case 'D':    case 'T':      break;    case 'f':#ifdef FIG_SUPPORT      whole_file_flag++;      fig_flag++;#else      fatal("fig support not included");#endif      break;    case 'n':      driver_extension_flag = 0;      break;    case 'p':    case 'x':      warning("-%1 option is obsolete", char(opt));      break;    case 't':#ifdef TEX_SUPPORT      tex_flag++;#else      fatal("TeX support not included");#endif      break;    case 'c':#ifdef TEX_SUPPORT      tpic_flag++;#else      fatal("TeX support not included");#endif      break;    case 'v':      {	extern const char *version_string;	fprintf(stderr, "GNU pic version %s\n", version_string);	fflush(stderr);	break;      }    case 'z':      // zero length lines will be printed as dots      zero_length_line_flag++;      break;    case '?':      usage();      break;    default:      assert(0);    }  parse_init();#ifdef TEX_SUPPORT  if (tpic_flag) {    out = make_tpic_output();    lf_flag = 0;  }  else if (tex_flag) {    out = make_tex_output();    command_char = '\\';    lf_flag = 0;  }  else#endif#ifdef FIG_SUPPORT  if (fig_flag)    out = make_fig_output();  else#endif    out = make_troff_output();#ifdef FIG_SUPPORT  if (whole_file_flag) {    if (optind >= argc)      do_whole_file("-");    else if (argc - optind > 1)      usage();    else      do_whole_file(argv[optind]);  }  else {#endif    if (optind >= argc)      do_file("-");    else      for (int i = optind; i < argc; i++)	do_file(argv[i]);#ifdef FIG_SUPPORT  }#endif  delete out;  if (ferror(stdout) || fflush(stdout) < 0)    fatal("output error");  exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -