From 6a4f3d0fd940c1e7052ddf23907f0e297dc42f4b Mon Sep 17 00:00:00 2001 From: etheisen Date: Sat, 14 Sep 1996 19:02:02 +0000 Subject: Third time because import sucks. --- gnu/usr.bin/groff/libgroff/Makefile.dep | 39 ++ gnu/usr.bin/groff/libgroff/Makefile.sub | 15 + gnu/usr.bin/groff/libgroff/assert.cc | 34 ++ gnu/usr.bin/groff/libgroff/change_lf.cc | 37 ++ gnu/usr.bin/groff/libgroff/cmap.cc | 56 ++ gnu/usr.bin/groff/libgroff/cset.cc | 102 ++++ gnu/usr.bin/groff/libgroff/device.cc | 36 ++ gnu/usr.bin/groff/libgroff/errarg.cc | 118 ++++ gnu/usr.bin/groff/libgroff/error.cc | 137 +++++ gnu/usr.bin/groff/libgroff/fatal.cc | 27 + gnu/usr.bin/groff/libgroff/filename.cc | 1 + gnu/usr.bin/groff/libgroff/fmod.c | 28 + gnu/usr.bin/groff/libgroff/font.cc | 911 ++++++++++++++++++++++++++++++ gnu/usr.bin/groff/libgroff/fontfile.cc | 64 +++ gnu/usr.bin/groff/libgroff/getcwd.c | 38 ++ gnu/usr.bin/groff/libgroff/iftoa.c | 65 +++ gnu/usr.bin/groff/libgroff/illegal.cc | 22 + gnu/usr.bin/groff/libgroff/itoa.c | 43 ++ gnu/usr.bin/groff/libgroff/lf.cc | 62 ++ gnu/usr.bin/groff/libgroff/lineno.cc | 1 + gnu/usr.bin/groff/libgroff/macropath.cc | 28 + gnu/usr.bin/groff/libgroff/matherr.c | 45 ++ gnu/usr.bin/groff/libgroff/nametoindex.cc | 118 ++++ gnu/usr.bin/groff/libgroff/new.cc | 67 +++ gnu/usr.bin/groff/libgroff/prime.cc | 26 + gnu/usr.bin/groff/libgroff/progname.cc | 1 + gnu/usr.bin/groff/libgroff/ptable.cc | 52 ++ gnu/usr.bin/groff/libgroff/putenv.c | 96 ++++ gnu/usr.bin/groff/libgroff/searchpath.cc | 117 ++++ gnu/usr.bin/groff/libgroff/strerror.c | 37 ++ gnu/usr.bin/groff/libgroff/string.cc | 311 ++++++++++ gnu/usr.bin/groff/libgroff/strsave.cc | 31 + gnu/usr.bin/groff/libgroff/strtol.c | 131 +++++ gnu/usr.bin/groff/libgroff/tmpfile.cc | 99 ++++ 34 files changed, 2995 insertions(+) create mode 100644 gnu/usr.bin/groff/libgroff/Makefile.dep create mode 100644 gnu/usr.bin/groff/libgroff/Makefile.sub create mode 100644 gnu/usr.bin/groff/libgroff/assert.cc create mode 100644 gnu/usr.bin/groff/libgroff/change_lf.cc create mode 100644 gnu/usr.bin/groff/libgroff/cmap.cc create mode 100644 gnu/usr.bin/groff/libgroff/cset.cc create mode 100644 gnu/usr.bin/groff/libgroff/device.cc create mode 100644 gnu/usr.bin/groff/libgroff/errarg.cc create mode 100644 gnu/usr.bin/groff/libgroff/error.cc create mode 100644 gnu/usr.bin/groff/libgroff/fatal.cc create mode 100644 gnu/usr.bin/groff/libgroff/filename.cc create mode 100644 gnu/usr.bin/groff/libgroff/fmod.c create mode 100644 gnu/usr.bin/groff/libgroff/font.cc create mode 100644 gnu/usr.bin/groff/libgroff/fontfile.cc create mode 100644 gnu/usr.bin/groff/libgroff/getcwd.c create mode 100644 gnu/usr.bin/groff/libgroff/iftoa.c create mode 100644 gnu/usr.bin/groff/libgroff/illegal.cc create mode 100644 gnu/usr.bin/groff/libgroff/itoa.c create mode 100644 gnu/usr.bin/groff/libgroff/lf.cc create mode 100644 gnu/usr.bin/groff/libgroff/lineno.cc create mode 100644 gnu/usr.bin/groff/libgroff/macropath.cc create mode 100644 gnu/usr.bin/groff/libgroff/matherr.c create mode 100644 gnu/usr.bin/groff/libgroff/nametoindex.cc create mode 100644 gnu/usr.bin/groff/libgroff/new.cc create mode 100644 gnu/usr.bin/groff/libgroff/prime.cc create mode 100644 gnu/usr.bin/groff/libgroff/progname.cc create mode 100644 gnu/usr.bin/groff/libgroff/ptable.cc create mode 100644 gnu/usr.bin/groff/libgroff/putenv.c create mode 100644 gnu/usr.bin/groff/libgroff/searchpath.cc create mode 100644 gnu/usr.bin/groff/libgroff/strerror.c create mode 100644 gnu/usr.bin/groff/libgroff/string.cc create mode 100644 gnu/usr.bin/groff/libgroff/strsave.cc create mode 100644 gnu/usr.bin/groff/libgroff/strtol.c create mode 100644 gnu/usr.bin/groff/libgroff/tmpfile.cc (limited to 'gnu/usr.bin/groff/libgroff') diff --git a/gnu/usr.bin/groff/libgroff/Makefile.dep b/gnu/usr.bin/groff/libgroff/Makefile.dep new file mode 100644 index 00000000000..2ddf6405767 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/Makefile.dep @@ -0,0 +1,39 @@ +assert.o: assert.cc ../include/assert.h +change_lf.o: change_lf.cc +cmap.o: cmap.cc ../include/cmap.h +cset.o: cset.cc ../include/cset.h +device.o: device.cc ../include/device.h ../include/defs.h +errarg.o: errarg.cc ../include/assert.h ../include/errarg.h +error.o: error.cc ../include/errarg.h ../include/error.h +fatal.o: fatal.cc +filename.o: filename.cc +font.o: font.cc ../include/errarg.h ../include/error.h \ + ../include/cset.h ../include/font.h ../include/lib.h +fontfile.o: fontfile.cc ../include/font.h ../include/lib.h \ + ../include/searchpath.h ../include/device.h ../include/defs.h +lf.o: lf.cc ../include/cset.h ../include/stringclass.h +lineno.o: lineno.cc +macropath.o: macropath.cc ../include/lib.h ../include/searchpath.h \ + ../include/macropath.h ../include/defs.h +nametoindex.o: nametoindex.cc ../include/lib.h ../include/errarg.h \ + ../include/error.h ../include/font.h ../include/ptable.h +new.o: new.cc ../include/posix.h +prime.o: prime.cc +progname.o: progname.cc +ptable.o: ptable.cc ../include/ptable.h ../include/errarg.h \ + ../include/error.h +searchpath.o: searchpath.cc ../include/lib.h ../include/searchpath.h +string.o: string.cc ../include/stringclass.h ../include/lib.h +strsave.o: strsave.cc +tmpfile.o: tmpfile.cc ../include/posix.h ../include/lib.h \ + ../include/errarg.h ../include/error.h +version.o: version.cc +illegal.o: illegal.cc ../include/lib.h +fmod.o: fmod.c +getcwd.o: getcwd.c +iftoa.o: iftoa.c +itoa.o: itoa.c +matherr.o: matherr.c +strerror.o: strerror.c +strtol.o: strtol.c +putenv.o: putenv.c diff --git a/gnu/usr.bin/groff/libgroff/Makefile.sub b/gnu/usr.bin/groff/libgroff/Makefile.sub new file mode 100644 index 00000000000..a3126bf047d --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/Makefile.sub @@ -0,0 +1,15 @@ +LIB=groff +OBJS=assert.o change_lf.o cmap.o cset.o device.o errarg.o error.o fatal.o \ + filename.o font.o fontfile.o lf.o lineno.o macropath.o nametoindex.o new.o \ + prime.o progname.o ptable.o searchpath.o string.o strsave.o tmpfile.o \ + iftoa.o itoa.o matherr.o version.o illegal.o $(LIBOBJS) +CCSRCS=assert.cc change_lf.cc cmap.cc cset.cc device.cc errarg.cc error.cc \ + fatal.cc filename.cc font.cc fontfile.cc lf.cc lineno.cc macropath.cc \ + nametoindex.cc new.cc prime.cc progname.cc ptable.cc searchpath.cc \ + string.cc strsave.cc tmpfile.cc version.cc illegal.cc +CSRCS=fmod.c getcwd.c iftoa.c itoa.c matherr.c strerror.c strtol.c putenv.c +GENSRCS=version.cc + +version.cc: $(srcdir)/../VERSION + @echo Making version.cc + @echo const char \*version_string = \"`cat $(srcdir)/../VERSION`\"\; >$@ diff --git a/gnu/usr.bin/groff/libgroff/assert.cc b/gnu/usr.bin/groff/libgroff/assert.cc new file mode 100644 index 00000000000..89742e32cbb --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/assert.cc @@ -0,0 +1,34 @@ +/* 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 +#include +#include "assert.h" + +extern const char *program_name; + +void assertion_failed(int lineno, const char *filename) +{ + if (program_name != 0) + fprintf(stderr, "%s: ", program_name); + fprintf(stderr, "Failed assertion at line %d, file `%s'.\n", + lineno, filename); + fflush(stderr); + abort(); +} diff --git a/gnu/usr.bin/groff/libgroff/change_lf.cc b/gnu/usr.bin/groff/libgroff/change_lf.cc new file mode 100644 index 00000000000..2e44af1d574 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/change_lf.cc @@ -0,0 +1,37 @@ +/* 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 + +extern char *strsave(const char *); + +extern const char *current_filename; +extern int current_lineno; + +void change_filename(const char *f) +{ + if (current_filename != 0 && strcmp(current_filename, f) == 0) + return; + current_filename = strsave(f); +} + +void change_lineno(int ln) +{ + current_lineno = ln; +} diff --git a/gnu/usr.bin/groff/libgroff/cmap.cc b/gnu/usr.bin/groff/libgroff/cmap.cc new file mode 100644 index 00000000000..4b75d06f1dc --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/cmap.cc @@ -0,0 +1,56 @@ +// -*- 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 +#include "cmap.h" + +cmap cmlower(CMAP_BUILTIN); +cmap cmupper(CMAP_BUILTIN); + +#ifdef isascii +#define ISASCII(c) isascii(c) +#else +#define ISASCII(c) (1) +#endif + +cmap::cmap() +{ + unsigned char *p = v; + for (int i = 0; i <= UCHAR_MAX; i++) + p[i] = i; +} + +cmap::cmap(cmap_builtin) +{ + // these are initialised by cmap_init::cmap_init() +} + +int cmap_init::initialised = 0; + +cmap_init::cmap_init() +{ + if (initialised) + return; + initialised = 1; + for (int i = 0; i <= UCHAR_MAX; i++) { + cmupper.v[i] = ISASCII(i) && islower(i) ? toupper(i) : i; + cmlower.v[i] = ISASCII(i) && isupper(i) ? tolower(i) : i; + } +} diff --git a/gnu/usr.bin/groff/libgroff/cset.cc b/gnu/usr.bin/groff/libgroff/cset.cc new file mode 100644 index 00000000000..e4845c11012 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/cset.cc @@ -0,0 +1,102 @@ +// -*- 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 +#include "cset.h" + +cset csalpha(CSET_BUILTIN); +cset csupper(CSET_BUILTIN); +cset cslower(CSET_BUILTIN); +cset csdigit(CSET_BUILTIN); +cset csxdigit(CSET_BUILTIN); +cset csspace(CSET_BUILTIN); +cset cspunct(CSET_BUILTIN); +cset csalnum(CSET_BUILTIN); +cset csprint(CSET_BUILTIN); +cset csgraph(CSET_BUILTIN); +cset cscntrl(CSET_BUILTIN); + +#ifdef isascii +#define ISASCII(c) isascii(c) +#else +#define ISASCII(c) (1) +#endif + +void cset::clear() +{ + char *p = v; + for (int i = 0; i <= UCHAR_MAX; i++) + p[i] = 0; +} + +cset::cset() +{ + clear(); +} + +cset::cset(const char *s) +{ + clear(); + while (*s) + v[(unsigned char)*s++] = 1; +} + +cset::cset(const unsigned char *s) +{ + clear(); + while (*s) + v[*s++] = 1; +} + +cset::cset(cset_builtin) +{ + // these are initialised by cset_init::cset_init() +} + +cset &cset::operator|=(const cset &cs) +{ + for (int i = 0; i <= UCHAR_MAX; i++) + if (cs.v[i]) + v[i] = 1; + return *this; +} + + +int cset_init::initialised = 0; + +cset_init::cset_init() +{ + if (initialised) + return; + initialised = 1; + for (int i = 0; i <= UCHAR_MAX; i++) { + csalpha.v[i] = ISASCII(i) && isalpha(i); + csupper.v[i] = ISASCII(i) && isupper(i); + cslower.v[i] = ISASCII(i) && islower(i); + csdigit.v[i] = ISASCII(i) && isdigit(i); + csxdigit.v[i] = ISASCII(i) && isxdigit(i); + csspace.v[i] = ISASCII(i) && isspace(i); + cspunct.v[i] = ISASCII(i) && ispunct(i); + csalnum.v[i] = ISASCII(i) && isalnum(i); + csprint.v[i] = ISASCII(i) && isprint(i); + csgraph.v[i] = ISASCII(i) && isgraph(i); + cscntrl.v[i] = ISASCII(i) && iscntrl(i); + } +} diff --git a/gnu/usr.bin/groff/libgroff/device.cc b/gnu/usr.bin/groff/libgroff/device.cc new file mode 100644 index 00000000000..7efbfef25a2 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/device.cc @@ -0,0 +1,36 @@ +// -*- 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 +#include "device.h" +#include "defs.h" + +const char *device = DEVICE; + +struct device_init { + device_init(); +} _device_init; + +device_init::device_init() +{ + char *tem = getenv("GROFF_TYPESETTER"); + if (tem) + device = tem; +} diff --git a/gnu/usr.bin/groff/libgroff/errarg.cc b/gnu/usr.bin/groff/libgroff/errarg.cc new file mode 100644 index 00000000000..ea30c370b59 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/errarg.cc @@ -0,0 +1,118 @@ +// -*- 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 +#include "assert.h" +#include "errarg.h" + +errarg::errarg(const char *p) : type(STRING) +{ + s = p ? p : "(null)"; +} + +errarg::errarg() : type(EMPTY) +{ +} + +errarg::errarg(unsigned char cc) : type(CHAR) +{ + c = cc; +} + +errarg::errarg(int nn) : type(INTEGER) +{ + n = nn; +} + +errarg::errarg(char cc) : type(CHAR) +{ + c = cc; +} + +errarg::errarg(double dd) : type(DOUBLE) +{ + d = dd; +} + +int errarg::empty() const +{ + return type == EMPTY; +} + +extern "C" { + const char *itoa(int); +} + +void errarg::print() const +{ + switch (type) { + case INTEGER: + fputs(itoa(n), stderr); + break; + case CHAR: + putc(c, stderr); + break; + case STRING: + fputs(s, stderr); + break; + case DOUBLE: + fprintf(stderr, "%g", d); + break; + case EMPTY: + break; + } +} + +errarg empty_errarg; + +void errprint(const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + assert(format != 0); + char c; + while ((c = *format++) != '\0') { + if (c == '%') { + c = *format++; + switch(c) { + case '%': + fputc('%', stderr); + break; + case '1': + assert(!arg1.empty()); + arg1.print(); + break; + case '2': + assert(!arg2.empty()); + arg2.print(); + break; + case '3': + assert(!arg3.empty()); + arg3.print(); + break; + default: + assert(0); + } + } + else + putc(c, stderr); + } +} diff --git a/gnu/usr.bin/groff/libgroff/error.cc b/gnu/usr.bin/groff/libgroff/error.cc new file mode 100644 index 00000000000..53fd629845f --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/error.cc @@ -0,0 +1,137 @@ +// -*- 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 +#include +#include +#include "errarg.h" +#include "error.h" + +extern void fatal_error_exit(); + +enum error_type { WARNING, ERROR, FATAL }; + +static void do_error_with_file_and_line(const char *filename, int lineno, + error_type type, + const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + int need_space = 0; + if (program_name) { + fprintf(stderr, "%s:", program_name); + need_space = 1; + } + if (lineno >= 0 && filename != 0) { + if (strcmp(filename, "-") == 0) + filename = ""; + fprintf(stderr, "%s:%d:", filename, lineno); + need_space = 1; + } + switch (type) { + case FATAL: + fputs("fatal error:", stderr); + need_space = 1; + break; + case ERROR: + break; + case WARNING: + fputs("warning:", stderr); + need_space = 1; + break; + } + if (need_space) + fputc(' ', stderr); + errprint(format, arg1, arg2, arg3); + fputc('\n', stderr); + fflush(stderr); + if (type == FATAL) + fatal_error_exit(); +} + + +static void do_error(error_type type, + const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error_with_file_and_line(current_filename, current_lineno, + type, format, arg1, arg2, arg3); +} + + +void error(const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error(ERROR, format, arg1, arg2, arg3); +} + +void warning(const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error(WARNING, format, arg1, arg2, arg3); +} + +void fatal(const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error(FATAL, format, arg1, arg2, arg3); +} + +void error_with_file_and_line(const char *filename, + int lineno, + const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error_with_file_and_line(filename, lineno, + ERROR, format, arg1, arg2, arg3); +} + +void warning_with_file_and_line(const char *filename, + int lineno, + const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error_with_file_and_line(filename, lineno, + WARNING, format, arg1, arg2, arg3); +} + +void fatal_with_file_and_line(const char *filename, + int lineno, + const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + do_error_with_file_and_line(filename, lineno, + FATAL, format, arg1, arg2, arg3); +} diff --git a/gnu/usr.bin/groff/libgroff/fatal.cc b/gnu/usr.bin/groff/libgroff/fatal.cc new file mode 100644 index 00000000000..42560dcaf5e --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/fatal.cc @@ -0,0 +1,27 @@ +/* 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 + +#define FATAL_ERROR_EXIT_CODE 3 + +void fatal_error_exit() +{ + exit(FATAL_ERROR_EXIT_CODE); +} diff --git a/gnu/usr.bin/groff/libgroff/filename.cc b/gnu/usr.bin/groff/libgroff/filename.cc new file mode 100644 index 00000000000..1cbaa93dddf --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/filename.cc @@ -0,0 +1 @@ +const char *current_filename = 0; diff --git a/gnu/usr.bin/groff/libgroff/fmod.c b/gnu/usr.bin/groff/libgroff/fmod.c new file mode 100644 index 00000000000..818f946edc0 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/fmod.c @@ -0,0 +1,28 @@ +/* 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 + +double fmod(x, y) + double x, y; +{ + double quot = x/y; + return x - (quot < 0.0 ? ceil(quot) : floor(quot)) * y; +} + diff --git a/gnu/usr.bin/groff/libgroff/font.cc b/gnu/usr.bin/groff/libgroff/font.cc new file mode 100644 index 00000000000..95da6b7997c --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/font.cc @@ -0,0 +1,911 @@ +// -*- 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 +#include +#include +#include +#include +#include +#include "errarg.h" +#include "error.h" +#include "cset.h" +#include "font.h" +#include "lib.h" + +const char *const WS = " \t\n\r"; + +struct font_char_metric { + char type; + int code; + int width; + int height; + int depth; + int pre_math_space; + int italic_correction; + int subscript_correction; +}; + +struct font_kern_list { + int i1; + int i2; + int amount; + font_kern_list *next; + + font_kern_list(int, int, int, font_kern_list * = 0); +}; + +struct font_widths_cache { + font_widths_cache *next; + int point_size; + int *width; + + font_widths_cache(int, int, font_widths_cache *); + ~font_widths_cache(); +}; + +/* text_file */ + +struct text_file { + FILE *fp; + char *path; + int lineno; + int size; + int skip_comments; + char *buf; + text_file(FILE *fp, char *p); + ~text_file(); + int next(); + void error(const char *format, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); +}; + +text_file::text_file(FILE *p, char *s) +: lineno(0), buf(0), size(0), skip_comments(1), fp(p), path(s) +{ +} + +text_file::~text_file() +{ + a_delete buf; + a_delete path; + if (fp) + fclose(fp); +} + + +int text_file::next() +{ + if (fp == 0) + return 0; + if (buf == 0) { + buf = new char [128]; + size = 128; + } + for (;;) { + int i = 0; + for (;;) { + int c = getc(fp); + if (c == EOF) + break; + if (illegal_input_char(c)) + error("illegal input character code `%1'", int(c)); + else { + if (i + 1 >= size) { + char *old_buf = buf; + buf = new char[size*2]; + memcpy(buf, old_buf, size); + a_delete old_buf; + size *= 2; + } + buf[i++] = c; + if (c == '\n') + break; + } + } + if (i == 0) + break; + buf[i] = '\0'; + lineno++; + char *ptr = buf; + while (csspace(*ptr)) + ptr++; + if (*ptr != 0 && (!skip_comments || *ptr != '#')) + return 1; + } + return 0; +} + +void text_file::error(const char *format, + const errarg &arg1, + const errarg &arg2, + const errarg &arg3) +{ + error_with_file_and_line(path, lineno, format, arg1, arg2, arg3); +} + + +/* font functions */ + +font::font(const char *s) +: special(0), ligatures(0), kern_hash_table(0), space_width(0), + ch(0), ch_used(0), ch_size(0), ch_index(0), nindices(0), widths_cache(0) +{ + name = new char[strlen(s) + 1]; + strcpy(name, s); + internalname = 0; + slant = 0.0; + // load(); // for testing +} + +font::~font() +{ + a_delete ch; + a_delete ch_index; + if (kern_hash_table) { + for (int i = 0; i < KERN_HASH_TABLE_SIZE; i++) { + font_kern_list *kerns = kern_hash_table[i]; + while (kerns) { + font_kern_list *tem = kerns; + kerns = kerns->next; + delete tem; + } + } + a_delete kern_hash_table; + } + a_delete name; + a_delete internalname; + while (widths_cache) { + font_widths_cache *tem = widths_cache; + widths_cache = widths_cache->next; + delete tem; + } +} + +static int scale_round(int n, int x, int y) +{ + assert(x >= 0 && y > 0); + int y2 = y/2; + if (x == 0) + return 0; + if (n >= 0) { + if (n <= (INT_MAX - y2)/x) + return (n*x + y2)/y; + return int(n*double(x)/double(y) + .5); + } + else { + if (-(unsigned)n <= (-(unsigned)INT_MIN - y2)/x) + return (n*x - y2)/y; + return int(n*double(x)/double(y) - .5); + } +} + +inline int font::scale(int w, int sz) +{ + return sz == unitwidth ? w : scale_round(w, sz, unitwidth); +} + +int font::get_skew(int c, int point_size, int sl) +{ + int h = get_height(c, point_size); + return int(h*tan((slant+sl)*PI/180.0) + .5); +} + +int font::contains(int c) +{ + return c >= 0 && c < nindices && ch_index[c] >= 0; +} + +int font::is_special() +{ + return special; +} + +font_widths_cache::font_widths_cache(int ps, int ch_size, + font_widths_cache *p = 0) +: next(p), point_size(ps) +{ + width = new int[ch_size]; + for (int i = 0; i < ch_size; i++) + width[i] = -1; +} + +font_widths_cache::~font_widths_cache() +{ + a_delete width; +} + +int font::get_width(int c, int point_size) +{ + assert(c >= 0 && c < nindices); + int i = ch_index[c]; + assert(i >= 0); + + if (point_size == unitwidth) + return ch[i].width; + + if (!widths_cache) + widths_cache = new font_widths_cache(point_size, ch_size); + else if (widths_cache->point_size != point_size) { + font_widths_cache **p; + for (p = &widths_cache; *p; p = &(*p)->next) + if ((*p)->point_size == point_size) + break; + if (*p) { + font_widths_cache *tem = *p; + *p = (*p)->next; + tem->next = widths_cache; + widths_cache = tem; + } + else + widths_cache = new font_widths_cache(point_size, ch_size, widths_cache); + } + int &w = widths_cache->width[i]; + if (w < 0) + w = scale(ch[i].width, point_size); + return w; +} + +int font::get_height(int c, int point_size) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].height, point_size); +} + +int font::get_depth(int c, int point_size) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].depth, point_size); +} + +int font::get_italic_correction(int c, int point_size) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].italic_correction, point_size); +} + +int font::get_left_italic_correction(int c, int point_size) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].pre_math_space, point_size); +} + +int font::get_subscript_correction(int c, int point_size) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].subscript_correction, point_size); +} + +int font::get_space_width(int point_size) +{ + return scale(space_width, point_size); +} + +font_kern_list::font_kern_list(int c1, int c2, int n, font_kern_list *p) + : i1(c1), i2(c2), amount(n), next(p) +{ +} + +inline int font::hash_kern(int i1, int i2) +{ + int n = ((i1 << 10) + i2) % KERN_HASH_TABLE_SIZE; + return n < 0 ? -n : n; +} + +void font::add_kern(int i1, int i2, int amount) +{ + if (!kern_hash_table) { + kern_hash_table = new font_kern_list *[KERN_HASH_TABLE_SIZE]; + for (int i = 0; i < KERN_HASH_TABLE_SIZE; i++) + kern_hash_table[i] = 0; + } + font_kern_list **p = kern_hash_table + hash_kern(i1, i2); + *p = new font_kern_list(i1, i2, amount, *p); +} + +int font::get_kern(int i1, int i2, int point_size) +{ + if (kern_hash_table) { + for (font_kern_list *p = kern_hash_table[hash_kern(i1, i2)]; p; p = p->next) + if (i1 == p->i1 && i2 == p->i2) + return scale(p->amount, point_size); + } + return 0; +} + +int font::has_ligature(int mask) +{ + return mask & ligatures; +} + +int font::get_character_type(int c) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return ch[ch_index[c]].type; +} + +int font::get_code(int c) +{ + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return ch[ch_index[c]].code; +} + +const char *font::get_name() +{ + return name; +} + +const char *font::get_internal_name() +{ + return internalname; +} + +void font::alloc_ch_index(int index) +{ + if (nindices == 0) { + nindices = 128; + if (index >= nindices) + nindices = index + 10; + ch_index = new short[nindices]; + for (int i = 0; i < nindices; i++) + ch_index[i] = -1; + } + else { + int old_nindices = nindices; + nindices *= 2; + if (index >= nindices) + nindices = index + 10; + short *old_ch_index = ch_index; + ch_index = new short[nindices]; + memcpy(ch_index, old_ch_index, sizeof(short)*old_nindices); + for (int i = old_nindices; i < nindices; i++) + ch_index[i] = -1; + a_delete old_ch_index; + } +} + +void font::extend_ch() +{ + if (ch == 0) + ch = new font_char_metric[ch_size = 16]; + else { + int old_ch_size = ch_size; + ch_size *= 2; + font_char_metric *old_ch = ch; + ch = new font_char_metric[ch_size]; + memcpy(ch, old_ch, old_ch_size*sizeof(font_char_metric)); + a_delete old_ch; + } +} + +void font::compact() +{ + int i; + for (i = nindices - 1; i >= 0; i--) + if (ch_index[i] >= 0) + break; + i++; + if (i < nindices) { + short *old_ch_index = ch_index; + ch_index = new short[i]; + memcpy(ch_index, old_ch_index, i*sizeof(short)); + a_delete old_ch_index; + nindices = i; + } + if (ch_used < ch_size) { + font_char_metric *old_ch = ch; + ch = new font_char_metric[ch_used]; + memcpy(ch, old_ch, ch_used*sizeof(font_char_metric)); + a_delete old_ch; + ch_size = ch_used; + } +} + +void font::add_entry(int index, const font_char_metric &metric) +{ + assert(index >= 0); + if (index >= nindices) + alloc_ch_index(index); + assert(index < nindices); + if (ch_used + 1 >= ch_size) + extend_ch(); + assert(ch_used + 1 < ch_size); + ch_index[index] = ch_used; + ch[ch_used++] = metric; +} + +void font::copy_entry(int new_index, int old_index) +{ + assert(new_index >= 0 && old_index >= 0 && old_index < nindices); + if (new_index >= nindices) + alloc_ch_index(new_index); + ch_index[new_index] = ch_index[old_index]; +} + +font *font::load_font(const char *s, int *not_found) +{ + font *f = new font(s); + if (!f->load(not_found)) { + delete f; + return 0; + } + return f; +} + +static char *trim_arg(char *p) +{ + if (!p) + return 0; + while (csspace(*p)) + p++; + char *q = strchr(p, '\0'); + while (q > p && csspace(q[-1])) + q--; + *q = '\0'; + return p; +} + +// If the font can't be found, then if not_found is NULL it will be set +// to 1 otherwise a message will be printed. + +int font::load(int *not_found) +{ + char *path; + FILE *fp; + if ((fp = open_file(name, &path)) == NULL) { + if (not_found) + *not_found = 1; + else + error("can't find font file `%1'", name); + return 0; + } + text_file t(fp, path); + t.skip_comments = 1; + char *p; + for (;;) { + if (!t.next()) { + t.error("missing charset command"); + return 0; + } + p = strtok(t.buf, WS); + if (strcmp(p, "name") == 0) { + } + else if (strcmp(p, "spacewidth") == 0) { + p = strtok(0, WS); + int n; + if (p == 0 || sscanf(p, "%d", &n) != 1 || n <= 0) { + t.error("bad argument for spacewidth command"); + return 0; + } + space_width = n; + } + else if (strcmp(p, "slant") == 0) { + p = strtok(0, WS); + double n; + if (p == 0 || sscanf(p, "%lf", &n) != 1 || n >= 90.0 || n <= -90.0) { + t.error("bad argument for slant command", p); + return 0; + } + slant = n; + } + else if (strcmp(p, "ligatures") == 0) { + for (;;) { + p = strtok(0, WS); + if (p == 0 || strcmp(p, "0") == 0) + break; + if (strcmp(p, "ff") == 0) + ligatures |= LIG_ff; + else if (strcmp(p, "fi") == 0) + ligatures |= LIG_fi; + else if (strcmp(p, "fl") == 0) + ligatures |= LIG_fl; + else if (strcmp(p, "ffi") == 0) + ligatures |= LIG_ffi; + else if (strcmp(p, "ffl") == 0) + ligatures |= LIG_ffl; + else { + t.error("unrecognised ligature `%1'", p); + return 0; + } + } + } + else if (strcmp(p, "internalname") == 0) { + p = strtok(0, WS); + if (!p) { + t.error("`internalname command requires argument"); + return 0; + } + internalname = new char[strlen(p) + 1]; + strcpy(internalname, p); + } + else if (strcmp(p, "special") == 0) { + special = 1; + } + else if (strcmp(p, "kernpairs") != 0 && strcmp(p, "charset") != 0) { + char *command = p; + p = strtok(0, "\n"); + handle_unknown_font_command(command, trim_arg(p), t.path, t.lineno); + } + else + break; + } + char *command = p; + int had_charset = 0; + t.skip_comments = 0; + while (command) { + if (strcmp(command, "kernpairs") == 0) { + for (;;) { + if (!t.next()) { + command = 0; + break; + } + char *c1 = strtok(t.buf, WS); + if (c1 == 0) + continue; + char *c2 = strtok(0, WS); + if (c2 == 0) { + command = c1; + break; + } + p = strtok(0, WS); + if (p == 0) { + t.error("missing kern amount"); + return 0; + } + int n; + if (sscanf(p, "%d", &n) != 1) { + t.error("bad kern amount `%1'", p); + return 0; + } + int i1 = name_to_index(c1); + if (i1 < 0) { + t.error("illegal character `%1'", c1); + return 0; + } + int i2 = name_to_index(c2); + if (i2 < 0) { + t.error("illegal character `%1'", c2); + return 0; + } + add_kern(i1, i2, n); + } + } + else if (strcmp(command, "charset") == 0) { + had_charset = 1; + int last_index = -1; + for (;;) { + if (!t.next()) { + command = 0; + break; + } + char *nm = strtok(t.buf, WS); + if (nm == 0) + continue; // I dont think this should happen + p = strtok(0, WS); + if (p == 0) { + command = nm; + break; + } + if (p[0] == '"') { + if (last_index == -1) { + t.error("first charset entry is duplicate"); + return 0; + } + if (strcmp(nm, "---") == 0) { + t.error("unnamed character cannot be duplicate"); + return 0; + } + int index = name_to_index(nm); + if (index < 0) { + t.error("illegal character `%1'", nm); + return 0; + } + copy_entry(index, last_index); + } + else { + font_char_metric metric; + metric.height = 0; + metric.depth = 0; + metric.pre_math_space = 0; + metric.italic_correction = 0; + metric.subscript_correction = 0; + int nparms = sscanf(p, "%d,%d,%d,%d,%d,%d", + &metric.width, &metric.height, &metric.depth, + &metric.italic_correction, + &metric.pre_math_space, + &metric.subscript_correction); + if (nparms < 1) { + t.error("bad width for `%1'", nm); + return 0; + } + p = strtok(0, WS); + if (p == 0) { + t.error("missing character type for `%1'", nm); + return 0; + } + int type; + if (sscanf(p, "%d", &type) != 1) { + t.error("bad character type for `%1'", nm); + return 0; + } + if (type < 0 || type > 255) { + t.error("character code `%1' out of range", type); + return 0; + } + metric.type = type; + p = strtok(0, WS); + if (p == 0) { + t.error("missing code for `%1'", nm); + return 0; + } + char *ptr; + metric.code = (int)strtol(p, &ptr, 0); + if (metric.code == 0 && ptr == p) { + t.error("bad code `%1' for character `%2'", p, nm); + return 0; + } + if (strcmp(nm, "---") == 0) { + last_index = number_to_index(metric.code); + add_entry(last_index, metric); + } + else { + last_index = name_to_index(nm); + if (last_index < 0) { + t.error("illegal character `%1'", nm); + return 0; + } + add_entry(last_index, metric); + copy_entry(number_to_index(metric.code), last_index); + } + } + } + if (last_index == -1) { + t.error("I didn't seem to find any characters"); + return 0; + } + } + else { + t.error("unrecognised command `%1' after `kernpairs' or `charset' command", command); + return 0; + } + } + if (!had_charset) { + t.error("missing charset command"); + return 0; + } + if (space_width == 0) + space_width = scale_round(unitwidth, res, 72*3*sizescale); + compact(); + return 1; +} + +static struct { + const char *command; + int *ptr; +} table[] = { + { "res", &font::res }, + { "hor", &font::hor }, + { "vert", &font::vert }, + { "unitwidth", &font::unitwidth }, + { "paperwidth", &font::paperwidth }, + { "paperlength", &font::paperlength }, + { "spare1", &font::biggestfont }, + { "biggestfont", &font::biggestfont }, + { "spare2", &font::spare2 }, + { "sizescale", &font::sizescale } + }; + + +int font::load_desc() +{ + int nfonts = 0; + FILE *fp; + char *path; + if ((fp = open_file("DESC", &path)) == 0) { + error("can't find `DESC' file"); + return 0; + } + text_file t(fp, path); + t.skip_comments = 1; + res = 0; + while (t.next()) { + char *p = strtok(t.buf, WS); + int found = 0; + int i; + for (i = 0; !found && i < sizeof(table)/sizeof(table[0]); i++) + if (strcmp(table[i].command, p) == 0) + found = 1; + if (found) { + char *q = strtok(0, WS); + if (!q) { + t.error("missing value for command `%1'", p); + return 0; + } + //int *ptr = &(this->*(table[i-1].ptr)); + int *ptr = table[i-1].ptr; + if (sscanf(q, "%d", ptr) != 1) { + t.error("bad number `%1'", q); + return 0; + } + } + else if (strcmp("tcommand", p) == 0) { + tcommand = 1; + } + else if (strcmp("family", p) == 0) { + p = strtok(0, WS); + if (!p) { + t.error("family command requires an argument"); + return 0; + } + char *tem = new char[strlen(p)+1]; + strcpy(tem, p); + family = tem; + } + else if (strcmp("fonts", p) == 0) { + p = strtok(0, WS); + if (!p || sscanf(p, "%d", &nfonts) != 1 || nfonts <= 0) { + t.error("bad number of fonts `%1'", p); + return 0; + } + font_name_table = (const char **)new char *[nfonts+1]; + for (int i = 0; i < nfonts; i++) { + p = strtok(0, WS); + while (p == 0) { + if (!t.next()) { + t.error("end of file while reading list of fonts"); + return 0; + } + p = strtok(t.buf, WS); + } + char *temp = new char[strlen(p)+1]; + strcpy(temp, p); + font_name_table[i] = temp; + } + p = strtok(0, WS); + if (p != 0) { + t.error("font count does not match number of fonts"); + return 0; + } + font_name_table[nfonts] = 0; + } + else if (strcmp("sizes", p) == 0) { + int n = 16; + sizes = new int[n]; + int i = 0; + for (;;) { + p = strtok(0, WS); + while (p == 0) { + if (!t.next()) { + t.error("list of sizes must be terminated by `0'"); + return 0; + } + p = strtok(t.buf, WS); + } + int lower, upper; + switch (sscanf(p, "%d-%d", &lower, &upper)) { + case 1: + upper = lower; + // fall through + case 2: + if (lower <= upper && lower >= 0) + break; + // fall through + default: + t.error("bad size range `%1'", p); + return 0; + } + if (i + 2 > n) { + int *old_sizes = sizes; + sizes = new int[n*2]; + memcpy(sizes, old_sizes, n*sizeof(int)); + n *= 2; + a_delete old_sizes; + } + sizes[i++] = lower; + if (lower == 0) + break; + sizes[i++] = upper; + } + if (i == 1) { + t.error("must have some sizes"); + return 0; + } + } + else if (strcmp("styles", p) == 0) { + int style_table_size = 5; + style_table = (const char **)new char *[style_table_size]; + int j; + for (j = 0; j < style_table_size; j++) + style_table[j] = 0; + int i = 0; + for (;;) { + p = strtok(0, WS); + if (p == 0) + break; + // leave room for terminating 0 + if (i + 1 >= style_table_size) { + const char **old_style_table = style_table; + style_table_size *= 2; + style_table = (const char **)new char*[style_table_size]; + for (j = 0; j < i; j++) + style_table[j] = old_style_table[j]; + for (; j < style_table_size; j++) + style_table[j] = 0; + a_delete old_style_table; + } + char *tem = new char[strlen(p) + 1]; + strcpy(tem, p); + style_table[i++] = tem; + } + } + else if (strcmp("charset", p) == 0) + break; + else if (unknown_desc_command_handler) { + char *command = p; + p = strtok(0, "\n"); + (*unknown_desc_command_handler)(command, trim_arg(p), t.path, t.lineno); + } + } + if (res == 0) { + t.error("missing `res' command"); + return 0; + } + if (unitwidth == 0) { + t.error("missing `unitwidth' command"); + return 0; + } + if (font_name_table == 0) { + t.error("missing `fonts' command"); + return 0; + } + if (sizes == 0) { + t.error("missing `sizes' command"); + return 0; + } + if (sizescale < 1) { + t.error("bad `sizescale' value"); + return 0; + } + if (hor < 1) { + t.error("bad `hor' value"); + return 0; + } + if (vert < 1) { + t.error("bad `vert' value"); + return 0; + } + return 1; +} + +void font::handle_unknown_font_command(const char *, const char *, + const char *, int) +{ +} + +FONT_COMMAND_HANDLER +font::set_unknown_desc_command_handler(FONT_COMMAND_HANDLER func) +{ + FONT_COMMAND_HANDLER prev = unknown_desc_command_handler; + unknown_desc_command_handler = func; + return prev; +} + diff --git a/gnu/usr.bin/groff/libgroff/fontfile.cc b/gnu/usr.bin/groff/libgroff/fontfile.cc new file mode 100644 index 00000000000..e86579aee2a --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/fontfile.cc @@ -0,0 +1,64 @@ +// -*- 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 +#include +#include +#include +#include +#include "font.h" +#include "lib.h" +#include "searchpath.h" +#include "device.h" +#include "defs.h" + +const char *const FONT_ENV_VAR = "GROFF_FONT_PATH"; + +static search_path font_path(FONT_ENV_VAR, FONTPATH); + +int font::res = 0; +int font::hor = 1; +int font::vert = 1; +int font::unitwidth = 0; +int font::paperwidth = 0; +int font::paperlength = 0; +int font::biggestfont = 0; +int font::spare2 = 0; +int font::sizescale = 1; +int font::tcommand = 0; +const char **font::font_name_table = 0; +int *font::sizes = 0; +const char *font::family = 0; +const char **font::style_table = 0; +FONT_COMMAND_HANDLER font::unknown_desc_command_handler = 0; + +void font::command_line_font_dir(const char *dir) +{ + font_path.command_line_dir(dir); +} + +FILE *font::open_file(const char *name, char **pathp) +{ + char *filename = new char[strlen(name) + strlen(device) + 5]; + sprintf(filename, "dev%s/%s", device, name); + FILE *fp = font_path.open_file(filename, pathp); + a_delete filename; + return fp; +} diff --git a/gnu/usr.bin/groff/libgroff/getcwd.c b/gnu/usr.bin/groff/libgroff/getcwd.c new file mode 100644 index 00000000000..208e8111853 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/getcwd.c @@ -0,0 +1,38 @@ +/* Partial emulation of getcwd in terms of getwd. */ + +#include +#include +#include +#ifndef errno +extern int errno; +#endif + +char *getwd(); + +char *getcwd(buf, size) + char *buf; + int size; /* POSIX says this should be size_t */ +{ + if (size <= 0) { + errno = EINVAL; + return 0; + } + else { + char mybuf[MAXPATHLEN]; + int saved_errno = errno; + + errno = 0; + if (!getwd(mybuf)) { + if (errno == 0) + ; /* what to do? */ + return 0; + } + errno = saved_errno; + if (strlen(mybuf) + 1 > size) { + errno = ERANGE; + return 0; + } + strcpy(buf, mybuf); + return buf; + } +} diff --git a/gnu/usr.bin/groff/libgroff/iftoa.c b/gnu/usr.bin/groff/libgroff/iftoa.c new file mode 100644 index 00000000000..75cd5e44dbd --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/iftoa.c @@ -0,0 +1,65 @@ +/* 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. */ + +#define INT_DIGITS 19 /* enough for 64-bit integer */ + +char *iftoa(i, decimal_point) + int i, decimal_point; +{ + /* room for a -, INT_DIGITS digits, a decimal point, and a terminating '\0' */ + static char buf[INT_DIGITS + 3]; + char *p = buf + INT_DIGITS + 2; + int point = 0; + buf[INT_DIGITS + 2] = '\0'; + /* assert(decimal_point <= INT_DIGITS); */ + if (i >= 0) { + do { + *--p = '0' + (i % 10); + i /= 10; + if (++point == decimal_point) + *--p = '.'; + } while (i != 0 || point < decimal_point); + } + else { /* i < 0 */ + do { + *--p = '0' - (i % 10); + i /= 10; + if (++point == decimal_point) + *--p = '.'; + } while (i != 0 || point < decimal_point); + *--p = '-'; + } + if (decimal_point > 0) { + char *q; + /* there must be a dot, so this will terminate */ + for (q = buf + INT_DIGITS + 2; q[-1] == '0'; --q) + ; + if (q[-1] == '.') { + if (q - 1 == p) { + q[-1] = '0'; + q[0] = '\0'; + } + else + q[-1] = '\0'; + } + else + *q = '\0'; + } + return p; +} diff --git a/gnu/usr.bin/groff/libgroff/illegal.cc b/gnu/usr.bin/groff/libgroff/illegal.cc new file mode 100644 index 00000000000..10f4d5bd7d5 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/illegal.cc @@ -0,0 +1,22 @@ +#include "lib.h" + +// Table of illegal input characters. + +char illegal_char_table[256]= { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/gnu/usr.bin/groff/libgroff/itoa.c b/gnu/usr.bin/groff/libgroff/itoa.c new file mode 100644 index 00000000000..69f21cc8893 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/itoa.c @@ -0,0 +1,43 @@ +/* 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. */ + +#define INT_DIGITS 19 /* enough for 64 bit integer */ + +char *itoa(i) + int i; +{ + /* Room for INT_DIGITS digits, - and '\0' */ + static char buf[INT_DIGITS + 2]; + char *p = buf + INT_DIGITS + 1; /* points to terminating '\0' */ + if (i >= 0) { + do { + *--p = '0' + (i % 10); + i /= 10; + } while (i != 0); + return p; + } + else { /* i < 0 */ + do { + *--p = '0' - (i % 10); + i /= 10; + } while (i != 0); + *--p = '-'; + } + return p; +} diff --git a/gnu/usr.bin/groff/libgroff/lf.cc b/gnu/usr.bin/groff/libgroff/lf.cc new file mode 100644 index 00000000000..34272c7d03d --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/lf.cc @@ -0,0 +1,62 @@ +// -*- 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 +#include +#include "cset.h" +#include "stringclass.h" + +extern void change_filename(const char *); +extern void change_lineno(int); + +int interpret_lf_args(const char *p) +{ + while (*p == ' ') + p++; + if (!csdigit(*p)) + return 0; + int ln = 0; + do { + ln *= 10; + ln += *p++ - '0'; + } while (csdigit(*p)); + if (*p != ' ' && *p != '\n' && *p != '\0') + return 0; + while (*p == ' ') + p++; + if (*p == '\0' || *p == '\n') { + change_lineno(ln); + return 1; + } + const char *q; + for (q = p; + *q != '\0' && *q != ' ' && *q != '\n' && *q != '\\'; + q++) + ; + string tem(p, q - p); + while (*q == ' ') + q++; + if (*q != '\n' && *q != '\0') + return 0; + tem += '\0'; + change_filename(tem.contents()); + change_lineno(ln); + return 1; +} diff --git a/gnu/usr.bin/groff/libgroff/lineno.cc b/gnu/usr.bin/groff/libgroff/lineno.cc new file mode 100644 index 00000000000..f7138dba021 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/lineno.cc @@ -0,0 +1 @@ +int current_lineno = 0; diff --git a/gnu/usr.bin/groff/libgroff/macropath.cc b/gnu/usr.bin/groff/libgroff/macropath.cc new file mode 100644 index 00000000000..4fd22a30a5b --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/macropath.cc @@ -0,0 +1,28 @@ +// -*- 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 "lib.h" +#include "searchpath.h" +#include "macropath.h" +#include "defs.h" + +#define MACROPATH_ENVVAR "GROFF_TMAC_PATH" + +search_path macro_path(MACROPATH_ENVVAR, MACROPATH); diff --git a/gnu/usr.bin/groff/libgroff/matherr.c b/gnu/usr.bin/groff/libgroff/matherr.c new file mode 100644 index 00000000000..b0097b8b555 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/matherr.c @@ -0,0 +1,45 @@ +/* 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 +#include + +#ifdef HAVE_STRUCT_EXCEPTION +#ifdef TLOSS + +int matherr(exc) +struct exception *exc; +{ + switch (exc->type) { + case SING: + case DOMAIN: + errno = EDOM; + break; + case OVERFLOW: + case UNDERFLOW: + case TLOSS: + case PLOSS: + errno = ERANGE; + break; + } + return 1; +} + +#endif /* TLOSS */ +#endif /* HAVE_STRUCT_EXCEPTION */ diff --git a/gnu/usr.bin/groff/libgroff/nametoindex.cc b/gnu/usr.bin/groff/libgroff/nametoindex.cc new file mode 100644 index 00000000000..694cab94b83 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/nametoindex.cc @@ -0,0 +1,118 @@ +// -*- 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 +#include +#include +#include +#include +#include "lib.h" +#include "errarg.h" +#include "error.h" +#include "font.h" +#include "ptable.h" + +declare_ptable(int) +implement_ptable(int) + +class character_indexer { +public: + character_indexer(); + ~character_indexer(); + int ascii_char_index(unsigned char); + int named_char_index(const char *); + int numbered_char_index(int); +private: + enum { NSMALL = 256 }; + int next_index; + int ascii_index[256]; + int small_number_index[NSMALL]; + PTABLE(int) table; + int lookup_char(const char *, int); +}; + +character_indexer::character_indexer() +: next_index(0) +{ + int i; + for (i = 0; i < 256; i++) + ascii_index[i] = -1; + for (i = 0; i < NSMALL; i++) + small_number_index[i] = -1; +} + +character_indexer::~character_indexer() +{ +} + +int character_indexer::ascii_char_index(unsigned char c) +{ + if (ascii_index[c] < 0) + ascii_index[c] = next_index++; + return ascii_index[c]; +} + +int character_indexer::numbered_char_index(int n) +{ + if (n >= 0 && n < NSMALL) { + if (small_number_index[n] < 0) + small_number_index[n] = next_index++; + return small_number_index[n]; + } + // Not the most efficient possible implementation. + char buf[INT_DIGITS + 3]; + buf[0] = ' '; + strcpy(buf + 1, itoa(n)); + return named_char_index(buf); +} + +int character_indexer::named_char_index(const char *s) +{ + int *np = table.lookup(s); + if (!np) { + np = new int; + *np = next_index++; + table.define(s, np); + } + return *np; +} + +static character_indexer indexer; + +int font::number_to_index(int n) +{ + return indexer.numbered_char_index(n); +} + +int font::name_to_index(const char *s) +{ + assert(s != 0 && s[0] != '\0' && s[0] != ' '); + if (s[1] == '\0') + return indexer.ascii_char_index(s[0]); + /* char128 and \200 are synonyms */ + if (s[0] == 'c' && s[1] == 'h' && s[2] == 'a' && s[3] == 'r') { + char *res; + long n = strtol(s + 4, &res, 10); + if (res != s + 4 && *res == '\0' && n >= 0 && n < 256) + return indexer.ascii_char_index((unsigned char)n); + } + return indexer.named_char_index(s); +} + diff --git a/gnu/usr.bin/groff/libgroff/new.cc b/gnu/usr.bin/groff/libgroff/new.cc new file mode 100644 index 00000000000..d26db2f5a38 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/new.cc @@ -0,0 +1,67 @@ +/* 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 +#include +#include + +#include "posix.h" + +extern const char *program_name; + +static void ewrite(const char *s) +{ + write(2, s, strlen(s)); +} + +void *operator new(size_t size) +{ + // Avoid relying on the behaviour of malloc(0). + if (size == 0) + size++; +#ifdef COOKIE_BUG + char *p = (char *)malloc(unsigned(size + 8)); +#else /* not COOKIE_BUG */ + char *p = (char *)malloc(unsigned(size)); +#endif /* not COOKIE_BUG */ + if (p == 0) { + if (program_name) { + ewrite(program_name); + ewrite(": "); + } + ewrite("out of memory\n"); + _exit(-1); + } +#ifdef COOKIE_BUG + ((unsigned *)p)[1] = 0; + return p + 8; +#else /* not COOKIE_BUG */ + return p; +#endif /* not COOKIE_BUG */ +} + +#ifdef COOKIE_BUG + +void operator delete(void *p) +{ + if (p) + free((void *)((char *)p - 8)); +} + +#endif /* COOKIE_BUG */ diff --git a/gnu/usr.bin/groff/libgroff/prime.cc b/gnu/usr.bin/groff/libgroff/prime.cc new file mode 100644 index 00000000000..f0b1eadcc68 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/prime.cc @@ -0,0 +1,26 @@ +#include + +int is_prime(unsigned n) +{ + if (n <= 3) + return 1; + if (!(n & 1)) + return 0; + if (n % 3 == 0) + return 0; + unsigned lim = unsigned(sqrt((double)n)); + unsigned d = 5; + for (;;) { + if (d > lim) + break; + if (n % d == 0) + return 0; + d += 2; + if (d > lim) + break; + if (n % d == 0) + return 0; + d += 4; + } + return 1; +} diff --git a/gnu/usr.bin/groff/libgroff/progname.cc b/gnu/usr.bin/groff/libgroff/progname.cc new file mode 100644 index 00000000000..a70e3419c2b --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/progname.cc @@ -0,0 +1 @@ +const char *program_name = 0; diff --git a/gnu/usr.bin/groff/libgroff/ptable.cc b/gnu/usr.bin/groff/libgroff/ptable.cc new file mode 100644 index 00000000000..76735c2426d --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/ptable.cc @@ -0,0 +1,52 @@ +/* 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 "ptable.h" +#include "errarg.h" +#include "error.h" + +unsigned long hash_string(const char *s) +{ + assert(s != 0); + unsigned long h = 0, g; + while (*s != 0) { + h <<= 4; + h += *s++; + if ((g = h & 0xf0000000) != 0) { + h ^= g >> 24; + h ^= g; + } + } + return h; +} + +static const unsigned table_sizes[] = { +101, 503, 1009, 2003, 3001, 4001, 5003, 10007, 20011, 40009, +80021, 160001, 500009, 1000003, 2000003, 4000037, 8000009, +16000057, 32000011, 64000031, 128000003, 0 +}; + +unsigned next_ptable_size(unsigned n) +{ + const unsigned *p; + for (p = table_sizes; *p <= n; p++) + if (*p == 0) + fatal("cannot expand table"); + return *p; +} diff --git a/gnu/usr.bin/groff/libgroff/putenv.c b/gnu/usr.bin/groff/libgroff/putenv.c new file mode 100644 index 00000000000..9e1cd322cac --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/putenv.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Hacked slightly by jjc@jclark.com for groff. */ + +#include + +#ifdef __STDC__ +#include +typedef void *PTR; +typedef size_t SIZE_T; +#else /* not __STDC__ */ +typedef char *PTR; +typedef int SIZE_T; +#endif /* not __STDC__ */ + +#ifdef HAVE_STDLIB_H +#include +#else /* not HAVE_STDLIB_H */ +PTR malloc(); +#endif /* not HAVE_STDLIB_H */ + +#ifndef NULL +#define NULL 0 +#endif + +extern char **environ; + +/* Put STRING, which is of the form "NAME=VALUE", in the environment. */ + +int putenv(string) + char *string; +{ + char *name_end = strchr(string, '='); + SIZE_T size; + char **ep; + + if (name_end == NULL) + { + /* Remove the variable from the environment. */ + size = strlen(string); + for (ep = environ; *ep != NULL; ++ep) + if (!strncmp(*ep, string, size) && (*ep)[size] == '=') + { + while (ep[1] != NULL) + { + ep[0] = ep[1]; + ++ep; + } + *ep = NULL; + return 0; + } + } + + size = 0; + for (ep = environ; *ep != NULL; ++ep) + if (!strncmp(*ep, string, name_end - string) + && (*ep)[name_end - string] == '=') + break; + else + ++size; + + if (*ep == NULL) + { + static char **last_environ = NULL; + char **new_environ = (char **) malloc((size + 2) * sizeof(char *)); + if (new_environ == NULL) + return -1; + (void) memcpy((PTR) new_environ, (PTR) environ, size * sizeof(char *)); + new_environ[size] = (char *) string; + new_environ[size + 1] = NULL; + if (last_environ != NULL) + free((PTR) last_environ); + last_environ = new_environ; + environ = new_environ; + } + else + *ep = (char *) string; + + return 0; +} diff --git a/gnu/usr.bin/groff/libgroff/searchpath.cc b/gnu/usr.bin/groff/libgroff/searchpath.cc new file mode 100644 index 00000000000..730b5d9967f --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/searchpath.cc @@ -0,0 +1,117 @@ +// -*- 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 +#include +#include +#include + +#include "lib.h" +#include "searchpath.h" + +search_path::search_path(const char *envvar, const char *standard) +{ + char *e = envvar ? getenv(envvar) : 0; + if (e && standard) { + dirs = new char[strlen(e) + strlen(standard) + 2]; + strcpy(dirs, e); + strcat(dirs, ":"); + strcat(dirs, standard); + } + else + dirs = strsave(e ? e : standard); + init_len = dirs ? strlen(dirs) : 0; +} + +search_path::~search_path() +{ + if (dirs) + a_delete dirs; +} + +void search_path::command_line_dir(const char *s) +{ + if (!dirs) + dirs = strsave(s); + else { + char *old = dirs; + unsigned old_len = strlen(old); + unsigned slen = strlen(s); + dirs = new char[old_len + 1 + slen + 1]; + memcpy(dirs, old, old_len - init_len); + char *p = dirs; + p += old_len - init_len; + if (init_len == 0) + *p++ = ':'; + memcpy(p, s, slen); + p += slen; + if (init_len > 0) { + *p++ = ':'; + memcpy(p, old + old_len - init_len, init_len); + p += init_len; + } + *p++ = '\0'; + a_delete old; + } +} + +FILE *search_path::open_file(const char *name, char **pathp) +{ + assert(name != 0); + if (*name == '/' || dirs == 0 || *dirs == '\0') { + FILE *fp = fopen(name, "r"); + if (fp) { + if (pathp) + *pathp = strsave(name); + return fp; + } + else + return 0; + } + unsigned namelen = strlen(name); + char *p = dirs; + for (;;) { + char *end = strchr(p, ':'); + if (!end) + end = strchr(p, '\0'); + int need_slash = end > p && end[-1] != '/'; + char *path = new char[(end - p) + need_slash + namelen + 1]; + memcpy(path, p, end - p); + if (need_slash) + path[end - p] = '/'; + strcpy(path + (end - p) + need_slash, name); +#if 0 + fprintf(stderr, "trying `%s'\n", path); +#endif + FILE *fp = fopen(path, "r"); + if (fp) { + if (pathp) + *pathp = path; + else + a_delete path; + return fp; + } + a_delete path; + if (*end == '\0') + break; + p = end + 1; + } + return 0; +} diff --git a/gnu/usr.bin/groff/libgroff/strerror.c b/gnu/usr.bin/groff/libgroff/strerror.c new file mode 100644 index 00000000000..63ef056cf6c --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/strerror.c @@ -0,0 +1,37 @@ +/* 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 + +#define INT_DIGITS 19 /* enough for 64 bit integer */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +char *strerror(n) + int n; +{ + static char buf[sizeof("Error ") + 1 + INT_DIGITS]; + if (n >= 0 && n < sys_nerr && sys_errlist[n] != 0) + return sys_errlist[n]; + else { + sprintf(buf, "Error %d", n); + return buf; + } +} diff --git a/gnu/usr.bin/groff/libgroff/string.cc b/gnu/usr.bin/groff/libgroff/string.cc new file mode 100644 index 00000000000..7d1471a7c4a --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/string.cc @@ -0,0 +1,311 @@ +// -*- 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 +#include "stringclass.h" +#include "lib.h" + +static char *salloc(int len, int *sizep); +static void sfree(char *ptr, int size); +static char *sfree_alloc(char *ptr, int size, int len, int *sizep); +static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep); + +static char *salloc(int len, int *sizep) +{ + if (len == 0) { + *sizep = 0; + return 0; + } + else + return new char[*sizep = len*2]; +} + +static void sfree(char *ptr, int) +{ + a_delete ptr; +} + +static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep) +{ + if (oldsz >= len) { + *sizep = oldsz; + return ptr; + } + a_delete ptr; + if (len == 0) { + *sizep = 0; + return 0; + } + else + return new char[*sizep = len*2]; +} + +static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep) +{ + if (oldsz >= newlen) { + *sizep = oldsz; + return ptr; + } + if (newlen == 0) { + a_delete ptr; + *sizep = 0; + return 0; + } + else { + char *p = new char[*sizep = newlen*2]; + if (oldlen < newlen && oldlen != 0) + memcpy(p, ptr, oldlen); + a_delete ptr; + return p; + } +} + +string::string() : len(0), ptr(0), sz(0) +{ +} + +string::string(const char *p, int n) : len(n) +{ + assert(n >= 0); + ptr = salloc(n, &sz); + if (n != 0) + memcpy(ptr, p, n); +} + +string::string(const char *p) +{ + if (p == 0) { + len = 0; + ptr = 0; + sz = 0; + } + else { + len = strlen(p); + ptr = salloc(len, &sz); + memcpy(ptr, p, len); + } +} + +string::string(char c) : len(1) +{ + ptr = salloc(1, &sz); + *ptr = c; +} + +string::string(const string &s) : len(s.len) +{ + ptr = salloc(len, &sz); + if (len != 0) + memcpy(ptr, s.ptr, len); +} + +string::~string() +{ + sfree(ptr, sz); +} + +string &string::operator=(const string &s) +{ + ptr = sfree_alloc(ptr, sz, s.len, &sz); + len = s.len; + if (len != 0) + memcpy(ptr, s.ptr, len); + return *this; +} + +string &string::operator=(const char *p) +{ + if (p == 0) { + sfree(ptr, len); + len = 0; + ptr = 0; + sz = 0; + } + else { + int slen = strlen(p); + ptr = sfree_alloc(ptr, sz, slen, &sz); + len = slen; + memcpy(ptr, p, len); + } + return *this; +} + +string &string::operator=(char c) +{ + ptr = sfree_alloc(ptr, sz, 1, &sz); + len = 1; + *ptr = c; + return *this; +} + +void string::move(string &s) +{ + sfree(ptr, sz); + ptr = s.ptr; + len = s.len; + sz = s.sz; + s.ptr = 0; + s.len = 0; + s.sz = 0; +} + +void string::grow1() +{ + ptr = srealloc(ptr, sz, len, len + 1, &sz); +} + +string &string::operator+=(const char *p) +{ + if (p != 0) { + int n = strlen(p); + int newlen = len + n; + if (newlen > sz) + ptr = srealloc(ptr, sz, len, newlen, &sz); + memcpy(ptr + len, p, n); + len = newlen; + } + return *this; +} + +string &string::operator+=(const string &s) +{ + if (s.len != 0) { + int newlen = len + s.len; + if (newlen > sz) + ptr = srealloc(ptr, sz, len, newlen, &sz); + memcpy(ptr + len, s.ptr, s.len); + len = newlen; + } + return *this; +} + +void string::append(const char *p, int n) +{ + if (n > 0) { + int newlen = len + n; + if (newlen > sz) + ptr = srealloc(ptr, sz, len, newlen, &sz); + memcpy(ptr + len, p, n); + len = newlen; + } +} + +string::string(const char *s1, int n1, const char *s2, int n2) +{ + assert(n1 >= 0 && n2 >= 0); + len = n1 + n2; + if (len == 0) { + sz = 0; + ptr = 0; + } + else { + ptr = salloc(len, &sz); + if (n1 == 0) + memcpy(ptr, s2, n2); + else { + memcpy(ptr, s1, n1); + if (n2 != 0) + memcpy(ptr + n1, s2, n2); + } + } +} + +int operator<=(const string &s1, const string &s2) +{ + return (s1.len <= s2.len + ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0 + : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0); +} + +int operator<(const string &s1, const string &s2) +{ + return (s1.len < s2.len + ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0 + : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0); +} + +int operator>=(const string &s1, const string &s2) +{ + return (s1.len >= s2.len + ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0 + : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0); +} + +int operator>(const string &s1, const string &s2) +{ + return (s1.len > s2.len + ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0 + : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0); +} + +void string::set_length(int i) +{ + assert(i >= 0); + if (i > sz) + ptr = srealloc(ptr, sz, len, i, &sz); + len = i; +} + +void string::clear() +{ + len = 0; +} + +int string::search(char c) const +{ + char *p = (char *)memchr(ptr, c, len); + return p ? p - ptr : -1; +} + +// we silently strip nuls + +char *string::extract() const +{ + char *p = ptr; + int n = len; + int nnuls = 0; + int i; + for (i = 0; i < n; i++) + if (p[i] == '\0') + nnuls++; + char *q = new char[n + 1 - nnuls]; + char *r = q; + for (i = 0; i < n; i++) + if (p[i] != '\0') + *r++ = p[i]; + q[n] = '\0'; + return q; +} + +void put_string(const string &s, FILE *fp) +{ + int len = s.length(); + const char *ptr = s.contents(); + for (int i = 0; i < len; i++) + putc(ptr[i], fp); +} + +string as_string(int i) +{ + static char buf[INT_DIGITS + 2]; + sprintf(buf, "%d", i); + return string(buf); +} + diff --git a/gnu/usr.bin/groff/libgroff/strsave.cc b/gnu/usr.bin/groff/libgroff/strsave.cc new file mode 100644 index 00000000000..dfd2b6f4074 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/strsave.cc @@ -0,0 +1,31 @@ +// -*- 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 + +char *strsave(const char *s) +{ + if (s == 0) + return 0; + char *p = new char[strlen(s) + 1]; + strcpy(p, s); + return p; +} + diff --git a/gnu/usr.bin/groff/libgroff/strtol.c b/gnu/usr.bin/groff/libgroff/strtol.c new file mode 100644 index 00000000000..071bade8dc1 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/strtol.c @@ -0,0 +1,131 @@ +/* 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 +#include +#include +#ifndef errno +extern int errno; +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif + +#ifdef isascii +#define ISASCII(c) isascii(c) +#else +#define ISASCII(c) (1) +#endif + +long strtol(str, ptr, base) + char *str, **ptr; + int base; +{ + char *start = str; + int neg = 0; + long val; + char *p; + static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + + while (ISASCII((unsigned char)*str) && isspace((unsigned char)*str)) + str++; + + if (*str == '-') { + neg = 1; + str++; + } + if (base == 0) { + if (*str == '0') { + if (str[1] == 'x' || str[1] == 'X') { + str += 2; + base = 16; + } + else + base = 8; + } + else + base = 10; + } + if (base < 2 || base > 36) + base = 10; + else if (base == 16 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) + str += 2; + + p = strchr(digits, (ISASCII((unsigned char)*str) + && isupper((unsigned char)*str) + ? tolower((unsigned char)*str) + : *str)); + if (p == 0 || (val = (p - digits)) >= base) { + if (base == 16 && str > start && (str[-1] == 'x' || str[-1] == 'X')) { + if (ptr) + *ptr = str - 1; + } + else { + if (ptr) + *ptr = start; + errno = ERANGE; + } + return 0; + } + if (neg) + val = -val; + + while (*++str != '\0') { + int n; + + p = strchr(digits, (ISASCII((unsigned char)*str) + && isupper((unsigned char)*str) + ? tolower((unsigned char)*str) : *str)); + if (p == 0) + break; + n = p - digits; + if (n >= base) + break; + if (neg) { + if (-(unsigned long)val > (-(unsigned long)LONG_MIN - n)/base) { + val = LONG_MIN; + errno = ERANGE; + } + else + val = val*base - n; + } + else { + if (val > (LONG_MAX - n)/base) { + val = LONG_MAX; + errno = ERANGE; + } + else + val = val*base + n; + } + } + + if (ptr) + *ptr = str; + + return val; +} diff --git a/gnu/usr.bin/groff/libgroff/tmpfile.cc b/gnu/usr.bin/groff/libgroff/tmpfile.cc new file mode 100644 index 00000000000..280d87c5e22 --- /dev/null +++ b/gnu/usr.bin/groff/libgroff/tmpfile.cc @@ -0,0 +1,99 @@ +// -*- 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 +#include +#include +#include + +#include "posix.h" +#include "lib.h" +#include "errarg.h" +#include "error.h" + +extern "C" { + // Sun's stdlib.h fails to declare this. + char *mktemp(char *); + int mkstemp(char *); +} + +// If this is set, create temporary files there +#define GROFF_TMPDIR_ENVVAR "GROFF_TMPDIR" +// otherwise if this is set, create temporary files there +#define TMPDIR_ENVVAR "TMPDIR" +// otherwise create temporary files here. +#define DEFAULT_TMPDIR "/tmp" +// Use this as the prefix for temporary filenames. +#define TMPFILE_PREFIX "groff" + +// Open a temporary file with fatal error on failure. + +FILE *xtmpfile() +{ + const char *dir = getenv(GROFF_TMPDIR_ENVVAR); + if (!dir) { + dir = getenv(TMPDIR_ENVVAR); + if (!dir) + dir = DEFAULT_TMPDIR; + } + + const char *p = strrchr(dir, '/'); + int needs_slash = (!p || p[1]); + char *templ = new char[strlen(dir) + needs_slash + + sizeof(TMPFILE_PREFIX) - 1 + 6 + 1]; + strcpy(templ, dir); + if (needs_slash) + strcat(templ, "/"); + strcat(templ, TMPFILE_PREFIX); + strcat(templ, "XXXXXX"); + +#ifdef HAVE_MKSTEMP + errno = 0; + int fd = mkstemp(templ); + if (fd < 0) + fatal("cannot create temporary file: %1", strerror(errno)); + errno = 0; + FILE *fp = fdopen(fd, "w+"); + if (!fp) + fatal("fdopen: %1", strerror(errno)); +#else /* not HAVE_MKSTEMP */ + if (!mktemp(templ) || !templ[0]) + fatal("cannot create file name for temporary file"); + errno = 0; + FILE *fp = fopen(templ, "w+"); + if (!fp) + fatal("cannot open `%1': %2", templ, strerror(errno)); +#endif /* not HAVE_MKSTEMP */ + if (unlink(templ) < 0) + error("cannot unlink `%1': %2", templ, strerror(errno)); + a_delete templ; + return fp; +} + +#if 0 +// If you're not running Unix, the following will do: +FILE *xtmpfile() +{ + FILE *fp = tmpfile(); + if (!fp) + fatal("couldn't create temporary file"); + return fp; +} +#endif -- cgit v1.2.3