Beispiel #1
0
int file_input::read_line()
{
  for (;;) {
    line.clear();
    lineno++;
    for (;;) {
      int c = getc(fp);
      if (c == EOF)
	break;
      else if (invalid_input_char(c))
	lex_error("invalid input character code %1", c);
      else {
	line += char(c);
	if (c == '\n') 
	  break;
      }
    }
    if (line.length() == 0)
      return 0;
    if (!(line.length() >= 3 && line[0] == '.' && line[1] == 'E'
	  && (line[2] == 'Q' || line[2] == 'N')
	  && (line.length() == 3 || line[3] == ' ' || line[3] == '\n'
	      || compatible_flag))) {
      line += '\0';
      ptr = line.contents();
      return 1;
    }
  }
}
Beispiel #2
0
int simple_file_input::peek()
{
  int c = getc(fp);
  while (invalid_input_char(c)) {
    error("invalid input character code %1", c);
    c = getc(fp);
  }
  if (c != EOF)
    ungetc(c, fp);
  return c;
}
Beispiel #3
0
int simple_file_input::get()
{
  int c = getc(fp);
  while (invalid_input_char(c)) {
    error("invalid input character code %1", c);
    c = getc(fp);
  }
  if (c == '\n')
    lineno++;
  return c;
}
Beispiel #4
0
int read_line(FILE *fp, string *p)
{
  p->clear();
  int c = -1;
  while ((c = getc(fp)) != EOF) {
    if (!invalid_input_char(c))
      *p += char(c);
    else
      error("invalid input character code `%1'", c);
    if (c == '\n')
      break;
  }
  current_lineno++;
  return p->length() > 0;
}
Beispiel #5
0
int text_file::next()
{
  if (fp == 0)
    return 0;
  if (buf == 0) {
    buf = new char[128];
    size = 128;
  }
  for (;;) {
    int i = 0;
    for (;;) {
      int c = getc(fp);
      if (c == EOF)
	break;
      if (invalid_input_char(c))
	error("invalid input character code `%1'", int(c));
      else {
	if (i + 1 >= size) {
	  char *old_buf = buf;
	  buf = new char[size*2];
	  memcpy(buf, old_buf, size);
	  a_delete old_buf;
	  size *= 2;
	}
	buf[i++] = c;
	if (c == '\n')
	  break;
      }
    }
    if (i == 0)
      break;
    buf[i] = '\0';
    lineno++;
    char *ptr = buf;
    while (csspace(*ptr))
      ptr++;
    if (*ptr != 0 && (!skip_comments || *ptr != '#'))
      return 1;
  }
  return 0;
}
Beispiel #6
0
int main(int argc, char **argv)
{
  program_name = argv[0];
  static char stderr_buf[BUFSIZ];
  setbuf(stderr, stderr_buf);
  int opt;
  int load_startup_file = 1;
  static const struct option long_options[] = {
    { "help", no_argument, 0, CHAR_MAX + 1 },
    { "version", no_argument, 0, 'v' },
    { NULL, 0, 0, 0 }
  };
  while ((opt = getopt_long(argc, argv, "DCRvd:f:p:s:m:T:M:rN", long_options,
			    NULL))
	 != EOF)
    switch (opt) {
    case 'C':
      compatible_flag = 1;
      break;
    case 'R':			// don't load eqnrc
      load_startup_file = 0;
      break;
    case 'M':
      config_macro_path.command_line_dir(optarg);
      break;
    case 'v':
      printf("GNU eqn (groff) version %s\n", Version_string);
      exit(0);
      break;
    case 'd':
      if (optarg[0] == '\0' || optarg[1] == '\0')
	error("-d requires two character argument");
      else if (invalid_input_char(optarg[0]))
	error("bad delimiter `%1'", optarg[0]);
      else if (invalid_input_char(optarg[1]))
	error("bad delimiter `%1'", optarg[1]);
      else {
	start_delim = optarg[0];
	end_delim = optarg[1];
      }
      break;
    case 'f':
      set_gfont(optarg);
      break;
    case 'T':
      device = optarg;
      if (strcmp(device, "ps:html") == 0) {
	device = "ps";
	html = 1;
      }
      else if (strcmp(device, "MathML") == 0) {
	output_format = mathml;
	load_startup_file = 0;
      }
      else if (strcmp(device, "mathml:xhtml") == 0) {
	device = "MathML";
	output_format = mathml;
	load_startup_file = 0;
	xhtml = 1;
      }
      break;
    case 's':
      if (!set_gsize(optarg))
	error("invalid size `%1'", optarg);
      break;
    case 'p':
      {
	int n;
	if (sscanf(optarg, "%d", &n) == 1)
	  set_script_reduction(n);
	else
	  error("bad size `%1'", optarg);
      }
      break;
    case 'm':
      {
	int n;
	if (sscanf(optarg, "%d", &n) == 1)
	  set_minimum_size(n);
	else
	  error("bad size `%1'", optarg);
      }
      break;
    case 'r':
      one_size_reduction_flag = 1;
      break;
    case 'D':
      warning("-D option is obsolete: use `set draw_lines 1' instead");
      draw_flag = 1;
      break;
    case 'N':
      no_newline_in_delim_flag = 1;
      break;
    case CHAR_MAX + 1: // --help
      usage(stdout);
      exit(0);
      break;
    case '?':
      usage(stderr);
      exit(1);
      break;
    default:
      assert(0);
    }
  init_table(device);
  init_char_table();
  if (output_format == troff) {
    printf(".if !'\\*(.T'%s' "
	   ".if !'\\*(.T'html' "	// the html device uses `-Tps' to render
				  // equations as images
	   ".tm warning: %s should have been given a `-T\\*(.T' option\n",
	   device, program_name);
    printf(".if '\\*(.T'html' "
	   ".if !'%s'ps' "
	   ".tm warning: %s should have been given a `-Tps' option\n",
	   device, program_name);
    printf(".if '\\*(.T'html' "
	   ".if !'%s'ps' "
	   ".tm warning: (it is advisable to invoke groff via: groff -Thtml -e)\n",
	   device);
  }
  if (load_startup_file) {
    char *path;
    FILE *fp = config_macro_path.open_file(STARTUP_FILE, &path);
    if (fp) {
      do_file(fp, path);
      fclose(fp);
      a_delete path;
    }
  }
  if (optind >= argc)
    do_file(stdin, "-");
  else
    for (int i = optind; i < argc; i++)
      if (strcmp(argv[i], "-") == 0)
	do_file(stdin, "-");
      else {
	errno = 0;
	FILE *fp = fopen(argv[i], "r");
	if (!fp)
	  fatal("can't open `%1': %2", argv[i], strerror(errno));
	else {
	  do_file(fp, argv[i]);
	  fclose(fp);
	}
      }
  if (ferror(stdout) || fflush(stdout) < 0)
    fatal("output error");
  return 0;
}
Beispiel #7
0
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 (invalid_input_char(c)) {
    error("invalid 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;
}
Beispiel #8
0
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 (invalid_input_char(c)) {
    error("invalid 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;
}
Beispiel #9
0
void input_stack::push_file(const char *fn)
{
  FILE *fp;
  if (strcmp(fn, "-") == 0) {
    fp = stdin;
    fn = "<standard input>";
  }
  else {
    errno = 0;
    fp = fopen(fn, "r");
    if (fp == 0) {
      error("can't open `%1': %2", fn, strerror(errno));
      return;
    }
  }
  string buf;
  int bol = 1;
  int lineno = 1;
  for (;;) {
    int c = getc(fp);
    if (bol && c == '.') {
      // replace lines beginning with .R1 or .R2 with a blank line
      c = getc(fp);
      if (c == 'R') {
	c = getc(fp);
	if (c == '1' || c == '2') {
	  int cc = c;
	  c = getc(fp);
	  if (compatible_flag || c == ' ' || c == '\n' || c == EOF) {
	    while (c != '\n' && c != EOF)
	      c = getc(fp);
	  }
	  else {
	    buf += '.';
	    buf += 'R';
	    buf += cc;
	  }
	}
	else {
	  buf += '.';
	  buf += 'R';
	}
      }
      else
	buf += '.';
    }
    if (c == EOF)
      break;
    if (invalid_input_char(c))
      error_with_file_and_line(fn, lineno,
			       "invalid input character code %1", int(c));
    else {
      buf += c;
      if (c == '\n') {
	bol = 1;
	lineno++;
      }
      else
	bol = 0;
    }
  }
  if (fp != stdin)
    fclose(fp);
  if (buf.length() > 0 && buf[buf.length() - 1] != '\n')
    buf += '\n';
  input_item *it = new input_item(buf, fn);
  it->next = top;
  top = it;
}