diff options
author | ru <ru@FreeBSD.org> | 2000-12-05 18:49:44 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2000-12-05 18:49:44 +0000 |
commit | 7c20aabe3d743227b595c80f68ddd7437f1fe991 (patch) | |
tree | 1cc7fdea840e261aeaa58a7fbfccbac65d3becf0 /contrib/groff/troff | |
parent | 580d412c4db23b27cbf5c5e6fb9e2881c00be47b (diff) | |
parent | a812d8b090bc4edc23150bff257717b24f282e41 (diff) | |
download | FreeBSD-src-7c20aabe3d743227b595c80f68ddd7437f1fe991.zip FreeBSD-src-7c20aabe3d743227b595c80f68ddd7437f1fe991.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r69626,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/groff/troff')
-rw-r--r-- | contrib/groff/troff/Makefile.sub | 51 | ||||
-rw-r--r-- | contrib/groff/troff/TODO | 4 | ||||
-rw-r--r-- | contrib/groff/troff/charinfo.h | 6 | ||||
-rw-r--r-- | contrib/groff/troff/column.cc | 4 | ||||
-rw-r--r-- | contrib/groff/troff/dictionary.cc | 2 | ||||
-rw-r--r-- | contrib/groff/troff/div.cc | 35 | ||||
-rw-r--r-- | contrib/groff/troff/env.cc | 217 | ||||
-rw-r--r-- | contrib/groff/troff/env.h | 1 | ||||
-rw-r--r-- | contrib/groff/troff/input.cc | 373 | ||||
-rw-r--r-- | contrib/groff/troff/node.cc | 94 | ||||
-rw-r--r-- | contrib/groff/troff/node.h | 3 | ||||
-rw-r--r-- | contrib/groff/troff/reg.cc | 25 | ||||
-rw-r--r-- | contrib/groff/troff/request.h | 2 | ||||
-rw-r--r-- | contrib/groff/troff/token.h | 6 |
14 files changed, 669 insertions, 154 deletions
diff --git a/contrib/groff/troff/Makefile.sub b/contrib/groff/troff/Makefile.sub index dc67031..342ad59 100644 --- a/contrib/groff/troff/Makefile.sub +++ b/contrib/groff/troff/Makefile.sub @@ -2,27 +2,54 @@ PROG=troff MAN1=troff.n XLIBS=$(LIBGROFF) MLIB=$(LIBM) -OBJS=env.o node.o input.o div.o symbol.o dictionary.o reg.o \ - number.o majorminor.o -CCSRCS=env.cc node.cc input.cc div.cc symbol.cc dictionary.cc reg.cc \ - number.cc majorminor.cc -HDRS=charinfo.h dictionary.h div.h env.h hvunits.h node.h reg.h request.h \ - symbol.h token.h troff.h +OBJS=\ + env.o \ + node.o \ + input.o \ + div.o \ + symbol.o \ + dictionary.o \ + reg.o \ + number.o \ + majorminor.o +CCSRCS=\ + $(srcdir)/env.cc \ + $(srcdir)/node.cc \ + $(srcdir)/input.cc \ + $(srcdir)/div.cc \ + $(srcdir)/symbol.cc \ + $(srcdir)/dictionary.cc \ + $(srcdir)/reg.cc \ + $(srcdir)/number.cc \ + majorminor.cc +HDRS=\ + $(srcdir)/charinfo.h \ + $(srcdir)/dictionary.h \ + $(srcdir)/div.h \ + $(srcdir)/env.h \ + $(srcdir)/hvunits.h \ + $(srcdir)/node.h \ + $(srcdir)/reg.h \ + $(srcdir)/request.h \ + $(srcdir)/symbol.h \ + $(srcdir)/token.h \ + $(srcdir)/troff.h GENSRCS=majorminor.cc NAMEPREFIX=$(g) -majorminor.cc: ../VERSION +majorminor.cc: $(top_srcdir)/VERSION $(top_srcdir)/REVISION @echo Making $@ @-rm -f $@ @echo const char \*major_version = \ - \"`sed -e 's/^\([^.]*\)\..*$$/\1/' $(srcdir)/../VERSION`\"\; >$@ + \"`sed -e 's/^\([^.]*\)\..*$$/\1/' $(top_srcdir)/VERSION`\"\; >$@ @echo const char \*minor_version = \ - \"`sed -e 's/^[^.]*\.\([0-9]*\).*$$/\1/' $(srcdir)/../VERSION`\"\; >>$@ + \"`sed -e 's/^[^.]*\.\([0-9]*\).*$$/\1/' $(top_srcdir)/VERSION`\"\; >>$@ + @echo const char \*revision = \"`cat $(top_srcdir)/REVISION`\"\; >>$@ install_data: hyphen.us - -test -d $(datadir) || mkdir $(datadir) - -test -d $(datasubdir) || mkdir $(datasubdir) - -test -d $(tmacdir) || mkdir $(tmacdir) + -test -d $(datadir) || $(mkinstalldirs) $(datadir) + -test -d $(datasubdir) || $(mkinstalldirs) $(datasubdir) + -test -d $(tmacdir) || $(mkinstalldirs) $(tmacdir) -rm -f $(tmacdir)/hyphen.us $(INSTALL_DATA) $(srcdir)/hyphen.us $(tmacdir)/hyphen.us diff --git a/contrib/groff/troff/TODO b/contrib/groff/troff/TODO index 7e51123..3e6480b 100644 --- a/contrib/groff/troff/TODO +++ b/contrib/groff/troff/TODO @@ -77,8 +77,6 @@ Then is you ask for R at pointsize 16, groff will first look for R.display and then R. Probably necessary to be able to specify a separate unitwidth for each sizesuffix (eg. for X). -Request to copy an environment into the current environment. - Variant of `.it' for which a line interrupted with \c counts as one input line. @@ -105,7 +103,7 @@ optionally print the contents of a macro. Provide some way to round numbers to multiples of the current horizontal or vertical resolution. -Better string-processing support (substring, length, search). +Better string-processing support (search). Generalized ligatures. diff --git a/contrib/groff/troff/charinfo.h b/contrib/groff/troff/charinfo.h index 9979d37..a4ecd57 100644 --- a/contrib/groff/troff/charinfo.h +++ b/contrib/groff/troff/charinfo.h @@ -74,6 +74,7 @@ public: void set_number(int); int get_number(); int numbered(); + symbol *get_symbol(); }; charinfo *get_charinfo(symbol); @@ -163,3 +164,8 @@ inline int charinfo::first_time_not_found() return 1; } } + +inline symbol *charinfo::get_symbol() +{ + return( &nm ); +} diff --git a/contrib/groff/troff/column.cc b/contrib/groff/troff/column.cc index fce389d..096f381 100644 --- a/contrib/groff/troff/column.cc +++ b/contrib/groff/troff/column.cc @@ -624,7 +624,7 @@ public: const char *column_bottom_reg::get_string() { - return itoa(the_column->get_bottom().to_units()); + return i_to_a(the_column->get_bottom().to_units()); } class column_extra_space_reg : public reg { @@ -634,7 +634,7 @@ public: const char *column_extra_space_reg::get_string() { - return itoa(the_column->get_last_extra_space().to_units()); + return i_to_a(the_column->get_last_extra_space().to_units()); } class column_active_reg : public reg { diff --git a/contrib/groff/troff/dictionary.cc b/contrib/groff/troff/dictionary.cc index fc71e3c..169536c 100644 --- a/contrib/groff/troff/dictionary.cc +++ b/contrib/groff/troff/dictionary.cc @@ -38,7 +38,7 @@ static int is_good_size(int p) return 1; } -dictionary::dictionary(int n) : threshold(0.5), factor(1.5), used(0), size(n) +dictionary::dictionary(int n) : size(n), used(0), threshold(0.5), factor(1.5) { table = new association[n]; } diff --git a/contrib/groff/troff/div.cc b/contrib/groff/troff/div.cc index e5b4b58..013ea66 100644 --- a/contrib/groff/troff/div.cc +++ b/contrib/groff/troff/div.cc @@ -48,7 +48,7 @@ static vunits truncated_space; static vunits needed_space; diversion::diversion(symbol s) -: nm(s), prev(0), vertical_position(V0), marked_place(V0), high_water_mark(V0) +: prev(0), nm(s), vertical_position(V0), high_water_mark(V0), marked_place(V0) { } @@ -235,8 +235,7 @@ void macro_diversion::output(node *nd, int retain_size, mac->append(temp); } } - if (!v.post_extra.is_zero()) - last_post_line_extra_space = v.post_extra.to_units(); + last_post_line_extra_space = v.post_extra.to_units(); if (!retain_size) { v.pre = vs; v.post = post_vs; @@ -284,10 +283,11 @@ void macro_diversion::copy_file(const char *filename) } top_level_diversion::top_level_diversion() -: page_count(0), have_next_page_number(0), page_length(units_per_inch*11), - page_offset(units_per_inch), prev_page_offset(units_per_inch), - ejecting_page(0), page_trap_list(0), before_first_page(1), no_space_mode(0), - page_number(0), last_page_count(-1) +: page_number(0), page_count(0), last_page_count(-1), + page_length(units_per_inch*11), + prev_page_offset(units_per_inch), page_offset(units_per_inch), + page_trap_list(0), have_next_page_number(0), + ejecting_page(0), before_first_page(1), no_space_mode(0) { } @@ -338,8 +338,7 @@ void top_level_diversion::output(node *nd, int retain_size, vertical_size v(vs, post_vs); for (node *tem = nd; tem != 0; tem = tem->next) tem->set_vertical_size(&v); - if (!v.post_extra.is_zero()) - last_post_line_extra_space = v.post_extra.to_units(); + last_post_line_extra_space = v.post_extra.to_units(); if (!retain_size) { v.pre = vs; v.post = post_vs; @@ -437,7 +436,7 @@ void top_level_diversion::space(vunits n, int forced) } trap::trap(symbol s, vunits n, trap *p) - : nm(s), next(p), position(n) + : next(p), position(n), nm(s) { } @@ -914,7 +913,7 @@ int page_offset_reg::get_value(units *res) const char *page_offset_reg::get_string() { - return itoa(topdiv->get_page_offset().to_units()); + return i_to_a(topdiv->get_page_offset().to_units()); } class page_length_reg : public reg { @@ -931,7 +930,7 @@ int page_length_reg::get_value(units *res) const char *page_length_reg::get_string() { - return itoa(topdiv->get_page_length().to_units()); + return i_to_a(topdiv->get_page_length().to_units()); } class vertical_position_reg : public reg { @@ -954,7 +953,7 @@ const char *vertical_position_reg::get_string() if (curdiv == topdiv && topdiv->before_first_page) return "-1"; else - return itoa(curdiv->get_vertical_position().to_units()); + return i_to_a(curdiv->get_vertical_position().to_units()); } class high_water_mark_reg : public reg { @@ -971,7 +970,7 @@ int high_water_mark_reg::get_value(units *res) const char *high_water_mark_reg::get_string() { - return itoa(curdiv->get_high_water_mark().to_units()); + return i_to_a(curdiv->get_high_water_mark().to_units()); } class distance_to_next_trap_reg : public reg { @@ -988,7 +987,7 @@ int distance_to_next_trap_reg::get_value(units *res) const char *distance_to_next_trap_reg::get_string() { - return itoa(curdiv->distance_to_next_trap().to_units()); + return i_to_a(curdiv->distance_to_next_trap().to_units()); } class diversion_name_reg : public reg { @@ -1030,7 +1029,7 @@ public: const char *next_page_number_reg::get_string() { - return itoa(topdiv->get_next_page_number()); + return i_to_a(topdiv->get_next_page_number()); } class page_ejecting_reg : public reg { @@ -1040,7 +1039,7 @@ public: const char *page_ejecting_reg::get_string() { - return itoa(topdiv->get_ejecting()); + return i_to_a(topdiv->get_ejecting()); } class constant_vunits_reg : public reg { @@ -1056,7 +1055,7 @@ constant_vunits_reg::constant_vunits_reg(vunits *q) : p(q) const char *constant_vunits_reg::get_string() { - return itoa(p->to_units()); + return i_to_a(p->to_units()); } class nl_reg : public variable_reg { diff --git a/contrib/groff/troff/env.cc b/contrib/groff/troff/env.cc index 07093b0..fbea78e 100644 --- a/contrib/groff/troff/env.cc +++ b/contrib/groff/troff/env.cc @@ -195,7 +195,7 @@ int font_size::nranges = 0; extern "C" { -static int compare_ranges(const void *p1, const void *p2) +int compare_ranges(const void *p1, const void *p2) { return ((size_range *)p1)->min - ((size_range *)p2)->min; } @@ -430,6 +430,7 @@ void environment::set_font(symbol nm) prev_fontno = tem; } else { + prev_fontno = fontno; int n = symbol_fontno(nm); if (n < 0) { n = next_available_font_position(); @@ -438,7 +439,6 @@ void environment::set_font(symbol nm) } if (family->make_definite(n) < 0) return; - prev_fontno = fontno; fontno = n; } } @@ -511,7 +511,7 @@ void environment::set_char_slant(int n) } environment::environment(symbol nm) -: name(nm), +: dummy(0), prev_line_length((units_per_inch*13)/2), line_length((units_per_inch*13)/2), prev_title_length((units_per_inch*13)/2), @@ -538,45 +538,45 @@ environment::environment(symbol nm) line_spacing(1), prev_indent(0), indent(0), - have_temporary_indent(0), temporary_indent(0), + have_temporary_indent(0), underline_lines(0), input_trap_count(0), + line(0), prev_text_length(0), width_total(0), space_total(0), input_line_start(0), - control_char('.'), - no_break_control_char('\''), - hyphen_indicator_char(0), - spread_flag(0), - line(0), - pending_lines(0), - discarding(0), tabs(units_per_inch/2, TAB_LEFT), current_tab(TAB_NONE), + leader_node(0), + tab_char(0), + leader_char(charset_table['.']), current_field(0), + discarding(0), + spread_flag(0), margin_character_flags(0), margin_character_node(0), margin_character_distance(points_to_units(10)), numbering_nodes(0), number_text_separation(1), - line_number_multiple(1), line_number_indent(0), + line_number_multiple(1), no_number_count(0), - tab_char(0), - leader_char(charset_table['.']), hyphenation_flags(1), - dummy(0), - leader_node(0), -#ifdef WIDOW_CONTROL - widow_control(0), -#endif /* WIDOW_CONTROL */ hyphen_line_count(0), hyphen_line_max(-1), hyphenation_space(H0), hyphenation_margin(H0), - composite(0) + composite(0), + pending_lines(0), +#ifdef WIDOW_CONTROL + widow_control(0), +#endif /* WIDOW_CONTROL */ + name(nm), + control_char('.'), + no_break_control_char('\''), + hyphen_indicator_char(0) { prev_family = family = lookup_family(default_family); prev_fontno = fontno = 1; @@ -588,17 +588,21 @@ environment::environment(symbol nm) } environment::environment(const environment *e) -: name(e->name), // so that eg `.if "\n[.ev]"0"' works +: dummy(1), prev_line_length(e->prev_line_length), line_length(e->line_length), prev_title_length(e->prev_title_length), title_length(e->title_length), prev_size(e->prev_size), size(e->size), - prev_requested_size(e->prev_requested_size), requested_size(e->requested_size), + prev_requested_size(e->prev_requested_size), char_height(e->char_height), char_slant(e->char_slant), + prev_fontno(e->prev_fontno), + fontno(e->fontno), + prev_family(e->prev_family), + family(e->family), space_size(e->space_size), sentence_space_size(e->sentence_space_size), adjust_mode(e->adjust_mode), @@ -615,50 +619,119 @@ environment::environment(const environment *e) line_spacing(e->line_spacing), prev_indent(e->prev_indent), indent(e->indent), - have_temporary_indent(0), temporary_indent(0), + have_temporary_indent(0), underline_lines(0), input_trap_count(0), + line(0), prev_text_length(e->prev_text_length), width_total(0), space_total(0), input_line_start(0), - control_char(e->control_char), - no_break_control_char(e->no_break_control_char), - hyphen_indicator_char(e->hyphen_indicator_char), - spread_flag(0), - line(0), - pending_lines(0), - discarding(0), tabs(e->tabs), current_tab(TAB_NONE), + leader_node(0), + tab_char(e->tab_char), + leader_char(e->leader_char), current_field(0), + discarding(0), + spread_flag(0), margin_character_flags(e->margin_character_flags), margin_character_node(e->margin_character_node), margin_character_distance(e->margin_character_distance), numbering_nodes(0), number_text_separation(e->number_text_separation), - line_number_multiple(e->line_number_multiple), line_number_indent(e->line_number_indent), + line_number_multiple(e->line_number_multiple), no_number_count(e->no_number_count), - tab_char(e->tab_char), - leader_char(e->leader_char), hyphenation_flags(e->hyphenation_flags), - fontno(e->fontno), - prev_fontno(e->prev_fontno), - dummy(1), - family(e->family), - prev_family(e->prev_family), - leader_node(0), -#ifdef WIDOW_CONTROL - widow_control(e->widow_control), -#endif /* WIDOW_CONTROL */ - hyphen_line_max(e->hyphen_line_max), hyphen_line_count(0), + hyphen_line_max(e->hyphen_line_max), hyphenation_space(e->hyphenation_space), hyphenation_margin(e->hyphenation_margin), - composite(0) -{ + composite(0), + pending_lines(0), +#ifdef WIDOW_CONTROL + widow_control(e->widow_control), +#endif /* WIDOW_CONTROL */ + name(e->name), // so that eg `.if "\n[.ev]"0"' works + control_char(e->control_char), + no_break_control_char(e->no_break_control_char), + hyphen_indicator_char(e->hyphen_indicator_char) +{ +} + +void environment::copy(const environment *e) +{ + prev_line_length = e->prev_line_length; + line_length = e->line_length; + prev_title_length = e->prev_title_length; + title_length = e->title_length; + prev_size = e->prev_size; + size = e->size; + prev_requested_size = e->prev_requested_size; + requested_size = e->requested_size; + char_height = e->char_height; + char_slant = e->char_slant; + space_size = e->space_size; + sentence_space_size = e->sentence_space_size; + adjust_mode = e->adjust_mode; + fill = e->fill; + interrupted = 0; + prev_line_interrupted = 0; + center_lines = 0; + right_justify_lines = 0; + prev_vertical_spacing = e->prev_vertical_spacing; + vertical_spacing = e->vertical_spacing; + prev_post_vertical_spacing = e->prev_post_vertical_spacing, + post_vertical_spacing = e->post_vertical_spacing, + prev_line_spacing = e->prev_line_spacing; + line_spacing = e->line_spacing; + prev_indent = e->prev_indent; + indent = e->indent; + have_temporary_indent = 0; + temporary_indent = 0; + underline_lines = 0; + input_trap_count = 0; + prev_text_length = e->prev_text_length; + width_total = 0; + space_total = 0; + input_line_start = 0; + control_char = e->control_char; + no_break_control_char = e->no_break_control_char; + hyphen_indicator_char = e->hyphen_indicator_char; + spread_flag = 0; + line = 0; + pending_lines = 0; + discarding = 0; + tabs = e->tabs; + current_tab = TAB_NONE; + current_field = 0; + margin_character_flags = e->margin_character_flags; + margin_character_node = e->margin_character_node; + margin_character_distance = e->margin_character_distance; + numbering_nodes = 0; + number_text_separation = e->number_text_separation; + line_number_multiple = e->line_number_multiple; + line_number_indent = e->line_number_indent; + no_number_count = e->no_number_count; + tab_char = e->tab_char; + leader_char = e->leader_char; + hyphenation_flags = e->hyphenation_flags; + fontno = e->fontno; + prev_fontno = e->prev_fontno; + dummy = e->dummy; + family = e->family; + prev_family = e->prev_family; + leader_node = 0; +#ifdef WIDOW_CONTROL + widow_control = e->widow_control; +#endif /* WIDOW_CONTROL */ + hyphen_line_max = e->hyphen_line_max; + hyphen_line_count = 0; + hyphenation_space = e->hyphenation_space; + hyphenation_margin = e->hyphenation_margin; + composite = 0; } environment::~environment() @@ -896,11 +969,11 @@ void environment_switch() if (n >= 0 && n < NENVIRONMENTS) { env_stack = new env_list(curenv, env_stack); if (env_table[n] == 0) - env_table[n] = new environment(itoa(n)); + env_table[n] = new environment(i_to_a(n)); curenv = env_table[n]; } else - nm = itoa(n); + nm = i_to_a(n); } else pop = 2; @@ -935,6 +1008,33 @@ void environment_switch() skip_line(); } +void environment_copy() +{ + symbol nm; + environment *e=0; + tok.skip(); + if (!tok.delimiter()) { + // It looks like a number. + int n; + if (get_integer(&n)) { + if (n >= 0 && n < NENVIRONMENTS) + e = env_table[n]; + else + nm = i_to_a(n); + } + } + else + nm = get_long_name(1); + if (!e && !nm.is_null()) + e = (environment *)env_dictionary.lookup(nm); + if (e == 0) { + error("No environment to copy from"); + return; + } + else + curenv->copy(e); + skip_line(); +} static symbol P_symbol("P"); @@ -2117,7 +2217,7 @@ const char *tab_stops::to_string() } char *ptr = buf; for (p = initial_list; p; p = p->next) { - strcpy(ptr, itoa(p->pos.to_units())); + strcpy(ptr, i_to_a(p->pos.to_units())); ptr = strchr(ptr, '\0'); *ptr++ = 'u'; *ptr = '\0'; @@ -2138,7 +2238,7 @@ const char *tab_stops::to_string() if (repeated_list) *ptr++ = TAB_REPEAT_CHAR; for (p = repeated_list; p; p = p->next) { - strcpy(ptr, itoa(p->pos.to_units())); + strcpy(ptr, i_to_a(p->pos.to_units())); ptr = strchr(ptr, '\0'); *ptr++ = 'u'; *ptr = '\0'; @@ -2521,7 +2621,7 @@ int int_env_reg::get_value(units *val) const char *int_env_reg::get_string() { - return itoa((curenv->*func)()); + return i_to_a((curenv->*func)()); } vunits_env_reg::vunits_env_reg(VUNITS_FUNCP f) : func(f) @@ -2536,7 +2636,7 @@ int vunits_env_reg::get_value(units *val) const char *vunits_env_reg::get_string() { - return itoa((curenv->*func)().to_units()); + return i_to_a((curenv->*func)().to_units()); } hunits_env_reg::hunits_env_reg(HUNITS_FUNCP f) : func(f) @@ -2551,7 +2651,7 @@ int hunits_env_reg::get_value(units *val) const char *hunits_env_reg::get_string() { - return itoa((curenv->*func)().to_units()); + return i_to_a((curenv->*func)().to_units()); } string_env_reg::string_env_reg(STRING_FUNCP f) : func(f) @@ -2602,9 +2702,9 @@ const char *sptoa(int sp) assert(sp > 0); assert(sizescale > 0); if (sizescale == 1) - return itoa(sp); + return i_to_a(sp); if (sp % sizescale == 0) - return itoa(sp/sizescale); + return i_to_a(sp/sizescale); // See if 1/sizescale is exactly representable as a decimal fraction, // ie its only prime factors are 2 and 5. int n = sizescale; @@ -2628,7 +2728,7 @@ const char *sptoa(int sp) for (t = decimal_point - power5; --t >= 0;) factor *= 5; if (factor == 1 || sp <= INT_MAX/factor) - return iftoa(sp*factor, decimal_point); + return if_to_a(sp*factor, decimal_point); } } double s = double(sp)/double(sizescale); @@ -2642,7 +2742,7 @@ const char *sptoa(int sp) val = v; factor *= 10.0; } while (++decimal_point < 10); - return iftoa(int(val), decimal_point); + return if_to_a(int(val), decimal_point); } const char *environment::get_point_size_string() @@ -2673,6 +2773,7 @@ void init_env_requests() init_request("ad", adjust); init_request("na", no_adjust); init_request("ev", environment_switch); + init_request("evc", environment_copy); init_request("lt", title_length); init_request("ps", point_size); init_request("ft", font_change); @@ -2872,7 +2973,7 @@ struct trie_node { }; trie_node::trie_node(char ch, trie_node *p) -: c(ch), right(p), down(0), val(0) +: c(ch), down(0), right(p), val(0) { } @@ -2941,7 +3042,7 @@ struct operation { }; operation::operation(int i, int j, operation *op) -: num(i), distance(j), next(op) +: next(op), distance(j), num(i) { } diff --git a/contrib/groff/troff/env.h b/contrib/groff/troff/env.h index c0cc90d..1db463d 100644 --- a/contrib/groff/troff/env.h +++ b/contrib/groff/troff/env.h @@ -206,6 +206,7 @@ public: environment(symbol); environment(const environment *); // for temporary environment ~environment(); + void copy(const environment *); int is_dummy() { return dummy; } int is_empty(); int is_composite() { return composite; } diff --git a/contrib/groff/troff/input.cc b/contrib/groff/troff/input.cc index 9d98040..529a70f 100644 --- a/contrib/groff/troff/input.cc +++ b/contrib/groff/troff/input.cc @@ -37,6 +37,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Needed for getpid(). #include "posix.h" +#include "nonposix.h" + #ifdef ISATTY_MISSING #undef isatty #define isatty(n) (1) @@ -50,7 +52,8 @@ extern "C" { #define USAGE_EXIT_CODE 1 #define MACRO_PREFIX "tmac." -#define STARTUP_FILE "troffrc" +#define INITIAL_STARTUP_FILE "troffrc" +#define FINAL_STARTUP_FILE "troffrc-end" #define DEFAULT_INPUT_STACK_LIMIT 1000 #ifndef DEFAULT_WARNING_MASK @@ -127,6 +130,8 @@ struct input_iterator; input_iterator *make_temp_iterator(const char *); const char *input_char_description(int); +#ifndef IS_EBCDIC_HOST + const int ESCAPE_QUESTION = 015; const int BEGIN_TRAP = 016; const int END_TRAP = 017; @@ -157,6 +162,41 @@ const int ESCAPE_E = 0204; const int LAST_PAGE_EJECTOR = 0205; const int ESCAPE_RIGHT_PARENTHESIS = 0206; +#else /* IS_EBCDIC_HOST */ + +const int ESCAPE_QUESTION = 010; +const int BEGIN_TRAP = 011; +const int END_TRAP = 013; +const int PAGE_EJECTOR = 015; +const int ESCAPE_NEWLINE = 016; +const int ESCAPE_AMPERSAND = 017; +const int ESCAPE_UNDERSCORE = 020; +const int ESCAPE_BAR = 021; +const int ESCAPE_CIRCUMFLEX = 022; +const int ESCAPE_LEFT_BRACE = 023; +const int ESCAPE_RIGHT_BRACE = 024; +const int ESCAPE_LEFT_QUOTE = 027; +const int ESCAPE_RIGHT_QUOTE = 030; +const int ESCAPE_HYPHEN = 031; +const int ESCAPE_BANG = 032; +const int ESCAPE_c = 033; +const int ESCAPE_e = 034; +const int ESCAPE_PERCENT = 035; +const int ESCAPE_SPACE = 036; + +const int TITLE_REQUEST = 060; +const int COPY_FILE_REQUEST = 061; +const int TRANSPARENT_FILE_REQUEST = 062; +#ifdef COLUMN +const int VJUSTIFY_REQUEST = 063; +#endif /* COLUMN */ +const int ESCAPE_E = 064; +const int LAST_PAGE_EJECTOR = 065; +const int ESCAPE_RIGHT_PARENTHESIS = 066; + +#endif /* IS_EBCDIC_HOST */ + + void set_escape_char() { if (has_arg()) { @@ -263,8 +303,13 @@ public: }; file_iterator::file_iterator(FILE *f, const char *fn, int po) -: fp(f), filename(fn), lineno(1), newline_flag(0), popened(po) +: fp(f), lineno(1), filename(fn), popened(po), newline_flag(0) { + if ((font::use_charnames_in_special) && (fn != 0)) { + if (!the_output) + init_output(); + the_output->put_filename(fn); + } } file_iterator::~file_iterator() @@ -365,8 +410,12 @@ void file_iterator::backtrace() int file_iterator::set_location(const char *f, int ln) { - if (f) + if (f) { filename = f; + if (!the_output) + init_output(); + the_output->put_filename(f); + } lineno = ln; return 1; } @@ -1954,7 +2003,7 @@ static int transparent_translate(int cc) case charinfo::TRANSLATE_HYPHEN_INDICATOR: return ESCAPE_PERCENT; } - // This is realy ugly. + // This is really ugly. ci = ci->get_translation(1); if (ci) { int c = ci->get_ascii_code(); @@ -2300,7 +2349,7 @@ private: }; char_list::char_list() -: head(0), tail(0), ptr(0), len(0) +: ptr(0), len(0), head(0), tail(0) { } @@ -2388,6 +2437,7 @@ node_list::~node_list() } struct macro_header { +public: int count; char_list cl; node_list nl; @@ -2413,7 +2463,7 @@ macro::macro() } macro::macro(const macro &m) -: filename(m.filename), lineno(m.lineno), p(m.p), length(m.length) +: p(m.p), filename(m.filename), lineno(m.lineno), length(m.length) { if (p != 0) p->count++; @@ -2530,7 +2580,7 @@ public: }; string_iterator::string_iterator(const macro &m, const char *p, symbol s) -: lineno(1), mac(m), newline_flag(0), how_invoked(p), nm(s) +: mac(m), how_invoked(p), newline_flag(0), lineno(1), nm(s) { count = mac.length; if (count != 0) { @@ -3015,7 +3065,7 @@ void read_request() } } if (reading_from_terminal) { - fputc(had_prompt ? ':' : '\007', stderr); + fputc(had_prompt ? ':' : '\a', stderr); fflush(stderr); } input_stack::push(mi); @@ -3502,6 +3552,44 @@ void substring_macro() skip_line(); } +void length_macro() +{ + symbol ret; + ret = get_name(1); + if (ret.is_null()) { + skip_line(); + return; + } + int c; + node *n; + if (tok.newline()) + c = '\n'; + else if (tok.tab()) + c = '\t'; + else if (!tok.space()) { + error("bad string definition"); + skip_line(); + return; + } + else + c = get_copy(&n); + while (c == ' ') + c = get_copy(&n); + if (c == '"') + c = get_copy(&n); + int len = 0; + while (c != '\n' && c != EOF) { + ++len; + c = get_copy(&n); + } + tok.next(); + reg *r = (reg*)number_reg_dictionary.lookup(ret); + if (r) + r->set_value(len); + else + set_number_reg(ret, len); +} + void asciify_macro() { symbol s = get_name(1); @@ -3820,7 +3908,7 @@ static void do_width() } env.wrap_up_tab(); units x = env.get_input_line_position().to_units(); - input_stack::push(make_temp_iterator(itoa(x))); + input_stack::push(make_temp_iterator(i_to_a(x))); env.width_registers(); curenv = oldenv; } @@ -3926,6 +4014,38 @@ static node *do_non_interpreted() return new non_interpreted_node(mac); } +static void encode_char (macro *mac, char c) +{ + if (c == '\0') { + if ((font::use_charnames_in_special) && tok.special()) { + charinfo *ci=tok.get_char(1); + const char *s=ci->get_symbol()->contents(); + + if (s[0] != (char)0) { + mac->append('\\'); + mac->append('('); + int i=0; + while (s[i] != (char)0) { + mac->append(s[i]); + i++; + } + mac->append('\\'); + mac->append(')'); + } + } else { + error("%1 is illegal within \\X", tok.description()); + } + } else { + if ((font::use_charnames_in_special) && (c == '\\')) { + /* + * add escape escape sequence + */ + mac->append(c); + } + mac->append(c); + } +} + node *do_special() { token start; @@ -3955,10 +4075,7 @@ node *do_special() c = '\b'; else c = tok.ch(); - if (c == '\0') - error("%1 is illegal within \\X", tok.description()); - else - mac.append(c); + encode_char(&mac, c); } return new special_node(mac); } @@ -4332,7 +4449,7 @@ void pipe_source() } buf[buf_used] = '\0'; errno = 0; - FILE *fp = popen(buf, "r"); + FILE *fp = popen(buf, POPEN_RT); if (fp) input_stack::push(new file_iterator(fp, symbol(buf).contents(), 1)); else @@ -4343,6 +4460,193 @@ void pipe_source() #endif /* not POPEN_MISSING */ } + +// .psbb + +static int llx_reg_contents = 0; +static int lly_reg_contents = 0; +static int urx_reg_contents = 0; +static int ury_reg_contents = 0; + +struct bounding_box { + int llx, lly, urx, ury; +}; + +/* Parse the argument to a %%BoundingBox comment. Return 1 if it +contains 4 numbers, 2 if it contains (atend), 0 otherwise. */ + +int parse_bounding_box(char *p, bounding_box *bb) +{ + if (sscanf(p, "%d %d %d %d", + &bb->llx, &bb->lly, &bb->urx, &bb->ury) == 4) + return 1; + else { + /* The Document Structuring Conventions say that the numbers + should be integers. Unfortunately some broken applications + get this wrong. */ + double x1, x2, x3, x4; + if (sscanf(p, "%lf %lf %lf %lf", &x1, &x2, &x3, &x4) == 4) { + bb->llx = (int)x1; + bb->lly = (int)x2; + bb->urx = (int)x3; + bb->ury = (int)x4; + return 1; + } + else { + for (; *p == ' ' || *p == '\t'; p++) + ; + if (strncmp(p, "(atend)", 7) == 0) { + return 2; + } + } + } + bb->llx = bb->lly = bb->urx = bb->ury = 0; + return 0; +} + +// This version is taken from psrm.cc + +#define PS_LINE_MAX 255 +cset white_space("\n\r \t"); + +int ps_get_line(char *buf, FILE *fp, const char* filename) +{ + int c = getc(fp); + if (c == EOF) { + buf[0] = '\0'; + return 0; + } + int i = 0; + int err = 0; + while (c != '\r' && c != '\n' && c != EOF) { + if ((c < 0x1b && !white_space(c)) || c == 0x7f) + error("illegal input character code %1 in `%2'", int(c), filename); + else if (i < PS_LINE_MAX) + buf[i++] = c; + else if (!err) { + err = 1; + error("PostScript file `%1' is non-conforming " + "because length of line exceeds 255", filename); + } + c = getc(fp); + } + buf[i++] = '\n'; + buf[i] = '\0'; + if (c == '\r') { + c = getc(fp); + if (c != EOF && c != '\n') + ungetc(c, fp); + } + return 1; +} + +void do_ps_file(FILE *fp, const char* filename) +{ + bounding_box bb; + int bb_at_end = 0; + char buf[PS_LINE_MAX]; + llx_reg_contents = lly_reg_contents = + urx_reg_contents = ury_reg_contents = 0; + if (!ps_get_line(buf, fp, filename)) { + error("`%1' is empty", filename); + return; + } + if (strncmp("%!PS-Adobe-", buf, 11) != 0) { + error("`%1' is not conforming to the Document Structuring Conventions", + filename); + return; + } + while (ps_get_line(buf, fp, filename) != 0) { + if (buf[0] != '%' || buf[1] != '%' + || strncmp(buf + 2, "EndComments", 11) == 0) + break; + if (strncmp(buf + 2, "BoundingBox:", 12) == 0) { + int res = parse_bounding_box(buf + 14, &bb); + if (res == 1) + goto assign_registers; + else if (res == 2) { + bb_at_end = 1; + break; + } + else { + error("the arguments to the %%%%BoundingBox comment in `%1' are bad", + filename); + return; + } + } + } + if (bb_at_end) { + long offset; + int last_try = 0; + /* in the trailer, the last BoundingBox comment is significant */ + for (offset = 512; !last_try; offset *= 2) { + int had_trailer = 0; + int got_bb = 0; + if (offset > 32768 || fseek(fp, -offset, 2) == -1) { + last_try = 1; + if (fseek(fp, 0L, 0) == -1) + break; + } + while (ps_get_line(buf, fp, filename) != 0) { + if (buf[0] == '%' && buf[1] == '%') { + if (!had_trailer) { + if (strncmp(buf + 2, "Trailer", 7) == 0) + had_trailer = 1; + } + else { + if (strncmp(buf + 2, "BoundingBox:", 12) == 0) { + int res = parse_bounding_box(buf + 14, &bb); + if (res == 1) + got_bb = 1; + else if (res == 2) { + error("`(atend)' not allowed in trailer of `%1'", filename); + return; + } + else { + error("the arguments to the %%%%BoundingBox comment in `%1' are bad", + filename); + return; + } + } + } + } + } + if (got_bb) + goto assign_registers; + } + } + error("%%%%BoundingBox comment not found in `%1'", filename); + return; + +assign_registers: + llx_reg_contents = bb.llx; + lly_reg_contents = bb.lly; + urx_reg_contents = bb.urx; + ury_reg_contents = bb.ury; +} + +void ps_bbox_request() +{ + symbol nm = get_long_name(1); + if (nm.is_null()) + skip_line(); + else { + while (!tok.newline() && !tok.eof()) + tok.next(); + errno = 0; + // PS files might contain non-printable characters, such as ^Z + // and CRs not followed by an LF, so open them in binary mode. + FILE *fp = fopen(nm.contents(), FOPEN_RB); + if (fp) { + do_ps_file(fp, nm.contents()); + fclose(fp); + } + else + error("can't open `%1': %2", nm.contents(), strerror(errno)); + tok.next(); + } +} + const char *asciify(int c) { static char buf[3]; @@ -4418,7 +4722,7 @@ const char *input_char_description(int c) case '\001': return "a leader character"; case '\t': - return "a tab character "; + return "a tab character"; case ' ': return "a space character"; case '\0': @@ -4576,7 +4880,7 @@ static void init_charset_table() char buf[16]; strcpy(buf, "char"); for (int i = 0; i < 256; i++) { - strcpy(buf + 4, itoa(i)); + strcpy(buf + 4, i_to_a(i)); charset_table[i] = get_charinfo(symbol(buf)); charset_table[i]->set_ascii_code(i); if (csalpha(i)) @@ -4883,7 +5187,7 @@ public: const char *nargs_reg::get_string() { - return itoa(input_stack::nargs()); + return i_to_a(input_stack::nargs()); } class lineno_reg : public reg { @@ -4897,7 +5201,7 @@ const char *lineno_reg::get_string() const char *file; if (!input_stack::get_location(0, &file, &line)) line = 0; - return itoa(line); + return i_to_a(line); } @@ -4965,7 +5269,7 @@ constant_int_reg::constant_int_reg(int *q) : p(q) const char *constant_int_reg::get_string() { - return itoa(*p); + return i_to_a(*p); } void abort_request() @@ -5213,10 +5517,10 @@ static void process_macro_file(const char *mac) process_input_stack(); } -static void process_startup_file() +static void process_startup_file(char *filename) { char *path; - FILE *fp = macro_path.open_file(STARTUP_FILE, &path); + FILE *fp = macro_path.open_file(filename, &path); if (fp) { input_stack::push(new file_iterator(fp, symbol(path).contents())); a_delete path; @@ -5368,7 +5672,7 @@ int main(int argc, char **argv) int fflag = 0; int nflag = 0; int safer_flag = 1; // safer by default - int no_rc = 0; // don't process troffrc + int no_rc = 0; // don't process troffrc and troffrc-end int next_page_number; opterr = 0; hresolution = vresolution = 1; @@ -5377,8 +5681,8 @@ int main(int argc, char **argv) switch(c) { case 'v': { - extern const char *version_string; - fprintf(stderr, "GNU troff version %s\n", version_string); + extern const char *Version_string; + fprintf(stderr, "GNU troff version %s\n", Version_string); fflush(stderr); break; } @@ -5511,7 +5815,7 @@ int main(int argc, char **argv) delete tem; } if (!no_rc) - process_startup_file(); + process_startup_file(INITIAL_STARTUP_FILE); if (safer_flag) prepend_string("safer", ¯os); while (macros) { @@ -5520,6 +5824,8 @@ int main(int argc, char **argv) macros = macros->next; delete tem; } + if (!no_rc) + process_startup_file(FINAL_STARTUP_FILE); for (i = optind; i < argc; i++) process_input_file(argv[i]); if (optind >= argc || iflag) @@ -5556,6 +5862,7 @@ static void init_registers() set_number_reg("dw", int(tt->tm_wday + 1)); set_number_reg("dy", int(tt->tm_mday)); set_number_reg("mo", int(tt->tm_mon + 1)); + set_number_reg("year", int(1900 + tt->tm_year)); set_number_reg("yr", int(tt->tm_year)); set_number_reg("$$", getpid()); number_reg_dictionary.define(".A", @@ -5607,6 +5914,7 @@ void init_input_requests() init_request("backtrace", backtrace_request); init_request("chop", chop_macro); init_request("substring", substring_macro); + init_request("length", length_macro); init_request("asciify", asciify_macro); init_request("warn", warn_request); init_request("open", open_request); @@ -5628,6 +5936,7 @@ void init_input_requests() #ifndef POPEN_MISSING init_request("pso", pipe_source); #endif /* not POPEN_MISSING */ + init_request("psbb", ps_bbox_request); number_reg_dictionary.define("systat", new variable_reg(&system_status)); number_reg_dictionary.define("slimit", new variable_reg(&input_stack::limit)); @@ -5643,8 +5952,14 @@ void init_input_requests() number_reg_dictionary.define(".x", new constant_reg(major_version)); extern const char *minor_version; number_reg_dictionary.define(".y", new constant_reg(minor_version)); + extern const char *revision; + number_reg_dictionary.define(".Y", new constant_reg(revision)); number_reg_dictionary.define(".g", new constant_reg("1")); number_reg_dictionary.define(".warn", new constant_int_reg(&warning_mask)); + number_reg_dictionary.define("llx", new variable_reg(&llx_reg_contents)); + number_reg_dictionary.define("lly", new variable_reg(&lly_reg_contents)); + number_reg_dictionary.define("urx", new variable_reg(&urx_reg_contents)); + number_reg_dictionary.define("ury", new variable_reg(&ury_reg_contents)); } object_dictionary request_dictionary(501); @@ -5988,9 +6303,9 @@ charinfo *get_charinfo(symbol nm) int charinfo::next_index = 0; charinfo::charinfo(symbol s) -: nm(s), hyphenation_code(0), translation(0), flags(0), ascii_code(0), - special_translation(TRANSLATE_NONE), mac(0), not_found(0), - transparent_translate(1) +: translation(0), mac(0), special_translation(TRANSLATE_NONE), + hyphenation_code(0), flags(0), ascii_code(0), not_found(0), + transparent_translate(1), nm(s) { index = next_index++; } @@ -6059,7 +6374,7 @@ charinfo *get_charinfo_by_number(int n) return ci; } else { - symbol ns(itoa(n)); + symbol ns(i_to_a(n)); charinfo *ci = (charinfo *)numbered_charinfo_dictionary.lookup(ns); if (!ci) { ci = new charinfo(UNNAMED_SYMBOL); diff --git a/contrib/groff/troff/node.cc b/contrib/groff/troff/node.cc index 5c1fa43..d53bf33 100644 --- a/contrib/groff/troff/node.cc +++ b/contrib/groff/troff/node.cc @@ -18,6 +18,10 @@ 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. */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + #include "troff.h" #include "symbol.h" #include "dictionary.h" @@ -30,6 +34,25 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "font.h" #include "reg.h" +#include "nonposix.h" + +#ifdef _POSIX_VERSION + +#include <sys/wait.h> + +#else /* not _POSIX_VERSION */ + +/* traditional Unix */ + +#define WIFEXITED(s) (((s) & 0377) == 0) +#define WEXITSTATUS(s) (((s) >> 8) & 0377) +#define WTERMSIG(s) ((s) & 0177) +#define WIFSTOPPED(s) (((s) & 0377) == 0177) +#define WSTOPSIG(s) (((s) >> 8) & 0377) +#define WIFSIGNALED(s) (((s) & 0377) != 0 && (((s) & 0377) != 0177)) + +#endif /* not _POSIX_VERSION */ + #define STORE_WIDTH 1 symbol HYPHEN_SYMBOL("hy"); @@ -180,11 +203,10 @@ static font_info **font_table = 0; static int font_table_size = 0; font_info::font_info(symbol nm, int n, symbol enm, font *f) -: internal_name(nm), external_name(enm), fm(f), number(n), - is_constant_spaced(CONSTANT_SPACE_NONE), - sf(0), is_bold(0), cond_bold_list(0), - last_ligature_mode(1), last_kern_mode(1), - last_tfont(0), last_size(0) +: last_tfont(0), number(n), last_size(0), + internal_name(nm), external_name(enm), fm(f), + is_bold(0), is_constant_spaced(CONSTANT_SPACE_NONE), last_ligature_mode(1), + last_kern_mode(1), cond_bold_list(0), sf(0) { } @@ -298,7 +320,7 @@ void font_info::set_conditional_bold(int fontno, hunits offset) } conditional_bold::conditional_bold(int f, hunits h, conditional_bold *x) - : fontno(f), offset(h), next(x) + : next(x), fontno(f), offset(h) { } @@ -631,6 +653,7 @@ class real_output_file : public output_file { vunits before, vunits after) = 0; virtual void really_begin_page(int pageno, vunits page_length) = 0; virtual void really_copy_file(hunits x, vunits y, const char *filename); + virtual void really_put_filename(const char *filename); protected: FILE *fp; public: @@ -640,6 +663,7 @@ public: void transparent_char(unsigned char); void print_line(hunits x, vunits y, node *n, vunits before, vunits after); void begin_page(int pageno, vunits page_length); + void put_filename(const char *filename); int is_printing(); void copy_file(hunits x, vunits y, const char *filename); }; @@ -719,6 +743,7 @@ public: void really_print_line(hunits x, vunits y, node *n, vunits before, vunits after); void really_begin_page(int pageno, vunits page_length); void really_copy_file(hunits x, vunits y, const char *filename); + void really_put_filename(const char *filename); void draw(char, hvpair *, int, font_size); int get_hpos() { return hpos; } int get_vpos() { return vpos; } @@ -747,7 +772,7 @@ inline void troff_output_file::put(const char *s) inline void troff_output_file::put(int i) { - put_string(itoa(i), fp); + put_string(i_to_a(i), fp); } void troff_output_file::start_special() @@ -1067,6 +1092,14 @@ void troff_output_file::draw(char code, hvpair *point, int npoints, put('\n'); } +void troff_output_file::really_put_filename(const char *filename) +{ + flush_tbuf(); + put("F "); + put(filename); + put('\n'); +} + void troff_output_file::really_begin_page(int pageno, vunits page_length) { flush_tbuf(); @@ -1142,7 +1175,7 @@ void troff_output_file::trailer(vunits page_length) } troff_output_file::troff_output_file() -: current_height(0), current_slant(0), tbuf_len(0), nfont_positions(10), +: current_slant(0), current_height(0), nfont_positions(10), tbuf_len(0), begun_page(0) { font_position = new symbol[nfont_positions]; @@ -1175,12 +1208,17 @@ void output_file::trailer(vunits) { } + +void output_file::put_filename(const char *filename) +{ +} + real_output_file::real_output_file() : printing(0) { #ifndef POPEN_MISSING if (pipe_command) { - if ((fp = popen(pipe_command, "w")) != 0) { + if ((fp = popen(pipe_command, POPEN_WT)) != 0) { piped = 1; return; } @@ -1206,11 +1244,12 @@ real_output_file::~real_output_file() fp = 0; if (result < 0) fatal("pclose failed"); - if ((result & 0x7f) != 0) + if (!WIFEXITED(result)) error("output process `%1' got fatal signal %2", - pipe_command, result & 0x7f); + pipe_command, + WIFSIGNALED(result) ? WTERMSIG(result) : WSTOPSIG(result)); else { - int exit_status = (result >> 8) & 0xff; + int exit_status = WEXITSTATUS(result); if (exit_status != 0) error("output process `%1' exited with status %2", pipe_command, exit_status); @@ -1267,6 +1306,14 @@ void real_output_file::really_copy_file(hunits, vunits, const char *) // do nothing } +void real_output_file::put_filename(const char *filename) +{ + really_put_filename(filename); +} + +void real_output_file::really_put_filename(const char *filename) +{ +} /* ascii_output_file */ @@ -1324,7 +1371,7 @@ public: }; charinfo_node::charinfo_node(charinfo *c, node *x) -: ci(c), node(x) +: node(x), ci(c) { } @@ -1491,7 +1538,7 @@ void glyph_node::operator delete(void *p) void ligature_node::operator delete(void *p) { - delete p; + delete[] (char *)p; } glyph_node::glyph_node(charinfo *c, tfont *t, node *x) @@ -1697,7 +1744,7 @@ node *ligature_node::add_self(node *n, hyphen_list **p) } kern_pair_node::kern_pair_node(hunits n, node *first, node *second, node *x) - : node(x), n1(first), n2(second), amount(n) + : node(x), amount(n), n1(first), n2(second) { } @@ -2044,7 +2091,7 @@ node *node::add_italic_correction(hunits *width) } italic_corrected_node::italic_corrected_node(node *nn, hunits xx, node *p) -: n(nn), x(xx), node(p) +: node(p), n(nn), x(xx) { assert(n != 0); } @@ -2380,7 +2427,7 @@ void zero_width_node::vertical_extent(vunits *min, vunits *max) node_list_vertical_extent(n, min, max); } -overstrike_node::overstrike_node() : max_width(H0), list(0) +overstrike_node::overstrike_node() : list(0), max_width(H0) { } @@ -2416,7 +2463,7 @@ hunits overstrike_node::width() return max_width; } -bracket_node::bracket_node() : max_width(H0), list(0) +bracket_node::bracket_node() : list(0), max_width(H0) { } @@ -2428,7 +2475,8 @@ bracket_node::~bracket_node() node *bracket_node::copy() { bracket_node *on = new bracket_node; - node *last, *tem; + node *last = 0; + node *tem; for (tem = list; tem; tem = tem->next) { if (tem->next) tem->next->last = tem; @@ -3293,7 +3341,7 @@ hvpair::hvpair() } draw_node::draw_node(char c, hvpair *p, int np, font_size s) - : code(c), npoints(np), sz(s) + : npoints(np), sz(s), code(c) { point = new hvpair[npoints]; for (int i = 0; i < npoints; i++) @@ -3969,7 +4017,7 @@ const char *italic_corrected_node::type() left_italic_corrected_node::left_italic_corrected_node(node *x) -: n(0), node(x) +: node(x), n(0) { } @@ -4396,7 +4444,7 @@ void font_position() } font_family::font_family(symbol s) -: nm(s), map_size(10) +: map_size(10), nm(s) { map = new int[map_size]; for (int i = 0; i < map_size; i++) @@ -4832,7 +4880,7 @@ public: const char *next_available_font_position_reg::get_string() { - return itoa(next_available_font_position()); + return i_to_a(next_available_font_position()); } class printing_reg : public reg { diff --git a/contrib/groff/troff/node.h b/contrib/groff/troff/node.h index fdfe36d..b509557 100644 --- a/contrib/groff/troff/node.h +++ b/contrib/groff/troff/node.h @@ -440,7 +440,7 @@ node *copy_node_list(node *); int get_bold_fontno(int f); inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p) -: hyphenation_code(code), next(p), hyphen(0), breakable(0) +: hyphen(0), breakable(0), hyphenation_code(code), next(p) { } @@ -466,6 +466,7 @@ public: virtual void begin_page(int pageno, vunits page_length) = 0; virtual void copy_file(hunits x, vunits y, const char *filename) = 0; virtual int is_printing() = 0; + virtual void put_filename (const char *filename); #ifdef COLUMN virtual void vjustify(vunits, symbol); #endif /* COLUMN */ diff --git a/contrib/groff/troff/reg.cc b/contrib/groff/troff/reg.cc index a9eec05..79e7806 100644 --- a/contrib/groff/troff/reg.cc +++ b/contrib/groff/troff/reg.cc @@ -66,15 +66,29 @@ 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 itoa(value); + return i_to_a(value); else if (width > sizeof(buf) - 2) - sprintf(buf, "%.*d", sizeof(buf) - 2, int(value)); + sprintf(buf, "%.*d", int(sizeof(buf) - 2), int(value)); else sprintf(buf, "%.*d", width, int(value)); break; @@ -88,7 +102,7 @@ static const char *number_value_to_ascii(int value, char format, int width) int n = int(value); if (n >= 40000 || n <= -40000) { error("magnitude of `%1' too big for i or I format", n); - return itoa(n); + return i_to_a(n); } if (n == 0) { *p++ = '0'; @@ -167,10 +181,11 @@ static const char *number_value_to_ascii(int value, char format, int width) d = 26; n -= d; n /= 26; - *p++ = format + d - 1; + *p++ = format == 'a' ? lowercase_array[d - 1] : + uppercase_array[d - 1]; } *p-- = 0; - char *q = buf[0] == '-' ? buf+1 : buf; + char *q = buf[0] == '-' ? buf + 1 : buf; while (q < p) { char temp = *q; *q = *p; diff --git a/contrib/groff/troff/request.h b/contrib/groff/troff/request.h index 2334a46..5703175 100644 --- a/contrib/groff/troff/request.h +++ b/contrib/groff/troff/request.h @@ -73,8 +73,6 @@ extern void init_env_requests(); extern void init_hyphen_requests(); extern void init_request(const char *s, REQUEST_FUNCP f); -extern int no_break_flag; // indicates whether request was invoked with . or ' - class charinfo; class environment; diff --git a/contrib/groff/troff/token.h b/contrib/groff/troff/token.h index 5a7d440..f6707f2 100644 --- a/contrib/groff/troff/token.h +++ b/contrib/groff/troff/token.h @@ -68,6 +68,7 @@ public: int nspaces(); // 1 if space, 2 if double space, 0 otherwise int space(); // is it a space or double space? int white_space(); // is the current token space or tab? + int special(); // is the current token a special character? int newline(); // is the current token a newline? int tab(); // is the current token a tab? int leader(); @@ -124,6 +125,11 @@ inline int token::space() return type == TOKEN_SPACE; } +inline int token::special() +{ + return type == TOKEN_SPECIAL; +} + inline int token::nspaces() { if (type == TOKEN_SPACE) |