diff options
Diffstat (limited to 'contrib/bc/dc')
-rw-r--r-- | contrib/bc/dc/Makefile.in | 110 | ||||
-rw-r--r-- | contrib/bc/dc/array.c | 47 | ||||
-rw-r--r-- | contrib/bc/dc/dc-proto.h | 18 | ||||
-rw-r--r-- | contrib/bc/dc/dc.c | 28 | ||||
-rw-r--r-- | contrib/bc/dc/dc.h | 5 | ||||
-rw-r--r-- | contrib/bc/dc/eval.c | 93 | ||||
-rw-r--r-- | contrib/bc/dc/misc.c | 12 | ||||
-rw-r--r-- | contrib/bc/dc/numeric.c | 95 | ||||
-rw-r--r-- | contrib/bc/dc/stack.c | 46 | ||||
-rw-r--r-- | contrib/bc/dc/string.c | 12 |
10 files changed, 314 insertions, 152 deletions
diff --git a/contrib/bc/dc/Makefile.in b/contrib/bc/dc/Makefile.in index 44faf94..ae4e460 100644 --- a/contrib/bc/dc/Makefile.in +++ b/contrib/bc/dc/Makefile.in @@ -1,8 +1,14 @@ -# Makefile.in generated automatically by automake 1.1n from Makefile.am +# Makefile.in generated automatically by automake 1.3 from Makefile.am -# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. SHELL = /bin/sh @@ -26,6 +32,8 @@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include +DISTDIR = + pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -43,14 +51,15 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ -NORMAL_INSTALL = true -PRE_INSTALL = true -POST_INSTALL = true -NORMAL_UNINSTALL = true -PRE_UNINSTALL = true -POST_UNINSTALL = true +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : CC = @CC@ LEX = @LEX@ +MAKEINFO = @MAKEINFO@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ VERSION = @VERSION@ @@ -79,7 +88,7 @@ dc_DEPENDENCIES = ../lib/libbc.a dc_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -LINK = $(CC) $(LDFLAGS) -o $@ +LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ HEADERS = $(noinst_HEADERS) DIST_COMMON = Makefile.am Makefile.in @@ -92,14 +101,14 @@ GZIP = --best SOURCES = $(dc_SOURCES) OBJECTS = $(dc_OBJECTS) -default: all +all: Makefile $(PROGRAMS) $(HEADERS) .SUFFIXES: -.SUFFIXES: .c .o -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu dc/Makefile +.SUFFIXES: .S .c .o .s +$(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 $(BUILT_SOURCES) +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status @@ -107,7 +116,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) mostlyclean-binPROGRAMS: clean-binPROGRAMS: - test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: @@ -115,30 +124,36 @@ maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - $(mkinstalldirs) $(bindir) + $(mkinstalldirs) $(DESTDIR)$(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-binPROGRAMS: - $(NORMAL_UNINSTALL) + @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ done .c.o: $(COMPILE) -c $< +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + mostlyclean-compile: - rm -f *.o core + -rm -f *.o core *.core clean-compile: distclean-compile: - rm -f *.tab.c + -rm -f *.tab.c maintainer-clean-compile: @@ -148,30 +163,33 @@ dc: $(dc_OBJECTS) $(dc_DEPENDENCIES) tags: TAGS -ID: $(HEADERS) $(SOURCES) - here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS) +ID: $(HEADERS) $(SOURCES) $(LISP) + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - done; \ - test -z "$(ETAGS_ARGS)$(SOURCES)$(HEADERS)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $(SOURCES) $(HEADERS) -o $$here/TAGS) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: - rm -f TAGS ID + -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = dc + distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ @@ -195,28 +213,26 @@ install: install-exec install-data all uninstall: uninstall-binPROGRAMS -all: $(PROGRAMS) $(HEADERS) Makefile - install-strip: - $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: - $(mkinstalldirs) $(bindir) + $(mkinstalldirs) $(DATADIR)$(bindir) mostlyclean-generic: - test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: - test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - rm -f Makefile $(DISTCLEANFILES) - rm -f config.cache config.log stamp-h - test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -rm -f Makefile $(DISTCLEANFILES) + -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) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic @@ -225,7 +241,7 @@ clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean-generic clean - rm -f config.status + -rm -f config.status maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ maintainer-clean-tags maintainer-clean-generic \ @@ -233,9 +249,9 @@ maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -.PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ -clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ -install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ +.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 \ diff --git a/contrib/bc/dc/array.c b/contrib/bc/dc/array.c index 2fc1b7e..bc701a1 100644 --- a/contrib/bc/dc/array.c +++ b/contrib/bc/dc/array.c @@ -1,7 +1,7 @@ /* * implement arrays for dc * - * Copyright (C) 1994 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -39,20 +39,12 @@ struct dc_array { dc_data value; struct dc_array *next; }; -typedef struct dc_array dc_array; -/* I can find no reason not to place arrays in their own namespace... */ -static dc_array *dc_array_register[DC_REGCOUNT]; - -/* initialize the arrays to their initial values */ +/* initialize the arrays */ void dc_array_init DC_DECLVOID() { - int i; - - for (i=0; i<DC_REGCOUNT; ++i) - dc_array_register[i] = NULL; } /* store value into array_id[Index] */ @@ -62,12 +54,11 @@ dc_array_set DC_DECLARG((array_id, Index, value)) int Index DC_DECLSEP dc_data value DC_DECLEND { - dc_array *cur; - dc_array *prev=NULL; - dc_array *newentry; + struct dc_array *cur; + struct dc_array *prev=NULL; + struct dc_array *newentry; - array_id = regmap(array_id); - cur = dc_array_register[array_id]; + cur = dc_get_stacked_array(array_id); while (cur && cur->Index < Index){ prev = cur; cur = cur->next; @@ -88,7 +79,7 @@ dc_array_set DC_DECLARG((array_id, Index, value)) if (prev) prev->next = newentry; else - dc_array_register[array_id] = newentry; + dc_set_stacked_array(array_id, newentry); } } @@ -99,10 +90,30 @@ dc_array_get DC_DECLARG((array_id, Index)) int array_id DC_DECLSEP int Index DC_DECLEND { - dc_array *cur; + struct dc_array *cur; - for (cur=dc_array_register[regmap(array_id)]; cur; cur=cur->next) + for (cur=dc_get_stacked_array(array_id); cur; cur=cur->next) if (cur->Index == Index) return dc_dup(cur->value); return dc_int2data(0); } + +/* free an array chain */ +void +dc_array_free DC_DECLARG((a_head)) + struct dc_array *a_head DC_DECLEND +{ + struct dc_array *cur; + struct dc_array *next; + + for (cur=a_head; cur; cur=next) { + next = cur->next; + if (cur->value.dc_type == DC_NUMBER) + dc_free_num(&cur->value.v.number); + else if (cur->value.dc_type == DC_STRING) + dc_free_str(&cur->value.v.string); + else + dc_garbage("in stack", -1); + free(cur); + } +} diff --git a/contrib/bc/dc/dc-proto.h b/contrib/bc/dc/dc-proto.h index 5aa9bc7..1e7c52c 100644 --- a/contrib/bc/dc/dc-proto.h +++ b/contrib/bc/dc/dc-proto.h @@ -1,7 +1,7 @@ /* * prototypes of all externally visible dc functions * - * Copyright (C) 1994, 1997 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -22,8 +22,10 @@ extern const char *dc_str2charp DC_PROTO((dc_str)); extern const char *dc_system DC_PROTO((const char *)); extern void *dc_malloc DC_PROTO((size_t)); +extern struct dc_array *dc_get_stacked_array DC_PROTO((int)); extern void dc_array_set DC_PROTO((int, int, dc_data)); +extern void dc_array_free DC_PROTO((struct dc_array *)); extern void dc_array_init DC_PROTO((void)); extern void dc_binop DC_PROTO((int (*)(dc_num, dc_num, int, dc_num *), int)); extern void dc_binop2 DC_PROTO((int (*)(dc_num, dc_num, int, @@ -31,19 +33,21 @@ extern void dc_binop2 DC_PROTO((int (*)(dc_num, dc_num, int, extern void dc_triop DC_PROTO((int (*)(dc_num, dc_num, dc_num, int, dc_num *), int)); extern void dc_clear_stack DC_PROTO((void)); +extern void dc_dump_num(dc_num, dc_discard); extern void dc_free_num DC_PROTO((dc_num *)); extern void dc_free_str DC_PROTO((dc_str *)); extern void dc_garbage DC_PROTO((const char *, int)); extern void dc_math_init DC_PROTO((void)); extern void dc_memfail DC_PROTO((void)); -extern void dc_out_num DC_PROTO((dc_num, int, dc_boolean, dc_boolean)); -extern void dc_out_str DC_PROTO((dc_str, dc_boolean, dc_boolean)); -extern void dc_print DC_PROTO((dc_data, int)); +extern void dc_out_num DC_PROTO((dc_num, int, dc_newline, dc_discard)); +extern void dc_out_str DC_PROTO((dc_str, dc_newline, dc_discard)); +extern void dc_print DC_PROTO((dc_data, int, dc_newline, dc_discard)); extern void dc_printall DC_PROTO((int)); extern void dc_push DC_PROTO((dc_data)); extern void dc_register_init DC_PROTO((void)); extern void dc_register_push DC_PROTO((int, dc_data)); extern void dc_register_set DC_PROTO((int, dc_data)); +extern void dc_set_stacked_array DC_PROTO((int, struct dc_array *)); extern void dc_show_id DC_PROTO((FILE *, int, const char *)); extern void dc_string_init DC_PROTO((void)); @@ -51,13 +55,13 @@ extern int dc_cmpop DC_PROTO((void)); extern int dc_compare DC_PROTO((dc_num, dc_num)); extern int dc_evalfile DC_PROTO((FILE *)); extern int dc_evalstr DC_PROTO((dc_data)); -extern int dc_num2int DC_PROTO((dc_num, dc_boolean)); +extern int dc_num2int DC_PROTO((dc_num, dc_discard)); extern int dc_numlen DC_PROTO((dc_num)); extern int dc_pop DC_PROTO((dc_data *)); extern int dc_register_get DC_PROTO((int, dc_data *)); extern int dc_register_pop DC_PROTO((int, dc_data *)); -extern int dc_tell_length DC_PROTO((dc_data, dc_boolean)); -extern int dc_tell_scale DC_PROTO((dc_num, dc_boolean)); +extern int dc_tell_length DC_PROTO((dc_data, dc_discard)); +extern int dc_tell_scale DC_PROTO((dc_num, dc_discard)); extern int dc_tell_stackdepth DC_PROTO((void)); extern int dc_top_of_stack DC_PROTO((dc_data *)); diff --git a/contrib/bc/dc/dc.c b/contrib/bc/dc/dc.c index 85da40f..fa213ba 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 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -65,7 +65,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 @\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); } @@ -94,17 +95,21 @@ r1bindex DC_DECLARG((s, c)) } static void -try_file(const char *filename) { +try_file(const char *filename) +{ FILE *input; - if ( !(input=fopen(filename, "r")) ) { + if (strcmp(filename, "-") == 0) { + input = stdin; + } else if ( !(input=fopen(filename, "r")) ) { fprintf(stderr, "Could not open file "); perror(filename); exit(EXIT_FAILURE); } if (dc_evalfile(input)) exit(EXIT_FAILURE); - fclose(input); + if (input != stdin) + fclose(input); } @@ -124,12 +129,16 @@ main DC_DECLARG((argc, argv)) int c; progname = r1bindex(*argv, '/'); +#ifdef HAVE_SETVBUF + /* attempt to simplify interaction with applications such as emacs */ + (void) setvbuf(stdout, NULL, _IOLBF, 0); +#endif dc_math_init(); dc_string_init(); dc_register_init(); dc_array_init(); - while ((c = getopt_long(argc, argv, "hVe:", long_opts, (int *)0)) != EOF) { + while ((c = getopt_long(argc, argv, "hVe:f:", long_opts, (int *)0)) != EOF) { switch (c) { case 'e': { dc_data string = dc_makestring(optarg, strlen(optarg)); @@ -156,12 +165,7 @@ main DC_DECLARG((argc, argv)) } for (; optind < argc; ++optind) { - if (strcmp(argv[optind], "-") == 0) { - if (dc_evalfile(stdin)) - return EXIT_FAILURE; - } else { - try_file(argv[optind]); - } + try_file(argv[optind]); did_eval = 1; } if (!did_eval) { diff --git a/contrib/bc/dc/dc.h b/contrib/bc/dc/dc.h index eeac77b..5e2d65a 100644 --- a/contrib/bc/dc/dc.h +++ b/contrib/bc/dc/dc.h @@ -1,7 +1,7 @@ /* * Header file for dc routines * - * Copyright (C) 1994, 1997 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -47,7 +47,8 @@ #endif /* __STDC__ */ -typedef enum {DC_FALSE, DC_TRUE} dc_boolean; +typedef enum {DC_TOSS, DC_KEEP} dc_discard; +typedef enum {DC_NONL, DC_WITHNL} dc_newline; /* type discriminant for dc_data */ diff --git a/contrib/bc/dc/eval.c b/contrib/bc/dc/eval.c index cac4cb1..0cb2185 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 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -38,6 +38,8 @@ #include "dc.h" #include "dc-proto.h" +typedef enum {DC_FALSE, DC_TRUE} dc_boolean; + typedef enum { DC_OKAY = DC_SUCCESS, /* no further intervention needed for this command */ DC_EATONE, /* caller needs to eat the lookahead char */ @@ -50,6 +52,7 @@ typedef enum { DC_STR, /* caller needs to parse a dc_str from input stream */ DC_SYSTEM, /* caller needs to run a system() on next input line */ DC_COMMENT, /* caller needs to skip to the next input line */ + DC_NEGCMP, /* caller needs to re-call dc_func() with `negcmp' set */ DC_EOF_ERROR /* unexpected end of input; abort current eval */ } dc_status; @@ -127,11 +130,13 @@ dc_eval_and_free_str DC_DECLARG((string)) * * c -> the "current" input character under consideration * peekc -> the lookahead input character + * negcmp -> negate comparison test (for <,=,> commands) */ static dc_status -dc_func DC_DECLARG((c, peekc)) +dc_func DC_DECLARG((c, peekc, negcmp)) int c DC_DECLSEP - int peekc DC_DECLEND + int peekc DC_DECLSEP + int negcmp DC_DECLEND { /* we occasionally need these for temporary data */ /* Despite the GNU coding standards, it is much easier @@ -198,7 +203,7 @@ dc_func DC_DECLARG((c, peekc)) */ if (peekc == EOF) return DC_EOF_ERROR; - if (dc_cmpop() < 0) + if ( (dc_cmpop() < 0) == !negcmp ) if (dc_register_get(peekc, &datum) == DC_SUCCESS) if (dc_eval_and_free_str(datum) == DC_QUIT) return DC_QUIT; @@ -209,7 +214,7 @@ dc_func DC_DECLARG((c, peekc)) */ if (peekc == EOF) return DC_EOF_ERROR; - if (dc_cmpop() == 0) + if ( (dc_cmpop() == 0) == !negcmp ) if (dc_register_get(peekc, &datum) == DC_SUCCESS) if (dc_eval_and_free_str(datum) == DC_QUIT) return DC_QUIT; @@ -220,7 +225,7 @@ dc_func DC_DECLARG((c, peekc)) */ if (peekc == EOF) return DC_EOF_ERROR; - if (dc_cmpop() > 0) + if ( (dc_cmpop() > 0) == !negcmp ) if (dc_register_get(peekc, &datum) == DC_SUCCESS) if (dc_eval_and_free_str(datum) == DC_QUIT) return DC_QUIT; @@ -236,6 +241,8 @@ dc_func DC_DECLARG((c, peekc)) case '[': /* read to balancing ']' into a dc_str */ return DC_STR; case '!': /* read to newline and call system() on resulting string */ + if (peekc == '<' || peekc == '=' || peekc == '>') + return DC_NEGCMP; return DC_SYSTEM; case '#': /* comment; skip remainder of current line */ return DC_COMMENT; @@ -244,8 +251,7 @@ dc_func DC_DECLARG((c, peekc)) if (dc_pop(&datum) == DC_SUCCESS){ char tmps; if (datum.dc_type == DC_NUMBER){ - tmps = (char) dc_num2int(datum.v.number, DC_TRUE); - dc_free_num(&datum.v.number); + tmps = (char) dc_num2int(datum.v.number, DC_TOSS); }else if (datum.dc_type == DC_STRING){ tmps = *dc_str2charp(datum.v.string); dc_free_str(&datum.v.string); @@ -269,7 +275,7 @@ dc_func DC_DECLARG((c, peekc)) if (dc_pop(&datum) == DC_SUCCESS){ tmpint = 0; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) ) fprintf(stderr, "%s: input base must be a number \ @@ -283,7 +289,7 @@ between 2 and %d (inclusive)\n", if (dc_pop(&datum) == DC_SUCCESS){ tmpint = -1; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); if ( ! (tmpint >= 0) ) fprintf(stderr, "%s: scale must be a nonnegative number\n", @@ -301,11 +307,17 @@ between 2 and %d (inclusive)\n", if (dc_register_get(peekc, &datum) == DC_SUCCESS) dc_push(datum); return DC_EATONE; + case 'n': /* print the value popped off of top-of-stack; + * do not add a trailing newline + */ + if (dc_pop(&datum) == DC_SUCCESS) + dc_print(datum, dc_obase, DC_NONL, DC_TOSS); + break; case 'o': /* set output base to value on top of stack */ if (dc_pop(&datum) == DC_SUCCESS){ tmpint = 0; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); if ( ! (tmpint > 1) ) fprintf(stderr, "%s: output base must be a number greater than 1\n", @@ -314,12 +326,14 @@ between 2 and %d (inclusive)\n", dc_obase = tmpint; } break; - case 'p': /* print the datum on the top of stack */ + case 'p': /* print the datum on the top of stack, + * with a trailing newline + */ if (dc_top_of_stack(&datum) == DC_SUCCESS) - dc_print(datum, dc_obase); + dc_print(datum, dc_obase, DC_WITHNL, DC_KEEP); break; case 'q': /* quit two levels of evaluation, posibly exiting program */ - unwind_depth = 2; + unwind_depth = 1; /* the return below is the first level of returns */ unwind_noexit = DC_FALSE; return DC_QUIT; case 'r': /* rotate (swap) the top two elements on the stack @@ -389,14 +403,18 @@ between 2 and %d (inclusive)\n", case 'O': /* push the current output base onto the stack */ dc_push(dc_int2data(dc_obase)); break; - case 'P': /* print the value popped off of top-of-stack; - * do not add a trailing newline - */ + case 'P': + /* Pop the value off the top of a stack. If it is + * a number, dump out the integer portion of its + * absolute value as a "base UCHAR_MAX+1" byte stream; + * if it is a string, just print it. + * In either case, do not append a trailing newline. + */ if (dc_pop(&datum) == DC_SUCCESS){ - if (datum.dc_type == DC_STRING) - dc_out_str(datum.v.string, DC_FALSE, DC_TRUE); - else if (datum.dc_type == DC_NUMBER) - dc_out_num(datum.v.number, dc_obase, DC_FALSE, DC_TRUE); + if (datum.dc_type == DC_NUMBER) + dc_dump_num(datum.v.number, DC_TOSS); + else if (datum.dc_type == DC_STRING) + dc_out_str(datum.v.string, DC_NONL, DC_TOSS); else dc_garbage("at top of stack", -1); } @@ -409,9 +427,10 @@ between 2 and %d (inclusive)\n", unwind_depth = 0; unwind_noexit = DC_TRUE; if (datum.dc_type == DC_NUMBER) - unwind_depth = dc_num2int(datum.v.number, DC_TRUE); - if (unwind_depth > 0) + unwind_depth = dc_num2int(datum.v.number, DC_TOSS); + if (unwind_depth-- > 0) return DC_QUIT; + unwind_depth = 0; /* paranoia */ fprintf(stderr, "%s: Q command requires a number >= 1\n", progname); @@ -427,7 +446,7 @@ between 2 and %d (inclusive)\n", if (dc_pop(&datum) == DC_SUCCESS){ tmpint = 0; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); dc_stack_rotate(tmpint); } break; @@ -444,13 +463,13 @@ between 2 and %d (inclusive)\n", if (dc_pop(&datum) == DC_SUCCESS){ tmpint = 0; if (datum.dc_type == DC_NUMBER) - tmpint = dc_tell_scale(datum.v.number, DC_TRUE); + tmpint = dc_tell_scale(datum.v.number, DC_TOSS); dc_push(dc_int2data(tmpint)); } break; case 'Z': /* replace the datum on the top-of-stack with its length */ if (dc_pop(&datum) == DC_SUCCESS) - dc_push(dc_int2data(dc_tell_length(datum, DC_TRUE))); + dc_push(dc_int2data(dc_tell_length(datum, DC_TOSS))); break; case ':': /* store into array */ @@ -459,7 +478,7 @@ between 2 and %d (inclusive)\n", if (dc_pop(&datum) == DC_SUCCESS){ tmpint = -1; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); if (dc_pop(&datum) == DC_SUCCESS){ if (tmpint < 0) fprintf(stderr, @@ -476,7 +495,7 @@ between 2 and %d (inclusive)\n", if (dc_pop(&datum) == DC_SUCCESS){ tmpint = -1; if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); + tmpint = dc_num2int(datum.v.number, DC_TOSS); if (tmpint < 0) fprintf(stderr, "%s: array index must be a nonnegative integer\n", @@ -507,6 +526,8 @@ dc_evalstr DC_DECLARG((string)) int c; int peekc; int count; + int negcmp; + int next_negcmp = 0; if (string.dc_type != DC_STRING){ fprintf(stderr, @@ -521,7 +542,9 @@ dc_evalstr DC_DECLARG((string)) peekc = EOF; if (s < end) peekc = *(const unsigned char *)s; - switch (dc_func(c, peekc)){ + negcmp = next_negcmp; + next_negcmp = 0; + switch (dc_func(c, peekc, negcmp)){ case DC_OKAY: break; case DC_EATONE: @@ -562,6 +585,9 @@ dc_evalstr DC_DECLARG((string)) else ++s; break; + case DC_NEGCMP: + next_negcmp = 1; + break; case DC_EOF_ERROR: fprintf(stderr, "%s: unexpected EOS\n", progname); @@ -582,6 +608,8 @@ dc_evalfile DC_DECLARG((fp)) { int c; int peekc; + int negcmp; + int next_negcmp = 0; dc_data datum; stdin_lookahead = EOF; @@ -593,7 +621,9 @@ dc_evalfile DC_DECLARG((fp)) */ if (fp == stdin) stdin_lookahead = peekc; - switch (dc_func(c, peekc)){ + negcmp = next_negcmp; + next_negcmp = 0; + switch (dc_func(c, peekc, negcmp)){ case DC_OKAY: if (stdin_lookahead != peekc && fp == stdin) peekc = getc(fp); @@ -636,6 +666,9 @@ dc_evalfile DC_DECLARG((fp)) if (peekc != EOF) peekc = getc(fp); break; + case DC_NEGCMP: + next_negcmp = 1; + break; case DC_EOF_ERROR: fprintf(stderr, "%s: unexpected EOF\n", progname); diff --git a/contrib/bc/dc/misc.c b/contrib/bc/dc/misc.c index 8c360ca..65f986b 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 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -150,14 +150,16 @@ dc_system DC_DECLARG((s)) /* print out the indicated value */ void -dc_print DC_DECLARG((value, obase)) +dc_print DC_DECLARG((value, obase, newline_p, discard_p)) dc_data value DC_DECLSEP - int obase DC_DECLEND + int obase DC_DECLSEP + dc_newline newline_p DC_DECLSEP + dc_discard discard_p DC_DECLEND { if (value.dc_type == DC_NUMBER) { - dc_out_num(value.v.number, obase, DC_TRUE, DC_FALSE); + dc_out_num(value.v.number, obase, newline_p, discard_p); } else if (value.dc_type == DC_STRING) { - dc_out_str(value.v.string, DC_TRUE, DC_FALSE); + dc_out_str(value.v.string, newline_p, discard_p); } else { dc_garbage("in data being printed", -1); } diff --git a/contrib/bc/dc/numeric.c b/contrib/bc/dc/numeric.c index ec19344..d5abf13 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 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -28,12 +28,23 @@ #include <stdio.h> #include <ctype.h> +#ifdef HAVE_LIMITS_H +# include <limits.h> +#else +# define UCHAR_MAX ((unsigned char)~0) +#endif #include "bcdefs.h" #include "proto.h" #include "global.h" #include "dc.h" #include "dc-proto.h" +#ifdef __GNUC__ +# define ATTRIB(x) __attribute__(x) +#else +# define ATTRIB(x) +#endif + /* there is no POSIX standard for dc, so we'll take the GNU definitions */ int std_only = FALSE; @@ -47,7 +58,7 @@ int dc_add DC_DECLARG((a, b, kscale, result)) dc_num a DC_DECLSEP dc_num b DC_DECLSEP - int kscale DC_DECLSEP + int kscale ATTRIB((unused)) DC_DECLSEP dc_num *result DC_DECLEND { init_num((bc_num *)result); @@ -62,7 +73,7 @@ int dc_sub DC_DECLARG((a, b, kscale, result)) dc_num a DC_DECLSEP dc_num b DC_DECLSEP - int kscale DC_DECLSEP + int kscale ATTRIB((unused)) DC_DECLSEP dc_num *result DC_DECLEND { init_num((bc_num *)result); @@ -211,17 +222,17 @@ dc_compare DC_DECLARG((a, b)) } /* attempt to convert a dc_num to its corresponding int value - * If discard_flag is true then deallocate the value after use. + * If discard_p is DC_TOSS then deallocate the value after use. */ int -dc_num2int DC_DECLARG((value, discard_flag)) +dc_num2int DC_DECLARG((value, discard_p)) dc_num value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND + dc_discard discard_p DC_DECLEND { long result; result = num2long(CastNum(value)); - if (discard_flag) + if (discard_p == DC_TOSS) dc_free_num(&value); return (int)result; } @@ -346,17 +357,17 @@ dc_numlen DC_DECLARG((value)) } /* return the scale factor of the passed dc_num - * If discard_flag is true then deallocate the value after use. + * If discard_p is DC_TOSS then deallocate the value after use. */ int -dc_tell_scale DC_DECLARG((value, discard_flag)) +dc_tell_scale DC_DECLARG((value, discard_p)) dc_num value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND + dc_discard discard_p DC_DECLEND { int kscale; kscale = CastNum(value)->n_scale; - if (discard_flag) + if (discard_p == DC_TOSS) dc_free_num(&value); return kscale; } @@ -370,23 +381,71 @@ dc_math_init DC_DECLVOID() } /* print out a dc_num in output base obase to stdout; - * if newline is true, terminate output with a '\n'; - * if discard_flag is true then deallocate the value after use + * if newline_p is DC_WITHNL, terminate output with a '\n'; + * if discard_p is DC_TOSS then deallocate the value after use */ void -dc_out_num DC_DECLARG((value, obase, newline, discard_flag)) +dc_out_num DC_DECLARG((value, obase, newline_p, discard_p)) dc_num value DC_DECLSEP int obase DC_DECLSEP - dc_boolean newline DC_DECLSEP - dc_boolean discard_flag DC_DECLEND + dc_newline newline_p DC_DECLSEP + dc_discard discard_p DC_DECLEND { out_num(CastNum(value), obase, out_char); - if (newline) + if (newline_p == DC_WITHNL) out_char('\n'); - if (discard_flag) + if (discard_p == DC_TOSS) dc_free_num(&value); } +/* dump out the absolute value of the integer part of a + * dc_num as a byte stream, without any line wrapping; + * if discard_p is DC_TOSS then deallocate the value after use + */ +void +dc_dump_num DC_DECLARG((value, discard_p)) + dc_num dcvalue DC_DECLSEP + dc_discard discard_p DC_DECLEND +{ + struct digit_stack { int digit; struct digit_stack *link;}; + struct digit_stack *top_of_stack = NULL; + struct digit_stack *cur; + struct digit_stack *next; + bc_num value; + bc_num obase; + bc_num digit; + + init_num(&value); + init_num(&obase); + init_num(&digit); + + /* we only handle the integer portion: */ + bc_divide(CastNum(dcvalue), _one_, &value, 0); + /* we only handle the absolute value: */ + value->n_sign = PLUS; + /* we're done with the dcvalue parameter: */ + if (discard_p == DC_TOSS) + dc_free_num(&dcvalue); + + 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->link = top_of_stack; + top_of_stack = cur; + } while (!is_zero(value)); + + for (cur=top_of_stack; cur; cur=next) { + putchar(cur->digit); + next = cur->link; + free(cur); + } + + free_num(&digit); + free_num(&obase); + free_num(&value); +} /* deallocate an instance of a dc_num */ void diff --git a/contrib/bc/dc/stack.c b/contrib/bc/dc/stack.c index c8cd195..0268b70 100644 --- a/contrib/bc/dc/stack.c +++ b/contrib/bc/dc/stack.c @@ -1,7 +1,7 @@ /* * implement stack functions for dc * - * Copyright (C) 1994, 1997 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -41,6 +41,7 @@ /* simple linked-list implementaion suffices: */ struct dc_list { dc_data value; + struct dc_array *array; /* opaque */ struct dc_list *link; }; typedef struct dc_list dc_list; @@ -60,6 +61,7 @@ dc_alloc DC_DECLVOID() result = dc_malloc(sizeof *result); result->value.dc_type = DC_UNINITIALIZED; + result->array = NULL; result->link = NULL; return result; } @@ -247,6 +249,7 @@ dc_clear_stack DC_DECLVOID() dc_free_str(&n->value.v.string); else dc_garbage("in stack", -1); + dc_array_free(n->array); free(n); } dc_stack = NULL; @@ -369,6 +372,7 @@ dc_pop DC_DECLARG((result)) dc_garbage("at top of stack", -1); *result = r->value; dc_stack = r->link; + dc_array_free(r->array); free(r); return DC_SUCCESS; } @@ -396,6 +400,7 @@ dc_register_pop DC_DECLARG((stackid, result)) dc_garbage(" stack", stackid); *result = r->value; dc_register[stackid] = r->link; + dc_array_free(r->array); free(r); return DC_SUCCESS; } @@ -415,25 +420,25 @@ dc_tell_stackdepth DC_DECLVOID() /* return the length of the indicated data value; - * if discard_flag is true, the deallocate the value when done + * if discard_p is DC_TOSS, the deallocate the value when done * * The definition of a datum's length is deligated to the * appropriate module. */ int -dc_tell_length DC_DECLARG((value, discard_flag)) +dc_tell_length DC_DECLARG((value, discard_p)) dc_data value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND + dc_discard discard_p DC_DECLEND { int length; if (value.dc_type == DC_NUMBER){ length = dc_numlen(value.v.number); - if (discard_flag == DC_TRUE) + if (discard_p == DC_TOSS) dc_free_num(&value.v.number); } else if (value.dc_type == DC_STRING) { length = dc_strlen(value.v.string); - if (discard_flag == DC_TRUE) + if (discard_p == DC_TOSS) dc_free_str(&value.v.string); } else { dc_garbage("in tell_length", -1); @@ -453,5 +458,32 @@ dc_printall DC_DECLARG((obase)) dc_list *n; for (n=dc_stack; n; n=n->link) - dc_print(n->value, obase); + dc_print(n->value, obase, DC_WITHNL, DC_KEEP); +} + + + + +/* get the current array head for the named array */ +struct dc_array * +dc_get_stacked_array DC_DECLARG((array_id)) + int array_id DC_DECLEND +{ + dc_list *r = dc_register[regmap(array_id)]; + return r ? r->array : NULL; +} + +/* set the current array head for the named array */ +void +dc_set_stacked_array DC_DECLARG((array_id, new_head)) + int array_id DC_DECLSEP + struct dc_array *new_head DC_DECLEND +{ + dc_list *r; + + array_id = regmap(array_id); + r = dc_register[array_id]; + if ( ! r ) + r = dc_register[array_id] = dc_alloc(); + r->array = new_head; } diff --git a/contrib/bc/dc/string.c b/contrib/bc/dc/string.c index 35bc263..6cffffd 100644 --- a/contrib/bc/dc/string.c +++ b/contrib/bc/dc/string.c @@ -1,7 +1,7 @@ /* * implement string functions for dc * - * Copyright (C) 1994, 1997 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997, 1998 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 @@ -92,13 +92,13 @@ dc_free_str DC_DECLARG((value)) void dc_out_str DC_DECLARG((value, newline, discard_flag)) dc_str value DC_DECLSEP - dc_boolean newline DC_DECLSEP - dc_boolean discard_flag DC_DECLEND + dc_newline newline DC_DECLSEP + dc_discard discard_flag DC_DECLEND { fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout); - if (newline == DC_TRUE) - printf("\n"); - if (discard_flag == DC_TRUE) + if (newline == DC_WITHNL) + putchar('\n'); + if (discard_flag == DC_TOSS) dc_free_str(&value); } |