diff options
Diffstat (limited to 'contrib/groff/troff/reg.cc')
-rw-r--r-- | contrib/groff/troff/reg.cc | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/contrib/groff/troff/reg.cc b/contrib/groff/troff/reg.cc deleted file mode 100644 index 79e780627781..000000000000 --- a/contrib/groff/troff/reg.cc +++ /dev/null @@ -1,473 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 char uppercase_array[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', -}; - -static char lowercase_array[] = { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', -}; - -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 i_to_a(value); - else if (width > sizeof(buf) - 2) - sprintf(buf, "%.*d", int(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 i_to_a(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 == 'a' ? lowercase_array[d - 1] : - uppercase_array[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 0 -void 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"); - } - } - } -} -#endif - -void 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); -} |