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

📄 input.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
	  ;	if (cc == '\n')	  type = TOKEN_NEWLINE;	else	  type = TOKEN_EOF;	return;      case '#':			// Like \" but newline is ignored.	while ((cc = input_stack::get(NULL)) != '\n')	  if (cc == EOF) {	    type = TOKEN_EOF;	    return;	  }	break;      case '$':	{	  symbol nm = read_escape_name();	  if (!nm.is_null())	    interpolate_arg(nm);	  break;	}      case '*':	{	  symbol nm = read_escape_name();	  if (!nm.is_null())	    interpolate_string(nm);	  break;	}      case 'a':	nd = new non_interpreted_char_node('\001');	type = TOKEN_NODE;	return;      case 'A':	c = '0' + do_name_test();	type = TOKEN_CHAR;	return;      case 'b':	nd = do_bracket();	type = TOKEN_NODE;	return;      case 'c':	goto ESCAPE_c;      case 'C':	nm = get_delim_name();	if (nm.is_null())	  break;	type = TOKEN_SPECIAL;	return;      case 'd':	type = TOKEN_NODE;	nd = new vmotion_node(curenv->get_size()/2);	return;      case 'D':	nd = read_draw_node();	if (!nd)	  break;	type = TOKEN_NODE;	return;      case 'e':	goto ESCAPE_e;      case 'E':	goto handle_escape_char;      case 'f':	{	  symbol s = read_escape_name();	  if (s.is_null())	    break;	  for (const char *p = s.contents(); *p != '\0'; p++)	    if (!csdigit(*p))	      break;	  if (*p)	    curenv->set_font(s);	  else	    curenv->set_font(atoi(s.contents()));	  break;	}      case 'g':	{	  symbol s = read_escape_name();	  if (!s.is_null())	    interpolate_number_format(s);	  break;	}      case 'h':	if (!get_delim_number(&x, 'm'))	  break;	type = TOKEN_NODE;	nd = new hmotion_node(x);	return;      case 'H':	if (get_delim_number(&x, 'z', curenv->get_requested_point_size()))	  curenv->set_char_height(x);	break;      case 'k':	nm = read_escape_name();	if (nm.is_null())	  break;	type = TOKEN_MARK_INPUT;	return;      case 'l':      case 'L':	{	  charinfo *s = 0;	  if (!get_line_arg(&x, (cc == 'l' ? 'm': 'v'), &s))	    break;	  if (s == 0)	    s = get_charinfo(cc == 'l' ? "ru" : "br");	  type = TOKEN_NODE;	  node *n = curenv->make_char_node(s);	  if (cc == 'l')	    nd = new hline_node(x, n);	  else	    nd = new vline_node(x, n);	  return;	}      case 'n':	{	  int inc;	  symbol nm = read_increment_and_escape_name(&inc);	  if (!nm.is_null())	    interpolate_number_reg(nm, inc);	  break;	}      case 'N':	if (!get_delim_number(&val, 0))	  break;	type = TOKEN_NUMBERED_CHAR;	return;      case 'o':	nd = do_overstrike();	type = TOKEN_NODE;	return;      case 'p':	type = TOKEN_SPREAD;	return;      case 'r':	type = TOKEN_NODE;	nd = new vmotion_node(-curenv->get_size());	return;      case 'R':	do_register();	break;      case 's':	if (read_size(&x))	  curenv->set_size(x);	break;      case 'S':	if (get_delim_number(&x, 0))	  curenv->set_char_slant(x);	break;      case 't':	type = TOKEN_NODE;	nd = new non_interpreted_char_node('\t');	return;      case 'u':	type = TOKEN_NODE;	nd = new vmotion_node(-curenv->get_size()/2);	return;      case 'v':	if (!get_delim_number(&x, 'v'))	  break;	type = TOKEN_NODE;	nd = new vmotion_node(x);	return;      case 'V':        {	  symbol nm = read_escape_name();	  if (!nm.is_null())	    interpolate_environment_variable(nm);	  break;	}      case 'w':	do_width();	break;      case 'x':	if (!get_delim_number(&x, 'v'))	  break;	type = TOKEN_NODE;	nd = new extra_size_node(x);	return;      case 'X':	nd = do_special();	if (!nd)	  break;	type = TOKEN_NODE;	return;      case 'Y':	{	  symbol s = read_escape_name();	  if (s.is_null())	    break;	  request_or_macro *p = lookup_request(s);	  macro *m = p->to_macro();	  if (!m) {	    error("can't transparently throughput a request");	    break;	  }	  nd = new special_node(*m);	  type = TOKEN_NODE;	  return;	}      case 'z':	{	  next();          if (type == TOKEN_NODE)            nd = new zero_width_node(nd);          else {  	    charinfo *ci = get_char(1);	    if (ci == 0)	      break;	    node *gn = curenv->make_char_node(ci);	    if (gn == 0)	      break;	    nd = new zero_width_node(gn);	    type = TOKEN_NODE;          }	  return;	}      case 'Z':	nd = do_zero_width();	if (nd == 0)	  break;	type = TOKEN_NODE;	return;      case '{':	goto ESCAPE_LEFT_BRACE;      case '}':	goto ESCAPE_RIGHT_BRACE;      case '\n':	break;      case '[':	if (!compatible_flag) {	  nm = read_long_escape_name();	  if (nm.is_null())	    break;	  type = TOKEN_SPECIAL;	  return;	}	goto handle_normal_char;      default:	if (cc != escape_char && cc != '.')	  warning(WARN_ESCAPE, "escape character ignored before %1",		  input_char_description(cc));	goto handle_normal_char;      }    }  }}int token::operator==(const token &t){  if (type != t.type)    return 0;  switch(type) {  case TOKEN_CHAR:    return c == t.c;  case TOKEN_SPECIAL:    return nm == t.nm;  case TOKEN_NUMBERED_CHAR:    return val == t.val;  default:    return 1;  }}int token::operator!=(const token &t){  return !(*this == t);}// is token a suitable delimiter (like ')?int token::delimiter(int err){  switch(type) {  case TOKEN_CHAR:    switch(c) {    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    case '+':    case '-':    case '/':    case '*':    case '%':    case '<':    case '>':    case '=':    case '&':    case ':':    case '(':    case ')':    case '.':      if (err)	error("cannot use character `%1' as a starting delimiter", char(c));      return 0;    default:      return 1;    }  case TOKEN_NODE:  case TOKEN_SPACE:  case TOKEN_TAB:  case TOKEN_NEWLINE:    if (err)      error("cannot use %1 as a starting delimiter", description());    return 0;  default:    return 1;  }}const char *token::description(){  static char buf[4];  switch (type) {  case TOKEN_BACKSPACE:    return "a backspace character";  case TOKEN_CHAR:    buf[0] = '`';    buf[1] = c;    buf[2] = '\'';    buf[3] = '\0';    return buf;  case TOKEN_DUMMY:    return "`\\&'";  case TOKEN_ESCAPE:    return "`\\e'";  case TOKEN_HYPHEN_INDICATOR:    return "`\\%'";  case TOKEN_INTERRUPT:    return "`\\c'";  case TOKEN_ITALIC_CORRECTION:    return "`\\/'";  case TOKEN_LEADER:    return "a leader character";  case TOKEN_LEFT_BRACE:    return "`\\{'";  case TOKEN_MARK_INPUT:    return "`\\k'";  case TOKEN_NEWLINE:    return "newline";  case TOKEN_NODE:    return "a node";  case TOKEN_NUMBERED_CHAR:    return "`\\N'";  case TOKEN_RIGHT_BRACE:    return "`\\}'";  case TOKEN_SPACE:    return "a space";  case TOKEN_SPECIAL:    return "a special character";  case TOKEN_SPREAD:    return "`\\p'";  case TOKEN_TAB:    return "a tab character";  case TOKEN_TRANSPARENT:    return "`\\!'";  case TOKEN_EOF:    return "end of input";  default:    break;  }  return "a magic token";}void skip_line(){  while (!tok.newline())    if (tok.eof())      return;    else      tok.next();  tok.next();}void compatible(){  int n;  if (has_arg() && get_integer(&n))    compatible_flag = n != 0;  else    compatible_flag = 1;  skip_line();}static void empty_name_warning(int required){  if (tok.newline() || tok.eof()) {    if (required)      warning(WARN_MISSING, "missing name");  }  else if (tok.right_brace() || tok.tab()) {    const char *start = tok.description();    do {      tok.next();    } while (tok.space() || tok.right_brace() || tok.tab());    if (!tok.newline() && !tok.eof())      error("%1 is not allowed before an argument", start);    else if (required)      warning(WARN_MISSING, "missing name");  }  else if (required)    error("name expected (got %1)", tok.description());  else    error("name expected (got %1): treated as missing", tok.description());}static void non_empty_name_warning(){  if (!tok.newline() && !tok.eof() && !tok.space() && !tok.tab()      && !tok.right_brace()      // We don't want to give a warning for .el\{      && !tok.left_brace())    error("%1 is not allowed in a name", tok.description());}symbol get_name(int required){  if (compatible_flag) {    char buf[3];    tok.skip();    if ((buf[0] = tok.ch()) != 0) {      tok.next();      if ((buf[1] = tok.ch()) != 0) {	buf[2] = 0;	tok.make_space();      }      else	non_empty_name_warning();      return symbol(buf);    }    else {      empty_name_warning(required);      return NULL_SYMBOL;    }  }  else     return get_long_name(required);}symbol get_long_name(int required){  while (tok.space())    tok.next();  char abuf[ABUF_SIZE];  char *buf = abuf;  int buf_size = ABUF_SIZE;  int i = 0;  for (;;) {    if (i + 1 > buf_size) {      if (buf == abuf) {	buf = new char [ABUF_SIZE*2];	memcpy(buf, abuf, buf_size);	buf_size = ABUF_SIZE*2;      }      else {	char *old_buf = buf;	buf = new char[buf_size*2];	memcpy(buf, old_buf, buf_size);	buf_size *= 2;	a_delete old_buf;      }    }    if ((buf[i] = tok.ch()) == 0)      break;    i++;    tok.next();  }  if (i == 0) {    empty_name_warning(required);    return NULL_SYMBOL;  }  non_empty_name_warning();  if (buf == abuf)    return symbol(buf);  else {    symbol s(buf);    a_delete buf;    return s;  }}NO_RETURN void exit_troff(){  exit_started = 1;  topdiv->set_last_page();  if (!end_macro_name.is_null()) {    spring_trap(end_macro_name);    tok.next();    process_input_stack();  }  curenv->final_break();  tok.next();  process_input_stack();  end_diversions();  done_end_macro = 1;  topdiv->set_ejecting();  static unsigned char buf[2] = { LAST_PAGE_EJECTOR, '\0' };  input_stack::push(make_temp_iterator((char *)buf));  topdiv->space(topdiv->get_page_length(), 1);  tok.next();  process_input_stack();  seen_last_page_ejector = 1;	// should be set already  topdiv->set_ejecting();  push_page_ejector();  topdiv->space(topdiv->get_page_length(), 1);  tok.next();  process_input_stack();  // This will only happen if a trap-invoked macro starts a diversion,  // or if vertical position traps have been disabled.  cleanup_and_exit(0);}// This implements .ex.  The input stack must be cleared before calling// exit_troff().void exit_request(){  input_stack::clear();  if (exit_started)    tok.next();  else    exit_troff();}void end_macro(){  end_macro_name = get_name();  skip_line();}void do_request(){  int saved_compatible_flag = compatible_flag;  compatible_flag = 0;  symbol nm = get_name();  if (nm.is_null())    skip_line();  else    interpolate_macro(nm);  compatible_flag = saved_compatible_flag;}inline int possibly_handle_first_page_transition(){  if (topdiv->before_first_page && curdiv == topdiv && !curenv->is_dummy()) {    handle_first_page_transition();    return 1;  }  else    return 0;}static int transparent_translate(int cc){  if (!illegal_input_char(cc)) {    charinfo *ci = charset_table[cc];    switch (ci->get_special_translation(1)) {    case charinfo::TRANSLATE_SPACE:      return ' ';    case charinfo::TRANSLATE_DUMMY:      return ESCAPE_AMPERSAND;    case charinfo::TRANSLATE_HYPHEN_INDICATOR:      return ESCAPE_PERCENT;    }    // This is realy ugly.    ci = ci->get_translation(1);    if (ci) {      int c = ci->get_ascii_code();      if (c != '\0')	return c;      error("can't translate %1 to special character `%2'"	    " in transparent throughput",	    input_char_description(cc),	    ci->nm.contents());    }  }  return cc;}class int_stack {  struct int_stack_element {    int n;    int_stack_element *next;  } *top;public:  int_stack();  ~int_stack();  void push(int);  int is_empty();  int pop();};int_stack::int_stack(){  top = 0;}int_stack::~int_stack(){  while (top != 0) {    int_stack_element *temp = top;    top = top->next;    delete temp;  }  }int int_stack::is_empty(){  return top == 0;}void int_stack::push(int n){  int_stack_element *p = new int_stack_element;  p->next = top;  p->n = n;  top = p;}int int_stack::pop(){  assert(top != 0);  int_stack_element *p = top;  top = top->next;  int n = p->n;  delete p;  return n;}int node::reread(int *){  return 0;}int diverted_space_node::reread(int *bolp){  if (curenv->get_fill())    blank_line();  else    curdiv->space(n);  *bolp = 1;  return 1;}int diverted_copy_file_node::reread(int *bolp){  curdiv->copy_file(filename.contents());  *bolp = 1;  return 1;}static void process_input_stack(){  int_stack trap_bol_stack;  int bol = 1;  for (;;) {    int suppress_next = 0;    switch (tok.type) {    case token::TOKEN_CHAR:

⌨️ 快捷键说明

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