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 | a812d8b090bc4edc23150bff257717b24f282e41 (patch) | |
tree | 19d4540966cb92612af25d5154efcc062eefb5c5 /contrib/groff/troff | |
parent | 2e2c9047c3a8b5b6fdcdcd4585d5b114f31cd386 (diff) | |
download | FreeBSD-src-a812d8b090bc4edc23150bff257717b24f282e41.zip FreeBSD-src-a812d8b090bc4edc23150bff257717b24f282e41.tar.gz |
Virgin import of FSF groff v1.16.1
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 | ||||
-rw-r--r-- | contrib/groff/troff/troff.man | 124 |
15 files changed, 782 insertions, 165 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) diff --git a/contrib/groff/troff/troff.man b/contrib/groff/troff/troff.man index 4d54afd..616dcad 100644 --- a/contrib/groff/troff/troff.man +++ b/contrib/groff/troff/troff.man @@ -1,5 +1,5 @@ .ig \"-*- nroff -*- -Copyright (C) 1989-1999 Free Software Foundation, Inc. +Copyright (C) 1989-2000 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -33,7 +33,7 @@ the original English. .\" The BSD man macros can't handle " in arguments to font change macros, .\" so use \(ts instead of ". .tr \(ts" -.TH @G@TROFF 1 "@MDATE@" "Groff Version @VERSION@" +.TH @G@TROFF @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@" .SH NAME @g@troff \- format documents .SH SYNOPSIS @@ -62,6 +62,9 @@ the original English. .RI "[\ " files\|.\|.\|. "\ ]" .br .ad \na +.PP +It is possible to have whitespace between a command line option and its +parameter. .SH DESCRIPTION This manual page describes the GNU version of .BR troff , @@ -81,7 +84,7 @@ approximation of the typeset output. Print a backtrace with each warning or error message. This backtrace should help track down the cause of the error. The line numbers given in the backtrace may not always be correct: -.B troff 's +.BR troff 's idea of line numbers gets confused by .B as @@ -142,9 +145,10 @@ as the default font family. Read in the file .BI tmac. name\fR. Normally this will be searched for in @MACRODIR@. -By default is used the +By default, the .I safer -macro (reverted using -U ). +macro is used (this can be reverted using +.BR \-U ). .TP .B \-U Unsafe option, avoids default use of @@ -153,7 +157,9 @@ macro. .TP .B \-R Don't load -.BR troffrc . +.B troffrc +and +.BR troffrc-end . .TP .BI \-n num Number the first page @@ -473,7 +479,7 @@ is a numeric expression with a default scale indicator of .TQ .BI \eV[ xxx ] Interpolate the contents of the environment variable -.I xxx , +.IR xxx , as returned by .BR getenv (3). .B \eV @@ -877,6 +883,12 @@ sourced by are interpreted. .RE .TP +.BI .evc\ xx +Copy the contents of environment +.I xx +to the current environment. +No pushing or popping of environents will be done. +.TP .BI .fam\ xx Set the current font family to .IR xx . @@ -1047,12 +1059,19 @@ If .I n is non-zero or missing, enable pairwise kerning, otherwise disable it. .TP +.BI .length\ xx\ string +Compute the length of +.I string +and return it in the number register +.I xx +(which is not necessarily defined before). +.TP .BI .mso\ file The same as the .B so request except that .I file -is searched for in the same way that +is searched for in the same directories as .BI tmac. name is searched for when the .BI \-m name @@ -1092,8 +1111,25 @@ exists, append to it instead of truncating it. Print the names and contents of all currently defined number registers on stderr. .TP +.BI .psbb \ filename +Get the bounding box of a PostScript image +.IR filename . +This file must conform to Adobe's Document Structuring Conventions; the +command looks for a +.B %%BoundingBox +comment to extract the bounding box values. +After a successful call, the coordinates (in PostScript units) of the lower +left and upper right corner can be found in the registers +.BR \en[llx] , +.BR \en[lly] , +.BR \en[urx] , +and +.BR \en[ury] , +respectively. +If some error has occurred, the four registers are set to zero. +.TP .BI .pso \ command -This is behaves like the +This behaves like the .B so request except that input comes from the standard output of .IR command . @@ -1220,6 +1256,25 @@ The styles command in the file controls which font positions (if any) are initially associated with styles rather than fonts. .TP +.BI .substring\ xx\ n1\ [ n2 ] +Replace the string in register +.I xx +with the substring defined by the indices +.I n1 +and +.IR n2 . +The first character in the string has index one. +If +.I n2 +is omitted, it is taken to be equal to the string's length. If the +index value +.I n1 +or +.I n2 +is negative or zero, it will be counted from the end of the string, +going backwards: The last character has index 0, the character before +the last character has index -1, etc. +.TP .BI .tkf\ f\ s1\ n1\ s2\ n2 Enable track kerning for font .IR f . @@ -1639,6 +1694,21 @@ then .B \en(.y will contain .BR 03 . +.TP +.B \en(.Y +The revision number of groff. +.TP +.B \en[llx] +.TQ +.B \en[lly] +.TQ +.B \en[urx] +.TQ +.B \en[ury] +These four registers are set by the +.B \&.psbb +request and contain the bounding box values (in PostScript units) of a given +PostScript image. .LP The following registers are set by the .B \ew @@ -1676,7 +1746,32 @@ If greater than 0, the maximum number of objects on the input stack. If less than or equal to 0, there is no limit on the number of objects on the input stack. With no limit, recursion can continue until virtual memory is exhausted. +.TP +.B \en[year] +The current year. +Note that the traditional +.B troff +number register +.B \en(yr +is the current year minus 1900. .SS Miscellaneous +.B @g@troff +predefines a single (read/write) string-based register, +.BR \e*(.T , +which contains the argument given to the +.B -T +command line option, namely the current output device (for example, +.I latin1 +or +.IR ascii ). +Note that this is not the same as the (read-only) number register +.B \en(.T +which is defined to be\ 1 if +.B troff +is called with the +.B -T +command line option, and zero otherwise. This behaviour is different to +Unix troff. .LP Fonts not listed in the .SM DESC @@ -2034,7 +2129,10 @@ after these. .SH FILES .Tp \w'@FONTDIR@/devname/DESC'u+3n .B @MACRODIR@/troffrc -Initialization file +Initialization file (called before any other macro package). +.TP +.B @MACRODIR@/troffrc-end +Initialization file (called after any other macro package). .TP .BI @MACRODIR@/tmac. name Macro files @@ -2049,14 +2147,18 @@ Font file for font of device .IR name . .SH "SEE ALSO" -.BR groff (@MAN1EXT@) +.BR groff (@MAN1EXT@), .BR @g@tbl (@MAN1EXT@), .BR @g@pic (@MAN1EXT@), .BR @g@eqn (@MAN1EXT@), +.BR @g@refer (@MAN1EXT@), +.BR @g@soelim (@MAN1EXT@), +.BR @g@grn (@MAN1EXT@), .BR grops (@MAN1EXT@), .BR grodvi (@MAN1EXT@), .BR grotty (@MAN1EXT@), .BR grohtml (@MAN1EXT@), +.BR grolj4 (@MAN1EXT@), .BR groff_font (@MAN5EXT@), .BR groff_out (@MAN5EXT@), .BR groff_char (@MAN7EXT@) |