void do_file(FILE *fp, const char *filename) { string linebuf; string str; string fn(filename); fn += '\0'; normalize_for_lf(fn); current_filename = fn.contents(); if (output_format == troff) printf(".lf 1 %s\n", current_filename); current_lineno = 0; while (read_line(fp, &linebuf)) { if (linebuf.length() >= 4 && linebuf[0] == '.' && linebuf[1] == 'l' && linebuf[2] == 'f' && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) { put_string(linebuf, stdout); linebuf += '\0'; if (interpret_lf_args(linebuf.contents() + 3)) current_lineno--; } else if (linebuf.length() >= 4 && linebuf[0] == '.' && linebuf[1] == 'E' && linebuf[2] == 'Q' && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) { put_string(linebuf, stdout); int start_lineno = current_lineno + 1; str.clear(); for (;;) { if (!read_line(fp, &linebuf)) fatal("end of file before .EN"); if (linebuf.length() >= 3 && linebuf[0] == '.' && linebuf[1] == 'E') { if (linebuf[2] == 'N' && (linebuf.length() == 3 || linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) break; else if (linebuf[2] == 'Q' && linebuf.length() > 3 && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) fatal("nested .EQ"); } str += linebuf; } str += '\0'; start_string(); init_lex(str.contents(), current_filename, start_lineno); non_empty_flag = 0; inline_flag = 0; yyparse(); restore_compatibility(); if (non_empty_flag) { if (output_format == mathml) putchar('\n'); else { printf(".lf %d\n", current_lineno - 1); output_string(); } } if (output_format == troff) printf(".lf %d\n", current_lineno); put_string(linebuf, stdout); } else if (start_delim != '\0' && linebuf.search(start_delim) >= 0 && inline_equation(fp, linebuf, str)) ; else put_string(linebuf, stdout); } current_filename = 0; current_lineno = 0; }
void do_file(const char *filename) { FILE *fp; if (strcmp(filename, "-") == 0) fp = stdin; else { errno = 0; fp = fopen(filename, "r"); if (fp == 0) { delete out; 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); }
int do_file(const char *filename) { FILE *fp; if (strcmp(filename, "-") == 0) fp = stdin; else { errno = 0; fp = fopen(filename, "r"); if (fp == 0) { error("can't open `%1': %2", filename, strerror(errno)); return 0; } } current_filename = filename; current_lineno = 1; set_location(); enum { START, MIDDLE, HAD_DOT, HAD_s, HAD_so, 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 == 's') state = HAD_s; else if (c == 'l') state = HAD_l; else { putchar('.'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_s: if (c == 'o') state = HAD_so; else { putchar('.'); putchar('s'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_so: if (c == ' ' || c == '\n' || compatible_flag) { string line; for (; c != EOF && c != '\n'; c = getc(fp)) line += c; current_lineno++; line += '\n'; line += '\0'; do_so(line.contents()); state = START; } else { fputs(".so", 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; for (; c != EOF && c != '\n'; c = getc(fp)) line += c; current_lineno++; line += '\n'; 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 HAD_DOT: fputs(".\n", stdout); break; case HAD_l: fputs(".l\n", stdout); break; case HAD_s: fputs(".s\n", stdout); break; case HAD_lf: fputs(".lf\n", stdout); break; case HAD_so: fputs(".so\n", stdout); break; case MIDDLE: putc('\n', stdout); break; case START: break; } if (fp != stdin) fclose(fp); current_filename = 0; return 1; }
void process_input_file(FILE *fp) { enum { START, MIDDLE, HAD_DOT, HAD_T, HAD_TS, HAD_l, HAD_lf } state; state = START; int c; while ((c = getc(fp)) != EOF) switch (state) { case START: if (c == '.') state = HAD_DOT; else { if (c == '\n') current_lineno++; else state = MIDDLE; putchar(c); } break; case MIDDLE: if (c == '\n') { current_lineno++; state = START; } putchar(c); break; case HAD_DOT: if (c == 'T') state = HAD_T; else if (c == 'l') state = HAD_l; else { putchar('.'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_T: if (c == 'S') state = HAD_TS; else { putchar('.'); putchar('T'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_TS: if (c == ' ' || c == '\n' || compatible_flag) { putchar('.'); putchar('T'); putchar('S'); while (c != '\n') { if (c == EOF) { error("end of file at beginning of table"); return; } putchar(c); c = getc(fp); } putchar('\n'); current_lineno++; { table_input input(fp); process_table(input); set_troff_location(current_filename, current_lineno); if (input.ended()) { fputs(".TE", stdout); while ((c = getc(fp)) != '\n') { if (c == EOF) { putchar('\n'); return; } putchar(c); } putchar('\n'); current_lineno++; } } state = START; } else { fputs(".TS", 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_l: fputs(".l\n", stdout); break; case HAD_T: fputs(".T\n", stdout); break; case HAD_lf: fputs(".lf\n", stdout); break; case HAD_TS: fputs(".TS\n", stdout); break; } if (fp != stdin) fclose(fp); }
table *process_data(table_input &in, format *f, options *opt) { char tab_char = opt->tab_char; int ncolumns = f->ncolumns; int current_row = 0; int format_index = 0; int give_up = 0; enum { DATA_INPUT_LINE, TROFF_INPUT_LINE, SINGLE_HLINE, DOUBLE_HLINE } type; table *tbl = new table(ncolumns, opt->flags, opt->linesize, opt->decimal_point_char); if (opt->delim[0] != '\0') tbl->set_delim(opt->delim[0], opt->delim[1]); for (;;) { // first determine what type of line this is int c = in.get(); if (c == EOF) break; if (c == '.') { int d = in.get(); if (d != EOF && csdigit(d)) { in.unget(d); type = DATA_INPUT_LINE; } else { in.unget(d); type = TROFF_INPUT_LINE; } } else if (c == '_' || c == '=') { int d = in.get(); if (d == '\n') { if (c == '_') type = SINGLE_HLINE; else type = DOUBLE_HLINE; } else { in.unget(d); type = DATA_INPUT_LINE; } } else { type = DATA_INPUT_LINE; } switch (type) { case DATA_INPUT_LINE: { string input_entry; if (format_index >= f->nrows) format_index = f->nrows - 1; // A format row that is all lines doesn't use up a data line. while (format_index < f->nrows - 1) { int cnt; for (cnt = 0; cnt < ncolumns; cnt++) { entry_format *e = f->entry[format_index] + cnt; if (e->type != FORMAT_HLINE && e->type != FORMAT_DOUBLE_HLINE // Unfortunately tbl treats a span as needing data. // && e->type != FORMAT_SPAN ) break; } if (cnt < ncolumns) break; for (cnt = 0; cnt < ncolumns; cnt++) tbl->add_entry(current_row, cnt, input_entry, f->entry[format_index] + cnt, current_filename, current_lineno); tbl->add_vlines(current_row, f->vline[format_index]); format_index++; current_row++; } entry_format *line_format = f->entry[format_index]; int col = 0; int row_comment = 0; for (;;) { if (c == tab_char || c == '\n') { int ln = current_lineno; if (c == '\n') --ln; if ((opt->flags & table::NOSPACES)) input_entry.remove_spaces(); while (col < ncolumns && line_format[col].type == FORMAT_SPAN) { tbl->add_entry(current_row, col, "", &line_format[col], current_filename, ln); col++; } if (c == '\n' && input_entry.length() == 2 && input_entry[0] == 'T' && input_entry[1] == '{') { input_entry = ""; ln++; enum { START, MIDDLE, GOT_T, GOT_RIGHT_BRACE, GOT_DOT, GOT_l, GOT_lf, END } state = START; while (state != END) { c = in.get(); if (c == EOF) break; switch (state) { case START: if (c == 'T') state = GOT_T; else if (c == '.') state = GOT_DOT; else { input_entry += c; if (c != '\n') state = MIDDLE; } break; case GOT_T: if (c == '}') state = GOT_RIGHT_BRACE; else { input_entry += 'T'; input_entry += c; state = c == '\n' ? START : MIDDLE; } break; case GOT_DOT: if (c == 'l') state = GOT_l; else { input_entry += '.'; input_entry += c; state = c == '\n' ? START : MIDDLE; } break; case GOT_l: if (c == 'f') state = GOT_lf; else { input_entry += ".l"; input_entry += c; state = c == '\n' ? START : MIDDLE; } break; case GOT_lf: if (c == ' ' || c == '\n' || compatible_flag) { string args; input_entry += ".lf"; while (c != EOF) { args += c; if (c == '\n') break; c = in.get(); } args += '\0'; interpret_lf_args(args.contents()); // remove the '\0' args.set_length(args.length() - 1); input_entry += args; state = START; } else { input_entry += ".lf"; input_entry += c; state = MIDDLE; } break; case GOT_RIGHT_BRACE: if ((opt->flags & table::NOSPACES)) { while (c == ' ') c = in.get(); if (c == EOF) break; } if (c == '\n' || c == tab_char) state = END; else { input_entry += 'T'; input_entry += '}'; input_entry += c; state = MIDDLE; } break; case MIDDLE: if (c == '\n') state = START; input_entry += c; break; case END: default: assert(0); } } if (c == EOF) { error("end of data in middle of text block"); give_up = 1; break; } } if (col >= ncolumns) { if (!input_entry.empty()) { if (input_entry.length() >= 2 && input_entry[0] == '\\' && input_entry[1] == '"') row_comment = 1; else if (!row_comment) { if (c == '\n') in.unget(c); input_entry += '\0'; error("excess data entry `%1' discarded", input_entry.contents()); if (c == '\n') (void)in.get(); } } } else tbl->add_entry(current_row, col, input_entry, &line_format[col], current_filename, ln); col++; if (c == '\n') break; input_entry = ""; } else input_entry += c; c = in.get(); if (c == EOF) break; } if (give_up) break; input_entry = ""; for (; col < ncolumns; col++) tbl->add_entry(current_row, col, input_entry, &line_format[col], current_filename, current_lineno - 1); tbl->add_vlines(current_row, f->vline[format_index]); current_row++; format_index++; } break; case TROFF_INPUT_LINE: { string line; int ln = current_lineno; for (;;) { line += c; if (c == '\n') break; c = in.get(); if (c == EOF) { break; } } tbl->add_text_line(current_row, line, current_filename, ln); if (line.length() >= 4 && line[0] == '.' && line[1] == 'T' && line[2] == '&') { format *newf = process_format(in, opt, f); if (newf == 0) give_up = 1; else f = newf; } if (line.length() >= 3 && line[0] == '.' && line[1] == 'l' && line[2] == 'f') { line += '\0'; interpret_lf_args(line.contents() + 3); } } break; case SINGLE_HLINE: tbl->add_single_hline(current_row); break; case DOUBLE_HLINE: tbl->add_double_hline(current_row); break; default: assert(0); } if (give_up) break; } if (!give_up && current_row == 0) { error("no real data"); give_up = 1; } if (give_up) { delete tbl; return 0; } // Do this here rather than at the beginning in case continued formats // change it. int i; for (i = 0; i < ncolumns - 1; i++) if (f->separation[i] >= 0) tbl->set_column_separation(i, f->separation[i]); for (i = 0; i < ncolumns; i++) if (!f->width[i].empty()) tbl->set_minimum_width(i, f->width[i]); for (i = 0; i < ncolumns; i++) if (f->equal[i]) tbl->set_equal_column(i); return tbl; }
int do_file(const char *filename) { char *file_name_in_path = 0; FILE *fp = include_search_path.open_file_cautious(filename, &file_name_in_path); int err = errno; string whole_filename(file_name_in_path ? file_name_in_path : filename); whole_filename += '\0'; a_delete file_name_in_path; if (fp == 0) { error("can't open `%1': %2", whole_filename.contents(), strerror(err)); return 0; } current_filename = whole_filename.contents(); current_lineno = 1; set_location(); enum { START, MIDDLE, HAD_DOT, HAD_s, HAD_so, 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 == 's') state = HAD_s; else if (c == 'l') state = HAD_l; else { putchar('.'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_s: if (c == 'o') state = HAD_so; else { putchar('.'); putchar('s'); putchar(c); if (c == '\n') { current_lineno++; state = START; } else state = MIDDLE; } break; case HAD_so: if (c == ' ' || c == '\n' || compatible_flag) { string line; for (; c != EOF && c != '\n'; c = getc(fp)) line += c; current_lineno++; line += '\n'; line += '\0'; do_so(line.contents()); state = START; } else { fputs(".so", 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; for (; c != EOF && c != '\n'; c = getc(fp)) line += c; current_lineno++; line += '\n'; 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 HAD_DOT: fputs(".\n", stdout); break; case HAD_l: fputs(".l\n", stdout); break; case HAD_s: fputs(".s\n", stdout); break; case HAD_lf: fputs(".lf\n", stdout); break; case HAD_so: fputs(".so\n", stdout); break; case MIDDLE: putc('\n', stdout); break; case START: break; } if (fp != stdin) fclose(fp); current_filename = 0; return 1; }