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

📄 input.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
static symbol read_escape_name(){  int c = get_char_for_escape_name();  if (c == 0)    return NULL_SYMBOL;  if (c == '(')    return read_two_char_escape_name();  if (c == '[' && !compatible_flag)    return read_long_escape_name();  char buf[2];  buf[0] = c;  buf[1] = '\0';  return symbol(buf);}static symbol read_increment_and_escape_name(int *incp){  int c = get_char_for_escape_name();  switch (c) {  case 0:    *incp = 0;    return NULL_SYMBOL;  case '(':    *incp = 0;    return read_two_char_escape_name();  case '+':    *incp = 1;    return read_escape_name();  case '-':    *incp = -1;    return read_escape_name();  case '[':    if (!compatible_flag) {      *incp = 0;      return read_long_escape_name();    }    break;  }  *incp = 0;  char buf[2];  buf[0] = c;  buf[1] = '\0';  return symbol(buf);}static int get_copy(node **nd, int defining){  for (;;) {    int c = input_stack::get(nd);    if (c == ESCAPE_NEWLINE) {      if (defining)	return c;      do {	c = input_stack::get(nd);      } while (c == ESCAPE_NEWLINE);    }    if (c != escape_char || escape_char <= 0)      return c;    c = input_stack::peek();    switch(c) {    case 0:      return escape_char;    case '"':      (void)input_stack::get(NULL);      while ((c = input_stack::get(NULL)) != '\n' && c != EOF)	;      return c;    case '#':			// Like \" but newline is ignored.      (void)input_stack::get(NULL);      while ((c = input_stack::get(NULL)) != '\n')	if (c == EOF)	  return EOF;      break;    case '$':      {	(void)input_stack::get(NULL);	symbol s = read_escape_name();	if (!s.is_null())	  interpolate_arg(s);	break;      }    case '*':      {	(void)input_stack::get(NULL);	symbol s = read_escape_name();	if (!s.is_null())	  interpolate_string(s);	break;      }    case 'a':      (void)input_stack::get(NULL);      return '\001';    case 'e':      (void)input_stack::get(NULL);      return ESCAPE_e;    case 'E':      (void)input_stack::get(NULL);      return ESCAPE_E;    case 'n':      {	(void)input_stack::get(NULL);	int inc;	symbol s = read_increment_and_escape_name(&inc);	if (!s.is_null())	  interpolate_number_reg(s, inc);	break;      }    case 'g':      {        (void)input_stack::get(NULL);        symbol s = read_escape_name();	if (!s.is_null())	  interpolate_number_format(s);        break;      }    case 't':      (void)input_stack::get(NULL);      return '\t';    case 'V':      {        (void)input_stack::get(NULL);	symbol s = read_escape_name();	if (!s.is_null())	  interpolate_environment_variable(s);	break;      }    case '\n':      (void)input_stack::get(NULL);      if (defining)	return ESCAPE_NEWLINE;      break;    case ' ':      (void)input_stack::get(NULL);      return ESCAPE_SPACE;    case '|':      (void)input_stack::get(NULL);      return ESCAPE_BAR;    case '^':       (void)input_stack::get(NULL);      return ESCAPE_CIRCUMFLEX;    case '{':      (void)input_stack::get(NULL);      return ESCAPE_LEFT_BRACE;    case '}':      (void)input_stack::get(NULL);      return ESCAPE_RIGHT_BRACE;    case '`':      (void)input_stack::get(NULL);      return ESCAPE_LEFT_QUOTE;    case '\'':      (void)input_stack::get(NULL);      return ESCAPE_RIGHT_QUOTE;    case '-':      (void)input_stack::get(NULL);      return ESCAPE_HYPHEN;    case '_':      (void)input_stack::get(NULL);      return ESCAPE_UNDERSCORE;    case 'c':      (void)input_stack::get(NULL);      return ESCAPE_c;    case '!':      (void)input_stack::get(NULL);      return ESCAPE_BANG;    case '?':      (void)input_stack::get(NULL);      return ESCAPE_QUESTION;    case '&':      (void)input_stack::get(NULL);      return ESCAPE_AMPERSAND;    case ')':      (void)input_stack::get(NULL);      return ESCAPE_RIGHT_PARENTHESIS;    case '.':      (void)input_stack::get(NULL);      return c;			    case '%':      (void)input_stack::get(NULL);      return ESCAPE_PERCENT;    default:      if (c == escape_char) {	(void)input_stack::get(NULL);	return c;      }      else	return escape_char;    }  }}class non_interpreted_char_node : public node {  unsigned char c;public:  non_interpreted_char_node(unsigned char);  node *copy();  int interpret(macro *);  int same(node *);  const char *type();};int non_interpreted_char_node::same(node *nd){  return c == ((non_interpreted_char_node *)nd)->c;}const char *non_interpreted_char_node::type(){  return "non_interpreted_char_node";}non_interpreted_char_node::non_interpreted_char_node(unsigned char n) : c(n){  assert(n != 0);}node *non_interpreted_char_node::copy(){  return new non_interpreted_char_node(c);}int non_interpreted_char_node::interpret(macro *mac){  mac->append(c);  return 1;}static void do_width();static node *do_non_interpreted();static node *do_special();static void do_register();static node *do_overstrike(){  token start;  overstrike_node *on = new overstrike_node;  start.next();  tok.next();  while (tok != start) {    if (tok.newline() || tok.eof()) {      warning(WARN_DELIM, "missing closing delimiter");      break;    }    charinfo *ci = tok.get_char(1);    if (ci) {      node *n = curenv->make_char_node(ci);      if (n)	on->overstrike(n);    }    tok.next();  }  return on;}static node *do_bracket(){  token start;  bracket_node *bn = new bracket_node;  start.next();  tok.next();  while (tok != start) {    if (tok.eof()) {      warning(WARN_DELIM, "missing closing delimiter");      break;    }    if (tok.newline()) {      warning(WARN_DELIM, "missing closing delimiter");      input_stack::push(make_temp_iterator("\n"));      break;    }    charinfo *ci = tok.get_char(1);    if (ci) {      node *n = curenv->make_char_node(ci);      if (n)	bn->bracket(n);    }    tok.next();  }  return bn;}static int do_name_test(){  token start;  start.next();  int start_level = input_stack::get_level();  int bad_char = 0;  int some_char = 0;  for (;;) {    tok.next();    if (tok.newline() || tok.eof()) {      warning(WARN_DELIM, "missing closing delimiter");      break;    }    if (tok == start	&& (compatible_flag || input_stack::get_level() == start_level))      break;    if (!tok.ch())      bad_char = 1;    some_char = 1;  }  return some_char && !bad_char;}#if 0static node *do_zero_width(){  token start;  start.next();  int start_level = input_stack::get_level();  environment env(curenv);  environment *oldenv = curenv;  curenv = &env;  for (;;) {    tok.next();    if (tok.newline() || tok.eof()) {      error("missing closing delimiter");      break;    }    if (tok == start	&& (compatible_flag || input_stack::get_level() == start_level))      break;    tok.process();  }  curenv = oldenv;  node *rev = env.extract_output_line();  node *n = 0;  while (rev) {    node *tem = rev;    rev = rev->next;    tem->next = n;    n = tem;  }  return new zero_width_node(n);}  #else// It's undesirable for \Z to change environments, because then// \n(.w won't work as expected.static node *do_zero_width(){  node *rev = new dummy_node;  token start;  start.next();  int start_level = input_stack::get_level();  for (;;) {    tok.next();    if (tok.newline() || tok.eof()) {      warning(WARN_DELIM, "missing closing delimiter");      break;    }    if (tok == start	&& (compatible_flag || input_stack::get_level() == start_level))      break;    if (!tok.add_to_node_list(&rev))      error("illegal token in argument to \\Z");  }  node *n = 0;  while (rev) {    node *tem = rev;    rev = rev->next;    tem->next = n;    n = tem;  }  return new zero_width_node(n);}#endiftoken_node *node::get_token_node(){  return 0;}class token_node : public node {public:  token tk;  token_node(const token &t);  node *copy();  token_node *get_token_node();  int same(node *);  const char *type();};token_node::token_node(const token &t) : tk(t){}node *token_node::copy(){  return new token_node(tk);}token_node *token_node::get_token_node(){  return this;}int token_node::same(node *nd){  return tk == ((token_node *)nd)->tk;}const char *token_node::type(){  return "token_node";}token::token() : nd(0), type(TOKEN_EMPTY){}token::~token(){  delete nd;}token::token(const token &t): nm(t.nm), c(t.c), val(t.val), dim(t.dim), type(t.type){  // Use two statements to work around bug in SGI C++.  node *tem = t.nd;  nd = tem ? tem->copy() : 0;}void token::operator=(const token &t){  delete nd;  nm = t.nm;  // Use two statements to work around bug in SGI C++.  node *tem = t.nd;  nd = tem ? tem->copy() : 0;  c = t.c;  val = t.val;  dim = t.dim;  type = t.type;}void token::skip(){  while (space())    next();}int has_arg(){  while (tok.space())    tok.next();  return !tok.newline();}void token::make_space(){  type = TOKEN_SPACE;}void token::make_newline(){  type = TOKEN_NEWLINE;}void token::next(){  if (nd) {    delete nd;    nd = 0;  }  units x;  for (;;) {    node *n;    int cc = input_stack::get(&n);    if (cc != escape_char || escape_char == 0) {    handle_normal_char:      switch(cc) {      case EOF:	type = TOKEN_EOF;	return;      case TRANSPARENT_FILE_REQUEST:      case TITLE_REQUEST:      case COPY_FILE_REQUEST:#ifdef COLUMN      case VJUSTIFY_REQUEST:#endif /* COLUMN */	type = TOKEN_REQUEST;	c = cc;	return;      case BEGIN_TRAP:	type = TOKEN_BEGIN_TRAP;	return;      case END_TRAP:	type = TOKEN_END_TRAP;	return;      case LAST_PAGE_EJECTOR:	seen_last_page_ejector = 1;	// fall through      case PAGE_EJECTOR:	type = TOKEN_PAGE_EJECTOR;	return;      case ESCAPE_PERCENT:      ESCAPE_PERCENT:	type = TOKEN_HYPHEN_INDICATOR;	return;      case ESCAPE_SPACE:      ESCAPE_SPACE:	type = TOKEN_NODE;	nd = new space_char_hmotion_node(curenv->get_space_width());	return;      case ESCAPE_e:      ESCAPE_e:	type = TOKEN_ESCAPE;	return;      case ESCAPE_E:	goto handle_escape_char;      case ESCAPE_BAR:      ESCAPE_BAR:	type = TOKEN_NODE;	nd = new hmotion_node(curenv->get_narrow_space_width());	return;      case ESCAPE_CIRCUMFLEX:      ESCAPE_CIRCUMFLEX:	type = TOKEN_NODE;	nd = new hmotion_node(curenv->get_half_narrow_space_width());	return;      case ESCAPE_NEWLINE:	break;      case ESCAPE_LEFT_BRACE:      ESCAPE_LEFT_BRACE:	type = TOKEN_LEFT_BRACE;	return;      case ESCAPE_RIGHT_BRACE:      ESCAPE_RIGHT_BRACE:	type = TOKEN_RIGHT_BRACE;	return;      case ESCAPE_LEFT_QUOTE:      ESCAPE_LEFT_QUOTE:	type = TOKEN_SPECIAL;	nm = symbol("ga");	return;      case ESCAPE_RIGHT_QUOTE:      ESCAPE_RIGHT_QUOTE:	type = TOKEN_SPECIAL;	nm = symbol("aa");	return;      case ESCAPE_HYPHEN:      ESCAPE_HYPHEN:	type = TOKEN_SPECIAL;	nm = symbol("-");	return;      case ESCAPE_UNDERSCORE:      ESCAPE_UNDERSCORE:	type = TOKEN_SPECIAL;	nm = symbol("ul");	return;      case ESCAPE_c:      ESCAPE_c:	type = TOKEN_INTERRUPT;	return;      case ESCAPE_BANG:      ESCAPE_BANG:	type = TOKEN_TRANSPARENT;	return;      case ESCAPE_QUESTION:      ESCAPE_QUESTION:	nd = do_non_interpreted();	if (nd) {	  type = TOKEN_NODE;	  return;	}	break;      case ESCAPE_AMPERSAND:      ESCAPE_AMPERSAND:	type = TOKEN_DUMMY;	return;      case ESCAPE_RIGHT_PARENTHESIS:      ESCAPE_RIGHT_PARENTHESIS:	type = TOKEN_NODE;	nd = new transparent_dummy_node;	return;      case '\b':	type = TOKEN_BACKSPACE;	return;      case ' ':	type = TOKEN_SPACE;	return;      case '\t':	type = TOKEN_TAB;	return;      case '\n':	type = TOKEN_NEWLINE;	return;      case '\001':	type = TOKEN_LEADER;	return;      case 0:	{	  assert(n != 0);	  token_node *tn = n->get_token_node();	  if (tn) {	    *this = tn->tk;	    delete tn;	  }	  else {	    nd = n;	    type = TOKEN_NODE;	  }	}	return;      default:	type = TOKEN_CHAR;	c = cc;	return;      }    }    else {    handle_escape_char:      cc = input_stack::get(NULL);      switch(cc) {      case '(':	nm = read_two_char_escape_name();	type = TOKEN_SPECIAL;	return;      case EOF:	type = TOKEN_EOF;	error("end of input after escape character");	return;      case '`':	goto ESCAPE_LEFT_QUOTE;      case '\'':	goto ESCAPE_RIGHT_QUOTE;      case '-':	goto ESCAPE_HYPHEN;      case '_':	goto ESCAPE_UNDERSCORE;      case '%':	goto ESCAPE_PERCENT;      case ' ':	goto ESCAPE_SPACE;      case '0':	nd = new hmotion_node(curenv->get_digit_width());	type = TOKEN_NODE;	return;      case '|':	goto ESCAPE_BAR;      case '^':	goto ESCAPE_CIRCUMFLEX;      case '/':	type = TOKEN_ITALIC_CORRECTION;	return;      case ',':	type = TOKEN_NODE;	nd = new left_italic_corrected_node;	return;      case '&':	goto ESCAPE_AMPERSAND;      case ')':	goto ESCAPE_RIGHT_PARENTHESIS;      case '!':	goto ESCAPE_BANG;      case '?':	goto ESCAPE_QUESTION;      case '~':	nd = new unbreakable_space_node(curenv->get_space_width());	type = TOKEN_NODE;	return;      case '"':	while ((cc = input_stack::get(NULL)) != '\n' && cc != EOF)

⌨️ 快捷键说明

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