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

📄 reg.cc

📁 早期freebsd实现
💻 CC
字号:
// -*- 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 "troff.h"#include "symbol.h"#include "dictionary.h"#include "token.h"#include "request.h"#include "reg.h"object_dictionary number_reg_dictionary(101);int reg::get_value(units * /*d*/){  return 0;}void reg::increment(){  error("can't increment read-only register");}void reg::decrement(){  error("can't decrement read-only register");}void reg::set_increment(units /*n*/){  error("can't auto increment read-only register");}void reg::alter_format(char /*f*/, int /*w*/){  error("can't alter format of read-only register");}const char *reg::get_format(){  return "0";}void reg::set_value(units /*n*/){  error("can't write read-only register");}general_reg::general_reg() : format('1'), width(0), inc(0){}static const char *number_value_to_ascii(int value, char format, int width){  static char buf[128];		// must be at least 21  switch(format) {  case '1':    if (width <= 0)      return itoa(value);    else if (width > sizeof(buf) - 2)      sprintf(buf, "%.*d", sizeof(buf) - 2, int(value));    else      sprintf(buf, "%.*d", width, int(value));    break;  case 'i':  case 'I':    {      char *p = buf;      // troff uses z and w to represent 10000 and 5000 in Roman      // numerals; I can find no historical basis for this usage      const char *s = format == 'i' ? "zwmdclxvi" : "ZWMDCLXVI";      int n = int(value);      if (n >= 40000 || n <= -40000) {	error("magnitude of `%1' too big for i or I format", n);	return itoa(n);      }      if (n == 0) {	*p++ = '0';	*p = 0;	break;      }      if (n < 0) {	*p++ = '-';	n = -n;      }      while (n >= 10000) {	*p++ = s[0];	n -= 10000;      }      for (int i = 1000; i > 0; i /= 10, s += 2) {	int m = n/i;	n -= m*i;	switch (m) {	case 3:	  *p++ = s[2];	  /* falls through */	case 2:	  *p++ = s[2];	  /* falls through */	case 1:	  *p++ = s[2];	  break;	case 4:	  *p++ = s[2];	  *p++ = s[1];	  break;	case 8:	  *p++ = s[1];	  *p++ = s[2];	  *p++ = s[2];	  *p++ = s[2];	  break;	case 7:	  *p++ = s[1];	  *p++ = s[2];	  *p++ = s[2];	  break;	case 6:	  *p++ = s[1];	  *p++ = s[2];	  break;	case 5:	  *p++ = s[1];	  break;	case 9:	  *p++ = s[2];	  *p++ = s[0];	}      }      *p = 0;      break;    }  case 'a':  case 'A':    {      int n = value;      char *p = buf;      if (n == 0) {	*p++ = '0';	*p = 0;      }      else {	if (n < 0) {	  n = -n;	  *p++ = '-';	}	// this is a bit tricky	while (n > 0) {	  int d = n % 26;	  if (d == 0)	    d = 26;	  n -= d;	  n /= 26;	  *p++ = format + d - 1;	}	*p-- = 0;	char *q = buf[0] == '-' ? buf+1 : buf;	while (q < p) {	  char temp = *q;	  *q = *p;	  *p = temp;	  --p;	  ++q;	}      }      break;    }  default:    assert(0);    break;  }  return buf;}const char *general_reg::get_string(){  units n;  if (!get_value(&n))    return "";  return number_value_to_ascii(n, format, width);}void general_reg::increment(){  int n;  if (get_value(&n))    set_value(n + inc);}void general_reg::decrement(){  int n;  if (get_value(&n))    set_value(n - inc);}void general_reg::set_increment(units n){  inc = n;}void general_reg::alter_format(char f, int w){  format = f;  width = w;}static const char *number_format_to_ascii(char format, int width){  static char buf[24];  if (format == '1') {    if (width > 0) {      int n = width;      if (n > int(sizeof(buf)) - 1)	n = int(sizeof(buf)) - 1;      sprintf(buf, "%.*d", n, 0);      return buf;    }    else      return "0";  }  else {    buf[0] = format;    buf[1] = '\0';    return buf;  }}const char *general_reg::get_format(){  return number_format_to_ascii(format, width);}class number_reg : public general_reg {  units value;public:  number_reg();  int get_value(units *);  void set_value(units);};number_reg::number_reg() : value(0){}int number_reg::get_value(units *res){  *res = value;  return 1;}void number_reg::set_value(units n){  value = n;}variable_reg::variable_reg(units *p) : ptr(p){}void variable_reg::set_value(units n){  *ptr = n;}int variable_reg::get_value(units *res){  *res = *ptr;  return 1;}void define_number_reg(){  symbol nm = get_name(1);  if (nm.is_null()) {    skip_line();    return;  }  reg *r = (reg *)number_reg_dictionary.lookup(nm);  units v;  units prev_value;  if (!r || !r->get_value(&prev_value))    prev_value = 0;  if (get_number(&v, 'u', prev_value)) {    if (r == 0) {      r = new number_reg;      number_reg_dictionary.define(nm, r);    }    r->set_value(v);    if (tok.space() && has_arg() && get_number(&v, 'u'))      r->set_increment(v);  }  skip_line();}#if 0void inline_define_reg(){  token start;  start.next();  if (!start.delimiter(1))    return;  tok.next();  symbol nm = get_name(1);  if (nm.is_null())    return;  reg *r = (reg *)number_reg_dictionary.lookup(nm);  if (r == 0) {    r = new number_reg;    number_reg_dictionary.define(nm, r);  }  units v;  units prev_value;  if (!r->get_value(&prev_value))    prev_value = 0;  if (get_number(&v, 'u', prev_value)) {    r->set_value(v);    if (start != tok) {      if (get_number(&v, 'u')) {	r->set_increment(v);	if (start != tok)	  warning(WARN_DELIM, "closing delimiter does not match");      }    }  }}#endifvoid set_number_reg(symbol nm, units n){  reg *r = (reg *)number_reg_dictionary.lookup(nm);  if (r == 0) {    r = new number_reg;    number_reg_dictionary.define(nm, r);  }  r->set_value(n);}reg *lookup_number_reg(symbol nm){  reg *r = (reg *)number_reg_dictionary.lookup(nm);  if (r == 0) {    warning(WARN_REG, "number register `%1' not defined", nm.contents());    r = new number_reg;    number_reg_dictionary.define(nm, r);  }  return r;}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();}void remove_reg(){  for (;;) {    symbol s = get_name();    if (s.is_null())      break;    number_reg_dictionary.remove(s);  }  skip_line();}void alias_reg(){  symbol s1 = get_name(1);  if (!s1.is_null()) {    symbol s2 = get_name(1);    if (!s2.is_null()) {      if (!number_reg_dictionary.alias(s1, s2))	warning(WARN_REG, "number register `%1' not defined", s2.contents());    }  }  skip_line();}void rename_reg(){  symbol s1 = get_name(1);  if (!s1.is_null()) {    symbol s2 = get_name(1);    if (!s2.is_null())      number_reg_dictionary.rename(s1, s2);  }  skip_line();}void print_number_regs(){  object_dictionary_iterator iter(number_reg_dictionary);  reg *r;  symbol s;  while (iter.get(&s, (object **)&r)) {    assert(!s.is_null());    errprint("%1\t", s.contents());    const char *p = r->get_string();    if (p)      errprint(p);    errprint("\n");  }  fflush(stderr);  skip_line();}void init_reg_requests(){  init_request("rr", remove_reg);  init_request("nr", define_number_reg);  init_request("af", alter_format);  init_request("aln", alias_reg);  init_request("rnn", rename_reg);  init_request("pnr", print_number_regs);}

⌨️ 快捷键说明

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