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

📄 main.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
      list->vline = 2;      error("more than 2 vertical bars between key letters");    }    if (c == '\n' || c == ',') {      c = in.get();      list->last_column = 1;    }  }  if (c == '.') {    do {      c = in.get();    } while (c == ' ' || c == '\t');    if (c != '\n') {      error("`.' not last character on line");      free_input_entry_format_list(list);      return 0;    }  }  if (!list) {    error("no format");    free_input_entry_format_list(list);    return 0;  }  list->last_column = 1;  // now reverse the list so that the first row is at the beginning  input_entry_format *rev = 0;  while (list != 0) {    input_entry_format *tem = list->next;    list->next = rev;    rev = list;    list = tem;  }  list = rev;  input_entry_format *tem;#if 0  for (tem = list; tem; tem = tem->next)    tem->debug_print();  putc('\n', stderr);#endif  // compute number of columns and rows  int ncolumns = 0;  int nrows = 0;  int col = 0;  for (tem = list; tem; tem = tem->next) {    if (tem->last_column) {      if (col >= ncolumns)	ncolumns = col + 1;      col = 0;      nrows++;    }    else      col++;  }  int row;  format *f;  if (current_format) {    if (ncolumns > current_format->ncolumns) {      error("cannot increase the number of columns in a continued format");      free_input_entry_format_list(list);      return 0;    }    f = current_format;    row = f->nrows;    f->add_rows(nrows);  }  else {    f = new format(nrows, ncolumns);    row = 0;  }  col = 0;  for (tem = list; tem; tem = tem->next) {    f->entry[row][col] = *tem;    if (col < ncolumns-1) {      // use the greatest separation      if (tem->separation > f->separation[col]) {	if (current_format)	  error("cannot change column separation in continued format");	else	  f->separation[col] = tem->separation;      }    }    else if (tem->separation >= 0)      error("column separation specified for last column");    if (tem->equal && !f->equal[col]) {      if (current_format)	error("cannot change which columns are equal in continued format");      else	f->equal[col] = 1;    }    if (!tem->width.empty()) {      // use the last width      if (!f->width[col].empty() && f->width[col] != tem->width)	error("multiple widths for column %1", col+1);      f->width[col] = tem->width;    }    if (tem->pre_vline) {      assert(col == 0);      f->vline[row][col] = tem->pre_vline;    }    f->vline[row][col+1] = tem->vline;    if (tem->last_column) {      row++;      col = 0;    }    else      col++;  }  free_input_entry_format_list(list);  for (col = 0; col < ncolumns; col++) {    entry_format *e = f->entry[f->nrows-1] + col;    if (e->type != FORMAT_HLINE	&& e->type != FORMAT_DOUBLE_HLINE	&& e->type != FORMAT_SPAN)      break;  }  if (col >= ncolumns) {    error("last row of format is all lines");    delete f;    return 0;  }  return f;}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) {	  for (int c = 0; c < ncolumns; c++) {	    entry_format *e = f->entry[format_index] + c;	    if (e->type != FORMAT_HLINE		&& e->type != FORMAT_DOUBLE_HLINE		// Unfortunately tbl treats a span as needing data.		// && e->type != FORMAT_SPAN		)	      break;	  }	  if (c < ncolumns)	    break;	  for (c = 0; c < ncolumns; c++)	    tbl->add_entry(current_row, c, input_entry,			   f->entry[format_index] + c, 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;	for (;;) {	  if (c == tab_char || c == '\n') {	    int ln = current_lineno;	    if (c == '\n')	      --ln;	    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 (c == '\n' || c == tab_char)		    state = END;		  else {		    input_entry += 'T';		    input_entry += '}';		    input_entry += c;		    state = c == '\n' ? START : 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 (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] == 'f' && 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.  for (int 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;}void process_table(table_input &in){  int c;  options *opt = 0;  format *form = 0;  table *tbl = 0;  if ((opt = process_options(in)) != 0       && (form = process_format(in, opt)) != 0      && (tbl = process_data(in, form, opt)) != 0) {    tbl->print();    delete tbl;  }  else {    error("giving up on this table");    while ((c = in.get()) != EOF)      ;  }  delete opt;  delete form;  if (!in.ended())    error("premature end of file");}static void usage(){  fprintf(stderr, "usage: %s [ -vC ] [ files... ]\n", program_name);  exit(1);}int main(int argc, char **argv){  program_name = argv[0];  static char stderr_buf[BUFSIZ];  setbuf(stderr, stderr_buf);  int opt;  while ((opt = getopt(argc, argv, "vC")) != EOF)    switch (opt) {    case 'C':      compatible_flag = 1;      break;    case 'v':      {	extern const char *version_string;	fprintf(stderr, "GNU tbl version %s\n", version_string);	fflush(stderr);	break;      }    case '?':      usage();      break;    default:      assert(0);    }  printf(".if !\\n(.g .ab GNU tbl requires GNU troff.\n"	 ".if !dTS .ds TS\n"	 ".if !dTE .ds TE\n");  if (argc > optind) {    for (int i = optind; i < argc; i++)       if (argv[i][0] == '-' && argv[i][1] == '\0') {	current_filename = "-";	current_lineno = 1;	printf(".lf 1 -\n");	process_input_file(stdin);      }      else {	errno = 0;	FILE *fp = fopen(argv[i], "r");	if (fp == 0) {	  current_lineno = -1;	  error("can't open `%1': %2", argv[i], strerror(errno));	}	else {	  current_lineno = 1;	  current_filename = argv[i];	  printf(".lf 1 %s\n", current_filename);	  process_input_file(fp);	}      }  }  else {    current_filename = "-";    current_lineno = 1;    printf(".lf 1 -\n");    process_input_file(stdin);  }  if (ferror(stdout) || fflush(stdout) < 0)    fatal("output error");  exit(0);}

⌨️ 快捷键说明

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