示例#1
0
void alter_format()
{
  symbol nm = get_name(1);
  if (nm.is_null()) {
    skip_line();
    return;
  }
  reg *r = (reg *)number_reg_dictionary.lookup(nm);
  if (r == 0) {
    r = new number_reg;
    number_reg_dictionary.define(nm, r);
  }
  tok.skip();
  char c = tok.ch();
  if (csdigit(c)) {
    int n = 0;
    do {
      ++n;
      tok.next();
    } while (csdigit(tok.ch()));
    r->alter_format('1', n);
  }
  else if (c == 'i' || c == 'I' || c == 'a' || c == 'A')
    r->alter_format(c);
  else if (tok.newline() || tok.eof())
    warning(WARN_MISSING, "missing number register format");
  else
    error("bad number register format (got %1)", tok.description());
  skip_line();
}
示例#2
0
static int store_key(char *s, int len)
{
  if (len < shortest_len)
    return 0;
  int is_number = 1;
  for (int i = 0; i < len; i++)
    if (!csdigit(s[i])) {
      is_number = 0;
      s[i] = cmlower(s[i]);
    }
  if (is_number && !(len == 4 && s[0] == '1' && s[1] == '9'))
    return 0;
  int h = hash(s, len) % hash_table_size;
  if (common_words_table) {
    for (word_list *ptr = common_words_table[h]; ptr; ptr = ptr->next)
      if (len == ptr->len && memcmp(s, ptr->str, len) == 0)
	return 0;
  }
  table_entry *pp =  hash_table + h;
  if (!pp->ptr)
    pp->ptr = new block;
  else if (pp->ptr->v[pp->ptr->used - 1] == ntags)
    return 1;
  else if (pp->ptr->used >= BLOCK_SIZE)
    pp->ptr = new block(pp->ptr);
  pp->ptr->v[(pp->ptr->used)++] = ntags;
  return 1;
}
示例#3
0
文件: ref.cpp 项目: att/uwin
const char *find_year(const char *start, const char *end, const char **endp)
{
  for (;;) {
    while (start < end && !csdigit(*start))
      start++;
    const char *ptr = start;
    if (start == end)
      break;
    while (ptr < end && csdigit(*ptr))
      ptr++;
    if (ptr - start == 4 || ptr - start == 3
	|| (ptr - start == 2
	    && (start[0] >= '4' || (start[0] == '3' && start[1] >= '2')))) {
      *endp = ptr;
      return start;
    }
    start = ptr;
  }
  return 0;
}
示例#4
0
int font::scan_papersize(const char *p,
			 const char **size, double *length, double *width)
{
  double l, w;
  char lu[2], wu[2];
  const char *pp = p;
  int test_file = 1;
  char line[255];
again:
  if (csdigit(*pp)) {
    if (sscanf(pp, "%lf%1[ipPc],%lf%1[ipPc]", &l, lu, &w, wu) == 4
	&& l > 0 && w > 0
	&& unit_scale(&l, lu[0]) && unit_scale(&w, wu[0])) {
      if (length)
	*length = l;
      if (width)
	*width = w;
      if (size)
	*size = "custom";
      return 1;
    }
  }
  else {
    int i;
    for (i = 0; i < NUM_PAPERSIZES; i++)
      if (strcasecmp(papersizes[i].name, pp) == 0) {
	if (length)
	  *length = papersizes[i].length;
	if (width)
	  *width = papersizes[i].width;
	if (size)
	  *size = papersizes[i].name;
	return 1;
      }
    if (test_file) {
      FILE *f = fopen(p, "r");
      if (f) {
	fgets(line, 254, f);
	fclose(f);
	test_file = 0;
	char *linep = strchr(line, '\0');
	// skip final newline, if any
	if (*(--linep) == '\n')
	  *linep = '\0';
	pp = line;
	goto again;
      }
    }
  }
  return 0;
}
示例#5
0
文件: ref.cpp 项目: att/uwin
static const char *find_day(const char *start, const char *end,
			    const char **endp)
{
  for (;;) {
    while (start < end && !csdigit(*start))
      start++;
    const char *ptr = start;
    if (start == end)
      break;
    while (ptr < end && csdigit(*ptr))
      ptr++;
    if ((ptr - start == 1 && start[0] != '0')
	|| (ptr - start == 2 &&
	    (start[0] == '1'
	     || start[0] == '2'
	     || (start[0] == '3' && start[1] <= '1')
	     || (start[0] == '0' && start[1] != '0')))) {
      *endp = ptr;
      return start;
    }
    start = ptr;
  }
  return 0;
}
示例#6
0
map_init::map_init()
{
  int i;
  for (i = 0; i < 256; i++)
    map[i] = csalnum(i) ? cmlower(i) : '\0';
  for (i = 0; i < 256; i++) {
    if (cslower(i)) {
      inv_map[i][0] = i;
      inv_map[i][1] = cmupper(i);
      inv_map[i][2] = '\0';
    }
    else if (csdigit(i)) {
      inv_map[i][0] = i;
      inv_map[i][1] = 0;
    }
    else
      inv_map[i][0] = '\0';
  }
}
示例#7
0
static int atoh(unsigned int *result,
		const char * const s, const size_t length)
{
  size_t i = 0;
  unsigned int val = 0;
  while ((i < length) && csxdigit(s[i])) {
    if (csdigit(s[i]))
      val = val*0x10 + (s[i]-'0');
    else if (csupper(s[i]))
      val = val*0x10 + (s[i]-'A') + 10;
    else
      val = val*0x10 + (s[i]-'a') + 10;
    i++;
  }
  if (i != length)
    return 0;
  *result = val;
  return 1;
}
示例#8
0
const char *check_unicode_name(const char *u)
{
  if (*u != 'u')
    return 0;
  const char *p = ++u;
  for (;;) {
    int val = 0;
    const char *start = p;
    for (;;) {
      // only uppercase hex digits allowed
      if (!csxdigit(*p))
	return 0;
      if (csdigit(*p))
	val = val*0x10 + (*p-'0');
      else if (csupper(*p))
	val = val*0x10 + (*p-'A'+10);
      else
	return 0;
      // biggest Unicode value is U+10FFFF
      if (val > 0x10FFFF)
	return 0;
      p++;
      if (*p == '\0' || *p == '_')
	break;
    }
    // surrogates not allowed
    if ((val >= 0xD800 && val <= 0xDBFF) || (val >= 0xDC00 && val <= 0xDFFF))
      return 0;
    if (val > 0xFFFF) {
      if (*start == '0')	// no leading zeros allowed if > 0xFFFF
	return 0;
    }
    else if (p - start != 4)	// otherwise, check for exactly 4 hex digits
      return 0;
    if (*p == '\0')
      break;
    p++;
  }
  return u;
}
示例#9
0
const int *index_search_item::search1(const char **pp, const char *end)
{
  while (*pp < end && !csalnum(**pp))
    *pp += 1;
  if (*pp >= end)
    return 0;
  const char *start = *pp;
  while (*pp < end && csalnum(**pp))
    *pp += 1;
  int len = *pp - start;
  if (len < header.shortest)
    return 0;
  if (len > header.truncate)
    len = header.truncate;
  int is_number = 1;
  for (int i = 0; i < len; i++)
    if (csdigit(start[i]))
      key_buffer[i] = start[i];
    else {
      key_buffer[i] = cmlower(start[i]);
      is_number = 0;
    }
  if (is_number && !(len == 4 && start[0] == '1' && start[1] == '9'))
    return 0;
  unsigned hc = hash(key_buffer, len);
  if (common_words_table) {
    for (int h = hc % common_words_table_size;
	 common_words_table[h];
	 --h) {
      if (strlen(common_words_table[h]) == (size_t)len
	  && memcmp(common_words_table[h], key_buffer, len) == 0)
	return 0;
      if (h == 0)
	h = common_words_table_size;
    }
  }
  int li = table[int(hc % header.table_size)];
  return li < 0 ? &minus_one : lists + li;
}
示例#10
0
文件: ref.cpp 项目: att/uwin
void reference::compute_sort_key()
{
  if (sort_fields.length() == 0)
    return;
  sort_fields += '\0';
  const char *sf = sort_fields.contents();
  while (*sf != '\0') {
    sort_key += SORT_SEP;
    char f = *sf++;
    int n = 1;
    if (*sf == '+') {
      n = INT_MAX;
      sf++;
    }
    else if (csdigit(*sf)) {
      char *ptr;
      long l = strtol(sf, &ptr, 10);
      if (l == 0 && ptr == sf)
	;
      else {
	sf = ptr;
	if (l < 0) {
	  n = 1;
	}
	else {
	  n = int(l);
	}
      }
    }
    if (f == '.')
      sortify_label(label.contents(), label.length(), sort_key);
    else if (f == AUTHOR_FIELDS[0])
      sortify_authors(n, sort_key);
    else
      sortify_field(f, n, sort_key);
  }
  sort_fields.set_length(sort_fields.length() - 1);
}
示例#11
0
文件: main.cpp 项目: att/uwin
format *process_format(table_input &in, options *opt,
		       format *current_format = 0)
{
  input_entry_format *list = 0;
  int c = in.get();
  for (;;) {
    int pre_vline = 0;
    int got_format = 0;
    int got_period = 0;
    format_type t = FORMAT_LEFT;
    for (;;) {
      if (c == EOF) {
	error("end of input while processing format");
	free_input_entry_format_list(list);
	return 0;
      }
      switch (c) {
      case 'n':
      case 'N':
	t = FORMAT_NUMERIC;
	got_format = 1;
	break;
      case 'a':
      case 'A':
	got_format = 1;
	t = FORMAT_ALPHABETIC;
	break;
      case 'c':
      case 'C':
	got_format = 1;
	t = FORMAT_CENTER;
	break;
      case 'l':
      case 'L':
	got_format = 1;
	t = FORMAT_LEFT;
	break;
      case 'r':
      case 'R':
	got_format = 1;
	t = FORMAT_RIGHT;
	break;
      case 's':
      case 'S':
	got_format = 1;
	t = FORMAT_SPAN;
	break;
      case '^':
	got_format = 1;
	t = FORMAT_VSPAN;
	break;
      case '_':
      case '-':			// tbl also accepts this
	got_format = 1;
	t = FORMAT_HLINE;
	break;
      case '=':
	got_format = 1;
	t = FORMAT_DOUBLE_HLINE;
	break;
      case '.':
	got_period = 1;
	break;
      case '|':
	pre_vline++;
	break;
      case ' ':
      case '\t':
      case '\n':
	break;
      default:
	if (c == opt->tab_char)
	  break;
	error("unrecognised format `%1'", char(c));
	free_input_entry_format_list(list);
	return 0;
      }
      if (got_period)
	break;
      c = in.get();
      if (got_format)
	break;
    }
    if (got_period)
      break;
    list = new input_entry_format(t, list);
    if (pre_vline)
      list->pre_vline = pre_vline;
    int success = 1;
    do {
      switch (c) {
      case 't':
      case 'T':
	c = in.get();
	list->vertical_alignment = entry_modifier::TOP;
	break;
      case 'd':
      case 'D':
	c = in.get();
	list->vertical_alignment = entry_modifier::BOTTOM;
	break;
      case 'u':
      case 'U':
	c = in.get();
	list->stagger = 1;
	break;
      case 'z':
      case 'Z':
	c = in.get();
	list->zero_width = 1;
	break;
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
	{
	  int w = 0;
	  do {
	    w = w*10 + (c - '0');
	    c = in.get();
	  } while (c != EOF && csdigit(c));
	  list->separation = w;
	}
	break;
      case 'f':
      case 'F':
	do {
	  c = in.get();
	} while (c == ' ' || c == '\t');
	if (c == EOF) {
	  error("missing font name");
	  break;
	}
	if (c == '(') {
	  for (;;) {
	    c = in.get();
	    if (c == EOF || c == ' ' || c == '\t') {
	      error("missing `)'");
	      break;
	    }
	    if (c == ')') {
	      c = in.get();
	      break;
	    }
	    list->font += char(c);
	  }
	}
	else {
	  list->font = c;
	  char cc = c;
	  c = in.get();
	  if (!csdigit(cc)
	      && c != EOF && c != ' ' && c != '\t' && c != '.' && c != '\n') {
	    list->font += char(c);
	    c = in.get();
	  }
	}
	break;
      case 'x':
      case 'X':
	do {
	  c = in.get();
	} while (c == ' ' || c == '\t');
	if (c == EOF) {
	  error("missing macro name");
	  break;
	}
	if (c == '(') {
	  for (;;) {
	    c = in.get();
	    if (c == EOF || c == ' ' || c == '\t') {
	      error("missing `)'");
	      break;
	    }
	    if (c == ')') {
	      c = in.get();
	      break;
	    }
	    list->macro += char(c);
	  }
	}
	else {
	  list->macro = c;
	  char cc = c;
	  c = in.get();
	  if (!csdigit(cc)
	      && c != EOF && c != ' ' && c != '\t' && c != '.' && c != '\n') {
	    list->macro += char(c);
	    c = in.get();
	  }
	}
	break;
      case 'v':
      case 'V':
	c = in.get();
	list->vertical_spacing.val = 0;
	list->vertical_spacing.inc = 0;
	if (c == '+' || c == '-') {
	  list->vertical_spacing.inc = (c == '+' ? 1 : -1);
	  c = in.get();
	}
	if (c == EOF || !csdigit(c)) {
	  error("`v' modifier must be followed by number");
	  list->vertical_spacing.inc = 0;
	}
	else {
	  do {
	    list->vertical_spacing.val *= 10;
	    list->vertical_spacing.val += c - '0';
	    c = in.get();
	  } while (c != EOF && csdigit(c));
	}
	if (list->vertical_spacing.val > MAX_VERTICAL_SPACING
	    || list->vertical_spacing.val < -MAX_VERTICAL_SPACING) {
	  error("unreasonable vertical spacing");
	  list->vertical_spacing.val = 0;
	  list->vertical_spacing.inc = 0;
	}
	break;
      case 'p':
      case 'P':
	c = in.get();
	list->point_size.val = 0;
	list->point_size.inc = 0;
	if (c == '+' || c == '-') {
	  list->point_size.inc = (c == '+' ? 1 : -1);
	  c = in.get();
	}
	if (c == EOF || !csdigit(c)) {
	  error("`p' modifier must be followed by number");
	  list->point_size.inc = 0;
	}
	else {
	  do {
	    list->point_size.val *= 10;
	    list->point_size.val += c - '0';
	    c = in.get();
	  } while (c != EOF && csdigit(c));
	}
	if (list->point_size.val > MAX_POINT_SIZE
	    || list->point_size.val < -MAX_POINT_SIZE) {
	  error("unreasonable point size");
	  list->point_size.val = 0;
	  list->point_size.inc = 0;
	}
	break;
      case 'w':
      case 'W':
	c = in.get();
	while (c == ' ' || c == '\t')
	  c = in.get();
	if (c == '(') {
	  list->width = "";
	  c = in.get();
	  while (c != ')') {
	    if (c == EOF || c == '\n') {
	      error("missing `)'");
	      free_input_entry_format_list(list);
	      return 0;
	    }
	    list->width += c;
	    c = in.get();
	  }
	  c = in.get();
	}
	else {
	  if (c == '+' || c == '-') {
	    list->width = char(c);
	    c = in.get();
	  }
	  else
	    list->width = "";
	  if (c == EOF || !csdigit(c))
	    error("bad argument for `w' modifier");
	  else {
	    do {
	      list->width += char(c);
	      c = in.get();
	    } while (c != EOF && csdigit(c));
	  }
	}
	break;
      case 'e':
      case 'E':
	c = in.get();
	list->equal++;
	break;
      case '|':
	c = in.get();
	list->vline++;
	break;
      case 'B':
      case 'b':
	c = in.get();
	list->font = "B";
	break;
      case 'I':
      case 'i':
	c = in.get();
	list->font = "I";
	break;
      case ' ':
      case '\t':
	c = in.get();
	break;
      default:
	if (c == opt->tab_char)
	  c = in.get();
	else
	  success = 0;
	break;
      }
    } while (success);
    if (list->vline > 2) {
      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;
}
示例#12
0
文件: main.cpp 项目: att/uwin
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;
}
示例#13
0
static int parse_term(units *v, int scale_indicator,
		      int parenthesised, int rigid)
{
  int negative = 0;
  for (;;)
    if (parenthesised && tok.space())
      tok.next();
    else if (tok.ch() == '+')
      tok.next();
    else if (tok.ch() == '-') {
      tok.next();
      negative = !negative;
    }
    else
      break;
  unsigned char c = tok.ch();
  switch (c) {
  case '|':
    // | is not restricted to the outermost level
    // tbl uses this
    tok.next();
    if (!parse_term(v, scale_indicator, parenthesised, rigid))
      return 0;
    int tem;
    tem = (scale_indicator == 'v'
	   ? curdiv->get_vertical_position().to_units()
	   : curenv->get_input_line_position().to_units());
    if (tem >= 0) {
      if (*v < INT_MIN + tem) {
	error("numeric overflow");
	return 0;
      }
    }
    else {
      if (*v > INT_MAX + tem) {
	error("numeric overflow");
	return 0;
      }
    }
    *v -= tem;
    if (negative) {
      if (*v == INT_MIN) {
	error("numeric overflow");
	return 0;
      }
      *v = -*v;
    }
    return 1;
  case '(':
    tok.next();
    c = tok.ch();
    if (c == ')') {
      if (rigid)
	return 0;
      warning(WARN_SYNTAX, "empty parentheses");
      tok.next();
      *v = 0;
      return 1;
    }
    else if (c != 0 && strchr(SCALE_INDICATOR_CHARS, c) != 0) {
      tok.next();
      if (tok.ch() == ';') {
	tok.next();
	scale_indicator = c;
      }
      else {
	error("expected `;' after scale-indicator (got %1)",
	      tok.description());
	return 0;
      }
    }
    else if (c == ';') {
      scale_indicator = 0;
      tok.next();
    }
    if (!parse_expr(v, scale_indicator, 1, rigid))
      return 0;
    tok.skip();
    if (tok.ch() != ')') {
      if (rigid)
	return 0;
      warning(WARN_SYNTAX, "missing `)' (got %1)", tok.description());
    }
    else
      tok.next();
    if (negative) {
      if (*v == INT_MIN) {
	error("numeric overflow");
	return 0;
      }
      *v = -*v;
    }
    return 1;
  case '.':
    *v = 0;
    break;
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    *v = 0;
    do {
      if (*v > INT_MAX/10) {
	error("numeric overflow");
	return 0;
      }
      *v *= 10;
      if (*v > INT_MAX - (int(c) - '0')) {
	error("numeric overflow");
	return 0;
      }
      *v += c - '0';
      tok.next();
      c = tok.ch();
    } while (csdigit(c));
    break;
  case '/':
  case '*':
  case '%':
  case ':':
  case '&':
  case '>':
  case '<':
  case '=':
    warning(WARN_SYNTAX, "empty left operand");
    *v = 0;
    return rigid ? 0 : 1;
  default:
    warning(WARN_NUMBER, "numeric expression expected (got %1)",
	    tok.description());
    return 0;
  }
  int divisor = 1;
  if (tok.ch() == '.') {
    tok.next();
    for (;;) {
      c = tok.ch();
      if (!csdigit(c))
	break;
      // we may multiply the divisor by 254 later on
      if (divisor <= INT_MAX/2540 && *v <= (INT_MAX - 9)/10) {
	*v *= 10;
	*v += c - '0';
	divisor *= 10;
      }
      tok.next();
    }
  }
  int si = scale_indicator;
  int do_next = 0;
  if ((c = tok.ch()) != 0 && strchr(SCALE_INDICATOR_CHARS, c) != 0) {
    switch (scale_indicator) {
    case 'z':
      if (c != 'u' && c != 'z') {
	warning(WARN_SCALE,
		"only `z' and `u' scale indicators valid in this context");
	break;
      }
      si = c;
      break;
    case 0:
      warning(WARN_SCALE, "scale indicator invalid in this context");
      break;
    case 'u':
      si = c;
      break;
    default:
      if (c == 'z') {
	warning(WARN_SCALE, "`z' scale indicator invalid in this context");
	break;
      }
      si = c;
      break;
    }
    // Don't do tok.next() here because the next token might be \s, which
    // would affect the interpretation of m.
    do_next = 1;
  }
  switch (si) {
  case 'i':
    *v = scale(*v, units_per_inch, divisor);
    break;
  case 'c':
    *v = scale(*v, units_per_inch*100, divisor*254);
    break;
  case 0:
  case 'u':
    if (divisor != 1)
      *v /= divisor;
    break;
  case 'f':
    *v = scale(*v, 65536, divisor);
    break;
  case 'p':
    *v = scale(*v, units_per_inch, divisor*72);
    break;
  case 'P':
    *v = scale(*v, units_per_inch, divisor*6);
    break;
  case 'm':
    {
      // Convert to hunits so that with -Tascii `m' behaves as in nroff.
      hunits em = curenv->get_size();
      *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), divisor);
    }
    break;
  case 'M':
    {
      hunits em = curenv->get_size();
      *v = scale(*v, em.is_zero() ? hresolution : em.to_units(), divisor*100);
    }
    break;
  case 'n':
    {
      // Convert to hunits so that with -Tascii `n' behaves as in nroff.
      hunits en = curenv->get_size()/2;
      *v = scale(*v, en.is_zero() ? hresolution : en.to_units(), divisor);
    }
    break;
  case 'v':
    *v = scale(*v, curenv->get_vertical_spacing().to_units(), divisor);
    break;
  case 's':
    while (divisor > INT_MAX/(sizescale*72)) {
      divisor /= 10;
      *v /= 10;
    }
    *v = scale(*v, units_per_inch, divisor*sizescale*72);
    break;
  case 'z':
    *v = scale(*v, sizescale, divisor);
    break;
  default:
    assert(0);
  }
  if (do_next)
    tok.next();
  if (negative) {
    if (*v == INT_MIN) {
      error("numeric overflow");
      return 0;
    }
    *v = -*v;
  }
  return 1;
}
示例#14
0
文件: ref.cpp 项目: att/uwin
void reference::output(FILE *fp)
{
  fputs(".]-\n", fp);
  for (int i = 0; i < 256; i++)
    if (field_index[i] != NULL_FIELD_INDEX && i != annotation_field) {
      string &f = field[field_index[i]];
      if (!csdigit(i)) {
	int j = reverse_fields.search(i);
	if (j >= 0) {
	  int n;
	  int len = reverse_fields.length();
	  if (++j < len && csdigit(reverse_fields[j])) {
	    n = reverse_fields[j] - '0';
	    for (++j; j < len && csdigit(reverse_fields[j]); j++)
	      // should check for overflow
	      n = n*10 + reverse_fields[j] - '0';
	  }
	  else 
	    n = INT_MAX;
	  reverse_names(f, n);
	}
      }
      int is_multiple = join_fields(f) > 0;
      if (capitalize_fields.search(i) >= 0)
	capitalize_field(f);
      if (memchr(f.contents(), '\n', f.length()) == 0) {
	fprintf(fp, ".ds [%c ", i);
	if (f[0] == ' ' || f[0] == '\\' || f[0] == '"')
	  putc('"', fp);
	put_string(f, fp);
	putc('\n', fp);
      }
      else {
	fprintf(fp, ".de [%c\n", i);
	put_string(f, fp);
	fputs("..\n", fp);
      }
      if (i == 'P') {
	int multiple_pages = 0;
	const char *s = f.contents();
	const char *end = f.contents() + f.length();
	for (;;) {
	  const char *token_start = s;
	  if (!get_token(&s, end))
	    break;
	  const token_info *ti = lookup_token(token_start, s);
	  if (ti->is_hyphen() || ti->is_range_sep()) {
	    multiple_pages = 1;
	    break;
	  }
	}
	fprintf(fp, ".nr [P %d\n", multiple_pages);
      }
      else if (i == 'E')
	fprintf(fp, ".nr [E %d\n", is_multiple);
    }
  for (const char *p = "TAO"; *p; p++) {
    int fi = field_index[(unsigned char)*p];
    if (fi != NULL_FIELD_INDEX) {
      string &f = field[fi];
      fprintf(fp, ".nr [%c %d\n", *p,
	      is_terminated(f.contents(), f.contents() + f.length()));
    }
  }
  int t = classify();
  fprintf(fp, ".][ %d %s\n", t, reference_types[t]);
  if (annotation_macro.length() > 0 && annotation_field >= 0
      && field_index[annotation_field] != NULL_FIELD_INDEX) {
    putc('.', fp);
    put_string(annotation_macro, fp);
    putc('\n', fp);
    put_string(field[field_index[annotation_field]], fp);
  }
}
示例#15
0
int get_token(int lookup_flag)
{
  context_buffer.clear();
  for (;;) {
    int n = 0;
    int bol = input_stack::bol();
    int c = input_stack::get_char();
    if (bol && c == command_char) {
      token_buffer.clear();
      token_buffer += c;
      // the newline is not part of the token
      for (;;) {
	c = input_stack::peek_char();
	if (c == EOF || c == '\n')
	  break;
	input_stack::get_char();
	token_buffer += char(c);
      }
      context_buffer = token_buffer;
      return COMMAND_LINE;
    }
    switch (c) {
    case EOF:
      return EOF;
    case ' ':
    case '\t':
      break;
    case '\\':
      {
	int d = input_stack::peek_char();
	if (d != '\n') {
	  context_buffer = '\\';
	  return '\\';
	}
	input_stack::get_char();
	break;
      }
    case '#':
      do {
	c = input_stack::get_char();
      } while (c != '\n' && c != EOF);
      if (c == '\n')
	context_buffer = '\n';
      return c;
    case '"':
      context_buffer = '"';
      token_buffer.clear();
      for (;;) {
	c = input_stack::get_char();
	if (c == '\\') {
	  context_buffer += '\\';
	  c = input_stack::peek_char();
	  if (c == '"') {
	    input_stack::get_char();
	    token_buffer += '"';
	    context_buffer += '"';
	  }
	  else
	    token_buffer += '\\';
	}
	else if (c == '\n') {
	  error("newline in string");
	  break;
	}
	else if (c == EOF) {
	  error("missing `\"'");
	  break;
	}
	else if (c == '"') {
	  context_buffer += '"';
	  break;
	}
	else {
	  context_buffer += char(c);
	  token_buffer += char(c);
	}
      }
      return TEXT;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      {   
	int overflow = 0;
	n = 0;
	for (;;) {
	  if (n > (INT_MAX - 9)/10) {
	    overflow = 1;
	    break;
	  }
	  n *= 10;
	  n += c - '0';
	  context_buffer += char(c);
	  c = input_stack::peek_char();
	  if (c == EOF || !csdigit(c))
	    break;
	  c = input_stack::get_char();
	}
	token_double = n;
	if (overflow) {
	  for (;;) {
	    token_double *= 10.0;
	    token_double += c - '0';
	    context_buffer += char(c);
	    c = input_stack::peek_char();
	    if (c == EOF || !csdigit(c))
	      break;
	    c = input_stack::get_char();
	  }
	  // if somebody asks for 1000000000000th, we will silently
	  // give them INT_MAXth
	  double temp = token_double; // work around gas 1.34/sparc bug
	  if (token_double > INT_MAX)
	    n = INT_MAX;
	  else
	    n = int(temp);
	}
      }
      switch (c) {
      case 'i':
      case 'I':
	context_buffer += char(c);
	input_stack::get_char();
	return NUMBER;
      case '.':
	{
	  context_buffer += '.';
	  input_stack::get_char();
	got_dot:
	  double factor = 1.0;
	  for (;;) {
	    c = input_stack::peek_char();
	    if (c == EOF || !csdigit(c))
	      break;
	    input_stack::get_char();
	    context_buffer += char(c);
	    factor /= 10.0;
	    if (c != '0')
	      token_double += factor*(c - '0');
	  }
	  if (c != 'e' && c != 'E') {
	    if (c == 'i' || c == 'I') {
	      context_buffer += char(c);
	      input_stack::get_char();
	    }
	    return NUMBER;
	  }
	}
	// fall through
      case 'e':
      case 'E':
	{
	  int echar = c;
	  input_stack::get_char();
	  c = input_stack::peek_char();
	  int sign = '+';
	  if (c == '+' || c == '-') {
	    sign = c;
	    input_stack::get_char();
	    c = input_stack::peek_char();
	    if (c == EOF || !csdigit(c)) {
	      input_stack::push_back(sign);
	      input_stack::push_back(echar);
	      return NUMBER;
	    }
	    context_buffer += char(echar);
	    context_buffer += char(sign);
	  }
	  else {
	    if (c == EOF || !csdigit(c)) {
	      input_stack::push_back(echar);
	      return NUMBER;
	    }
	    context_buffer += char(echar);
	  }
	  input_stack::get_char();
	  context_buffer += char(c);
	  n = c - '0';
	  for (;;) {
	    c = input_stack::peek_char();
	    if (c == EOF || !csdigit(c))
	      break;
	    input_stack::get_char();
	    context_buffer += char(c);
	    n = n*10 + (c - '0');
	  }
	  if (sign == '-')
	    n = -n;
	  if (c == 'i' || c == 'I') {
	    context_buffer += char(c);
	    input_stack::get_char();
	  }
	  token_double *= pow(10.0, n);
	  return NUMBER;
	}
      case 'n':
	input_stack::get_char();
	c = input_stack::peek_char();
	if (c == 'd') {
	  input_stack::get_char();
	  token_int = n;
	  context_buffer += "nd";
	  return ORDINAL;
	}
	input_stack::push_back('n');
	return NUMBER;
      case 'r':
	input_stack::get_char();
	c = input_stack::peek_char();
	if (c == 'd') {
	  input_stack::get_char();
	  token_int = n;
	  context_buffer += "rd";
	  return ORDINAL;
	}
	input_stack::push_back('r');
	return NUMBER;
      case 't':
	input_stack::get_char();
	c = input_stack::peek_char();
	if (c == 'h') {
	  input_stack::get_char();
	  token_int = n;
	  context_buffer += "th";
	  return ORDINAL;
	}
	input_stack::push_back('t');
	return NUMBER;
      case 's':
	input_stack::get_char();
	c = input_stack::peek_char();
	if (c == 't') {
	  input_stack::get_char();
	  token_int = n;
	  context_buffer += "st";
	  return ORDINAL;
	}
	input_stack::push_back('s');
	return NUMBER;
      default:
	return NUMBER;
      }
      break;
    case '\'':
      {
	c = input_stack::peek_char();
	if (c == 't') {
	  input_stack::get_char();
	  c = input_stack::peek_char();
	  if (c == 'h') {
	    input_stack::get_char();
	    context_buffer = "'th";
	    return TH;
	  }
	  else
	    input_stack::push_back('t');
	}
	context_buffer = "'";
	return '\'';
      }
    case '.':
      {
	c = input_stack::peek_char();
	if (c != EOF && csdigit(c)) {
	  n = 0;
	  token_double = 0.0;
	  context_buffer = '.';
	  goto got_dot;
	}
	return get_token_after_dot(c);
      }
    case '<':
      c = input_stack::peek_char();
      if (c == '-') {
	input_stack::get_char();
	c = input_stack::peek_char();
	if (c == '>') {
	  input_stack::get_char();
	  context_buffer = "<->";
	  return DOUBLE_ARROW_HEAD;
	}
	context_buffer = "<-";
	return LEFT_ARROW_HEAD;
      }
      else if (c == '=') {
	input_stack::get_char();
	context_buffer = "<=";
	return LESSEQUAL;
      }
      context_buffer = "<";
      return '<';
    case '-':
      c = input_stack::peek_char();
      if (c == '>') {
	input_stack::get_char();
	context_buffer = "->";
	return RIGHT_ARROW_HEAD;
      }
      context_buffer = "-";
      return '-';
    case '!':
      c = input_stack::peek_char();
      if (c == '=') {
	input_stack::get_char();
	context_buffer = "!=";
	return NOTEQUAL;
      }
      context_buffer = "!";
      return '!';
    case '>':
      c = input_stack::peek_char();
      if (c == '=') {
	input_stack::get_char();
	context_buffer = ">=";
	return GREATEREQUAL;
      }
      context_buffer = ">";
      return '>';
    case '=':
      c = input_stack::peek_char();
      if (c == '=') {
	input_stack::get_char();
	context_buffer = "==";
	return EQUALEQUAL;
      }
      context_buffer = "=";
      return '=';
    case '&':
      c = input_stack::peek_char();
      if (c == '&') {
	input_stack::get_char();
	context_buffer = "&&";
	return ANDAND;
      }
      context_buffer = "&";
      return '&';
    case '|':
      c = input_stack::peek_char();
      if (c == '|') {
	input_stack::get_char();
	context_buffer = "||";
	return OROR;
      }
      context_buffer = "|";
      return '|';
    default:
      if (c != EOF && csalpha(c)) {
	token_buffer.clear();
	token_buffer = c;
	for (;;) {
	  c = input_stack::peek_char();
	  if (c == EOF || (!csalnum(c) && c != '_'))
	    break;
	  input_stack::get_char();
	  token_buffer += char(c);
	}
	int tok = lookup_keyword(token_buffer.contents(),
				 token_buffer.length());
	if (tok != 0) {
	  context_buffer = token_buffer;
	  return tok;
	}
	char *def = 0;
	if (lookup_flag) {
	  token_buffer += '\0';
	  def = macro_table.lookup(token_buffer.contents());
	  token_buffer.set_length(token_buffer.length() - 1);
	  if (def) {
	    if (c == '(') {
	      input_stack::get_char();
	      interpolate_macro_with_args(def);
	    }
	    else
	      input_stack::push(new macro_input(def));
	  }
	}
	if (!def) {
	  context_buffer = token_buffer;
	  if (csupper(token_buffer[0]))
	    return LABEL;
	  else
	    return VARIABLE;
	}
      }
      else {
	context_buffer = char(c);
	return (unsigned char)c;
      }
      break;
    }
  }
}