diff options
author | wl <wl> | 2004-09-27 06:09:39 +0000 |
---|---|---|
committer | wl <wl> | 2004-09-27 06:09:39 +0000 |
commit | 57788613c9a22bd23178938a9b5797ca4c7b1ea0 (patch) | |
tree | ce8988ddf7e97403f5817ee6955c5e46c3eb76a6 /src | |
parent | 0d9052d57cd6c3cf98b8a5f10a0b114b424df2e1 (diff) | |
download | groff-57788613c9a22bd23178938a9b5797ca4c7b1ea0.tar.gz |
Fix \$@ and \$* to handle any number of arguments.
* src/roff/troff/input.h (BEGIN_QUOTE, END_QUOTE): New special
characters.
* src/roff/troff/input.cpp (input_iterator::internal_level):
Removed.
(input_stack): New member functions `increase_level' and
`decrease_level'.
(input_stack::get_level): Don't use `internal_level'.
(get_copy, token::next): Handle BEGIN_QUOTE and END_QUOTE.
(end_quote_iterator): Completely removed.
(interpolate_arg): Build string for \$@ and \$* which is then
pushed onto the input stack.
Diffstat (limited to 'src')
-rw-r--r-- | src/roff/troff/input.cpp | 87 | ||||
-rw-r--r-- | src/roff/troff/input.h | 4 |
2 files changed, 61 insertions, 30 deletions
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 5ad1c745..70340d7c 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -214,7 +214,6 @@ private: virtual int next_file(FILE *, const char *) { return 0; } virtual void shift(int) {} virtual int is_boundary() {return 0; } - virtual int internal_level() { return 0; } virtual int is_file() { return 0; } virtual int is_macro() { return 0; } virtual void save_compatible_flag(int) {} @@ -416,6 +415,8 @@ public: static int is_return_boundary(); static void remove_boundary(); static int get_level(); + static void increase_level(); + static void decrease_level(); static void clear(); static void pop_macro(); static void save_compatible_flag(int); @@ -436,7 +437,17 @@ int input_stack::limit = DEFAULT_INPUT_STACK_LIMIT; inline int input_stack::get_level() { - return level + top->internal_level(); + return level; +} + +inline void input_stack::increase_level() +{ + level++; +} + +inline void input_stack::decrease_level() +{ + level--; } inline int input_stack::get(node **np) @@ -850,6 +861,14 @@ static int get_copy(node **nd, int defining) compatible_flag = input_stack::get_compatible_flag(); continue; } + if (c == BEGIN_QUOTE) { + input_stack::increase_level(); + continue; + } + if (c == END_QUOTE) { + input_stack::decrease_level(); + continue; + } if (c == ESCAPE_NEWLINE) { if (defining) return c; @@ -1584,6 +1603,12 @@ void token::next() case POP_GROFFCOMP_MODE: compatible_flag = input_stack::get_compatible_flag(); continue; + case BEGIN_QUOTE: + input_stack::increase_level(); + continue; + case END_QUOTE: + input_stack::decrease_level(); + continue; case EOF: type = TOKEN_EOF; return; @@ -4029,26 +4054,6 @@ static void interpolate_string_with_args(symbol s) } } -/* This class is used for the implementation of \$@. It is used for -each of the closing double quotes. It artificially increases the -input level by 2, so that the closing double quote will appear to have -the same input level as the opening quote. */ - -class end_quote_iterator : public input_iterator { - unsigned char buf[1]; -public: - end_quote_iterator(); - ~end_quote_iterator() { } - int internal_level() { return 2; } -}; - -end_quote_iterator::end_quote_iterator() -{ - buf[0] = '"'; - ptr = buf; - eptr = buf + 1; -} - static void interpolate_arg(symbol nm) { const char *s = nm.contents(); @@ -4057,17 +4062,39 @@ static void interpolate_arg(symbol nm) else if (s[1] == 0 && csdigit(s[0])) input_stack::push(input_stack::get_arg(s[0] - '0')); else if (s[0] == '*' && s[1] == '\0') { - for (int i = input_stack::nargs(); i > 0; i--) { - input_stack::push(input_stack::get_arg(i)); - if (i != 1) - input_stack::push(make_temp_iterator(" ")); + int limit = input_stack::nargs(); + string args; + for (int i = 1; i <= limit; i++) { + input_iterator *p = input_stack::get_arg(i); + int c; + while ((c = p->get(0)) != EOF) + args += c; + if (i != limit) + args += ' '; + } + if (limit > 0) { + args += '\0'; + input_stack::push(make_temp_iterator(args.contents())); } } else if (s[0] == '@' && s[1] == '\0') { - for (int i = input_stack::nargs(); i > 0; i--) { - input_stack::push(new end_quote_iterator); - input_stack::push(input_stack::get_arg(i)); - input_stack::push(make_temp_iterator(i == 1 ? "\"" : " \"")); + int limit = input_stack::nargs(); + string args; + for (int i = 1; i <= limit; i++) { + args += '"'; + args += BEGIN_QUOTE; + input_iterator *p = input_stack::get_arg(i); + int c; + while ((c = p->get(0)) != EOF) + args += c; + args += END_QUOTE; + args += '"'; + if (i != limit) + args += ' '; + } + if (limit > 0) { + args += '\0'; + input_stack::push(make_temp_iterator(args.contents())); } } else { diff --git a/src/roff/troff/input.h b/src/roff/troff/input.h index 59f9e005..aaaa70bd 100644 --- a/src/roff/troff/input.h +++ b/src/roff/troff/input.h @@ -57,6 +57,8 @@ const int ESCAPE_COLON = 0210; const int PUSH_GROFF_MODE = 0211; const int PUSH_COMP_MODE = 0212; const int POP_GROFFCOMP_MODE = 0213; +const int BEGIN_QUOTE = 0214; +const int END_QUOTE = 0215; #else /* IS_EBCDIC_HOST */ @@ -94,6 +96,8 @@ const int ESCAPE_COLON = 070; const int PUSH_GROFF_MODE = 071; const int PUSH_COMP_MODE = 072; const int POP_GROFFCOMP_MODE = 073; +const int BEGIN_QUOTE = 074; +const int END_QUOTE = 075; #endif /* IS_EBCDIC_HOST */ |