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

📄 command.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "refer.h"#include "refid.h"#include "search.h"#include "command.h"cset cs_field_name = csalpha;class input_item {  input_item *next;  char *filename;  int first_lineno;  string buffer;  const char *ptr;  const char *end;public:  input_item(string &, const char *, int = 1);  ~input_item();  int get_char();  int peek_char();  void skip_char();  int get_location(const char **, int *);  friend class input_stack;};input_item::input_item(string &s, const char *fn, int ln): filename(strsave(fn)), first_lineno(ln){  buffer.move(s);  ptr = buffer.contents();  end = ptr + buffer.length();}input_item::~input_item(){  a_delete filename;}inline int input_item::peek_char(){  if (ptr >= end)    return EOF;  else    return (unsigned char)*ptr;}inline int input_item::get_char(){  if (ptr >= end)    return EOF;  else    return (unsigned char)*ptr++;}inline void input_item::skip_char(){  ptr++;}int input_item::get_location(const char **filenamep, int *linenop){  *filenamep = filename;  if (ptr == buffer.contents())    *linenop = first_lineno;  else {    int ln = first_lineno;    const char *e = ptr - 1;    for (const char *p = buffer.contents(); p < e; p++)      if (*p == '\n')	ln++;    *linenop = ln;  }  return 1;}class input_stack {  static input_item *top;public:  static void init();  static int get_char();  static int peek_char();  static void skip_char() { top->skip_char(); }  static void push_file(const char *);  static void push_string(string &, const char *, int);  static void error(const char *format,		    const errarg &arg1 = empty_errarg,		    const errarg &arg2 = empty_errarg,		    const errarg &arg3 = empty_errarg);};input_item *input_stack::top = 0;void input_stack::init(){  while (top) {    input_item *tem = top;    top = top->next;    delete tem;  }}int input_stack::get_char(){  while (top) {    int c = top->get_char();    if (c >= 0)      return c;    input_item *tem = top;    top = top->next;    delete tem;  }  return -1;}int input_stack::peek_char(){  while (top) {    int c = top->peek_char();    if (c >= 0)      return c;    input_item *tem = top;    top = top->next;    delete tem;  }  return -1;}void input_stack::push_file(const char *fn){  FILE *fp;  if (strcmp(fn, "-") == 0) {    fp = stdin;    fn = "<standard input>";  }  else {    errno = 0;    fp = fopen(fn, "r");    if (fp == 0) {      error("can't open `%1': %2", fn, strerror(errno));      return;    }  }  string buf;  int bol = 1;  int lineno = 1;  for (;;) {    int c = getc(fp);    if (bol && c == '.') {      // replace lines beginning with .R1 or .R2 with a blank line      c = getc(fp);      if (c == 'R') {	c = getc(fp);	if (c == '1' || c == '2') {	  int cc = c;	  c = getc(fp);	  if (compatible_flag || c == ' ' || c == '\n' || c == EOF) {	    while (c != '\n' && c != EOF)	      c = getc(fp);	  }	  else {	    buf += '.';	    buf += 'R';	    buf += cc;	  }	}	else {	  buf += '.';	  buf += 'R';	}      }      else	buf += '.';    }    if (c == EOF)      break;    if (illegal_input_char(c))      error_with_file_and_line(fn, lineno,			       "illegal input character code %1", int(c));    else {      buf += c;      if (c == '\n') {	bol = 1;	lineno++;      }      else	bol = 0;    }  }  if (fp != stdin)    fclose(fp);  if (buf.length() > 0 && buf[buf.length() - 1] != '\n')    buf += '\n';  input_item *it = new input_item(buf, fn);  it->next = top;  top = it;}void input_stack::push_string(string &s, const char *filename, int lineno){  input_item *it = new input_item(s, filename, lineno);  it->next = top;  top = it;}void input_stack::error(const char *format, const errarg &arg1,			const errarg &arg2, const errarg &arg3){  const char *filename;  int lineno;  for (input_item *it = top; it; it = it->next)    if (it->get_location(&filename, &lineno)) {      error_with_file_and_line(filename, lineno, format, arg1, arg2, arg3);      return;    }  ::error(format, arg1, arg2, arg3);}void command_error(const char *format, const errarg &arg1,		   const errarg &arg2, const errarg &arg3){  input_stack::error(format, arg1, arg2, arg3);}// # not recognized in ""// \<newline> is recognized in ""// # does not conceal newline// if missing closing quote, word extends to end of line// no special treatment of \ other than before newline// \<newline> not recognized after #// ; allowed as alternative to newline// ; not recognized in ""// don't clear word_buffer; just append on// return -1 for EOF, 0 for newline, 1 for wordint get_word(string &word_buffer){  int c = input_stack::get_char();  for (;;) {    if (c == '#') {      do {	c = input_stack::get_char();      } while (c != '\n' && c != EOF);      break;    }    if (c == '\\' && input_stack::peek_char() == '\n')      input_stack::skip_char();    else if (c != ' ' && c != '\t')      break;    c = input_stack::get_char();  }  if (c == EOF)    return -1;  if (c == '\n' || c == ';')    return 0;  if (c == '"') {    for (;;) {      c = input_stack::peek_char();      if (c == EOF || c == '\n')	break;      input_stack::skip_char();      if (c == '"') {	int d = input_stack::peek_char();	if (d == '"')	  input_stack::skip_char();	else	  break;      }      else if (c == '\\') {	int d = input_stack::peek_char();	if (d == '\n')	  input_stack::skip_char();	else	  word_buffer += '\\';      }      else	word_buffer += c;    }    return 1;  }  word_buffer += c;  for (;;) {    c = input_stack::peek_char();    if (c == ' ' || c == '\t' || c == '\n' || c == '#' || c == ';')      break;    input_stack::skip_char();    if (c == '\\') {      int d = input_stack::peek_char();      if (d == '\n')	input_stack::skip_char();      else	word_buffer += '\\';    }    else      word_buffer += c;  }  return 1;}union argument {  const char *s;  int n;};// This is for debugging.static void echo_command(int argc, argument *argv){  for (int i = 0; i < argc; i++)    fprintf(stderr, "%s\n", argv[i].s);}static void include_command(int argc, argument *argv){  assert(argc == 1);  input_stack::push_file(argv[0].s);}static void capitalize_command(int argc, argument *argv){  if (argc > 0)    capitalize_fields = argv[0].s;  else    capitalize_fields.clear();}static void accumulate_command(int, argument *){  accumulate = 1;}static void no_accumulate_command(int, argument *){  accumulate = 0;}static void move_punctuation_command(int, argument *){  move_punctuation = 1;}static void no_move_punctuation_command(int, argument *){  move_punctuation = 0;}static void sort_command(int argc, argument *argv){  if (argc == 0)    sort_fields = "AD";  else    sort_fields = argv[0].s;  accumulate = 1;}static void no_sort_command(int, argument *){  sort_fields.clear();}static void articles_command(int argc, argument *argv){  articles.clear();  int i;  for (i = 0; i < argc; i++) {    articles += argv[i].s;    articles += '\0';  }  int len = articles.length();  for (i = 0; i < len; i++)    articles[i] = cmlower(articles[i]);}static void database_command(int argc, argument *argv){  for (int i = 0; i < argc; i++)    database_list.add_file(argv[i].s);}static void default_database_command(int, argument *){  search_default = 1;}static void no_default_database_command(int, argument *)

⌨️ 快捷键说明

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