diff options
Diffstat (limited to 'contrib/bc')
61 files changed, 4644 insertions, 1549 deletions
diff --git a/contrib/bc/AUTHORS b/contrib/bc/AUTHORS index c78d68f..b665a63 100644 --- a/contrib/bc/AUTHORS +++ b/contrib/bc/AUTHORS @@ -1,4 +1,4 @@ -Phil Nelson <phil@cs.wwu.edu> wrote bc, including the number.c +Phil Nelson <philnelson@acm.org> wrote bc, including the number.c source in the "lib" directory. Ken Pizzini wrote dc. diff --git a/contrib/bc/ChangeLog b/contrib/bc/ChangeLog index ca010b8..f277079 100644 --- a/contrib/bc/ChangeLog +++ b/contrib/bc/ChangeLog @@ -1,3 +1,224 @@ +Wed Sep 27 17:19:48 2000 Phil Nelson <phil@cs.wwu.edu> + + * doc/bc.texi: Added new file. Mainly translated from bc.1 + by Brian Youmans. + doc/bc.1: Minor changes made as part of reviewing bc.texi. + +Wed Sep 20 11:45:00 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/bc.y: Added a comment on the meanings of lvals. + +Wed Sep 13 11:40:24 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/main.c: add --interactive to long options. + bc/bc.1: add -i/--interactive to doc. + MANY: Update FSF address and Phil's e-mail. + +Tue Sep 12 13:58:16 2000 Phil Nelson <phil@cs.wwu.edu> + + * NEWS: update for recent changes. + bc/bc.y: remove required parens around return expression. + doc/bc.1: update for recent changes. + +Fri Sep 8 10:20:01 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/Makefile.am, dc/Makefile.am, lib/Makefile.am: + Compile with unsigned characters. + bc/main.c: Add --help option. + bc/scan.l: Print illegal, non-printable characters in octal. + +Fri Sep 8 09:36:54 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/bc.y: Allow more newlines in function definitions. + bc/proto.h: Don't prototype main. + +Fri Sep 1 16:09:50 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/bc.y: Spelling correction + bc/execute.c: Correct expressions for multi-byte names. + bc/load.c: Add parens for correct casting. + doc/bc.1: Typos. + Above fixes pointed out by kwzh@gnu.org (Karl Heuer). + +Tue Aug 29 23:03:30 PDT 2000 Phil Nelson <phil@cs.wwu.edu> + + * lib/testmul.c: #ifdef out a declaration matching #ifdef out + code. + +Mon Jul 31 07:01:42 2000 Ken Pizzini <ken@gnu.org> + + * dc/numeric.c: use of the "n" command can cause a number to be printed + without a trailing newline, which would cause the column counter to + fail to be reset and result in inappropriately wrapped numeric outputs. + Fixed by always clearing the column counter before outputting each number. + + * dc/stack.c: if a stack is used without ever using the correspondingly + named register, it is perfectly legitimate for the register to be + uninitialized; added an "else if" to handle this case without aborting. + + * dc/eval.c: updated the comment explaining the restrictions + on the | command to better reflect reality. + + * doc/dc.texi: update the FSF office address in the copyright notice + +Thu Jul 13 18:13:00 2000 Phil Nelson <phil@cs.wwu.edu> + + * README: note --with-libedit configure parameter. + +Tue Jun 20 22:52:10 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/bcdefs.h: Include <readline/history.h> to quiet warnings. + + * configure.in: make --with-readline and --with-libedit work correctly. + + * Makefile.am: use $(MAKE) instead of directly calling make. + + * lib/testmul.c: Update to use bc_ on all number.c routines. + +Sat Jun 10 22:44:29 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/Makefile.am: Add scan.c to maintainer-clean target. + + * acconfig.h configure.in stamp-h.in bc/Makefile.am bc/execute.c + bc/fix-libmath_h bc/global.c bc/load.c bc/main.c bc/storage.c: + Remove long string for libmath. Clean up for compiler errors. + + * dc/numeric.c: Correct parameter name. + +Wed May 10 15:51:16 2000 Phil Nelson <phil@cs.wwu.edu> + + * {bc,doc,dc,lib}/Makefile.am: Add Makefile.in to maintainer-clean. + + * bootstrap.sh: Added script to run the auto* tools. + + * Imported all into CVS tree. + +Sun 2000-05-07 Phil Nelson <phil@cs.wwu.edu> + + * bc/Makefile.am, dc/Makefile.am, lib/Makefile.am: Add -Wall to CFLAGS. + + * bc/{execute.c,proto.h,storage.c,util.c}, dc/numeric.c: Changes for + -Wall and for name changes in lib/number.c. (Added bc_ to several + routine. Updated copyright notice.) + + * h/number.h, lib/number.c: Now comes from bcmath library which is + distributed in a different place. + +Wed Mar 29 17:47:34 2000 Phil Nelson <phil@cs.wwu.edu> + + * bc/{bc.y,bcdefs.h,global.h,main.c,proto.h,scan.l,storage.c}: + Added BSD libedit support. Generic support for both where possible. + Fixed bugs in readline support noticed during libedit addition. + Works with NetBSD-1.4.1 libedit. + * doc/bc.1: Documented libedit addition. + +Wed Mar 29 10:20:18 2000 Phil Nelson <phil@cs.wwu.edu> + + * FAQ: Added this file. + * Makfile.am: Added FAQ to distribution + +Tue Mar 28 13:52:35 2000 Phil Nelson <phil@cs.wwu.edu> + + * lib/number.c, h/number.h: Moved definitions so + number.c/number.h is a stand-alone "library". + Changed definition of out_num to not reference a global. + * lib/testmul.c: updated #includes for number.h changes. + * h/{bcdefs.h,const.h,global.h,proto.h} moved to + bc where they really belong. + * bc/execute.c: Changed calls to out_num for correctness. + * dc/numeric.c: Changed calls to out_num for correctness, + include only number.h now and not all the other junk. + * configure.in, acconfig.h: Start of support for BSD libedit, + added --with-pkg for NetBSD /usr/pkg tree. + +Tue Mar 28 11:20:00 2000 Phil Nelson <phil@cs.wwu.edu> + + * Test/{exp.b,fact.b,jn.b,mul.b,raise.b}: Tweeks on the tests + run to do more computation and test the recursive multiply. + * bc/scan.l: Removed a printf('\r') that was unneeded. + +Mon Mar 27 14:00:00 2000 Phil Nelson <phil@cs.wwu.edu> + + * NEWS: Updated for 1.06. + * lib/number.c, h/number.h: Fixed bugs in recursive multiply. + Changed these files to be under the LGPL. + * Tests/jn.b: Added more tests. + * lib/Makefile.am: Only generate a timed version of number.o if + requested. + * README: Updated with information on how to generate a timed + version of number.o. + * h/version.h: Updated copyright and version number for dc. + +Thu Mar 16 14:01:45 2000 Phil Nelson <phil@cs.wwu.edu> + + * doc/bc.1, doc/dc.1, doc/dc.texi: Changed bug reporting address + to bug-bc@gnu.org to update with what we hope will be reality. + +Tue Feb 8 08:54:19 2000 Phil Nelson <phil@cs.wwu.edu> + + * doc/bc.1, bc/util.c: Removed "multiply digits" + limit due to new recursive algorithm that doesn't + have those limits. + +Tue Feb 8 08:47:05 2000 Phil Nelson <phil@cs.wwu.edu> + + * lib/Makefile.am, lib/testmul.c, lib/number.c, Makefile.am: + Finally got a resonable version of the program + to test the crossover between non-recursive and + recursive multiply algorithms. Added to distribution + and build process. Does increase build time by + about 10 minutes. + +Wed Oct 6 13:28:59 1999 Phil Nelson <phil@cs.wwu.edu> + + * lib/Makefile.am: Added rules to allow DEFSADD definitions. + +Sat Oct 2 19:59:51 1999 Phil Nelson <phil@cs.wwu.edu> + + * bc/libmath.b: Correctly do the cosine accuracy. + +Fri Oct 1 12:41:51 1999 Phil Nelson <phil@cs.wwu.edu> + + * lib/number.c: Increase accuracy of computing raise. + Also turn off use of recursive multiply routines + until furthur testing. + * bc/libmath.b: Increase accuracy of cosine. + * bc/Makefile.am: Remove -lfl from items to make. + +Wed Jul 28 10:29:28 1999 Phil Nelson <phil@cs.wwu.edu> + + * bc/scan.l: rl_len from char to int. (From FreeBSD + bug tracking system and Nick Hibma <nick.hibma@jrc.it>) + +Tue Jun 22 08:00:28 1999 Phil Nelson <phil@cs.wwu.edu> + + * lib/number.c: Rewrote bc_multiply to use a faster + algorithm. Old code not removed yet. + +Mon Jun 21 03:08:02 1999 Phil Nelson <phil@cs.wwu.edu> + + * h/version.h: Updated version number to 1.06. + bc/bc.y: Corrected bug in for statement, not popping. + bc/execute.c: Improved stack dump/instruction tracing. + +Tue Jun 15 22:30:42 1999 Phil Nelson <phil@cs.wwu.edu> + + * configure.in: Updated bc version to 1.06. + +Tue Jun 15 22:27:44 1999 Phil Nelson <phil@cs.wwu.edu> + + * h/bcdefs.h, h/const.h, bc/execute.c, bc/load.c, bc/storage.c, + bc/util.c: Removed segmented function storaged. Now + dynamically expands (by doubling, starting at 1024 bytes) + to allow arbitrary sized functions. + +Thu Jun 10 22:33:44 1999 Phil Nelson <phil@cs.wwu.edu> + + * bc/libmath.b: change scaling in computation of j(n,x) so + it correctly computes the value. + +Wed Jun 10 10:10:10 1998 Release of bc-1.05a. + Fri Apr 17 10:40:59 1998 Phil Nelson <phil@cs.wwu.edu> * bc/main.c: Enable readline only if interactive. @@ -820,4 +1041,3 @@ Tue Oct 29 10:06:32 1991 Phil Nelson (phil at cs.wwu.edu) * Called current version 1.00. * Submitted GNU bc-1.00 to comp.sources.reviewed - diff --git a/contrib/bc/FAQ b/contrib/bc/FAQ new file mode 100644 index 0000000..32dd051 --- /dev/null +++ b/contrib/bc/FAQ @@ -0,0 +1,17 @@ +Because of frequent questions ....... here is the BC FAQ + + +1) Why does BC have its own arbitrary precision number routines + (found in lib/number.c) rather than using GMP? + +GMP has "integers" (no digits after a decimal), "rational numbers" +(stored as 2 integers) and "floats". None of these will correctly +represent a POSIX BC number. Floats are the closest, but will not +behave correctly for many computations. For example, BC numbers have +a "scale" that represent the number of digits to represent after the +decimal point. The multiplying two of these numbers requires one to +calculate an exact number of digits after the decimal point regardless +of the number of digits in the integer part. GMP floats have a +"fixed, but arbitrary" mantissa and so multiplying two floats will end +up dropping digits BC must calculate. + diff --git a/contrib/bc/Makefile.am b/contrib/bc/Makefile.am index cbdde44..6703d74 100644 --- a/contrib/bc/Makefile.am +++ b/contrib/bc/Makefile.am @@ -1,9 +1,18 @@ ## Process this file with automake to produce Makefile.in + SUBDIRS = lib bc dc doc +MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \ + $(distdir).tar.gz h/number.h + dist-hook: mkdir $(distdir)/h $(distdir)/Examples $(distdir)/Test cp -p $(srcdir)/h/*.h $(distdir)/h cp -p $(srcdir)/Examples/*.b $(distdir)/Examples cp -p $(srcdir)/Test/*.b $(srcdir)/Test/*.bc $(distdir)/Test cp -p $(srcdir)/Test/signum $(srcdir)/Test/timetest $(distdir)/Test + cp -p $(srcdir)/lib/testmul.c $(distdir)/lib + cp -p $(srcdir)/FAQ $(distdir) + +timetest: + (cd lib; $(MAKE) specialnumber) diff --git a/contrib/bc/Makefile.in b/contrib/bc/Makefile.in index 0f7ae3f..b57eae5 100644 --- a/contrib/bc/Makefile.in +++ b/contrib/bc/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.3 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,7 +11,7 @@ # PARTICULAR PURPOSE. -SHELL = /bin/sh +SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -32,7 +32,7 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DISTDIR = +DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ @@ -62,27 +62,30 @@ LEX = @LEX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +READLINELIB = @READLINELIB@ VERSION = @VERSION@ YACC = @YACC@ SUBDIRS = lib bc dc doc + +MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in $(distdir).tar.gz h/number.h + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = -DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ -Makefile.in NEWS acconfig.h aclocal.m4 config.h.in configure \ -configure.in install-sh missing mkinstalldirs stamp-h.in +DIST_COMMON = README ./stamp-h.in AUTHORS COPYING COPYING.LIB ChangeLog \ +INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 config.h.in \ +configure configure.in install-sh missing mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar -GZIP = --best -all: all-recursive-am all-am - +GZIP_ENV = --best +all: all-redirect .SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -92,22 +95,29 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(ACLOCAL_M4): configure.in cd $(srcdir) && $(ACLOCAL) -config.status: $(srcdir)/configure +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h - @: + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status - @echo timestamp > stamp-h + @echo timestamp > stamp-h 2> /dev/null $(srcdir)/config.h.in: $(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h cd $(top_srcdir) && $(AUTOHEADER) - @echo timestamp > $(srcdir)/stamp-h.in + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null mostlyclean-hdr: @@ -131,41 +141,65 @@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ - target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ - (cd $$subdir && $(MAKE) $$target) \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ - target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ - (cd $$subdir && $(MAKE) $$target) \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ - (cd $$subdir && $(MAKE) tags); \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + && mkid -f$$here/ID $$unique $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ @@ -191,29 +225,31 @@ top_distdir = $(distdir) # tarfile. distcheck: dist -rm -rf $(distdir) - GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ - && $(MAKE) \ - && $(MAKE) dvi \ - && $(MAKE) check \ - && $(MAKE) install \ - && $(MAKE) installcheck \ - && $(MAKE) dist + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist -rm -rf $(distdir) - @echo "========================"; \ - echo "$(distdir).tar.gz is ready for distribution"; \ - echo "========================" + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" dist: distdir -chmod -R a+r $(distdir) - GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) - GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) @@ -221,78 +257,84 @@ distdir: $(DISTFILES) -chmod 777 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ done for subdir in $(SUBDIRS); do \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ done - $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +info-am: info: info-recursive +dvi-am: dvi: dvi-recursive -check: all-am - $(MAKE) check-recursive +check-am: all-am +check: check-recursive +installcheck-am: installcheck: installcheck-recursive all-recursive-am: config.h - $(MAKE) all-recursive - -all-am: Makefile config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive +install-exec-am: install-exec: install-exec-recursive - @$(NORMAL_INSTALL) +install-data-am: install-data: install-data-recursive - @$(NORMAL_INSTALL) +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am install: install-recursive - @: - +uninstall-am: uninstall: uninstall-recursive - +all-am: Makefile config.h +all-redirect: all-recursive-am install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: installdirs-recursive +installdirs-am: mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(DISTCLEANFILES) + -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic -clean-am: clean-hdr clean-tags clean-generic mostlyclean-am - -distclean-am: distclean-hdr distclean-tags distclean-generic clean-am +mostlyclean: mostlyclean-recursive -maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ - maintainer-clean-generic distclean-am +clean-am: clean-hdr clean-tags clean-generic mostlyclean-am -mostlyclean: mostlyclean-recursive mostlyclean-am +clean: clean-recursive -clean: clean-recursive clean-am +distclean-am: distclean-hdr distclean-tags distclean-generic clean-am -distclean: distclean-recursive distclean-am +distclean: distclean-recursive -rm -f config.status -maintainer-clean: maintainer-clean-recursive maintainer-clean-am +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ + maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive -rm -f config.status .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ @@ -301,11 +343,12 @@ uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ all-recursive check-recursive installcheck-recursive info-recursive \ dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ -installcheck all-recursive-am all-am install-exec install-data install \ -uninstall all installdirs mostlyclean-generic distclean-generic \ -clean-generic maintainer-clean-generic clean mostlyclean distclean \ -maintainer-clean +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean dist-hook: @@ -314,6 +357,11 @@ dist-hook: cp -p $(srcdir)/Examples/*.b $(distdir)/Examples cp -p $(srcdir)/Test/*.b $(srcdir)/Test/*.bc $(distdir)/Test cp -p $(srcdir)/Test/signum $(srcdir)/Test/timetest $(distdir)/Test + cp -p $(srcdir)/lib/testmul.c $(distdir)/lib + cp -p $(srcdir)/FAQ $(distdir) + +timetest: + (cd lib; $(MAKE) specialnumber) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/contrib/bc/NEWS b/contrib/bc/NEWS index 105795d..fc02a0d 100644 --- a/contrib/bc/NEWS +++ b/contrib/bc/NEWS @@ -1,4 +1,19 @@ -This is GNU bc version 1.05. (And dc version 1.2) +This is GNU bc version 1.06. (And dc version 1.2) + +Changes in dc from 1.2 to 1.3: + Minor bug fixes. + New multiply algorithm of bc. + +Changes in bc from 1.05 to 1.06: + New multiply algoirthm and many other changes in lib/number.c + Function size now done dynamically. + Function syntax in non-posix mode allows newlines in more places. + Bug fixes: + improved computation of j(n,x). + enables readline only if interactive. + for statment bug fixed. + use int instead of char for readline char counts. + improved cosine accuracy. Changes in dc from 1.1 to 1.2: added !< != !> commands diff --git a/contrib/bc/README b/contrib/bc/README index 7bc2315..2813fb8 100644 --- a/contrib/bc/README +++ b/contrib/bc/README @@ -1,3 +1,31 @@ +GNU bc version 1.06: + +Extra configuration options: + + --with-readline tells bc to use the readline package that allows + for editing input lines when run interactive. + + --with-editline tells bc to use the BSD editline package that + allows for editing input lines when run interactive. + +Extra make steps: + + The simple make compiles a version of bc with fixed parameters + for the recursive multiplication algorithm. The fixed parameter + is the number of digits where a sequential algorithm is used + instead of the recursive algorithm. It is set to a value that + is known good on a couple of machines. (Sparc Ultra 10, Pentium + II, 450.) I'm calling this point the crossover point. + + To make a version of bc with a custom crossover point for your + machine, do the following steps: + + make timetest + make + + The timetest step takes a minimum of 10 minutes to complete. + + -------- Original comp.sources.reviewed README -------- Program: GNU bc @@ -55,3 +83,4 @@ an executable statement unlike the quit (i.e. "if (1 == 0) quit" will halt bc but "if (1 == 0) halt" will not halt bc.), and (h) the addition of the special variable "last" that is assigned the value of each print as the number is printed. +----------------------------------------------------------------------- diff --git a/contrib/bc/Test/exp.b b/contrib/bc/Test/exp.b index ed0e536..92c482c 100644 --- a/contrib/bc/Test/exp.b +++ b/contrib/bc/Test/exp.b @@ -1,3 +1,3 @@ -for (a=0; a<150; a++) x=e(a) +for (a=0; a<180; a+=.4) x=e(a) x quit diff --git a/contrib/bc/Test/fact.b b/contrib/bc/Test/fact.b index 8d14747..995a26d 100644 --- a/contrib/bc/Test/fact.b +++ b/contrib/bc/Test/fact.b @@ -4,8 +4,7 @@ define f (x) { return (f(x-1)*x) } -"Here we go" -for (a=1; a<100; a++) b+=f(a)/a +for (a=1; a<600; a++) b=f(a) " " "b=";b diff --git a/contrib/bc/Test/jn.b b/contrib/bc/Test/jn.b index 80ac915..a4e0624 100644 --- a/contrib/bc/Test/jn.b +++ b/contrib/bc/Test/jn.b @@ -1,6 +1,6 @@ -scale = 30 -for (a=0; a<5; a=a+2) { - for (b=0; b<100; b=b+10) x=j(a,b) +scale = 50 +for (a=0; a<=100; a += 20) { + for (b=0; b<=300; b += 20) x=j(a,b) + x } -x quit diff --git a/contrib/bc/Test/ln.b b/contrib/bc/Test/ln.b index 00a1deb..cd00232 100644 --- a/contrib/bc/Test/ln.b +++ b/contrib/bc/Test/ln.b @@ -1,3 +1,4 @@ -for (a=1; a<10000000000000000000000000000; a = a*2) x=l(a) +scale = 60 +for (a=1; a<100000000000000000000000000000000000000; a = a*2) x=l(a) x quit diff --git a/contrib/bc/Test/mul.b b/contrib/bc/Test/mul.b index 1970ed1..722086f 100644 --- a/contrib/bc/Test/mul.b +++ b/contrib/bc/Test/mul.b @@ -1,7 +1,13 @@ scale = 20 -for (i=0; i<1000; i++) { +for (i=0; i<10000; i++) { for (j=1; j<100; j++) b=i*j } b +for (i=0; i<10000; i++) { + for (j=1000000000000000000000000000000000000000000000000000000000000000000; \ + j<1000000000000000000000000000000000000000000000000000000000000000100; \ + j++) b=i*j +} +b quit diff --git a/contrib/bc/Test/raise.b b/contrib/bc/Test/raise.b index a885815..ec6929d 100644 --- a/contrib/bc/Test/raise.b +++ b/contrib/bc/Test/raise.b @@ -1,3 +1,7 @@ for (i=0; i<1000; i++) a = 2^i; a +for (i=3000; i<3100; i++) a = 3^i; +a +for (i=200; i<220; i++) a = (4^100)^i; +a quit diff --git a/contrib/bc/Test/timetest b/contrib/bc/Test/timetest index 792c591..1a4d0ea 100755 --- a/contrib/bc/Test/timetest +++ b/contrib/bc/Test/timetest @@ -2,11 +2,13 @@ # # Time the functions. # -BC=../bc/bc SYSBC=/usr/bin/bc +if [ x$BC = x ] ; then + BC=../bc/bc +fi for file in exp.b ln.b sine.b atan.b jn.b mul.b div.b raise.b sqrt.b do -for prog in $BC $SYSBC +for prog in $BC $SYSBC $OTHERBC do echo Timing $file with $prog time $prog -l $file diff --git a/contrib/bc/acconfig.h b/contrib/bc/acconfig.h index ac625a5..ff17f82 100644 --- a/contrib/bc/acconfig.h +++ b/contrib/bc/acconfig.h @@ -4,12 +4,21 @@ /* Package VERSION number */ #undef VERSION -/* define if the math lib is to be loaded from a file. */ -#undef BC_MATH_FILE +/* VERSION number for DC target*/ +#undef DC_VERSION + +/* COPYRIGHT notice for DC target */ +#undef DC_COPYRIGHT + +/* COPYRIGHT notice for BC target */ +#undef BC_COPYRIGHT /* Define to use the readline library. */ #undef READLINE +/* Define to use the BSD libedit library. */ +#undef LIBEDIT + /* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */ #undef ptrdiff_t diff --git a/contrib/bc/aclocal.m4 b/contrib/bc/aclocal.m4 index 8c0d9c0..102dc3e 100644 --- a/contrib/bc/aclocal.m4 +++ b/contrib/bc/aclocal.m4 @@ -1,7 +1,7 @@ -dnl aclocal.m4 generated automatically by aclocal 1.3 +dnl aclocal.m4 generated automatically by aclocal 1.4 -dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. -dnl This Makefile.in is free software; the Free Software Foundation +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -20,7 +20,7 @@ dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, -[AC_REQUIRE([AM_PROG_INSTALL]) +[AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] @@ -30,8 +30,8 @@ if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi ifelse([$3],, -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") -AC_DEFINE_UNQUOTED(VERSION, "$VERSION")) +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) AC_REQUIRE([AM_SANITY_CHECK]) AC_REQUIRE([AC_ARG_PROGRAM]) dnl FIXME This is truly gross. @@ -43,15 +43,6 @@ AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_REQUIRE([AC_PROG_MAKE_SET])]) - -# serial 1 - -AC_DEFUN(AM_PROG_INSTALL, -[AC_REQUIRE([AC_PROG_INSTALL]) -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' -AC_SUBST(INSTALL_SCRIPT)dnl -]) - # # Check to make sure that the build environment is sane. # diff --git a/contrib/bc/bc/Makefile.am b/contrib/bc/bc/Makefile.am index d02daf0..9187339 100644 --- a/contrib/bc/bc/Makefile.am +++ b/contrib/bc/bc/Makefile.am @@ -3,46 +3,40 @@ bin_PROGRAMS = bc bc_SOURCES = main.c bc.y scan.l execute.c load.c storage.c util.c global.c -EXTRA_DIST = bc.h fix-libmath_h libmath.b sbc.y +EXTRA_DIST = bc.h bcdefs.h const.h fix-libmath_h global.h libmath.b proto.h \ + sbc.y noinst_HEADERS = libmath.h DISTCLEANFILES = sbc sbc.c sbc.h -MAINTAINERCLEANFILES = libmath.h bc.c bc.h -datadir = $(prefix)/@DATADIRNAME@ +MAINTAINERCLEANFILES = Makefile.in libmath.h bc.c bc.h scan.c INCLUDES = -I$(srcdir) -I$(srcdir)/../h -LDADD = ../lib/libbc.a @LEXLIB@ +LIBBC = ../lib/libbc.a +LIBL = @LEXLIB@ +LDADD = $(LIBBC) $(LIBL) @READLINELIB@ YFLAGS = -d -$(PROGRAMS): $(LDADD) +CFLAGS = @CFLAGS@ -Wall -funsigned-char + +$(PROGRAMS): $(LIBBC) scan.o: bc.h global.o: libmath.h libmath.h: libmath.b - echo \"\" > libmath.h + echo '{0}' > libmath.h $(MAKE) fbc ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h $(srcdir)/fix-libmath_h rm -f ./fbc -install-data-local: - if grep -s "define BC_MATH_FILE" ../config.h; \ - then $(mkinstalldirs) $(libdir); \ - rm -f $(libdir)/libmath.b; \ - $(INSTALL_DATA) $(srcdir)/libmath.b $(libdir); \ - chmod 444 $(libdir)/libmath.b; \ - else true; \ - fi - fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o fbc: $(fbcOBJ) - $(LINK) $(fbcOBJ) $(LDADD) $(LIBS) - + $(LINK) $(fbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS) sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o sbc.o: sbc.c sbc: $(sbcOBJ) - $(LINK) $(sbcOBJ) $(LDADD) $(LIBS) + $(LINK) $(sbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS) diff --git a/contrib/bc/bc/Makefile.in b/contrib/bc/bc/Makefile.in index 2398cb0..18ebce0 100644 --- a/contrib/bc/bc/Makefile.in +++ b/contrib/bc/bc/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.3 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,7 +11,7 @@ # PARTICULAR PURPOSE. -SHELL = /bin/sh +SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -22,6 +22,7 @@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ +datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ @@ -31,7 +32,7 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DISTDIR = +DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -45,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ @@ -61,6 +62,7 @@ LEX = @LEX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +READLINELIB = @READLINELIB@ VERSION = @VERSION@ YACC = @YACC@ @@ -68,19 +70,23 @@ bin_PROGRAMS = bc bc_SOURCES = main.c bc.y scan.l execute.c load.c storage.c util.c global.c -EXTRA_DIST = bc.h fix-libmath_h libmath.b sbc.y +EXTRA_DIST = bc.h bcdefs.h const.h fix-libmath_h global.h libmath.b proto.h sbc.y + noinst_HEADERS = libmath.h DISTCLEANFILES = sbc sbc.c sbc.h -MAINTAINERCLEANFILES = libmath.h bc.c bc.h -datadir = $(prefix)/@DATADIRNAME@ +MAINTAINERCLEANFILES = Makefile.in libmath.h bc.c bc.h scan.c INCLUDES = -I$(srcdir) -I$(srcdir)/../h -LDADD = ../lib/libbc.a @LEXLIB@ +LIBBC = ../lib/libbc.a +LIBL = @LEXLIB@ +LDADD = $(LIBBC) $(LIBL) @READLINELIB@ YFLAGS = -d +CFLAGS = @CFLAGS@ -Wall -funsigned-char + fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o @@ -101,9 +107,9 @@ bc_DEPENDENCIES = ../lib/libbc.a bc_LDFLAGS = LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LEXLIB = @LEXLIB@ -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ HEADERS = $(noinst_HEADERS) DIST_COMMON = Makefile.am Makefile.in bc.c scan.c @@ -112,15 +118,14 @@ DIST_COMMON = Makefile.am Makefile.in bc.c scan.c DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar -GZIP = --best +GZIP_ENV = --best SOURCES = $(bc_SOURCES) OBJECTS = $(bc_OBJECTS) -all: Makefile $(PROGRAMS) $(HEADERS) - +all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .l .o .s .y -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps bc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -142,15 +147,15 @@ install-binPROGRAMS: $(bin_PROGRAMS) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: @@ -175,21 +180,25 @@ maintainer-clean-compile: bc: $(bc_OBJECTS) $(bc_DEPENDENCIES) @rm -f bc $(LINK) $(bc_LDFLAGS) $(bc_OBJECTS) $(bc_LDADD) $(LIBS) +.l.c: + $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ .y.c: - $(YACC) $(YFLAGS) $< && mv y.tab.c $*.c + $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c if test -f y.tab.h; then \ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ else :; fi bc.h: bc.c -.l.c: - $(LEX) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ @@ -217,97 +226,119 @@ subdir = bc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ done -info: -dvi: -check: all - $(MAKE) -installcheck: -install-exec: install-binPROGRAMS - @$(NORMAL_INSTALL) - -install-data: install-data-local - @$(NORMAL_INSTALL) - -install: install-exec install-data all - @: - -uninstall: uninstall-binPROGRAMS - +bc.o: bc.c bcdefs.h ../config.h const.h ../h/number.h global.h proto.h +execute.o: execute.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + proto.h +global.o: global.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + libmath.h +load.o: load.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + proto.h +main.o: main.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + proto.h ../h/getopt.h +scan.o: scan.c bcdefs.h ../config.h const.h ../h/number.h bc.h global.h \ + proto.h +storage.o: storage.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + proto.h +util.o: util.c bcdefs.h ../config.h const.h ../h/number.h global.h \ + proto.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +all-redirect: all-am install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: - $(mkinstalldirs) $(DATADIR)$(bindir) + $(mkinstalldirs) $(DESTDIR)$(bindir) mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(DISTCLEANFILES) + -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ + -test -z "scanlbchbcc$(MAINTAINERCLEANFILES)" || rm -f scanl bch bcc $(MAINTAINERCLEANFILES) +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic -clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ - mostlyclean +mostlyclean: mostlyclean-am -distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ - distclean-generic clean - -rm -f config.status +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am -maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ - maintainer-clean-tags maintainer-clean-generic \ - distclean +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." +maintainer-clean: maintainer-clean-am + .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir info dvi installcheck \ -install-exec install-data install uninstall all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean -$(PROGRAMS): $(LDADD) +$(PROGRAMS): $(LIBBC) scan.o: bc.h global.o: libmath.h libmath.h: libmath.b - echo \"\" > libmath.h + echo '{0}' > libmath.h $(MAKE) fbc ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h $(srcdir)/fix-libmath_h rm -f ./fbc - -install-data-local: - if grep -s "define BC_MATH_FILE" ../config.h; \ - then $(mkinstalldirs) $(libdir); \ - rm -f $(libdir)/libmath.b; \ - $(INSTALL_DATA) $(srcdir)/libmath.b $(libdir); \ - chmod 444 $(libdir)/libmath.b; \ - else true; \ - fi fbc: $(fbcOBJ) - $(LINK) $(fbcOBJ) $(LDADD) $(LIBS) + $(LINK) $(fbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS) sbc.o: sbc.c sbc: $(sbcOBJ) - $(LINK) $(sbcOBJ) $(LDADD) $(LIBS) + $(LINK) $(sbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/contrib/bc/bc/bc.y b/contrib/bc/bc/bc.y index 81e77a8..403e326 100644 --- a/contrib/bc/bc/bc.y +++ b/contrib/bc/bc/bc.y @@ -16,11 +16,13 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program; see the file COPYING. If not, write to: + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -43,7 +45,7 @@ } /* Extensions over POSIX bc. - a) NAME was LETTER. This grammer allows longer names. + a) NAME was LETTER. This grammar allows longer names. Single letter names will still work. b) Relational_expression allowed only one comparison. This grammar has added boolean expressions with @@ -61,7 +63,7 @@ j) limits statement to print the processor's limits. */ -%token <i_value> NEWLINE AND OR NOT +%token <i_value> ENDOFLINE AND OR NOT %token <s_value> STRING NAME NUMBER /* '-', '+' are tokens themselves */ /* '=', '+=', '-=', '*=', '/=', '%=', '^=' */ @@ -79,7 +81,7 @@ /* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */ %token <i_value> Warranty, Halt, Last, Continue, Print, Limits /* 'history' */ -%token <i_value> UNARY_MINUS History +%token <i_value> UNARY_MINUS HistoryVar /* Types of all other things. */ %type <i_value> expression return_expression named_expression opt_expression @@ -87,7 +89,7 @@ %type <a_value> opt_parameter_list opt_auto_define_list define_list %type <a_value> opt_argument_list argument_list %type <i_value> program input_item semicolon_list statement_list -%type <i_value> statement function statement_or_error +%type <i_value> statement function statement_or_error required_eol /* precedence */ %left OR @@ -107,24 +109,24 @@ program : /* empty */ $$ = 0; if (interactive && !quiet) { - printf ("%s\n", BC_VERSION); + show_bc_version (); welcome (); } } | program input_item ; -input_item : semicolon_list NEWLINE +input_item : semicolon_list ENDOFLINE { run_code (); } | function { run_code (); } - | error NEWLINE + | error ENDOFLINE { yyerrok; init_gen (); } ; opt_newline : /* empty */ - | NEWLINE + | ENDOFLINE { warn ("newline not allowed"); } ; semicolon_list : /* empty */ @@ -136,8 +138,8 @@ semicolon_list : /* empty */ statement_list : /* empty */ { $$ = 0; } | statement_or_error - | statement_list NEWLINE - | statement_list NEWLINE statement_or_error + | statement_list ENDOFLINE + | statement_list ENDOFLINE statement_or_error | statement_list ';' | statement_list ';' statement ; @@ -190,9 +192,7 @@ statement : Warranty { exit (0); } | Halt { generate ("h"); } - | Return - { generate ("0R"); } - | Return '(' return_expression ')' + | Return return_expression { generate ("R"); } | For { @@ -201,13 +201,12 @@ statement : Warranty } '(' opt_expression ';' { - if ($4 > 1) + if ($4 & 2) warn ("Comparison in first for expression"); + if ($4 >= 0) + generate ("p"); $4 = next_label++; - if ($4 < 0) - sprintf (genstr, "N%1d:", $4); - else - sprintf (genstr, "pN%1d:", $4); + sprintf (genstr, "N%1d:", $4); generate (genstr); } opt_expression ';' @@ -223,9 +222,9 @@ statement : Warranty } opt_expression ')' { - if ($10 > 1) + if ($10 & 2 ) warn ("Comparison in third for expression"); - if ($10 < 0) + if ($10 & 16) sprintf (genstr, "J%1d:N%1d:", $4, $7); else sprintf (genstr, "pJ%1d:N%1d:", $4, $7); @@ -300,7 +299,7 @@ opt_else : /* nothing */ } opt_newline statement function : Define NAME '(' opt_parameter_list ')' opt_newline - '{' NEWLINE opt_auto_define_list + '{' required_eol opt_auto_define_list { /* Check auto list against parameter list? */ check_params ($4,$9); @@ -313,7 +312,7 @@ function : Define NAME '(' opt_parameter_list ')' opt_newline $1 = next_label; next_label = 1; } - statement_list /* NEWLINE */ '}' + statement_list /* ENDOFLINE */ '}' { generate ("0R]"); next_label = $1; @@ -325,7 +324,7 @@ opt_parameter_list : /* empty */ ; opt_auto_define_list : /* empty */ { $$ = NULL; } - | Auto define_list NEWLINE + | Auto define_list ENDOFLINE { $$ = $2; } | Auto define_list ';' { $$ = $2; } @@ -349,7 +348,7 @@ opt_argument_list : /* empty */ ; argument_list : expression { - if ($1 > 1) warn ("comparison in argument"); + if ($1 & 2) warn ("comparison in argument"); $$ = nextarg (NULL,0,FALSE); } | NAME '[' ']' @@ -360,7 +359,7 @@ argument_list : expression } | argument_list ',' expression { - if ($3 > 1) warn ("comparison in argument"); + if ($3 & 2) warn ("comparison in argument"); $$ = nextarg ($1,0,FALSE); } | argument_list ',' NAME '[' ']' @@ -370,9 +369,18 @@ argument_list : expression $$ = nextarg ($1,1,FALSE); } ; + +/* Expression lval meanings! (Bits mean something!) + * 0 => Top op is assignment. + * 1 => Top op is not assignment. + * 2 => Comparison is somewhere in expression. + * 4 => Expression is in parenthesis. + * 16 => Empty optional expression. + */ + opt_expression : /* empty */ { - $$ = -1; + $$ = 16; warn ("Missing expression in for statement"); } | expression @@ -384,8 +392,10 @@ return_expression : /* empty */ } | expression { - if ($1 > 1) + if ($1 & 2) warn ("comparison in return expresion"); + if (!($1 & 4)) + warn ("return expression requires parenthesis"); } ; expression : named_expression ASSIGN_OP @@ -401,7 +411,7 @@ expression : named_expression ASSIGN_OP } expression { - if ($4 > 1) warn("comparison in assignment"); + if ($4 & 2) warn("comparison in assignment"); if ($2 != '=') { sprintf (genstr, "%c", $2); @@ -426,7 +436,7 @@ expression : named_expression ASSIGN_OP { sprintf (genstr, "DZ%d:p1N%d:", $2, $2); generate (genstr); - $$ = $1 | $4; + $$ = ($1 | $4) & ~4; } | expression OR { @@ -442,11 +452,11 @@ expression : named_expression ASSIGN_OP sprintf (genstr, "B%d:0J%d:N%d:1N%d:", $2, tmplab, $2, tmplab); generate (genstr); - $$ = $1 | $4; + $$ = ($1 | $4) & ~4; } | NOT expression { - $$ = $2; + $$ = $2 & ~4; warn("! operator"); generate ("!"); } @@ -481,37 +491,37 @@ expression : named_expression ASSIGN_OP | expression '+' expression { generate ("+"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | expression '-' expression { generate ("-"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | expression '*' expression { generate ("*"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | expression '/' expression { generate ("/"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | expression '%' expression { generate ("%"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | expression '^' expression { generate ("^"); - $$ = $1 | $3; + $$ = ($1 | $3) & ~4; } | '-' expression %prec UNARY_MINUS { generate ("n"); - $$ = $2; + $$ = $2 & ~4; } | named_expression { @@ -539,7 +549,7 @@ expression : named_expression ASSIGN_OP free ($1); } | '(' expression ')' - { $$ = $2 | 1; } + { $$ = $2 | 5; } | NAME '(' opt_argument_list ')' { $$ = 1; @@ -623,7 +633,7 @@ named_expression : NAME { $$ = 1; } | Scale { $$ = 2; } - | History + | HistoryVar { $$ = 3; warn ("History variable"); } @@ -633,5 +643,12 @@ named_expression : NAME } ; + +required_eol : { warn ("End of line required"); } + | ENDOFLINE + | required_eol ENDOFLINE + { warn ("Too many end of lines"); } + ; + %% diff --git a/contrib/bc/bc/bcdefs.h b/contrib/bc/bc/bcdefs.h new file mode 100644 index 0000000..260cd12 --- /dev/null +++ b/contrib/bc/bc/bcdefs.h @@ -0,0 +1,188 @@ +/* bcdefs.h: The single file to include all constants and type definitions. */ + +/* This file is part of GNU bc. + Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + + This program 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 of the License , or + (at your option) any later version. + + This program 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 this program; see the file COPYING. If not, write to + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA + + You may contact the author by: + e-mail: philnelson@acm.org + us-mail: Philip A. Nelson + Computer Science Department, 9062 + Western Washington University + Bellingham, WA 98226-9062 + +*************************************************************************/ + +/* Include the configuration file. */ +#include "config.h" + +/* Standard includes for all files. */ +#include <stdio.h> +#include <sys/types.h> +#include <ctype.h> +#ifdef HAVE_STRINGS_H +#include <strings.h> +#else +#include <string.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#if defined(LIBEDIT) +#include <histedit.h> +#endif + +#if defined(READLINE) +#include <readline/readline.h> +#include <readline/history.h> +#endif + +/* Include the other definitions. */ +#include "const.h" +#include "number.h" + +/* These definitions define all the structures used in + code and data storage. This includes the representation of + labels. The "guiding" principle is to make structures that + take a minimum of space when unused but can be built to contain + the full structures. */ + +/* Labels are first. Labels are generated sequentially in functions + and full code. They just "point" to a single bye in the code. The + "address" is the byte number. The byte number is used to get an + actual character pointer. */ + +typedef struct bc_label_group + { + long l_adrs [ BC_LABEL_GROUP ]; + struct bc_label_group *l_next; + } bc_label_group; + +/* Argument list. Recorded in the function so arguments can + be checked at call time. */ + +typedef struct arg_list + { + int av_name; + int arg_is_var; /* Extension ... variable parameters. */ + struct arg_list *next; + } arg_list; + +/* Each function has its own code segments and labels. There can be + no jumps between functions so labels are unique to a function. */ + +typedef struct + { + char f_defined; /* Is this function defined yet. */ + char *f_body; + int f_body_size; /* Size of body. Power of 2. */ + int f_code_size; + bc_label_group *f_label; + arg_list *f_params; + arg_list *f_autos; + } bc_function; + +/* Code addresses. */ +typedef struct { + int pc_func; + int pc_addr; + } program_counter; + + +/* Variables are "pushable" (auto) and thus we need a stack mechanism. + This is built into the variable record. */ + +typedef struct bc_var + { + bc_num v_value; + struct bc_var *v_next; + } bc_var; + + +/* bc arrays can also be "auto" variables and thus need the same + kind of stacking mechanisms. */ + +typedef struct bc_array_node + { + union + { + bc_num n_num [NODE_SIZE]; + struct bc_array_node *n_down [NODE_SIZE]; + } n_items; + } bc_array_node; + +typedef struct bc_array + { + bc_array_node *a_tree; + short a_depth; + } bc_array; + +typedef struct bc_var_array + { + bc_array *a_value; + char a_param; + struct bc_var_array *a_next; + } bc_var_array; + + +/* For the stacks, execution and function, we need records to allow + for arbitrary size. */ + +typedef struct estack_rec { + bc_num s_num; + struct estack_rec *s_next; +} estack_rec; + +typedef struct fstack_rec { + int s_val; + struct fstack_rec *s_next; +} fstack_rec; + + +/* The following are for the name tree. */ + +typedef struct id_rec { + char *id; /* The program name. */ + /* A name == 0 => nothing assigned yet. */ + int a_name; /* The array variable name (number). */ + int f_name; /* The function name (number). */ + int v_name; /* The variable name (number). */ + short balance; /* For the balanced tree. */ + struct id_rec *left, *right; /* Tree pointers. */ +} id_rec; + + +/* A list of files to process. */ + +typedef struct file_node { + char *name; + struct file_node *next; +} file_node; + +/* Macro Definitions */ + +#if defined(LIBEDIT) +#define HISTORY_SIZE(n) history(hist, &histev, H_SETSIZE, n) +#define UNLIMIT_HISTORY history(hist, &histev, H_SETSIZE, INT_MAX) +#endif + +#if defined(READLINE) +#define HISTORY_SIZE(n) stifle_history(n) +#define UNLIMIT_HISTORY unstifle_history() +#endif diff --git a/contrib/bc/bc/const.h b/contrib/bc/bc/const.h new file mode 100644 index 0000000..1a7c5b8 --- /dev/null +++ b/contrib/bc/bc/const.h @@ -0,0 +1,98 @@ +/* const.h: Constants for bc. */ + +/* This file is part of GNU bc. + Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + + This program 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 of the License , or + (at your option) any later version. + + This program 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 this program; see the file COPYING. If not, write to + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA + + You may contact the author by: + e-mail: philnelson@acm.org + us-mail: Philip A. Nelson + Computer Science Department, 9062 + Western Washington University + Bellingham, WA 98226-9062 + +*************************************************************************/ + + +/* Define INT_MAX and LONG_MAX if not defined. Assuming 32 bits... */ + +#ifndef INT_MAX +#define INT_MAX 0x7FFFFFFF +#endif +#ifndef LONG_MAX +#define LONG_MAX 0x7FFFFFFF +#endif + + +/* Define constants in some reasonable size. The next 4 constants are + POSIX constants. */ + +#ifdef BC_BASE_MAX + /* <limits.h> on a POSIX.2 system may have defined these. Override. */ +# undef BC_BASE_MAX +# undef BC_SCALE_MAX +# undef BC_STRING_MAX +# undef BC_DIM_MAX +#endif + +#define BC_BASE_MAX INT_MAX +#define BC_SCALE_MAX INT_MAX +#define BC_STRING_MAX INT_MAX + + +/* Definitions for arrays. */ + +#define BC_DIM_MAX 65535 /* this should be NODE_SIZE^NODE_DEPTH-1 */ + +#define NODE_SIZE 16 /* Must be a power of 2. */ +#define NODE_MASK 0xf /* Must be NODE_SIZE-1. */ +#define NODE_SHIFT 4 /* Number of 1 bits in NODE_MASK. */ +#define NODE_DEPTH 4 + + +/* Other BC limits defined but not part of POSIX. */ + +#define BC_LABEL_GROUP 64 +#define BC_LABEL_LOG 6 +#define BC_START_SIZE 1024 /* Initial code body size. */ + +/* Maximum number of variables, arrays and functions and the + allocation increment for the dynamic arrays. */ + +#define MAX_STORE 32767 +#define STORE_INCR 32 + +/* Other interesting constants. */ + +#define FALSE 0 +#define TRUE 1 + +/* for use with lookup (). */ +#define SIMPLE 0 +#define ARRAY 1 +#define FUNCT 2 +#define FUNCTDEF 3 + +#define EXTERN extern +#ifdef __STDC__ +#define CONST const +#define VOID void +#else +#define CONST +#define VOID +#endif diff --git a/contrib/bc/bc/execute.c b/contrib/bc/bc/execute.c index c8f3df2..d2864d11 100644 --- a/contrib/bc/bc/execute.c +++ b/contrib/bc/bc/execute.c @@ -1,7 +1,7 @@ /* execute.c - run a bc program. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -52,11 +54,7 @@ unsigned char byte (pc) program_counter *pc; { - int seg, offset; - - seg = pc->pc_addr >> BC_SEG_LOG; - offset = pc->pc_addr++ % BC_SEG_SIZE; - return (functions[pc->pc_func].f_body[seg][offset]); + return (functions[pc->pc_func].f_body[pc->pc_addr++]); } @@ -81,7 +79,7 @@ execute () pc.pc_func = 0; pc.pc_addr = 0; runtime_error = FALSE; - init_num (&temp_num); + bc_init_num (&temp_num); /* Set up the interrupt mechanism for an interactive session. */ if (interactive) @@ -105,11 +103,12 @@ execute () depth = 1; while (temp != NULL) { - printf (" %d = ", depth); - out_num (temp->s_num, 10, out_char); + printf (" %d = ", depth); + bc_out_num (temp->s_num, 10, out_char, std_only); depth++; temp = temp->s_next; } + out_char ('\n'); } } #endif @@ -120,13 +119,13 @@ execute () case 'A' : /* increment array variable (Add one). */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); incr_array (var_name); break; case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */ case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */ - c_code = !is_zero (ex_stack->s_num); + c_code = !bc_is_zero (ex_stack->s_num); pop (); case 'J' : /* Jump to a label. */ label_num = byte(&pc); /* Low order bits first. */ @@ -145,7 +144,7 @@ execute () /* Get the function number. */ new_func = byte(&pc); if ((new_func & 0x80) != 0) - new_func = ((new_func << 8) & 0x7f) + byte(&pc); + new_func = ((new_func & 0x7f) << 8) + byte(&pc); /* Check to make sure it is defined. */ if (!functions[new_func].f_defined) @@ -192,14 +191,14 @@ execute () case 'L' : /* load array variable */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); load_array (var_name); break; case 'M' : /* decrement array variable (Minus!) */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); decr_array (var_name); break; @@ -245,18 +244,18 @@ execute () case 'S' : /* store array variable */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f ) << 8) + byte(&pc); store_array (var_name); break; case 'T' : /* Test tos for zero */ - c_code = is_zero (ex_stack->s_num); + c_code = bc_is_zero (ex_stack->s_num); assign (c_code); break; case 'W' : /* Write the value on the top of the stack. */ case 'P' : /* Write the value on the top of the stack. No newline. */ - out_num (ex_stack->s_num, o_base, out_char); + bc_out_num (ex_stack->s_num, o_base, out_char, std_only); if (inst == 'W') out_char ('\n'); store_var (4); /* Special variable "last". */ fflush (stdout); @@ -273,14 +272,14 @@ execute () if (ex_stack->s_num->n_len == 1 && ex_stack->s_num->n_scale != 0 && ex_stack->s_num->n_value[0] == 0 ) - int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); + bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); else - int2num (&ex_stack->s_num, ex_stack->s_num->n_len + bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_len + ex_stack->s_num->n_scale); break; case 'S': /* Scale function. */ - int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); + bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); break; case 'R': /* Square Root function. */ @@ -297,7 +296,7 @@ execute () case 'd' : /* Decrement number */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); decr_var (var_name); break; @@ -307,14 +306,14 @@ execute () case 'i' : /* increment number */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); incr_var (var_name); break; case 'l' : /* load variable */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); load_var (var_name); break; @@ -329,7 +328,7 @@ execute () case 's' : /* store variable */ var_name = byte(&pc); if ((var_name & 0x80) != 0) - var_name = ((var_name << 8) & 0x7f) + byte(&pc); + var_name = ((var_name & 0x7f) << 8) + byte(&pc); store_var (var_name); break; @@ -355,15 +354,15 @@ execute () break; case '!' : /* Negate the boolean value on top of the stack. */ - c_code = is_zero (ex_stack->s_num); + c_code = bc_is_zero (ex_stack->s_num); assign (c_code); break; case '&' : /* compare greater than */ if (check_stack(2)) { - c_code = !is_zero (ex_stack->s_next->s_num) - && !is_zero (ex_stack->s_num); + c_code = !bc_is_zero (ex_stack->s_next->s_num) + && !bc_is_zero (ex_stack->s_num); pop (); assign (c_code); } @@ -372,8 +371,8 @@ execute () case '|' : /* compare greater than */ if (check_stack(2)) { - c_code = !is_zero (ex_stack->s_next->s_num) - || !is_zero (ex_stack->s_num); + c_code = !bc_is_zero (ex_stack->s_next->s_num) + || !bc_is_zero (ex_stack->s_num); pop (); assign (c_code); } @@ -386,7 +385,7 @@ execute () pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } break; @@ -397,7 +396,7 @@ execute () pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } break; @@ -409,7 +408,7 @@ execute () pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } break; @@ -422,7 +421,7 @@ execute () pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } else rt_error ("Divide by zero"); @@ -432,7 +431,7 @@ execute () case '%' : /* remainder */ if (check_stack(2)) { - if (is_zero (ex_stack->s_num)) + if (bc_is_zero (ex_stack->s_num)) rt_error ("Modulo by zero"); else { @@ -441,7 +440,7 @@ execute () pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } } break; @@ -451,12 +450,12 @@ execute () { bc_raise (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, scale); - if (is_zero (ex_stack->s_next->s_num) && is_neg (ex_stack->s_num)) + if (bc_is_zero (ex_stack->s_next->s_num) && bc_is_neg (ex_stack->s_num)) rt_error ("divide by zero"); pop(); pop(); push_num (temp_num); - init_num (&temp_num); + bc_init_num (&temp_num); } break; @@ -578,7 +577,7 @@ input_char () } /* Classify and preprocess the input character. */ - if (isdigit(in_ch)) + if (isdigit((int)in_ch)) return (in_ch - '0'); if (in_ch >= 'A' && in_ch <= 'F') return (in_ch + 10 - 'A'); @@ -608,14 +607,14 @@ push_constant (in_char, conv_base) char negative; /* Initialize all bc numbers */ - init_num (&temp); - init_num (&result); - init_num (&mult); - build = copy_num (_zero_); + bc_init_num (&temp); + bc_init_num (&result); + bc_init_num (&mult); + build = bc_copy_num (_zero_); negative = FALSE; /* The conversion base. */ - int2num (&mult, conv_base); + bc_int2num (&mult, conv_base); /* Get things ready. */ in_ch = in_char(); @@ -638,7 +637,7 @@ push_constant (in_char, conv_base) in_ch = in_char(); if (in_ch < 16 && first_ch >= conv_base) first_ch = conv_base - 1; - int2num (&build, (int) first_ch); + bc_int2num (&build, (int) first_ch); } /* Convert the integer part. */ @@ -646,7 +645,7 @@ push_constant (in_char, conv_base) { if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; bc_multiply (build, mult, &result, 0); - int2num (&temp, (int) in_ch); + bc_int2num (&temp, (int) in_ch); bc_add (result, temp, &build, 0); in_ch = in_char(); } @@ -654,15 +653,15 @@ push_constant (in_char, conv_base) { in_ch = in_char(); if (in_ch >= conv_base) in_ch = conv_base-1; - free_num (&result); - free_num (&temp); - divisor = copy_num (_one_); - result = copy_num (_zero_); + bc_free_num (&result); + bc_free_num (&temp); + divisor = bc_copy_num (_one_); + result = bc_copy_num (_zero_); digits = 0; while (in_ch < 16) { bc_multiply (result, mult, &result, 0); - int2num (&temp, (int) in_ch); + bc_int2num (&temp, (int) in_ch); bc_add (result, temp, &result, 0); bc_multiply (divisor, mult, &divisor, 0); digits++; @@ -678,9 +677,9 @@ push_constant (in_char, conv_base) bc_sub (_zero_, build, &build, 0); push_num (build); - free_num (&temp); - free_num (&result); - free_num (&mult); + bc_free_num (&temp); + bc_free_num (&result); + bc_free_num (&mult); } @@ -738,8 +737,8 @@ push_b10_const (pc) } if (inchar > 9) { - init_num (&build); - int2num (&build, inchar); + bc_init_num (&build); + bc_int2num (&build, inchar); push_num (build); inchar = byte(pc); return; @@ -749,23 +748,25 @@ push_b10_const (pc) /* Build the new number. */ if (kdigits == 0) { - build = new_num (1,kscale); + build = bc_new_num (1,kscale); ptr = build->n_value; *ptr++ = 0; } else { - build = new_num (kdigits,kscale); + build = bc_new_num (kdigits,kscale); ptr = build->n_value; } while (inchar != ':') { if (inchar != '.') - if (inchar > 9) - *ptr++ = 9; - else - *ptr++ = inchar; + { + if (inchar > 9) + *ptr++ = 9; + else + *ptr++ = inchar; + } inchar = byte(pc); } push_num (build); @@ -778,9 +779,10 @@ void assign (c_code) char c_code; { - free_num (&ex_stack->s_num); + bc_free_num (&ex_stack->s_num); if (c_code) - ex_stack->s_num = copy_num (_one_); + ex_stack->s_num = bc_copy_num (_one_); else - ex_stack->s_num = copy_num (_zero_); + ex_stack->s_num = bc_copy_num (_zero_); } + diff --git a/contrib/bc/bc/fix-libmath_h b/contrib/bc/bc/fix-libmath_h index 5a002c4..f973a8c 100755 --- a/contrib/bc/bc/fix-libmath_h +++ b/contrib/bc/bc/fix-libmath_h @@ -1,8 +1,9 @@ ed libmath.h <<EOS-EOS -1,1s/^/"/ -1,\$s/\$/\\\\/ +1,1s/^/{"/ +1,\$s/\$/",/ +2,\$s/^/"/ \$,\$d -\$,\$s/\\\\\$/"/ +\$,\$s/,\$/,0}/ w q EOS-EOS diff --git a/contrib/bc/bc/global.c b/contrib/bc/bc/global.c index 3165434..5d1205c 100644 --- a/contrib/bc/bc/global.c +++ b/contrib/bc/bc/global.c @@ -1,7 +1,7 @@ /* global.c: This defines the global variables. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -35,8 +37,6 @@ /* Define all the global variables for bc. */ #include "global.h" -#ifndef BC_MATH_FILE -CONST char libmath[] = +CONST char *libmath[] = #include "libmath.h" ; -#endif diff --git a/contrib/bc/bc/global.h b/contrib/bc/bc/global.h new file mode 100644 index 0000000..cf6945c --- /dev/null +++ b/contrib/bc/bc/global.h @@ -0,0 +1,154 @@ +/* global.h: The global variables for bc. */ + +/* This file is part of GNU bc. + Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + + This program 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 of the License , or + (at your option) any later version. + + This program 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 this program; see the file COPYING. If not, write to + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA + + You may contact the author by: + e-mail: philnelson@acm.org + us-mail: Philip A. Nelson + Computer Science Department, 9062 + Western Washington University + Bellingham, WA 98226-9062 + +*************************************************************************/ + + +/* The current break level's lable. */ +EXTERN int break_label; + +/* The current if statement's else label or label after else. */ +EXTERN int if_label; + +/* The current for statement label for continuing the loop. */ +EXTERN int continue_label; + +/* Next available label number. */ +EXTERN int next_label; + +/* Byte code character storage. Used in many places for generation of code. */ +EXTERN char genstr[80]; + +/* Count of characters printed to the output in compile_only mode. */ +EXTERN int out_count; + +/* Have we generated any code since the last initialization of the code + generator. */ +EXTERN char did_gen; + +/* Is this run an interactive execution. (Is stdin a terminal?) */ +EXTERN char interactive; + +/* Just generate the byte code. -c flag. */ +EXTERN int compile_only; + +/* Load the standard math functions. -l flag. */ +EXTERN int use_math; + +/* Give a warning on use of any non-standard feature (non-POSIX). -w flag. */ +EXTERN int warn_not_std; + +/* Accept POSIX bc only! -s flag. */ +EXTERN int std_only; + +/* Don't print the banner at start up. -q flag. */ +EXTERN int quiet; + +/* The list of file names to process. */ +EXTERN file_node *file_names; + +/* The name of the current file being processed. */ +EXTERN char *file_name; + +/* Is the current file a named file or standard input? */ +EXTERN char is_std_in; + +/* global variables for the bc machine. All will be dynamic in size.*/ +/* Function storage. main is (0) and functions (1-f_count) */ + +EXTERN bc_function *functions; +EXTERN char **f_names; +EXTERN int f_count; + +/* Variable stoarge and reverse names. */ + +EXTERN bc_var **variables; +EXTERN char **v_names; +EXTERN int v_count; + +/* Array Variable storage and reverse names. */ + +EXTERN bc_var_array **arrays; +EXTERN char **a_names; +EXTERN int a_count; + +/* Execution stack. */ +EXTERN estack_rec *ex_stack; + +/* Function return stack. */ +EXTERN fstack_rec *fn_stack; + +/* Current ibase, obase, scale, and n_history (if needed). */ +EXTERN int i_base; +EXTERN int o_base; +EXTERN int scale; +#if defined(READLINE) || defined(LIBEDIT) +EXTERN int n_history; +#endif + +#if defined(LIBEDIT) +/* LIBEDIT data */ +EditLine *edit; +History *hist; +HistEvent histev; +#endif + +/* "Condition code" -- false (0) or true (1) */ +EXTERN char c_code; + +/* Records the number of the runtime error. */ +EXTERN char runtime_error; + +/* Holds the current location of execution. */ +EXTERN program_counter pc; + +/* For POSIX bc, this is just for number output, not strings. */ +EXTERN int out_col; + +/* Keeps track of the current number of characters per output line. + This includes the \n at the end of the line. */ +EXTERN int line_size; + +/* Input Line numbers and other error information. */ +EXTERN int line_no; +EXTERN int had_error; + +/* For larger identifiers, a tree, and how many "storage" locations + have been allocated. */ + +EXTERN int next_array; +EXTERN int next_func; +EXTERN int next_var; + +EXTERN id_rec *name_tree; + +/* For use with getopt. Do not declare them here.*/ +extern int optind; + +/* Access to the yy input file. Defined in scan.c. */ +extern FILE *yyin; diff --git a/contrib/bc/bc/libmath.b b/contrib/bc/bc/libmath.b index 7549a57..7bb6405 100644 --- a/contrib/bc/bc/libmath.b +++ b/contrib/bc/bc/libmath.b @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -158,10 +160,11 @@ define s(x) { /* Cosine : cos(x) = sin(x+pi/2) */ define c(x) { - auto v; - scale += 1; + auto v, z; + z = scale; + scale = scale*1.2; v = s(x+a(1)*2); - scale -= 1; + scale = z; return (v/1); } @@ -244,7 +247,7 @@ define a(x) { - x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... ) */ define j(n,x) { - auto a, d, e, f, i, m, s, v, z + auto a, b, d, e, f, i, m, s, v, z /* Make n an integer and check for negative n. */ z = scale; @@ -255,6 +258,10 @@ define j(n,x) { if (n%2 == 1) m = 1; } + /* save ibase */ + b = ibase; + ibase = A; + /* Compute the factor of x^n/(2^n*n!) */ f = 1; for (i=2; i<=n; i++) f = f*i; @@ -264,12 +271,13 @@ define j(n,x) { /* Initialize the loop .*/ v = e = 1; s = -x*x/4 - scale = 1.5*z + scale = 1.5*z + length(f) - scale(f); /* The Loop.... */ for (i=1; 1; i++) { e = e * s / i / (n+i); if (e == 0) { + ibase = b; scale = z if (m) return (-f*v/1); return (f*v/1); diff --git a/contrib/bc/bc/libmath.h b/contrib/bc/bc/libmath.h index 9481bb9..bf48f4b 100644 --- a/contrib/bc/bc/libmath.h +++ b/contrib/bc/bc/libmath.h @@ -1,40 +1,40 @@ -"@iK20:s2:p@r\ -@iF1,5.6,7,8,9,10,11,12,13,14[l5:0<Z1:1s11:pl5:ns5:pN1:l2:s14:\ -pK6:l14:+K.44:l5:*+s12:pl5:cS1+s2:pN2:l5:1>Z3:l9:1+s9:pl5:K2:\ -/s5:pl2:1+s2:pJ2:N3:l12:s2:p1l5:+s13:pl5:s6:p1s7:pK2:s10:pN5:\ -1B6:J4:N7:l10:i10:pJ5:N6:l6:l5:*s6:l7:l10:*s7:/s8:pl8:0=Z8:l9:\ -0>Z9:N10:l9:d9:Z11:l13:l13:*s13:pJ10:N11:N9:l14:s2:pl11:Z12:1\ -l13:/RN12:l13:1/RN8:l13:l8:+s13:pJ7:N4:0R]@r\ -@iF2,5.8,9,10,11,12,13,14[l5:0{Z1:1K10:l2:^-1/RN1:l2:s14:pK6:\ -l2:+s2:pK2:s9:p0s10:pN2:l5:K2:}Z3:l9:K2:*s9:pl5:cRs5:pJ2:N3:N4:\ -l5:K.5:{Z5:l9:K2:*s9:pl5:cRs5:pJ4:N5:l5:1-l5:1+/s12:s13:pl12:\ -l12:*s11:pK3:s10:pN7:1B8:J6:N9:l10:K2:+s10:pJ7:N8:l12:l11:*s12:\ -l10:/s8:pl8:0=Z10:l9:l13:*s13:pl14:s2:pl13:1/RN10:l13:l8:+s13:\ -pJ9:N6:0R]@r\ -@iF3,5.8,10,11,12,15,13,14[l2:s14:pK1.1:l14:*K2:+s2:p1C4,0:s13:\ -pl5:0<Z1:1s11:pl5:ns5:pN1:0s2:pl5:l13:/K2:+K4:/s12:pl5:K4:l12:\ -*l13:*-s5:pl12:K2:%Z2:l5:ns5:pN2:l14:K2:+s2:pl5:s8:s13:pl5:nl5:\ -*s15:pK3:s10:pN4:1B5:J3:N6:l10:K2:+s10:pJ4:N5:l8:l15:l10:l10:\ -1-*/*s8:pl8:0=Z7:l14:s2:pl11:Z8:l13:n1/RN8:l13:1/RN7:l13:l8:+\ -s13:pJ6:N3:0R]@r\ -@iF5,5.13[l2:1+s2:pl5:1C4,0:K2:*+C3,0:s13:pl2:1-s2:pl13:1/R0R]\ -@r\ -@iF4,5.6,8,9,10,11,12,15,13,14[1s11:pl5:0<Z1:1ns11:pl5:ns5:pN1:\ -l5:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l11:/RN3:l2:K40\ -:{Z4:K.7853981633974483096156608458198757210492:l11:/RN4:l2:K\ -60:{Z5:K.785398163397448309615660845819875721049292349843776455243736\ -:l11:/RN5:N2:l5:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497\ -:l11:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475\ -:l11:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688\ -:l11:/RN9:N6:l2:s14:pl5:K.2:>Z10:l14:K5:+s2:pK.2:C4,0:s6:pN10:\ -l14:K3:+s2:pN11:l5:K.2:>Z12:l9:1+s9:pl5:K.2:-1l5:K.2:*+/s5:pJ11:N12:\ -l5:s12:s13:pl5:nl5:*s15:pK3:s10:pN14:1B15:J13:N16:l10:K2:+s10:\ -pJ14:N15:l12:l15:*s12:l10:/s8:pl8:0=Z17:l14:s2:pl9:l6:*l13:+l11:\ -/RN17:l13:l8:+s13:pJ16:N13:0R]@r\ -@iF6,12,5.6,7,8,9,10,11,15,13,14[l2:s14:p0s2:pl12:1/s12:pl12:\ -0<Z1:l12:ns12:pl12:K2:%1=Z2:1s11:pN2:N1:1s9:pK2:s10:pN4:l10:l12:\ -{B5:J3:N6:l10:i10:pJ4:N5:l9:l10:*s9:pJ6:N3:K1.5:l14:*s2:pl5:l12:\ -^K2:l12:^/l9:/s9:p1s8:s13:pl5:nl5:*K4:/s15:pK1.5:l14:*s2:p1s10:\ -pN8:1B9:J7:N10:l10:i10:pJ8:N9:l8:l15:*l10:/l12:l10:+/s8:pl8:0\ -=Z11:l14:s2:pl11:Z12:l9:nl13:*1/RN12:l9:l13:*1/RN11:l13:l8:+s13:\ -pJ10:N7:0R]@r" +{"@iK20:s2:p@r", +"@iF1,5.6,7,8,9,10,11,12,13,14[l5:0<Z1:1s11:pl5:ns5:pN1:l2:s14:", +"pK6:l14:+K.44:l5:*+s12:pl5:cS1+s2:pN2:l5:1>Z3:l9:1+s9:pl5:K2:", +"/s5:pl2:1+s2:pJ2:N3:l12:s2:p1l5:+s13:pl5:s6:p1s7:pK2:s10:pN5:", +"1B6:J4:N7:l10:i10:pJ5:N6:l6:l5:*s6:l7:l10:*s7:/s8:pl8:0=Z8:l9:", +"0>Z9:N10:l9:d9:Z11:l13:l13:*s13:pJ10:N11:N9:l14:s2:pl11:Z12:1", +"l13:/RN12:l13:1/RN8:l13:l8:+s13:pJ7:N4:0R]@r", +"@iF2,5.8,9,10,11,12,13,14[l5:0{Z1:1K10:l2:^-1/RN1:l2:s14:pK6:", +"l2:+s2:pK2:s9:p0s10:pN2:l5:K2:}Z3:l9:K2:*s9:pl5:cRs5:pJ2:N3:N4:", +"l5:K.5:{Z5:l9:K2:*s9:pl5:cRs5:pJ4:N5:l5:1-l5:1+/s12:s13:pl12:", +"l12:*s11:pK3:s10:pN7:1B8:J6:N9:l10:K2:+s10:pJ7:N8:l12:l11:*s12:", +"l10:/s8:pl8:0=Z10:l9:l13:*s13:pl14:s2:pl13:1/RN10:l13:l8:+s13:", +"pJ9:N6:0R]@r", +"@iF3,5.8,10,11,12,15,13,14[l2:s14:pK1.1:l14:*K2:+s2:p1C4,0:s13:", +"pl5:0<Z1:1s11:pl5:ns5:pN1:0s2:pl5:l13:/K2:+K4:/s12:pl5:K4:l12:", +"*l13:*-s5:pl12:K2:%Z2:l5:ns5:pN2:l14:K2:+s2:pl5:s8:s13:pl5:nl5:", +"*s15:pK3:s10:pN4:1B5:J3:N6:l10:K2:+s10:pJ4:N5:l8:l15:l10:l10:", +"1-*/*s8:pl8:0=Z7:l14:s2:pl11:Z8:l13:n1/RN8:l13:1/RN7:l13:l8:+", +"s13:pJ6:N3:0R]@r", +"@iF5,5.13,14[l2:s14:pl2:K1.2:*s2:pl5:1C4,0:K2:*+C3,0:s13:pl14:", +"s2:pl13:1/R0R]@r", +"@iF4,5.6,8,9,10,11,12,15,13,14[1s11:pl5:0<Z1:1ns11:pl5:ns5:pN1:", +"l5:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l11:/RN3:l2:K40", +":{Z4:K.7853981633974483096156608458198757210492:l11:/RN4:l2:K", +"60:{Z5:K.785398163397448309615660845819875721049292349843776455243736", +":l11:/RN5:N2:l5:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497", +":l11:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475", +":l11:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688", +":l11:/RN9:N6:l2:s14:pl5:K.2:>Z10:l14:K5:+s2:pK.2:C4,0:s6:pN10:", +"l14:K3:+s2:pN11:l5:K.2:>Z12:l9:1+s9:pl5:K.2:-1l5:K.2:*+/s5:pJ11:N12:", +"l5:s12:s13:pl5:nl5:*s15:pK3:s10:pN14:1B15:J13:N16:l10:K2:+s10:", +"pJ14:N15:l12:l15:*s12:l10:/s8:pl8:0=Z17:l14:s2:pl9:l6:*l13:+l11:", +"/RN17:l13:l8:+s13:pJ16:N13:0R]@r", +"@iF6,12,5.6,16,7,8,9,10,11,15,13,14[l2:s14:p0s2:pl12:1/s12:pl12:", +"0<Z1:l12:ns12:pl12:K2:%1=Z2:1s11:pN2:N1:l0:s16:pKA:s0:p1s9:pK", +"2:s10:pN4:l10:l12:{B5:J3:N6:l10:i10:pJ4:N5:l9:l10:*s9:pJ6:N3:", +"K1.5:l14:*s2:pl5:l12:^K2:l12:^/l9:/s9:p1s8:s13:pl5:nl5:*K4:/s15:", +"pK1.5:l14:*l9:cL+l9:cS-s2:p1s10:pN8:1B9:J7:N10:l10:i10:pJ8:N9:", +"l8:l15:*l10:/l12:l10:+/s8:pl8:0=Z11:l16:s0:pl14:s2:pl11:Z12:l9:", +"nl13:*1/RN12:l9:l13:*1/RN11:l13:l8:+s13:pJ10:N7:0R]@r",0} diff --git a/contrib/bc/bc/load.c b/contrib/bc/bc/load.c index 055a7c0..40b8051 100644 --- a/contrib/bc/bc/load.c +++ b/contrib/bc/bc/load.c @@ -1,7 +1,7 @@ /* load.c: This code "loads" code into the code segments. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -52,28 +54,29 @@ void addbyte (byte) char byte; { - int seg, offset, func; + int pc; + bc_function *f; + char *new_body; /* If there was an error, don't continue. */ if (had_error) return; /* Calculate the segment and offset. */ - seg = load_adr.pc_addr >> BC_SEG_LOG; - offset = load_adr.pc_addr++ % BC_SEG_SIZE; - func = load_adr.pc_func; + pc = load_adr.pc_addr++; + f = &functions[load_adr.pc_func]; - if (seg >= BC_MAX_SEGS) + if (pc >= f->f_body_size) { - yyerror ("Function too big."); - return; + f->f_body_size *= 2; + new_body = (char *) bc_malloc (f->f_body_size); + memcpy(new_body, f->f_body, f->f_body_size/2); + free (f->f_body); + f->f_body = new_body; } - if (functions[func].f_body[seg] == NULL) - functions[func].f_body[seg] = (char *) bc_malloc (BC_SEG_SIZE); - /* Store the byte. */ - functions[func].f_body[seg][offset] = byte; - functions[func].f_code_size++; + f->f_body[pc] = byte; + f->f_code_size++; } @@ -132,7 +135,7 @@ long_val (str) neg = TRUE; (*str)++; } - while (isdigit(**str)) + while (isdigit((int)(**str))) val = val*10 + *(*str)++ - '0'; if (neg) @@ -216,8 +219,8 @@ load_code (code) fprintf (stderr,"Program too big.\n"); exit(1); } - addbyte ( (char) label_no & 0xFF); - addbyte ( (char) label_no >> 8); + addbyte ( (char) (label_no & 0xFF)); + addbyte ( (char) (label_no >> 8)); break; case 'F': /* A function, get the name and initialize it. */ @@ -286,7 +289,7 @@ load_code (code) addbyte ( (char) func); else { - addbyte ((func >> 8) & 0xff | 0x80); + addbyte (((func >> 8) & 0xff) | 0x80); addbyte (func & 0xff); } if (*str == ',') str++; @@ -319,7 +322,7 @@ load_code (code) addbyte (vaf_name); else { - addbyte ((vaf_name >> 8) & 0xff | 0x80); + addbyte (((vaf_name >> 8) & 0xff) | 0x80); addbyte (vaf_name & 0xff); } break; diff --git a/contrib/bc/bc/main.c b/contrib/bc/bc/main.c index 29a334f..1b9f6d2 100644 --- a/contrib/bc/bc/main.c +++ b/contrib/bc/bc/main.c @@ -1,7 +1,7 @@ /* main.c: The main program for bc. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -34,22 +36,17 @@ /* Variables for processing multiple files. */ -char first_file; -extern FILE *yyin; +static char first_file; /* Points to the last node in the file name list for easy adding. */ static file_node *last = NULL; -#ifdef READLINE -/* Readline support. */ -extern char *rl_readline_name; -extern FILE *rl_instream; -#endif - /* long option support */ static struct option long_options[] = { {"compile", 0, &compile_only, TRUE}, + {"help", 0, 0, 'h'}, + {"interactive", 0, 0, 'i'}, {"mathlib", 0, &use_math, TRUE}, {"quiet", 0, &quiet, TRUE}, {"standard", 0, &std_only, TRUE}, @@ -61,6 +58,20 @@ static struct option long_options[] = void +usage (char *progname) +{ + printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname, + " -h --help print this usage and exit\n", + " -i --interactive force interactive mode\n", + " -l --mathlib use the predefine math routnes\n", + " -q --quiet don't print initial banner\n", + " -s --standard non-standard bc constructs are errors\n", + " -w --warn warn about non-standard bc constructs\n", + " -v --version print version information and exit\n"); +} + + +void parse_args (argc, argv) int argc; char **argv; @@ -75,7 +86,7 @@ parse_args (argc, argv) /* Parse the command line */ while (1) { - optch = getopt_long (argc, argv, "lciqsvw", long_options, &long_index); + optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index); if (optch == EOF) /* End of arguments. */ break; @@ -86,14 +97,19 @@ parse_args (argc, argv) compile_only = TRUE; break; - case 'l': /* math lib */ - use_math = TRUE; + case 'h': /* help */ + usage(argv[0]); + exit (0); break; case 'i': /* force interactive */ interactive = TRUE; break; + case 'l': /* math lib */ + use_math = TRUE; + break; + case 'q': /* quiet mode */ quiet = TRUE; break; @@ -103,13 +119,17 @@ parse_args (argc, argv) break; case 'v': /* Print the version. */ - printf ("%s\n", BC_VERSION); + show_bc_version (); exit (0); break; case 'w': /* Non standard features give warnings. */ warn_not_std = TRUE; break; + + default: + usage(argv[0]); + exit (1); } } @@ -213,7 +233,20 @@ main (argc, argv) if (!open_new_file ()) exit (1); -#ifdef READLINE +#if defined(LIBEDIT) + if (interactive) { + /* Enable libedit support. */ + edit = el_init ("bc", stdin, stdout, stderr); + hist = history_init(); + el_set (edit, EL_EDITOR, "emacs"); + el_set (edit, EL_HIST, history, hist); + el_set (edit, EL_PROMPT, null_prompt); + el_source (edit, NULL); + history (hist, &histev, H_SETSIZE, INT_MAX); + } +#endif + +#if defined(READLINE) if (interactive) { /* Readline support. Set both application name and input file. */ rl_readline_name = "bc"; @@ -252,23 +285,9 @@ open_new_file () /* Open the other files. */ if (use_math && first_file) { -#ifdef BC_MATH_FILE - /* Make the first file be the math library. */ - new_file = fopen (BC_MATH_FILE, "r"); - use_math = FALSE; - if (new_file != NULL) - { - new_yy_file (new_file); - return TRUE; - } - else - { - fprintf (stderr, "Math Library unavailable.\n"); - exit (1); - } -#else /* Load the code from a precompiled version of the math libarary. */ - extern char libmath[]; + extern char *libmath[]; + char **mstr; char tmp; /* These MUST be in the order of first mention of each function. That is why "a" comes before "c" even though "a" is defined after @@ -279,8 +298,11 @@ open_new_file () tmp = lookup ("a", FUNCT); tmp = lookup ("c", FUNCT); tmp = lookup ("j", FUNCT); - load_code (libmath); -#endif + mstr = libmath; + while (*mstr) { + load_code (*mstr); + mstr++; + } } /* One of the argv values. */ diff --git a/contrib/bc/bc/proto.h b/contrib/bc/bc/proto.h new file mode 100644 index 0000000..1e7311f --- /dev/null +++ b/contrib/bc/bc/proto.h @@ -0,0 +1,148 @@ +/* proto.h: Prototype function definitions for "external" functions. */ + +/* This file is part of GNU bc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. + + This program 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 of the License , or + (at your option) any later version. + + This program 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 this program; see the file COPYING. If not, write to + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA + + You may contact the author by: + e-mail: philnelson@acm.org + us-mail: Philip A. Nelson + Computer Science Department, 9062 + Western Washington University + Bellingham, WA 98226-9062 + +*************************************************************************/ + +/* For the pc version using k&r ACK. (minix1.5 and earlier.) */ +#ifdef SHORTNAMES +#define init_numbers i_numbers +#define push_constant push__constant +#define load_const in_load_const +#define yy_get_next_buffer yyget_next_buffer +#define yy_init_buffer yyinit_buffer +#define yy_last_accepting_state yylast_accepting_state +#define arglist1 arg1list +#endif + +/* Include the standard library header files. */ +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +/* Define the _PROTOTYPE macro if it is needed. */ + +#ifndef _PROTOTYPE +#ifdef __STDC__ +#define _PROTOTYPE(func, args) func args +#else +#define _PROTOTYPE(func, args) func() +#endif +#endif + +/* From execute.c */ +_PROTOTYPE(void stop_execution, (int)); +_PROTOTYPE(unsigned char byte, (program_counter *pc)); +_PROTOTYPE(void execute, (void)); +_PROTOTYPE(char prog_char, (void)); +_PROTOTYPE(char input_char, (void)); +_PROTOTYPE(void push_constant, (char (*in_char)(void), int conv_base)); +_PROTOTYPE(void push_b10_const, (program_counter *pc)); +_PROTOTYPE(void assign, (int c_code)); + +/* From util.c */ +_PROTOTYPE(char *strcopyof, (char *str)); +_PROTOTYPE(arg_list *nextarg, (arg_list *args, int val, int is_var)); +_PROTOTYPE(char *arg_str, (arg_list *args)); +_PROTOTYPE(char *call_str, (arg_list *args)); +_PROTOTYPE(void free_args, (arg_list *args)); +_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos)); +_PROTOTYPE(void init_gen, (void)); +_PROTOTYPE(void generate, (char *str)); +_PROTOTYPE(void run_code, (void)); +_PROTOTYPE(void out_char, (int ch)); +_PROTOTYPE(void out_schar, (int ch)); +_PROTOTYPE(id_rec *find_id, (id_rec *tree, char *id)); +_PROTOTYPE(int insert_id_rec, (id_rec **root, id_rec *new_id)); +_PROTOTYPE(void init_tree, (void)); +_PROTOTYPE(int lookup, (char *name, int namekind)); +_PROTOTYPE(char *bc_malloc, (int)); +_PROTOTYPE(void out_of_memory, (void)); +_PROTOTYPE(void welcome, (void)); +_PROTOTYPE(void warranty, (char *)); +_PROTOTYPE(void show_bc_version, (void)); +_PROTOTYPE(void limits, (void)); +_PROTOTYPE(void yyerror, (char *str ,...)); +_PROTOTYPE(void warn, (char *mesg ,...)); +_PROTOTYPE(void rt_error, (char *mesg ,...)); +_PROTOTYPE(void rt_warn, (char *mesg ,...)); + +/* From load.c */ +_PROTOTYPE(void init_load, (void)); +_PROTOTYPE(void addbyte, (int byte)); +_PROTOTYPE(void def_label, (long lab)); +_PROTOTYPE(long long_val, (char **str)); +_PROTOTYPE(void load_code, (char *code)); + +/* From main.c */ +_PROTOTYPE(int open_new_file, (void)); +_PROTOTYPE(void new_yy_file, (FILE *file)); +_PROTOTYPE(void use_quit, (int)); + +/* From storage.c */ +_PROTOTYPE(void init_storage, (void)); +_PROTOTYPE(void more_functions, (void)); +_PROTOTYPE(void more_variables, (void)); +_PROTOTYPE(void more_arrays, (void)); +_PROTOTYPE(void clear_func, (int func )); +_PROTOTYPE(int fpop, (void)); +_PROTOTYPE(void fpush, (int val )); +_PROTOTYPE(void pop, (void)); +_PROTOTYPE(void push_copy, (bc_num num )); +_PROTOTYPE(void push_num, (bc_num num )); +_PROTOTYPE(char check_stack, (int depth )); +_PROTOTYPE(bc_var *get_var, (int var_name )); +_PROTOTYPE(bc_num *get_array_num, (int var_index, long index )); +_PROTOTYPE(void store_var, (int var_name )); +_PROTOTYPE(void store_array, (int var_name )); +_PROTOTYPE(void load_var, (int var_name )); +_PROTOTYPE(void load_array, (int var_name )); +_PROTOTYPE(void decr_var, (int var_name )); +_PROTOTYPE(void decr_array, (int var_name )); +_PROTOTYPE(void incr_var, (int var_name )); +_PROTOTYPE(void incr_array, (int var_name )); +_PROTOTYPE(void auto_var, (int name )); +_PROTOTYPE(void free_a_tree, (bc_array_node *root, int depth )); +_PROTOTYPE(void pop_vars, (arg_list *list )); +_PROTOTYPE(void process_params, (program_counter *pc, int func )); + +/* For the scanner and parser.... */ +_PROTOTYPE(int yyparse, (void)); +_PROTOTYPE(int yylex, (void)); + +#if defined(LIBEDIT) +/* The *?*&^ prompt function */ +_PROTOTYPE(char *null_prompt, (EditLine *)); +#endif + +/* Other things... */ +#ifndef HAVE_UNISTD_H +_PROTOTYPE (int getopt, (int, char *[], CONST char *)); +#endif diff --git a/contrib/bc/bc/sbc.y b/contrib/bc/bc/sbc.y index 9e1bd33..b1ff1d1 100644 --- a/contrib/bc/bc/sbc.y +++ b/contrib/bc/bc/sbc.y @@ -16,10 +16,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -41,7 +43,7 @@ arg_list *a_value; } -%token <i_value> NEWLINE AND OR NOT +%token <i_value> ENDOFLINE AND OR NOT %token <s_value> STRING NAME NUMBER /* '-', '+' are tokens themselves */ %token <c_value> ASSIGN_OP @@ -88,11 +90,11 @@ program : /* empty */ } | program input_item ; -input_item : semicolon_list NEWLINE +input_item : semicolon_list ENDOFLINE { run_code(); } | function { run_code(); } - | error NEWLINE + | error ENDOFLINE { yyerrok; init_gen() ; @@ -107,8 +109,8 @@ semicolon_list : /* empty */ statement_list : /* empty */ { $$ = 0; } | statement - | statement_list NEWLINE - | statement_list NEWLINE statement + | statement_list ENDOFLINE + | statement_list ENDOFLINE statement | statement_list ';' | statement_list ';' statement ; @@ -214,7 +216,7 @@ statement : Warranty { $$ = 0; } ; function : Define NAME '(' opt_parameter_list ')' '{' - NEWLINE opt_auto_define_list + ENDOFLINE opt_auto_define_list { check_params ($4,$8); sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT), @@ -225,7 +227,7 @@ function : Define NAME '(' opt_parameter_list ')' '{' $1 = next_label; next_label = 0; } - statement_list NEWLINE '}' + statement_list ENDOFLINE '}' { generate ("0R]"); next_label = $1; @@ -242,7 +244,7 @@ parameter_list : NAME ; opt_auto_define_list : /* empty */ { $$ = NULL; } - | Auto define_list NEWLINE + | Auto define_list ENDOFLINE { $$ = $2; } | Auto define_list ';' { $$ = $2; } diff --git a/contrib/bc/bc/scan.l b/contrib/bc/bc/scan.l index 8b5b25d..b4addaa 100644 --- a/contrib/bc/bc/scan.l +++ b/contrib/bc/bc/scan.l @@ -16,10 +16,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -48,6 +50,83 @@ #undef yywrap _PROTOTYPE(int yywrap, (void)); +#if defined(LIBEDIT) +/* Support for the BSD libedit with history for + nicer input on the interactive part of input. */ + +#include <histedit.h> + +/* Have input call the following function. */ +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + bcel_input((char *)buf, &result, max_size) + +/* Variables to help interface editline with bc. */ +static const char *bcel_line = (char *)NULL; +static int bcel_len = 0; + + +/* Required to get rid of that ugly ? default prompt! */ +char * +null_prompt (EditLine *el) +{ + return ""; +} + + +/* bcel_input puts upto MAX characters into BUF with the number put in + BUF placed in *RESULT. If the yy input file is the same as + stdin, use editline. Otherwise, just read it. +*/ + +static void +bcel_input (buf, result, max) + char *buf; + int *result; + int max; +{ + if (!edit || yyin != stdin) + { + while ( (*result = read( fileno(yyin), buf, max )) < 0 ) + if (errno != EINTR) + { + yyerror( "read() in flex scanner failed" ); + exit (1); + } + return; + } + + /* Do we need a new string? */ + if (bcel_len == 0) + { + bcel_line = el_gets(edit, &bcel_len); + if (bcel_line == NULL) { + /* end of file */ + *result = 0; + bcel_len = 0; + return; + } + if (bcel_len != 0) + history (hist, &histev, H_ENTER, bcel_line); + fflush (stdout); + } + + if (bcel_len <= max) + { + strncpy (buf, bcel_line, bcel_len); + *result = bcel_len; + bcel_len = 0; + } + else + { + strncpy (buf, bcel_line, max); + *result = max; + bcel_line += max; + bcel_len -= max; + } +} +#endif + #ifdef READLINE /* Support for the readline and history libraries. This allows nicer input on the interactive part of input. */ @@ -60,15 +139,12 @@ _PROTOTYPE(int yywrap, (void)); /* Variables to help interface readline with bc. */ static char *rl_line = (char *)NULL; static char *rl_start = (char *)NULL; -static char rl_len = 0; +static int rl_len = 0; /* Definitions for readline access. */ extern FILE *rl_instream; _PROTOTYPE(char *readline, (char *)); -/* Needed here? */ -extern FILE *yyin; - /* rl_input puts upto MAX characters into BUF with the number put in BUF placed in *RESULT. If the yy input file is the same as rl_instream (stdin), use readline. Otherwise, just read it. @@ -94,20 +170,20 @@ rl_input (buf, result, max) /* Do we need a new string? */ if (rl_len == 0) { - if (rl_line) - free(rl_line); - rl_line = readline (""); - if (rl_line == NULL) { + if (rl_start) + free(rl_start); + rl_start = readline (""); + if (rl_start == NULL) { /* end of file */ *result = 0; rl_len = 0; return; } + rl_line = rl_start; rl_len = strlen (rl_line)+1; if (rl_len != 1) add_history (rl_line); rl_line[rl_len-1] = '\n'; - printf ("\r"); fflush (stdout); } @@ -121,10 +197,14 @@ rl_input (buf, result, max) { strncpy (buf, rl_line, max); *result = max; + rl_line += max; rl_len -= max; } } -#else +#endif + +#if !defined(READLINE) && !defined(LIBEDIT) + /* MINIX returns from read with < 0 if SIGINT is encountered. In flex, we can redefine YY_INPUT to the following. In lex, this does nothing! */ @@ -134,6 +214,7 @@ rl_input (buf, result, max) if (errno != EINTR) \ YY_FATAL_ERROR( "read() in flex scanner failed" ); #endif + %} DIGIT [0-9A-F] LETTER [a-z] @@ -146,7 +227,7 @@ LETTER [a-z] yyerror ("illegal character: #"); } <slcomment>[^\n]* { BEGIN(INITIAL); } -<slcomment>"\n" { line_no++; BEGIN(INITIAL); return(NEWLINE); } +<slcomment>"\n" { line_no++; BEGIN(INITIAL); return(ENDOFLINE); } define return(Define); break return(Break); quit return(Quit); @@ -165,8 +246,8 @@ read return(Read); halt return(Halt); last return(Last); history { -#ifdef READLINE - return(History); +#if defined(READLINE) || defined(LIBEDIT) + return(HistoryVar); #else yylval.s_value = strcopyof(yytext); return(NAME); #endif @@ -206,7 +287,7 @@ limits return(Limits); } ==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); } \+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); } -"\n" { line_no++; return(NEWLINE); } +"\n" { line_no++; return(ENDOFLINE); } \\\n { line_no++; /* ignore a "quoted" newline */ } [ \t]+ { /* ignore spaces and tabs */ } "/*" { @@ -275,7 +356,7 @@ limits return(Limits); yyerror ("illegal character: ^%c",yytext[0] + '@'); else if (yytext[0] > '~') - yyerror ("illegal character: \\%3d", (int) yytext[0]); + yyerror ("illegal character: \\%03o", (int) yytext[0]); else yyerror ("illegal character: %s",yytext); } diff --git a/contrib/bc/bc/storage.c b/contrib/bc/bc/storage.c index 781fe96..10ebf5c 100644 --- a/contrib/bc/bc/storage.c +++ b/contrib/bc/bc/storage.c @@ -1,7 +1,7 @@ /* storage.c: Code and data storage manipulations. This includes labels. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -56,11 +58,11 @@ init_storage () i_base = 10; o_base = 10; scale = 0; -#ifdef READLINE - n_history = -1; /* no limit. */ +#if defined(READLINE) || defined(LIBEDIT) + n_history = -1; #endif c_code = FALSE; - init_numbers(); + bc_init_numbers(); } /* Three functions for increasing the number of functions, variables, or @@ -70,7 +72,7 @@ void more_functions (VOID) { int old_count; - int indx1, indx2; + int indx; bc_function *old_f; bc_function *f; char **old_names; @@ -86,19 +88,19 @@ more_functions (VOID) f_names = (char **) bc_malloc (f_count*sizeof (char *)); /* Copy old ones. */ - for (indx1 = 0; indx1 < old_count; indx1++) + for (indx = 0; indx < old_count; indx++) { - functions[indx1] = old_f[indx1]; - f_names[indx1] = old_names[indx1]; + functions[indx] = old_f[indx]; + f_names[indx] = old_names[indx]; } /* Initialize the new ones. */ - for (; indx1 < f_count; indx1++) + for (; indx < f_count; indx++) { - f = &functions[indx1]; + f = &functions[indx]; f->f_defined = FALSE; - for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++) - f->f_body [indx2] = NULL; + f->f_body = (char *) bc_malloc (BC_START_SIZE); + f->f_body_size = BC_START_SIZE; f->f_code_size = 0; f->f_label = NULL; f->f_autos = NULL; @@ -187,26 +189,15 @@ more_arrays () void clear_func (func) - char func; + int func; { bc_function *f; - int indx; bc_label_group *lg; /* Set the pointer to the function. */ f = &functions[func]; f->f_defined = FALSE; - - /* Clear the code segments. */ - for (indx = 0; indx < BC_MAX_SEGS; indx++) - { - if (f->f_body[indx] != NULL) - { - free (f->f_body[indx]); - f->f_body[indx] = NULL; - } - } - + /* XXX restore f_body to initial size??? */ f->f_code_size = 0; if (f->f_autos != NULL) { @@ -242,6 +233,11 @@ fpop() retval = temp->s_val; free (temp); } + else + { + retval = 0; + rt_error ("function stack underflow, contact maintainer."); + } return (retval); } @@ -272,7 +268,7 @@ pop () { temp = ex_stack; ex_stack = temp->s_next; - free_num (&temp->s_num); + bc_free_num (&temp->s_num); free (temp); } } @@ -287,7 +283,7 @@ push_copy (num) estack_rec *temp; temp = (estack_rec *) bc_malloc (sizeof (estack_rec)); - temp->s_num = copy_num (num); + temp->s_num = bc_copy_num (num); temp->s_next = ex_stack; ex_stack = temp; } @@ -349,7 +345,7 @@ get_var (var_name) if (var_ptr == NULL) { var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var)); - init_num (&var_ptr->v_value); + bc_init_num (&var_ptr->v_value); } return var_ptr; } @@ -414,7 +410,7 @@ get_array_num (var_index, index) else { for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_num[ix] = copy_num(_zero_); + temp->n_items.n_num[ix] = bc_copy_num(_zero_); } a_var->a_tree = temp; a_var->a_depth++; @@ -435,7 +431,7 @@ get_array_num (var_index, index) temp->n_items.n_down[ix] = NULL; else for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_num[ix] = copy_num(_zero_); + temp->n_items.n_num[ix] = bc_copy_num(_zero_); } else temp = temp->n_items.n_down[ix1]; @@ -463,15 +459,16 @@ store_var (var_name) var_ptr = get_var (var_name); if (var_ptr != NULL) { - free_num(&var_ptr->v_value); - var_ptr->v_value = copy_num (ex_stack->s_num); + bc_free_num(&var_ptr->v_value); + var_ptr->v_value = bc_copy_num (ex_stack->s_num); } } else { /* It is a special variable... */ toobig = FALSE; - if (is_neg (ex_stack->s_num)) + temp = 0; + if (bc_is_neg (ex_stack->s_num)) { switch (var_name) { @@ -487,7 +484,7 @@ store_var (var_name) rt_warn ("negative scale, set to 0"); temp = 0; break; -#ifdef READLINE +#if defined(READLINE) || defined(LIBEDIT) case 3: temp = -1; break; @@ -496,8 +493,8 @@ store_var (var_name) } else { - temp = num2long (ex_stack->s_num); - if (!is_zero (ex_stack->s_num) && temp == 0) + temp = bc_num2long (ex_stack->s_num); + if (!bc_is_zero (ex_stack->s_num) && temp == 0) toobig = TRUE; } switch (var_name) @@ -546,21 +543,21 @@ store_var (var_name) scale = (int) temp; break; -#ifdef READLINE +#if defined(READLINE) || defined(LIBEDIT) case 3: if (toobig) { temp = -1; rt_warn ("history too large, set to unlimited"); - unstifle_history (); + UNLIMIT_HISTORY; } else { n_history = temp; - if (temp == -1) - unstifle_history (); + if (temp < 0) + UNLIMIT_HISTORY; else - stifle_history (n_history); + HISTORY_SIZE(n_history); } #endif } @@ -580,20 +577,20 @@ store_array (var_name) long index; if (!check_stack(2)) return; - index = num2long (ex_stack->s_next->s_num); + index = bc_num2long (ex_stack->s_next->s_num); if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero(ex_stack->s_next->s_num))) + (index == 0 && !bc_is_zero(ex_stack->s_next->s_num))) rt_error ("Array %s subscript out of bounds.", a_names[var_name]); else { num_ptr = get_array_num (var_name, index); if (num_ptr != NULL) { - free_num (num_ptr); - *num_ptr = copy_num (ex_stack->s_num); - free_num (&ex_stack->s_next->s_num); + bc_free_num (num_ptr); + *num_ptr = bc_copy_num (ex_stack->s_num); + bc_free_num (&ex_stack->s_next->s_num); ex_stack->s_next->s_num = ex_stack->s_num; - init_num (&ex_stack->s_num); + bc_init_num (&ex_stack->s_num); pop(); } } @@ -615,26 +612,26 @@ load_var (var_name) case 0: /* Special variable ibase. */ push_copy (_zero_); - int2num (&ex_stack->s_num, i_base); + bc_int2num (&ex_stack->s_num, i_base); break; case 1: /* Special variable obase. */ push_copy (_zero_); - int2num (&ex_stack->s_num, o_base); + bc_int2num (&ex_stack->s_num, o_base); break; case 2: /* Special variable scale. */ push_copy (_zero_); - int2num (&ex_stack->s_num, scale); + bc_int2num (&ex_stack->s_num, scale); break; -#ifdef READLINE +#if defined(READLINE) || defined(LIBEDIT) case 3: /* Special variable history. */ push_copy (_zero_); - int2num (&ex_stack->s_num, n_history); + bc_int2num (&ex_stack->s_num, n_history); break; #endif @@ -660,9 +657,9 @@ load_array (var_name) long index; if (!check_stack(1)) return; - index = num2long (ex_stack->s_num); + index = bc_num2long (ex_stack->s_num); if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero(ex_stack->s_num))) + (index == 0 && !bc_is_zero(ex_stack->s_num))) rt_error ("Array %s subscript out of bounds.", a_names[var_name]); else { @@ -709,16 +706,16 @@ decr_var (var_name) rt_warn ("scale can not be negative in -- "); break; -#ifdef READLINE +#if defined(READLINE) || defined(LIBEDIT) case 3: /* history */ n_history--; - if (n_history > 0) - stifle_history (n_history); + if (n_history >= 0) + HISTORY_SIZE(n_history); else { n_history = -1; rt_warn ("history is negative, set to unlimited"); - unstifle_history (); + UNLIMIT_HISTORY; } #endif @@ -735,16 +732,16 @@ decr_var (var_name) void decr_array (var_name) - char var_name; + int var_name; { bc_num *num_ptr; long index; /* It is an array variable. */ if (!check_stack (1)) return; - index = num2long (ex_stack->s_num); + index = bc_num2long (ex_stack->s_num); if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero (ex_stack->s_num))) + (index == 0 && !bc_is_zero (ex_stack->s_num))) rt_error ("Array %s subscript out of bounds.", a_names[var_name]); else { @@ -791,16 +788,16 @@ incr_var (var_name) rt_warn ("Scale too big in ++"); break; -#ifdef READLINE +#if defined(READLINE) || defined(LIBEDIT) case 3: /* history */ n_history++; if (n_history > 0) - stifle_history (n_history); + HISTORY_SIZE(n_history); else { n_history = -1; rt_warn ("history set to unlimited"); - unstifle_history (); + UNLIMIT_HISTORY; } #endif @@ -824,9 +821,9 @@ incr_array (var_name) long index; if (!check_stack (1)) return; - index = num2long (ex_stack->s_num); + index = bc_num2long (ex_stack->s_num); if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !is_zero (ex_stack->s_num))) + (index == 0 && !bc_is_zero (ex_stack->s_num))) rt_error ("Array %s subscript out of bounds.", a_names[var_name]); else { @@ -858,7 +855,7 @@ auto_var (name) ix = name; v_temp = (bc_var *) bc_malloc (sizeof (bc_var)); v_temp->v_next = variables[ix]; - init_num (&v_temp->v_value); + bc_init_num (&v_temp->v_value); variables[ix] = v_temp; } else @@ -891,7 +888,7 @@ free_a_tree ( root, depth ) free_a_tree (root->n_items.n_down[ix], depth-1); else for (ix = 0; ix < NODE_SIZE; ix++) - free_num ( &(root->n_items.n_num[ix])); + bc_free_num ( &(root->n_items.n_num[ix])); free (root); } } @@ -918,7 +915,7 @@ pop_vars (list) if (v_temp != NULL) { variables[ix] = v_temp->v_next; - free_num (&v_temp->v_value); + bc_free_num (&v_temp->v_value); free (v_temp); } } @@ -962,7 +959,7 @@ copy_tree (ary_node, depth) else for (i=0; i<NODE_SIZE; i++) if (ary_node->n_items.n_num[i] != NULL) - res->n_items.n_num[i] = copy_num (ary_node->n_items.n_num[i]); + res->n_items.n_num[i] = bc_copy_num (ary_node->n_items.n_num[i]); else res->n_items.n_num[i] = NULL; return res; @@ -1013,7 +1010,7 @@ process_params (pc, func) v_temp = (bc_var *) bc_malloc (sizeof(bc_var)); v_temp->v_next = variables[ix]; v_temp->v_value = ex_stack->s_num; - init_num (&ex_stack->s_num); + bc_init_num (&ex_stack->s_num); variables[ix] = v_temp; } else @@ -1022,7 +1019,7 @@ process_params (pc, func) /* The variables is an array variable. */ /* Compute source index and make sure some structure exists. */ - ix = (int) num2long (ex_stack->s_num); + ix = (int) bc_num2long (ex_stack->s_num); n_temp = get_array_num (ix, 0); /* Push a new array and Compute Destination index */ diff --git a/contrib/bc/bc/util.c b/contrib/bc/bc/util.c index 514df26..c305c2e 100644 --- a/contrib/bc/bc/util.c +++ b/contrib/bc/bc/util.c @@ -1,7 +1,7 @@ /* util.c: Utility routines for bc. */ /* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. + Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,12 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111 USA You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -308,7 +310,7 @@ run_code() void out_char (ch) - char ch; + int ch; { if (ch == '\n') { @@ -335,7 +337,7 @@ out_char (ch) void out_schar (ch) - char ch; + int ch; { if (ch == '\n') { @@ -620,6 +622,10 @@ lookup (name, namekind) yyerror ("Too many variables"); exit (1); } + + yyerror ("End of util.c/lookup() reached. Please report this bug."); + exit (1); + /* not reached */ } @@ -632,6 +638,13 @@ welcome() printf ("For details type `warranty'. \n"); } +/* Print out the version information. */ +void +show_bc_version() +{ + printf("%s %s\n%s\n", PACKAGE, VERSION, BC_COPYRIGHT); +} + /* Print out the warranty information. */ @@ -639,19 +652,22 @@ void warranty(prefix) char *prefix; { - printf ("\n%s%s\n\n", prefix, BC_VERSION); - printf ("%s%s%s%s%s%s%s%s%s%s%s", -" This program is free software; you can redistribute it and/or modify\n", -" it under the terms of the GNU General Public License as published by\n", -" the Free Software Foundation; either version 2 of the License , or\n", -" (at your option) any later version.\n\n", -" This program is distributed in the hope that it will be useful,\n", -" but WITHOUT ANY WARRANTY; without even the implied warranty of\n", -" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", -" GNU General Public License for more details.\n\n", -" You should have received a copy of the GNU General Public License\n", -" along with this program. If not, write to the Free Software\n", -" Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n\n"); + printf ("\n%s", prefix); + show_bc_version (); + printf ("\n" +" This program is free software; you can redistribute it and/or modify\n" +" it under the terms of the GNU General Public License as published by\n" +" the Free Software Foundation; either version 2 of the License , or\n" +" (at your option) any later version.\n\n" +" This program is distributed in the hope that it will be useful,\n" +" but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +" GNU General Public License for more details.\n\n" +" You should have received a copy of the GNU General Public License\n" +" along with this program. If not, write to\n\n" +" The Free Software Foundation, Inc.\n" +" 59 Temple Place, Suite 330\n" +" Boston, MA 02111, USA.\n\n"); } /* Print out the limits of this program. */ @@ -664,8 +680,6 @@ limits() printf ("BC_SCALE_MAX = %d\n", BC_SCALE_MAX); printf ("BC_STRING_MAX = %d\n", BC_STRING_MAX); printf ("MAX Exponent = %ld\n", (long) LONG_MAX); - printf ("MAX code = %ld\n", (long) BC_MAX_SEGS * (long) BC_SEG_SIZE); - printf ("multiply digits = %ld\n", (long) LONG_MAX / (long) 90); printf ("Number of vars = %ld\n", (long) MAX_STORE); #ifdef OLD_EQ_OP printf ("Old assignment operatiors are valid. (=-, =+, ...)\n"); @@ -808,18 +822,18 @@ rt_error (mesg, va_alist) #endif { va_list args; - char error_mesg [255]; + fprintf (stderr, "Runtime error (func=%s, adr=%d): ", + f_names[pc.pc_func], pc.pc_addr); #ifndef VARARGS va_start (args, mesg); #else va_start (args); #endif - vsprintf (error_mesg, mesg, args); + vfprintf (stderr, mesg, args); va_end (args); - fprintf (stderr, "Runtime error (func=%s, adr=%d): %s\n", - f_names[pc.pc_func], pc.pc_addr, error_mesg); + fprintf (stderr, "\n"); runtime_error = TRUE; } @@ -844,16 +858,16 @@ rt_warn (mesg, va_alist) #endif { va_list args; - char error_mesg [255]; + fprintf (stderr, "Runtime warning (func=%s, adr=%d): ", + f_names[pc.pc_func], pc.pc_addr); #ifndef VARARGS va_start (args, mesg); #else va_start (args); #endif - vsprintf (error_mesg, mesg, args); + vfprintf (stderr, mesg, args); va_end (args); - fprintf (stderr, "Runtime warning (func=%s, adr=%d): %s\n", - f_names[pc.pc_func], pc.pc_addr, error_mesg); + fprintf (stderr, "\n"); } diff --git a/contrib/bc/config.h.in b/contrib/bc/config.h.in index 1f33161..ebb9e34 100644 --- a/contrib/bc/config.h.in +++ b/contrib/bc/config.h.in @@ -28,18 +28,21 @@ /* Define if lex declares yytext as a char * by default, not a char[]. */ #undef YYTEXT_POINTER -/* PACKAGE name */ -#undef PACKAGE +/* VERSION number for DC target*/ +#undef DC_VERSION -/* Package VERSION number */ -#undef VERSION +/* COPYRIGHT notice for DC target */ +#undef DC_COPYRIGHT -/* define if the math lib is to be loaded from a file. */ -#undef BC_MATH_FILE +/* COPYRIGHT notice for BC target */ +#undef BC_COPYRIGHT /* Define to use the readline library. */ #undef READLINE +/* Define to use the BSD libedit library. */ +#undef LIBEDIT + /* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */ #undef ptrdiff_t @@ -69,3 +72,10 @@ /* Define if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Version number of package */ +#undef VERSION + diff --git a/contrib/bc/configure b/contrib/bc/configure index dfe4aa2..e5fc7d9 100755 --- a/contrib/bc/configure +++ b/contrib/bc/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12 +# Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -12,6 +12,11 @@ ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help + --with-pkg use software installed in /usr/pkg tree" +ac_help="$ac_help + --with-libedit support fancy BSD command input +editing" +ac_help="$ac_help --with-readline support fancy command input editing" # Initialize some variables set by options. @@ -51,6 +56,7 @@ mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 @@ -334,7 +340,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12" + echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) @@ -504,9 +510,11 @@ ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross +ac_exeext= +ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then @@ -546,28 +554,30 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:554: checking for a BSD compatible install" >&5 +echo "configure:563: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" @@ -597,13 +607,12 @@ echo "$ac_t""$INSTALL" 1>&6 # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:607: checking whether build environment is sane" >&5 +echo "configure:616: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -660,7 +669,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:664: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:673: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -687,9 +696,9 @@ else fi -PACKAGE=bc +PACKAGE="bc" -VERSION=1.05 +VERSION="1.06" if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -706,7 +715,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:710: checking for working aclocal" >&5 +echo "configure:719: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -719,7 +728,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:723: checking for working autoconf" >&5 +echo "configure:732: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -732,7 +741,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:736: checking for working automake" >&5 +echo "configure:745: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -745,7 +754,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:749: checking for working autoheader" >&5 +echo "configure:758: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -758,7 +767,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:762: checking for working makeinfo" >&5 +echo "configure:771: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -775,18 +784,32 @@ fi +cat >> confdefs.h <<\EOF +#define DC_VERSION "1.3" +EOF + +cat >> confdefs.h <<EOF +#define BC_COPYRIGHT "Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc." +EOF + +cat >> confdefs.h <<EOF +#define DC_COPYRIGHT "Copyright 1994, 1997, 1998, 2000 Free Software Foundation, Inc." +EOF + + # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:782: checking for $ac_word" >&5 +echo "configure:804: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" @@ -807,16 +830,17 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:811: checking for $ac_word" >&5 +echo "configure:834: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no - for ac_dir in $PATH; do + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then @@ -851,25 +875,61 @@ else echo "$ac_t""no" 1>&6 fi + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:885: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:859: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:917: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross -cat > conftest.$ac_ext <<EOF -#line 869 "configure" +cat > conftest.$ac_ext << EOF + +#line 928 "configure" #include "confdefs.h" + main(){return(0);} EOF -if { (eval echo configure:873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -883,18 +943,24 @@ else ac_cv_prog_cc_works=no fi rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:893: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:959: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:898: checking whether we are using GNU C" >&5 +echo "configure:964: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -903,7 +969,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:907: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:973: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -914,11 +980,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:922: checking whether ${CC-cc} accepts -g" >&5 +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:992: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -933,20 +1003,24 @@ rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then CFLAGS="-g -O2" else - CFLAGS="-O2" + CFLAGS="-g" fi else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:950: checking how to run the C preprocessor" >&5 +echo "configure:1024: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -961,14 +1035,14 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF -#line 965 "configure" +#line 1039 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:971: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -978,14 +1052,31 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF -#line 982 "configure" +#line 1056 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 1073 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1079: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -998,6 +1089,8 @@ fi rm -f conftest* fi rm -f conftest* +fi +rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" @@ -1008,18 +1101,18 @@ echo "$ac_t""$CPP" 1>&6 ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6 -echo "configure:1012: checking for minix/config.h" >&5 +echo "configure:1105: checking for minix/config.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1017 "configure" +#line 1110 "configure" #include "confdefs.h" #include <minix/config.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1022: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1115: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1062,15 +1155,16 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1066: checking for $ac_word" >&5 +echo "configure:1159: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_LEX="$ac_prog" @@ -1094,15 +1188,16 @@ test -n "$LEX" || LEX=""$missing_dir/missing flex"" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1098: checking for $ac_word" >&5 +echo "configure:1192: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_LEX="flex" @@ -1127,7 +1222,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1131: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1226: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1135,7 +1230,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <<EOF -#line 1139 "configure" +#line 1234 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -1146,7 +1241,7 @@ int main() { yywrap() ; return 0; } EOF -if { (eval echo configure:1150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1169,7 +1264,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:1173: checking lex output file root" >&5 +echo "configure:1268: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1190,7 +1285,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:1194: checking whether yytext is a pointer" >&5 +echo "configure:1289: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1202,14 +1297,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <<EOF -#line 1206 "configure" +#line 1301 "configure" #include "confdefs.h" `cat $LEX_OUTPUT_ROOT.c` int main() { ; return 0; } EOF -if { (eval echo configure:1213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -1235,15 +1330,16 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1239: checking for $ac_word" >&5 +echo "configure:1334: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_YACC="$ac_prog" @@ -1271,28 +1367,30 @@ test -n "$YACC" || YACC="yacc" # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1279: checking for a BSD compatible install" >&5 +echo "configure:1376: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" @@ -1322,20 +1420,23 @@ echo "$ac_t""$INSTALL" 1>&6 # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1331: checking for $ac_word" >&5 +echo "configure:1431: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" @@ -1354,7 +1455,7 @@ else fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:1358: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:1459: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1381,23 +1482,22 @@ else fi - for ac_hdr in stdarg.h stddef.h stdlib.h string.h limits.h unistd.h lib.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1390: checking for $ac_hdr" >&5 +echo "configure:1490: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1395 "configure" +#line 1495 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1400: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1500: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1423,12 +1523,12 @@ fi done echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:1427: checking for working const" >&5 +echo "configure:1527: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1432 "configure" +#line 1532 "configure" #include "confdefs.h" int main() { @@ -1477,7 +1577,7 @@ ccp = (char const *const *) p; ; return 0; } EOF -if { (eval echo configure:1481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1581: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1498,12 +1598,12 @@ EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1502: checking for ANSI C header files" >&5 +echo "configure:1602: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1507 "configure" +#line 1607 "configure" #include "confdefs.h" #include <stdlib.h> #include <stdarg.h> @@ -1511,8 +1611,8 @@ else #include <float.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1515: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1615: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes @@ -1528,7 +1628,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext <<EOF -#line 1532 "configure" +#line 1632 "configure" #include "confdefs.h" #include <string.h> EOF @@ -1546,7 +1646,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext <<EOF -#line 1550 "configure" +#line 1650 "configure" #include "confdefs.h" #include <stdlib.h> EOF @@ -1567,7 +1667,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF -#line 1571 "configure" +#line 1671 "configure" #include "confdefs.h" #include <ctype.h> #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1578,7 +1678,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1602,12 +1702,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:1606: checking for size_t" >&5 +echo "configure:1706: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1611 "configure" +#line 1711 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -1616,7 +1716,7 @@ else #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else @@ -1635,12 +1735,12 @@ EOF fi echo $ac_n "checking for ptrdiff_t""... $ac_c" 1>&6 -echo "configure:1639: checking for ptrdiff_t" >&5 +echo "configure:1739: checking for ptrdiff_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ptrdiff_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1644 "configure" +#line 1744 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS @@ -1649,7 +1749,7 @@ else #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "ptrdiff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + egrep "(^|[^a-zA-Z_0-9])ptrdiff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_ptrdiff_t=yes else @@ -1669,12 +1769,12 @@ fi echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:1673: checking for vprintf" >&5 +echo "configure:1773: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1678 "configure" +#line 1778 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char vprintf(); below. */ @@ -1697,7 +1797,7 @@ vprintf(); ; return 0; } EOF -if { (eval echo configure:1701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -1721,12 +1821,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:1725: checking for _doprnt" >&5 +echo "configure:1825: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1730 "configure" +#line 1830 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _doprnt(); below. */ @@ -1749,7 +1849,7 @@ _doprnt(); ; return 0; } EOF -if { (eval echo configure:1753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -1776,12 +1876,12 @@ fi for ac_func in isgraph setvbuf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1780: checking for $ac_func" >&5 +echo "configure:1880: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1785 "configure" +#line 1885 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -1804,7 +1904,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:1808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1829,54 +1929,156 @@ fi done -SaveCFLAGS="$CFLAGS" -CFLAGS="-g -O -I. -I$srcdir" -echo $ac_n "checking if long strings are accepted by the C compiler""... $ac_c" 1>&6 -echo "configure:1836: checking if long strings are accepted by the C compiler" >&5 +# Check whether --with-pkg or --without-pkg was given. +if test "${with_pkg+set}" = set; then + withval="$with_pkg" + + CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + LDFLAGS="$LDFLAGS -L/usr/pkg/lib" + echo Using /usr/pkg/include and /usr/pkg/lib + +fi + + +bcle=n +# Check whether --with-libedit or --without-libedit was given. +if test "${with_libedit+set}" = set; then + withval="$with_libedit" + + echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 +echo "configure:1950: checking for tgetent in -ltermcap" >&5 +ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <<EOF -#line 1838 "configure" +#line 1958 "configure" #include "confdefs.h" - -char libmath[] = -#include "bc/libmath.h" -; +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char tgetent(); int main() { - +tgetent() ; return 0; } EOF -if { (eval echo configure:1849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - echo "$ac_t""yes" 1>&6 + eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + TERMLIB=-ltermcap +else echo "$ac_t""no" 1>&6 -echo "configure: warning: libmath.b will not be preloaded into the executable" 1>&2 -if test "${prefix}" = "NONE" ; then -cat >> confdefs.h <<EOF -#define BC_MATH_FILE "/usr/local/lib/libmath.b" -EOF +fi + LDSAVE=$LDFLAGS + LDFLAGS="$LDFLAGS $TERMLIB" + echo $ac_n "checking for el_gets in -ledit""... $ac_c" 1>&6 +echo "configure:1992: checking for el_gets in -ledit" >&5 +ac_lib_var=`echo edit'_'el_gets | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 else -cat >> confdefs.h <<EOF -#define BC_MATH_FILE "${prefix}/lib/libmath.b" + ac_save_LIBS="$LIBS" +LIBS="-ledit $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2000 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char el_gets(); + +int main() { +el_gets() +; return 0; } EOF +if { (eval echo configure:2011: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_safe=`echo "histedit.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for histedit.h""... $ac_c" 1>&6 +echo "configure:2028: checking for histedit.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2033 "configure" +#include "confdefs.h" +#include <histedit.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2038: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* -CFLAGS="$SaveCFLAGS" +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + READLINELIB="-ledit $TERMLIB";bcle=y +else + echo "$ac_t""no" 1>&6 +fi + +else + echo "$ac_t""no" 1>&6 +READLINELIB="" +fi + + if test "$bcle" = "y"; then + echo Using the libedit library. + cat >> confdefs.h <<\EOF +#define LIBEDIT 1 +EOF -echo $LIBS -bcrl=nA + fi + LDFLAGS=$LDSAVE + +fi + + +bcrl=n # Check whether --with-readline or --without-readline was given. if test "${with_readline+set}" = set; then withval="$with_readline" echo $ac_n "checking for tparm in -lncurses""... $ac_c" 1>&6 -echo "configure:1880: checking for tparm in -lncurses" >&5 +echo "configure:2082: checking for tparm in -lncurses" >&5 ac_lib_var=`echo ncurses'_'tparm | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1884,7 +2086,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <<EOF -#line 1888 "configure" +#line 2090 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -1895,7 +2097,7 @@ int main() { tparm() ; return 0; } EOF -if { (eval echo configure:1899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1914,7 +2116,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 -echo "configure:1918: checking for tgetent in -ltermcap" >&5 +echo "configure:2120: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1922,7 +2124,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <<EOF -#line 1926 "configure" +#line 2128 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -1933,7 +2135,7 @@ int main() { tgetent() ; return 0; } EOF -if { (eval echo configure:1937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2139: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1955,10 +2157,10 @@ fi fi - saved_LIBS="$LIBS" - LIBS="$LIBS $TERMLIB" + LDSAVE=$LDFLAGS + LDFLAGS="$LDFLAGS $TERMLIB" echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 -echo "configure:1962: checking for readline in -lreadline" >&5 +echo "configure:2164: checking for readline in -lreadline" >&5 ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1966,7 +2168,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $LIBS" cat > conftest.$ac_ext <<EOF -#line 1970 "configure" +#line 2172 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -1977,7 +2179,7 @@ int main() { readline() ; return 0; } EOF -if { (eval echo configure:1981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1994,18 +2196,18 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_safe=`echo "readline/readline.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for readline/readline.h""... $ac_c" 1>&6 -echo "configure:1998: checking for readline/readline.h" >&5 +echo "configure:2200: checking for readline/readline.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2003 "configure" +#line 2205 "configure" #include "confdefs.h" #include <readline/readline.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2008: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:2210: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -2020,14 +2222,14 @@ rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 - LIBS="$saved_LIBS -lreadline $TERMLIB";bcrl=y + READLINELIB="-lreadline $TERMLIB";bcrl=y else echo "$ac_t""no" 1>&6 fi else echo "$ac_t""no" 1>&6 -LIBS="$saved_LIBS" +READLINELIB="" fi if test "$bcrl" = "y" ; then @@ -2037,11 +2239,10 @@ fi EOF fi + LDFLAGS=$LDSAVE fi -echo $LIBS - if test "$LEX" = "flex" ; then LEX="flex -I8" @@ -2051,11 +2252,16 @@ else fi fi +if test "$bcrl" = "y" -a "$bcle" = "y" ; then + { echo "configure: error: Can not use both readline and libedit. Aborting." 1>&2; exit 1; } +fi + if test "$LEX" = "lex" -a `uname -s` = "SunOS" ; then LEXLIB="" echo "SunOS using lex does not have a -ll." fi + if test "$program_transform_name" = s,x,x,; then program_transform_name= else @@ -2098,7 +2304,7 @@ EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | - case `(ac_space=' '; set) 2>&1` in + case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). @@ -2165,7 +2371,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12" + echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; @@ -2185,9 +2391,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub +s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g @@ -2207,8 +2415,8 @@ s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g s%@PACKAGE@%$PACKAGE%g s%@VERSION@%$VERSION%g s%@ACLOCAL@%$ACLOCAL%g @@ -2224,6 +2432,7 @@ s%@LEXLIB@%$LEXLIB%g s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g s%@YACC@%$YACC%g s%@RANLIB@%$RANLIB%g +s%@READLINELIB@%$READLINELIB%g CEOF EOF diff --git a/contrib/bc/configure.in b/contrib/bc/configure.in index 0068e31..5f982d3 100644 --- a/contrib/bc/configure.in +++ b/contrib/bc/configure.in @@ -1,8 +1,14 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(doc/bc.1) -AM_INIT_AUTOMAKE(bc, 1.05) +AM_INIT_AUTOMAKE("bc", "1.06") AM_CONFIG_HEADER(config.h) +AC_DEFINE(DC_VERSION,"1.3") +AC_DEFINE_UNQUOTED(BC_COPYRIGHT, dnl + ["Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc."]) +AC_DEFINE_UNQUOTED(DC_COPYRIGHT, dnl + ["Copyright 1994, 1997, 1998, 2000 Free Software Foundation, Inc."]) + AC_PROG_CC AC_MINIX dnl AC_ISC_POSIX @@ -13,7 +19,6 @@ AC_PROG_INSTALL AC_PROG_RANLIB AC_PROG_MAKE_SET - AC_CHECK_HEADERS(stdarg.h stddef.h stdlib.h string.h limits.h unistd.h lib.h) AC_C_CONST AC_TYPE_SIZE_T @@ -22,53 +27,45 @@ AC_CHECK_TYPE(ptrdiff_t, size_t) AC_FUNC_VPRINTF AC_CHECK_FUNCS(isgraph setvbuf) -SaveCFLAGS="$CFLAGS" -CFLAGS="-g -O -I. -I$srcdir" -AC_MSG_CHECKING(if long strings are accepted by the C compiler) -AC_TRY_COMPILE([ -char libmath[] = -#include "bc/libmath.h" -; -],[],AC_MSG_RESULT(yes), -AC_MSG_RESULT(no) -AC_MSG_WARN(libmath.b will not be preloaded into the executable) -if test "${prefix}" = "NONE" ; then -AC_DEFINE_UNQUOTED(BC_MATH_FILE,"/usr/local/lib/libmath.b") -else -AC_DEFINE_UNQUOTED(BC_MATH_FILE,"${prefix}/lib/libmath.b") -fi) -CFLAGS="$SaveCFLAGS" +AC_ARG_WITH(pkg,[ --with-pkg use software installed in /usr/pkg tree], [ + CPPFLAGS="$CPPFLAGS -I/usr/pkg/include" + LDFLAGS="$LDFLAGS -L/usr/pkg/lib" + echo Using /usr/pkg/include and /usr/pkg/lib +]) -echo $LIBS -bcrl=nA +bcle=n +AC_ARG_WITH(libedit,[ --with-libedit support fancy BSD command input +editing], [ + AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap) + LDSAVE=$LDFLAGS + LDFLAGS="$LDFLAGS $TERMLIB" + AC_CHECK_LIB(edit,el_gets, + [AC_CHECK_HEADER(histedit.h, + READLINELIB="-ledit $TERMLIB";bcle=y)], + READLINELIB="") + if test "$bcle" = "y"; then + echo Using the libedit library. + AC_DEFINE(LIBEDIT,1) + fi + LDFLAGS=$LDSAVE +]) + +bcrl=n AC_ARG_WITH(readline,[ --with-readline support fancy command input editing], [ AC_CHECK_LIB(ncurses,tparm,TERMLIB=-lncurses, - AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap)) - saved_LIBS="$LIBS" - LIBS="$LIBS $TERMLIB" + AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap)) + LDSAVE=$LDFLAGS + LDFLAGS="$LDFLAGS $TERMLIB" AC_CHECK_LIB(readline,readline, [AC_CHECK_HEADER(readline/readline.h, - LIBS="$saved_LIBS -lreadline $TERMLIB";bcrl=y)], - LIBS="$saved_LIBS") + READLINELIB="-lreadline $TERMLIB";bcrl=y)], + READLINELIB="") if test "$bcrl" = "y" ; then echo Using the readline library. AC_DEFINE(READLINE,1) fi + LDFLAGS=$LDSAVE ]) -echo $LIBS - -dnl AC_ARG_WITH(readline,[ --with-readline support fancy command input editing], [ -dnl if test "$with_readline" = "yes" ; then -dnl echo Using the readline library. -dnl AC_DEFINE(READLINE,1) -dnl LIBS="$LIBS -lreadline -ltermcap" -dnl bcrl=y -dnl else -dnl bcrl=n -dnl fi -dnl ], [ -dnl bcrl=n -dnl ]) if test "$LEX" = "flex" ; then LEX="flex -I8" @@ -78,10 +75,15 @@ else fi fi +if test "$bcrl" = "y" -a "$bcle" = "y" ; then + AC_MSG_ERROR(Can not use both readline and libedit. Aborting.) +fi + if test "$LEX" = "lex" -a `uname -s` = "SunOS" ; then LEXLIB="" echo "SunOS using lex does not have a -ll." fi +AC_SUBST(READLINELIB) AC_ARG_PROGRAM AC_OUTPUT(Makefile bc/Makefile dc/Makefile doc/Makefile lib/Makefile) diff --git a/contrib/bc/dc/Makefile.am b/contrib/bc/dc/Makefile.am index 4de00ab..99164ba 100644 --- a/contrib/bc/dc/Makefile.am +++ b/contrib/bc/dc/Makefile.am @@ -7,4 +7,8 @@ noinst_HEADERS = dc.h dc-proto.h dc-regdef.h INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../h LDADD = ../lib/libbc.a +MAINTAINERCLEANFILES = Makefile.in + +CFLAGS = @CFLAGS@ -Wall -funsigned-char + $(PROGRAMS): $(LDADD) diff --git a/contrib/bc/dc/Makefile.in b/contrib/bc/dc/Makefile.in index ae4e460..0772dd6 100644 --- a/contrib/bc/dc/Makefile.in +++ b/contrib/bc/dc/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.3 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,7 +11,7 @@ # PARTICULAR PURPOSE. -SHELL = /bin/sh +SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -32,7 +32,7 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DISTDIR = +DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ @@ -62,6 +62,7 @@ LEX = @LEX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +READLINELIB = @READLINELIB@ VERSION = @VERSION@ YACC = @YACC@ @@ -72,6 +73,10 @@ noinst_HEADERS = dc.h dc-proto.h dc-regdef.h INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../h LDADD = ../lib/libbc.a + +MAINTAINERCLEANFILES = Makefile.in + +CFLAGS = @CFLAGS@ -Wall -funsigned-char mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -86,9 +91,9 @@ dc_OBJECTS = dc.o misc.o eval.o stack.o array.o numeric.o string.o dc_LDADD = $(LDADD) dc_DEPENDENCIES = ../lib/libbc.a dc_LDFLAGS = -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ HEADERS = $(noinst_HEADERS) DIST_COMMON = Makefile.am Makefile.in @@ -97,15 +102,14 @@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar -GZIP = --best +GZIP_ENV = --best SOURCES = $(dc_SOURCES) OBJECTS = $(dc_OBJECTS) -all: Makefile $(PROGRAMS) $(HEADERS) - +all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps dc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -127,15 +131,15 @@ install-binPROGRAMS: $(bin_PROGRAMS) $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done .c.o: @@ -164,8 +168,12 @@ dc: $(dc_OBJECTS) $(dc_DEPENDENCIES) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ @@ -193,70 +201,92 @@ subdir = dc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ done -info: -dvi: -check: all - $(MAKE) -installcheck: -install-exec: install-binPROGRAMS - @$(NORMAL_INSTALL) - -install-data: - @$(NORMAL_INSTALL) - -install: install-exec install-data all - @: - -uninstall: uninstall-binPROGRAMS - +array.o: array.c ../config.h dc.h dc-proto.h dc-regdef.h +dc.o: dc.c ../config.h ../h/getopt.h dc.h dc-proto.h +eval.o: eval.c ../config.h dc.h dc-proto.h +misc.o: misc.c ../config.h ../h/getopt.h dc.h dc-proto.h +numeric.o: numeric.c ../config.h ../h/number.h dc.h dc-proto.h +stack.o: stack.c ../config.h dc.h dc-proto.h dc-regdef.h +string.o: string.c ../config.h dc.h dc-proto.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +all-redirect: all-am install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: - $(mkinstalldirs) $(DATADIR)$(bindir) + $(mkinstalldirs) $(DESTDIR)$(bindir) mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(DISTCLEANFILES) + -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic -clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ - mostlyclean +mostlyclean: mostlyclean-am -distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ - distclean-generic clean - -rm -f config.status +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am -maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ - maintainer-clean-tags maintainer-clean-generic \ - distclean +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." +maintainer-clean: maintainer-clean-am + .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir info dvi installcheck \ -install-exec install-data install uninstall all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean $(PROGRAMS): $(LDADD) diff --git a/contrib/bc/dc/array.c b/contrib/bc/dc/array.c index bc701a1..d97f716 100644 --- a/contrib/bc/dc/array.c +++ b/contrib/bc/dc/array.c @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This module is the only one that knows what arrays look like. */ diff --git a/contrib/bc/dc/dc-proto.h b/contrib/bc/dc/dc-proto.h index 1e7c52c..f0ac28b 100644 --- a/contrib/bc/dc/dc-proto.h +++ b/contrib/bc/dc/dc-proto.h @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ extern const char *dc_str2charp DC_PROTO((dc_str)); diff --git a/contrib/bc/dc/dc-regdef.h b/contrib/bc/dc/dc-regdef.h index 129d0ae..540268c 100644 --- a/contrib/bc/dc/dc-regdef.h +++ b/contrib/bc/dc/dc-regdef.h @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ #ifdef HAVE_LIMITS_H diff --git a/contrib/bc/dc/dc.c b/contrib/bc/dc/dc.c index fa213ba..a72644c 100644 --- a/contrib/bc/dc/dc.c +++ b/contrib/bc/dc/dc.c @@ -1,7 +1,7 @@ /* * implement the "dc" Desk Calculator language. * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* Written with strong hiding of implementation details @@ -42,8 +44,6 @@ #include "dc.h" #include "dc-proto.h" -#include "version.h" - #ifndef EXIT_SUCCESS /* C89 <stdlib.h> */ # define EXIT_SUCCESS 0 #endif @@ -53,6 +53,22 @@ const char *progname; /* basename of program invocation */ +static void +bug_report_info DC_DECLVOID() +{ + printf("Email bug reports to: bug-dc@gnu.org .\n"); +} + +static void +show_version DC_DECLVOID() +{ + printf("dc (GNU %s %s) %s\n", PACKAGE, VERSION, DC_VERSION); + printf("\n%s\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\ +to the extent permitted by law.\n", DC_COPYRIGHT); +} + /* your generic usage function */ static void usage DC_DECLARG((f)) @@ -65,18 +81,8 @@ Usage: %s [OPTION] [file ...]\n\ -h, --help display this help and exit\n\ -V, --version output version information and exit\n\ \n\ -Report bugs to bug-gnu-utils@prep.ai.mit.edu\n\ -Be sure to include the word ``dc'' somewhere in the ``Subject:'' field.\n\ ", progname); -} - -static void -show_version DC_DECLVOID() -{ - printf("%s\n\n", DC_VERSION); - printf("Email bug reports to: bug-gnu-utils@prep.ai.mit.edu .\n"); - printf("Be sure to include the word ``dc'' \ -somewhere in the ``Subject:'' field.\n"); + bug_report_info(); } /* returns a pointer to one past the last occurance of c in s, diff --git a/contrib/bc/dc/dc.h b/contrib/bc/dc/dc.h index 5e2d65a..3300f44 100644 --- a/contrib/bc/dc/dc.h +++ b/contrib/bc/dc/dc.h @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ #ifndef DC_DEFS_H diff --git a/contrib/bc/dc/eval.c b/contrib/bc/dc/eval.c index 0cb2185..21592d9 100644 --- a/contrib/bc/dc/eval.c +++ b/contrib/bc/dc/eval.c @@ -1,7 +1,7 @@ /* * evaluate the dc language, from a FILE* or a string * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This is the only module which knows about the dc input language */ @@ -185,12 +187,13 @@ dc_func DC_DECLARG((c, peekc, negcmp)) case '|': /* Consider the top three elements of the stack as (base, exp, mod), * where mod is top-of-stack, exp is next-to-top, and base is - * second-from-top. Mod must be non-zero and exp must be a - * non-negative integer. Push the result of raising base to the exp - * power, reduced modulo mod. If we had base in register b, exp in - * register e, and mod in register m then this is conceptually - * equivalent to "lble^lm%", but it is implemented in a more efficient - * manner, and can handle arbritrarily large values for exp. + * second-from-top. Mod must be non-zero, exp must be non-negative, + * and all three must be integers. Push the result of raising + * base to the exp power, reduced modulo mod. If we had base in + * register b, exp in register e, and mod in register m then this + * is conceptually equivalent to "lble^lm%", but it is implemented + * in a more efficient manner, and can handle arbritrarily large + * values for exp. */ dc_triop(dc_modexp, dc_scale); break; @@ -633,7 +636,7 @@ dc_evalfile DC_DECLARG((fp)) break; case DC_QUIT: if (unwind_noexit != DC_TRUE) - return DC_FAIL; + return DC_SUCCESS; fprintf(stderr, "%s: Q command argument exceeded string execution depth\n", progname); diff --git a/contrib/bc/dc/misc.c b/contrib/bc/dc/misc.c index 65f986b..fa94de1 100644 --- a/contrib/bc/dc/misc.c +++ b/contrib/bc/dc/misc.c @@ -1,7 +1,7 @@ /* * misc. functions for the "dc" Desk Calculator language. * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This module contains miscelaneous functions that have no @@ -48,8 +50,6 @@ #include "dc.h" #include "dc-proto.h" -#include "version.h" - #ifndef EXIT_FAILURE /* C89 <stdlib.h> */ # define EXIT_FAILURE 1 #endif diff --git a/contrib/bc/dc/numeric.c b/contrib/bc/dc/numeric.c index d5abf13..6086be5 100644 --- a/contrib/bc/dc/numeric.c +++ b/contrib/bc/dc/numeric.c @@ -1,7 +1,7 @@ /* * interface dc to the bc numeric routines * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,8 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This should be the only module that knows the internals of type dc_num */ @@ -33,18 +35,23 @@ #else # define UCHAR_MAX ((unsigned char)~0) #endif -#include "bcdefs.h" -#include "proto.h" -#include "global.h" +#include <stdlib.h> +#include "number.h" #include "dc.h" #include "dc-proto.h" #ifdef __GNUC__ -# define ATTRIB(x) __attribute__(x) -#else +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__-0 >= 7) +# define ATTRIB(x) __attribute__(x) +# endif +#endif +#ifndef ATTRIB # define ATTRIB(x) #endif +/* Forward prototype */ +static void out_char (int); + /* there is no POSIX standard for dc, so we'll take the GNU definitions */ int std_only = FALSE; @@ -61,7 +68,7 @@ dc_add DC_DECLARG((a, b, kscale, result)) int kscale ATTRIB((unused)) DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); bc_add(CastNum(a), CastNum(b), (bc_num *)result, 0); return DC_SUCCESS; } @@ -76,7 +83,7 @@ dc_sub DC_DECLARG((a, b, kscale, result)) int kscale ATTRIB((unused)) DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); bc_sub(CastNum(a), CastNum(b), (bc_num *)result, 0); return DC_SUCCESS; } @@ -91,7 +98,7 @@ dc_mul DC_DECLARG((a, b, kscale, result)) int kscale DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); bc_multiply(CastNum(a), CastNum(b), (bc_num *)result, kscale); return DC_SUCCESS; } @@ -106,7 +113,7 @@ dc_div DC_DECLARG((a, b, kscale, result)) int kscale DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); if (bc_divide(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ fprintf(stderr, "%s: divide by zero\n", progname); return DC_DOMAIN_ERROR; @@ -126,8 +133,8 @@ dc_divrem DC_DECLARG((a, b, kscale, quotient, remainder)) dc_num *quotient DC_DECLSEP dc_num *remainder DC_DECLEND { - init_num((bc_num *)quotient); - init_num((bc_num *)remainder); + bc_init_num((bc_num *)quotient); + bc_init_num((bc_num *)remainder); if (bc_divmod(CastNum(a), CastNum(b), (bc_num *)quotient, (bc_num *)remainder, kscale)){ fprintf(stderr, "%s: divide by zero\n", progname); @@ -146,7 +153,7 @@ dc_rem DC_DECLARG((a, b, kscale, result)) int kscale DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ fprintf(stderr, "%s: remainder by zero\n", progname); return DC_DOMAIN_ERROR; @@ -162,10 +169,10 @@ dc_modexp DC_DECLARG((base, expo, mod, kscale, result)) int kscale DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod), (bc_num *)result, kscale)){ - if (is_zero(CastNum(mod))) + if (bc_is_zero(CastNum(mod))) fprintf(stderr, "%s: remainder by zero\n", progname); return DC_DOMAIN_ERROR; } @@ -182,7 +189,7 @@ dc_exp DC_DECLARG((a, b, kscale, result)) int kscale DC_DECLSEP dc_num *result DC_DECLEND { - init_num((bc_num *)result); + bc_init_num((bc_num *)result); bc_raise(CastNum(a), CastNum(b), (bc_num *)result, kscale); return DC_SUCCESS; } @@ -198,10 +205,10 @@ dc_sqrt DC_DECLARG((value, kscale, result)) { bc_num tmp; - tmp = copy_num(CastNum(value)); + tmp = bc_copy_num(CastNum(value)); if (!bc_sqrt(&tmp, kscale)){ fprintf(stderr, "%s: square root of negative number\n", progname); - free_num(&tmp); + bc_free_num(&tmp); return DC_DOMAIN_ERROR; } *((bc_num *)result) = tmp; @@ -231,7 +238,7 @@ dc_num2int DC_DECLARG((value, discard_p)) { long result; - result = num2long(CastNum(value)); + result = bc_num2long(CastNum(value)); if (discard_p == DC_TOSS) dc_free_num(&value); return (int)result; @@ -247,8 +254,8 @@ dc_int2data DC_DECLARG((value)) { dc_data result; - init_num((bc_num *)&result.v.number); - int2num((bc_num *)&result.v.number, value); + bc_init_num((bc_num *)&result.v.number); + bc_int2num((bc_num *)&result.v.number, value); result.dc_type = DC_NUMBER; return result; } @@ -279,11 +286,11 @@ dc_getnum DC_DECLARG((input, ibase, readahead)) int decimal; int c; - init_num(&tmp); - init_num(&build); - init_num(&base); - result = copy_num(_zero_); - int2num(&base, ibase); + bc_init_num(&tmp); + bc_init_num(&build); + bc_init_num(&base); + result = bc_copy_num(_zero_); + bc_int2num(&base, ibase); c = (*input)(); while (isspace(c)) c = (*input)(); @@ -303,15 +310,15 @@ dc_getnum DC_DECLARG((input, ibase, readahead)) else break; c = (*input)(); - int2num(&tmp, digit); + bc_int2num(&tmp, digit); bc_multiply(result, base, &result, 0); bc_add(result, tmp, &result, 0); } if (c == '.'){ - free_num(&build); - free_num(&tmp); - divisor = copy_num(_one_); - build = copy_num(_zero_); + bc_free_num(&build); + bc_free_num(&tmp); + divisor = bc_copy_num(_one_); + build = bc_copy_num(_zero_); decimal = 0; for (;;){ c = (*input)(); @@ -321,7 +328,7 @@ dc_getnum DC_DECLARG((input, ibase, readahead)) digit = 10 + c - 'A'; else break; - int2num(&tmp, digit); + bc_int2num(&tmp, digit); bc_multiply(build, base, &build, 0); bc_add(build, tmp, &build, 0); bc_multiply(divisor, base, &divisor, 0); @@ -334,9 +341,9 @@ dc_getnum DC_DECLARG((input, ibase, readahead)) if (negative) bc_sub(_zero_, result, &result, 0); - free_num(&tmp); - free_num(&build); - free_num(&base); + bc_free_num(&tmp); + bc_free_num(&build); + bc_free_num(&base); if (readahead) *readahead = c; full_result.v.number = (dc_num)result; @@ -353,7 +360,7 @@ dc_numlen DC_DECLARG((value)) bc_num num = CastNum(value); /* is this right??? */ - return num->n_len + num->n_scale; + return num->n_len + num->n_scale - (*num->n_value == '\0'); } /* return the scale factor of the passed dc_num @@ -377,7 +384,7 @@ dc_tell_scale DC_DECLARG((value, discard_p)) void dc_math_init DC_DECLVOID() { - init_numbers(); + bc_init_numbers(); } /* print out a dc_num in output base obase to stdout; @@ -391,9 +398,10 @@ dc_out_num DC_DECLARG((value, obase, newline_p, discard_p)) dc_newline newline_p DC_DECLSEP dc_discard discard_p DC_DECLEND { - out_num(CastNum(value), obase, out_char); + out_char('\0'); /* clear the column counter */ + bc_out_num(CastNum(value), obase, out_char, 0); if (newline_p == DC_WITHNL) - out_char('\n'); + putchar ('\n'); if (discard_p == DC_TOSS) dc_free_num(&value); } @@ -403,7 +411,7 @@ dc_out_num DC_DECLARG((value, obase, newline_p, discard_p)) * if discard_p is DC_TOSS then deallocate the value after use */ void -dc_dump_num DC_DECLARG((value, discard_p)) +dc_dump_num DC_DECLARG((dcvalue, discard_p)) dc_num dcvalue DC_DECLSEP dc_discard discard_p DC_DECLEND { @@ -415,9 +423,9 @@ dc_dump_num DC_DECLARG((value, discard_p)) bc_num obase; bc_num digit; - init_num(&value); - init_num(&obase); - init_num(&digit); + bc_init_num(&value); + bc_init_num(&obase); + bc_init_num(&digit); /* we only handle the integer portion: */ bc_divide(CastNum(dcvalue), _one_, &value, 0); @@ -427,14 +435,14 @@ dc_dump_num DC_DECLARG((value, discard_p)) if (discard_p == DC_TOSS) dc_free_num(&dcvalue); - int2num(&obase, 1+UCHAR_MAX); + bc_int2num(&obase, 1+UCHAR_MAX); do { (void) bc_divmod(value, obase, &value, &digit, 0); cur = dc_malloc(sizeof *cur); - cur->digit = (int)num2long(digit); + cur->digit = (int)bc_num2long(digit); cur->link = top_of_stack; top_of_stack = cur; - } while (!is_zero(value)); + } while (!bc_is_zero(value)); for (cur=top_of_stack; cur; cur=next) { putchar(cur->digit); @@ -442,9 +450,9 @@ dc_dump_num DC_DECLARG((value, discard_p)) free(cur); } - free_num(&digit); - free_num(&obase); - free_num(&value); + bc_free_num(&digit); + bc_free_num(&obase); + bc_free_num(&value); } /* deallocate an instance of a dc_num */ @@ -452,7 +460,7 @@ void dc_free_num DC_DECLARG((value)) dc_num *value DC_DECLEND { - free_num((bc_num *)value); + bc_free_num((bc_num *)value); } /* return a duplicate of the number in the passed value */ @@ -498,15 +506,14 @@ int out_col = 0; It keeps track of the number of characters output and may break the output with a "\<cr>". */ -void +static void out_char (ch) - char ch; + int ch; { - if (ch == '\n') + if (ch == '\0') { out_col = 0; - putchar ('\n'); } else { @@ -547,17 +554,16 @@ rt_error (mesg, va_alist) #endif { va_list args; - char error_mesg [255]; + fprintf (stderr, "Runtime error: "); #ifdef HAVE_STDARG_H va_start (args, mesg); #else va_start (args); #endif - vsprintf (error_mesg, mesg, args); + vfprintf (stderr, mesg, args); va_end (args); - - fprintf (stderr, "Runtime error: %s\n", error_mesg); + fprintf (stderr, "\n"); } @@ -581,15 +587,14 @@ rt_warn (mesg, va_alist) #endif { va_list args; - char error_mesg [255]; + fprintf (stderr, "Runtime warning: "); #ifdef HAVE_STDARG_H va_start (args, mesg); #else va_start (args); #endif - vsprintf (error_mesg, mesg, args); + vfprintf (stderr, mesg, args); va_end (args); - - fprintf (stderr, "Runtime warning: %s\n", error_mesg); + fprintf (stderr, "\n"); } diff --git a/contrib/bc/dc/stack.c b/contrib/bc/dc/stack.c index 0268b70..1d8a9bf 100644 --- a/contrib/bc/dc/stack.c +++ b/contrib/bc/dc/stack.c @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This module is the only one that knows what stacks (both the @@ -347,6 +350,8 @@ dc_register_set DC_DECLARG((regid, value)) dc_free_num(&r->value.v.number); else if (r->value.dc_type == DC_STRING) dc_free_str(&r->value.v.string); + else if (r->value.dc_type == DC_UNINITIALIZED) + ; else dc_garbage("", regid); dc_register[regid]->value = value; diff --git a/contrib/bc/dc/string.c b/contrib/bc/dc/string.c index 6cffffd..a7f79a4 100644 --- a/contrib/bc/dc/string.c +++ b/contrib/bc/dc/string.c @@ -15,8 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. + * program's author (see below) or write to: + * + * The Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111 USA */ /* This should be the only module that knows the internals of type dc_string */ diff --git a/contrib/bc/doc/Makefile.am b/contrib/bc/doc/Makefile.am index d4ed7eb..a729cee 100644 --- a/contrib/bc/doc/Makefile.am +++ b/contrib/bc/doc/Makefile.am @@ -1,8 +1,10 @@ ## Process this file with automake to produce Makefile.in -info_TEXINFOS = dc.texi +info_TEXINFOS = bc.texi dc.texi MAKEINFO = makeinfo --no-split +MAINTAINERCLEANFILES = Makefile.in + # FIXME: remove this when automake has been fixed to include these # files automatically EXTRA_DIST = bc.1 dc.1 diff --git a/contrib/bc/doc/Makefile.in b/contrib/bc/doc/Makefile.in index 2593d25..840d007 100644 --- a/contrib/bc/doc/Makefile.in +++ b/contrib/bc/doc/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.3 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,7 +11,7 @@ # PARTICULAR PURPOSE. -SHELL = /bin/sh +SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -32,7 +32,7 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DISTDIR = +DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ @@ -61,12 +61,15 @@ CC = @CC@ LEX = @LEX@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +READLINELIB = @READLINELIB@ VERSION = @VERSION@ YACC = @YACC@ -info_TEXINFOS = dc.texi +info_TEXINFOS = bc.texi dc.texi MAKEINFO = makeinfo --no-split +MAINTAINERCLEANFILES = Makefile.in + # FIXME: remove this when automake has been fixed to include these # files automatically EXTRA_DIST = bc.1 dc.1 @@ -76,10 +79,9 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = TEXI2DVI = texi2dvi -TEXINFO_TEX = $(srcdir)/texinfo.tex -INFO_DEPS = dc.info -DVIS = dc.dvi -TEXINFOS = dc.texi +INFO_DEPS = bc.info dc.info +DVIS = bc.dvi dc.dvi +TEXINFOS = bc.texi dc.texi man1dir = $(mandir)/man1 MANS = $(man_MANS) @@ -90,12 +92,11 @@ DIST_COMMON = Makefile.am Makefile.in texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar -GZIP = --best -all: Makefile $(INFO_DEPS) $(MANS) - +GZIP_ENV = --best +all: all-redirect .SUFFIXES: .SUFFIXES: .dvi .info .ps .texi .texinfo .txi -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -103,6 +104,10 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +bc.info: bc.texi +bc.dvi: bc.texi + + dc.info: dc.texi dc.dvi: dc.texi @@ -115,7 +120,7 @@ DVIPS = dvips && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texi.dvi: - TEXINPUTS=$(srcdir):$$TEXINPUTS \ + TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .texi: @@ -134,7 +139,7 @@ DVIPS = dvips && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo.dvi: - TEXINPUTS=$(srcdir):$$TEXINPUTS \ + TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi.info: @@ -143,7 +148,7 @@ DVIPS = dvips && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .txi.dvi: - TEXINPUTS=$(srcdir):$$TEXINPUTS \ + TEXINPUTS=.:$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi: @@ -156,7 +161,8 @@ DVIPS = dvips install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(infodir) - @for file in $(INFO_DEPS); do \ + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ d=$(srcdir); \ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ if test -f $$d/$$ifile; then \ @@ -167,7 +173,8 @@ install-info-am: $(INFO_DEPS) done @$(POST_INSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ - for file in $(INFO_DEPS); do \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ done; \ @@ -178,17 +185,20 @@ uninstall-info: @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ ii=yes; \ else ii=; fi; \ - for file in $(INFO_DEPS); do \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ test -z "$ii" \ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ done @$(NORMAL_UNINSTALL) - for file in $(INFO_DEPS); do \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ done dist-info: $(INFO_DEPS) - for base in $(INFO_DEPS); do \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ d=$(srcdir); \ for file in `cd $$d && eval echo $$base*`; do \ test -f $(distdir)/$$file \ @@ -198,16 +208,18 @@ dist-info: $(INFO_DEPS) done mostlyclean-aminfo: - -rm -f dc.aux dc.cp dc.cps dc.dvi dc.fn dc.fns dc.ky dc.kys dc.ps \ - dc.log dc.pg dc.toc dc.tp dc.tps dc.vr dc.vrs dc.op dc.tr \ - dc.cv dc.cn + -rm -f bc.aux bc.cp bc.cps bc.dvi bc.fn bc.fns bc.ky bc.kys bc.ps \ + bc.log bc.pg bc.toc bc.tp bc.tps bc.vr bc.vrs bc.op bc.tr \ + bc.cv bc.cn dc.aux dc.cp dc.cps dc.dvi dc.fn dc.fns dc.ky \ + dc.kys dc.ps dc.log dc.pg dc.toc dc.tp dc.tps dc.vr dc.vrs \ + dc.op dc.tr dc.cv dc.cn clean-aminfo: distclean-aminfo: maintainer-clean-aminfo: - for i in $(INFO_DEPS); do \ + cd $(srcdir) && for i in $(INFO_DEPS); do \ rm -f $$i; \ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ rm -f $$i-[0-9]*; \ @@ -248,10 +260,10 @@ uninstall-man1: done install-man: $(MANS) @$(NORMAL_INSTALL) - $(MAKE) install-man1 + $(MAKE) $(AM_MAKEFLAGS) install-man1 uninstall-man: @$(NORMAL_UNINSTALL) - $(MAKE) uninstall-man1 + $(MAKE) $(AM_MAKEFLAGS) uninstall-man1 tags: TAGS TAGS: @@ -263,64 +275,78 @@ subdir = doc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ done - $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info -info: $(INFO_DEPS) -dvi: $(DVIS) -check: all - $(MAKE) -installcheck: -install-exec: - @$(NORMAL_INSTALL) - -install-data: install-info-am install-man - @$(NORMAL_INSTALL) - -install: install-exec install-data all - @: - -uninstall: uninstall-info uninstall-man - + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info +info-am: $(INFO_DEPS) +info: info-am +dvi-am: $(DVIS) +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-info-am install-man +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-info uninstall-man +uninstall: uninstall-am +all-am: Makefile $(INFO_DEPS) $(MANS) +all-redirect: all-am install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: $(mkinstalldirs) $(DESTDIR)$(infodir) $(DESTDIR)$(mandir)/man1 mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(DISTCLEANFILES) + -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -mostlyclean: mostlyclean-aminfo mostlyclean-generic +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic -clean: clean-aminfo clean-generic mostlyclean +mostlyclean: mostlyclean-am -distclean: distclean-aminfo distclean-generic clean - -rm -f config.status +clean-am: clean-aminfo clean-generic mostlyclean-am -maintainer-clean: maintainer-clean-aminfo maintainer-clean-generic \ - distclean +clean: clean-am + +distclean-am: distclean-aminfo distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \ + distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." +maintainer-clean: maintainer-clean-am + .PHONY: install-info-am uninstall-info mostlyclean-aminfo \ distclean-aminfo clean-aminfo maintainer-clean-aminfo install-man1 \ -uninstall-man1 install-man uninstall-man tags distdir info dvi \ -installcheck install-exec install-data install uninstall all \ -installdirs mostlyclean-generic distclean-generic clean-generic \ +uninstall-man1 install-man uninstall-man tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean diff --git a/contrib/bc/doc/bc.1 b/contrib/bc/doc/bc.1 index e0cef9c..c0b03f7 100644 --- a/contrib/bc/doc/bc.1 +++ b/contrib/bc/doc/bc.1 @@ -2,7 +2,7 @@ .\" bc.1 - the *roff document processor source for the bc manual .\" .\" This file is part of GNU bc. -.\" Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. +.\" Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by @@ -15,24 +15,26 @@ .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License -.\" along with this program; see the file COPYING. If not, write to -.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +.\" along with this program; see the file COPYING. If not, write to: +.\" The Free Software Foundation, Inc. +.\" 59 Temple Place, Suite 330 +.\" Boston, MA 02111 USA .\" .\" You may contact the author by: -.\" e-mail: phil@cs.wwu.edu +.\" e-mail: philnelson@acm.org .\" us-mail: Philip A. Nelson .\" Computer Science Department, 9062 .\" Western Washington University .\" Bellingham, WA 98226-9062 .\" .\" -.TH bc 1 .\" "Command Manual" v1.04 "June 22, 1995" +.TH bc 1 .\" "Command Manual" v1.06 "Sept 12, 2000" .SH NAME bc - An arbitrary precision calculator language .SH SYNTAX -\fBbc\fR [ \fB-lwsqv\fR ] [long-options] [ \fI file ...\fR ] +\fBbc\fR [ \fB-hlwsqv\fR ] [long-options] [ \fI file ...\fR ] .SH VERSION -This man page documents GNU bc version 1.04. +This man page documents GNU bc version 1.06. .SH DESCRIPTION \fBbc\fR is a language that supports arbitrary precision numbers with interactive execution of statements. There are some similarities @@ -52,25 +54,19 @@ or to be rejected. This document describes the language accepted by this processor. Extensions will be identified as such. .SS OPTIONS -.IP -l +.IP "-h, --help" +Print the usage and exit. +.IP "-i, --interactive" +Force interactive mode. +.IP "-l, --mathlib" Define the standard math library. -.IP -w +.IP "-w, --warn" Give warnings for extensions to POSIX \fBbc\fR. -.IP -s +.IP "-s, --standard" Process exactly the POSIX \fBbc\fR language. -.IP -q +.IP "-q, --quiet" Do not print the normal GNU bc welcome. -.IP -v -Print the version number and copyright and quit. -.IP --mathlib -Define the standard math library. -.IP --warn -Give warnings for extensions to POSIX \fBbc\fR. -.IP --standard -Process exactly the POSIX \fBbc\fR language. -.IP --quiet -Do not print the normal GNU bc welcome. -.IP --version +.IP "-v, --version" Print the version number and copyright and quit. .SS NUMBERS The most basic element in \fBbc\fR is the number. Numbers are @@ -328,8 +324,8 @@ base ten value of "obase-1". Since numbers are of arbitrary precision, some numbers may not be printable on a single output line. These long numbers will be split across lines using the "\e" as the last character on a line. The maximum number of characters printed -per line is 70. Due to the interactive nature of \fBbc\fR printing -a number cause the side effect of assigning the printed value the the +per line is 70. Due to the interactive nature of \fBbc\fR, printing +a number causes the side effect of assigning the printed value to the special variable \fBlast\fR. This allows the user to recover the last value printed without having to retype the expression that printed the number. Assigning to \fBlast\fR is legal and will @@ -348,7 +344,7 @@ The print statement (an extension) provides another method of output. The "list" is a list of strings and expressions separated by commas. Each string or expression is printed in the order of the list. No terminating newline is printed. Expressions are evaluated and their -value is printed and assigned the the variable \fBlast\fR. Strings +value is printed and assigned to the variable \fBlast\fR. Strings in the print statement are printed to the output and may contain special characters. Special characters start with the backslash character (\e). The special characters recognized by \fBbc\fR are @@ -405,7 +401,7 @@ not executed. Return the value 0 from a function. (See the section on functions.) .IP "\fBreturn\fR ( expression )" Return the value of the expression from a function. (See the section on -functions.) +functions.) As an extension, the parenthesis are not required. .SS PSEUDO STATEMENTS These statements are not statements in the traditional sense. They are not executed statements. Their function is performed at "compile" time. @@ -460,7 +456,7 @@ popped so that the original value (at the time of the function call) of these variables are restored. The parameters are really auto variables that are initialized to a value provided in the function call. Auto variables are different than traditional local variables -in the fact that if function A calls function B, B may access function +because if function A calls function B, B may access function A's auto variables by just using the same name, unless function B has called them auto variables. Due to the fact that auto variables and parameters are pushed onto a stack, \fBbc\fR supports recursive functions. @@ -481,6 +477,22 @@ constants in the function body will be converted using the value of will be ignored during the execution of the function except for the standard function \fBread\fR, which will always use the current value of \fBibase\fR for conversion of numbers. +.PP +As an extension, the format of the definition has been slightly relaxed. +The standard requires the opening brace be on the same line as the +\fBdefine\fR keyword and all other parts must be on following lines. +This version of \fBbc\fR will allow any number of newlines before and +after the opening brace of the function. For example, the following +definitions are legal. +.nf +.RS +\f(CW +define d (n) { return (2*n); } +define d (n) + { return (2*n); } +\fR +.RE +.fi .SS MATH LIBRARY If \fBbc\fR is invoked with the \fB-l\fR option, a math library is preloaded and the default scale is set to 20. The math functions will calculate their @@ -594,19 +606,21 @@ define f (x) { \fR .RE .fi -.SS READLINE OPTION -GNU \fBbc\fR can be compiled (via a configure option) to use the -GNU \fBreadline\fR input editor library. This allows the user -to do more editing of lines before sending them to \fBbc\fR. -It also allows for a history of previous lines typed. When this -option is selected, \fBbc\fR has one more special variable. -This special variable, \fBhistory\fR is the number of lines of -history retained. A value of -1 means that an unlimited number -of history lines are retained. This is the default value. -Setting the value of \fBhistory\fR to a positive number restricts -the number of history lines to the number given. The value of -0 disables the history feature. For more information, read the -user manuals for the GNU \fBreadline\fR and \fBhistory\fR libraries. +.SS READLINE AND LIBEDIT OPTIONS +GNU \fBbc\fR can be compiled (via a configure option) to use the GNU +\fBreadline\fR input editor library or the BSD \fBlibedit\fR library. +This allows the user to do editing of lines before sending them +to \fBbc\fR. It also allows for a history of previous lines typed. +When this option is selected, \fBbc\fR has one more special variable. +This special variable, \fBhistory\fR is the number of lines of history +retained. For \fBreadline\fR, a value of -1 means that an unlimited +number of history lines are retained. Setting the value of +\fBhistory\fR to a positive number restricts the number of history +lines to the number given. The value of 0 disables the history +feature. The default value is 100. For more information, read the +user manuals for the GNU \fBreadline\fR, \fBhistory\fR and BSD \fBlibedit\fR +libraries. One can not enable both \fBreadline\fR and \fBlibedit\fR +at the same time. .SS DIFFERENCES This version of .B bc @@ -657,12 +671,17 @@ POSIX \fBbc\fR does not have a read function. POSIX \fBbc\fR does not have a print statement . .IP "continue statement" POSIX \fBbc\fR does not have a continue statement. +.IP "return statement" +POSIX \fBbc\fR requires parentheses around the return expression. .IP "array parameters" POSIX \fBbc\fR does not (currently) support array parameters in full. The POSIX grammar allows for arrays in function definitions, but does not provide a method to specify an array as an actual parameter. (This is most likely an oversight in the grammar.) Traditional implementations of \fBbc\fR have only call by value array parameters. +.IP "function format" +POSIX \fBbc\fR requires the opening brace on the same line as the +\fBdefine\fR key word and the \fBauto\fR statement on the next line. .IP "=+, =-, =*, =/, =%, =^" POSIX \fBbc\fR does not require these "old style" assignment operators to be defined. This version may allow these "old style" assignments. Use @@ -732,14 +751,6 @@ digits. The limit on the number of characters in a string is INT_MAX characters. .IP exponent The value of the exponent in the raise operation (^) is limited to LONG_MAX. -.IP multiply -The multiply routine may yield incorrect results if a number -has more than LONG_MAX / 90 total digits. For 32 bit longs, this number is -23,860,929 digits. -.IP "code size" -Each function and the "main" program are limited to 16384 bytes of -compiled byte code each. This limit (BC_MAX_SEGS) can be easily changed -to have more than 16 segments of 1024 bytes. .IP "variable names" The current limit on the number of unique names is 32767 for each of simple variables, arrays and functions. @@ -760,12 +771,6 @@ the user wants defined every time \fBbc\fR is run. This should be an integer specifing the number of characters in an output line for numbers. This includes the backslash and newline characters for long numbers. -.SH FILES -In most installations, \fBbc\fR is completely self-contained. -Where executable size is of importance or the C compiler does -not deal with very long strings, \fBbc\fR will read -the standard math library from the file /usr/local/lib/libmath.b. -(The actual location may vary. It may be /lib/libmath.b.) .SH DIAGNOSTICS If any file on the command line can not be opened, \fBbc\fR will report that the file is unavailable and terminate. Also, there are compile @@ -774,12 +779,12 @@ and run time diagnostics that should be self-explanatory. Error recovery is not very good yet. .PP Email bug reports to -.BR bug-gnu-utils@prep.ai.mit.edu . +.BR bug-bc@gnu.org . Be sure to include the word ``bc'' somewhere in the ``Subject:'' field. .SH AUTHOR .nf Philip A. Nelson -phil@cs.wwu.edu +philnelson@acm.org .fi .SH ACKNOWLEDGEMENTS The author would like to thank Steve Sommars (Steve.Sommars@att.com) for diff --git a/contrib/bc/doc/bc.texi b/contrib/bc/doc/bc.texi new file mode 100644 index 0000000..a7cb9f6 --- /dev/null +++ b/contrib/bc/doc/bc.texi @@ -0,0 +1,1014 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename bc.info +@settitle bc Command Manual +@c %**end of header + +@c This file has the new style title page commands. +@c Run `makeinfo' rather than `texinfo-format-buffer'. + +@smallbook + +@c tex +@c \overfullrule=0pt +@c end tex + +@titlepage +@title @command{bc} +@subtitle an arbitrary precision calculator language +@subtitle version 1.06 + +@author Philip A. Nelson +@page + +This manual documents @command{bc}, an arbitrary precision calculator language. + +This manual is part of GNU @command{bc}.@* +@sp4 +Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + +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. + +@iftex +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). +@end iftex + +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 stated in a translation approved +by the Foundation. + +You may contact the author by: +e-mail: @email{phil@@cs.wwu.edu}@* +us-mail: Philip A. Nelson@* +Computer Science Department, 9062@* +Western Washington University@* +Bellingham, WA 98226-9062 + +@end titlepage + +@node Top, Introduction, (dir), (dir) + +@menu +* Introduction:: +* Basic Elements:: +* Expressions:: +* Statements:: +* Functions:: +* Examples:: +* Readline and Libedit Options:: +* GNU @command{bc} and Other Implementations:: +* Limits:: +* Environment Variables:: +@end menu + +@node Introduction, Basic Elements, Top, Top +@chapter Introduction +@menu +* Description:: +* Command Line Options:: +@end menu + +@node Description, Command Line Options, Introduction, Introduction +@section Description + +@command{bc} [ -hlwsqv ] [long-options] [ @var{ file ...} ] + +@command{bc} is a language that supports arbitrary precision numbers +with interactive execution of statements. There are some similarities +in the syntax to the C programming language. +A standard math library is available by command line option. +If requested, the math library is defined before processing any files. +@command{bc} starts by processing code from all the files listed +on the command line in the order listed. After all files have been +processed, @command{bc} reads from the standard input. All code is +executed as it is read. (If a file contains a command to halt the +processor, @command{bc} will never read from the standard input.) + +This version of @command{bc} contains several extensions beyond +traditional @command{bc} implementations and the POSIX draft standard. +Command line options can cause these extensions to print a warning or to +be rejected. This document describes the language accepted by this +processor. Extensions will be identified as such. + +The author would like to thank Steve Sommars +(@email{Steve.Sommars@@att.com}) for his extensive help in testing the +implementation. Many great suggestions were given. This is a much +better product due to his involvement. + +Email bug reports to @email{bug-bc@@gnu.org}. Be sure to include +the word ``bc'' somewhere in the ``Subject:'' field. + +@node Command Line Options, Numbers, Description, Introduction +@section Command Line Options + +@command{bc} takes the following options from the command line: +@table @code + +@item -h, --help +Print the usage and exit. + +@item -l, --mathlib +Define the standard math library. + +@item -w, --warn +Give warnings for extensions to POSIX @command{bc}. + +@item -s, --standard +Process exactly the POSIX @command{bc} language. + +@item -q, --quiet +Do not print the normal GNU @command{bc} welcome. + +@item -v, --version +Print the version number and copyright and quit. + +@end table + + +@node Basic Elements, Expressions, Introduction, Top +@chapter Basic Elements +@menu +* Numbers:: +* Variables:: +* Comments:: +@end menu + +@node Numbers, Variables, Command Line Options, Basic Elements +@section Numbers + +The most basic element in @command{bc} is the number. Numbers are +arbitrary precision numbers. This precision is both in the integer part +and the fractional part. All numbers are represented internally in +decimal and all computation is done in decimal. (This version truncates +results from divide and multiply operations.) There are two attributes +of numbers, the length and the scale. The length is the total number of +significant decimal digits in a number and the scale is the total number +of decimal digits after the decimal point. For example, .000001 has a +length of 6 and scale of 6, while 1935.000 has a length of 7 and a scale +of 3. + +@node Variables, Comments, Numbers, Basic Elements +@section Variables + +Numbers are stored in two types of variables, simple variables and +arrays. Both simple variables and array variables are named. Names +begin with a letter followed by any number of letters, digits and +underscores. All letters must be lower case. (Full alphanumeric +names are an extension. In POSIX @command{bc} all names are a single +lower case letter.) The type of variable is clear by the context +because all array variable names will be followed by brackets ( [ ] ). + +There are four special variables, @var{scale}, @var{ibase}, @var{obase}, and +@var{last}. @var{scale} defines how some operations use digits after the +decimal point. The default value of @var{scale} is 0. @var{ibase} +and @var{obase} define the conversion base for input and output +numbers. The default for both input and output is base 10. +@var{last} (an extension) is a variable that has the value of the last +printed number. These will be discussed in further detail where +appropriate. All of these variables may have values assigned to them +as well as used in expressions. + +@node Comments, , Variables, Basic Elements +@section Comments + +Comments in @command{bc} start with the characters @code{/*} and end with +the characters @code{*/}. Comments may start anywhere and appear as a +single space in the input. (This causes comments to delimit other +input items. For example, a comment can not be found in the middle of +a variable name.) Comments include any newlines (end of line) between +the start and the end of the comment. + +To support the use of scripts for @command{bc}, a single line comment has been +added as an extension. A single line comment starts at a @code{#} +character and continues to the next end of the line. The end of line +character is not part of the comment and is processed normally. + +@node Expressions, Statements, Basic Elements, Top +@chapter Expressions + +@menu +* About Expressions and Special Variables:: +* Basic Expressions:: +* Relational Expressions:: +* Boolean Expressions:: +* Precedence:: +* Special Expressions:: +@end menu + +@node About Expressions and Special Variables, Basic Expressions, Expressions, Expressions +@section About Expressions and Special Variables + +The numbers are manipulated by expressions and statements. Since +the language was designed to be interactive, statements and expressions +are executed as soon as possible. There is no main program. Instead, +code is executed as it is encountered. (Functions, discussed in +detail later, are defined when encountered.) + +A simple expression is just a constant. @command{bc} converts constants +into internal decimal numbers using the current input base, specified by +the variable @var{ibase}. (There is an exception in functions.) The +legal values of @var{ibase} are 2 through 16. Assigning a value outside +this range to @var{ibase} will result in a value of 2 or 16. Input +numbers may contain the characters 0-9 and A-F. (Note: They must be +capitals. Lower case letters are variable names.) Single digit numbers +always have the value of the digit regardless of the value of +@var{ibase}. (i.e. A = 10.) For multi-digit numbers, @command{bc} +changes all input digits greater or equal to @var{ibase} to the value of +@var{ibase}-1. This makes the number @code{FFF} always be the largest +3 digit number of the input base. + +Full expressions are similar to many other high level languages. +Since there is only one kind of number, there are no rules for mixing +types. Instead, there are rules on the scale of expressions. Every +expression has a scale. This is derived from the scale of original +numbers, the operation performed and in many cases, the value of the +variable @var{scale}. Legal values of the variable @var{scale} are +0 to the maximum number representable by a C integer. + +@node Basic Expressions, Relational Expressions, About Expressions and Special Variables, Expressions +@section Basic Expressions + +In the following descriptions of legal expressions, "expr" refers to a +complete expression and "@var{var}" refers to a simple or an array variable. +A simple variable is just a + +@var{name} + +and an array variable is specified as + +@var{name}[@var{expr}] + +Unless specifically mentioned the scale of the result is the maximum +scale of the expressions involved. + +@table @code +@item - expr +The result is the negation of the expression. + +@item ++ @var{var} +The variable is incremented by one and the new value is the result of +the expression. + +@item -- @var{var} +The variable +is decremented by one and the new value is the result of the +expression. + +@item @var{var} ++ + The result of the expression is the value of +the variable and then the variable is incremented by one. + +@item @var{var} -- +The result of the expression is the value of the variable and then +the variable is decremented by one. + +@item expr + expr +The result of the expression is the sum of the two expressions. + +@item expr - expr +The result of the expression is the difference of the two expressions. + +@item expr * expr +The result of the expression is the product of the two expressions. + +@item expr / expr +The result of the expression is the quotient of the two expressions. +The scale of the result is the value of the variable @code{scale} + +@item expr % expr +The result of the expression is the "remainder" and it is computed in the +following way. To compute a%b, first a/b is computed to @var{scale} +digits. That result is used to compute a-(a/b)*b to the scale of the +maximum of @var{scale}+scale(b) and scale(a). If @var{scale} is set +to zero and both expressions are integers this expression is the +integer remainder function. + +@item expr ^ expr +The result of the expression is the value of the first raised to the +second. The second expression must be an integer. (If the second +expression is not an integer, a warning is generated and the +expression is truncated to get an integer value.) The scale of the +result is @var{scale} if the exponent is negative. If the exponent +is positive the scale of the result is the minimum of the scale of the +first expression times the value of the exponent and the maximum of +@var{scale} and the scale of the first expression. (e.g. scale(a^b) += min(scale(a)*b, max(@var{scale}, scale(a))).) It should be noted +that expr^0 will always return the value of 1. + +@item ( expr ) +This alters the standard precedence to force the evaluation of the +expression. + +@item @var{var} = expr +The variable is assigned the value of the expression. + +@item @var{var} <op>= expr +This is equivalent to "@var{var} = @var{var} <op> expr" with the +exception that the "@var{var}" part is evaluated only once. This can +make a difference if "@var{var}" is an array. +@end table + +@node Relational Expressions, Boolean Expressions, Basic Expressions, Expressions +@section Relational Expressions + +Relational expressions are a special kind of expression that always +evaluate to 0 or 1, 0 if the relation is false and 1 if the relation is +true. These may appear in any legal expression. (POSIX @command{bc} +requires that relational expressions are used only in @code{if}, +@code{while}, and @code{for} statements and that only one relational +test may be done in them.) The relational operators are + +@table @code +@item expr1 < expr2 +The result is 1 if expr1 is strictly less than expr2. + +@item expr1 <= expr2 +The result is 1 if expr1 is less than or equal to expr2. + +@item expr1 > expr2 +The result is 1 if expr1 is strictly greater than expr2. + +@item expr1 >= expr2 +The result is 1 if expr1 is greater than or equal to expr2. + +@item expr1 == expr2 +The result is 1 if expr1 is equal to expr2. + +@item expr1 != expr2 +The result is 1 if expr1 is not equal to expr2. +@end table + +@node Boolean Expressions, Precedence, Relational Expressions, Expressions +@section Boolean Expressions + +Boolean operations are also legal. (POSIX @command{bc} does NOT have +boolean operations). The result of all boolean operations are 0 and 1 +(for false and true) as in relational expressions. The boolean +operators are: + +@table @code +@item !expr +The result is 1 if expr is 0. + +@item expr && expr +The result is 1 if both expressions are non-zero. + +@item expr || expr +The result is 1 if either expression is non-zero. +@end table + +@node Precedence, Special Expressions, Boolean Expressions, Expressions +@section Precedence + +The expression precedence is as follows: (lowest to highest) + +@example +|| operator, left associative +&& operator, left associative +! operator, nonassociative +Relational operators, left associative +Assignment operator, right associative ++ and - operators, left associative +*, / and % operators, left associative +^ operator, right associative +unary - operator, nonassociative +++ and -- operators, nonassociative +@end example + +This precedence was chosen so that POSIX compliant @command{bc} programs +will run correctly. This will cause the use of the relational and +logical operators to have some unusual behavior when used with +assignment expressions. Consider the expression: + +@example +a = 3 < 5 +@end example + +Most C programmers would assume this would assign the result of "3 < +5" (the value 1) to the variable "a". What this does in @command{bc} is +assign the value 3 to the variable "a" and then compare 3 to 5. It is +best to use parentheses when using relational and logical operators +with the assignment operators. + +@node Special Expressions, , Precedence, Expressions +@section Special Expressions + +There are a few more special expressions that are provided in +@command{bc}. These have to do with user-defined functions and standard +functions. They all appear as +"@var{name}@code{(}@var{parameters}@code{)}". @xref{Functions}, for +user-defined functions. The standard functions are: + +@table @code +@item length ( expression ) +The value of the length function is the number of significant digits in the +expression. + +@item read ( ) +The @code{read} function (an extension) will read a number from the +standard input, regardless of where the function occurs. Beware, this +can cause problems with the mixing of data and program in the standard +input. The best use for this function is in a previously written +program that needs input from the user, but never allows program code to +be input from the user. The value of the @code{read} function is the +number read from the standard input using the current value of the +variable @var{ibase} for the conversion base. + +@item scale ( expression ) +The value of the @code{scale} function is the number of digits after the +decimal point in the expression. + +@item sqrt ( expression ) +The value of the @code{sqrt} function is the square root of the +expression. If the expression is negative, a run time error is +generated. +@end table + +@node Statements, Functions, Expressions, Top +@chapter Statements + +@menu +* Pseudo Statements:: +@end menu + +Statements (as in most algebraic languages) provide the sequencing of +expression evaluation. In @command{bc} statements are executed "as soon +as possible." Execution happens when a newline in encountered and there +is one or more complete statements. Due to this immediate execution, +newlines are very important in @command{bc}. In fact, both a semicolon +and a newline are used as statement separators. An improperly placed +newline will cause a syntax error. Because newlines are statement +separators, it is possible to hide a newline by using the backslash +character. The sequence "\<nl>", where <nl> is the newline appears to +@command{bc} as whitespace instead of a newline. A statement list is a +series of statements separated by semicolons and newlines. The +following is a list of @command{bc} statements and what they do: (Things +enclosed in brackets ( [ ] ) are optional parts of the statement.) + +@table @var +@item expression +This statement does one of two things. If the expression starts with +"<variable> <assignment> ...", it is considered to be an assignment +statement. If the expression is not an assignment statement, the +expression is evaluated and printed to the output. After the number is +printed, a newline is printed. For example, "a=1" is an assignment +statement and "(a=1)" is an expression that has an embedded assignment. +All numbers that are printed are printed in the base specified by the +variable @var{obase}. The legal values for @var{obase} are 2 through +BC_BASE_MAX (@pxref{Environment Variables}). For bases 2 through 16, +the usual method of writing numbers is used. For bases greater than 16, +@command{bc} uses a multi-character digit method of printing the numbers +where each higher base digit is printed as a base 10 number. The +multi-character digits are separated by spaces. Each digit contains the +number of characters required to represent the base ten value of +"@var{obase} -1". Since numbers are of arbitrary precision, some +numbers may not be printable on a single output line. These long +numbers will be split across lines using the "\" as the last character +on a line. The maximum number of characters printed per line is 70. +Due to the interactive nature of @command{bc}, printing a number causes +the side effect of assigning the printed value to the special variable +@var{last}. This allows the user to recover the last value printed +without having to retype the expression that printed the number. +Assigning to @var{last} is legal and will overwrite the last printed +value with the assigned value. The newly assigned value will remain +until the next number is printed or another value is assigned to +@var{last}. (Some installations may allow the use of a single period +(.) which is not part of a number as a short hand notation for for +@var{last}.) + +@item string +The string is printed to the output. Strings start with a double quote +character and contain all characters until the next double quote character. +All characters are taken literally, including any newline. No newline +character is printed after the string. + +@item @code{print} @var{list} +The @code{print} statement (an extension) provides another method of +output. The @var{list} is a list of strings and expressions separated by +commas. Each string or expression is printed in the order of the list. +No terminating newline is printed. Expressions are evaluated and their +value is printed and assigned to the variable @code{last}. Strings in +the print statement are printed to the output and may contain special +characters. Special characters start with the backslash character (\e). +The special characters recognized by @command{bc} are "a" (alert or +bell), "b" (backspace), "f" (form feed), "n" (newline), "r" (carriage +return), "q" (double quote), "t" (tab), and "\e" (backslash). Any other +character following the backslash will be ignored. + +@item @{ statement_list @} +This is the compound statement. It allows multiple statements to be +grouped together for execution. + +@item @code{if} ( expression ) statement1 [@code{else} statement2] +The if statement evaluates the expression and executes statement1 or +statement2 depending on the value of the expression. If the expression +is non-zero, statement1 is executed. If statement2 is present and +the value of the expression is 0, then statement2 is executed. (The +@code{else} clause is an extension.) + +@item @code{while} ( expression ) statement +The while statement will execute the statement while the expression +is non-zero. It evaluates the expression before each execution of +the statement. Termination of the loop is caused by a zero +expression value or the execution of a @code{break} statement. + +@item @code{for} ( [expression1] ; [expression2] ; [expression3] ) statement +The @code{for} statement controls repeated execution of the statement. +@var{Expression1} is evaluated before the loop. @var{Expression2} is +evaluated before each execution of the statement. If it is non-zero, +the statement is evaluated. If it is zero, the loop is terminated. +After each execution of the statement, @var{expression3} is evaluated +before the reevaluation of expression2. If @var{expression1} or +@var{expression3} are missing, nothing is evaluated at the point they +would be evaluated. If @var{expression2} is missing, it is the same as +substituting the value 1 for @var{expression2}. (The optional +expressions are an extension. POSIX @command{bc} requires all three +expressions.) The following is equivalent code for the @code{for} +statement: + +@example +expression1; +while (expression2) @{ + statement; + expression3; +@} +@end example + +@item @code{break} +This statement causes a forced exit of the most recent enclosing @code{while} +statement or @code{for} statement. + +@item @code{continue} +The @code{continue} statement (an extension) causes the most recent enclosing +@code{for} statement to start the next iteration. + +@item @code{halt} +The @code{halt} statement (an extension) is an executed statement that +causes the @command{bc} processor to quit only when it is executed. For +example, "if (0 == 1) halt" will not cause @command{bc} to terminate +because the @code{halt} is not executed. + +@item @code{return} +Return the value 0 from a function. (@xref{Functions}.) + +@item @code{return} ( expression ) +Return the value of the expression from a function. (@xref{Functions}.) +As an extension, the parenthesis are not required. +@end table + +@node Pseudo Statements, , Statements, Statements +@section Pseudo Statements + +These statements are not statements in the traditional sense. They are +not executed statements. Their function is performed at "compile" time. + +@table @code +@item limits +Print the local limits enforced by the local version of @command{bc}. This +is an extension. + +@item quit +When the @code{quit} statement is read, the @command{bc} processor +is terminated, regardless of where the @code{quit} statement is found. For +example, "if (0 == 1) quit" will cause @command{bc} to terminate. + +@item warranty +Print a longer warranty notice. This is an extension. +@end table + +@node Functions, Examples, Statements, Top +@chapter Functions + +@menu +* Math Library Functions:: +@end menu + +Functions provide a method of defining a computation that can be +executed later. Functions in @command{bc} always compute a value and +return it to the caller. Function definitions are "dynamic" in the +sense that a function is undefined until a definition is encountered in +the input. That definition is then used until another definition +function for the same name is encountered. The new definition then +replaces the older definition. A function is defined as follows: + +@example +@code{define} @var{name} @code{(} @var{parameters} @code{)} @code{@{} @var{newline} + @var{auto_list statement_list} @code{@}} +@end example + +A function call is just an expression of the form +"@code{name} @code{(}@var{parameters}@code{)}". + +Parameters are numbers or arrays (an extension). In the function definition, +zero or more parameters are defined by listing their names separated by +commas. Numbers are only call by value parameters. Arrays are only +call by variable. Arrays are specified in the parameter definition by +the notation "@var{name}@code{[ ]}". In the function call, actual parameters +are full expressions for number parameters. The same notation is used +for passing arrays as for defining array parameters. The named array is +passed by variable to the function. Since function definitions are dynamic, +parameter numbers and types are checked when a function is called. Any +mismatch in number or types of parameters will cause a runtime error. +A runtime error will also occur for the call to an undefined function. + +The @var{auto_list} is an optional list of variables that are for +"local" use. The syntax of the auto list (if present) is "@code{auto} +@var{name}, ... ;". (The semicolon is optional.) Each @var{name} is +the name of an auto variable. Arrays may be specified by using the +same notation as used in parameters. These variables have their +values pushed onto a stack at the start of the function. The +variables are then initialized to zero and used throughout the +execution of the function. At function exit, these variables are +popped so that the original value (at the time of the function call) +of these variables are restored. The parameters are really auto +variables that are initialized to a value provided in the function +call. +Auto variables are different than traditional local variables +because if function A calls function B, B may access function +A's auto variables by just using the same name, unless function B has +called them auto variables. Due to the fact that auto variables and +parameters are pushed onto a stack, @command{bc} supports recursive functions. + +The function body is a list of @command{bc} statements. Again, statements +are separated by semicolons or newlines. Return statements cause the +termination of a function and the return of a value. There are two +versions of the return statement. The first form, "@code{return}", returns +the value 0 to the calling expression. The second form, +"@code{return} ( @var{expression} )", computes the value of the expression +and returns that value to the calling expression. There is an implied +"@code{return} (0)" at the end of every function. This allows a function +to terminate and return 0 without an explicit @code{return} statement. + +Functions also change the usage of the variable @var{ibase}. All +constants in the function body will be converted using the value of +@var{ibase} at the time of the function call. Changes of @var{ibase} +will be ignored during the execution of the function except for the +standard function @code{read}, which will always use the current value +of @var{ibase} for conversion of numbers. + +As an extension, the format of the definition has been slightly relaxed. +The standard requires the opening brace be on the same line as the +@code{define} keyword and all other parts must be on following lines. +This version of @command{bc} will allow any number of newlines before and +after the opening brace of the function. For example, the following +definitions are legal. + +@example + define d (n) @{ return (2*n); @} + define d (n) + @{ return (2*n); @} +@end example + + +@node Math Library Functions, , Functions, Functions +@section Math Library Functions + +If @command{bc} is invoked with the @code{-l} option, a math library is +preloaded and the default @var{scale} is set to 20. The math functions will +calculate their results to the scale set at the time of their call. The +math library defines the following functions: + +@table @code +@item s (@var{x}) +The sine of @var{x}, @var{x} is in radians. + +@item c (@var{x}) +The cosine of @var{x}, @var{x} is in radians. + +@item a (@var{x}) +The arctangent of @var{x}, arctangent returns radians. + +@item l (@var{x}) +The natural logarithm of @var{x}. + +@item @var{e} (@var{x}) +The exponential function of raising @var{e} to the value @var{x}. + +@item @var{j} (@var{n,x}) +The bessel function of integer order @var{n} of @var{x}. +@end table + +@node Examples, Readline and Libedit Options, Functions, Top +@chapter Examples + +In /bin/sh, the following will assign the value of "pi" to the shell +variable @var{pi}. +@example + +pi=$(echo "scale=10; 4*a(1)" | bc -l) + +@end example + +The following is the definition of the exponential function used in the +math library. This function is written in POSIX @command{bc}. + +@example + +scale = 20 + +/* Uses the fact that e^x = (e^(x/2))^2 + When x is small enough, we use the series: + e^x = 1 + x + x^2/2! + x^3/3! + ... +*/ + +define e(x) @{ + auto a, d, e, f, i, m, v, z + + /* Check the sign of x. */ + if (x<0) @{ + m = 1 + x = -x + @} + + /* Precondition x. */ + z = scale; + scale = 4 + z + .44*x; + while (x > 1) @{ + f += 1; + x /= 2; + @} + + /* Initialize the variables. */ + v = 1+x + a = x + d = 1 + + for (i=2; 1; i++) @{ + e = (a *= x) / (d *= i) + if (e == 0) @{ + if (f>0) while (f--) v = v*v; + scale = z + if (m) return (1/v); + return (v/1); + @} + v += e + @} +@} + +@end example + +The following is code that uses the extended features of @command{bc} to +implement a simple program for calculating checkbook balances. This +program is best kept in a file so that it can be used many times +without having to retype it at every use. + +@example + +scale=2 +print "\nCheck book program\n!" +print " Remember, deposits are negative transactions.\n" +print " Exit by a 0 transaction.\n\n" + +print "Initial balance? "; bal = read() +bal /= 1 +print "\n" +while (1) @{ + "current balance = "; bal + "transaction? "; trans = read() + if (trans == 0) break; + bal -= trans + bal /= 1 +@} +quit + +@end example + + +The following is the definition of the recursive factorial function. + +@example + +define f (x) @{ + if (x <= 1) return (1); + return (f(x-1) * x); +@} + +@end example + +@node Readline and Libedit Options, GNU @command{bc} and Other Implementations, Examples, Top +@chapter Readline and Libedit Options + +GNU @command{bc} can be compiled (via a configure option) to use the GNU +@command{readline} input editor library or the BSD @command{libedit} +library. This allows the user to do +more editing of lines before sending them to @command{bc}. It also +allows for a history of previous lines typed. When this option is +selected, @command{bc} has one more special variable. This special +variable, @var{history} is the number of lines of history retained. A +value of -1 means that an unlimited number of history lines are +retained. This is the default value. Setting the value of +@var{history} to a positive number restricts the number of history lines +to the number given. The value of 0 disables the history feature. For +more information, read the user manuals for the GNU @command{readline}, +@command{history} and BSD @command{libedit} libraries. One can not +enable both @command{readline} and @command{libedit} at the same time. + +@node GNU @command{bc} and Other Implementations, Limits, Readline and Libedit Options, Top +@chapter GNU @command{bc} and Other Implementations + +This version of @command{bc} was implemented from the POSIX P1003.2/D11 +draft and contains several differences and extensions relative to the +draft and traditional implementations. It is not implemented in the +traditional way using @command{dc}. This version is a single process +which parses and runs a byte code translation of the program. There is +an "undocumented" option (-c) that causes the program to output the byte +code to the standard output instead of running it. It was mainly used +for debugging the parser and preparing the math library. + +A major source of differences is extensions, where a feature is extended +to add more functionality and additions, where new features are added. +The following is the list of differences and extensions. + +@table @var + +@item LANG environment +This version does not conform to the POSIX standard in the processing +of the LANG environment variable and all environment variables starting +with LC_. + +@item names +Traditional and POSIX @command{bc} +have single letter names for functions, variables and arrays. They have +been extended to be multi-character names that start with a letter and +may contain letters, numbers and the underscore character. + +@item Strings +Strings are not allowed to contain NUL characters. POSIX says all characters +must be included in strings. + +@item last +POSIX @command{bc} does not have a \fBlast variable. Some implementations +of @command{bc} use the period (.) in a similar way. + +@item comparisons +POSIX @command{bc} allows comparisons only in the @code{if} statement, +the @code{while} statement, and the second expression of the @code{for} +statement. Also, only one relational operation is allowed in each of +those statements. + +@item if statement, else clause +POSIX @command{bc} does not have an @code{else} clause. + +@item for statement +POSIX @command{bc} requires all expressions to be present in the +@code{for} statement. + +@item &&, ||, ! +POSIX @command{bc} does not have the logical operators. + +@item read function +POSIX @command{bc} does not have a @code{read} function. + +@item print statement +POSIX @command{bc} does not have a @code{print} statement. + +@item continue statement +POSIX @command{bc} does not have a continue statement. + +@item array parameters +POSIX @command{bc} does not (currently) support array parameters in full. +The POSIX grammar allows for arrays in function definitions, but does +not provide a method to specify an array as an actual parameter. (This +is most likely an oversight in the grammar.) Traditional implementations +of @command{bc} have only call by value array parameters. + +@item function format +POSIX @command{bc} requires the opening brace on the same line as the +@code{define} key word and the @code{auto} statement on the next line. + +@item =+, =-, =*, =/, =%, =^ +POSIX @command{bc} does not require these "old style" assignment +operators to be defined. This version may allow these "old style" +assignments. Use the @code{limits} statement to see if the installed +version supports them. If it does support the "old style" assignment +operators, the statement "a =- 1" will decrement @code{a} by 1 instead +of setting @code{a} to the value -1. + +@item spaces in numbers +Other implementations of @command{bc} allow spaces in numbers. For example, +"x=1 3" would assign the value 13 to the variable x. The same statement +would cause a syntax error in this version of @command{bc}. + +@item errors and execution +This implementation varies from other implementations in terms of what +code will be executed when syntax and other errors are found in the +program. If a syntax error is found in a function definition, error +recovery tries to find the beginning of a statement and continue to +parse the function. Once a syntax error is found in the function, the +function will not be callable and becomes undefined. +Syntax errors in the interactive execution code will invalidate the +current execution block. The execution block is terminated by an +end of line that appears after a complete sequence of statements. +For example, + +@example +a = 1 +b = 2 +@end example + +has two execution blocks and + +@example +@{ a = 1 + b = 2 @} +@end example + +has one execution block. Any runtime error will terminate the execution +of the current execution block. A runtime warning will not terminate the +current execution block. + +@item Interrupts +During an interactive session, the SIGINT signal (usually generated by +the control-C character from the terminal) will cause execution of the +current execution block to be interrupted. It will display a "runtime" +error indicating which function was interrupted. After all runtime +structures have been cleaned up, a message will be printed to notify the +user that @command{bc} is ready for more input. All previously defined +functions remain defined and the value of all non-auto variables are the +value at the point of interruption. All auto variables and function +parameters are removed during the clean up process. During a +non-interactive session, the SIGINT signal will terminate the entire run +of @command{bc}. +@end table + +@node Limits, Environment Variables, GNU @command{bc} and Other Implementations, Top +@chapter Limits + +The following are the limits currently in place for this @command{bc} +processor. Some of them may have been changed by an installation. Use +the @code{limits} statement to see the actual values. + +@table @code + +@item BC_BASE_MAX +The maximum output base is currently set at 999. The maximum input base +is 16. + +@item BC_DIM_MAX +This is currently an arbitrary limit of 65535 as distributed. Your +installation may be different. + +@item BC_SCALE_MAX +The number of digits after the decimal point is limited to INT_MAX digits. +Also, the number of digits before the decimal point is limited to INT_MAX +digits. + +@item BC_STRING_MAX +The limit on the number of characters in a string is INT_MAX characters. + +@item exponent +The value of the exponent in the raise operation (^) is limited to LONG_MAX. + +@item multiply +The multiply routine may yield incorrect results if a number +has more than LONG_MAX / 90 total digits. For 32 bit longs, this number is +23,860,929 digits. + +@item variable names +The current limit on the number of unique names is 32767 for each of +simple variables, arrays and functions. +@end table + +@node Environment Variables, , Limits, Top +@chapter Environment Variables + +The following environment variables are processed by @command{bc}: + +@table @code + + +@item POSIXLY_CORRECT +This is the same as the -s option (@pxref{Command Line Options}). + +@item BC_ENV_ARGS +This is another mechanism to get arguments to @command{bc}. The format +is the same as the command line arguments. These arguments are +processed first, so any files listed in the environent arguments are +processed before any command line argument files. This allows the user +to set up "standard" options and files to be processed at every +invocation of @command{bc}. The files in the environment variables +would typically contain function definitions for functions the user +wants defined every time @command{bc} is run. + +@item BC_LINE_LENGTH +This should be an integer specifing the number of characters in an +output line for numbers. This includes the backslash and newline +characters for long numbers. +@end table + +@contents +@bye + + diff --git a/contrib/bc/doc/dc.1 b/contrib/bc/doc/dc.1 index dd1357a..7a136a7 100644 --- a/contrib/bc/doc/dc.1 +++ b/contrib/bc/doc/dc.1 @@ -2,7 +2,7 @@ .\" dc.1 - the *roff document processor source for the dc manual .\" .\" This file is part of GNU dc. -.\" Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. +.\" Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by @@ -15,8 +15,10 @@ .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License -.\" along with this program; see the file COPYING. If not, write to -.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +.\" along with this program; see the file COPYING. If not, write to: +.\" The Free Software Foundation, Inc. +.\" 59 Temple Place, Suite 330 +.\" Boston, MA 02111 USA .\" .TH DC 1 "1997-03-25" "GNU Project" .ds dc \fIdc\fP @@ -24,7 +26,10 @@ .SH NAME dc \- an arbitrary precision calculator .SH SYNOPSIS -dc +dc [-V] [--version] [-h] [--help] + [-e scriptexpression] [--expression=scriptexpression] + [-f scriptfile] [--file=scriptfile] + [file ...] .SH DESCRIPTION .PP \*(Dc is a reverse-polish desk calculator which supports @@ -52,6 +57,43 @@ as it is a binary operator for subtraction instead. To enter two numbers in succession, separate them with spaces or newlines. These have no meaning as commands. +.SH OPTIONS +\*(Dc may be invoked with the following command-line options: +.TP +.B -V +.TP +.B --version +Print out the version of \*(dc that is being run and a copyright notice, +then exit. +.TP +.B -h +.TP +.B --help +Print a usage message briefly summarizing these command-line options +and the bug-reporting address, +then exit. +.TP +.B -e \fIscript\fP +.TP +.BI --expression= script +Add the commands in +.I script +to the set of commands to be run while processing the input. +.TP +.B -f \fIscript-file\fP +.TP +.BI --file= script-file +Add the commands contained in the file +.I script-file +to the set of commands to be run while processing the input. +.PP +If any command-line parameters remain after processing the above, +these parameters are interpreted as the names of input files to +be processed. +A file name of +.B - +refers to the standard input stream. +The standard input will processed if no file names are specified. .PD .SH Printing Commands @@ -149,7 +191,7 @@ and any fractional part of this exponent will be ignored. The third value popped is the base which gets exponentiated, which should be an integer. For small integers this is like the sequence \fBSm^Lm%\fP, -but, unlike \fB^\fP, this command will work with arbritrarily large exponents. +but, unlike \fB^\fP, this command will work with arbitrarily large exponents. .TP .B v Pops one value, @@ -415,7 +457,7 @@ Miscellaneous .TP .B ! Will run the rest of the line as a system command. -Note that parsing of the !<, !=, and !> commands take precidence, +Note that parsing of the !<, !=, and !> commands take precedence, so if you want to run a command starting with <, =, or > you will need to add a space after the !. .TP @@ -443,5 +485,4 @@ was later popped. BUGS .PP Email bug reports to -.BR bug-gnu-utils@prep.ai.mit.edu . -Be sure to include the word ``dc'' somewhere in the ``Subject:'' field. +.BR bug-dc@gnu.org . diff --git a/contrib/bc/doc/dc.texi b/contrib/bc/doc/dc.texi index 968a819..0a4d973 100644 --- a/contrib/bc/doc/dc.texi +++ b/contrib/bc/doc/dc.texi @@ -21,13 +21,16 @@ @syncodeindex tp fn @ifinfo +@direntry +* dc: (dc). Arbritrary precision RPN ``Desktop Calculator''. +@end direntry This file documents @sc{dc}, an arbitrary precision calculator. -Published by the Free Software Foundation, -675 Massachusetts Avenue, -Cambridge, MA 02139 USA +Published by the Free Software Foundation, Inc. +59 Temple Place, Suite 330 +Boston, MA 02111 USA -Copyright (C) 1984, 1994, 1997, 1998 Free Software Foundation, Inc. +Copyright (C) 1984, 1994, 1997, 1998, 2000 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -64,8 +67,8 @@ Copyright @copyright{} 1994, 1997, 1998 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation, @* -675 Massachusetts Avenue, @* -Cambridge, MA 02139 USA +59 Temple Place, Suite 330 @* +Boston, MA 02111 USA Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -518,8 +521,6 @@ that was later popped. @node Reporting bugs, , Miscellaneous, Top @chapter Reporting bugs -Email bug reports to @code{bug-gnu-utils@@prep.ai.mit.edu}. -Be sure to include the word ``dc'' somewhere in the ``Subject:'' field. - +Email bug reports to @email{bug-dc@@gnu.org}. @contents @bye diff --git a/contrib/bc/h/number.h b/contrib/bc/h/number.h index 6ead2f57..8d78120 100644 --- a/contrib/bc/h/number.h +++ b/contrib/bc/h/number.h @@ -1,7 +1,6 @@ /* number.h: Arbitrary precision numbers header file. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. +/* + Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,11 +13,15 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program; see the file COPYING. If not, write to: + + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111-1307 USA. + You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University @@ -26,20 +29,29 @@ *************************************************************************/ +#ifndef _NUMBER_H_ +#define _NUMBER_H_ typedef enum {PLUS, MINUS} sign; -typedef struct +typedef struct bc_struct *bc_num; + +typedef struct bc_struct { - sign n_sign; - int n_len; /* The number of digits before the decimal point. */ - int n_scale; /* The number of digits after the decimal point. */ - int n_refs; /* The number of pointers to this number. */ - char n_value[1]; /* The storage. Not zero char terminated. It is - allocated with all other fields. */ + sign n_sign; + int n_len; /* The number of digits before the decimal point. */ + int n_scale; /* The number of digits after the decimal point. */ + int n_refs; /* The number of pointers to this number. */ + bc_num n_next; /* Linked list for available list. */ + char *n_ptr; /* The pointer to the actual storage. + If NULL, n_value points to the inside of + another number (bc_multiply...) and should + not be "freed." */ + char *n_value; /* The number. Not zero char terminated. + May not point to the same place as n_ptr as + in the case of leading zeros generated. */ } bc_struct; -typedef bc_struct *bc_num; /* The base used in storing the numbers in n_value above. Currently this MUST be 10. */ @@ -63,3 +75,79 @@ typedef bc_struct *bc_num; #define TRUE 1 #define FALSE 0 #endif + +#ifndef LONG_MAX +#define LONG_MAX 0x7ffffff +#endif + + +/* Global numbers. */ +extern bc_num _zero_; +extern bc_num _one_; +extern bc_num _two_; + + +/* Function Prototypes */ + +/* Define the _PROTOTYPE macro if it is needed. */ + +#ifndef _PROTOTYPE +#ifdef __STDC__ +#define _PROTOTYPE(func, args) func args +#else +#define _PROTOTYPE(func, args) func() +#endif +#endif + +_PROTOTYPE(void bc_init_numbers, (void)); + +_PROTOTYPE(bc_num bc_new_num, (int length, int scale)); + +_PROTOTYPE(void bc_free_num, (bc_num *num)); + +_PROTOTYPE(bc_num bc_copy_num, (bc_num num)); + +_PROTOTYPE(void bc_init_num, (bc_num *num)); + +_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale)); + +_PROTOTYPE(char *bc_num2str, (bc_num num)); + +_PROTOTYPE(void bc_int2num, (bc_num *num, int val)); + +_PROTOTYPE(long bc_num2long, (bc_num num)); + +_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2)); + +_PROTOTYPE(char bc_is_zero, (bc_num num)); + +_PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale)); + +_PROTOTYPE(char bc_is_neg, (bc_num num)); + +_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result, int scale_min)); + +_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result, int scale_min)); + +_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale)); + +_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale)); + +_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result, + int scale)); + +_PROTOTYPE(int bc_divmod, (bc_num num1, bc_num num2, bc_num *quot, + bc_num *rem, int scale)); + +_PROTOTYPE(int bc_raisemod, (bc_num base, bc_num expo, bc_num mod, + bc_num *result, int scale)); + +_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result, + int scale)); + +_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale)); + +_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int), + int leading_zero)); + +#endif diff --git a/contrib/bc/lib/Makefile.am b/contrib/bc/lib/Makefile.am index bf33e3f..6f74b4d 100644 --- a/contrib/bc/lib/Makefile.am +++ b/contrib/bc/lib/Makefile.am @@ -1,9 +1,26 @@ ## Process this file with automake to produce Makefile.in noinst_LIBRARIES = libbc.a -INCLUDES = -I$(srcdir) -I$(srcdir)/../h +INCLUDES = -I. -I.. -I$(srcdir)/../h libbc_a_SOURCES = getopt.c getopt1.c vfprintf.c number.c -#libbc_LIBADD = @LIBOBJS@ -#libbc_DEPENDENCIES = $(bc_LIBADD) +DEFS = @DEFS@ $(DEFSADD) + +CFLAGS = @CFLAGS@ -Wall -funsigned-char + +MAINTAINERCLEANFILES = Makefile.in number.c + +newnumber.o: number.c muldigits.h + $(CC) $(CFLAGS) $(INCLUDES) -c -DMULDIGITS -o newnumber.o $(srcdir)/number.c + +muldigits.h: testmul + @echo "The following may take up to 10 minutes." + testmul > muldigits.h + +testmul: testmul.o number.o + $(CC) $(CFLAGS) -o testmul testmul.o number.o + +specialnumber: newnumber.o + cp newnumber.o number.o + diff --git a/contrib/bc/lib/Makefile.in b/contrib/bc/lib/Makefile.in index 4d3ca83..5ffa593 100644 --- a/contrib/bc/lib/Makefile.in +++ b/contrib/bc/lib/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.3 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,7 +11,7 @@ # PARTICULAR PURPOSE. -SHELL = /bin/sh +SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -32,7 +32,7 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include -DISTDIR = +DESTDIR = pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ @@ -62,45 +62,49 @@ LEX = @LEX@ MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ +READLINELIB = @READLINELIB@ VERSION = @VERSION@ YACC = @YACC@ noinst_LIBRARIES = libbc.a -INCLUDES = -I$(srcdir) -I$(srcdir)/../h +INCLUDES = -I. -I.. -I$(srcdir)/../h libbc_a_SOURCES = getopt.c getopt1.c vfprintf.c number.c + +DEFS = @DEFS@ $(DEFSADD) + +CFLAGS = @CFLAGS@ -Wall -funsigned-char + +MAINTAINERCLEANFILES = Makefile.in number.c mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) - -DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libbc_a_LIBADD = libbc_a_OBJECTS = getopt.o getopt1.o vfprintf.o number.o AR = ar -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar -GZIP = --best +GZIP_ENV = --best SOURCES = $(libbc_a_SOURCES) OBJECTS = $(libbc_a_OBJECTS) -all: Makefile $(LIBRARIES) - +all: all-redirect .SUFFIXES: .SUFFIXES: .S .c .o .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @@ -144,8 +148,12 @@ libbc.a: $(libbc_a_OBJECTS) $(libbc_a_DEPENDENCIES) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) + && mkid -f$$here/ID $$unique $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ @@ -173,73 +181,102 @@ subdir = lib distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ done -info: -dvi: -check: all - $(MAKE) -installcheck: -install-exec: - @$(NORMAL_INSTALL) - -install-data: - @$(NORMAL_INSTALL) - -install: install-exec install-data all - @: - -uninstall: - +getopt.o: getopt.c ../config.h ../h/getopt.h +getopt1.o: getopt1.c ../config.h ../h/getopt.h +number.o: number.c ../config.h ../h/number.h +vfprintf.o: vfprintf.c ../config.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install installdirs: mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(DISTCLEANFILES) + -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \ +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean-tags mostlyclean-generic -clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ - mostlyclean +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am -distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \ - distclean-generic clean - -rm -f config.status +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am -maintainer-clean: maintainer-clean-noinstLIBRARIES \ +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-generic distclean + maintainer-clean-generic distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." +maintainer-clean: maintainer-clean-am + .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir info dvi installcheck \ -install-exec install-data install uninstall all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +newnumber.o: number.c muldigits.h + $(CC) $(CFLAGS) $(INCLUDES) -c -DMULDIGITS -o newnumber.o $(srcdir)/number.c + +muldigits.h: testmul + @echo "The following may take up to 10 minutes." + testmul > muldigits.h +testmul: testmul.o number.o + $(CC) $(CFLAGS) -o testmul testmul.o number.o -#libbc_LIBADD = @LIBOBJS@ -#libbc_DEPENDENCIES = $(bc_LIBADD) +specialnumber: newnumber.o + cp newnumber.o number.o # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/contrib/bc/lib/number.c b/contrib/bc/lib/number.c index 469d44c8b..1f913d5 100644 --- a/contrib/bc/lib/number.c +++ b/contrib/bc/lib/number.c @@ -1,7 +1,6 @@ /* number.c: Implements arbitrary precision numbers. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc. +/* + Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,70 +13,98 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program; see the file COPYING. If not, write to: + + The Free Software Foundation, Inc. + 59 Temple Place, Suite 330 + Boston, MA 02111-1307 USA. + You may contact the author by: - e-mail: phil@cs.wwu.edu + e-mail: philnelson@acm.org us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University Bellingham, WA 98226-9062 - + *************************************************************************/ -#include "bcdefs.h" -#include "proto.h" -#include "global.h" +#include <stdio.h> +#include <config.h> +#include <number.h> +#include <assert.h> +#include <stdlib.h> +#include <ctype.h>/* Prototypes needed for external utility routines. */ + +#define bc_rt_warn rt_warn +#define bc_rt_error rt_error +#define bc_out_of_memory out_of_memory + +_PROTOTYPE(void rt_warn, (char *mesg ,...)); +_PROTOTYPE(void rt_error, (char *mesg ,...)); +_PROTOTYPE(void out_of_memory, (void)); /* Storage used for special numbers. */ bc_num _zero_; bc_num _one_; bc_num _two_; - -/* "Frees" a bc_num NUM. Actually decreases reference count and only - frees the storage if reference count is zero. */ - -void -free_num (num) - bc_num *num; -{ - if (*num == NULL) return; - (*num)->n_refs--; - if ((*num)->n_refs == 0) free(*num); - *num = NULL; -} - +static bc_num _bc_Free_list = NULL; /* new_num allocates a number and sets fields to known values. */ bc_num -new_num (length, scale) +bc_new_num (length, scale) int length, scale; { bc_num temp; - temp = (bc_num) malloc (sizeof(bc_struct)+length+scale); - if (temp == NULL) out_of_memory (); + if (_bc_Free_list != NULL) { + temp = _bc_Free_list; + _bc_Free_list = temp->n_next; + } else { + temp = (bc_num) malloc (sizeof(bc_struct)); + if (temp == NULL) bc_out_of_memory (); + } temp->n_sign = PLUS; temp->n_len = length; temp->n_scale = scale; temp->n_refs = 1; - temp->n_value[0] = 0; + temp->n_ptr = (char *) malloc (length+scale); + if (temp->n_ptr == NULL) bc_out_of_memory(); + temp->n_value = temp->n_ptr; + memset (temp->n_ptr, 0, length+scale); return temp; } +/* "Frees" a bc_num NUM. Actually decreases reference count and only + frees the storage if reference count is zero. */ + +void +bc_free_num (num) + bc_num *num; +{ + if (*num == NULL) return; + (*num)->n_refs--; + if ((*num)->n_refs == 0) { + if ((*num)->n_ptr) + free ((*num)->n_ptr); + (*num)->n_next = _bc_Free_list; + _bc_Free_list = *num; + } + *num = NULL; +} + /* Intitialize the number package! */ void -init_numbers () +bc_init_numbers () { - _zero_ = new_num (1,0); - _one_ = new_num (1,0); + _zero_ = bc_new_num (1,0); + _one_ = bc_new_num (1,0); _one_->n_value[0] = 1; - _two_ = new_num (1,0); + _two_ = bc_new_num (1,0); _two_->n_value[0] = 2; } @@ -85,7 +112,7 @@ init_numbers () /* Make a copy of a number! Just increments the reference count! */ bc_num -copy_num (num) +bc_copy_num (num) bc_num num; { num->n_refs++; @@ -96,105 +123,34 @@ copy_num (num) /* Initialize a number NUM by making it a copy of zero. */ void -init_num (num) +bc_init_num (num) bc_num *num; { - *num = copy_num (_zero_); + *num = bc_copy_num (_zero_); } +/* For many things, we may have leading zeros in a number NUM. + _bc_rm_leading_zeros just moves the data "value" pointer to the + correct place and adjusts the length. */ -/* Convert an integer VAL to a bc number NUM. */ - -void -int2num (num, val) - bc_num *num; - int val; -{ - char buffer[30]; - char *bptr, *vptr; - int ix = 1; - char neg = 0; - - /* Sign. */ - if (val < 0) - { - neg = 1; - val = -val; - } - - /* Get things going. */ - bptr = buffer; - *bptr++ = val % BASE; - val = val / BASE; - - /* Extract remaining digits. */ - while (val != 0) - { - *bptr++ = val % BASE; - val = val / BASE; - ix++; /* Count the digits. */ - } - - /* Make the number. */ - free_num (num); - *num = new_num (ix, 0); - if (neg) (*num)->n_sign = MINUS; - - /* Assign the digits. */ - vptr = (*num)->n_value; - while (ix-- > 0) - *vptr++ = *--bptr; -} - - -/* Convert a number NUM to a long. The function returns only the integer - part of the number. For numbers that are too large to represent as - a long, this function returns a zero. This can be detected by checking - the NUM for zero after having a zero returned. */ - -long -num2long (num) +static void +_bc_rm_leading_zeros (num) bc_num num; { - long val; - char *nptr; - int index; - - /* Extract the int value, ignore the fraction. */ - val = 0; - nptr = num->n_value; - for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--) - val = val*BASE + *nptr++; - - /* Check for overflow. If overflow, return zero. */ - if (index>0) val = 0; - if (val < 0) val = 0; - - /* Return the value. */ - if (num->n_sign == PLUS) - return (val); - else - return (-val); + /* We can move n_value to point to the first non zero digit! */ + while (*num->n_value == 0 && num->n_len > 1) { + num->n_value++; + num->n_len--; + } } -/* The following are some math routines for numbers. */ -_PROTOTYPE(static int _do_compare, (bc_num n1, bc_num n2, int use_sign, - int ignore_last)); -_PROTOTYPE(static void _rm_leading_zeros, (bc_num num)); -_PROTOTYPE(static bc_num _do_add, (bc_num n1, bc_num n2, int scale_min)); -_PROTOTYPE(static bc_num _do_sub, (bc_num n1, bc_num n2, int scale_min)); -_PROTOTYPE(static void _one_mult, (unsigned char *num, int size, int digit, - unsigned char *result)); - - - /* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just compare the magnitudes. */ static int -_do_compare (n1, n2, use_sign, ignore_last) +_bc_do_compare (n1, n2, use_sign, ignore_last) bc_num n1, n2; int use_sign; int ignore_last; @@ -268,30 +224,32 @@ _do_compare (n1, n2, use_sign, ignore_last) /* They are equal up to the last part of the equal part of the fraction. */ if (n1->n_scale != n2->n_scale) - if (n1->n_scale > n2->n_scale) - { - for (count = n1->n_scale-n2->n_scale; count>0; count--) - if (*n1ptr++ != 0) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - } - else - { - for (count = n2->n_scale-n1->n_scale; count>0; count--) - if (*n2ptr++ != 0) - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } + { + if (n1->n_scale > n2->n_scale) + { + for (count = n1->n_scale-n2->n_scale; count>0; count--) + if (*n1ptr++ != 0) + { + /* Magnitude of n1 > n2. */ + if (!use_sign || n1->n_sign == PLUS) + return (1); + else + return (-1); + } + } + else + { + for (count = n2->n_scale-n1->n_scale; count>0; count--) + if (*n2ptr++ != 0) + { + /* Magnitude of n1 < n2. */ + if (!use_sign || n1->n_sign == PLUS) + return (-1); + else + return (1); + } + } + } /* They must be equal! */ return (0); @@ -304,14 +262,22 @@ int bc_compare (n1, n2) bc_num n1, n2; { - return _do_compare (n1, n2, TRUE, FALSE); + return _bc_do_compare (n1, n2, TRUE, FALSE); } +/* In some places we need to check if the number is negative. */ + +char +bc_is_neg (num) + bc_num num; +{ + return num->n_sign == MINUS; +} /* In some places we need to check if the number NUM is zero. */ char -is_zero (num) +bc_is_zero (num) bc_num num; { int count; @@ -333,41 +299,33 @@ is_zero (num) return TRUE; } - -/* In some places we need to check if the number is negative. */ +/* In some places we need to check if the number NUM is almost zero. + Specifically, all but the last digit is 0 and the last digit is 1. + Last digit is defined by scale. */ char -is_neg (num) +bc_is_near_zero (num, scale) bc_num num; + int scale; { - return num->n_sign == MINUS; -} + int count; + char *nptr; + /* Error checking */ + if (scale > num->n_scale) + scale = num->n_scale; -/* For many things, we may have leading zeros in a number NUM. - _rm_leading_zeros just moves the data to the correct - place and adjusts the length. */ + /* Initialize */ + count = num->n_len + scale; + nptr = num->n_value; -static void -_rm_leading_zeros (num) - bc_num num; -{ - int bytes; - char *dst, *src; - - /* Do a quick check to see if we need to do it. */ - if (*num->n_value != 0) return; - - /* The first "digit" is 0, find the first non-zero digit in the second - or greater "digit" to the left of the decimal place. */ - bytes = num->n_len; - src = num->n_value; - while (bytes > 1 && *src == 0) src++, bytes--; - num->n_len = bytes; - bytes += num->n_scale; - dst = num->n_value; - while (bytes-- > 0) *dst++ = *src++; + /* The check */ + while ((count > 0) && (*nptr++ == 0)) count--; + if (count != 0 && (count != 1 || *--nptr != 1)) + return FALSE; + else + return TRUE; } @@ -376,7 +334,7 @@ _rm_leading_zeros (num) SCALE_MIN is to set the minimum scale of the result. */ static bc_num -_do_add (n1, n2, scale_min) +_bc_do_add (n1, n2, scale_min) bc_num n1, n2; int scale_min; { @@ -389,7 +347,7 @@ _do_add (n1, n2, scale_min) /* Prepare sum. */ sum_scale = MAX (n1->n_scale, n2->n_scale); sum_digits = MAX (n1->n_len, n2->n_len) + 1; - sum = new_num (sum_digits, MAX(sum_scale, scale_min)); + sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min)); /* Zero extra digits made by scale_min. */ if (scale_min > sum_scale) @@ -457,7 +415,7 @@ _do_add (n1, n2, scale_min) *sumptr += 1; /* Adjust sum and return. */ - _rm_leading_zeros (sum); + _bc_rm_leading_zeros (sum); return sum; } @@ -468,7 +426,7 @@ _do_add (n1, n2, scale_min) of the result. */ static bc_num -_do_sub (n1, n2, scale_min) +_bc_do_sub (n1, n2, scale_min) bc_num n1, n2; int scale_min; { @@ -483,7 +441,7 @@ _do_sub (n1, n2, scale_min) diff_scale = MAX (n1->n_scale, n2->n_scale); min_len = MIN (n1->n_len, n2->n_len); min_scale = MIN (n1->n_scale, n2->n_scale); - diff = new_num (diff_len, MAX(diff_scale, scale_min)); + diff = bc_new_num (diff_len, MAX(diff_scale, scale_min)); /* Zero extra digits made by scale_min. */ if (scale_min > diff_scale) @@ -558,109 +516,340 @@ _do_sub (n1, n2, scale_min) } /* Clean up and return. */ - _rm_leading_zeros (diff); + _bc_rm_leading_zeros (diff); return diff; } -/* Here is the full add routine that takes care of negative numbers. - N1 is added to N2 and the result placed into RESULT. SCALE_MIN +/* Here is the full subtract routine that takes care of negative numbers. + N2 is subtracted from N1 and the result placed in RESULT. SCALE_MIN is the minimum scale for the result. */ void -bc_add (n1, n2, result, scale_min) +bc_sub (n1, n2, result, scale_min) bc_num n1, n2, *result; int scale_min; { - bc_num sum; + bc_num diff = NULL; int cmp_res; int res_scale; - if (n1->n_sign == n2->n_sign) + if (n1->n_sign != n2->n_sign) { - sum = _do_add (n1, n2, scale_min); - sum->n_sign = n1->n_sign; + diff = _bc_do_add (n1, n2, scale_min); + diff->n_sign = n1->n_sign; } else { /* subtraction must be done. */ - cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ + /* Compare magnitudes. */ + cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE); switch (cmp_res) { case -1: /* n1 is less than n2, subtract n1 from n2. */ - sum = _do_sub (n2, n1, scale_min); - sum->n_sign = n2->n_sign; + diff = _bc_do_sub (n2, n1, scale_min); + diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS); break; case 0: - /* They are equal! return zero with the correct scale! */ + /* They are equal! return zero! */ res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale)); - sum = new_num (1, res_scale); - memset (sum->n_value, 0, res_scale+1); + diff = bc_new_num (1, res_scale); + memset (diff->n_value, 0, res_scale+1); break; case 1: /* n2 is less than n1, subtract n2 from n1. */ - sum = _do_sub (n1, n2, scale_min); - sum->n_sign = n1->n_sign; + diff = _bc_do_sub (n1, n2, scale_min); + diff->n_sign = n1->n_sign; + break; } } /* Clean up and return. */ - free_num (result); - *result = sum; + bc_free_num (result); + *result = diff; } -/* Here is the full subtract routine that takes care of negative numbers. - N2 is subtracted from N1 and the result placed in RESULT. SCALE_MIN +/* Here is the full add routine that takes care of negative numbers. + N1 is added to N2 and the result placed into RESULT. SCALE_MIN is the minimum scale for the result. */ void -bc_sub (n1, n2, result, scale_min) +bc_add (n1, n2, result, scale_min) bc_num n1, n2, *result; int scale_min; { - bc_num diff; + bc_num sum = NULL; int cmp_res; int res_scale; - if (n1->n_sign != n2->n_sign) + if (n1->n_sign == n2->n_sign) { - diff = _do_add (n1, n2, scale_min); - diff->n_sign = n1->n_sign; + sum = _bc_do_add (n1, n2, scale_min); + sum->n_sign = n1->n_sign; } else { /* subtraction must be done. */ - cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ + cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ switch (cmp_res) { case -1: /* n1 is less than n2, subtract n1 from n2. */ - diff = _do_sub (n2, n1, scale_min); - diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS); + sum = _bc_do_sub (n2, n1, scale_min); + sum->n_sign = n2->n_sign; break; case 0: - /* They are equal! return zero! */ + /* They are equal! return zero with the correct scale! */ res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale)); - diff = new_num (1, res_scale); - memset (diff->n_value, 0, res_scale+1); + sum = bc_new_num (1, res_scale); + memset (sum->n_value, 0, res_scale+1); break; case 1: /* n2 is less than n1, subtract n2 from n1. */ - diff = _do_sub (n1, n2, scale_min); - diff->n_sign = n1->n_sign; - break; + sum = _bc_do_sub (n1, n2, scale_min); + sum->n_sign = n1->n_sign; } } /* Clean up and return. */ - free_num (result); - *result = diff; + bc_free_num (result); + *result = sum; +} + +/* Recursive vs non-recursive multiply crossover ranges. */ +#if defined(MULDIGITS) +#include "muldigits.h" +#else +#define MUL_BASE_DIGITS 80 +#endif + +int mul_base_digits = MUL_BASE_DIGITS; +#define MUL_SMALL_DIGITS mul_base_digits/4 + +/* Multiply utility routines */ + +static bc_num +new_sub_num (length, scale, value) + int length, scale; + char *value; +{ + bc_num temp; + + if (_bc_Free_list != NULL) { + temp = _bc_Free_list; + _bc_Free_list = temp->n_next; + } else { + temp = (bc_num) malloc (sizeof(bc_struct)); + if (temp == NULL) bc_out_of_memory (); + } + temp->n_sign = PLUS; + temp->n_len = length; + temp->n_scale = scale; + temp->n_refs = 1; + temp->n_ptr = NULL; + temp->n_value = value; + return temp; +} + +static void +_bc_simp_mul (bc_num n1, int n1len, bc_num n2, int n2len, bc_num *prod, + int full_scale) +{ + char *n1ptr, *n2ptr, *pvptr; + char *n1end, *n2end; /* To the end of n1 and n2. */ + int indx, sum, prodlen; + + prodlen = n1len+n2len+1; + + *prod = bc_new_num (prodlen, 0); + + n1end = (char *) (n1->n_value + n1len - 1); + n2end = (char *) (n2->n_value + n2len - 1); + pvptr = (char *) ((*prod)->n_value + prodlen - 1); + sum = 0; + + /* Here is the loop... */ + for (indx = 0; indx < prodlen-1; indx++) + { + n1ptr = (char *) (n1end - MAX(0, indx-n2len+1)); + n2ptr = (char *) (n2end - MIN(indx, n2len-1)); + while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) + sum += *n1ptr-- * *n2ptr++; + *pvptr-- = sum % BASE; + sum = sum / BASE; + } + *pvptr = sum; +} + + +/* A special adder/subtractor for the recursive divide and conquer + multiply algorithm. Note: if sub is called, accum must + be larger that what is being subtracted. Also, accum and val + must have n_scale = 0. (e.g. they must look like integers. *) */ +static void +_bc_shift_addsub (bc_num accum, bc_num val, int shift, int sub) +{ + signed char *accp, *valp; + int count, carry; + + count = val->n_len; + if (val->n_value[0] == 0) + count--; + assert (accum->n_len+accum->n_scale >= shift+count); + + /* Set up pointers and others */ + accp = (signed char *)(accum->n_value + + accum->n_len + accum->n_scale - shift - 1); + valp = (signed char *)(val->n_value + val->n_len - 1); + carry = 0; + + if (sub) { + /* Subtraction, carry is really borrow. */ + while (count--) { + *accp -= *valp-- + carry; + if (*accp < 0) { + carry = 1; + *accp-- += BASE; + } else { + carry = 0; + accp--; + } + } + while (carry) { + *accp -= carry; + if (*accp < 0) + *accp-- += BASE; + else + carry = 0; + } + } else { + /* Addition */ + while (count--) { + *accp += *valp-- + carry; + if (*accp > (BASE-1)) { + carry = 1; + *accp-- -= BASE; + } else { + carry = 0; + accp--; + } + } + while (carry) { + *accp += carry; + if (*accp > (BASE-1)) + *accp-- -= BASE; + else + carry = 0; + } + } } +/* Recursive divide and conquer multiply algorithm. + Based on + Let u = u0 + u1*(b^n) + Let v = v0 + v1*(b^n) + Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0 + + B is the base of storage, number of digits in u1,u0 close to equal. +*/ +static void +_bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod, + int full_scale) +{ + bc_num u0, u1, v0, v1; + int u0len, v0len; + bc_num m1, m2, m3, d1, d2; + int n, prodlen, m1zero; + int d1len, d2len; + + /* Base case? */ + if ((ulen+vlen) < mul_base_digits + || ulen < MUL_SMALL_DIGITS + || vlen < MUL_SMALL_DIGITS ) { + _bc_simp_mul (u, ulen, v, vlen, prod, full_scale); + return; + } + + /* Calculate n -- the u and v split point in digits. */ + n = (MAX(ulen, vlen)+1) / 2; + + /* Split u and v. */ + if (ulen < n) { + u1 = bc_copy_num (_zero_); + u0 = new_sub_num (ulen,0, u->n_value); + } else { + u1 = new_sub_num (ulen-n, 0, u->n_value); + u0 = new_sub_num (n, 0, u->n_value+ulen-n); + } + if (vlen < n) { + v1 = bc_copy_num (_zero_); + v0 = new_sub_num (vlen,0, v->n_value); + } else { + v1 = new_sub_num (vlen-n, 0, v->n_value); + v0 = new_sub_num (n, 0, v->n_value+vlen-n); + } + _bc_rm_leading_zeros (u1); + _bc_rm_leading_zeros (u0); + u0len = u0->n_len; + _bc_rm_leading_zeros (v1); + _bc_rm_leading_zeros (v0); + v0len = v0->n_len; + + m1zero = bc_is_zero(u1) || bc_is_zero(v1); + + /* Calculate sub results ... */ + + bc_init_num(&d1); + bc_init_num(&d2); + bc_sub (u1, u0, &d1, 0); + d1len = d1->n_len; + bc_sub (v0, v1, &d2, 0); + d2len = d2->n_len; + + + /* Do recursive multiplies and shifted adds. */ + if (m1zero) + m1 = bc_copy_num (_zero_); + else + _bc_rec_mul (u1, u1->n_len, v1, v1->n_len, &m1, 0); + + if (bc_is_zero(d1) || bc_is_zero(d2)) + m2 = bc_copy_num (_zero_); + else + _bc_rec_mul (d1, d1len, d2, d2len, &m2, 0); + + if (bc_is_zero(u0) || bc_is_zero(v0)) + m3 = bc_copy_num (_zero_); + else + _bc_rec_mul (u0, u0->n_len, v0, v0->n_len, &m3, 0); + + /* Initialize product */ + prodlen = ulen+vlen+1; + *prod = bc_new_num(prodlen, 0); + + if (!m1zero) { + _bc_shift_addsub (*prod, m1, 2*n, 0); + _bc_shift_addsub (*prod, m1, n, 0); + } + _bc_shift_addsub (*prod, m3, n, 0); + _bc_shift_addsub (*prod, m3, 0, 0); + _bc_shift_addsub (*prod, m2, n, d1->n_sign != d2->n_sign); + + /* Now clean up! */ + bc_free_num (&u1); + bc_free_num (&u0); + bc_free_num (&v1); + bc_free_num (&m1); + bc_free_num (&v0); + bc_free_num (&m2); + bc_free_num (&m3); + bc_free_num (&d1); + bc_free_num (&d2); +} -/* The multiply routine. N2 time N1 is put int PROD with the scale of +/* The multiply routine. N2 times N1 is put int PROD with the scale of the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)). */ @@ -669,59 +858,31 @@ bc_multiply (n1, n2, prod, scale) bc_num n1, n2, *prod; int scale; { - bc_num pval; /* For the working storage. */ - char *n1ptr, *n2ptr, *pvptr; /* Work pointers. */ - char *n1end, *n2end; /* To the end of n1 and n2. */ - - int indx; - int len1, len2, total_digits; - long sum; + bc_num pval; + int len1, len2; int full_scale, prod_scale; - int toss; /* Initialize things. */ len1 = n1->n_len + n1->n_scale; len2 = n2->n_len + n2->n_scale; - total_digits = len1 + len2; full_scale = n1->n_scale + n2->n_scale; prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale))); - toss = full_scale - prod_scale; - pval = new_num (total_digits-full_scale, prod_scale); - pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - n1end = (char *) (n1->n_value + len1 - 1); - n2end = (char *) (n2->n_value + len2 - 1); - pvptr = (char *) (pval->n_value + total_digits - toss - 1); - sum = 0; - /* Here are the loops... */ - for (indx = 0; indx < toss; indx++) - { - n1ptr = (char *) (n1end - MAX(0, indx-len2+1)); - n2ptr = (char *) (n2end - MIN(indx, len2-1)); - while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) - sum += *n1ptr-- * *n2ptr++; - sum = sum / BASE; - } - for ( ; indx < total_digits-1; indx++) - { - n1ptr = (char *) (n1end - MAX(0, indx-len2+1)); - n2ptr = (char *) (n2end - MIN(indx, len2-1)); - while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) - sum += *n1ptr-- * *n2ptr++; - *pvptr-- = sum % BASE; - sum = sum / BASE; - } - *pvptr-- = sum; + /* Do the multiply */ + _bc_rec_mul (n1, len1, n2, len2, &pval, full_scale); /* Assign to prod and clean up the number. */ - free_num (prod); + pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); + pval->n_value = pval->n_ptr; + pval->n_len = len2 + len1 + 1 - full_scale; + pval->n_scale = prod_scale; + _bc_rm_leading_zeros (pval); + if (bc_is_zero (pval)) + pval->n_sign = PLUS; + bc_free_num (prod); *prod = pval; - _rm_leading_zeros (*prod); - if (is_zero (*prod)) - (*prod)->n_sign = PLUS; } - /* Some utility routines for the divide: First a one digit multiply. NUM (with SIZE digits) is multiplied by DIGIT and the result is placed into RESULT. It is written so that NUM and RESULT can be @@ -783,19 +944,19 @@ bc_divide (n1, n2, quot, scale) unsigned int norm; /* Test for divide by zero. */ - if (is_zero (n2)) return -1; + if (bc_is_zero (n2)) return -1; /* Test for divide by 1. If it is we must truncate. */ if (n2->n_scale == 0) { if (n2->n_len == 1 && *n2->n_value == 1) { - qval = new_num (n1->n_len, scale); + qval = bc_new_num (n1->n_len, scale); qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); memset (&qval->n_value[n1->n_len],0,scale); memcpy (qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale,scale)); - free_num (quot); + bc_free_num (quot); *quot = qval; } } @@ -813,13 +974,13 @@ bc_divide (n1, n2, quot, scale) else extra = 0; num1 = (unsigned char *) malloc (n1->n_len+n1->n_scale+extra+2); - if (num1 == NULL) out_of_memory(); + if (num1 == NULL) bc_out_of_memory(); memset (num1, 0, n1->n_len+n1->n_scale+extra+2); memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale); len2 = n2->n_len + scale2; num2 = (unsigned char *) malloc (len2+1); - if (num2 == NULL) out_of_memory(); + if (num2 == NULL) bc_out_of_memory(); memcpy (num2, n2->n_value, len2); *(num2+len2) = 0; n2ptr = num2; @@ -845,12 +1006,12 @@ bc_divide (n1, n2, quot, scale) } /* Allocate and zero the storage for the quotient. */ - qval = new_num (qdigits-scale,scale); + qval = bc_new_num (qdigits-scale,scale); memset (qval->n_value, 0, qdigits); /* Allocate storage for the temporary storage mval. */ mval = (unsigned char *) malloc (len2+1); - if (mval == NULL) out_of_memory (); + if (mval == NULL) bc_out_of_memory (); /* Now for the full divide algorithm. */ if (!zero) @@ -944,9 +1105,9 @@ bc_divide (n1, n2, quot, scale) /* Clean up and return the number. */ qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - if (is_zero (qval)) qval->n_sign = PLUS; - _rm_leading_zeros (qval); - free_num (quot); + if (bc_is_zero (qval)) qval->n_sign = PLUS; + _bc_rm_leading_zeros (qval); + bc_free_num (quot); *quot = qval; /* Clean up temporary storage. */ @@ -968,28 +1129,28 @@ bc_divmod (num1, num2, quot, rem, scale) bc_num num1, num2, *quot, *rem; int scale; { - bc_num quotient; + bc_num quotient = NULL; bc_num temp; int rscale; /* Check for correct numbers. */ - if (is_zero (num2)) return -1; + if (bc_is_zero (num2)) return -1; /* Calculate final scale. */ rscale = MAX (num1->n_scale, num2->n_scale+scale); - init_num (&temp); + bc_init_num(&temp); /* Calculate it. */ bc_divide (num1, num2, &temp, scale); if (quot) - quotient = copy_num(temp); + quotient = bc_copy_num (temp); bc_multiply (temp, num2, &temp, rscale); bc_sub (num1, temp, rem, rscale); - free_num (&temp); + bc_free_num (&temp); if (quot) { - free_num (quot); + bc_free_num (quot); *quot = quotient; } @@ -1008,7 +1169,6 @@ bc_modulo (num1, num2, result, scale) return bc_divmod (num1, num2, NULL, result, scale); } - /* Raise BASE to the EXPO power, reduced modulo MOD. The result is placed in RESULT. If a EXPO is not an integer, only the integer part is used. */ @@ -1022,36 +1182,36 @@ bc_raisemod (base, expo, mod, result, scale) int rscale; /* Check for correct numbers. */ - if (is_zero(mod)) return -1; - if (is_neg(expo)) return -1; + if (bc_is_zero(mod)) return -1; + if (bc_is_neg(expo)) return -1; /* Set initial values. */ - power = copy_num (base); - exponent = copy_num (expo); - temp = copy_num (_one_); - init_num (&parity); + power = bc_copy_num (base); + exponent = bc_copy_num (expo); + temp = bc_copy_num (_one_); + bc_init_num(&parity); /* Check the base for scale digits. */ if (base->n_scale != 0) - rt_warn ("non-zero scale in base"); + bc_rt_warn ("non-zero scale in base"); /* Check the exponent for scale digits. */ if (exponent->n_scale != 0) { - rt_warn ("non-zero scale in exponent"); + bc_rt_warn ("non-zero scale in exponent"); bc_divide (exponent, _one_, &exponent, 0); /*truncate */ } /* Check the modulus for scale digits. */ if (mod->n_scale != 0) - rt_warn ("non-zero scale in modulus"); + bc_rt_warn ("non-zero scale in modulus"); /* Do the calculation. */ rscale = MAX(scale, base->n_scale); - while ( !is_zero(exponent) ) + while ( !bc_is_zero(exponent) ) { (void) bc_divmod (exponent, _two_, &exponent, &parity, 0); - if ( !is_zero(parity) ) + if ( !bc_is_zero(parity) ) { bc_multiply (temp, power, &temp, rscale); (void) bc_modulo (temp, mod, &temp, scale); @@ -1062,14 +1222,13 @@ bc_raisemod (base, expo, mod, result, scale) } /* Assign the value. */ - free_num (&power); - free_num (&exponent); - free_num (result); + bc_free_num (&power); + bc_free_num (&exponent); + bc_free_num (result); *result = temp; return 0; /* Everything is OK. */ } - /* Raise NUM1 to the NUM2 power. The result is placed in RESULT. Maximum exponent is LONG_MAX. If a NUM2 is not an integer, only the integer part is used. */ @@ -1082,20 +1241,22 @@ bc_raise (num1, num2, result, scale) bc_num temp, power; long exponent; int rscale; + int pwrscale; + int calcscale; char neg; /* Check the exponent for scale digits and convert to a long. */ if (num2->n_scale != 0) - rt_warn ("non-zero scale in exponent"); - exponent = num2long (num2); + bc_rt_warn ("non-zero scale in exponent"); + exponent = bc_num2long (num2); if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) - rt_error ("exponent too large in raise"); + bc_rt_error ("exponent too large in raise"); /* Special case if exponent is a zero. */ if (exponent == 0) { - free_num (result); - *result = copy_num (_one_); + bc_free_num (result); + *result = bc_copy_num (_one_); return; } @@ -1113,22 +1274,27 @@ bc_raise (num1, num2, result, scale) } /* Set initial value of temp. */ - power = copy_num (num1); + power = bc_copy_num (num1); + pwrscale = num1->n_scale; while ((exponent & 1) == 0) { - bc_multiply (power, power, &power, rscale); + pwrscale = 2*pwrscale; + bc_multiply (power, power, &power, pwrscale); exponent = exponent >> 1; } - temp = copy_num (power); + temp = bc_copy_num (power); + calcscale = pwrscale; exponent = exponent >> 1; - /* Do the calculation. */ while (exponent > 0) { - bc_multiply (power, power, &power, rscale); - if ((exponent & 1) == 1) - bc_multiply (temp, power, &temp, rscale); + pwrscale = 2*pwrscale; + bc_multiply (power, power, &power, pwrscale); + if ((exponent & 1) == 1) { + calcscale = pwrscale + calcscale; + bc_multiply (temp, power, &temp, calcscale); + } exponent = exponent >> 1; } @@ -1136,37 +1302,16 @@ bc_raise (num1, num2, result, scale) if (neg) { bc_divide (_one_, temp, result, rscale); - free_num (&temp); + bc_free_num (&temp); } else { - free_num (result); + bc_free_num (result); *result = temp; + if ((*result)->n_scale > rscale) + (*result)->n_scale = rscale; } - free_num (&power); -} - -/* In some places we need to check if the number NUM is zero. */ - -char -is_near_zero (num, scale) - bc_num num; - int scale; -{ - int count; - char *nptr; - - /* Initialize */ - count = num->n_len + scale; - nptr = num->n_value; - - /* The check */ - while ((count > 0) && (*nptr++ == 0)) count--; - - if (count != 0 && (count != 1 || *--nptr != 1)) - return FALSE; - else - return TRUE; + bc_free_num (&power); } /* Take the square root NUM and return it in NUM with SCALE digits @@ -1189,25 +1334,25 @@ bc_sqrt (num, scale) { if (cmp_res == 0) { - free_num (num); - *num = copy_num (_zero_); + bc_free_num (num); + *num = bc_copy_num (_zero_); return 1; } } cmp_res = bc_compare (*num, _one_); if (cmp_res == 0) { - free_num (num); - *num = copy_num (_one_); + bc_free_num (num); + *num = bc_copy_num (_one_); return 1; } /* Initialize the variables. */ rscale = MAX (scale, (*num)->n_scale); - init_num (&guess); - init_num (&guess1); - init_num (&diff); - point5 = new_num (1,1); + bc_init_num(&guess); + bc_init_num(&guess1); + bc_init_num(&diff); + point5 = bc_new_num (1,1); point5->n_value[1] = 5; @@ -1215,19 +1360,19 @@ bc_sqrt (num, scale) if (cmp_res < 0) { /* The number is between 0 and 1. Guess should start at 1. */ - guess = copy_num (_one_); + guess = bc_copy_num (_one_); cscale = (*num)->n_scale; } else { /* The number is greater than 1. Guess should start at 10^(exp/2). */ - int2num (&guess,10); + bc_int2num (&guess,10); - int2num (&guess1,(*num)->n_len); + bc_int2num (&guess1,(*num)->n_len); bc_multiply (guess1, point5, &guess1, 0); guess1->n_scale = 0; bc_raise (guess, guess1, &guess, 0); - free_num (&guess1); + bc_free_num (&guess1); cscale = 3; } @@ -1235,26 +1380,28 @@ bc_sqrt (num, scale) done = FALSE; while (!done) { - free_num (&guess1); - guess1 = copy_num (guess); + bc_free_num (&guess1); + guess1 = bc_copy_num (guess); bc_divide (*num, guess, &guess, cscale); bc_add (guess, guess1, &guess, 0); bc_multiply (guess, point5, &guess, cscale); bc_sub (guess, guess1, &diff, cscale+1); - if (is_near_zero (diff, cscale)) - if (cscale < rscale+1) - cscale = MIN (cscale*3, rscale+1); - else - done = TRUE; + if (bc_is_near_zero (diff, cscale)) + { + if (cscale < rscale+1) + cscale = MIN (cscale*3, rscale+1); + else + done = TRUE; + } } /* Assign the number and clean up. */ - free_num (num); + bc_free_num (num); bc_divide (guess,_one_,num,rscale); - free_num (&guess); - free_num (&guess1); - free_num (&point5); - free_num (&diff); + bc_free_num (&guess); + bc_free_num (&guess1); + bc_free_num (&point5); + bc_free_num (&diff); return 1; } @@ -1269,7 +1416,7 @@ typedef struct stk_rec { } stk_rec; /* The reference string for digits. */ -char ref_str[] = "0123456789ABCDEF"; +static char ref_str[] = "0123456789ABCDEF"; /* A special output routine for "multi-character digits." Exactly @@ -1278,7 +1425,7 @@ char ref_str[] = "0123456789ABCDEF"; is the actual routine for writing the characters. */ void -out_long (val, size, space, out_char) +bc_out_long (val, size, space, out_char) long val; int size, space; #ifdef __STDC__ @@ -1306,7 +1453,7 @@ out_long (val, size, space, out_char) as the routine to do the actual output of the characters. */ void -out_num (num, o_base, out_char) +bc_out_num (num, o_base, out_char, leading_zero) bc_num num; int o_base; #ifdef __STDC__ @@ -1314,6 +1461,7 @@ out_num (num, o_base, out_char) #else void (*out_char)(); #endif + int leading_zero; { char *nptr; int index, fdigit, pre_space; @@ -1324,7 +1472,7 @@ out_num (num, o_base, out_char) if (num->n_sign == MINUS) (*out_char) ('-'); /* Output the number. */ - if (is_zero (num)) + if (bc_is_zero (num)) (*out_char) ('0'); else if (o_base == 10) @@ -1337,7 +1485,7 @@ out_num (num, o_base, out_char) else nptr++; - if (std_only && is_zero (num)) + if (leading_zero && bc_is_zero (num)) (*out_char) ('0'); /* Now the fraction. */ @@ -1351,32 +1499,32 @@ out_num (num, o_base, out_char) else { /* special case ... */ - if (std_only && is_zero (num)) + if (leading_zero && bc_is_zero (num)) (*out_char) ('0'); /* The number is some other base. */ digits = NULL; - init_num (&int_part); + bc_init_num (&int_part); bc_divide (num, _one_, &int_part, 0); - init_num (&frac_part); - init_num (&cur_dig); - init_num (&base); + bc_init_num (&frac_part); + bc_init_num (&cur_dig); + bc_init_num (&base); bc_sub (num, int_part, &frac_part, 0); /* Make the INT_PART and FRAC_PART positive. */ int_part->n_sign = PLUS; frac_part->n_sign = PLUS; - int2num (&base, o_base); - init_num (&max_o_digit); - int2num (&max_o_digit, o_base-1); + bc_int2num (&base, o_base); + bc_init_num (&max_o_digit); + bc_int2num (&max_o_digit, o_base-1); /* Get the digits of the integer part and push them on a stack. */ - while (!is_zero (int_part)) + while (!bc_is_zero (int_part)) { bc_modulo (int_part, base, &cur_dig, 0); temp = (stk_rec *) malloc (sizeof(stk_rec)); - if (temp == NULL) out_of_memory(); - temp->digit = num2long (cur_dig); + if (temp == NULL) bc_out_of_memory(); + temp->digit = bc_num2long (cur_dig); temp->next = digits; digits = temp; bc_divide (int_part, base, &int_part, 0); @@ -1393,7 +1541,7 @@ out_num (num, o_base, out_char) if (o_base <= 16) (*out_char) (ref_str[ (int) temp->digit]); else - out_long (temp->digit, max_o_digit->n_len, 1, out_char); + bc_out_long (temp->digit, max_o_digit->n_len, 1, out_char); free (temp); } } @@ -1403,65 +1551,148 @@ out_num (num, o_base, out_char) { (*out_char) ('.'); pre_space = 0; - t_num = copy_num (_one_); + t_num = bc_copy_num (_one_); while (t_num->n_len <= num->n_scale) { bc_multiply (frac_part, base, &frac_part, num->n_scale); - fdigit = num2long (frac_part); - int2num (&int_part, fdigit); + fdigit = bc_num2long (frac_part); + bc_int2num (&int_part, fdigit); bc_sub (frac_part, int_part, &frac_part, 0); if (o_base <= 16) (*out_char) (ref_str[fdigit]); else { - out_long (fdigit, max_o_digit->n_len, pre_space, out_char); + bc_out_long (fdigit, max_o_digit->n_len, pre_space, out_char); pre_space = 1; } bc_multiply (t_num, base, &t_num, 0); } - free_num (&t_num); + bc_free_num (&t_num); } /* Clean up. */ - free_num (&int_part); - free_num (&frac_part); - free_num (&base); - free_num (&cur_dig); - free_num (&max_o_digit); + bc_free_num (&int_part); + bc_free_num (&frac_part); + bc_free_num (&base); + bc_free_num (&cur_dig); + bc_free_num (&max_o_digit); } } +/* Convert a number NUM to a long. The function returns only the integer + part of the number. For numbers that are too large to represent as + a long, this function returns a zero. This can be detected by checking + the NUM for zero after having a zero returned. */ -#if DEBUG > 0 +long +bc_num2long (num) + bc_num num; +{ + long val; + char *nptr; + int index; -/* Debugging procedures. Some are just so one can call them from the - debugger. */ + /* Extract the int value, ignore the fraction. */ + val = 0; + nptr = num->n_value; + for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--) + val = val*BASE + *nptr++; -/* p_n prints the number NUM in base 10. */ + /* Check for overflow. If overflow, return zero. */ + if (index>0) val = 0; + if (val < 0) val = 0; -void -p_n (num) - bc_num num; -{ - out_num (num, 10, out_char); + /* Return the value. */ + if (num->n_sign == PLUS) + return (val); + else + return (-val); } -/* p_b prints a character array as if it was a string of bcd digits. */ +/* Convert an integer VAL to a bc number NUM. */ + void -p_v (name, num, len) - char *name; - unsigned char *num; - int len; +bc_int2num (num, val) + bc_num *num; + int val; { - int i; - printf ("%s=", name); - for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i])); - printf ("\n"); + char buffer[30]; + char *bptr, *vptr; + int ix = 1; + char neg = 0; + + /* Sign. */ + if (val < 0) + { + neg = 1; + val = -val; + } + + /* Get things going. */ + bptr = buffer; + *bptr++ = val % BASE; + val = val / BASE; + + /* Extract remaining digits. */ + while (val != 0) + { + *bptr++ = val % BASE; + val = val / BASE; + ix++; /* Count the digits. */ + } + + /* Make the number. */ + bc_free_num (num); + *num = bc_new_num (ix, 0); + if (neg) (*num)->n_sign = MINUS; + + /* Assign the digits. */ + vptr = (*num)->n_value; + while (ix-- > 0) + *vptr++ = *--bptr; } +/* Convert a numbers to a string. Base 10 only.*/ + +char +*num2str (num) + bc_num num; +{ + char *str, *sptr; + char *nptr; + int index, signch; + + /* Allocate the string memory. */ + signch = ( num->n_sign == PLUS ? 0 : 1 ); /* Number of sign chars. */ + if (num->n_scale > 0) + str = (char *) malloc (num->n_len + num->n_scale + 2 + signch); + else + str = (char *) malloc (num->n_len + 1 + signch); + if (str == NULL) bc_out_of_memory(); + + /* The negative sign if needed. */ + sptr = str; + if (signch) *sptr++ = '-'; + + /* Load the whole number. */ + nptr = num->n_value; + for (index=num->n_len; index>0; index--) + *sptr++ = BCD_CHAR(*nptr++); + + /* Now the fraction. */ + if (num->n_scale > 0) + { + *sptr++ = '.'; + for (index=0; index<num->n_scale; index++) + *sptr++ = BCD_CHAR(*nptr++); + } + /* Terminate the string and return it! */ + *sptr = '\0'; + return (str); +} /* Convert strings to bc numbers. Base 10 only.*/ void -str2num (num, str, scale) +bc_str2num (num, str, scale) bc_num *num; char *str; int scale; @@ -1471,7 +1702,7 @@ str2num (num, str, scale) char zero_int; /* Prepare num. */ - free_num (num); + bc_free_num (num); /* Check for valid number and count digits. */ ptr = str; @@ -1480,12 +1711,12 @@ str2num (num, str, scale) zero_int = FALSE; if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */ while (*ptr == '0') ptr++; /* Skip leading zeros. */ - while (isdigit(*ptr)) ptr++, digits++; /* digits */ + while (isdigit((int)*ptr)) ptr++, digits++; /* digits */ if (*ptr == '.') ptr++; /* decimal point */ - while (isdigit(*ptr)) ptr++, strscale++; /* digits */ + while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */ if ((*ptr != '\0') || (digits+strscale == 0)) { - *num = copy_num (_zero_); + *num = bc_copy_num (_zero_); return; } @@ -1496,7 +1727,7 @@ str2num (num, str, scale) zero_int = TRUE; digits = 1; } - *num = new_num (digits, strscale); + *num = bc_new_num (digits, strscale); /* Build the whole number. */ ptr = str; @@ -1530,43 +1761,33 @@ str2num (num, str, scale) } } -/* Convert a numbers to a string. Base 10 only.*/ +/* pn prints the number NUM in base 10. */ -char -*num2str (num) - bc_num num; +static void +out_char (int c) { - char *str, *sptr; - char *nptr; - int index, signch; - - /* Allocate the string memory. */ - signch = ( num->n_sign == PLUS ? 0 : 1 ); /* Number of sign chars. */ - if (num->n_scale > 0) - str = (char *) malloc (num->n_len + num->n_scale + 2 + signch); - else - str = (char *) malloc (num->n_len + 1 + signch); - if (str == NULL) out_of_memory(); + putchar(c); +} - /* The negative sign if needed. */ - sptr = str; - if (signch) *sptr++ = '-'; - /* Load the whole number. */ - nptr = num->n_value; - for (index=num->n_len; index>0; index--) - *sptr++ = BCD_CHAR(*nptr++); +void +pn (num) + bc_num num; +{ + bc_out_num (num, 10, out_char, 0); + out_char ('\n'); +} - /* Now the fraction. */ - if (num->n_scale > 0) - { - *sptr++ = '.'; - for (index=0; index<num->n_scale; index++) - *sptr++ = BCD_CHAR(*nptr++); - } - /* Terminate the string and return it! */ - *sptr = '\0'; - return (str); +/* pv prints a character array as if it was a string of bcd digits. */ +void +pv (name, num, len) + char *name; + unsigned char *num; + int len; +{ + int i; + printf ("%s=", name); + for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i])); + printf ("\n"); } -#endif diff --git a/contrib/bc/lib/testmul.c b/contrib/bc/lib/testmul.c new file mode 100644 index 0000000..f7044d6 --- /dev/null +++ b/contrib/bc/lib/testmul.c @@ -0,0 +1,244 @@ +/* compute the crossover for recursive and simple multiplication */ + +#include <stdio.h> +#include <time.h> +#include "number.h" +#ifndef VARARGS +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +/* from number.c ... */ +extern int mul_base_digits; +/* extern int mul_small_digits; */ +extern bc_num _one_; + +/* global variables */ +int test_n = 1000; +int test_time = 30 * CLOCKS_PER_SEC; /* 30 seconds */ + +/* Other things for number.c. */ +int std_only; + +void +out_of_memory() +{ + fprintf (stderr, "Fatal error: Out of memory for malloc.\n"); + exit (1); +} + +/* Runtime error will print a message and stop the machine. */ + +#ifndef VARARGS +#ifdef __STDC__ +void +rt_error (char *mesg, ...) +#else +void +rt_error (mesg) + char *mesg; +#endif +#else +void +rt_error (mesg, va_alist) + char *mesg; +#endif +{ + va_list args; + char error_mesg [255]; + +#ifndef VARARGS + va_start (args, mesg); +#else + va_start (args); +#endif + vsprintf (error_mesg, mesg, args); + va_end (args); + + fprintf (stderr, "Runtime error: %s\n", error_mesg); +} + +/* A runtime warning tells of some action taken by the processor that + may change the program execution but was not enough of a problem + to stop the execution. */ + +#ifndef VARARGS +#ifdef __STDC__ +void +rt_warn (char *mesg, ...) +#else +void +rt_warn (mesg) + char *mesg; +#endif +#else +void +rt_warn (mesg, va_alist) + char *mesg; +#endif +{ + va_list args; + char error_mesg [255]; + +#ifndef VARARGS + va_start (args, mesg); +#else + va_start (args); +#endif + vsprintf (error_mesg, mesg, args); + va_end (args); + + fprintf (stderr, "Runtime warning: %s\n", error_mesg); +} + +void +out_char (int ch) +{ + putchar (ch); +} + +/* Time stuff !!! */ + +int +timeit ( bc_num a, bc_num b, int *n) +{ + clock_t first; + int i, res; + bc_num c; + + bc_init_num (&c); + first = clock(); + *n = 0; + do { + for (i=0; i<test_n; i++) + bc_multiply(a,b,&c,0); + *n += test_n; + res = (int) (clock() - first); + } while (res < test_time); + return res; +} + +int debug = 0; /* Print debugging messages? */ + +int main (int argc, char **argv) +{ + bc_num ten, num, expo, big; + + int min, max, mid; + +#if 0 + int smallsize; +#endif + + int n1, n2; + clock_t t1, t2; + float permul1, permul2; + + /* args? */ + if (argc > 1) + if (strcmp (argv[1], "-d") == 0) + debug = 1; + + bc_init_numbers(); + bc_init_num (&ten); + bc_init_num (&num); + bc_init_num (&expo); + bc_init_num (&big); + bc_int2num (&ten, 10); + + if (debug) + fprintf (stderr, "Timings are for %d multiplies\n" + "Minimum time is %d seconds\n", test_n, + test_time/CLOCKS_PER_SEC); + + /* Two of the same size */ + min = 10; + max = 500; + + if (debug) + fprintf (stderr, "Testing numbers of the same length.\n"); + + while (min < max) { + mid = (min+max)/2; + if (debug) fprintf (stderr,"Checking %d...\n", mid); + + bc_int2num (&expo, mid); + bc_raise (ten, expo, &num, 0); + bc_sub (num, _one_, &num, 0); + + mul_base_digits = 2*mid+1; + t1 = timeit (num, num, &n1); + permul1 = (float)t1/(float)n1; + + mul_base_digits = 2*mid-1; + t2 = timeit (num, num, &n2); + permul2 = (float)t2/(float)n2; + + if (permul1 < permul2) + min = mid+1; + else + max = mid-1; + + if (debug) { + fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2); + fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2); + } + } + + if (debug) + fprintf (stderr, "Base digits crossover at %d digits\n", min); + printf ("#define MUL_BASE_DIGITS %d\n", 2*min); + + +#if 0 + mul_base_digits = min; + + /* Small one times a big one. */ + + smallsize = min/2; + bc_int2num (&expo, smallsize); + bc_raise (ten, expo, &big, 0); + bc_sub (num, _one_, &big, 0); + + min = min / 2; + max = 500; + + if (debug) + fprintf (stderr, "Testing numbers of the different length.\n"); + + while (min < max) { + mid = (min+max)/2; + if (debug) fprintf (stderr, "Checking %d...\n", mid); + + bc_int2num (&expo, mid-smallsize); + bc_raise (ten, expo, &num, 0); + bc_sub (num, _one_, &num, 0); + + mul_small_digits = mid+1; + t1 = timeit (big, num, &n1); + permul1 = (float)t1/(float)n1; + + mul_small_digits = mid-1; + t2 = timeit (big, num, &n2); + permul2 = (float)t2/(float)n2; + + if (permul1 < permul2) + min = mid+1; + else + max = mid-1; + + if (debug) { + fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2); + fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2); + } + } + + if (debug) + fprintf (stderr, "Non equal digits crossover at %d total digits\n", min); + printf ("#define MUL_SMALL_DIGITS = %d\n", min); + +#endif + + return 0; +} diff --git a/contrib/bc/lib/vfprintf.c b/contrib/bc/lib/vfprintf.c index 78edd35..ad53d0c 100644 --- a/contrib/bc/lib/vfprintf.c +++ b/contrib/bc/lib/vfprintf.c @@ -4,7 +4,7 @@ #include "config.h" #ifndef HAVE_VPRINTF #ifndef HAVE_DOPRINT -# error need vfprintf() or doprint() + #error need vfprintf() or doprint() #else #ifdef HAVE_LIB_H |