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; } } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }