summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/groff/pic
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/groff/pic')
-rw-r--r--gnu/usr.bin/groff/pic/Makefile.dep24
-rw-r--r--gnu/usr.bin/groff/pic/Makefile.sub11
-rw-r--r--gnu/usr.bin/groff/pic/TODO37
-rw-r--r--gnu/usr.bin/groff/pic/common.cc497
-rw-r--r--gnu/usr.bin/groff/pic/common.h70
-rw-r--r--gnu/usr.bin/groff/pic/depend21
-rw-r--r--gnu/usr.bin/groff/pic/lex.cc1939
-rw-r--r--gnu/usr.bin/groff/pic/main.cc621
-rw-r--r--gnu/usr.bin/groff/pic/object.cc1833
-rw-r--r--gnu/usr.bin/groff/pic/object.h217
-rw-r--r--gnu/usr.bin/groff/pic/output.h79
-rw-r--r--gnu/usr.bin/groff/pic/pic.1_in759
-rw-r--r--gnu/usr.bin/groff/pic/pic.h102
-rw-r--r--gnu/usr.bin/groff/pic/pic.y1784
-rw-r--r--gnu/usr.bin/groff/pic/position.h47
-rw-r--r--gnu/usr.bin/groff/pic/tex.cc411
-rw-r--r--gnu/usr.bin/groff/pic/text.h28
-rw-r--r--gnu/usr.bin/groff/pic/troff.cc500
18 files changed, 0 insertions, 8980 deletions
diff --git a/gnu/usr.bin/groff/pic/Makefile.dep b/gnu/usr.bin/groff/pic/Makefile.dep
deleted file mode 100644
index 1e07874890b..00000000000
--- a/gnu/usr.bin/groff/pic/Makefile.dep
+++ /dev/null
@@ -1,24 +0,0 @@
-lex.o: lex.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h ../include/ptable.h \
- object.h pic.cc
-main.o: main.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h
-object.o: object.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h ../include/ptable.h \
- object.h
-common.o: common.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h common.h
-troff.o: troff.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h common.h
-tex.o: tex.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h common.h
-pic.o: pic.cc pic.h ../include/assert.h ../include/cset.h \
- ../include/lib.h ../include/stringclass.h ../include/errarg.h \
- ../include/error.h position.h text.h output.h ../include/ptable.h \
- object.h
diff --git a/gnu/usr.bin/groff/pic/Makefile.sub b/gnu/usr.bin/groff/pic/Makefile.sub
deleted file mode 100644
index b36033cf449..00000000000
--- a/gnu/usr.bin/groff/pic/Makefile.sub
+++ /dev/null
@@ -1,11 +0,0 @@
-PROG=pic
-MAN1=pic.1
-XLIBS=$(LIBGROFF)
-MLIB=$(LIBM)
-OBJS=pic.o lex.o main.o object.o common.o troff.o tex.o # fig.o
-CCSRCS=lex.cc main.cc object.cc common.cc troff.cc tex.cc
-HDRS=common.h object.h output.h pic.h position.h text.h
-GRAM=pic.y
-YTABC=pic.cc
-YTABH=pic.tab.h
-NAMEPREFIX=$(g)
diff --git a/gnu/usr.bin/groff/pic/TODO b/gnu/usr.bin/groff/pic/TODO
deleted file mode 100644
index 2346b575e1d..00000000000
--- a/gnu/usr.bin/groff/pic/TODO
+++ /dev/null
@@ -1,37 +0,0 @@
-Dotted and dashed ellipses.
-
-In troff mode, dotted and dashed splines.
-
-Make DELIMITED have type lstr; this would allow us to give better
-error messages for problems within the body of for and if constructs.
-
-In troff mode without -x, fake \D't' with .ps commands.
-
-Perhaps an option to set command char.
-
-Add an output class for dumb line printers. It wouldn't be pretty but
-it would be better than nothing. Integrate it with texinfo. Useful
-for groff -Tascii as well.
-
-Option to allow better positioning of arrowheads on arcs.
-
-Perhaps add PostScript output mode.
-
-Change the interface to the output class so that output devices have
-the opportunity to handle arrowheads themselves.
-
-Consider whether the line thickness should scale.
-
-Consider whether the test in a for loop should be fuzzy (as it
-apparently is in grap).
-
-Possibly change fillval so that zero is black.
-
-Provide a way of getting text blocks (positioned with `.in' rather
-than \h), into pic. Should be possible to use block of diverted text
-in pic. Possibly something similar to T{ and T} in tbl.
-
-Option to provide macro backtraces.
-
-Have a path that is searched by `copy' statement. Set by environment
-variable or command line option.
diff --git a/gnu/usr.bin/groff/pic/common.cc b/gnu/usr.bin/groff/pic/common.cc
deleted file mode 100644
index e83ef312258..00000000000
--- a/gnu/usr.bin/groff/pic/common.cc
+++ /dev/null
@@ -1,497 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-#include "common.h"
-
-// output a dashed circle as a series of arcs
-
-void common_output::dashed_circle(const position &cent, double rad,
- const line_type &lt)
-{
- assert(lt.type == line_type::dashed);
- line_type slt = lt;
- slt.type = line_type::solid;
- double dash_angle = lt.dash_width/rad;
- int ndashes;
- double gap_angle;
- if (dash_angle >= M_PI/4.0) {
- if (dash_angle < M_PI/2.0) {
- gap_angle = M_PI/2.0 - dash_angle;
- ndashes = 4;
- }
- else if (dash_angle < M_PI) {
- gap_angle = M_PI - dash_angle;
- ndashes = 2;
- }
- else {
- circle(cent, rad, slt, -1.0);
- return;
- }
- }
- else {
- ndashes = 4*int(ceil(M_PI/(4.0*dash_angle)));
- gap_angle = (M_PI*2.0)/ndashes - dash_angle;
- }
- for (int i = 0; i < ndashes; i++) {
- double start_angle = i*(dash_angle+gap_angle) - dash_angle/2.0;
- solid_arc(cent, rad, start_angle, start_angle + dash_angle, lt);
- }
-}
-
-// output a dotted circle as a series of dots
-
-void common_output::dotted_circle(const position &cent, double rad,
- const line_type &lt)
-{
- assert(lt.type == line_type::dotted);
- double gap_angle = lt.dash_width/rad;
- int ndots;
- if (gap_angle >= M_PI/2.0) {
- // always have at least 2 dots
- gap_angle = M_PI;
- ndots = 2;
- }
- else {
- ndots = 4*int(M_PI/(2.0*gap_angle));
- gap_angle = (M_PI*2.0)/ndots;
- }
- double ang = 0.0;
- for (int i = 0; i < ndots; i++, ang += gap_angle)
- dot(cent + position(cos(ang), sin(ang))*rad, lt);
-}
-
-// return non-zero iff we can compute a center
-
-int compute_arc_center(const position &start, const position &cent,
- const position &end, position *result)
-{
- // This finds the point along the vector from start to cent that
- // is equidistant between start and end.
- distance c = cent - start;
- distance e = end - start;
- double n = c*e;
- if (n == 0.0)
- return 0;
- *result = start + c*((e*e)/(2.0*n));
- return 1;
-}
-
-// output a dashed arc as a series of arcs
-
-void common_output::dashed_arc(const position &start, const position &cent,
- const position &end, const line_type &lt)
-{
- assert(lt.type == line_type::dashed);
- position c;
- if (!compute_arc_center(start, cent, end, &c)) {
- line(start, &end, 1, lt);
- return;
- }
- distance start_offset = start - c;
- distance end_offset = end - c;
- double start_angle = atan2(start_offset.y, start_offset.x);
- double end_angle = atan2(end_offset.y, end_offset.x);
- double rad = hypot(c - start);
- double dash_angle = lt.dash_width/rad;
- double total_angle = end_angle - start_angle;
- while (total_angle < 0)
- total_angle += M_PI + M_PI;
- if (total_angle <= dash_angle*2.0) {
- solid_arc(cent, rad, start_angle, end_angle, lt);
- return;
- }
- int ndashes = int((total_angle - dash_angle)/(dash_angle*2.0) + .5);
- double dash_and_gap_angle = (total_angle - dash_angle)/ndashes;
- for (int i = 0; i <= ndashes; i++)
- solid_arc(cent, rad, start_angle + i*dash_and_gap_angle,
- start_angle + i*dash_and_gap_angle + dash_angle, lt);
-}
-
-// output a dotted arc as a series of dots
-
-void common_output::dotted_arc(const position &start, const position &cent,
- const position &end, const line_type &lt)
-{
- assert(lt.type == line_type::dotted);
- position c;
- if (!compute_arc_center(start, cent, end, &c)) {
- line(start, &end, 1, lt);
- return;
- }
- distance start_offset = start - c;
- distance end_offset = end - c;
- double start_angle = atan2(start_offset.y, start_offset.x);
- double total_angle = atan2(end_offset.y, end_offset.x) - start_angle;
- while (total_angle < 0)
- total_angle += M_PI + M_PI;
- double rad = hypot(c - start);
- int ndots = int(total_angle/(lt.dash_width/rad) + .5);
- if (ndots == 0)
- dot(start, lt);
- else {
- for (int i = 0; i <= ndots; i++) {
- double a = start_angle + (total_angle*i)/ndots;
- dot(cent + position(cos(a), sin(a))*rad, lt);
- }
- }
-}
-
-void common_output::solid_arc(const position &cent, double rad,
- double start_angle, double end_angle,
- const line_type &lt)
-{
- line_type slt = lt;
- slt.type = line_type::solid;
- arc(cent + position(cos(start_angle), sin(start_angle))*rad,
- cent,
- cent + position(cos(end_angle), sin(end_angle))*rad,
- slt);
-}
-
-
-void common_output::rounded_box(const position &cent, const distance &dim,
- double rad, const line_type &lt, double fill)
-{
- if (fill >= 0.0)
- filled_rounded_box(cent, dim, rad, fill);
- switch (lt.type) {
- case line_type::invisible:
- break;
- case line_type::dashed:
- dashed_rounded_box(cent, dim, rad, lt);
- break;
- case line_type::dotted:
- dotted_rounded_box(cent, dim, rad, lt);
- break;
- case line_type::solid:
- solid_rounded_box(cent, dim, rad, lt);
- break;
- default:
- assert(0);
- }
-}
-
-
-void common_output::dashed_rounded_box(const position &cent,
- const distance &dim, double rad,
- const line_type &lt)
-{
- line_type slt = lt;
- slt.type = line_type::solid;
-
- double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad;
- int n_hor_dashes = int(hor_length/(lt.dash_width*2.0) + .5);
- double hor_gap_width = (n_hor_dashes != 0
- ? hor_length/n_hor_dashes - lt.dash_width
- : 0.0);
-
- double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad;
- int n_vert_dashes = int(vert_length/(lt.dash_width*2.0) + .5);
- double vert_gap_width = (n_vert_dashes != 0
- ? vert_length/n_vert_dashes - lt.dash_width
- : 0.0);
- // Note that each corner arc has to be split into two for dashing,
- // because one part is dashed using vert_gap_width, and the other
- // using hor_gap_width.
- double offset = lt.dash_width/2.0;
- dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
- -M_PI/4.0, 0, slt, lt.dash_width, vert_gap_width, &offset);
- dash_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad),
- cent + position(dim.x/2.0, dim.y/2.0 - rad),
- slt, lt.dash_width, vert_gap_width, &offset);
- dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
- 0, M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);
-
- offset = lt.dash_width/2.0;
- dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
- M_PI/4.0, M_PI/2, slt, lt.dash_width, hor_gap_width, &offset);
- dash_line(cent + position(dim.x/2.0 - rad, dim.y/2.0),
- cent + position(-dim.x/2.0 + rad, dim.y/2.0),
- slt, lt.dash_width, hor_gap_width, &offset);
- dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
- M_PI/2, 3*M_PI/4.0, slt, lt.dash_width, hor_gap_width, &offset);
-
- offset = lt.dash_width/2.0;
- dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
- 3.0*M_PI/4.0, M_PI, slt, lt.dash_width, vert_gap_width, &offset);
- dash_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad),
- cent + position(-dim.x/2.0, -dim.y/2.0 + rad),
- slt, lt.dash_width, vert_gap_width, &offset);
- dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
- M_PI, 5.0*M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);
-
- offset = lt.dash_width/2.0;
- dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
- 5*M_PI/4.0, 3*M_PI/2.0, slt, lt.dash_width, hor_gap_width, &offset);
- dash_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0),
- cent + position(dim.x/2.0 - rad, -dim.y/2.0),
- slt, lt.dash_width, hor_gap_width, &offset);
- dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
- 3*M_PI/2, 7*M_PI/4, slt, lt.dash_width, hor_gap_width, &offset);
-}
-
-// Used by dashed_rounded_box.
-
-void common_output::dash_arc(const position &cent, double rad,
- double start_angle, double end_angle,
- const line_type &lt,
- double dash_width, double gap_width,
- double *offsetp)
-{
- double length = (end_angle - start_angle)*rad;
- double pos = 0.0;
- for (;;) {
- if (*offsetp >= dash_width) {
- double rem = dash_width + gap_width - *offsetp;
- if (pos + rem > length) {
- *offsetp += length - pos;
- break;
- }
- else {
- pos += rem;
- *offsetp = 0.0;
- }
- }
- else {
- double rem = dash_width - *offsetp;
- if (pos + rem > length) {
- solid_arc(cent, rad, start_angle + pos/rad, end_angle, lt);
- *offsetp += length - pos;
- break;
- }
- else {
- solid_arc(cent, rad, start_angle + pos/rad,
- start_angle + (pos + rem)/rad, lt);
- pos += rem;
- *offsetp = dash_width;
- }
- }
- }
-}
-
-// Used by dashed_rounded_box.
-
-void common_output::dash_line(const position &start, const position &end,
- const line_type &lt,
- double dash_width, double gap_width,
- double *offsetp)
-{
- distance dist = end - start;
- double length = hypot(dist);
- if (length == 0.0)
- return;
- double pos = 0.0;
- for (;;) {
- if (*offsetp >= dash_width) {
- double rem = dash_width + gap_width - *offsetp;
- if (pos + rem > length) {
- *offsetp += length - pos;
- break;
- }
- else {
- pos += rem;
- *offsetp = 0.0;
- }
- }
- else {
- double rem = dash_width - *offsetp;
- if (pos + rem > length) {
- line(start + dist*(pos/length), &end, 1, lt);
- *offsetp += length - pos;
- break;
- }
- else {
- position p(start + dist*((pos + rem)/length));
- line(start + dist*(pos/length), &p, 1, lt);
- pos += rem;
- *offsetp = dash_width;
- }
- }
- }
-}
-
-void common_output::dotted_rounded_box(const position &cent,
- const distance &dim, double rad,
- const line_type &lt)
-{
- line_type slt = lt;
- slt.type = line_type::solid;
-
- double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad;
- int n_hor_dots = int(hor_length/lt.dash_width + .5);
- double hor_gap_width = (n_hor_dots != 0
- ? hor_length/n_hor_dots
- : lt.dash_width);
-
- double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad;
- int n_vert_dots = int(vert_length/lt.dash_width + .5);
- double vert_gap_width = (n_vert_dots != 0
- ? vert_length/n_vert_dots
- : lt.dash_width);
- double epsilon = lt.dash_width/(rad*100.0);
-
- double offset = 0.0;
- dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
- -M_PI/4.0, 0, slt, vert_gap_width, &offset);
- dot_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad),
- cent + position(dim.x/2.0, dim.y/2.0 - rad),
- slt, vert_gap_width, &offset);
- dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
- 0, M_PI/4.0 - epsilon, slt, vert_gap_width, &offset);
-
- offset = 0.0;
- dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,
- M_PI/4.0, M_PI/2, slt, hor_gap_width, &offset);
- dot_line(cent + position(dim.x/2.0 - rad, dim.y/2.0),
- cent + position(-dim.x/2.0 + rad, dim.y/2.0),
- slt, hor_gap_width, &offset);
- dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
- M_PI/2, 3*M_PI/4.0 - epsilon, slt, hor_gap_width, &offset);
-
- offset = 0.0;
- dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,
- 3.0*M_PI/4.0, M_PI, slt, vert_gap_width, &offset);
- dot_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad),
- cent + position(-dim.x/2.0, -dim.y/2.0 + rad),
- slt, vert_gap_width, &offset);
- dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
- M_PI, 5.0*M_PI/4.0 - epsilon, slt, vert_gap_width, &offset);
-
- offset = 0.0;
- dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,
- 5*M_PI/4.0, 3*M_PI/2.0, slt, hor_gap_width, &offset);
- dot_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0),
- cent + position(dim.x/2.0 - rad, -dim.y/2.0),
- slt, hor_gap_width, &offset);
- dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,
- 3*M_PI/2, 7*M_PI/4 - epsilon, slt, hor_gap_width, &offset);
-}
-
-// Used by dotted_rounded_box.
-
-void common_output::dot_arc(const position &cent, double rad,
- double start_angle, double end_angle,
- const line_type &lt, double gap_width,
- double *offsetp)
-{
- double length = (end_angle - start_angle)*rad;
- double pos = 0.0;
- for (;;) {
- if (*offsetp == 0.0) {
- double ang = start_angle + pos/rad;
- dot(cent + position(cos(ang), sin(ang))*rad, lt);
- }
- double rem = gap_width - *offsetp;
- if (pos + rem > length) {
- *offsetp += length - pos;
- break;
- }
- else {
- pos += rem;
- *offsetp = 0.0;
- }
- }
-}
-
-// Used by dotted_rounded_box.
-
-void common_output::dot_line(const position &start, const position &end,
- const line_type &lt, double gap_width,
- double *offsetp)
-{
- distance dist = end - start;
- double length = hypot(dist);
- if (length == 0.0)
- return;
- double pos = 0.0;
- for (;;) {
- if (*offsetp == 0.0)
- dot(start + dist*(pos/length), lt);
- double rem = gap_width - *offsetp;
- if (pos + rem > length) {
- *offsetp += length - pos;
- break;
- }
- else {
- pos += rem;
- *offsetp = 0.0;
- }
- }
-}
-
-
-void common_output::solid_rounded_box(const position &cent,
- const distance &dim, double rad,
- const line_type &lt)
-{
- position tem = cent - dim/2.0;
- arc(tem + position(0.0, rad),
- tem + position(rad, rad),
- tem + position(rad, 0.0),
- lt);
- tem = cent + position(-dim.x/2.0, dim.y/2.0);
- arc(tem + position(rad, 0.0),
- tem + position(rad, -rad),
- tem + position(0.0, -rad),
- lt);
- tem = cent + dim/2.0;
- arc(tem + position(0.0, -rad),
- tem + position(-rad, -rad),
- tem + position(-rad, 0.0),
- lt);
- tem = cent + position(dim.x/2.0, -dim.y/2.0);
- arc(tem + position(-rad, 0.0),
- tem + position(-rad, rad),
- tem + position(0.0, rad),
- lt);
- position end;
- end = cent + position(-dim.x/2.0, dim.y/2.0 - rad);
- line(cent - dim/2.0 + position(0.0, rad), &end, 1, lt);
- end = cent + position(dim.x/2.0 - rad, dim.y/2.0);
- line(cent + position(-dim.x/2.0 + rad, dim.y/2.0), &end, 1, lt);
- end = cent + position(dim.x/2.0, -dim.y/2.0 + rad);
- line(cent + position(dim.x/2.0, dim.y/2.0 - rad), &end, 1, lt);
- end = cent + position(-dim.x/2.0 + rad, -dim.y/2.0);
- line(cent + position(dim.x/2.0 - rad, -dim.y/2.0), &end, 1, lt);
-}
-
-void common_output::filled_rounded_box(const position &cent,
- const distance &dim, double rad,
- double fill)
-{
- line_type ilt;
- ilt.type = line_type::invisible;
- circle(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, ilt, fill);
- circle(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, ilt, fill);
- circle(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, ilt, fill);
- circle(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, ilt, fill);
- position vec[4];
- vec[0] = cent + position(dim.x/2.0, dim.y/2.0 - rad);
- vec[1] = cent + position(-dim.x/2.0, dim.y/2.0 - rad);
- vec[2] = cent + position(-dim.x/2.0, -dim.y/2.0 + rad);
- vec[3] = cent + position(dim.x/2.0, -dim.y/2.0 + rad);
- polygon(vec, 4, ilt, fill);
- vec[0] = cent + position(dim.x/2.0 - rad, dim.y/2.0);
- vec[1] = cent + position(-dim.x/2.0 + rad, dim.y/2.0);
- vec[2] = cent + position(-dim.x/2.0 + rad, -dim.y/2.0);
- vec[3] = cent + position(dim.x/2.0 - rad, -dim.y/2.0);
- polygon(vec, 4, ilt, fill);
-}
diff --git a/gnu/usr.bin/groff/pic/common.h b/gnu/usr.bin/groff/pic/common.h
deleted file mode 100644
index 25a6e10c689..00000000000
--- a/gnu/usr.bin/groff/pic/common.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-class common_output : public output {
-private:
- void dash_line(const position &start, const position &end,
- const line_type &lt, double dash_width, double gap_width,
- double *offsetp);
- void dash_arc(const position &cent, double rad,
- double start_angle, double end_angle, const line_type &lt,
- double dash_width, double gap_width, double *offsetp);
- void dot_line(const position &start, const position &end,
- const line_type &lt, double gap_width, double *offsetp);
- void dot_arc(const position &cent, double rad,
- double start_angle, double end_angle, const line_type &lt,
- double gap_width, double *offsetp);
-protected:
- virtual void dot(const position &, const line_type &) = 0;
- void dashed_circle(const position &, double rad, const line_type &);
- void dotted_circle(const position &, double rad, const line_type &);
- void dashed_arc(const position &, const position &, const position &,
- const line_type &);
- void dotted_arc(const position &, const position &, const position &,
- const line_type &);
- virtual void solid_arc(const position &cent, double rad, double start_angle,
- double end_angle, const line_type &lt);
- void dashed_rounded_box(const position &, const distance &, double,
- const line_type &);
- void dotted_rounded_box(const position &, const distance &, double,
- const line_type &);
- void solid_rounded_box(const position &, const distance &, double,
- const line_type &);
- void filled_rounded_box(const position &, const distance &, double, double);
-public:
- void start_picture(double sc, const position &ll, const position &ur) = 0;
- void finish_picture() = 0;
- void circle(const position &, double rad, const line_type &, double) = 0;
- void text(const position &, text_piece *, int, double) = 0;
- void line(const position &, const position *, int n, const line_type &) = 0;
- void polygon(const position *, int n, const line_type &, double) = 0;
- void spline(const position &, const position *, int n,
- const line_type &) = 0;
- void arc(const position &, const position &, const position &,
- const line_type &) = 0;
- void ellipse(const position &, const distance &,
- const line_type &, double) = 0;
- void rounded_box(const position &, const distance &, double,
- const line_type &, double);
-};
-
-int compute_arc_center(const position &start, const position &cent,
- const position &end, position *result);
-
diff --git a/gnu/usr.bin/groff/pic/depend b/gnu/usr.bin/groff/pic/depend
deleted file mode 100644
index 73ac3ab9093..00000000000
--- a/gnu/usr.bin/groff/pic/depend
+++ /dev/null
@@ -1,21 +0,0 @@
-pic.tab.o : pic.tab.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h ../lib/ptable.h object.h
-lex.o : lex.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h ../lib/ptable.h object.h pic.tab.h
-main.o : main.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h
-object.o : object.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h ../lib/ptable.h object.h
-common.o : common.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h common.h
-troff.o : troff.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h common.h
-tex.o : tex.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \
- ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \
- output.h common.h
diff --git a/gnu/usr.bin/groff/pic/lex.cc b/gnu/usr.bin/groff/pic/lex.cc
deleted file mode 100644
index 920938d538e..00000000000
--- a/gnu/usr.bin/groff/pic/lex.cc
+++ /dev/null
@@ -1,1939 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-#include "ptable.h"
-#include "object.h"
-#include "pic.tab.h"
-
-declare_ptable(char)
-implement_ptable(char)
-
-PTABLE(char) macro_table;
-
-class macro_input : public input {
- char *s;
- char *p;
-public:
- macro_input(const char *);
- ~macro_input();
- int get();
- int peek();
-};
-
-class argument_macro_input : public input {
- char *s;
- char *p;
- char *ap;
- int argc;
- char *argv[9];
-public:
- argument_macro_input(const char *, int, char **);
- ~argument_macro_input();
- int get();
- int peek();
-};
-
-input::input() : next(0)
-{
-}
-
-input::~input()
-{
-}
-
-int input::get_location(const char **, int *)
-{
- return 0;
-}
-
-file_input::file_input(FILE *f, const char *fn)
-: lineno(0), ptr(""), filename(fn)
-{
- fp = f;
-}
-
-file_input::~file_input()
-{
- fclose(fp);
-}
-
-int file_input::read_line()
-{
- for (;;) {
- line.clear();
- lineno++;
- for (;;) {
- int c = getc(fp);
- if (c == EOF)
- break;
- else if (illegal_input_char(c))
- lex_error("illegal input character code %1", c);
- else {
- line += char(c);
- if (c == '\n')
- break;
- }
- }
- if (line.length() == 0)
- return 0;
- if (!(line.length() >= 3 && line[0] == '.' && line[1] == 'P'
- && (line[2] == 'S' || line[2] == 'E' || line[2] == 'F')
- && (line.length() == 3 || line[3] == ' ' || line[3] == '\n'
- || compatible_flag))) {
- line += '\0';
- ptr = line.contents();
- return 1;
- }
- }
-}
-
-int file_input::get()
-{
- if (*ptr != '\0' || read_line())
- return (unsigned char)*ptr++;
- else
- return EOF;
-}
-
-int file_input::peek()
-{
- if (*ptr != '\0' || read_line())
- return (unsigned char)*ptr;
- else
- return EOF;
-}
-
-int file_input::get_location(const char **fnp, int *lnp)
-{
- *fnp = filename;
- *lnp = lineno;
- return 1;
-}
-
-macro_input::macro_input(const char *str)
-{
- p = s = strsave(str);
-}
-
-macro_input::~macro_input()
-{
- a_delete s;
-}
-
-int macro_input::get()
-{
- if (p == 0 || *p == '\0')
- return EOF;
- else
- return (unsigned char)*p++;
-}
-
-int macro_input::peek()
-{
- if (p == 0 || *p == '\0')
- return EOF;
- else
- return (unsigned char)*p;
-}
-
-// Character representing $1. Must be illegal input character.
-#define ARG1 14
-
-char *process_body(const char *body)
-{
- char *s = strsave(body);
- int j = 0;
- for (int i = 0; s[i] != '\0'; i++)
- if (s[i] == '$' && s[i+1] >= '0' && s[i+1] <= '9') {
- if (s[i+1] != '0')
- s[j++] = ARG1 + s[++i] - '1';
- }
- else
- s[j++] = s[i];
- s[j] = '\0';
- return s;
-}
-
-
-argument_macro_input::argument_macro_input(const char *body, int ac, char **av)
-: argc(ac), ap(0)
-{
- for (int i = 0; i < argc; i++)
- argv[i] = av[i];
- p = s = process_body(body);
-}
-
-
-argument_macro_input::~argument_macro_input()
-{
- for (int i = 0; i < argc; i++)
- a_delete argv[i];
- a_delete s;
-}
-
-int argument_macro_input::get()
-{
- if (ap) {
- if (*ap != '\0')
- return (unsigned char)*ap++;
- ap = 0;
- }
- if (p == 0)
- return EOF;
- while (*p >= ARG1 && *p <= ARG1 + 8) {
- int i = *p++ - ARG1;
- if (i < argc && argv[i] != 0 && argv[i][0] != '\0') {
- ap = argv[i];
- return (unsigned char)*ap++;
- }
- }
- if (*p == '\0')
- return EOF;
- return (unsigned char)*p++;
-}
-
-int argument_macro_input::peek()
-{
- if (ap) {
- if (*ap != '\0')
- return (unsigned char)*ap;
- ap = 0;
- }
- if (p == 0)
- return EOF;
- while (*p >= ARG1 && *p <= ARG1 + 8) {
- int i = *p++ - ARG1;
- if (i < argc && argv[i] != 0 && argv[i][0] != '\0') {
- ap = argv[i];
- return (unsigned char)*ap;
- }
- }
- if (*p == '\0')
- return EOF;
- return (unsigned char)*p;
-}
-
-class input_stack {
- static input *current_input;
- static int bol_flag;
-public:
- static void push(input *);
- static void clear();
- static int get_char();
- static int peek_char();
- static int get_location(const char **fnp, int *lnp);
- static void push_back(unsigned char c, int was_bol = 0);
- static int bol();
-};
-
-input *input_stack::current_input = 0;
-int input_stack::bol_flag = 0;
-
-inline int input_stack::bol()
-{
- return bol_flag;
-}
-
-void input_stack::clear()
-{
- while (current_input != 0) {
- input *tem = current_input;
- current_input = current_input->next;
- delete tem;
- }
- bol_flag = 1;
-}
-
-void input_stack::push(input *in)
-{
- in->next = current_input;
- current_input = in;
-}
-
-void lex_init(input *top)
-{
- input_stack::clear();
- input_stack::push(top);
-}
-
-void lex_cleanup()
-{
- while (input_stack::get_char() != EOF)
- ;
-}
-
-int input_stack::get_char()
-{
- while (current_input != 0) {
- int c = current_input->get();
- if (c != EOF) {
- bol_flag = c == '\n';
- return c;
- }
- // don't pop the top-level input off the stack
- if (current_input->next == 0)
- return EOF;
- input *tem = current_input;
- current_input = current_input->next;
- delete tem;
- }
- return EOF;
-}
-
-int input_stack::peek_char()
-{
- while (current_input != 0) {
- int c = current_input->peek();
- if (c != EOF)
- return c;
- if (current_input->next == 0)
- return EOF;
- input *tem = current_input;
- current_input = current_input->next;
- delete tem;
- }
- return EOF;
-}
-
-class char_input : public input {
- int c;
-public:
- char_input(int);
- int get();
- int peek();
-};
-
-char_input::char_input(int n) : c((unsigned char)n)
-{
-}
-
-int char_input::get()
-{
- int n = c;
- c = EOF;
- return n;
-}
-
-int char_input::peek()
-{
- return c;
-}
-
-void input_stack::push_back(unsigned char c, int was_bol)
-{
- push(new char_input(c));
- bol_flag = was_bol;
-}
-
-int input_stack::get_location(const char **fnp, int *lnp)
-{
- for (input *p = current_input; p; p = p->next)
- if (p->get_location(fnp, lnp))
- return 1;
- return 0;
-}
-
-string context_buffer;
-
-string token_buffer;
-double token_double;
-int token_int;
-
-void interpolate_macro_with_args(const char *body)
-{
- char *argv[9];
- int argc = 0;
- int i;
- for (i = 0; i < 9; i++)
- argv[i] = 0;
- int level = 0;
- int c;
- enum { NORMAL, IN_STRING, IN_STRING_QUOTED } state = NORMAL;
- do {
- token_buffer.clear();
- for (;;) {
- c = input_stack::get_char();
- if (c == EOF) {
- lex_error("end of input while scanning macro arguments");
- break;
- }
- if (state == NORMAL && level == 0 && (c == ',' || c == ')')) {
- if (token_buffer.length() > 0) {
- token_buffer += '\0';
- argv[argc] = strsave(token_buffer.contents());
- }
- // for `foo()', argc = 0
- if (argc > 0 || c != ')' || i > 0)
- argc++;
- break;
- }
- token_buffer += char(c);
- switch (state) {
- case NORMAL:
- if (c == '"')
- state = IN_STRING;
- else if (c == '(')
- level++;
- else if (c == ')')
- level--;
- break;
- case IN_STRING:
- if (c == '"')
- state = NORMAL;
- else if (c == '\\')
- state = IN_STRING_QUOTED;
- break;
- case IN_STRING_QUOTED:
- state = IN_STRING;
- break;
- }
- }
- } while (c != ')' && c != EOF);
- input_stack::push(new argument_macro_input(body, argc, argv));
-}
-
-static int docmp(const char *s1, int n1, const char *s2, int n2)
-{
- if (n1 < n2) {
- int r = memcmp(s1, s2, n1);
- return r ? r : -1;
- }
- else if (n1 > n2) {
- int r = memcmp(s1, s2, n2);
- return r ? r : 1;
- }
- else
- return memcmp(s1, s2, n1);
-}
-
-int lookup_keyword(const char *str, int len)
-{
- static struct keyword {
- const char *name;
- int token;
- } table[] = {
- { "Here", HERE },
- { "above", ABOVE },
- { "aligned", ALIGNED },
- { "and", AND },
- { "arc", ARC },
- { "arrow", ARROW },
- { "at", AT },
- { "atan2", ATAN2 },
- { "below", BELOW },
- { "between", BETWEEN },
- { "bottom", BOTTOM },
- { "box", BOX },
- { "by", BY },
- { "ccw", CCW },
- { "center", CENTER },
- { "chop", CHOP },
- { "circle", CIRCLE },
- { "command", COMMAND },
- { "copy", COPY },
- { "cos", COS },
- { "cw", CW },
- { "dashed", DASHED },
- { "define", DEFINE },
- { "diam", DIAMETER },
- { "diameter", DIAMETER },
- { "do", DO },
- { "dotted", DOTTED },
- { "down", DOWN },
- { "ellipse", ELLIPSE },
- { "else", ELSE },
- { "end", END },
- { "exp", EXP },
- { "fill", FILL },
- { "filled", FILL },
- { "for", FOR },
- { "from", FROM },
- { "height", HEIGHT },
- { "ht", HEIGHT },
- { "if", IF },
- { "int", INT },
- { "invis", INVISIBLE },
- { "invisible", INVISIBLE },
- { "last", LAST },
- { "left", LEFT },
- { "line", LINE },
- { "ljust", LJUST },
- { "log", LOG },
- { "lower", LOWER },
- { "max", K_MAX },
- { "min", K_MIN },
- { "move", MOVE },
- { "of", OF },
- { "plot", PLOT },
- { "print", PRINT },
- { "rad", RADIUS },
- { "radius", RADIUS },
- { "rand", RAND },
- { "reset", RESET },
- { "right", RIGHT },
- { "rjust", RJUST },
- { "same", SAME },
- { "sh", SH },
- { "sin", SIN },
- { "spline", SPLINE },
- { "sprintf", SPRINTF },
- { "sqrt", SQRT },
- { "start", START },
- { "the", THE },
- { "then", THEN },
- { "thick", THICKNESS },
- { "thickness", THICKNESS },
- { "thru", THRU },
- { "to", TO },
- { "top", TOP },
- { "undef", UNDEF },
- { "until", UNTIL },
- { "up", UP },
- { "upper", UPPER },
- { "way", WAY },
- { "wid", WIDTH },
- { "width", WIDTH },
- { "with", WITH },
- };
-
- const keyword *start = table;
- const keyword *end = table + sizeof(table)/sizeof(table[0]);
- while (start < end) {
- // start <= target < end
- const keyword *mid = start + (end - start)/2;
-
- int cmp = docmp(str, len, mid->name, strlen(mid->name));
- if (cmp == 0)
- return mid->token;
- if (cmp < 0)
- end = mid;
- else
- start = mid + 1;
- }
- return 0;
-}
-
-int get_token_after_dot(int c)
-{
- // get_token deals with the case where c is a digit
- switch (c) {
- case 'h':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- context_buffer = ".ht";
- return DOT_HT;
- }
- else if (c == 'e') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'i') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'g') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'h') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- context_buffer = ".height";
- return DOT_HT;
- }
- input_stack::push_back('h');
- }
- input_stack::push_back('g');
- }
- input_stack::push_back('i');
- }
- input_stack::push_back('e');
- }
- input_stack::push_back('h');
- return '.';
- case 'x':
- input_stack::get_char();
- context_buffer = ".x";
- return DOT_X;
- case 'y':
- input_stack::get_char();
- context_buffer = ".y";
- return DOT_Y;
- case 'c':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'e') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'n') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'e') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'r') {
- input_stack::get_char();
- context_buffer = ".center";
- return DOT_C;
- }
- input_stack::push_back('e');
- }
- input_stack::push_back('t');
- }
- input_stack::push_back('n');
- }
- input_stack::push_back('e');
- }
- context_buffer = ".c";
- return DOT_C;
- case 'n':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'e') {
- input_stack::get_char();
- context_buffer = ".ne";
- return DOT_NE;
- }
- else if (c == 'w') {
- input_stack::get_char();
- context_buffer = ".nw";
- return DOT_NW;
- }
- else {
- context_buffer = ".n";
- return DOT_N;
- }
- break;
- case 'e':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'n') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'd') {
- input_stack::get_char();
- context_buffer = ".end";
- return DOT_END;
- }
- input_stack::push_back('n');
- context_buffer = ".e";
- return DOT_E;
- }
- context_buffer = ".e";
- return DOT_E;
- case 'w':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'i') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'd') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'h') {
- input_stack::get_char();
- context_buffer = ".width";
- return DOT_WID;
- }
- input_stack::push_back('t');
- }
- context_buffer = ".wid";
- return DOT_WID;
- }
- input_stack::push_back('i');
- }
- context_buffer = ".w";
- return DOT_W;
- case 's':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'e') {
- input_stack::get_char();
- context_buffer = ".se";
- return DOT_SE;
- }
- else if (c == 'w') {
- input_stack::get_char();
- context_buffer = ".sw";
- return DOT_SW;
- }
- else {
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'a') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'r') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- context_buffer = ".start";
- return DOT_START;
- }
- input_stack::push_back('r');
- }
- input_stack::push_back('a');
- }
- input_stack::push_back('t');
- }
- context_buffer = ".s";
- return DOT_S;
- }
- break;
- case 't':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'o') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'p') {
- input_stack::get_char();
- context_buffer = ".top";
- return DOT_N;
- }
- input_stack::push_back('o');
- }
- context_buffer = ".t";
- return DOT_N;
- case 'l':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'e') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'f') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- context_buffer = ".left";
- return DOT_W;
- }
- input_stack::push_back('f');
- }
- input_stack::push_back('e');
- }
- context_buffer = ".l";
- return DOT_W;
- case 'r':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'a') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'd') {
- input_stack::get_char();
- context_buffer = ".rad";
- return DOT_RAD;
- }
- input_stack::push_back('a');
- }
- else if (c == 'i') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'g') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'h') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- context_buffer = ".right";
- return DOT_E;
- }
- input_stack::push_back('h');
- }
- input_stack::push_back('g');
- }
- input_stack::push_back('i');
- }
- context_buffer = ".r";
- return DOT_E;
- case 'b':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'o') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'o') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'm') {
- input_stack::get_char();
- context_buffer = ".bottom";
- return DOT_S;
- }
- input_stack::push_back('o');
- }
- input_stack::push_back('t');
- }
- context_buffer = ".bot";
- return DOT_S;
- }
- input_stack::push_back('o');
- }
- context_buffer = ".b";
- return DOT_S;
- default:
- context_buffer = '.';
- return '.';
- }
-}
-
-int get_token(int lookup_flag)
-{
- context_buffer.clear();
- for (;;) {
- int n = 0;
- int bol = input_stack::bol();
- int c = input_stack::get_char();
- if (bol && c == command_char) {
- token_buffer.clear();
- token_buffer += c;
- // the newline is not part of the token
- for (;;) {
- c = input_stack::peek_char();
- if (c == EOF || c == '\n')
- break;
- input_stack::get_char();
- token_buffer += char(c);
- }
- context_buffer = token_buffer;
- return COMMAND_LINE;
- }
- switch (c) {
- case EOF:
- return EOF;
- case ' ':
- case '\t':
- break;
- case '\\':
- {
- int d = input_stack::peek_char();
- if (d != '\n') {
- context_buffer = '\\';
- return '\\';
- }
- input_stack::get_char();
- break;
- }
- case '#':
- do {
- c = input_stack::get_char();
- } while (c != '\n' && c != EOF);
- if (c == '\n')
- context_buffer = '\n';
- return c;
- case '"':
- context_buffer = '"';
- token_buffer.clear();
- for (;;) {
- c = input_stack::get_char();
- if (c == '\\') {
- context_buffer += '\\';
- c = input_stack::peek_char();
- if (c == '"') {
- input_stack::get_char();
- token_buffer += '"';
- context_buffer += '"';
- }
- else
- token_buffer += '\\';
- }
- else if (c == '\n') {
- error("newline in string");
- break;
- }
- else if (c == EOF) {
- error("missing `\"'");
- break;
- }
- else if (c == '"') {
- context_buffer += '"';
- break;
- }
- else {
- context_buffer += char(c);
- token_buffer += char(c);
- }
- }
- return TEXT;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- int overflow = 0;
- n = 0;
- for (;;) {
- if (n > (INT_MAX - 9)/10) {
- overflow = 1;
- break;
- }
- n *= 10;
- n += c - '0';
- context_buffer += char(c);
- c = input_stack::peek_char();
- if (c == EOF || !csdigit(c))
- break;
- c = input_stack::get_char();
- }
- token_double = n;
- if (overflow) {
- for (;;) {
- token_double *= 10.0;
- token_double += c - '0';
- context_buffer += char(c);
- c = input_stack::peek_char();
- if (c == EOF || !csdigit(c))
- break;
- c = input_stack::get_char();
- }
- // if somebody asks for 1000000000000th, we will silently
- // give them INT_MAXth
- double temp = token_double; // work around gas 1.34/sparc bug
- if (token_double > INT_MAX)
- n = INT_MAX;
- else
- n = int(temp);
- }
- }
- switch (c) {
- case 'i':
- case 'I':
- context_buffer += char(c);
- input_stack::get_char();
- return NUMBER;
- case '.':
- {
- context_buffer += '.';
- input_stack::get_char();
- got_dot:
- double factor = 1.0;
- for (;;) {
- c = input_stack::peek_char();
- if (!c == EOF || !csdigit(c))
- break;
- input_stack::get_char();
- context_buffer += char(c);
- factor /= 10.0;
- if (c != '0')
- token_double += factor*(c - '0');
- }
- if (c != 'e' && c != 'E') {
- if (c == 'i' || c == 'I') {
- context_buffer += char(c);
- input_stack::get_char();
- }
- return NUMBER;
- }
- }
- // fall through
- case 'e':
- case 'E':
- {
- int echar = c;
- input_stack::get_char();
- c = input_stack::peek_char();
- int sign = '+';
- if (c == '+' || c == '-') {
- sign = c;
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == EOF || !csdigit(c)) {
- input_stack::push_back(sign);
- input_stack::push_back(echar);
- return NUMBER;
- }
- context_buffer += char(echar);
- context_buffer += char(sign);
- }
- else {
- if (c == EOF || !csdigit(c)) {
- input_stack::push_back(echar);
- return NUMBER;
- }
- context_buffer += char(echar);
- }
- input_stack::get_char();
- context_buffer += char(c);
- n = c - '0';
- for (;;) {
- c = input_stack::peek_char();
- if (c == EOF || !csdigit(c))
- break;
- input_stack::get_char();
- context_buffer += char(c);
- n = n*10 + (c - '0');
- }
- if (sign == '-')
- n = -n;
- if (c == 'i' || c == 'I') {
- context_buffer += char(c);
- input_stack::get_char();
- }
- token_double *= pow(10.0, n);
- return NUMBER;
- }
- case 'n':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'd') {
- input_stack::get_char();
- token_int = n;
- context_buffer += "nd";
- return ORDINAL;
- }
- input_stack::push_back('n');
- return NUMBER;
- case 'r':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'd') {
- input_stack::get_char();
- token_int = n;
- context_buffer += "rd";
- return ORDINAL;
- }
- input_stack::push_back('r');
- return NUMBER;
- case 't':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'h') {
- input_stack::get_char();
- token_int = n;
- context_buffer += "th";
- return ORDINAL;
- }
- input_stack::push_back('t');
- return NUMBER;
- case 's':
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- token_int = n;
- context_buffer += "st";
- return ORDINAL;
- }
- input_stack::push_back('s');
- return NUMBER;
- default:
- return NUMBER;
- }
- break;
- case '\'':
- {
- c = input_stack::peek_char();
- if (c == 't') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == 'h') {
- input_stack::get_char();
- context_buffer = "'th";
- return TH;
- }
- else
- input_stack::push_back('t');
- }
- context_buffer = "'";
- return '\'';
- }
- case '.':
- {
- c = input_stack::peek_char();
- if (c != EOF && csdigit(c)) {
- n = 0;
- token_double = 0.0;
- context_buffer = '.';
- goto got_dot;
- }
- return get_token_after_dot(c);
- }
- case '<':
- c = input_stack::peek_char();
- if (c == '-') {
- input_stack::get_char();
- c = input_stack::peek_char();
- if (c == '>') {
- input_stack::get_char();
- context_buffer = "<->";
- return DOUBLE_ARROW_HEAD;
- }
- context_buffer = "<-";
- return LEFT_ARROW_HEAD;
- }
- else if (c == '=') {
- input_stack::get_char();
- context_buffer = "<=";
- return LESSEQUAL;
- }
- context_buffer = "<";
- return '<';
- case '-':
- c = input_stack::peek_char();
- if (c == '>') {
- input_stack::get_char();
- context_buffer = "->";
- return RIGHT_ARROW_HEAD;
- }
- context_buffer = "-";
- return '-';
- case '!':
- c = input_stack::peek_char();
- if (c == '=') {
- input_stack::get_char();
- context_buffer = "!=";
- return NOTEQUAL;
- }
- context_buffer = "!";
- return '!';
- case '>':
- c = input_stack::peek_char();
- if (c == '=') {
- input_stack::get_char();
- context_buffer = ">=";
- return GREATEREQUAL;
- }
- context_buffer = ">";
- return '>';
- case '=':
- c = input_stack::peek_char();
- if (c == '=') {
- input_stack::get_char();
- context_buffer = "==";
- return EQUALEQUAL;
- }
- context_buffer = "=";
- return '=';
- case '&':
- c = input_stack::peek_char();
- if (c == '&') {
- input_stack::get_char();
- context_buffer = "&&";
- return ANDAND;
- }
- context_buffer = "&";
- return '&';
- case '|':
- c = input_stack::peek_char();
- if (c == '|') {
- input_stack::get_char();
- context_buffer = "||";
- return OROR;
- }
- context_buffer = "|";
- return '|';
- default:
- if (c != EOF && csalpha(c)) {
- token_buffer.clear();
- token_buffer = c;
- for (;;) {
- c = input_stack::peek_char();
- if (c == EOF || (!csalnum(c) && c != '_'))
- break;
- input_stack::get_char();
- token_buffer += char(c);
- }
- int tok = lookup_keyword(token_buffer.contents(),
- token_buffer.length());
- if (tok != 0) {
- context_buffer = token_buffer;
- return tok;
- }
- char *def = 0;
- if (lookup_flag) {
- token_buffer += '\0';
- def = macro_table.lookup(token_buffer.contents());
- token_buffer.set_length(token_buffer.length() - 1);
- if (def) {
- if (c == '(') {
- input_stack::get_char();
- interpolate_macro_with_args(def);
- }
- else
- input_stack::push(new macro_input(def));
- }
- }
- if (!def) {
- context_buffer = token_buffer;
- if (csupper(token_buffer[0]))
- return LABEL;
- else
- return VARIABLE;
- }
- }
- else {
- context_buffer = char(c);
- return (unsigned char)c;
- }
- break;
- }
- }
-}
-
-int get_delimited()
-{
- token_buffer.clear();
- int c = input_stack::get_char();
- while (c == ' ' || c == '\t' || c == '\n')
- c = input_stack::get_char();
- if (c == EOF) {
- lex_error("missing delimiter");
- return 0;
- }
- context_buffer = char(c);
- int had_newline = 0;
- int start = c;
- int level = 0;
- enum { NORMAL, IN_STRING, IN_STRING_QUOTED, DELIM_END } state = NORMAL;
- for (;;) {
- c = input_stack::get_char();
- if (c == EOF) {
- lex_error("missing closing delimiter");
- return 0;
- }
- if (c == '\n')
- had_newline = 1;
- else if (!had_newline)
- context_buffer += char(c);
- switch (state) {
- case NORMAL:
- if (start == '{') {
- if (c == '{') {
- level++;
- break;
- }
- if (c == '}') {
- if (--level < 0)
- state = DELIM_END;
- break;
- }
- }
- else {
- if (c == start) {
- state = DELIM_END;
- break;
- }
- }
- if (c == '"')
- state = IN_STRING;
- break;
- case IN_STRING_QUOTED:
- if (c == '\n')
- state = NORMAL;
- else
- state = IN_STRING;
- break;
- case IN_STRING:
- if (c == '"' || c == '\n')
- state = NORMAL;
- else if (c == '\\')
- state = IN_STRING_QUOTED;
- break;
- case DELIM_END:
- // This case it just to shut cfront 2.0 up.
- default:
- assert(0);
- }
- if (state == DELIM_END)
- break;
- token_buffer += c;
- }
- return 1;
-}
-
-void do_define()
-{
- int t = get_token(0); // do not expand what we are defining
- if (t != VARIABLE && t != LABEL) {
- lex_error("can only define variable or placename");
- return;
- }
- token_buffer += '\0';
- string nm = token_buffer;
- const char *name = nm.contents();
- if (!get_delimited())
- return;
- token_buffer += '\0';
- macro_table.define(name, strsave(token_buffer.contents()));
-}
-
-void do_undef()
-{
- int t = get_token(0); // do not expand what we are undefining
- if (t != VARIABLE && t != LABEL) {
- lex_error("can only define variable or placename");
- return;
- }
- token_buffer += '\0';
- macro_table.define(token_buffer.contents(), 0);
-}
-
-
-class for_input : public input {
- char *var;
- char *body;
- double to;
- int by_is_multiplicative;
- double by;
- const char *p;
- int done_newline;
-public:
- for_input(char *, double, int, double, char *);
- ~for_input();
- int get();
- int peek();
-};
-
-for_input::for_input(char *vr, double t, int bim, double b, char *bd)
-: var(vr), to(t), by_is_multiplicative(bim), by(b), body(bd), p(body),
- done_newline(0)
-{
-}
-
-for_input::~for_input()
-{
- a_delete var;
- a_delete body;
-}
-
-int for_input::get()
-{
- if (p == 0)
- return EOF;
- for (;;) {
- if (*p != '\0')
- return (unsigned char)*p++;
- if (!done_newline) {
- done_newline = 1;
- return '\n';
- }
- double val;
- if (!lookup_variable(var, &val)) {
- lex_error("body of `for' terminated enclosing block");
- return EOF;
- }
- if (by_is_multiplicative)
- val *= by;
- else
- val += by;
- define_variable(var, val);
- if (val > to) {
- p = 0;
- return EOF;
- }
- p = body;
- done_newline = 0;
- }
-}
-
-int for_input::peek()
-{
- if (p == 0)
- return EOF;
- if (*p != '\0')
- return (unsigned char)*p;
- if (!done_newline)
- return '\n';
- double val;
- if (!lookup_variable(var, &val))
- return EOF;
- if (by_is_multiplicative) {
- if (val * by > to)
- return EOF;
- }
- else {
- if (val + by > to)
- return EOF;
- }
- if (*body == '\0')
- return EOF;
- return (unsigned char)*body;
-}
-
-void do_for(char *var, double from, double to, int by_is_multiplicative,
- double by, char *body)
-{
- define_variable(var, from);
- if (from <= to)
- input_stack::push(new for_input(var, to, by_is_multiplicative, by, body));
-}
-
-
-void do_copy(const char *filename)
-{
- errno = 0;
- FILE *fp = fopen(filename, "r");
- if (fp == 0) {
- lex_error("can't open `%1': %2", filename, strerror(errno));
- return;
- }
- input_stack::push(new file_input(fp, filename));
-}
-
-class copy_thru_input : public input {
- int done;
- char *body;
- char *until;
- const char *p;
- const char *ap;
- int argv[9];
- int argc;
- string line;
- int get_line();
- virtual int inget() = 0;
-public:
- copy_thru_input(const char *b, const char *u);
- ~copy_thru_input();
- int get();
- int peek();
-};
-
-class copy_file_thru_input : public copy_thru_input {
- input *in;
-public:
- copy_file_thru_input(input *, const char *b, const char *u);
- ~copy_file_thru_input();
- int inget();
-};
-
-copy_file_thru_input::copy_file_thru_input(input *i, const char *b,
- const char *u)
-: in(i), copy_thru_input(b, u)
-{
-}
-
-copy_file_thru_input::~copy_file_thru_input()
-{
- delete in;
-}
-
-int copy_file_thru_input::inget()
-{
- if (!in)
- return EOF;
- else
- return in->get();
-}
-
-class copy_rest_thru_input : public copy_thru_input {
-public:
- copy_rest_thru_input(const char *, const char *u);
- int inget();
-};
-
-copy_rest_thru_input::copy_rest_thru_input(const char *b, const char *u)
-: copy_thru_input(b, u)
-{
-}
-
-int copy_rest_thru_input::inget()
-{
- while (next != 0) {
- int c = next->get();
- if (c != EOF)
- return c;
- if (next->next == 0)
- return EOF;
- input *tem = next;
- next = next->next;
- delete tem;
- }
- return EOF;
-
-}
-
-copy_thru_input::copy_thru_input(const char *b, const char *u)
-: done(0)
-{
- ap = 0;
- body = process_body(b);
- p = 0;
- until = strsave(u);
-}
-
-
-copy_thru_input::~copy_thru_input()
-{
- a_delete body;
- a_delete until;
-}
-
-int copy_thru_input::get()
-{
- if (ap) {
- if (*ap != '\0')
- return (unsigned char)*ap++;
- ap = 0;
- }
- for (;;) {
- if (p == 0) {
- if (!get_line())
- break;
- p = body;
- }
- if (*p == '\0') {
- p = 0;
- return '\n';
- }
- while (*p >= ARG1 && *p <= ARG1 + 8) {
- int i = *p++ - ARG1;
- if (i < argc && line[argv[i]] != '\0') {
- ap = line.contents() + argv[i];
- return (unsigned char)*ap++;
- }
- }
- if (*p != '\0')
- return (unsigned char)*p++;
- }
- return EOF;
-}
-
-int copy_thru_input::peek()
-{
- if (ap) {
- if (*ap != '\0')
- return (unsigned char)*ap;
- ap = 0;
- }
- for (;;) {
- if (p == 0) {
- if (!get_line())
- break;
- p = body;
- }
- if (*p == '\0')
- return '\n';
- while (*p >= ARG1 && *p <= ARG1 + 8) {
- int i = *p++ - ARG1;
- if (i < argc && line[argv[i]] != '\0') {
- ap = line.contents() + argv[i];
- return (unsigned char)*ap;
- }
- }
- if (*p != '\0')
- return (unsigned char)*p;
- }
- return EOF;
-}
-
-int copy_thru_input::get_line()
-{
- if (done)
- return 0;
- line.clear();
- argc = 0;
- int c = inget();
- for (;;) {
- while (c == ' ')
- c = inget();
- if (c == EOF || c == '\n')
- break;
- if (argc == 9) {
- do {
- c = inget();
- } while (c != '\n' && c != EOF);
- break;
- }
- argv[argc++] = line.length();
- do {
- line += char(c);
- c = inget();
- } while (c != ' ' && c != '\n');
- line += '\0';
- }
- if (until != 0 && argc > 0 && strcmp(&line[argv[0]], until) == 0) {
- done = 1;
- return 0;
- }
- return argc > 0 || c == '\n';
-}
-
-class simple_file_input : public input {
- const char *filename;
- int lineno;
- FILE *fp;
-public:
- simple_file_input(FILE *, const char *);
- ~simple_file_input();
- int get();
- int peek();
- int get_location(const char **, int *);
-};
-
-simple_file_input::simple_file_input(FILE *p, const char *s)
-: filename(s), fp(p), lineno(1)
-{
-}
-
-simple_file_input::~simple_file_input()
-{
- // don't delete the filename
- fclose(fp);
-}
-
-int simple_file_input::get()
-{
- int c = getc(fp);
- while (illegal_input_char(c)) {
- error("illegal input character code %1", c);
- c = getc(fp);
- }
- if (c == '\n')
- lineno++;
- return c;
-}
-
-int simple_file_input::peek()
-{
- int c = getc(fp);
- while (illegal_input_char(c)) {
- error("illegal input character code %1", c);
- c = getc(fp);
- }
- if (c != EOF)
- ungetc(c, fp);
- return c;
-}
-
-int simple_file_input::get_location(const char **fnp, int *lnp)
-{
- *fnp = filename;
- *lnp = lineno;
- return 1;
-}
-
-
-void copy_file_thru(const char *filename, const char *body, const char *until)
-{
- errno = 0;
- FILE *fp = fopen(filename, "r");
- if (fp == 0) {
- lex_error("can't open `%1': %2", filename, strerror(errno));
- return;
- }
- input *in = new copy_file_thru_input(new simple_file_input(fp, filename),
- body, until);
- input_stack::push(in);
-}
-
-void copy_rest_thru(const char *body, const char *until)
-{
- input_stack::push(new copy_rest_thru_input(body, until));
-}
-
-void push_body(const char *s)
-{
- input_stack::push(new char_input('\n'));
- input_stack::push(new macro_input(s));
-}
-
-int delim_flag = 0;
-
-char *get_thru_arg()
-{
- int c = input_stack::peek_char();
- while (c == ' ') {
- input_stack::get_char();
- c = input_stack::peek_char();
- }
- if (c != EOF && csalpha(c)) {
- // looks like a macro
- input_stack::get_char();
- token_buffer = c;
- for (;;) {
- c = input_stack::peek_char();
- if (c == EOF || (!csalnum(c) && c != '_'))
- break;
- input_stack::get_char();
- token_buffer += char(c);
- }
- context_buffer = token_buffer;
- token_buffer += '\0';
- char *def = macro_table.lookup(token_buffer.contents());
- if (def)
- return strsave(def);
- // I guess it wasn't a macro after all; so push the macro name back.
- // -2 because we added a '\0'
- for (int i = token_buffer.length() - 2; i >= 0; i--)
- input_stack::push_back(token_buffer[i]);
- }
- if (get_delimited()) {
- token_buffer += '\0';
- return strsave(token_buffer.contents());
- }
- else
- return 0;
-}
-
-int lookahead_token = -1;
-string old_context_buffer;
-
-void do_lookahead()
-{
- if (lookahead_token == -1) {
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- }
-}
-
-int yylex()
-{
- if (delim_flag) {
- assert(lookahead_token == -1);
- if (delim_flag == 2) {
- if ((yylval.str = get_thru_arg()) != 0)
- return DELIMITED;
- else
- return 0;
- }
- else {
- if (get_delimited()) {
- token_buffer += '\0';
- yylval.str = strsave(token_buffer.contents());
- return DELIMITED;
- }
- else
- return 0;
- }
- }
- for (;;) {
- int t;
- if (lookahead_token >= 0) {
- t = lookahead_token;
- lookahead_token = -1;
- }
- else
- t = get_token(1);
- switch (t) {
- case '\n':
- return ';';
- case EOF:
- return 0;
- case DEFINE:
- do_define();
- break;
- case UNDEF:
- do_undef();
- break;
- case ORDINAL:
- yylval.n = token_int;
- return t;
- case NUMBER:
- yylval.x = token_double;
- return t;
- case COMMAND_LINE:
- case TEXT:
- token_buffer += '\0';
- if (!input_stack::get_location(&yylval.lstr.filename,
- &yylval.lstr.lineno)) {
- yylval.lstr.filename = 0;
- yylval.lstr.lineno = -1;
- }
- yylval.lstr.str = strsave(token_buffer.contents());
- return t;
- case LABEL:
- case VARIABLE:
- token_buffer += '\0';
- yylval.str = strsave(token_buffer.contents());
- return t;
- case LEFT:
- // change LEFT to LEFT_CORNER when followed by OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token == OF)
- return LEFT_CORNER;
- else
- return t;
- case RIGHT:
- // change RIGHT to RIGHT_CORNER when followed by OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token == OF)
- return RIGHT_CORNER;
- else
- return t;
- case UPPER:
- // recognise UPPER only before LEFT or RIGHT
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != LEFT && lookahead_token != RIGHT) {
- yylval.str = strsave("upper");
- return VARIABLE;
- }
- else
- return t;
- case LOWER:
- // recognise LOWER only before LEFT or RIGHT
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != LEFT && lookahead_token != RIGHT) {
- yylval.str = strsave("lower");
- return VARIABLE;
- }
- else
- return t;
- case TOP:
- // recognise TOP only before OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != OF) {
- yylval.str = strsave("top");
- return VARIABLE;
- }
- else
- return t;
- case BOTTOM:
- // recognise BOTTOM only before OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != OF) {
- yylval.str = strsave("bottom");
- return VARIABLE;
- }
- else
- return t;
- case CENTER:
- // recognise CENTER only before OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != OF) {
- yylval.str = strsave("center");
- return VARIABLE;
- }
- else
- return t;
- case START:
- // recognise START only before OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != OF) {
- yylval.str = strsave("start");
- return VARIABLE;
- }
- else
- return t;
- case END:
- // recognise END only before OF
- old_context_buffer = context_buffer;
- lookahead_token = get_token(1);
- if (lookahead_token != OF) {
- yylval.str = strsave("end");
- return VARIABLE;
- }
- else
- return t;
- default:
- return t;
- }
- }
-}
-
-void lex_error(const char *message,
- const errarg &arg1,
- const errarg &arg2,
- const errarg &arg3)
-{
- const char *filename;
- int lineno;
- if (!input_stack::get_location(&filename, &lineno))
- error(message, arg1, arg2, arg3);
- else
- error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3);
-}
-
-void lex_warning(const char *message,
- const errarg &arg1,
- const errarg &arg2,
- const errarg &arg3)
-{
- const char *filename;
- int lineno;
- if (!input_stack::get_location(&filename, &lineno))
- warning(message, arg1, arg2, arg3);
- else
- warning_with_file_and_line(filename, lineno, message, arg1, arg2, arg3);
-}
-
-void yyerror(const char *s)
-{
- const char *filename;
- int lineno;
- const char *context = 0;
- if (lookahead_token == -1) {
- if (context_buffer.length() > 0) {
- context_buffer += '\0';
- context = context_buffer.contents();
- }
- }
- else {
- if (old_context_buffer.length() > 0) {
- old_context_buffer += '\0';
- context = old_context_buffer.contents();
- }
- }
- if (!input_stack::get_location(&filename, &lineno)) {
- if (context) {
- if (context[0] == '\n' && context[1] == '\0')
- error("%1 before newline", s);
- else
- error("%1 before `%2'", s, context);
- }
- else
- error("%1 at end of picture", s);
- }
- else {
- if (context) {
- if (context[0] == '\n' && context[1] == '\0')
- error_with_file_and_line(filename, lineno, "%1 before newline", s);
- else
- error_with_file_and_line(filename, lineno, "%1 before `%2'",
- s, context);
- }
- else
- error_with_file_and_line(filename, lineno, "%1 at end of picture", s);
- }
-}
-
diff --git a/gnu/usr.bin/groff/pic/main.cc b/gnu/usr.bin/groff/pic/main.cc
deleted file mode 100644
index 87beb5dc285..00000000000
--- a/gnu/usr.bin/groff/pic/main.cc
+++ /dev/null
@@ -1,621 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-
-extern int yyparse();
-
-output *out;
-
-int flyback_flag;
-int zero_length_line_flag = 0;
-// Non-zero means we're using a groff driver.
-int driver_extension_flag = 1;
-int compatible_flag = 0;
-int safer_flag = 0;
-int command_char = '.'; // the character that introduces lines
- // that should be passed through tranparently
-static int lf_flag = 1; // non-zero if we should attempt to understand
- // lines beginning with `.lf'
-
-// Non-zero means a parse error was encountered.
-static int had_parse_error = 0;
-
-void do_file(const char *filename);
-
-class top_input : public input {
- FILE *fp;
- int bol;
- int eof;
- int push_back[3];
- int start_lineno;
-public:
- top_input(FILE *);
- int get();
- int peek();
- int get_location(const char **, int *);
-};
-
-top_input::top_input(FILE *p) : fp(p), bol(1), eof(0)
-{
- push_back[0] = push_back[1] = push_back[2] = EOF;
- start_lineno = current_lineno;
-}
-
-int top_input::get()
-{
- if (eof)
- return EOF;
- if (push_back[2] != EOF) {
- int c = push_back[2];
- push_back[2] = EOF;
- return c;
- }
- else if (push_back[1] != EOF) {
- int c = push_back[1];
- push_back[1] = EOF;
- return c;
- }
- else if (push_back[0] != EOF) {
- int c = push_back[0];
- push_back[0] = EOF;
- return c;
- }
- int c = getc(fp);
- while (illegal_input_char(c)) {
- error("illegal input character code %1", int(c));
- c = getc(fp);
- bol = 0;
- }
- if (bol && c == '.') {
- c = getc(fp);
- if (c == 'P') {
- c = getc(fp);
- if (c == 'F' || c == 'E') {
- int d = getc(fp);
- if (d != EOF)
- ungetc(d, fp);
- if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {
- eof = 1;
- flyback_flag = c == 'F';
- return EOF;
- }
- push_back[0] = c;
- push_back[1] = 'P';
- return '.';
- }
- if (c == 'S') {
- c = getc(fp);
- if (c != EOF)
- ungetc(c, fp);
- if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {
- error("nested .PS");
- eof = 1;
- return EOF;
- }
- push_back[0] = 'S';
- push_back[1] = 'P';
- return '.';
- }
- if (c != EOF)
- ungetc(c, fp);
- push_back[0] = 'P';
- return '.';
- }
- else {
- if (c != EOF)
- ungetc(c, fp);
- return '.';
- }
- }
- if (c == '\n') {
- bol = 1;
- current_lineno++;
- return '\n';
- }
- bol = 0;
- if (c == EOF) {
- eof = 1;
- error("end of file before .PE or .PF");
- error_with_file_and_line(current_filename, start_lineno - 1,
- ".PS was here");
- }
- return c;
-}
-
-int top_input::peek()
-{
- if (eof)
- return EOF;
- if (push_back[2] != EOF)
- return push_back[2];
- if (push_back[1] != EOF)
- return push_back[1];
- if (push_back[0] != EOF)
- return push_back[0];
- int c = getc(fp);
- while (illegal_input_char(c)) {
- error("illegal input character code %1", int(c));
- c = getc(fp);
- bol = 0;
- }
- if (bol && c == '.') {
- c = getc(fp);
- if (c == 'P') {
- c = getc(fp);
- if (c == 'F' || c == 'E') {
- int d = getc(fp);
- if (d != EOF)
- ungetc(d, fp);
- if (d == EOF || d == ' ' || d == '\n' || compatible_flag) {
- eof = 1;
- flyback_flag = c == 'F';
- return EOF;
- }
- push_back[0] = c;
- push_back[1] = 'P';
- push_back[2] = '.';
- return '.';
- }
- if (c == 'S') {
- c = getc(fp);
- if (c != EOF)
- ungetc(c, fp);
- if (c == EOF || c == ' ' || c == '\n' || compatible_flag) {
- error("nested .PS");
- eof = 1;
- return EOF;
- }
- push_back[0] = 'S';
- push_back[1] = 'P';
- push_back[2] = '.';
- return '.';
- }
- if (c != EOF)
- ungetc(c, fp);
- push_back[0] = 'P';
- push_back[1] = '.';
- return '.';
- }
- else {
- if (c != EOF)
- ungetc(c, fp);
- push_back[0] = '.';
- return '.';
- }
- }
- if (c != EOF)
- ungetc(c, fp);
- if (c == '\n')
- return '\n';
- return c;
-}
-
-int top_input::get_location(const char **filenamep, int *linenop)
-{
- *filenamep = current_filename;
- *linenop = current_lineno;
- return 1;
-}
-
-void do_picture(FILE *fp)
-{
- flyback_flag = 0;
- int c;
- while ((c = getc(fp)) == ' ')
- ;
- if (c == '<') {
- string filename;
- while ((c = getc(fp)) == ' ')
- ;
- while (c != EOF && c != ' ' && c != '\n') {
- filename += char(c);
- c = getc(fp);
- }
- if (c == ' ') {
- do {
- c = getc(fp);
- } while (c != EOF && c != '\n');
- }
- if (c == '\n')
- current_lineno++;
- if (filename.length() == 0)
- error("missing filename after `<'");
- else {
- filename += '\0';
- const char *old_filename = current_filename;
- int old_lineno = current_lineno;
- // filenames must be permanent
- do_file(strsave(filename.contents()));
- current_filename = old_filename;
- current_lineno = old_lineno;
- }
- out->set_location(current_filename, current_lineno);
- }
- else {
- out->set_location(current_filename, current_lineno);
- string start_line;
- while (c != EOF) {
- if (c == '\n') {
- current_lineno++;
- break;
- }
- start_line += c;
- c = getc(fp);
- }
- if (c == EOF)
- return;
- start_line += '\0';
- double wid, ht;
- switch (sscanf(&start_line[0], "%lf %lf", &wid, &ht)) {
- case 1:
- ht = 0.0;
- break;
- case 2:
- break;
- default:
- ht = wid = 0.0;
- break;
- }
- out->set_desired_width_height(wid, ht);
- out->set_args(start_line.contents());
- lex_init(new top_input(fp));
- if (yyparse()) {
- had_parse_error = 1;
- lex_error("giving up on this picture");
- }
- parse_cleanup();
- lex_cleanup();
-
- // skip the rest of the .PF/.PE line
- while ((c = getc(fp)) != EOF && c != '\n')
- ;
- if (c == '\n')
- current_lineno++;
- out->set_location(current_filename, current_lineno);
- }
-}
-
-void do_file(const char *filename)
-{
- FILE *fp;
- if (strcmp(filename, "-") == 0)
- fp = stdin;
- else {
- errno = 0;
- fp = fopen(filename, "r");
- if (fp == 0)
- fatal("can't open `%1': %2", filename, strerror(errno));
- }
- out->set_location(filename, 1);
- current_filename = filename;
- current_lineno = 1;
- enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START;
- for (;;) {
- int c = getc(fp);
- if (c == EOF)
- break;
- switch (state) {
- case START:
- if (c == '.')
- state = HAD_DOT;
- else {
- putchar(c);
- if (c == '\n') {
- current_lineno++;
- state = START;
- }
- else
- state = MIDDLE;
- }
- break;
- case MIDDLE:
- putchar(c);
- if (c == '\n') {
- current_lineno++;
- state = START;
- }
- break;
- case HAD_DOT:
- if (c == 'P')
- state = HAD_P;
- else if (lf_flag && c == 'l')
- state = HAD_l;
- else {
- putchar('.');
- putchar(c);
- if (c == '\n') {
- current_lineno++;
- state = START;
- }
- else
- state = MIDDLE;
- }
- break;
- case HAD_P:
- if (c == 'S')
- state = HAD_PS;
- else {
- putchar('.');
- putchar('P');
- putchar(c);
- if (c == '\n') {
- current_lineno++;
- state = START;
- }
- else
- state = MIDDLE;
- }
- break;
- case HAD_PS:
- if (c == ' ' || c == '\n' || compatible_flag) {
- ungetc(c, fp);
- do_picture(fp);
- state = START;
- }
- else {
- fputs(".PS", stdout);
- putchar(c);
- state = MIDDLE;
- }
- break;
- case HAD_l:
- if (c == 'f')
- state = HAD_lf;
- else {
- putchar('.');
- putchar('l');
- putchar(c);
- if (c == '\n') {
- current_lineno++;
- state = START;
- }
- else
- state = MIDDLE;
- }
- break;
- case HAD_lf:
- if (c == ' ' || c == '\n' || compatible_flag) {
- string line;
- while (c != EOF) {
- line += c;
- if (c == '\n') {
- current_lineno++;
- break;
- }
- c = getc(fp);
- }
- line += '\0';
- interpret_lf_args(line.contents());
- printf(".lf%s", line.contents());
- state = START;
- }
- else {
- fputs(".lf", stdout);
- putchar(c);
- state = MIDDLE;
- }
- break;
- default:
- assert(0);
- }
- }
- switch (state) {
- case START:
- break;
- case MIDDLE:
- putchar('\n');
- break;
- case HAD_DOT:
- fputs(".\n", stdout);
- break;
- case HAD_P:
- fputs(".P\n", stdout);
- break;
- case HAD_PS:
- fputs(".PS\n", stdout);
- break;
- case HAD_l:
- fputs(".l\n", stdout);
- break;
- case HAD_lf:
- fputs(".lf\n", stdout);
- break;
- }
- if (fp != stdin)
- fclose(fp);
-}
-
-#ifdef FIG_SUPPORT
-void do_whole_file(const char *filename)
-{
- // Do not set current_filename.
- FILE *fp;
- if (strcmp(filename, "-") == 0)
- fp = stdin;
- else {
- errno = 0;
- fp = fopen(filename, "r");
- if (fp == 0)
- fatal("can't open `%1': %2", filename, strerror(errno));
- }
- lex_init(new file_input(fp, filename));
- if (yyparse())
- had_parse_error = 1;
- parse_cleanup();
- lex_cleanup();
-}
-#endif
-
-void usage()
-{
- fprintf(stderr, "usage: %s [ -nvC ] [ filename ... ]\n", program_name);
-#ifdef TEX_SUPPORT
- fprintf(stderr, " %s -t [ -cvzC ] [ filename ... ]\n", program_name);
-#endif
-#ifdef FIG_SUPPORT
- fprintf(stderr, " %s -f [ -v ] [ filename ]\n", program_name);
-#endif
- exit(1);
-}
-
-#ifdef __MSDOS__
-static char *fix_program_name(char *arg, char *dflt)
-{
- if (!arg)
- return dflt;
- char *prog = strchr(arg, '\0');
- for (;;) {
- if (prog == arg)
- break;
- --prog;
- if (strchr("\\/:", *prog)) {
- prog++;
- break;
- }
- }
- char *ext = strchr(prog, '.');
- if (ext)
- *ext = '\0';
- for (char *p = prog; *p; p++)
- if ('A' <= *p && *p <= 'Z')
- *p = 'a' + (*p - 'A');
- return prog;
-}
-#endif /* __MSDOS__ */
-
-int main(int argc, char **argv)
-{
-#ifdef __MSDOS__
- argv[0] = fix_program_name(argv[0], "pic");
-#endif /* __MSDOS__ */
- program_name = argv[0];
- static char stderr_buf[BUFSIZ];
- setbuf(stderr, stderr_buf);
- int opt;
-#ifdef TEX_SUPPORT
- int tex_flag = 0;
- int tpic_flag = 0;
-#endif
-#ifdef FIG_SUPPORT
- int whole_file_flag = 0;
- int fig_flag = 0;
-#endif
- while ((opt = getopt(argc, argv, "T:CDStcvnxzpf")) != EOF)
- switch (opt) {
- case 'C':
- compatible_flag = 1;
- break;
- case 'D':
- case 'T':
- break;
- case 'S':
- safer_flag = 1;
- break;
- case 'f':
-#ifdef FIG_SUPPORT
- whole_file_flag++;
- fig_flag++;
-#else
- fatal("fig support not included");
-#endif
- break;
- case 'n':
- driver_extension_flag = 0;
- break;
- case 'p':
- case 'x':
- warning("-%1 option is obsolete", char(opt));
- break;
- case 't':
-#ifdef TEX_SUPPORT
- tex_flag++;
-#else
- fatal("TeX support not included");
-#endif
- break;
- case 'c':
-#ifdef TEX_SUPPORT
- tpic_flag++;
-#else
- fatal("TeX support not included");
-#endif
- break;
- case 'v':
- {
- extern const char *version_string;
- fprintf(stderr, "GNU pic version %s\n", version_string);
- fflush(stderr);
- break;
- }
- case 'z':
- // zero length lines will be printed as dots
- zero_length_line_flag++;
- break;
- case '?':
- usage();
- break;
- default:
- assert(0);
- }
- parse_init();
-#ifdef TEX_SUPPORT
- if (tpic_flag) {
- out = make_tpic_output();
- lf_flag = 0;
- }
- else if (tex_flag) {
- out = make_tex_output();
- command_char = '\\';
- lf_flag = 0;
- }
- else
-#endif
-#ifdef FIG_SUPPORT
- if (fig_flag)
- out = make_fig_output();
- else
-#endif
- out = make_troff_output();
-#ifdef FIG_SUPPORT
- if (whole_file_flag) {
- if (optind >= argc)
- do_whole_file("-");
- else if (argc - optind > 1)
- usage();
- else
- do_whole_file(argv[optind]);
- }
- else {
-#endif
- if (optind >= argc)
- do_file("-");
- else
- for (int i = optind; i < argc; i++)
- do_file(argv[i]);
-#ifdef FIG_SUPPORT
- }
-#endif
- delete out;
- if (ferror(stdout) || fflush(stdout) < 0)
- fatal("output error");
- return had_parse_error;
-}
-
diff --git a/gnu/usr.bin/groff/pic/object.cc b/gnu/usr.bin/groff/pic/object.cc
deleted file mode 100644
index b5ff195daed..00000000000
--- a/gnu/usr.bin/groff/pic/object.cc
+++ /dev/null
@@ -1,1833 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-#include "ptable.h"
-#include "object.h"
-
-void print_object_list(object *);
-
-line_type::line_type()
-: type(solid), thickness(1.0)
-{
-}
-
-output::output() : desired_height(0.0), desired_width(0.0), args(0)
-{
-}
-
-output::~output()
-{
- a_delete args;
-}
-
-void output::set_desired_width_height(double wid, double ht)
-{
- desired_width = wid;
- desired_height = ht;
-}
-
-void output::set_args(const char *s)
-{
- a_delete args;
- if (s == 0 || *s == '\0')
- args = 0;
- else
- args = strsave(s);
-}
-
-void output::command(const char *, const char *, int)
-{
-}
-
-void output::set_location(const char *, int)
-{
-}
-
-int output::supports_filled_polygons()
-{
- return 0;
-}
-
-void output::begin_block(const position &, const position &)
-{
-}
-
-void output::end_block()
-{
-}
-
-double output::compute_scale(double sc, const position &ll, const position &ur)
-{
- distance dim = ur - ll;
- if (desired_width != 0.0 || desired_height != 0.0) {
- sc = 0.0;
- if (desired_width != 0.0) {
- if (dim.x == 0.0)
- error("width specified for picture with zero width");
- else
- sc = dim.x/desired_width;
- }
- if (desired_height != 0.0) {
- if (dim.y == 0.0)
- error("height specified for picture with zero height");
- else {
- double tem = dim.y/desired_height;
- if (tem > sc)
- sc = tem;
- }
- }
- return sc == 0.0 ? 1.0 : sc;
- }
- else {
- if (sc <= 0.0)
- sc = 1.0;
- distance sdim = dim/sc;
- double max_width = 0.0;
- lookup_variable("maxpswid", &max_width);
- double max_height = 0.0;
- lookup_variable("maxpsht", &max_height);
- if ((max_width > 0.0 && sdim.x > max_width)
- || (max_height > 0.0 && sdim.y > max_height)) {
- double xscale = dim.x/max_width;
- double yscale = dim.y/max_height;
- return xscale > yscale ? xscale : yscale;
- }
- else
- return sc;
- }
-}
-
-position::position(const place &pl)
-{
- if (pl.obj != 0) {
- // Use two statements to work around bug in SGI C++.
- object *tem = pl.obj;
- *this = tem->origin();
- }
- else {
- x = pl.x;
- y = pl.y;
- }
-}
-
-position::position() : x(0.0), y(0.0)
-{
-}
-
-position::position(double a, double b) : x(a), y(b)
-{
-}
-
-
-int operator==(const position &a, const position &b)
-{
- return a.x == b.x && a.y == b.y;
-}
-
-int operator!=(const position &a, const position &b)
-{
- return a.x != b.x || a.y != b.y;
-}
-
-position &position::operator+=(const position &a)
-{
- x += a.x;
- y += a.y;
- return *this;
-}
-
-position &position::operator-=(const position &a)
-{
- x -= a.x;
- y -= a.y;
- return *this;
-}
-
-position &position::operator*=(double a)
-{
- x *= a;
- y *= a;
- return *this;
-}
-
-position &position::operator/=(double a)
-{
- x /= a;
- y /= a;
- return *this;
-}
-
-position operator-(const position &a)
-{
- return position(-a.x, -a.y);
-}
-
-position operator+(const position &a, const position &b)
-{
- return position(a.x + b.x, a.y + b.y);
-}
-
-position operator-(const position &a, const position &b)
-{
- return position(a.x - b.x, a.y - b.y);
-}
-
-position operator/(const position &a, double n)
-{
- return position(a.x/n, a.y/n);
-}
-
-position operator*(const position &a, double n)
-{
- return position(a.x*n, a.y*n);
-}
-
-// dot product
-
-double operator*(const position &a, const position &b)
-{
- return a.x*b.x + a.y*b.y;
-}
-
-double hypot(const position &a)
-{
- return hypot(a.x, a.y);
-}
-
-struct arrow_head_type {
- double height;
- double width;
- int solid;
-};
-
-void draw_arrow(const position &pos, const distance &dir,
- const arrow_head_type &aht, const line_type &lt)
-{
- double hyp = hypot(dir);
- if (hyp == 0.0) {
- error("cannot draw arrow on object with zero length");
- return;
- }
- position base = -dir;
- base *= aht.height/hyp;
- position n(dir.y, -dir.x);
- n *= aht.width/(hyp*2.0);
- line_type slt = lt;
- slt.type = line_type::solid;
- if (aht.solid && out->supports_filled_polygons()) {
- position v[3];
- v[0] = pos;
- v[1] = pos + base + n;
- v[2] = pos + base - n;
- // A value > 1 means fill with the current color.
- out->polygon(v, 3, slt, 2.0);
- }
- else {
- position v[2];
- v[0] = pos;
- v[1] = pos + base + n;
- out->line(pos + base - n, v, 2, slt);
- }
-}
-
-object::object() : prev(0), next(0)
-{
-}
-
-object::~object()
-{
-}
-
-void object::move_by(const position &)
-{
-}
-
-void object::print()
-{
-}
-
-void object::print_text()
-{
-}
-
-int object::blank()
-{
- return 0;
-}
-
-struct bounding_box {
- int blank;
- position ll;
- position ur;
-
- bounding_box();
- void encompass(const position &);
-};
-
-bounding_box::bounding_box()
-: blank(1)
-{
-}
-
-void bounding_box::encompass(const position &pos)
-{
- if (blank) {
- ll = pos;
- ur = pos;
- blank = 0;
- }
- else {
- if (pos.x < ll.x)
- ll.x = pos.x;
- if (pos.y < ll.y)
- ll.y = pos.y;
- if (pos.x > ur.x)
- ur.x = pos.x;
- if (pos.y > ur.y)
- ur.y = pos.y;
- }
-}
-
-void object::update_bounding_box(bounding_box *)
-{
-}
-
-position object::origin()
-{
- return position(0.0,0.0);
-}
-
-position object::north()
-{
- return origin();
-}
-
-position object::south()
-{
- return origin();
-}
-
-position object::east()
-{
- return origin();
-}
-
-position object::west()
-{
- return origin();
-}
-
-position object::north_east()
-{
- return origin();
-}
-
-position object::north_west()
-{
- return origin();
-}
-
-position object::south_east()
-{
- return origin();
-}
-
-position object::south_west()
-{
- return origin();
-}
-
-position object::start()
-{
- return origin();
-}
-
-position object::end()
-{
- return origin();
-}
-
-position object::center()
-{
- return origin();
-}
-
-double object::width()
-{
- return 0.0;
-}
-
-double object::radius()
-{
- return 0.0;
-}
-
-double object::height()
-{
- return 0.0;
-}
-
-place *object::find_label(const char *)
-{
- return 0;
-}
-
-segment::segment(const position &a, int n, segment *p)
-: pos(a), is_absolute(n), next(p)
-{
-}
-
-text_item::text_item(char *t, const char *fn, int ln)
-: filename(fn), lineno(ln), text(t), next(0)
-{
- adj.h = CENTER_ADJUST;
- adj.v = NONE_ADJUST;
-}
-
-text_item::~text_item()
-{
- a_delete text;
-}
-
-object_spec::object_spec(object_type t) : type(t)
-{
- flags = 0;
- tbl = 0;
- segment_list = 0;
- segment_width = segment_height = 0.0;
- segment_is_absolute = 0;
- text = 0;
- with = 0;
- dir = RIGHT_DIRECTION;
-}
-
-object_spec::~object_spec()
-{
- delete tbl;
- while (segment_list != 0) {
- segment *tem = segment_list;
- segment_list = segment_list->next;
- delete tem;
- }
- object *p = oblist.head;
- while (p != 0) {
- object *tem = p;
- p = p->next;
- delete tem;
- }
- while (text != 0) {
- text_item *tem = text;
- text = text->next;
- delete tem;
- }
- delete with;
-}
-
-class command_object : public object {
- char *s;
- const char *filename;
- int lineno;
-public:
- command_object(char *, const char *, int);
- ~command_object();
- object_type type() { return OTHER_OBJECT; }
- void print();
-};
-
-command_object::command_object(char *p, const char *fn, int ln)
-: s(p), filename(fn), lineno(ln)
-{
-}
-
-command_object::~command_object()
-{
- a_delete s;
-}
-
-void command_object::print()
-{
- out->command(s, filename, lineno);
-}
-
-object *make_command_object(char *s, const char *fn, int ln)
-{
- return new command_object(s, fn, ln);
-}
-
-class mark_object : public object {
-public:
- mark_object();
- object_type type();
-};
-
-object *make_mark_object()
-{
- return new mark_object();
-}
-
-mark_object::mark_object()
-{
-}
-
-object_type mark_object::type()
-{
- return MARK_OBJECT;
-}
-
-object_list::object_list() : head(0), tail(0)
-{
-}
-
-void object_list::append(object *obj)
-{
- if (tail == 0) {
- obj->next = obj->prev = 0;
- head = tail = obj;
- }
- else {
- obj->prev = tail;
- obj->next = 0;
- tail->next = obj;
- tail = obj;
- }
-}
-
-void object_list::wrap_up_block(object_list *ol)
-{
- object *p;
- for (p = tail; p && p->type() != MARK_OBJECT; p = p->prev)
- ;
- assert(p != 0);
- ol->head = p->next;
- if (ol->head) {
- ol->tail = tail;
- ol->head->prev = 0;
- }
- else
- ol->tail = 0;
- tail = p->prev;
- if (tail)
- tail->next = 0;
- else
- head = 0;
- delete p;
-}
-
-text_piece::text_piece()
-: text(0), filename(0), lineno(-1)
-{
- adj.h = CENTER_ADJUST;
- adj.v = NONE_ADJUST;
-}
-
-text_piece::~text_piece()
-{
- a_delete text;
-}
-
-class graphic_object : public object {
- int ntext;
- text_piece *text;
- int aligned;
-protected:
- line_type lt;
-public:
- graphic_object();
- ~graphic_object();
- object_type type() = 0;
- void print_text();
- void add_text(text_item *, int);
- void set_dotted(double);
- void set_dashed(double);
- void set_thickness(double);
- void set_invisible();
- virtual void set_fill(double);
-};
-
-graphic_object::graphic_object() : ntext(0), text(0), aligned(0)
-{
-}
-
-void graphic_object::set_dotted(double wid)
-{
- lt.type = line_type::dotted;
- lt.dash_width = wid;
-}
-
-void graphic_object::set_dashed(double wid)
-{
- lt.type = line_type::dashed;
- lt.dash_width = wid;
-}
-
-void graphic_object::set_thickness(double th)
-{
- lt.thickness = th;
-}
-
-void graphic_object::set_fill(double)
-{
-}
-
-void graphic_object::set_invisible()
-{
- lt.type = line_type::invisible;
-}
-
-void graphic_object::add_text(text_item *t, int a)
-{
- aligned = a;
- int len = 0;
- text_item *p;
- for (p = t; p; p = p->next)
- len++;
- if (len == 0)
- text = 0;
- else {
- text = new text_piece[len];
- for (p = t, len = 0; p; p = p->next, len++) {
- text[len].text = p->text;
- p->text = 0;
- text[len].adj = p->adj;
- text[len].filename = p->filename;
- text[len].lineno = p->lineno;
- }
- }
- ntext = len;
-}
-
-void graphic_object::print_text()
-{
- double angle = 0.0;
- if (aligned) {
- position d(end() - start());
- if (d.x != 0.0 || d.y != 0.0)
- angle = atan2(d.y, d.x);
- }
- if (text != 0)
- out->text(center(), text, ntext, angle);
-}
-
-graphic_object::~graphic_object()
-{
- if (text)
- ad_delete(ntext) text;
-}
-
-class rectangle_object : public graphic_object {
-protected:
- position cent;
- position dim;
-public:
- rectangle_object(const position &);
- double width() { return dim.x; }
- double height() { return dim.y; }
- position origin() { return cent; }
- position center() { return cent; }
- position north() { return position(cent.x, cent.y + dim.y/2.0); }
- position south() { return position(cent.x, cent.y - dim.y/2.0); }
- position east() { return position(cent.x + dim.x/2.0, cent.y); }
- position west() { return position(cent.x - dim.x/2.0, cent.y); }
- position north_east() { return position(cent.x + dim.x/2.0, cent.y + dim.y/2.0); }
- position north_west() { return position(cent.x - dim.x/2.0, cent.y + dim.y/2.0); }
- position south_east() { return position(cent.x + dim.x/2.0, cent.y - dim.y/2.0); }
- position south_west() { return position(cent.x - dim.x/2.0, cent.y - dim.y/2.0); }
- object_type type() = 0;
- void update_bounding_box(bounding_box *);
- void move_by(const position &);
-};
-
-rectangle_object::rectangle_object(const position &d)
-: dim(d)
-{
-}
-
-void rectangle_object::update_bounding_box(bounding_box *p)
-{
- p->encompass(cent - dim/2.0);
- p->encompass(cent + dim/2.0);
-}
-
-void rectangle_object::move_by(const position &a)
-{
- cent += a;
-}
-
-class closed_object : public rectangle_object {
-public:
- closed_object(const position &);
- object_type type() = 0;
- void set_fill(double);
-protected:
- double fill; // < 0 if not filled
-};
-
-closed_object::closed_object(const position &pos)
-: rectangle_object(pos), fill(-1.0)
-{
-}
-
-void closed_object::set_fill(double f)
-{
- assert(f >= 0.0);
- fill = f;
-}
-
-
-class box_object : public closed_object {
- double xrad;
- double yrad;
-public:
- box_object(const position &, double);
- object_type type() { return BOX_OBJECT; }
- void print();
- position north_east();
- position north_west();
- position south_east();
- position south_west();
-};
-
-box_object::box_object(const position &pos, double r)
-: closed_object(pos), xrad(dim.x > 0 ? r : -r), yrad(dim.y > 0 ? r : -r)
-{
-}
-
-const double CHOP_FACTOR = 1.0 - 1.0/M_SQRT2;
-
-position box_object::north_east()
-{
- return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad,
- cent.y + dim.y/2.0 - CHOP_FACTOR*yrad);
-}
-
-position box_object::north_west()
-{
- return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad,
- cent.y + dim.y/2.0 - CHOP_FACTOR*yrad);
-}
-
-position box_object::south_east()
-{
- return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad,
- cent.y - dim.y/2.0 + CHOP_FACTOR*yrad);
-}
-
-position box_object::south_west()
-{
- return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad,
- cent.y - dim.y/2.0 + CHOP_FACTOR*yrad);
-}
-
-void box_object::print()
-{
- if (lt.type == line_type::invisible && fill < 0.0)
- return;
- if (xrad == 0.0) {
- distance dim2 = dim/2.0;
- position vec[4];
- vec[0] = cent + position(dim2.x, -dim2.y);
- vec[1] = cent + position(dim2.x, dim2.y);
- vec[2] = cent + position(-dim2.x, dim2.y);
- vec[3] = cent + position(-dim2.x, -dim2.y);
- out->polygon(vec, 4, lt, fill);
- }
- else {
- distance abs_dim(fabs(dim.x), fabs(dim.y));
- out->rounded_box(cent, abs_dim, fabs(xrad), lt, fill);
- }
-}
-
-graphic_object *object_spec::make_box(position *curpos, direction *dirp)
-{
- static double last_box_height;
- static double last_box_width;
- static double last_box_radius;
- static int have_last_box = 0;
- if (!(flags & HAS_HEIGHT)) {
- if ((flags & IS_SAME) && have_last_box)
- height = last_box_height;
- else
- lookup_variable("boxht", &height);
- }
- if (!(flags & HAS_WIDTH)) {
- if ((flags & IS_SAME) && have_last_box)
- width = last_box_width;
- else
- lookup_variable("boxwid", &width);
- }
- if (!(flags & HAS_RADIUS)) {
- if ((flags & IS_SAME) && have_last_box)
- radius = last_box_radius;
- else
- lookup_variable("boxrad", &radius);
- }
- last_box_width = width;
- last_box_height = height;
- last_box_radius = radius;
- have_last_box = 1;
- radius = fabs(radius);
- if (radius*2.0 > fabs(width))
- radius = fabs(width/2.0);
- if (radius*2.0 > fabs(height))
- radius = fabs(height/2.0);
- box_object *p = new box_object(position(width, height), radius);
- if (!position_rectangle(p, curpos, dirp)) {
- delete p;
- p = 0;
- }
- return p;
-}
-
-// return non-zero for success
-
-int object_spec::position_rectangle(rectangle_object *p,
- position *curpos, direction *dirp)
-{
- position pos;
- dir = *dirp; // ignore any direction in attribute list
- position motion;
- switch (dir) {
- case UP_DIRECTION:
- motion.y = p->height()/2.0;
- break;
- case DOWN_DIRECTION:
- motion.y = -p->height()/2.0;
- break;
- case LEFT_DIRECTION:
- motion.x = -p->width()/2.0;
- break;
- case RIGHT_DIRECTION:
- motion.x = p->width()/2.0;
- break;
- default:
- assert(0);
- }
- if (flags & HAS_AT) {
- pos = at;
- if (flags & HAS_WITH) {
- place offset;
- place here;
- here.obj = p;
- if (!with->follow(here, &offset))
- return 0;
- pos -= offset;
- }
- }
- else {
- pos = *curpos;
- pos += motion;
- }
- p->move_by(pos);
- pos += motion;
- *curpos = pos;
- return 1;
-}
-
-class block_object : public rectangle_object {
- object_list oblist;
- PTABLE(place) *tbl;
-public:
- block_object(const position &, const object_list &ol, PTABLE(place) *t);
- ~block_object();
- place *find_label(const char *);
- object_type type();
- void move_by(const position &);
- void print();
-};
-
-block_object::block_object(const position &d, const object_list &ol,
- PTABLE(place) *t)
-: oblist(ol), tbl(t), rectangle_object(d)
-{
-}
-
-block_object::~block_object()
-{
- delete tbl;
- object *p = oblist.head;
- while (p != 0) {
- object *tem = p;
- p = p->next;
- delete tem;
- }
-}
-
-void block_object::print()
-{
- out->begin_block(south_west(), north_east());
- print_object_list(oblist.head);
- out->end_block();
-}
-
-static void adjust_objectless_places(PTABLE(place) *tbl, const position &a)
-{
- // Adjust all the labels that aren't attached to objects.
- PTABLE_ITERATOR(place) iter(tbl);
- const char *key;
- place *pl;
- while (iter.next(&key, &pl))
- if (key && csupper(key[0]) && pl->obj == 0) {
- pl->x += a.x;
- pl->y += a.y;
- }
-}
-
-void block_object::move_by(const position &a)
-{
- cent += a;
- for (object *p = oblist.head; p; p = p->next)
- p->move_by(a);
- adjust_objectless_places(tbl, a);
-}
-
-
-place *block_object::find_label(const char *name)
-{
- return tbl->lookup(name);
-}
-
-object_type block_object::type()
-{
- return BLOCK_OBJECT;
-}
-
-graphic_object *object_spec::make_block(position *curpos, direction *dirp)
-{
- bounding_box bb;
- for (object *p = oblist.head; p; p = p->next)
- p->update_bounding_box(&bb);
- position dim;
- if (!bb.blank) {
- position m = -(bb.ll + bb.ur)/2.0;
- for (object *p = oblist.head; p; p = p->next)
- p->move_by(m);
- adjust_objectless_places(tbl, m);
- dim = bb.ur - bb.ll;
- }
- if (flags & HAS_WIDTH)
- dim.x = width;
- if (flags & HAS_HEIGHT)
- dim.y = height;
- block_object *block = new block_object(dim, oblist, tbl);
- if (!position_rectangle(block, curpos, dirp)) {
- delete block;
- block = 0;
- }
- tbl = 0;
- oblist.head = oblist.tail = 0;
- return block;
-}
-
-class text_object : public rectangle_object {
-public:
- text_object(const position &);
- object_type type() { return TEXT_OBJECT; }
-};
-
-text_object::text_object(const position &d)
-: rectangle_object(d)
-{
-}
-
-graphic_object *object_spec::make_text(position *curpos, direction *dirp)
-{
- if (!(flags & HAS_HEIGHT)) {
- lookup_variable("textht", &height);
- int nitems = 0;
- for (text_item *t = text; t; t = t->next)
- nitems++;
- height *= nitems;
- }
- if (!(flags & HAS_WIDTH))
- lookup_variable("textwid", &width);
- text_object *p = new text_object(position(width, height));
- if (!position_rectangle(p, curpos, dirp)) {
- delete p;
- p = 0;
- }
- return p;
-}
-
-
-class ellipse_object : public closed_object {
-public:
- ellipse_object(const position &);
- position north_east() { return position(cent.x + dim.x/(M_SQRT2*2.0),
- cent.y + dim.y/(M_SQRT2*2.0)); }
- position north_west() { return position(cent.x - dim.x/(M_SQRT2*2.0),
- cent.y + dim.y/(M_SQRT2*2.0)); }
- position south_east() { return position(cent.x + dim.x/(M_SQRT2*2.0),
- cent.y - dim.y/(M_SQRT2*2.0)); }
- position south_west() { return position(cent.x - dim.x/(M_SQRT2*2.0),
- cent.y - dim.y/(M_SQRT2*2.0)); }
- double radius() { return dim.x/2.0; }
- object_type type() { return ELLIPSE_OBJECT; }
- void print();
-};
-
-ellipse_object::ellipse_object(const position &d)
-: closed_object(d)
-{
-}
-
-void ellipse_object::print()
-{
- if (lt.type == line_type::invisible && fill < 0.0)
- return;
- out->ellipse(cent, dim, lt, fill);
-}
-
-graphic_object *object_spec::make_ellipse(position *curpos, direction *dirp)
-{
- static double last_ellipse_height;
- static double last_ellipse_width;
- static int have_last_ellipse = 0;
- if (!(flags & HAS_HEIGHT)) {
- if ((flags & IS_SAME) && have_last_ellipse)
- height = last_ellipse_height;
- else
- lookup_variable("ellipseht", &height);
- }
- if (!(flags & HAS_WIDTH)) {
- if ((flags & IS_SAME) && have_last_ellipse)
- width = last_ellipse_width;
- else
- lookup_variable("ellipsewid", &width);
- }
- last_ellipse_width = width;
- last_ellipse_height = height;
- have_last_ellipse = 1;
- ellipse_object *p = new ellipse_object(position(width, height));
- if (!position_rectangle(p, curpos, dirp)) {
- delete p;
- return 0;
- }
- return p;
-}
-
-class circle_object : public ellipse_object {
-public:
- circle_object(double);
- object_type type() { return CIRCLE_OBJECT; }
- void print();
-};
-
-circle_object::circle_object(double diam)
-: ellipse_object(position(diam, diam))
-{
-}
-
-void circle_object::print()
-{
- if (lt.type == line_type::invisible && fill < 0.0)
- return;
- out->circle(cent, dim.x/2.0, lt, fill);
-}
-
-graphic_object *object_spec::make_circle(position *curpos, direction *dirp)
-{
- static double last_circle_radius;
- static int have_last_circle = 0;
- if (!(flags & HAS_RADIUS)) {
- if ((flags & IS_SAME) && have_last_circle)
- radius = last_circle_radius;
- else
- lookup_variable("circlerad", &radius);
- }
- last_circle_radius = radius;
- have_last_circle = 1;
- circle_object *p = new circle_object(radius*2.0);
- if (!position_rectangle(p, curpos, dirp)) {
- delete p;
- return 0;
- }
- return p;
-}
-
-class move_object : public graphic_object {
- position strt;
- position en;
-public:
- move_object(const position &s, const position &e);
- position origin() { return en; }
- object_type type() { return MOVE_OBJECT; }
- void update_bounding_box(bounding_box *);
- void move_by(const position &);
-};
-
-move_object::move_object(const position &s, const position &e)
-: strt(s), en(e)
-{
-}
-
-void move_object::update_bounding_box(bounding_box *p)
-{
- p->encompass(strt);
- p->encompass(en);
-}
-
-void move_object::move_by(const position &a)
-{
- strt += a;
- en += a;
-}
-
-graphic_object *object_spec::make_move(position *curpos, direction *dirp)
-{
- static position last_move;
- static int have_last_move = 0;
- *dirp = dir;
- // No need to look at at since `at' attribute sets `from' attribute.
- position startpos = (flags & HAS_FROM) ? from : *curpos;
- if (!(flags & HAS_SEGMENT)) {
- if ((flags & IS_SAME) && have_last_move)
- segment_pos = last_move;
- else {
- switch (dir) {
- case UP_DIRECTION:
- segment_pos.y = segment_height;
- break;
- case DOWN_DIRECTION:
- segment_pos.y = -segment_height;
- break;
- case LEFT_DIRECTION:
- segment_pos.x = -segment_width;
- break;
- case RIGHT_DIRECTION:
- segment_pos.x = segment_width;
- break;
- default:
- assert(0);
- }
- }
- }
- segment_list = new segment(segment_pos, segment_is_absolute, segment_list);
- // Reverse the segment_list so that it's in forward order.
- segment *old = segment_list;
- segment_list = 0;
- while (old != 0) {
- segment *tem = old->next;
- old->next = segment_list;
- segment_list = old;
- old = tem;
- }
- // Compute the end position.
- position endpos = startpos;
- for (segment *s = segment_list; s; s = s->next)
- if (s->is_absolute)
- endpos = s->pos;
- else
- endpos += s->pos;
- have_last_move = 1;
- last_move = endpos - startpos;
- move_object *p = new move_object(startpos, endpos);
- *curpos = endpos;
- return p;
-}
-
-class linear_object : public graphic_object {
-protected:
- char arrow_at_start;
- char arrow_at_end;
- arrow_head_type aht;
- position strt;
- position en;
-public:
- linear_object(const position &s, const position &e);
- position start() { return strt; }
- position end() { return en; }
- void move_by(const position &);
- void update_bounding_box(bounding_box *) = 0;
- object_type type() = 0;
- void add_arrows(int at_start, int at_end, const arrow_head_type &);
-};
-
-class line_object : public linear_object {
-protected:
- position *v;
- int n;
-public:
- line_object(const position &s, const position &e, position *, int);
- ~line_object();
- position origin() { return strt; }
- position center() { return (strt + en)/2.0; }
- position north() { return (en.y - strt.y) > 0 ? en : strt; }
- position south() { return (en.y - strt.y) < 0 ? en : strt; }
- position east() { return (en.x - strt.x) > 0 ? en : strt; }
- position west() { return (en.x - strt.x) < 0 ? en : strt; }
- object_type type() { return LINE_OBJECT; }
- void update_bounding_box(bounding_box *);
- void print();
- void move_by(const position &);
-};
-
-class arrow_object : public line_object {
-public:
- arrow_object(const position &, const position &, position *, int);
- object_type type() { return ARROW_OBJECT; }
-};
-
-class spline_object : public line_object {
-public:
- spline_object(const position &, const position &, position *, int);
- object_type type() { return SPLINE_OBJECT; }
- void print();
- void update_bounding_box(bounding_box *);
-};
-
-linear_object::linear_object(const position &s, const position &e)
-: strt(s), en(e), arrow_at_start(0), arrow_at_end(0)
-{
-}
-
-void linear_object::move_by(const position &a)
-{
- strt += a;
- en += a;
-}
-
-void linear_object::add_arrows(int at_start, int at_end,
- const arrow_head_type &a)
-{
- arrow_at_start = at_start;
- arrow_at_end = at_end;
- aht = a;
-}
-
-line_object::line_object(const position &s, const position &e,
- position *p, int i)
-: v(p), n(i), linear_object(s, e)
-{
-}
-
-void line_object::print()
-{
- if (lt.type == line_type::invisible)
- return;
- out->line(strt, v, n, lt);
- if (arrow_at_start)
- draw_arrow(strt, strt-v[0], aht, lt);
- if (arrow_at_end)
- draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt);
-}
-
-void line_object::update_bounding_box(bounding_box *p)
-{
- p->encompass(strt);
- for (int i = 0; i < n; i++)
- p->encompass(v[i]);
-}
-
-void line_object::move_by(const position &pos)
-{
- linear_object::move_by(pos);
- for (int i = 0; i < n; i++)
- v[i] += pos;
-}
-
-void spline_object::update_bounding_box(bounding_box *p)
-{
- p->encompass(strt);
- p->encompass(en);
- /*
-
- If
-
- p1 = q1/2 + q2/2
- p2 = q1/6 + q2*5/6
- p3 = q2*5/6 + q3/6
- p4 = q2/2 + q3/2
- [ the points for the Bezier cubic ]
-
- and
-
- t = .5
-
- then
-
- (1-t)^3*p1 + 3*t*(t - 1)^2*p2 + 3*t^2*(1-t)*p3 + t^3*p4
- [ the equation for the Bezier cubic ]
-
- = .125*q1 + .75*q2 + .125*q3
-
- */
- for (int i = 1; i < n; i++)
- p->encompass((i == 1 ? strt : v[i-2])*.125 + v[i-1]*.75 + v[i]*.125);
-}
-
-arrow_object::arrow_object(const position &s, const position &e,
- position *p, int i)
-: line_object(s, e, p, i)
-{
-}
-
-spline_object::spline_object(const position &s, const position &e,
- position *p, int i)
-: line_object(s, e, p, i)
-{
-}
-
-void spline_object::print()
-{
- if (lt.type == line_type::invisible)
- return;
- out->spline(strt, v, n, lt);
- if (arrow_at_start)
- draw_arrow(strt, strt-v[0], aht, lt);
- if (arrow_at_end)
- draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt);
-}
-
-line_object::~line_object()
-{
- a_delete v;
-}
-
-linear_object *object_spec::make_line(position *curpos, direction *dirp)
-{
- static position last_line;
- static int have_last_line = 0;
- *dirp = dir;
- // No need to look at at since `at' attribute sets `from' attribute.
- position startpos = (flags & HAS_FROM) ? from : *curpos;
- if (!(flags & HAS_SEGMENT)) {
- if ((flags & IS_SAME) && (type == LINE_OBJECT || type == ARROW_OBJECT)
- && have_last_line)
- segment_pos = last_line;
- else
- switch (dir) {
- case UP_DIRECTION:
- segment_pos.y = segment_height;
- break;
- case DOWN_DIRECTION:
- segment_pos.y = -segment_height;
- break;
- case LEFT_DIRECTION:
- segment_pos.x = -segment_width;
- break;
- case RIGHT_DIRECTION:
- segment_pos.x = segment_width;
- break;
- default:
- assert(0);
- }
- }
- segment_list = new segment(segment_pos, segment_is_absolute, segment_list);
- // reverse the segment_list so that it's in forward order
- segment *old = segment_list;
- segment_list = 0;
- while (old != 0) {
- segment *tem = old->next;
- old->next = segment_list;
- segment_list = old;
- old = tem;
- }
- // Absolutise all movements
- position endpos = startpos;
- int nsegments = 0;
- segment *s;
- for (s = segment_list; s; s = s->next, nsegments++)
- if (s->is_absolute)
- endpos = s->pos;
- else {
- endpos += s->pos;
- s->pos = endpos;
- s->is_absolute = 1; // to avoid confusion
- }
- // handle chop
- line_object *p = 0;
- position *v = new position[nsegments];
- int i = 0;
- for (s = segment_list; s; s = s->next, i++)
- v[i] = s->pos;
- if (flags & IS_DEFAULT_CHOPPED) {
- lookup_variable("circlerad", &start_chop);
- end_chop = start_chop;
- flags |= IS_CHOPPED;
- }
- if (flags & IS_CHOPPED) {
- position start_chop_vec, end_chop_vec;
- if (start_chop != 0.0) {
- start_chop_vec = v[0] - startpos;
- start_chop_vec *= start_chop / hypot(start_chop_vec);
- }
- if (end_chop != 0.0) {
- end_chop_vec = (v[nsegments - 1]
- - (nsegments > 1 ? v[nsegments - 2] : startpos));
- end_chop_vec *= end_chop / hypot(end_chop_vec);
- }
- startpos += start_chop_vec;
- v[nsegments - 1] -= end_chop_vec;
- endpos -= end_chop_vec;
- }
- switch (type) {
- case SPLINE_OBJECT:
- p = new spline_object(startpos, endpos, v, nsegments);
- break;
- case ARROW_OBJECT:
- p = new arrow_object(startpos, endpos, v, nsegments);
- break;
- case LINE_OBJECT:
- p = new line_object(startpos, endpos, v, nsegments);
- break;
- default:
- assert(0);
- }
- have_last_line = 1;
- last_line = endpos - startpos;
- *curpos = endpos;
- return p;
-}
-
-class arc_object : public linear_object {
- int clockwise;
- position cent;
- double rad;
-public:
- arc_object(int, const position &, const position &, const position &);
- position origin() { return cent; }
- position center() { return cent; }
- double radius() { return rad; }
- position north();
- position south();
- position east();
- position west();
- position north_east();
- position north_west();
- position south_east();
- position south_west();
- void update_bounding_box(bounding_box *);
- object_type type() { return ARC_OBJECT; }
- void print();
- void move_by(const position &pos);
-};
-
-arc_object::arc_object(int cw, const position &s, const position &e,
- const position &c)
-: linear_object(s, e), clockwise(cw), cent(c)
-{
- rad = hypot(c - s);
-}
-
-void arc_object::move_by(const position &pos)
-{
- linear_object::move_by(pos);
- cent += pos;
-}
-
-// we get arc corners from the corresponding circle
-
-position arc_object::north()
-{
- position result(cent);
- result.y += rad;
- return result;
-}
-
-position arc_object::south()
-{
- position result(cent);
- result.y -= rad;
- return result;
-}
-
-position arc_object::east()
-{
- position result(cent);
- result.x += rad;
- return result;
-}
-
-position arc_object::west()
-{
- position result(cent);
- result.x -= rad;
- return result;
-}
-
-position arc_object::north_east()
-{
- position result(cent);
- result.x += rad/M_SQRT2;
- result.y += rad/M_SQRT2;
- return result;
-}
-
-position arc_object::north_west()
-{
- position result(cent);
- result.x -= rad/M_SQRT2;
- result.y += rad/M_SQRT2;
- return result;
-}
-
-position arc_object::south_east()
-{
- position result(cent);
- result.x += rad/M_SQRT2;
- result.y -= rad/M_SQRT2;
- return result;
-}
-
-position arc_object::south_west()
-{
- position result(cent);
- result.x -= rad/M_SQRT2;
- result.y -= rad/M_SQRT2;
- return result;
-}
-
-
-void arc_object::print()
-{
- if (lt.type == line_type::invisible)
- return;
- if (clockwise)
- out->arc(en, cent, strt, lt);
- else
- out->arc(strt, cent, en, lt);
- if (arrow_at_start) {
- position c = cent - strt;
- draw_arrow(strt,
- (clockwise ? position(c.y, -c.x) : position(-c.y, c.x)),
- aht, lt);
- }
- if (arrow_at_end) {
- position e = en - cent;
- draw_arrow(en,
- (clockwise ? position(e.y, -e.x) : position(-e.y, e.x)),
- aht, lt);
- }
-}
-
-inline double max(double a, double b)
-{
- return a > b ? a : b;
-}
-
-void arc_object::update_bounding_box(bounding_box *p)
-{
- p->encompass(strt);
- p->encompass(en);
- position start_offset = strt - cent;
- if (start_offset.x == 0.0 && start_offset.y == 0.0)
- return;
- position end_offset = en - cent;
- if (end_offset.x == 0.0 && end_offset.y == 0.0)
- return;
- double start_quad = atan2(start_offset.y, start_offset.x)/(M_PI/2.0);
- double end_quad = atan2(end_offset.y, end_offset.x)/(M_PI/2.0);
- if (clockwise) {
- double temp = start_quad;
- start_quad = end_quad;
- end_quad = temp;
- }
- if (start_quad < 0.0)
- start_quad += 4.0;
- while (end_quad <= start_quad)
- end_quad += 4.0;
- double radius = max(hypot(start_offset), hypot(end_offset));
- for (int q = int(start_quad) + 1; q < end_quad; q++) {
- position offset;
- switch (q % 4) {
- case 0:
- offset.x = radius;
- break;
- case 1:
- offset.y = radius;
- break;
- case 2:
- offset.x = -radius;
- break;
- case 3:
- offset.y = -radius;
- break;
- }
- p->encompass(cent + offset);
- }
-}
-
-// We ignore the with attribute. The at attribute always refers to the center.
-
-linear_object *object_spec::make_arc(position *curpos, direction *dirp)
-{
- *dirp = dir;
- int cw = (flags & IS_CLOCKWISE) != 0;
- // compute the start
- position startpos;
- if (flags & HAS_FROM)
- startpos = from;
- else
- startpos = *curpos;
- if (!(flags & HAS_RADIUS))
- lookup_variable("arcrad", &radius);
- // compute the end
- position endpos;
- if (flags & HAS_TO)
- endpos = to;
- else {
- position m(radius, radius);
- // Adjust the signs.
- if (cw) {
- if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION)
- m.x = -m.x;
- if (dir == DOWN_DIRECTION || dir == RIGHT_DIRECTION)
- m.y = -m.y;
- *dirp = direction((dir + 3) % 4);
- }
- else {
- if (dir == UP_DIRECTION || dir == LEFT_DIRECTION)
- m.x = -m.x;
- if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION)
- m.y = -m.y;
- *dirp = direction((dir + 1) % 4);
- }
- endpos = startpos + m;
- }
- // compute the center
- position centerpos;
- if (flags & HAS_AT)
- centerpos = at;
- else if (startpos == endpos)
- centerpos = startpos;
- else {
- position h = (endpos - startpos)/2.0;
- double d = hypot(h);
- if (radius <= 0)
- radius = .25;
- // make the radius big enough
- while (radius < d)
- radius *= 2.0;
- double alpha = acos(d/radius);
- double theta = atan2(h.y, h.x);
- if (cw)
- theta -= alpha;
- else
- theta += alpha;
- centerpos = position(cos(theta), sin(theta))*radius + startpos;
- }
- arc_object *p = new arc_object(cw, startpos, endpos, centerpos);
- *curpos = endpos;
- return p;
-}
-
-graphic_object *object_spec::make_linear(position *curpos, direction *dirp)
-{
- linear_object *obj;
- if (type == ARC_OBJECT)
- obj = make_arc(curpos, dirp);
- else
- obj = make_line(curpos, dirp);
- if (type == ARROW_OBJECT
- && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD)) == 0)
- flags |= HAS_RIGHT_ARROW_HEAD;
- if (obj && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD))) {
- arrow_head_type a;
- int at_start = (flags & HAS_LEFT_ARROW_HEAD) != 0;
- int at_end = (flags & HAS_RIGHT_ARROW_HEAD) != 0;
- if (flags & HAS_HEIGHT)
- a.height = height;
- else
- lookup_variable("arrowht", &a.height);
- if (flags & HAS_WIDTH)
- a.width = width;
- else
- lookup_variable("arrowwid", &a.width);
- double solid;
- lookup_variable("arrowhead", &solid);
- a.solid = solid != 0.0;
- obj->add_arrows(at_start, at_end, a);
- }
- return obj;
-}
-
-object *object_spec::make_object(position *curpos, direction *dirp)
-{
- graphic_object *obj = 0;
- switch (type) {
- case BLOCK_OBJECT:
- obj = make_block(curpos, dirp);
- break;
- case BOX_OBJECT:
- obj = make_box(curpos, dirp);
- break;
- case TEXT_OBJECT:
- obj = make_text(curpos, dirp);
- break;
- case ELLIPSE_OBJECT:
- obj = make_ellipse(curpos, dirp);
- break;
- case CIRCLE_OBJECT:
- obj = make_circle(curpos, dirp);
- break;
- case MOVE_OBJECT:
- obj = make_move(curpos, dirp);
- break;
- case ARC_OBJECT:
- case LINE_OBJECT:
- case SPLINE_OBJECT:
- case ARROW_OBJECT:
- obj = make_linear(curpos, dirp);
- break;
- case MARK_OBJECT:
- case OTHER_OBJECT:
- default:
- assert(0);
- break;
- }
- if (obj) {
- if (flags & IS_INVISIBLE)
- obj->set_invisible();
- if (text != 0)
- obj->add_text(text, (flags & IS_ALIGNED) != 0);
- if (flags & IS_DOTTED)
- obj->set_dotted(dash_width);
- else if (flags & IS_DASHED)
- obj->set_dashed(dash_width);
- double th;
- if (flags & HAS_THICKNESS)
- th = thickness;
- else
- lookup_variable("linethick", &th);
- obj->set_thickness(th);
- if (flags & (IS_DEFAULT_FILLED|IS_FILLED)) {
- if (flags & IS_DEFAULT_FILLED)
- lookup_variable("fillval", &fill);
- if (fill < 0.0)
- error("bad fill value %1", fill);
- else
- obj->set_fill(fill);
- }
- }
- return obj;
-}
-
-struct string_list {
- string_list *next;
- char *str;
- string_list(char *);
- ~string_list();
-};
-
-string_list::string_list(char *s)
-: next(0), str(s)
-{
-}
-
-string_list::~string_list()
-{
- a_delete str;
-}
-
-/* A path is used to hold the argument to the with attribute. For example,
-`.nw' or `.A.s' or `.A'. The major operation on a path is to take a
-place and follow the path through the place to place within the place.
-Note that `.A.B.C.sw' will work. */
-
-path::path(corner c)
-: label_list(0), crn(c), ypath(0)
-{
-}
-
-path::path(char *l, corner c)
-: crn(c), ypath(0)
-{
- label_list = new string_list(l);
-}
-
-path::~path()
-{
- while (label_list) {
- string_list *tem = label_list;
- label_list = label_list->next;
- delete tem;
- }
- delete ypath;
-}
-
-void path::append(corner c)
-{
- assert(crn == 0);
- crn = c;
-}
-
-void path::append(char *s)
-{
- string_list **p;
- for (p = &label_list; *p; p = &(*p)->next)
- ;
- *p = new string_list(s);
-}
-
-void path::set_ypath(path *p)
-{
- ypath = p;
-}
-
-// return non-zero for success
-
-int path::follow(const place &pl, place *result) const
-{
- const place *p = &pl;
- for (string_list *lb = label_list; lb; lb = lb->next)
- if (p->obj == 0 || (p = p->obj->find_label(lb->str)) == 0) {
- lex_error("object does not contain a place `%1'", lb->str);
- return 0;
- }
- if (crn == 0 || p->obj == 0)
- *result = *p;
- else {
- position pos = ((p->obj)->*(crn))();
- result->x = pos.x;
- result->y = pos.y;
- result->obj = 0;
- }
- if (ypath) {
- place tem;
- if (!ypath->follow(pl, &tem))
- return 0;
- result->y = tem.y;
- if (result->obj != tem.obj)
- result->obj = 0;
- }
- return 1;
-}
-
-void print_object_list(object *p)
-{
- for (; p; p = p->next) {
- p->print();
- p->print_text();
- }
-}
-
-void print_picture(object *obj)
-{
- bounding_box bb;
- for (object *p = obj; p; p = p->next)
- p->update_bounding_box(&bb);
- double scale;
- lookup_variable("scale", &scale);
- out->start_picture(scale, bb.ll, bb.ur);
- print_object_list(obj);
- out->finish_picture();
-}
-
diff --git a/gnu/usr.bin/groff/pic/object.h b/gnu/usr.bin/groff/pic/object.h
deleted file mode 100644
index 2748e81e846..00000000000
--- a/gnu/usr.bin/groff/pic/object.h
+++ /dev/null
@@ -1,217 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-struct place;
-
-enum object_type {
- OTHER_OBJECT,
- BOX_OBJECT,
- CIRCLE_OBJECT,
- ELLIPSE_OBJECT,
- ARC_OBJECT,
- SPLINE_OBJECT,
- LINE_OBJECT,
- ARROW_OBJECT,
- MOVE_OBJECT,
- TEXT_OBJECT,
- BLOCK_OBJECT,
- MARK_OBJECT
- };
-
-struct bounding_box;
-
-struct object {
- object *prev;
- object *next;
- object();
- virtual ~object();
- virtual position origin();
- virtual double width();
- virtual double radius();
- virtual double height();
- virtual position north();
- virtual position south();
- virtual position east();
- virtual position west();
- virtual position north_east();
- virtual position north_west();
- virtual position south_east();
- virtual position south_west();
- virtual position start();
- virtual position end();
- virtual position center();
- virtual place *find_label(const char *);
- virtual void move_by(const position &);
- virtual int blank();
- virtual void update_bounding_box(bounding_box *);
- virtual object_type type() = 0;
- virtual void print();
- virtual void print_text();
-};
-
-typedef position (object::*corner)();
-
-struct place {
- object *obj;
- double x, y;
-};
-
-struct string_list;
-
-class path {
- corner crn;
- string_list *label_list;
- path *ypath;
-public:
- path(corner = 0);
- path(char *, corner = 0);
- ~path();
- void append(corner);
- void append(char *);
- void set_ypath(path *);
- int follow(const place &, place *) const;
-};
-
-struct object_list {
- object *head;
- object *tail;
- object_list();
- void append(object *);
- void wrap_up_block(object_list *);
-};
-
-declare_ptable(place)
-
-// these go counterclockwise
-enum direction {
- RIGHT_DIRECTION,
- UP_DIRECTION,
- LEFT_DIRECTION,
- DOWN_DIRECTION
- };
-
-struct graphics_state {
- double x, y;
- direction dir;
-};
-
-struct saved_state : public graphics_state {
- saved_state *prev;
- PTABLE(place) *tbl;
-};
-
-
-struct text_item {
- text_item *next;
- char *text;
- adjustment adj;
- const char *filename;
- int lineno;
-
- text_item(char *, const char *, int);
- ~text_item();
-};
-
-const unsigned long IS_DOTTED = 01;
-const unsigned long IS_DASHED = 02;
-const unsigned long IS_CLOCKWISE = 04;
-const unsigned long IS_INVISIBLE = 020;
-const unsigned long HAS_LEFT_ARROW_HEAD = 040;
-const unsigned long HAS_RIGHT_ARROW_HEAD = 0100;
-const unsigned long HAS_SEGMENT = 0200;
-const unsigned long IS_SAME = 0400;
-const unsigned long HAS_FROM = 01000;
-const unsigned long HAS_AT = 02000;
-const unsigned long HAS_WITH = 04000;
-const unsigned long HAS_HEIGHT = 010000;
-const unsigned long HAS_WIDTH = 020000;
-const unsigned long HAS_RADIUS = 040000;
-const unsigned long HAS_TO = 0100000;
-const unsigned long IS_CHOPPED = 0200000;
-const unsigned long IS_DEFAULT_CHOPPED = 0400000;
-const unsigned long HAS_THICKNESS = 01000000;
-const unsigned long IS_FILLED = 02000000;
-const unsigned long IS_DEFAULT_FILLED = 04000000;
-const unsigned long IS_ALIGNED = 010000000;
-
-struct segment {
- int is_absolute;
- position pos;
- segment *next;
- segment(const position &, int, segment *);
-};
-
-struct rectangle_object;
-struct graphic_object;
-struct linear_object;
-
-struct object_spec {
- unsigned long flags;
- object_type type;
- object_list oblist;
- PTABLE(place) *tbl;
- double dash_width;
- position from;
- position to;
- position at;
- position by;
- path *with;
- text_item *text;
- double height;
- double radius;
- double width;
- double segment_width;
- double segment_height;
- double start_chop;
- double end_chop;
- double thickness;
- double fill;
- direction dir;
- segment *segment_list;
- position segment_pos;
- int segment_is_absolute;
-
- object_spec(object_type);
- ~object_spec();
- object *make_object(position *, direction *);
- graphic_object *make_box(position *, direction *);
- graphic_object *make_block(position *, direction *);
- graphic_object *make_text(position *, direction *);
- graphic_object *make_ellipse(position *, direction *);
- graphic_object *make_circle(position *, direction *);
- linear_object *make_line(position *, direction *);
- linear_object *make_arc(position *, direction *);
- graphic_object *make_linear(position *, direction *);
- graphic_object *make_move(position *, direction *);
- int position_rectangle(rectangle_object *p, position *curpos,
- direction *dirp);
-};
-
-
-object *make_object(object_spec *, position *, direction *);
-
-object *make_mark_object();
-object *make_command_object(char *, const char *, int);
-
-int lookup_variable(const char *name, double *val);
-void define_variable(const char *name, double val);
-
-void print_picture(object *);
-
diff --git a/gnu/usr.bin/groff/pic/output.h b/gnu/usr.bin/groff/pic/output.h
deleted file mode 100644
index ac490db463e..00000000000
--- a/gnu/usr.bin/groff/pic/output.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-struct line_type {
- enum { invisible, solid, dotted, dashed } type;
- double dash_width;
- double thickness; // the thickness is in points
-
- line_type();
-};
-
-
-class output {
-protected:
- char *args;
- double desired_height; // zero if no height specified
- double desired_width; // zero if no depth specified
- double compute_scale(double, const position &, const position &);
-public:
- output();
- virtual ~output();
- void set_desired_width_height(double wid, double ht);
- void set_args(const char *);
- virtual void start_picture(double sc, const position &ll, const position &ur) = 0;
- virtual void finish_picture() = 0;
- virtual void circle(const position &, double rad,
- const line_type &, double) = 0;
- virtual void text(const position &, text_piece *, int, double) = 0;
- virtual void line(const position &, const position *, int n,
- const line_type &) = 0;
- virtual void polygon(const position *, int n,
- const line_type &, double) = 0;
- virtual void spline(const position &, const position *, int n,
- const line_type &) = 0;
- virtual void arc(const position &, const position &, const position &,
- const line_type &) = 0;
- virtual void ellipse(const position &, const distance &,
- const line_type &, double) = 0;
- virtual void rounded_box(const position &, const distance &, double,
- const line_type &, double) = 0;
- virtual void command(const char *, const char *, int);
- virtual void set_location(const char *, int);
- virtual int supports_filled_polygons();
- virtual void begin_block(const position &ll, const position &ur);
- virtual void end_block();
-};
-
-extern output *out;
-
-/* #define FIG_SUPPORT 1 */
-#define TEX_SUPPORT 1
-
-output *make_troff_output();
-
-#ifdef TEX_SUPPORT
-output *make_tex_output();
-output *make_tpic_output();
-#endif /* TEX_SUPPORT */
-
-#ifdef FIG_SUPPORT
-output *make_fig_output();
-#endif /* FIG_SUPPORT */
diff --git a/gnu/usr.bin/groff/pic/pic.1_in b/gnu/usr.bin/groff/pic/pic.1_in
deleted file mode 100644
index 70ab94631bb..00000000000
--- a/gnu/usr.bin/groff/pic/pic.1_in
+++ /dev/null
@@ -1,759 +0,0 @@
-.ig \"-*- nroff -*-
-Copyright (C) 1989-1999 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
-..
-.\" Like TP, but if specified indent is more than half
-.\" the current line-length - indent, use the default indent.
-.de Tp
-.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
-.el .TP "\\$1"
-..
-.ie t .ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X
-.el .ds tx TeX
-.ie \n(.g .ds ic \/
-.el .ds ic \^
-.\" The BSD man macros can't handle " in arguments to font change macros,
-.\" so use \(ts instead of ".
-.tr \(ts"
-.TH @G@PIC @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@"
-.SH NAME
-@g@pic \- compile pictures for troff or TeX
-.SH SYNOPSIS
-.B @g@pic
-[
-.B \-nvCSU
-]
-[
-.I filename
-\&.\|.\|.
-]
-.br
-.B @g@pic
-.B \-t
-[
-.B \-cvzCSU
-]
-[
-.I filename
-\&.\|.\|.
-]
-.SH DESCRIPTION
-.LP
-This manual page describes the GNU version of
-.BR pic ,
-which is part of the groff document formatting system.
-.B pic
-compiles descriptions of pictures embedded within
-.B troff
-or \*(tx input files into commands that are understood by \*(tx or
-.BR troff .
-Each picture starts with a line beginning with
-.B .PS
-and ends with a line beginning with
-.BR .PE .
-Anything outside of
-.B .PS
-and
-.B .PE
-is passed through without change.
-.LP
-It is the user's responsibility to provide appropriate definitions of the
-.B PS
-and
-.B PE
-macros.
-When the macro package being used does not supply such definitions
-(for example, old versions of \-ms),
-appropriate definitions can be obtained with
-.BR \-mpic :
-these will center each picture.
-.SH OPTIONS
-.LP
-Options that do not take arguments may be grouped behind a single
-.BR \- .
-The special option
-.B \-\^\-
-can be used to mark the end of the options.
-A filename of
-.B \-
-refers to the standard input.
-.TP
-.B \-C
-Recognize
-.B .PS
-and
-.B .PE
-even when followed by a character other than space or newline.
-.TP
-.B \-S
-Safer mode; do not execute
-.B sh
-commands.
-This can be useful when operating on untrustworthy input.
-(enabled by default)
-.TP
-.B \-U
-Unsafe mode; revert the default option
-.BR \-S .
-.TP
-.B \-n
-Don't use the groff extensions to the troff drawing commands.
-You should use this if you are using a postprocessor that doesn't support
-these extensions.
-The extensions are described in
-.BR groff_out (@MAN5EXT@).
-The
-.B \-n
-option also causes pic
-not to use zero-length lines to draw dots in troff mode.
-.TP
-.B \-t
-\*(tx mode.
-.TP
-.B \-c
-Be more compatible with
-.BR tpic .
-Implies
-.BR \-t .
-Lines beginning with
-.B \e
-are not passed through transparently.
-Lines beginning with
-.B .
-are passed through with the initial
-.B .
-changed to
-.BR \e .
-A line beginning with
-.B .ps
-is given special treatment:
-it takes an optional integer argument specifying
-the line thickness (pen size) in milliinches;
-a missing argument restores the previous line thickness;
-the default line thickness is 8 milliinches.
-The line thickness thus specified takes effect only
-when a non-negative line thickness has not been
-specified by use of the
-.B thickness
-attribute or by setting the
-.B linethick
-variable.
-.TP
-.B \-v
-Print the version number.
-.TP
-.B \-z
-In \*(tx mode draw dots using zero-length lines.
-.LP
-The following options supported by other versions of
-.B pic
-are ignored:
-.TP
-.B \-D
-Draw all lines using the \eD escape sequence.
-.B pic
-always does this.
-.TP
-.BI \-T \ dev
-Generate output for the
-.B troff
-device
-.IR dev .
-This is unnecessary because the
-.B troff
-output generated by
-.B pic
-is device-independent.
-.SH USAGE
-This section describes only the differences between GNU pic and the original
-version of pic.
-Many of these differences also apply to newer versions of Unix pic.
-.SS \*(tx mode
-.LP
-\*(tx mode is enabled by the
-.B \-t
-option.
-In \*(tx mode, pic will define a vbox called
-.B \egraph
-for each picture.
-You must yourself print that vbox using, for example, the command
-.RS
-.LP
-.B
-\ecenterline{\ebox\egraph}
-.RE
-.LP
-Actually, since the vbox has a height of zero this will produce
-slightly more vertical space above the picture than below it;
-.RS
-.LP
-.B
-\ecenterline{\eraise 1em\ebox\egraph}
-.RE
-.LP
-would avoid this.
-.LP
-You must use a \*(tx driver that supports the
-.B tpic
-specials, version 2.
-.LP
-Lines beginning with
-.B \e
-are passed through transparently; a
-.B %
-is added to the end of the line to avoid unwanted spaces.
-You can safely use this feature to change fonts or to
-change the value of
-.BR \ebaselineskip .
-Anything else may well produce undesirable results; use at your own risk.
-Lines beginning with a period are not given any special treatment.
-.SS Commands
-.TP
-\fBfor\fR \fIvariable\fR \fB=\fR \fIexpr1\fR \fBto\fR \fIexpr2\fR \
-[\fBby\fR [\fB*\fR]\fIexpr3\fR] \fBdo\fR \fIX\fR \fIbody\fR \fIX\fR
-Set
-.I variable
-to
-.IR expr1 .
-While the value of
-.I variable
-is less than or equal to
-.IR expr2 ,
-do
-.I body
-and increment
-.I variable
-by
-.IR expr3 ;
-if
-.B by
-is not given, increment
-.I variable
-by 1.
-If
-.I expr3
-is prefixed by
-.B *
-then
-.I variable
-will instead be multiplied by
-.IR expr3 .
-.I X
-can be any character not occurring in
-.IR body .
-.TP
-\fBif\fR \fIexpr\fR \fBthen\fR \fIX\fR \fIif-true\fR \fIX\fR \
-[\fBelse\fR \fIY\fR \fIif-false\fR \fIY\fR]
-Evaluate
-.IR expr ;
-if it is non-zero then do
-.IR if-true ,
-otherwise do
-.IR if-false .
-.I X
-can be any character not occurring in
-.IR if-true .
-.I Y
-can be any character not occurring in
-.IR if-false .
-.TP
-\fBprint\fR \fIarg\fR\|.\|.\|.
-Concatenate the arguments and print as a line on stderr.
-Each
-.I arg
-must be an expression, a position, or text.
-This is useful for debugging.
-.TP
-\fBcommand\fR \fIarg\fR\|.\|.\|.
-Concatenate the arguments
-and pass them through as a line to troff or\*(tx.
-Each
-.I arg
-must be an expression, a position, or text.
-This has a similar effect to a line beginning with
-.B .
-or
-.BR \e ,
-but allows the values of variables to be passed through.
-.TP
-\fBsh\fR \fIX\fR \fIcommand\fR \fIX\fR
-Pass
-.I command
-to a shell.
-.I X
-can be any character not occurring in
-.IR command .
-.TP
-\fBcopy\fR \fB"\fIfilename\fB"\fR
-Include
-.I filename
-at this point in the file.
-.TP
-\fBcopy\fR [\fB"\fIfilename\fB"\fR] \fBthru\fR \fIX\fR \fIbody\fR \fIX\fR \
-[\fBuntil\fR \fB"\fIword\*(ic\fB"\fR]
-.ns
-.TP
-\fBcopy\fR [\fB"\fIfilename\fB"\fR] \fBthru\fR \fImacro\fR \
-[\fBuntil\fR \fB"\fIword\*(ic\fB"\fR]
-This construct does
-.I body
-once for each line of
-.IR filename ;
-the line is split into blank-delimited words,
-and occurrences of
-.BI $ i
-in
-.IR body ,
-for
-.I i
-between 1 and 9,
-are replaced by the
-.IR i -th
-word of the line.
-If
-.I filename
-is not given, lines are taken from the current input up to
-.BR .PE .
-If an
-.B until
-clause is specified,
-lines will be read only until a line the first word of which is
-.IR word ;
-that line will then be discarded.
-.I X
-can be any character not occurring in
-.IR body .
-For example,
-.RS
-.IP
-.ft B
-.nf
-\&.PS
-copy thru % circle at ($1,$2) % until "END"
-1 2
-3 4
-5 6
-END
-box
-\&.PE
-.ft
-.fi
-.RE
-.IP
-is equivalent to
-.RS
-.IP
-.ft B
-.nf
-\&.PS
-circle at (1,2)
-circle at (3,4)
-circle at (5,6)
-box
-\&.PE
-.ft
-.fi
-.RE
-.IP
-The commands to be performed for each line can also be taken
-from a macro defined earlier by giving the name of the macro
-as the argument to
-.BR thru .
-.LP
-.B reset
-.br
-.ns
-.TP
-\fBreset\fI variable1\fB,\fI variable2 .\^.\^.
-Reset pre-defined variables
-.IR variable1 ,
-.I variable2
-\&.\^.\^. to their default values.
-If no arguments are given, reset all pre-defined variables
-to their default values.
-Note that assigning a value to
-.B scale
-also causes all pre-defined variables that control dimensions
-to be reset to their default values times the new value of scale.
-.TP
-\fBplot\fR \fIexpr\fR [\fB"\fItext\*(ic\fB"\fR]
-This is a text object which is constructed by using
-.I text
-as a format string for sprintf
-with an argument of
-.IR expr .
-If
-.I text
-is omitted a format string of
-.B "\(ts%g\(ts"
-is used.
-Attributes can be specified in the same way as for a normal text
-object.
-Be very careful that you specify an appropriate format string;
-pic does only very limited checking of the string.
-This is deprecated in favour of
-.BR sprintf .
-.TP
-.IB variable := expr
-This is similar to
-.B =
-except
-.I variable
-must already be defined,
-and the value of
-.I variable
-will be changed only in the innermost block in which it is defined.
-(By contrast,
-.B =
-defines the variable in the current block if it is not already defined there,
-and then changes the value in the current block.)
-.LP
-Arguments of the form
-.IP
-.IR X\ anything\ X
-.LP
-are also allowed to be of the form
-.IP
-.BI {\ anything\ }
-.LP
-In this case
-.I anything
-can contain balanced occurrences of
-.B {
-and
-.BR } .
-Strings may contain
-.I X
-or imbalanced occurrences of
-.B {
-and
-.BR } .
-.SS Expressions
-The syntax for expressions has been significantly extended:
-.LP
-.IB x\ ^\ y
-(exponentiation)
-.br
-.BI sin( x )
-.br
-.BI cos( x )
-.br
-.BI atan2( y , \ x )
-.br
-.BI log( x )
-(base 10)
-.br
-.BI exp( x )
-(base 10, ie 10\v'-.4m'\fIx\*(ic\fR\v'.4m')
-.br
-.BI sqrt( x )
-.br
-.BI int( x )
-.br
-.B rand()
-(return a random number between 0 and 1)
-.br
-.BI rand( x )
-(return a random number between 1 and
-.IR x ;
-deprecated)
-.br
-.BI max( e1 , \ e2 )
-.br
-.BI min( e1 , \ e2 )
-.br
-.BI ! e
-.br
-\fIe1\fB && \fIe2\fR
-.br
-\fIe1\fB || \fIe2\fR
-.br
-\fIe1\fB == \fIe2\fR
-.br
-\fIe1\fB != \fIe2\fR
-.br
-\fIe1\fB >= \fIe2\fR
-.br
-\fIe1\fB > \fIe2\fR
-.br
-\fIe1\fB <= \fIe2\fR
-.br
-\fIe1\fB < \fIe2\fR
-.br
-\fB"\fIstr1\*(ic\fB" == "\fIstr2\*(ic\fB"\fR
-.br
-\fB"\fIstr1\*(ic\fB" != "\fIstr2\*(ic\fB"\fR
-.br
-.LP
-String comparison expressions must be parenthesised in some contexts
-to avoid ambiguity.
-.SS Other Changes
-.LP
-A bare expression,
-.IR expr ,
-is acceptable as an attribute;
-it is equivalent to
-.IR dir\ expr ,
-where
-.I dir
-is the current direction.
-For example
-.IP
-.B line 2i
-.LP
-means draw a line 2 inches long in the current direction.
-.LP
-The maximum width and height of the picture are taken from the variables
-.B maxpswid
-and
-.BR maxpsht .
-Initially these have values 8.5 and 11.
-.LP
-Scientific notation is allowed for numbers.
-For example
-.RS
-.B
-x = 5e\-2
-.RE
-.LP
-Text attributes can be compounded.
-For example,
-.RS
-.B
-"foo" above ljust
-.RE
-is legal.
-.LP
-There is no limit to the depth to which blocks can be examined.
-For example,
-.RS
-.B
-[A: [B: [C: box ]]] with .A.B.C.sw at 1,2
-.br
-.B
-circle at last [\^].A.B.C
-.RE
-is acceptable.
-.LP
-Arcs now have compass points
-determined by the circle of which the arc is a part.
-.LP
-Circles and arcs can be dotted or dashed.
-In \*(tx mode splines can be dotted or dashed.
-.LP
-Boxes can have rounded corners.
-The
-.B rad
-attribute specifies the radius of the quarter-circles at each corner.
-If no
-.B rad
-or
-.B diam
-attribute is given, a radius of
-.B boxrad
-is used.
-Initially,
-.B boxrad
-has a value of 0.
-A box with rounded corners can be dotted or dashed.
-.LP
-The
-.B .PS
-line can have a second argument specifying a maximum height for
-the picture.
-If the width of zero is specified the width will be ignored in computing
-the scaling factor for the picture.
-Note that GNU pic will always scale a picture by the same amount
-vertically as horizontally.
-This is different from the
-.SM DWB
-2.0 pic which may scale a picture by a
-different amount vertically than horizontally if a height is
-specified.
-.LP
-Each text object has an invisible box associated with it.
-The compass points of a text object are determined by this box.
-The implicit motion associated with the object is also determined
-by this box.
-The dimensions of this box are taken from the width and height attributes;
-if the width attribute is not supplied then the width will be taken to be
-.BR textwid ;
-if the height attribute is not supplied then the height will be taken to be
-the number of text strings associated with the object
-times
-.BR textht .
-Initially
-.B textwid
-and
-.B textht
-have a value of 0.
-.LP
-In places where a quoted text string can be used,
-an expression of the form
-.IP
-.BI sprintf(\(ts format \(ts,\ arg ,\fR.\|.\|.\fB)
-.LP
-can also be used;
-this will produce the arguments formatted according to
-.IR format ,
-which should be a string as described in
-.BR printf (3)
-appropriate for the number of arguments supplied,
-using only the
-.BR e ,
-.BR f ,
-.B g
-or
-.B %
-format characters.
-.LP
-The thickness of the lines used to draw objects is controlled by the
-.B linethick
-variable.
-This gives the thickness of lines in points.
-A negative value means use the default thickness:
-in \*(tx output mode, this means use a thickness of 8 milliinches;
-in \*(tx output mode with the
-.B -c
-option, this means use the line thickness specified by
-.B .ps
-lines;
-in troff output mode, this means use a thickness proportional
-to the pointsize.
-A zero value means draw the thinnest possible line supported by
-the output device.
-Initially it has a value of -1.
-There is also a
-.BR thick [ ness ]
-attribute.
-For example,
-.RS
-.LP
-.B circle thickness 1.5
-.RE
-.LP
-would draw a circle using a line with a thickness of 1.5 points.
-The thickness of lines is not affected by the
-value of the
-.B scale
-variable, nor by the width or height given in the
-.B .PS
-line.
-.LP
-Boxes (including boxes with rounded corners),
-circles and ellipses can be filled by giving then an attribute of
-.BR fill [ ed ].
-This takes an optional argument of an expression with a value between
-0 and 1; 0 will fill it with white, 1 with black, values in between
-with a proportionally gray shade.
-A value greater than 1 can also be used:
-this means fill with the
-shade of gray that is currently being used for text and lines.
-Normally this will be black, but output devices may provide
-a mechanism for changing this.
-Without an argument, then the value of the variable
-.B fillval
-will be used.
-Initially this has a value of 0.5.
-The invisible attribute does not affect the filling of objects.
-Any text associated with a filled object will be added after the
-object has been filled, so that the text will not be obscured
-by the filling.
-.LP
-Arrow heads will be drawn as solid triangles if the variable
-.B arrowhead
-is non-zero and either \*(tx mode is enabled or
-the
-.B \-x
-option has been given.
-Initially
-.B arrowhead
-has a value of 1.
-.LP
-The troff output of pic is device-independent.
-The
-.B \-T
-option is therefore redundant.
-All numbers are taken to be in inches; numbers are never interpreted
-to be in troff machine units.
-.LP
-Objects can have an
-.B aligned
-attribute.
-This will only work when the postprocessor is
-.BR grops .
-Any text associated with an object having the
-.B aligned
-attribute will be rotated about the center of the object
-so that it is aligned in the direction from the start point
-to the end point of the object.
-Note that this attribute will have no effect for objects whose start and
-end points are coincident.
-.LP
-In places where
-.IB n th
-is allowed
-.BI ` expr 'th
-is also allowed.
-Note that
-.B 'th
-is a single token: no space is allowed between the
-.B '
-and the
-.BR th .
-For example,
-.IP
-.B
-.nf
-for i = 1 to 4 do {
- line from `i'th box.nw to `i+1'th box.se
-}
-.fi
-.SH FILES
-.Tp \w'\fB@MACRODIR@/tmac.pic'u+3n
-.B
-@MACRODIR@/tmac.pic
-Example definitions of the
-.B PS
-and
-.B PE
-macros.
-.SH "SEE ALSO"
-.BR @g@troff (@MAN1EXT@),
-.BR groff_out (@MAN5EXT@),
-.BR tex (1)
-.br
-Tpic: Pic for \*(tx
-.br
-Brian W. Kernighan,
-PIC \(em A Graphics Language for Typesetting (User Manual).
-AT&T Bell Laboratories, Computing Science Technical Report No.\ 116
-<URL:http://cm.bell-labs.com/cm/cs/cstr/116.ps.gz>
-(revised May, 1991).
-.SH BUGS
-.LP
-Input characters that are illegal for
-.B groff
-(ie those with
-.SM ASCII
-code 0 or between 013 and 037 octal or between 0200 and 0237 octal)
-are rejected even in \*(tx mode.
-.LP
-The interpretation of
-.B fillval
-is incompatible with the pic in 10th edition Unix,
-which interprets 0 as black and 1 as white.
diff --git a/gnu/usr.bin/groff/pic/pic.h b/gnu/usr.bin/groff/pic/pic.h
deleted file mode 100644
index 70e95676e9f..00000000000
--- a/gnu/usr.bin/groff/pic/pic.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-#include <errno.h>
-
-extern "C" {
- double hypot(double, double);
-}
-
-#include "assert.h"
-#include "cset.h"
-#include "lib.h"
-#include "stringclass.h"
-#include "errarg.h"
-#include "error.h"
-#include "position.h"
-#include "text.h"
-#include "output.h"
-
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-class input {
- input *next;
-public:
- input();
- virtual ~input();
- virtual int get() = 0;
- virtual int peek() = 0;
- virtual int get_location(const char **, int *);
- friend class input_stack;
- friend class copy_rest_thru_input;
-};
-
-class file_input : public input {
- FILE *fp;
- const char *filename;
- int lineno;
- string line;
- const char *ptr;
- int read_line();
-public:
- file_input(FILE *, const char *);
- ~file_input();
- int get();
- int peek();
- int get_location(const char **, int *);
-};
-
-void lex_init(input *);
-int get_location(char **, int *);
-
-void do_copy(const char *file);
-void parse_init();
-void parse_cleanup();
-
-void lex_error(const char *message,
- const errarg &arg1 = empty_errarg,
- const errarg &arg2 = empty_errarg,
- const errarg &arg3 = empty_errarg);
-
-void lex_warning(const char *message,
- const errarg &arg1 = empty_errarg,
- const errarg &arg2 = empty_errarg,
- const errarg &arg3 = empty_errarg);
-
-void lex_cleanup();
-
-extern int flyback_flag;
-extern int command_char;
-// zero_length_line_flag is non-zero if zero-length lines are drawn
-// as dots by the output device
-extern int zero_length_line_flag;
-extern int driver_extension_flag;
-extern int compatible_flag;
-extern int safer_flag;
diff --git a/gnu/usr.bin/groff/pic/pic.y b/gnu/usr.bin/groff/pic/pic.y
deleted file mode 100644
index d0420acd793..00000000000
--- a/gnu/usr.bin/groff/pic/pic.y
+++ /dev/null
@@ -1,1784 +0,0 @@
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-%{
-#include "pic.h"
-#include "ptable.h"
-#include "object.h"
-
-extern int delim_flag;
-extern void do_copy(const char *);
-extern void copy_rest_thru(const char *, const char *);
-extern void copy_file_thru(const char *, const char *, const char *);
-extern void push_body(const char *);
-extern void do_for(char *var, double from, double to,
- int by_is_multiplicative, double by, char *body);
-extern void do_lookahead();
-
-#ifndef HAVE_FMOD
-extern "C" {
- double fmod(double, double);
-}
-#endif
-
-#undef rand
-extern "C" {
- int rand();
-}
-
-/* Maximum number of characters produced by printf("%g") */
-#define GDIGITS 14
-
-int yylex();
-void yyerror(const char *);
-
-void reset(const char *nm);
-void reset_all();
-
-place *lookup_label(const char *);
-void define_label(const char *label, const place *pl);
-
-direction current_direction;
-position current_position;
-
-implement_ptable(place)
-
-PTABLE(place) top_table;
-
-PTABLE(place) *current_table = &top_table;
-saved_state *current_saved_state = 0;
-
-object_list olist;
-
-const char *ordinal_postfix(int n);
-const char *object_type_name(object_type type);
-char *format_number(const char *form, double n);
-char *do_sprintf(const char *form, const double *v, int nv);
-
-%}
-
-
-%union {
- char *str;
- int n;
- double x;
- struct { double x, y; } pair;
- struct { double x; char *body; } if_data;
- struct { char *str; const char *filename; int lineno; } lstr;
- struct { double *v; int nv; int maxv; } dv;
- struct { double val; int is_multiplicative; } by;
- place pl;
- object *obj;
- corner crn;
- path *pth;
- object_spec *spec;
- saved_state *pstate;
- graphics_state state;
- object_type obtype;
-}
-
-%token <str> LABEL
-%token <str> VARIABLE
-%token <x> NUMBER
-%token <lstr> TEXT
-%token <lstr> COMMAND_LINE
-%token <str> DELIMITED
-%token <n> ORDINAL
-%token TH
-%token LEFT_ARROW_HEAD
-%token RIGHT_ARROW_HEAD
-%token DOUBLE_ARROW_HEAD
-%token LAST
-%token UP
-%token DOWN
-%token LEFT
-%token RIGHT
-%token BOX
-%token CIRCLE
-%token ELLIPSE
-%token ARC
-%token LINE
-%token ARROW
-%token MOVE
-%token SPLINE
-%token HEIGHT
-%token RADIUS
-%token WIDTH
-%token DIAMETER
-%token UP
-%token DOWN
-%token RIGHT
-%token LEFT
-%token FROM
-%token TO
-%token AT
-%token WITH
-%token BY
-%token THEN
-%token DOTTED
-%token DASHED
-%token CHOP
-%token SAME
-%token INVISIBLE
-%token LJUST
-%token RJUST
-%token ABOVE
-%token BELOW
-%token OF
-%token THE
-%token WAY
-%token BETWEEN
-%token AND
-%token HERE
-%token DOT_N
-%token DOT_E
-%token DOT_W
-%token DOT_S
-%token DOT_NE
-%token DOT_SE
-%token DOT_NW
-%token DOT_SW
-%token DOT_C
-%token DOT_START
-%token DOT_END
-%token DOT_X
-%token DOT_Y
-%token DOT_HT
-%token DOT_WID
-%token DOT_RAD
-%token SIN
-%token COS
-%token ATAN2
-%token LOG
-%token EXP
-%token SQRT
-%token K_MAX
-%token K_MIN
-%token INT
-%token RAND
-%token COPY
-%token THRU
-%token TOP
-%token BOTTOM
-%token UPPER
-%token LOWER
-%token SH
-%token PRINT
-%token CW
-%token CCW
-%token FOR
-%token DO
-%token IF
-%token ELSE
-%token ANDAND
-%token OROR
-%token NOTEQUAL
-%token EQUALEQUAL
-%token LESSEQUAL
-%token GREATEREQUAL
-%token LEFT_CORNER
-%token RIGHT_CORNER
-%token CENTER
-%token END
-%token START
-%token RESET
-%token UNTIL
-%token PLOT
-%token THICKNESS
-%token FILL
-%token ALIGNED
-%token SPRINTF
-%token COMMAND
-
-%token DEFINE
-%token UNDEF
-
-/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */
-%left PLOT
-%left TEXT SPRINTF
-
-/* give text adjustments higher precedence than TEXT, so that
-box "foo" above ljust == box ("foo" above ljust)
-*/
-
-%left LJUST RJUST ABOVE BELOW
-
-%left LEFT RIGHT
-/* Give attributes that take an optional expression a higher
-precedence than left and right, so that eg `line chop left'
-parses properly. */
-%left CHOP DASHED DOTTED UP DOWN FILL
-%left LABEL
-
-%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND LAST
-%left ORDINAL HERE '`'
-
-/* these need to be lower than '-' */
-%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
-
-/* these must have higher precedence than CHOP so that `label %prec CHOP'
-works */
-%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
-%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
-%left UPPER LOWER CENTER START END
-
-%left ','
-%left OROR
-%left ANDAND
-%left EQUALEQUAL NOTEQUAL
-%left '<' '>' LESSEQUAL GREATEREQUAL
-
-%left BETWEEN OF
-%left AND
-
-%left '+' '-'
-%left '*' '/' '%'
-%right '!'
-%right '^'
-
-%type <x> expr any_expr text_expr
-%type <by> optional_by
-%type <pair> expr_pair position_not_place
-%type <if_data> simple_if
-%type <obj> nth_primitive
-%type <crn> corner
-%type <pth> path label_path relative_path
-%type <pl> place label element element_list middle_element_list
-%type <spec> object_spec
-%type <pair> position
-%type <obtype> object_type
-%type <n> optional_ordinal_last ordinal
-%type <str> until
-%type <dv> sprintf_args
-%type <lstr> text print_args print_arg
-
-%%
-
-top:
- optional_separator
- | element_list
- {
- if (olist.head)
- print_picture(olist.head);
- }
- ;
-
-
-element_list:
- optional_separator middle_element_list optional_separator
- { $$ = $2; }
- ;
-
-middle_element_list:
- element
- { $$ = $1; }
- | middle_element_list separator element
- { $$ = $1; }
- ;
-
-optional_separator:
- /* empty */
- | separator
- ;
-
-separator:
- ';'
- | separator ';'
- ;
-
-placeless_element:
- VARIABLE '=' any_expr
- {
- define_variable($1, $3);
- a_delete $1;
- }
- | VARIABLE ':' '=' any_expr
- {
- place *p = lookup_label($1);
- if (!p) {
- lex_error("variable `%1' not defined", $1);
- YYABORT;
- }
- p->obj = 0;
- p->x = $4;
- p->y = 0.0;
- a_delete $1;
- }
- | UP
- { current_direction = UP_DIRECTION; }
- | DOWN
- { current_direction = DOWN_DIRECTION; }
- | LEFT
- { current_direction = LEFT_DIRECTION; }
- | RIGHT
- { current_direction = RIGHT_DIRECTION; }
- | COMMAND_LINE
- {
- olist.append(make_command_object($1.str, $1.filename,
- $1.lineno));
- }
- | COMMAND print_args
- {
- olist.append(make_command_object($2.str, $2.filename,
- $2.lineno));
- }
- | PRINT print_args
- {
- fprintf(stderr, "%s\n", $2.str);
- a_delete $2.str;
- fflush(stderr);
- }
- | SH
- { delim_flag = 1; }
- DELIMITED
- {
- delim_flag = 0;
- if (safer_flag)
- lex_error("unsafe to run command `%1'", $3);
- else
- system($3);
- a_delete $3;
- }
- | COPY TEXT
- {
- if (yychar < 0)
- do_lookahead();
- do_copy($2.str);
- // do not delete the filename
- }
- | COPY TEXT THRU
- { delim_flag = 2; }
- DELIMITED
- { delim_flag = 0; }
- until
- {
- if (yychar < 0)
- do_lookahead();
- copy_file_thru($2.str, $5, $7);
- // do not delete the filename
- a_delete $5;
- a_delete $7;
- }
- | COPY THRU
- { delim_flag = 2; }
- DELIMITED
- { delim_flag = 0; }
- until
- {
- if (yychar < 0)
- do_lookahead();
- copy_rest_thru($4, $6);
- a_delete $4;
- a_delete $6;
- }
- | FOR VARIABLE '=' expr TO expr optional_by DO
- { delim_flag = 1; }
- DELIMITED
- {
- delim_flag = 0;
- if (yychar < 0)
- do_lookahead();
- do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10);
- }
- | simple_if
- {
- if (yychar < 0)
- do_lookahead();
- if ($1.x != 0.0)
- push_body($1.body);
- a_delete $1.body;
- }
- | simple_if ELSE
- { delim_flag = 1; }
- DELIMITED
- {
- delim_flag = 0;
- if (yychar < 0)
- do_lookahead();
- if ($1.x != 0.0)
- push_body($1.body);
- else
- push_body($4);
- a_delete $1.body;
- a_delete $4;
- }
- | reset_variables
- | RESET
- { define_variable("scale", 1.0); }
- ;
-
-reset_variables:
- RESET VARIABLE
- { reset($2); a_delete $2; }
- | reset_variables VARIABLE
- { reset($2); a_delete $2; }
- | reset_variables ',' VARIABLE
- { reset($3); a_delete $3; }
- ;
-
-print_args:
- print_arg
- { $$ = $1; }
- | print_args print_arg
- {
- $$.str = new char[strlen($1.str) + strlen($2.str) + 1];
- strcpy($$.str, $1.str);
- strcat($$.str, $2.str);
- a_delete $1.str;
- a_delete $2.str;
- if ($1.filename) {
- $$.filename = $1.filename;
- $$.lineno = $1.lineno;
- }
- else if ($2.filename) {
- $$.filename = $2.filename;
- $$.lineno = $2.lineno;
- }
- }
- ;
-
-print_arg:
- expr %prec ','
- {
- $$.str = new char[GDIGITS + 1];
- sprintf($$.str, "%g", $1);
- $$.filename = 0;
- $$.lineno = 0;
- }
- | text
- { $$ = $1; }
- | position %prec ','
- {
- $$.str = new char[GDIGITS + 2 + GDIGITS + 1];
- sprintf($$.str, "%g, %g", $1.x, $1.y);
- $$.filename = 0;
- $$.lineno = 0;
- }
-
-simple_if:
- IF any_expr THEN
- { delim_flag = 1; }
- DELIMITED
- { delim_flag = 0; $$.x = $2; $$.body = $5; }
- ;
-
-until:
- /* empty */
- { $$ = 0; }
- | UNTIL TEXT
- { $$ = $2.str; }
- ;
-
-any_expr:
- expr
- { $$ = $1; }
- | text_expr
- { $$ = $1; }
- ;
-
-text_expr:
- text EQUALEQUAL text
- {
- $$ = strcmp($1.str, $3.str) == 0;
- a_delete $1.str;
- a_delete $3.str;
- }
- | text NOTEQUAL text
- {
- $$ = strcmp($1.str, $3.str) != 0;
- a_delete $1.str;
- a_delete $3.str;
- }
- | text_expr ANDAND text_expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
- | text_expr ANDAND expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
- | expr ANDAND text_expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
- | text_expr OROR text_expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
- | text_expr OROR expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
- | expr OROR text_expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
- | '!' text_expr
- { $$ = ($2 == 0.0); }
- ;
-
-
-optional_by:
- /* empty */
- { $$.val = 1.0; $$.is_multiplicative = 0; }
- | BY expr
- { $$.val = $2; $$.is_multiplicative = 0; }
- | BY '*' expr
- { $$.val = $3; $$.is_multiplicative = 1; }
- ;
-
-element:
- object_spec
- {
- $$.obj = $1->make_object(&current_position,
- &current_direction);
- if ($$.obj == 0)
- YYABORT;
- delete $1;
- if ($$.obj)
- olist.append($$.obj);
- else {
- $$.x = current_position.x;
- $$.y = current_position.y;
- }
- }
- | LABEL ':' optional_separator element
- { $$ = $4; define_label($1, & $$); a_delete $1; }
- | LABEL ':' optional_separator position_not_place
- {
- $$.obj = 0;
- $$.x = $4.x;
- $$.y = $4.y;
- define_label($1, & $$);
- a_delete $1;
- }
- | LABEL ':' optional_separator place
- {
- $$ = $4;
- define_label($1, & $$);
- a_delete $1;
- }
- | '{'
- {
- $<state>$.x = current_position.x;
- $<state>$.y = current_position.y;
- $<state>$.dir = current_direction;
- }
- element_list '}'
- {
- current_position.x = $<state>2.x;
- current_position.y = $<state>2.y;
- current_direction = $<state>2.dir;
- }
- optional_element
- {
- $$ = $3;
- }
- | placeless_element
- {
- $$.obj = 0;
- $$.x = current_position.x;
- $$.y = current_position.y;
- }
- ;
-
-optional_element:
- /* empty */
- {}
- | element
- {}
- ;
-
-object_spec:
- BOX
- {
- $$ = new object_spec(BOX_OBJECT);
- }
- | CIRCLE
- {
- $$ = new object_spec(CIRCLE_OBJECT);
- }
- | ELLIPSE
- {
- $$ = new object_spec(ELLIPSE_OBJECT);
- }
- | ARC
- {
- $$ = new object_spec(ARC_OBJECT);
- $$->dir = current_direction;
- }
- | LINE
- {
- $$ = new object_spec(LINE_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
- | ARROW
- {
- $$ = new object_spec(ARROW_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
- | MOVE
- {
- $$ = new object_spec(MOVE_OBJECT);
- lookup_variable("moveht", & $$->segment_height);
- lookup_variable("movewid", & $$->segment_width);
- $$->dir = current_direction;
- }
- | SPLINE
- {
- $$ = new object_spec(SPLINE_OBJECT);
- lookup_variable("lineht", & $$->segment_height);
- lookup_variable("linewid", & $$->segment_width);
- $$->dir = current_direction;
- }
- | text %prec TEXT
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item($1.str, $1.filename, $1.lineno);
- }
- | PLOT expr
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item(format_number(0, $2), 0, -1);
- }
- | PLOT expr text
- {
- $$ = new object_spec(TEXT_OBJECT);
- $$->text = new text_item(format_number($3.str, $2),
- $3.filename, $3.lineno);
- a_delete $3.str;
- }
- | '['
- {
- saved_state *p = new saved_state;
- $<pstate>$ = p;
- p->x = current_position.x;
- p->y = current_position.y;
- p->dir = current_direction;
- p->tbl = current_table;
- p->prev = current_saved_state;
- current_position.x = 0.0;
- current_position.y = 0.0;
- current_table = new PTABLE(place);
- current_saved_state = p;
- olist.append(make_mark_object());
- }
- element_list ']'
- {
- current_position.x = $<pstate>2->x;
- current_position.y = $<pstate>2->y;
- current_direction = $<pstate>2->dir;
- $$ = new object_spec(BLOCK_OBJECT);
- olist.wrap_up_block(& $$->oblist);
- $$->tbl = current_table;
- current_table = $<pstate>2->tbl;
- current_saved_state = $<pstate>2->prev;
- delete $<pstate>2;
- }
- | object_spec HEIGHT expr
- {
- $$ = $1;
- $$->height = $3;
- $$->flags |= HAS_HEIGHT;
- }
- | object_spec RADIUS expr
- {
- $$ = $1;
- $$->radius = $3;
- $$->flags |= HAS_RADIUS;
- }
- | object_spec WIDTH expr
- {
- $$ = $1;
- $$->width = $3;
- $$->flags |= HAS_WIDTH;
- }
- | object_spec DIAMETER expr
- {
- $$ = $1;
- $$->radius = $3/2.0;
- $$->flags |= HAS_RADIUS;
- }
- | object_spec expr %prec HEIGHT
- {
- $$ = $1;
- $$->flags |= HAS_SEGMENT;
- switch ($$->dir) {
- case UP_DIRECTION:
- $$->segment_pos.y += $2;
- break;
- case DOWN_DIRECTION:
- $$->segment_pos.y -= $2;
- break;
- case RIGHT_DIRECTION:
- $$->segment_pos.x += $2;
- break;
- case LEFT_DIRECTION:
- $$->segment_pos.x -= $2;
- break;
- }
- }
- | object_spec UP
- {
- $$ = $1;
- $$->dir = UP_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y += $$->segment_height;
- }
- | object_spec UP expr
- {
- $$ = $1;
- $$->dir = UP_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y += $3;
- }
- | object_spec DOWN
- {
- $$ = $1;
- $$->dir = DOWN_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y -= $$->segment_height;
- }
- | object_spec DOWN expr
- {
- $$ = $1;
- $$->dir = DOWN_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.y -= $3;
- }
- | object_spec RIGHT
- {
- $$ = $1;
- $$->dir = RIGHT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $$->segment_width;
- }
- | object_spec RIGHT expr
- {
- $$ = $1;
- $$->dir = RIGHT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $3;
- }
- | object_spec LEFT
- {
- $$ = $1;
- $$->dir = LEFT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x -= $$->segment_width;
- }
- | object_spec LEFT expr
- {
- $$ = $1;
- $$->dir = LEFT_DIRECTION;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x -= $3;
- }
- | object_spec FROM position
- {
- $$ = $1;
- $$->flags |= HAS_FROM;
- $$->from.x = $3.x;
- $$->from.y = $3.y;
- }
- | object_spec TO position
- {
- $$ = $1;
- if ($$->flags & HAS_SEGMENT)
- $$->segment_list = new segment($$->segment_pos,
- $$->segment_is_absolute,
- $$->segment_list);
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x = $3.x;
- $$->segment_pos.y = $3.y;
- $$->segment_is_absolute = 1;
- $$->flags |= HAS_TO;
- $$->to.x = $3.x;
- $$->to.y = $3.y;
- }
- | object_spec AT position
- {
- $$ = $1;
- $$->flags |= HAS_AT;
- $$->at.x = $3.x;
- $$->at.y = $3.y;
- if ($$->type != ARC_OBJECT) {
- $$->flags |= HAS_FROM;
- $$->from.x = $3.x;
- $$->from.y = $3.y;
- }
- }
- | object_spec WITH path
- {
- $$ = $1;
- $$->flags |= HAS_WITH;
- $$->with = $3;
- }
- | object_spec BY expr_pair
- {
- $$ = $1;
- $$->flags |= HAS_SEGMENT;
- $$->segment_pos.x += $3.x;
- $$->segment_pos.y += $3.y;
- }
- | object_spec THEN
- {
- $$ = $1;
- if ($$->flags & HAS_SEGMENT) {
- $$->segment_list = new segment($$->segment_pos,
- $$->segment_is_absolute,
- $$->segment_list);
- $$->flags &= ~HAS_SEGMENT;
- $$->segment_pos.x = $$->segment_pos.y = 0.0;
- $$->segment_is_absolute = 0;
- }
- }
- | object_spec DOTTED
- {
- $$ = $1;
- $$->flags |= IS_DOTTED;
- lookup_variable("dashwid", & $$->dash_width);
- }
- | object_spec DOTTED expr
- {
- $$ = $1;
- $$->flags |= IS_DOTTED;
- $$->dash_width = $3;
- }
- | object_spec DASHED
- {
- $$ = $1;
- $$->flags |= IS_DASHED;
- lookup_variable("dashwid", & $$->dash_width);
- }
- | object_spec DASHED expr
- {
- $$ = $1;
- $$->flags |= IS_DASHED;
- $$->dash_width = $3;
- }
- | object_spec FILL
- {
- $$ = $1;
- $$->flags |= IS_DEFAULT_FILLED;
- }
- | object_spec FILL expr
- {
- $$ = $1;
- $$->flags |= IS_FILLED;
- $$->fill = $3;
- }
- | object_spec CHOP
- {
- $$ = $1;
- // line chop chop means line chop 0 chop 0
- if ($$->flags & IS_DEFAULT_CHOPPED) {
- $$->flags |= IS_CHOPPED;
- $$->flags &= ~IS_DEFAULT_CHOPPED;
- $$->start_chop = $$->end_chop = 0.0;
- }
- else if ($$->flags & IS_CHOPPED) {
- $$->end_chop = 0.0;
- }
- else {
- $$->flags |= IS_DEFAULT_CHOPPED;
- }
- }
- | object_spec CHOP expr
- {
- $$ = $1;
- if ($$->flags & IS_DEFAULT_CHOPPED) {
- $$->flags |= IS_CHOPPED;
- $$->flags &= ~IS_DEFAULT_CHOPPED;
- $$->start_chop = 0.0;
- $$->end_chop = $3;
- }
- else if ($$->flags & IS_CHOPPED) {
- $$->end_chop = $3;
- }
- else {
- $$->start_chop = $$->end_chop = $3;
- $$->flags |= IS_CHOPPED;
- }
- }
- | object_spec SAME
- {
- $$ = $1;
- $$->flags |= IS_SAME;
- }
- | object_spec INVISIBLE
- {
- $$ = $1;
- $$->flags |= IS_INVISIBLE;
- }
- | object_spec LEFT_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= HAS_LEFT_ARROW_HEAD;
- }
- | object_spec RIGHT_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= HAS_RIGHT_ARROW_HEAD;
- }
- | object_spec DOUBLE_ARROW_HEAD
- {
- $$ = $1;
- $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD);
- }
- | object_spec CW
- {
- $$ = $1;
- $$->flags |= IS_CLOCKWISE;
- }
- | object_spec CCW
- {
- $$ = $1;
- $$->flags &= ~IS_CLOCKWISE;
- }
- | object_spec text %prec TEXT
- {
- $$ = $1;
- text_item **p;
- for (p = & $$->text; *p; p = &(*p)->next)
- ;
- *p = new text_item($2.str, $2.filename, $2.lineno);
- }
- | object_spec LJUST
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.h = LEFT_ADJUST;
- }
- }
- | object_spec RJUST
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.h = RIGHT_ADJUST;
- }
- }
- | object_spec ABOVE
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.v = ABOVE_ADJUST;
- }
- }
- | object_spec BELOW
- {
- $$ = $1;
- if ($$->text) {
- text_item *p;
- for (p = $$->text; p->next; p = p->next)
- ;
- p->adj.v = BELOW_ADJUST;
- }
- }
- | object_spec THICKNESS expr
- {
- $$ = $1;
- $$->flags |= HAS_THICKNESS;
- $$->thickness = $3;
- }
- | object_spec ALIGNED
- {
- $$ = $1;
- $$->flags |= IS_ALIGNED;
- }
- ;
-
-text:
- TEXT
- {
- $$ = $1;
- }
- | SPRINTF '(' TEXT sprintf_args ')'
- {
- $$.filename = $3.filename;
- $$.lineno = $3.lineno;
- $$.str = do_sprintf($3.str, $4.v, $4.nv);
- a_delete $4.v;
- a_delete $3.str;
- }
- ;
-
-sprintf_args:
- /* empty */
- {
- $$.v = 0;
- $$.nv = 0;
- $$.maxv = 0;
- }
- | sprintf_args ',' expr
- {
- $$ = $1;
- if ($$.nv >= $$.maxv) {
- if ($$.nv == 0) {
- $$.v = new double[4];
- $$.maxv = 4;
- }
- else {
- double *oldv = $$.v;
- $$.maxv *= 2;
- $$.v = new double[$$.maxv];
- memcpy($$.v, oldv, $$.nv*sizeof(double));
- a_delete oldv;
- }
- }
- $$.v[$$.nv] = $3;
- $$.nv += 1;
- }
- ;
-
-position:
- position_not_place
- { $$ = $1; }
- | place
- {
- position pos = $1;
- $$.x = pos.x;
- $$.y = pos.y;
- }
- ;
-
-position_not_place:
- expr_pair
- { $$ = $1; }
- | position '+' expr_pair
- {
- $$.x = $1.x + $3.x;
- $$.y = $1.y + $3.y;
- }
- | position '-' expr_pair
- {
- $$.x = $1.x - $3.x;
- $$.y = $1.y - $3.y;
- }
- | '(' position ',' position ')'
- {
- $$.x = $2.x;
- $$.y = $4.y;
- }
- | expr between position AND position
- {
- $$.x = (1.0 - $1)*$3.x + $1*$5.x;
- $$.y = (1.0 - $1)*$3.y + $1*$5.y;
- }
- | expr '<' position ',' position '>'
- {
- $$.x = (1.0 - $1)*$3.x + $1*$5.x;
- $$.y = (1.0 - $1)*$3.y + $1*$5.y;
- }
- ;
-
-between:
- BETWEEN
- | OF THE WAY BETWEEN
- ;
-
-expr_pair:
- expr ',' expr
- { $$.x = $1; $$.y = $3; }
- | '(' expr_pair ')'
- { $$ = $2; }
- ;
-
-place:
- label %prec CHOP /* line at A left == line (at A) left */
- { $$ = $1; }
- | label corner
- {
- path pth($2);
- if (!pth.follow($1, & $$))
- YYABORT;
- }
- | corner label
- {
- path pth($1);
- if (!pth.follow($2, & $$))
- YYABORT;
- }
- | corner OF label
- {
- path pth($1);
- if (!pth.follow($3, & $$))
- YYABORT;
- }
- | HERE
- {
- $$.x = current_position.x;
- $$.y = current_position.y;
- $$.obj = 0;
- }
- ;
-
-label:
- LABEL
- {
- place *p = lookup_label($1);
- if (!p) {
- lex_error("there is no place `%1'", $1);
- YYABORT;
- }
- $$ = *p;
- a_delete $1;
- }
- | nth_primitive
- {
- $$.obj = $1;
- }
- | label '.' LABEL
- {
- path pth($3);
- if (!pth.follow($1, & $$))
- YYABORT;
- }
- ;
-
-ordinal:
- ORDINAL
- { $$ = $1; }
- | '`' any_expr TH
- {
- // XXX Check for overflow (and non-integers?).
- $$ = (int)$2;
- }
- ;
-
-optional_ordinal_last:
- LAST
- { $$ = 1; }
- | ordinal LAST
- { $$ = $1; }
- ;
-
-nth_primitive:
- ordinal object_type
- {
- int count = 0;
- object *p;
- for (p = olist.head; p != 0; p = p->next)
- if (p->type() == $2 && ++count == $1) {
- $$ = p;
- break;
- }
- if (p == 0) {
- lex_error("there is no %1%2 %3", $1, ordinal_postfix($1),
- object_type_name($2));
- YYABORT;
- }
- }
- | optional_ordinal_last object_type
- {
- int count = 0;
- object *p;
- for (p = olist.tail; p != 0; p = p->prev)
- if (p->type() == $2 && ++count == $1) {
- $$ = p;
- break;
- }
- if (p == 0) {
- lex_error("there is no %1%2 last %3", $1,
- ordinal_postfix($1), object_type_name($2));
- YYABORT;
- }
- }
- ;
-
-object_type:
- BOX
- { $$ = BOX_OBJECT; }
- | CIRCLE
- { $$ = CIRCLE_OBJECT; }
- | ELLIPSE
- { $$ = ELLIPSE_OBJECT; }
- | ARC
- { $$ = ARC_OBJECT; }
- | LINE
- { $$ = LINE_OBJECT; }
- | ARROW
- { $$ = ARROW_OBJECT; }
- | SPLINE
- { $$ = SPLINE_OBJECT; }
- | '[' ']'
- { $$ = BLOCK_OBJECT; }
- | TEXT
- { $$ = TEXT_OBJECT; }
- ;
-
-label_path:
- '.' LABEL
- {
- $$ = new path($2);
- }
- | label_path '.' LABEL
- {
- $$ = $1;
- $$->append($3);
- }
- ;
-
-relative_path:
- corner
- {
- $$ = new path($1);
- }
- /* give this a lower precedence than LEFT and RIGHT so that
- [A: box] with .A left == [A: box] with (.A left) */
-
- | label_path %prec TEXT
- {
- $$ = $1;
- }
- | label_path corner
- {
- $$ = $1;
- $$->append($2);
- }
- ;
-
-path:
- relative_path
- {
- $$ = $1;
- }
- | '(' relative_path ',' relative_path ')'
- {
- $$ = $2;
- $$->set_ypath($4);
- }
- /* The rest of these rules are a compatibility sop. */
- | ORDINAL LAST object_type relative_path
- {
- lex_warning("`%1%2 last %3' in `with' argument ignored",
- $1, ordinal_postfix($1), object_type_name($3));
- $$ = $4;
- }
- | LAST object_type relative_path
- {
- lex_warning("`last %1' in `with' argument ignored",
- object_type_name($2));
- $$ = $3;
- }
- | ORDINAL object_type relative_path
- {
- lex_warning("`%1%2 %3' in `with' argument ignored",
- $1, ordinal_postfix($1), object_type_name($2));
- $$ = $3;
- }
- | LABEL relative_path
- {
- lex_warning("initial `%1' in `with' argument ignored", $1);
- a_delete $1;
- $$ = $2;
- }
- ;
-
-corner:
- DOT_N
- { $$ = &object::north; }
- | DOT_E
- { $$ = &object::east; }
- | DOT_W
- { $$ = &object::west; }
- | DOT_S
- { $$ = &object::south; }
- | DOT_NE
- { $$ = &object::north_east; }
- | DOT_SE
- { $$ = &object:: south_east; }
- | DOT_NW
- { $$ = &object::north_west; }
- | DOT_SW
- { $$ = &object::south_west; }
- | DOT_C
- { $$ = &object::center; }
- | DOT_START
- { $$ = &object::start; }
- | DOT_END
- { $$ = &object::end; }
- | TOP
- { $$ = &object::north; }
- | BOTTOM
- { $$ = &object::south; }
- | LEFT
- { $$ = &object::west; }
- | RIGHT
- { $$ = &object::east; }
- | UPPER LEFT
- { $$ = &object::north_west; }
- | LOWER LEFT
- { $$ = &object::south_west; }
- | UPPER RIGHT
- { $$ = &object::north_east; }
- | LOWER RIGHT
- { $$ = &object::south_east; }
- | LEFT_CORNER
- { $$ = &object::west; }
- | RIGHT_CORNER
- { $$ = &object::east; }
- | UPPER LEFT_CORNER
- { $$ = &object::north_west; }
- | LOWER LEFT_CORNER
- { $$ = &object::south_west; }
- | UPPER RIGHT_CORNER
- { $$ = &object::north_east; }
- | LOWER RIGHT_CORNER
- { $$ = &object::south_east; }
- | CENTER
- { $$ = &object::center; }
- | START
- { $$ = &object::start; }
- | END
- { $$ = &object::end; }
- ;
-
-expr:
- VARIABLE
- {
- if (!lookup_variable($1, & $$)) {
- lex_error("there is no variable `%1'", $1);
- YYABORT;
- }
- a_delete $1;
- }
- | NUMBER
- { $$ = $1; }
- | place DOT_X
- {
- if ($1.obj != 0)
- $$ = $1.obj->origin().x;
- else
- $$ = $1.x;
- }
- | place DOT_Y
- {
- if ($1.obj != 0)
- $$ = $1.obj->origin().y;
- else
- $$ = $1.y;
- }
- | place DOT_HT
- {
- if ($1.obj != 0)
- $$ = $1.obj->height();
- else
- $$ = 0.0;
- }
- | place DOT_WID
- {
- if ($1.obj != 0)
- $$ = $1.obj->width();
- else
- $$ = 0.0;
- }
- | place DOT_RAD
- {
- if ($1.obj != 0)
- $$ = $1.obj->radius();
- else
- $$ = 0.0;
- }
- | expr '+' expr
- { $$ = $1 + $3; }
- | expr '-' expr
- { $$ = $1 - $3; }
- | expr '*' expr
- { $$ = $1 * $3; }
- | expr '/' expr
- {
- if ($3 == 0.0) {
- lex_error("division by zero");
- YYABORT;
- }
- $$ = $1/$3;
- }
- | expr '%' expr
- {
- if ($3 == 0.0) {
- lex_error("modulus by zero");
- YYABORT;
- }
- $$ = fmod($1, $3);
- }
- | expr '^' expr
- {
- errno = 0;
- $$ = pow($1, $3);
- if (errno == EDOM) {
- lex_error("arguments to `^' operator out of domain");
- YYABORT;
- }
- if (errno == ERANGE) {
- lex_error("result of `^' operator out of range");
- YYABORT;
- }
- }
- | '-' expr %prec '!'
- { $$ = -$2; }
- | '(' any_expr ')'
- { $$ = $2; }
- | SIN '(' any_expr ')'
- {
- errno = 0;
- $$ = sin($3);
- if (errno == ERANGE) {
- lex_error("sin result out of range");
- YYABORT;
- }
- }
- | COS '(' any_expr ')'
- {
- errno = 0;
- $$ = cos($3);
- if (errno == ERANGE) {
- lex_error("cos result out of range");
- YYABORT;
- }
- }
- | ATAN2 '(' any_expr ',' any_expr ')'
- {
- errno = 0;
- $$ = atan2($3, $5);
- if (errno == EDOM) {
- lex_error("atan2 argument out of domain");
- YYABORT;
- }
- if (errno == ERANGE) {
- lex_error("atan2 result out of range");
- YYABORT;
- }
- }
- | LOG '(' any_expr ')'
- {
- errno = 0;
- $$ = log10($3);
- if (errno == ERANGE) {
- lex_error("log result out of range");
- YYABORT;
- }
- }
- | EXP '(' any_expr ')'
- {
- errno = 0;
- $$ = pow(10.0, $3);
- if (errno == ERANGE) {
- lex_error("exp result out of range");
- YYABORT;
- }
- }
- | SQRT '(' any_expr ')'
- {
- errno = 0;
- $$ = sqrt($3);
- if (errno == EDOM) {
- lex_error("sqrt argument out of domain");
- YYABORT;
- }
- }
- | K_MAX '(' any_expr ',' any_expr ')'
- { $$ = $3 > $5 ? $3 : $5; }
- | K_MIN '(' any_expr ',' any_expr ')'
- { $$ = $3 < $5 ? $3 : $5; }
- | INT '(' any_expr ')'
- { $$ = floor($3); }
- | RAND '(' any_expr ')'
- { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); }
- | RAND '(' ')'
- {
- /* return a random number in the range [0,1) */
- /* portable, but not very random */
- $$ = (rand() & 0x7fff) / double(0x8000);
- }
- | expr '<' expr
- { $$ = ($1 < $3); }
- | expr LESSEQUAL expr
- { $$ = ($1 <= $3); }
- | expr '>' expr
- { $$ = ($1 > $3); }
- | expr GREATEREQUAL expr
- { $$ = ($1 >= $3); }
- | expr EQUALEQUAL expr
- { $$ = ($1 == $3); }
- | expr NOTEQUAL expr
- { $$ = ($1 != $3); }
- | expr ANDAND expr
- { $$ = ($1 != 0.0 && $3 != 0.0); }
- | expr OROR expr
- { $$ = ($1 != 0.0 || $3 != 0.0); }
- | '!' expr
- { $$ = ($2 == 0.0); }
-
- ;
-
-%%
-
-/* bison defines const to be empty unless __STDC__ is defined, which it
-isn't under cfront */
-
-#ifdef const
-#undef const
-#endif
-
-static struct {
- const char *name;
- double val;
- int scaled; // non-zero if val should be multiplied by scale
-} defaults_table[] = {
- { "arcrad", .25, 1 },
- { "arrowht", .1, 1 },
- { "arrowwid", .05, 1 },
- { "circlerad", .25, 1 },
- { "boxht", .5, 1 },
- { "boxwid", .75, 1 },
- { "boxrad", 0.0, 1 },
- { "dashwid", .05, 1 },
- { "ellipseht", .5, 1 },
- { "ellipsewid", .75, 1 },
- { "moveht", .5, 1 },
- { "movewid", .5, 1 },
- { "lineht", .5, 1 },
- { "linewid", .5, 1 },
- { "textht", 0.0, 1 },
- { "textwid", 0.0, 1 },
- { "scale", 1.0, 0 },
- { "linethick", -1.0, 0 }, // in points
- { "fillval", .5, 0 },
- { "arrowhead", 1.0, 0 },
- { "maxpswid", 8.5, 0 },
- { "maxpsht", 11.0, 0 },
-};
-
-place *lookup_label(const char *label)
-{
- saved_state *state = current_saved_state;
- PTABLE(place) *tbl = current_table;
- for (;;) {
- place *pl = tbl->lookup(label);
- if (pl)
- return pl;
- if (!state)
- return 0;
- tbl = state->tbl;
- state = state->prev;
- }
-}
-
-void define_label(const char *label, const place *pl)
-{
- place *p = new place;
- *p = *pl;
- current_table->define(label, p);
-}
-
-int lookup_variable(const char *name, double *val)
-{
- place *pl = lookup_label(name);
- if (pl) {
- *val = pl->x;
- return 1;
- }
- return 0;
-}
-
-void define_variable(const char *name, double val)
-{
- place *p = new place;
- p->obj = 0;
- p->x = val;
- p->y = 0.0;
- current_table->define(name, p);
- if (strcmp(name, "scale") == 0) {
- // When the scale changes, reset all scaled pre-defined variables to
- // their default values.
- for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++)
- if (defaults_table[i].scaled)
- define_variable(defaults_table[i].name, val*defaults_table[i].val);
- }
-}
-
-// called once only (not once per parse)
-
-void parse_init()
-{
- current_direction = RIGHT_DIRECTION;
- current_position.x = 0.0;
- current_position.y = 0.0;
- // This resets everything to its default value.
- reset_all();
-}
-
-void reset(const char *nm)
-{
- for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++)
- if (strcmp(nm, defaults_table[i].name) == 0) {
- double val = defaults_table[i].val;
- if (defaults_table[i].scaled) {
- double scale;
- lookup_variable("scale", &scale);
- val *= scale;
- }
- define_variable(defaults_table[i].name, val);
- return;
- }
- lex_error("`%1' is not a predefined variable", nm);
-}
-
-void reset_all()
-{
- // We only have to explicitly reset the pre-defined variables that
- // aren't scaled because `scale' is not scaled, and changing the
- // value of `scale' will reset all the pre-defined variables that
- // are scaled.
- for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++)
- if (!defaults_table[i].scaled)
- define_variable(defaults_table[i].name, defaults_table[i].val);
-}
-
-// called after each parse
-
-void parse_cleanup()
-{
- while (current_saved_state != 0) {
- delete current_table;
- current_table = current_saved_state->tbl;
- saved_state *tem = current_saved_state;
- current_saved_state = current_saved_state->prev;
- delete tem;
- }
- assert(current_table == &top_table);
- PTABLE_ITERATOR(place) iter(current_table);
- const char *key;
- place *pl;
- while (iter.next(&key, &pl))
- if (pl->obj != 0) {
- position pos = pl->obj->origin();
- pl->obj = 0;
- pl->x = pos.x;
- pl->y = pos.y;
- }
- while (olist.head != 0) {
- object *tem = olist.head;
- olist.head = olist.head->next;
- delete tem;
- }
- olist.tail = 0;
- current_direction = RIGHT_DIRECTION;
- current_position.x = 0.0;
- current_position.y = 0.0;
-}
-
-const char *ordinal_postfix(int n)
-{
- if (n < 10 || n > 20)
- switch (n % 10) {
- case 1:
- return "st";
- case 2:
- return "nd";
- case 3:
- return "rd";
- }
- return "th";
-}
-
-const char *object_type_name(object_type type)
-{
- switch (type) {
- case BOX_OBJECT:
- return "box";
- case CIRCLE_OBJECT:
- return "circle";
- case ELLIPSE_OBJECT:
- return "ellipse";
- case ARC_OBJECT:
- return "arc";
- case SPLINE_OBJECT:
- return "spline";
- case LINE_OBJECT:
- return "line";
- case ARROW_OBJECT:
- return "arrow";
- case MOVE_OBJECT:
- return "move";
- case TEXT_OBJECT:
- return "\"\"";
- case BLOCK_OBJECT:
- return "[]";
- case OTHER_OBJECT:
- case MARK_OBJECT:
- default:
- break;
- }
- return "object";
-}
-
-static char sprintf_buf[1024];
-
-char *format_number(const char *form, double n)
-{
- if (form == 0)
- form = "%g";
- return do_sprintf(form, &n, 1);
-}
-
-char *do_sprintf(const char *form, const double *v, int nv)
-{
- string result;
- int i = 0;
- string one_format;
- while (*form) {
- if (*form == '%') {
- one_format += *form++;
- for (; *form != '\0' && strchr("#-+ 0123456789.", *form) != 0; form++)
- one_format += *form;
- if (*form == '\0' || strchr("eEfgG%", *form) == 0) {
- lex_error("bad sprintf format");
- result += one_format;
- result += form;
- break;
- }
- if (*form == '%') {
- one_format += *form++;
- one_format += '\0';
- snprintf(sprintf_buf, sizeof(sprintf_buf),
- "%s", one_format.contents());
- }
- else {
- if (i >= nv) {
- lex_error("too few arguments to snprintf");
- result += one_format;
- result += form;
- break;
- }
- one_format += *form++;
- one_format += '\0';
- snprintf(sprintf_buf, sizeof(sprintf_buf),
- one_format.contents(), v[i++]);
- }
- one_format.clear();
- result += sprintf_buf;
- }
- else
- result += *form++;
- }
- result += '\0';
- return strsave(result.contents());
-}
diff --git a/gnu/usr.bin/groff/pic/position.h b/gnu/usr.bin/groff/pic/position.h
deleted file mode 100644
index ab7d5469c00..00000000000
--- a/gnu/usr.bin/groff/pic/position.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-struct place;
-struct position {
- double x;
- double y;
- position(double, double );
- position();
- position(const place &);
- position &operator+=(const position &);
- position &operator-=(const position &);
- position &operator*=(double);
- position &operator/=(double);
-};
-
-position operator-(const position &);
-position operator+(const position &, const position &);
-position operator-(const position &, const position &);
-position operator/(const position &, double);
-position operator*(const position &, double);
-// dot product
-double operator*(const position &, const position &);
-int operator==(const position &, const position &);
-int operator!=(const position &, const position &);
-
-double hypot(const position &a);
-
-typedef position distance;
-
diff --git a/gnu/usr.bin/groff/pic/tex.cc b/gnu/usr.bin/groff/pic/tex.cc
deleted file mode 100644
index 53107826092..00000000000
--- a/gnu/usr.bin/groff/pic/tex.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-
-#ifdef TEX_SUPPORT
-
-#include "common.h"
-
-class tex_output : public common_output {
-public:
- tex_output();
- ~tex_output();
- void start_picture(double, const position &ll, const position &ur);
- void finish_picture();
- void text(const position &, text_piece *, int, double);
- void line(const position &, const position *, int n,
- const line_type &);
- void polygon(const position *, int n,
- const line_type &, double);
- void spline(const position &, const position *, int n,
- const line_type &);
- void arc(const position &, const position &, const position &,
- const line_type &);
- void circle(const position &, double rad, const line_type &, double);
- void ellipse(const position &, const distance &, const line_type &, double);
- void command(const char *, const char *, int);
- int supports_filled_polygons();
-private:
- position upper_left;
- double height;
- double width;
- double scale;
- double pen_size;
-
- void point(const position &);
- void dot(const position &, const line_type &);
- void solid_arc(const position &cent, double rad, double start_angle,
- double end_angle, const line_type &lt);
- position transform(const position &);
-protected:
- virtual void set_pen_size(double ps);
-};
-
-// convert inches to milliinches
-
-inline int milliinches(double x)
-{
- return int(x*1000.0 + .5);
-}
-
-inline position tex_output::transform(const position &pos)
-{
- return position((pos.x - upper_left.x)/scale,
- (upper_left.y - pos.y)/scale);
-}
-
-output *make_tex_output()
-{
- return new tex_output;
-}
-
-tex_output::tex_output()
-{
-}
-
-tex_output::~tex_output()
-{
-}
-
-const int DEFAULT_PEN_SIZE = 8;
-
-void tex_output::set_pen_size(double ps)
-{
- if (ps < 0.0)
- ps = -1.0;
- if (ps != pen_size) {
- pen_size = ps;
- printf(" \\special{pn %d}%%\n",
- ps < 0.0 ? DEFAULT_PEN_SIZE : int(ps*(1000.0/72.0) + .5));
- }
-}
-
-void tex_output::start_picture(double sc, const position &ll,
- const position &ur)
-{
- upper_left.x = ll.x;
- upper_left.y = ur.y;
- scale = compute_scale(sc, ll, ur);
- height = (ur.y - ll.y)/scale;
- width = (ur.x - ll.x)/scale;
- /* the point of \vskip 0pt is to ensure that the vtop gets
- a height of 0 rather than the height of the hbox; this
- might be non-zero if text from text attributes lies outside pic's
- idea of the bounding box of the picture. */
- fputs("\\expandafter\\ifx\\csname graph\\endcsname\\relax \\csname newbox\\endcsname\\graph\\fi\n"
- "\\expandafter\\ifx\\csname graphtemp\\endcsname\\relax \\csname newdimen\\endcsname\\graphtemp\\fi\n"
- "\\setbox\\graph=\\vtop{\\vskip 0pt\\hbox{%\n",
- stdout);
- pen_size = -2.0;
-}
-
-void tex_output::finish_picture()
-{
- printf(" \\hbox{\\vrule depth%.3fin width0pt height 0pt}%%\n"
- " \\kern %.3fin\n"
- " }%%\n"
- "}%%\n",
- height, width);
-}
-
-void tex_output::text(const position &center, text_piece *v, int n, double)
-{
- position c = transform(center);
- for (int i = 0; i < n; i++)
- if (v[i].text != 0 && *v[i].text != '\0') {
- int j = 2*i - n + 1;
- if (v[i].adj.v == ABOVE_ADJUST)
- j--;
- else if (v[i].adj.v == BELOW_ADJUST)
- j++;
- if (j == 0) {
- printf(" \\graphtemp=.5ex\\advance\\graphtemp by %.3fin\n", c.y);
- }
- else {
- printf(" \\graphtemp=\\baselineskip"
- "\\multiply\\graphtemp by %d"
- "\\divide\\graphtemp by 2\n"
- " \\advance\\graphtemp by .5ex"
- "\\advance\\graphtemp by %.3fin\n",
- j, c.y);
- }
- printf(" \\rlap{\\kern %.3fin\\lower\\graphtemp", c.x);
- fputs("\\hbox to 0pt{", stdout);
- if (v[i].adj.h != LEFT_ADJUST)
- fputs("\\hss ", stdout);
- fputs(v[i].text, stdout);
- if (v[i].adj.h != RIGHT_ADJUST)
- fputs("\\hss", stdout);
- fputs("}}%\n", stdout);
- }
-}
-
-void tex_output::point(const position &pos)
-{
- position p = transform(pos);
- printf(" \\special{pa %d %d}%%\n", milliinches(p.x), milliinches(p.y));
-}
-
-void tex_output::line(const position &start, const position *v, int n,
- const line_type &lt)
-{
- set_pen_size(lt.thickness);
- point(start);
- for (int i = 0; i < n; i++)
- point(v[i]);
- fputs(" \\special{", stdout);
- switch(lt.type) {
- case line_type::invisible:
- fputs("ip", stdout);
- break;
- case line_type::solid:
- fputs("fp", stdout);
- break;
- case line_type::dotted:
- printf("dt %.3f", lt.dash_width/scale);
- break;
- case line_type::dashed:
- printf("da %.3f", lt.dash_width/scale);
- break;
- }
- fputs("}%\n", stdout);
-}
-
-void tex_output::polygon(const position *v, int n,
- const line_type &lt, double fill)
-{
- if (fill >= 0.0) {
- if (fill > 1.0)
- fill = 1.0;
- printf(" \\special{sh %.3f}%%\n", fill);
- }
- line(v[n-1], v, n, lt);
-}
-
-void tex_output::spline(const position &start, const position *v, int n,
- const line_type &lt)
-{
- if (lt.type == line_type::invisible)
- return;
- set_pen_size(lt.thickness);
- point(start);
- for (int i = 0; i < n; i++)
- point(v[i]);
- fputs(" \\special{sp", stdout);
- switch(lt.type) {
- case line_type::solid:
- break;
- case line_type::dotted:
- printf(" %.3f", -lt.dash_width/scale);
- break;
- case line_type::dashed:
- printf(" %.3f", lt.dash_width/scale);
- break;
- case line_type::invisible:
- assert(0);
- }
- fputs("}%\n", stdout);
-}
-
-void tex_output::solid_arc(const position &cent, double rad,
- double start_angle, double end_angle,
- const line_type &lt)
-{
- set_pen_size(lt.thickness);
- position c = transform(cent);
- printf(" \\special{ar %d %d %d %d %f %f}%%\n",
- milliinches(c.x),
- milliinches(c.y),
- milliinches(rad/scale),
- milliinches(rad/scale),
- -end_angle,
- (-end_angle > -start_angle) ? M_PI * 2 - start_angle : -start_angle);
-}
-
-void tex_output::arc(const position &start, const position &cent,
- const position &end, const line_type &lt)
-{
- switch (lt.type) {
- case line_type::invisible:
- break;
- case line_type::dashed:
- dashed_arc(start, cent, end, lt);
- break;
- case line_type::dotted:
- dotted_arc(start, cent, end, lt);
- break;
- case line_type::solid:
- {
- position c;
- if (!compute_arc_center(start, cent, end, &c)) {
- line(start, &end, 1, lt);
- break;
- }
- solid_arc(c,
- hypot(cent - start),
- atan2(start.y - c.y, start.x - c.x),
- atan2(end.y - c.y, end.x - c.x),
- lt);
- break;
- }
- }
-}
-
-void tex_output::circle(const position &cent, double rad,
- const line_type &lt, double fill)
-{
- if (fill >= 0.0 && lt.type != line_type::solid) {
- if (fill > 1.0)
- fill = 1.0;
- line_type ilt;
- ilt.type = line_type::invisible;
- ellipse(cent, position(rad*2.0, rad*2.0), ilt, fill);
- }
- switch (lt.type) {
- case line_type::dashed:
- dashed_circle(cent, rad, lt);
- break;
- case line_type::invisible:
- break;
- case line_type::solid:
- ellipse(cent, position(rad*2.0,rad*2.0), lt, fill);
- break;
- case line_type::dotted:
- dotted_circle(cent, rad, lt);
- break;
- default:
- assert(0);
- }
-}
-
-void tex_output::ellipse(const position &cent, const distance &dim,
- const line_type &lt, double fill)
-{
- if (lt.type == line_type::invisible) {
- if (fill < 0.0)
- return;
- }
- else
- set_pen_size(lt.thickness);
- if (fill >= 0.0) {
- if (fill > 1.0)
- fill = 1.0;
- printf(" \\special{sh %.3f}%%\n", fill);
- }
- position c = transform(cent);
- printf(" \\special{%s %d %d %d %d 0 6.28319}%%\n",
- (lt.type == line_type::invisible ? "ia" : "ar"),
- milliinches(c.x),
- milliinches(c.y),
- milliinches(dim.x/(2.0*scale)),
- milliinches(dim.y/(2.0*scale)));
-}
-
-void tex_output::command(const char *s, const char *, int)
-{
- fputs(s, stdout);
- putchar('%'); // avoid unwanted spaces
- putchar('\n');
-}
-
-int tex_output::supports_filled_polygons()
-{
- return 1;
-}
-
-void tex_output::dot(const position &pos, const line_type &lt)
-{
- if (zero_length_line_flag) {
- line_type slt = lt;
- slt.type = line_type::solid;
- line(pos, &pos, 1, slt);
- }
- else {
- int dot_rad = int(lt.thickness*(1000.0/(72.0*2)) + .5);
- if (dot_rad == 0)
- dot_rad = 1;
- position p = transform(pos);
- printf(" \\special{sh 1}%%\n"
- " \\special{ia %d %d %d %d 0 6.28319}%%\n",
- milliinches(p.x), milliinches(p.y), dot_rad, dot_rad);
- }
-}
-
-class tpic_output : public tex_output {
-public:
- tpic_output();
- void command(const char *, const char *, int);
-private:
- void set_pen_size(double ps);
- int default_pen_size;
- int prev_default_pen_size;
-};
-
-tpic_output::tpic_output()
-: default_pen_size(DEFAULT_PEN_SIZE), prev_default_pen_size(DEFAULT_PEN_SIZE)
-{
-}
-
-void tpic_output::command(const char *s, const char *filename, int lineno)
-{
- assert(s[0] == '.');
- if (s[1] == 'p' && s[2] == 's' && (s[3] == '\0' || !csalpha(s[3]))) {
- const char *p = s + 3;
- while (csspace(*p))
- p++;
- if (*p == '\0') {
- int temp = default_pen_size;
- default_pen_size = prev_default_pen_size;
- prev_default_pen_size = temp;
- }
- else {
- char *ptr;
- int temp = (int)strtol(p, &ptr, 10);
- if (temp == 0 && ptr == p)
- error_with_file_and_line(filename, lineno,
- "argument to `.ps' not an integer");
- else if (temp < 0)
- error_with_file_and_line(filename, lineno,
- "negative pen size");
- else {
- prev_default_pen_size = default_pen_size;
- default_pen_size = temp;
- }
- }
- }
- else
- printf("\\%s%%\n", s + 1);
-}
-
-void tpic_output::set_pen_size(double ps)
-{
- if (ps < 0.0)
- printf(" \\special{pn %d}%%\n", default_pen_size);
- else
- tex_output::set_pen_size(ps);
-}
-
-output *make_tpic_output()
-{
- return new tpic_output;
-}
-
-#endif
diff --git a/gnu/usr.bin/groff/pic/text.h b/gnu/usr.bin/groff/pic/text.h
deleted file mode 100644
index f9d34875075..00000000000
--- a/gnu/usr.bin/groff/pic/text.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// -*- C++ -*-
-
-enum hadjustment {
- CENTER_ADJUST,
- LEFT_ADJUST,
- RIGHT_ADJUST
- };
-
-enum vadjustment {
- NONE_ADJUST,
- ABOVE_ADJUST,
- BELOW_ADJUST
- };
-
-struct adjustment {
- hadjustment h;
- vadjustment v;
-};
-
-struct text_piece {
- char *text;
- adjustment adj;
- const char *filename;
- int lineno;
-
- text_piece();
- ~text_piece();
-};
diff --git a/gnu/usr.bin/groff/pic/troff.cc b/gnu/usr.bin/groff/pic/troff.cc
deleted file mode 100644
index 71444cdbf7e..00000000000
--- a/gnu/usr.bin/groff/pic/troff.cc
+++ /dev/null
@@ -1,500 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
- Written by James Clark (jjc@jclark.com)
-
-This file is part of groff.
-
-groff is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-groff is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with groff; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "pic.h"
-#include "common.h"
-
-
-const double RELATIVE_THICKNESS = -1.0;
-const double BAD_THICKNESS = -2.0;
-
-class simple_output : public common_output {
- virtual void simple_line(const position &, const position &) = 0;
- virtual void simple_spline(const position &, const position *, int n) = 0;
- virtual void simple_arc(const position &, const position &,
- const position &) = 0;
- virtual void simple_circle(int, const position &, double rad) = 0;
- virtual void simple_ellipse(int, const position &, const distance &) = 0;
- virtual void simple_polygon(int, const position *, int) = 0;
- virtual void line_thickness(double) = 0;
- virtual void set_fill(double) = 0;
- void dot(const position &, const line_type &) = 0;
-public:
- void start_picture(double sc, const position &ll, const position &ur) = 0;
- void finish_picture() = 0;
- void text(const position &, text_piece *, int, double) = 0;
- void line(const position &, const position *, int n,
- const line_type &);
- void polygon(const position *, int n,
- const line_type &, double);
- void spline(const position &, const position *, int n,
- const line_type &);
- void arc(const position &, const position &, const position &,
- const line_type &);
- void circle(const position &, double rad, const line_type &, double);
- void ellipse(const position &, const distance &, const line_type &, double);
- int supports_filled_polygons();
-};
-
-int simple_output::supports_filled_polygons()
-{
- return driver_extension_flag != 0;
-}
-
-void simple_output::arc(const position &start, const position &cent,
- const position &end, const line_type &lt)
-{
- switch (lt.type) {
- case line_type::solid:
- line_thickness(lt.thickness);
- simple_arc(start, cent, end);
- break;
- case line_type::invisible:
- break;
- case line_type::dashed:
- dashed_arc(start, cent, end, lt);
- break;
- case line_type::dotted:
- dotted_arc(start, cent, end, lt);
- break;
- }
-}
-
-void simple_output::line(const position &start, const position *v, int n,
- const line_type &lt)
-{
- position pos = start;
- line_thickness(lt.thickness);
- for (int i = 0; i < n; i++) {
- switch (lt.type) {
- case line_type::solid:
- simple_line(pos, v[i]);
- break;
- case line_type::dotted:
- {
- distance vec(v[i] - pos);
- double dist = hypot(vec);
- int ndots = int(dist/lt.dash_width + .5);
- if (ndots == 0)
- dot(pos, lt);
- else {
- vec /= double(ndots);
- for (int j = 0; j <= ndots; j++)
- dot(pos + vec*j, lt);
- }
- }
- break;
- case line_type::dashed:
- {
- distance vec(v[i] - pos);
- double dist = hypot(vec);
- if (dist <= lt.dash_width*2.0)
- simple_line(pos, v[i]);
- else {
- int ndashes = int((dist - lt.dash_width)/(lt.dash_width*2.0) + .5);
- distance dash_vec = vec*(lt.dash_width/dist);
- double dash_gap = (dist - lt.dash_width)/ndashes;
- distance dash_gap_vec = vec*(dash_gap/dist);
- for (int j = 0; j <= ndashes; j++) {
- position s(pos + dash_gap_vec*j);
- simple_line(s, s + dash_vec);
- }
- }
- }
- break;
- case line_type::invisible:
- break;
- default:
- assert(0);
- }
- pos = v[i];
- }
-}
-
-void simple_output::spline(const position &start, const position *v, int n,
- const line_type &lt)
-{
- line_thickness(lt.thickness);
- simple_spline(start, v, n);
-}
-
-void simple_output::polygon(const position *v, int n,
- const line_type &lt, double fill)
-{
- if (driver_extension_flag) {
- if (fill >= 0.0) {
- set_fill(fill);
- simple_polygon(1, v, n);
- }
- }
- if (lt.type == line_type::solid && driver_extension_flag) {
- line_thickness(lt.thickness);
- simple_polygon(0, v, n);
- }
- else if (lt.type != line_type::invisible) {
- line_thickness(lt.thickness);
- line(v[n - 1], v, n, lt);
- }
-}
-
-void simple_output::circle(const position &cent, double rad,
- const line_type &lt, double fill)
-{
- if (driver_extension_flag && fill >= 0.0) {
- set_fill(fill);
- simple_circle(1, cent, rad);
- }
- line_thickness(lt.thickness);
- switch (lt.type) {
- case line_type::invisible:
- break;
- case line_type::dashed:
- dashed_circle(cent, rad, lt);
- break;
- case line_type::dotted:
- dotted_circle(cent, rad, lt);
- break;
- case line_type::solid:
- simple_circle(0, cent, rad);
- break;
- default:
- assert(0);
- }
-}
-
-void simple_output::ellipse(const position &cent, const distance &dim,
- const line_type &lt, double fill)
-{
- if (driver_extension_flag && fill >= 0.0) {
- set_fill(fill);
- simple_ellipse(1, cent, dim);
- }
- if (lt.type != line_type::invisible)
- line_thickness(lt.thickness);
- switch (lt.type) {
- case line_type::invisible:
- break;
- case line_type::dotted:
- case line_type::dashed:
- case line_type::solid:
- simple_ellipse(0, cent, dim);
- break;
- default:
- assert(0);
- }
-}
-
-#define FILL_MAX 1000
-
-class troff_output : public simple_output {
- const char *last_filename;
- position upper_left;
- double height;
- double scale;
- double last_line_thickness;
- double last_fill;
-public:
- troff_output();
- ~troff_output();
- void start_picture(double, const position &ll, const position &ur);
- void finish_picture();
- void text(const position &, text_piece *, int, double);
- void dot(const position &, const line_type &);
- void command(const char *, const char *, int);
- void set_location(const char *, int);
- void simple_line(const position &, const position &);
- void simple_spline(const position &, const position *, int n);
- void simple_arc(const position &, const position &, const position &);
- void simple_circle(int, const position &, double rad);
- void simple_ellipse(int, const position &, const distance &);
- void simple_polygon(int, const position *, int);
- void line_thickness(double p);
- void set_fill(double);
- position transform(const position &);
-};
-
-output *make_troff_output()
-{
- return new troff_output;
-}
-
-troff_output::troff_output()
-: last_filename(0), last_line_thickness(BAD_THICKNESS), last_fill(-1.0)
-{
-}
-
-troff_output::~troff_output()
-{
-}
-
-inline position troff_output::transform(const position &pos)
-{
- return position((pos.x - upper_left.x)/scale,
- (upper_left.y - pos.y)/scale);
-}
-
-#define FILL_REG "00"
-
-// If this register > 0, then pic will generate \X'ps: ...' commands
-// if the aligned attribute is used.
-#define GROPS_REG "0p"
-
-// If this register is defined, geqn won't produce `\x's.
-#define EQN_NO_EXTRA_SPACE_REG "0x"
-
-void troff_output::start_picture(double sc,
- const position &ll, const position &ur)
-{
- upper_left.x = ll.x;
- upper_left.y = ur.y;
- scale = compute_scale(sc, ll, ur);
- height = (ur.y - ll.y)/scale;
- double width = (ur.x - ll.x)/scale;
- printf(".PS %.3fi %.3fi", height, width);
- if (args)
- printf(" %s\n", args);
- else
- putchar('\n');
- printf(".\\\" %g %g %g %g\n", ll.x, ll.y, ur.x, ur.y);
- printf(".\\\" %.3fi %.3fi %.3fi %.3fi\n", 0.0, height, width, 0.0);
- printf(".nr " FILL_REG " \\n(.u\n.nf\n");
- printf(".nr " EQN_NO_EXTRA_SPACE_REG " 1\n");
- // This guarantees that if the picture is used in a diversion it will
- // have the right width.
- printf("\\h'%.3fi'\n.sp -1\n", width);
-}
-
-void troff_output::finish_picture()
-{
- line_thickness(BAD_THICKNESS);
- last_fill = -1.0; // force it to be reset for each picture
- if (!flyback_flag)
- printf(".sp %.3fi+1\n", height);
- printf(".if \\n(" FILL_REG " .fi\n");
- printf(".br\n");
- printf(".nr " EQN_NO_EXTRA_SPACE_REG " 0\n");
- // this is a little gross
- set_location(current_filename, current_lineno);
- fputs(flyback_flag ? ".PF\n" : ".PE\n", stdout);
-}
-
-void troff_output::command(const char *s,
- const char *filename, int lineno)
-{
- if (filename != 0)
- set_location(filename, lineno);
- fputs(s, stdout);
- putchar('\n');
-}
-
-void troff_output::simple_circle(int filled, const position &cent, double rad)
-{
- position c = transform(cent);
- printf("\\h'%.3fi'"
- "\\v'%.3fi'"
- "\\D'%c%.3fi'"
- "\n.sp -1\n",
- c.x - rad/scale,
- c.y,
- (filled ? 'C' : 'c'),
- rad*2.0/scale);
-}
-
-void troff_output::simple_ellipse(int filled, const position &cent,
- const distance &dim)
-{
- position c = transform(cent);
- printf("\\h'%.3fi'"
- "\\v'%.3fi'"
- "\\D'%c%.3fi %.3fi'"
- "\n.sp -1\n",
- c.x - dim.x/(2.0*scale),
- c.y,
- (filled ? 'E' : 'e'),
- dim.x/scale, dim.y/scale);
-}
-
-void troff_output::simple_arc(const position &start, const distance &cent,
- const distance &end)
-{
- position s = transform(start);
- position c = transform(cent);
- distance cv = c - s;
- distance ev = transform(end) - c;
- printf("\\h'%.3fi'"
- "\\v'%.3fi'"
- "\\D'a%.3fi %.3fi %.3fi %.3fi'"
- "\n.sp -1\n",
- s.x, s.y, cv.x, cv.y, ev.x, ev.y);
-}
-
-void troff_output::simple_line(const position &start, const position &end)
-{
- position s = transform(start);
- distance ev = transform(end) - s;
- printf("\\h'%.3fi'"
- "\\v'%.3fi'"
- "\\D'l%.3fi %.3fi'"
- "\n.sp -1\n",
- s.x, s.y, ev.x, ev.y);
-}
-
-void troff_output::simple_spline(const position &start,
- const position *v, int n)
-{
- position pos = transform(start);
- printf("\\h'%.3fi'"
- "\\v'%.3fi'",
- pos.x, pos.y);
- fputs("\\D'~", stdout);
- for (int i = 0; i < n; i++) {
- position temp = transform(v[i]);
- distance d = temp - pos;
- pos = temp;
- if (i != 0)
- putchar(' ');
- printf("%.3fi %.3fi", d.x, d.y);
- }
- printf("'\n.sp -1\n");
-}
-
-// a solid polygon
-
-void troff_output::simple_polygon(int filled, const position *v, int n)
-{
- position pos = transform(v[0]);
- printf("\\h'%.3fi'"
- "\\v'%.3fi'",
- pos.x, pos.y);
- printf("\\D'%c", (filled ? 'P' : 'p'));
- for (int i = 1; i < n; i++) {
- position temp = transform(v[i]);
- distance d = temp - pos;
- pos = temp;
- if (i != 1)
- putchar(' ');
- printf("%.3fi %.3fi", d.x, d.y);
- }
- printf("'\n.sp -1\n");
-}
-
-const double TEXT_AXIS = 0.22; // in ems
-
-static const char *choose_delimiter(const char *text)
-{
- if (strchr(text, '\'') == 0)
- return "'";
- else
- return "\\(ts";
-}
-
-void troff_output::text(const position &center, text_piece *v, int n,
- double ang)
-{
- line_thickness(BAD_THICKNESS); // the text might use lines (eg in equations)
- int rotate_flag = 0;
- if (driver_extension_flag && ang != 0.0) {
- rotate_flag = 1;
- position c = transform(center);
- printf(".if \\n(" GROPS_REG " \\{\\\n"
- "\\h'%.3fi'"
- "\\v'%.3fi'"
- "\\X'ps: exec gsave currentpoint 2 copy translate %.4f rotate neg exch neg exch translate'"
- "\n.sp -1\n"
- ".\\}\n",
- c.x, c.y, -ang*180.0/M_PI);
- }
- for (int i = 0; i < n; i++)
- if (v[i].text != 0 && *v[i].text != '\0') {
- position c = transform(center);
- if (v[i].filename != 0)
- set_location(v[i].filename, v[i].lineno);
- printf("\\h'%.3fi", c.x);
- const char *delim = choose_delimiter(v[i].text);
- if (v[i].adj.h == RIGHT_ADJUST)
- printf("-\\w%s%s%su", delim, v[i].text, delim);
- else if (v[i].adj.h != LEFT_ADJUST)
- printf("-(\\w%s%s%su/2u)", delim, v[i].text, delim);
- putchar('\'');
- printf("\\v'%.3fi-(%dv/2u)+%dv+%.2fm",
- c.y,
- n - 1,
- i,
- TEXT_AXIS);
- if (v[i].adj.v == ABOVE_ADJUST)
- printf("-.5v");
- else if (v[i].adj.v == BELOW_ADJUST)
- printf("+.5v");
- putchar('\'');
- fputs(v[i].text, stdout);
- fputs("\n.sp -1\n", stdout);
- }
- if (rotate_flag)
- printf(".if '\\*(.T'ps' \\{\\\n"
- "\\X'ps: exec grestore'\n.sp -1\n"
- ".\\}\n");
-}
-
-void troff_output::line_thickness(double p)
-{
- if (p < 0.0)
- p = RELATIVE_THICKNESS;
- if (driver_extension_flag && p != last_line_thickness) {
- printf("\\D't %.3fp'\\h'%.3fp'\n.sp -1\n", p, -p);
- last_line_thickness = p;
- }
-}
-
-void troff_output::set_fill(double f)
-{
- if (driver_extension_flag && f != last_fill) {
- printf("\\D'f %du'\\h'%du'\n.sp -1\n", int(f*FILL_MAX), -int(f*FILL_MAX));
- last_fill = f;
- }
-}
-
-const double DOT_AXIS = .044;
-
-void troff_output::dot(const position &cent, const line_type &lt)
-{
- if (driver_extension_flag) {
- line_thickness(lt.thickness);
- simple_line(cent, cent);
- }
- else {
- position c = transform(cent);
- printf("\\h'%.3fi-(\\w'.'u/2u)'"
- "\\v'%.3fi+%.2fm'"
- ".\n.sp -1\n",
- c.x,
- c.y,
- DOT_AXIS);
- }
-}
-
-void troff_output::set_location(const char *s, int n)
-{
- if (last_filename != 0 && strcmp(s, last_filename) == 0)
- printf(".lf %d\n", n);
- else {
- printf(".lf %d %s\n", n, s);
- last_filename = s;
- }
-}