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

📄 input.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
      {	unsigned char ch = tok.c;	if (bol && 	    (ch == curenv->control_char	     || ch == curenv->no_break_control_char)) {	  break_flag = ch == curenv->control_char;	  // skip tabs as well as spaces here	  do {	    tok.next();	  } while (tok.white_space());	  symbol nm = get_name();	  if (nm.is_null())	    skip_line();	  else	    interpolate_macro(nm);	  suppress_next = 1;	}	else {	  if (possibly_handle_first_page_transition())	    ;	  else {	    for (;;) {	      curenv->add_char(charset_table[ch]);	      tok.next();	      if (tok.type != token::TOKEN_CHAR)		break;	      ch = tok.c;	    }	    suppress_next = 1;	    bol = 0;	  }	}	break;      }    case token::TOKEN_TRANSPARENT:      {	if (bol) {	  if (possibly_handle_first_page_transition())	    ;	  else {	    int cc;	    do {	      node *n;	      cc = get_copy(&n);	      if (cc != EOF)		if (cc != '\0')		  curdiv->transparent_output(transparent_translate(cc));		else		  curdiv->transparent_output(n);	    } while (cc != '\n' && cc != EOF);	    if (cc == EOF)	      curdiv->transparent_output('\n');	  }	}	break;      }    case token::TOKEN_NEWLINE:      {	if (bol && !curenv->get_prev_line_interrupted())	  blank_line();	else {	  curenv->newline();	  bol = 1;	}	break;      }    case token::TOKEN_REQUEST:      {	int request_code = tok.c;	tok.next();	switch (request_code) {	case TITLE_REQUEST:	  title();	  break;	case COPY_FILE_REQUEST:	  copy_file();	  break;	case TRANSPARENT_FILE_REQUEST:	  transparent_file();	  break;#ifdef COLUMN	case VJUSTIFY_REQUEST:	  vjustify();	  break;#endif /* COLUMN */	default:	  assert(0);	  break;	}	suppress_next = 1;	break;      }    case token::TOKEN_SPACE:      {	if (possibly_handle_first_page_transition())	  ;	else if (bol && !curenv->get_prev_line_interrupted()) {	  int nspaces = 0;	  do {	    nspaces += tok.nspaces();	    tok.next();	  } while (tok.space());	  if (tok.newline())	    blank_line();	  else {	    push_token(tok);	    curenv->do_break();	    curenv->add_node(new hmotion_node(curenv->get_space_width()*nspaces));	    bol = 0;	  }	}	else {	  curenv->space();	  bol = 0;	}	break;      }    case token::TOKEN_EOF:      return;    case token::TOKEN_NODE:      {	if (possibly_handle_first_page_transition())	  ;	else if (tok.nd->reread(&bol)) {	  delete tok.nd;	  tok.nd = 0;	}	else {	  curenv->add_node(tok.nd);	  tok.nd = 0;	  bol = 0;	}	break;      }    case token::TOKEN_PAGE_EJECTOR:      {	continue_page_eject();	// I think we just want to preserve bol.	// bol = 1;	break;      }    case token::TOKEN_BEGIN_TRAP:      {	trap_bol_stack.push(bol);	bol = 1;	break;      }    case token::TOKEN_END_TRAP:      {	if (trap_bol_stack.is_empty())	  error("spurious end trap token detected!");	else	  bol = trap_bol_stack.pop();	/* I'm not totally happy about this.  But I can't think of any other	  way to do it.  Doing an output_pending_lines() whenever a	  TOKEN_END_TRAP is detected doesn't work: for example,          .wh -1i x          .de x          'bp	  ..	  .wh -.5i y	  .de y	  .tl ''-%-''	  ..	  .br	  .ll .5i	  .sp |\n(.pu-1i-.5v	  a\%very\%very\%long\%word          will print all but the first lines from the word immediately          after the footer, rather than on the next page. */	if (trap_bol_stack.is_empty())	  curenv->output_pending_lines();	break;      }    default:      {	bol = 0;	tok.process();	break;      }    }    if (!suppress_next)      tok.next();    trap_sprung_flag = 0;  }}#ifdef WIDOW_CONTROLvoid flush_pending_lines(){  while (!tok.newline() && !tok.eof())    tok.next();  curenv->output_pending_lines();  tok.next();}#endif /* WIDOW_CONTROL */request_or_macro::request_or_macro(){}macro *request_or_macro::to_macro(){  return 0;}request::request(REQUEST_FUNCP pp) : p(pp){}void request::invoke(symbol){  (*p)();}struct char_block {  enum { SIZE = 128 };  unsigned char s[SIZE];  char_block *next;  char_block();};char_block::char_block(): next(0){}class char_list {public:  char_list();  ~char_list();  void append(unsigned char);  int length();private:  unsigned char *ptr;  int len;  char_block *head;  char_block *tail;  friend class macro_header;  friend class string_iterator;};char_list::char_list(): head(0), tail(0), ptr(0), len(0){}char_list::~char_list(){  while (head != 0) {    char_block *tem = head;    head = head->next;    delete tem;  }}int char_list::length(){  return len;}void char_list::append(unsigned char c){  if (tail == 0) {    head = tail = new char_block;    ptr = tail->s;  }  else {    if (ptr >= tail->s + char_block::SIZE) {      tail->next = new char_block;      tail = tail->next;      ptr = tail->s;    }  }  *ptr++ = c;  len++;}class node_list {  node *head;  node *tail;public:  node_list();  ~node_list();  void append(node *);  int length();  node *extract();  friend class macro_header;  friend class string_iterator;};void node_list::append(node *n){  if (head == 0) {    n->next = 0;    head = tail = n;  }  else {    n->next = 0;    tail = tail->next = n;  }}int node_list::length(){  int total = 0;  for (node *n = head; n != 0; n = n->next)    ++total;  return total;}node_list::node_list(){  head = tail = 0;}node *node_list::extract(){  node *temp = head;  head = tail = 0;  return temp;}node_list::~node_list(){  delete_node_list(head);}struct macro_header {  int count;  char_list cl;  node_list nl;  macro_header() { count = 1; }  macro_header *copy(int);};macro::~macro() {   if (p != 0 && --(p->count) <= 0)     delete p;}macro::macro(){  if (!input_stack::get_location(1, &filename, &lineno)) {    filename = 0;    lineno = 0;  }  length = 0;  p = 0;}macro::macro(const macro &m) : filename(m.filename), lineno(m.lineno), p(m.p), length(m.length){   if (p != 0)    p->count++;}macro &macro::operator=(const macro &m){  // don't assign object  if (m.p != 0)    m.p->count++;  if (p != 0 && --(p->count) <= 0)     delete p;   p = m.p;   filename = m.filename;  lineno = m.lineno;  length = m.length;  return *this;}void macro::append(unsigned char c){  assert(c != 0);  if (p == 0)    p = new macro_header;  if (p->cl.length() != length) {    macro_header *tem = p->copy(length);    if (--(p->count) <= 0)      delete p;    p = tem;  }  p->cl.append(c);  ++length;}void macro::append(node *n){  assert(n != 0);  if (p == 0)    p = new macro_header;  if (p->cl.length() != length) {    macro_header *tem = p->copy(length);    if (--(p->count) <= 0)      delete p;    p = tem;  }  p->cl.append(0);  p->nl.append(n);  ++length;}void macro::print_size(){  errprint("%1", length);}// make a copy of the first n bytesmacro_header *macro_header::copy(int n){  macro_header *p = new macro_header;  char_block *bp = cl.head;  unsigned char *ptr = bp->s;  node *nd = nl.head;  while (--n >= 0) {    if (ptr >= bp->s + char_block::SIZE) {      bp = bp->next;      ptr = bp->s;    }    int c = *ptr++;    p->cl.append(c);    if (c == 0) {      p->nl.append(nd->copy());      nd = nd->next;    }  }  return p;}void print_macros(){  object_dictionary_iterator iter(request_dictionary);  request_or_macro *rm;  symbol s;  while (iter.get(&s, (object **)&rm)) {    assert(!s.is_null());    macro *m = rm->to_macro();    if (m) {      errprint("%1\t", s.contents());      m->print_size();      errprint("\n");    }  }  fflush(stderr);  skip_line();}class string_iterator : public input_iterator {  macro mac;  const char *how_invoked;  int newline_flag;  int lineno;  char_block *bp;  int count;			// of characters remaining  node *nd;protected:  symbol nm;  string_iterator();public:  string_iterator(const macro &m, const char *p = 0, symbol s = NULL_SYMBOL);  int fill(node **);  int peek();  int get_location(int, const char **, int *);  void backtrace();};string_iterator::string_iterator(const macro &m, const char *p, symbol s) : lineno(1), mac(m), newline_flag(0), how_invoked(p), nm(s){  count = mac.length;  if (count != 0) {    bp = mac.p->cl.head;    nd = mac.p->nl.head;    ptr = eptr = bp->s;  }  else {    bp = 0;    nd = 0;    ptr = eptr = 0;  }}string_iterator::string_iterator(){  bp = 0;  nd = 0;  ptr = eptr = 0;  newline_flag = 0;  how_invoked = 0;  lineno = 1;  count = 0;}int string_iterator::fill(node **np){  if (newline_flag)    lineno++;  newline_flag = 0;  if (count <= 0)    return EOF;  const unsigned char *p = eptr;  if (p >= bp->s + char_block::SIZE) {    bp = bp->next;    p = bp->s;  }  if (*p == '\0') {    if (np)      *np = nd->copy();    nd = nd->next;    eptr = ptr = p + 1;    count--;    return 0;  }  const unsigned char *e = bp->s + char_block::SIZE;  if (e - p > count)    e = p + count;  ptr = p;  while (p < e) {    unsigned char c = *p;    if (c == '\n' || c == ESCAPE_NEWLINE) {      newline_flag = 1;      p++;      break;    }    if (c == '\0')      break;    p++;  }  eptr = p;  count -= p - ptr;  return *ptr++;}int string_iterator::peek(){  if (count <= 0)    return EOF;  const unsigned char *p = eptr;  if (count <= 0)    return EOF;  if (p >= bp->s + char_block::SIZE) {    p = bp->next->s;  }  return *p;}int string_iterator::get_location(int allow_macro,				  const char **filep, int *linep){  if (!allow_macro)    return 0;  if (mac.filename == 0)    return 0;  *filep = mac.filename;  *linep = mac.lineno + lineno - 1;  return 1;}void string_iterator::backtrace(){  if (mac.filename) {    errprint("%1:%2: backtrace", mac.filename, mac.lineno + lineno - 1);    if (how_invoked) {      if (!nm.is_null())	errprint(": %1 `%2'\n", how_invoked, nm.contents());      else	errprint(": %1\n", how_invoked);    }    else      errprint("\n");  }}class temp_iterator : public input_iterator {  unsigned char *base;  temp_iterator(const char *, int len);public:  ~temp_iterator();  friend input_iterator *make_temp_iterator(const char *);};#ifdef __GNUG__inline#endiftemp_iterator::temp_iterator(const char *s, int len){  base = new unsigned char[len];  memcpy(base, s, len);  ptr = base;  eptr = base + len;}temp_iterator::~temp_iterator(){  a_delete base;}class small_temp_iterator : public input_iterator {private:  small_temp_iterator(const char *, int);  ~small_temp_iterator();  enum { BLOCK = 16 };  static small_temp_iterator *free_list;  void *operator new(size_t);  void operator delete(void *);  enum { SIZE = 12 };  unsigned char buf[SIZE];  friend input_iterator *make_temp_iterator(const char *);};small_temp_iterator *small_temp_iterator::free_list = 0;void *small_temp_iterator::operator new(size_t n){  assert(n == sizeof(small_temp_iterator));  if (!free_list) {    free_list = (small_temp_iterator *)new char[sizeof(small_temp_iterator)*BLOCK];    for (int i = 0; i < BLOCK - 1; i++)      free_list[i].next = free_list + i + 1;    free_list[BLOCK-1].next = 0;  }  small_temp_iterator *p = free_list;  free_list = (small_temp_iterator *)(free_list->next);  p->next = 0;  return p;}#ifdef __GNUG__inline#endifvoid small_temp_iterator::operator delete(void *p){  if (p) {    ((small_temp_iterator *)p)->next = free_list;    free_list = (small_temp_iterator *)p;  }}small_temp_iterator::~small_temp_iterator(){}#ifdef __GNUG__inline#endifsmall_temp_iterator::small_temp_iterator(const char *s, int len){  for (int i = 0; i < len; i++)    buf[i] = s[i];  ptr = buf;  eptr = buf + len;}input_iterator *make_temp_iterator(const char *s){

⌨️ 快捷键说明

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