summaryrefslogtreecommitdiffstats
path: root/contrib/bc/dc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bc/dc')
-rw-r--r--contrib/bc/dc/Makefile.in110
-rw-r--r--contrib/bc/dc/array.c47
-rw-r--r--contrib/bc/dc/dc-proto.h18
-rw-r--r--contrib/bc/dc/dc.c28
-rw-r--r--contrib/bc/dc/dc.h5
-rw-r--r--contrib/bc/dc/eval.c93
-rw-r--r--contrib/bc/dc/misc.c12
-rw-r--r--contrib/bc/dc/numeric.c95
-rw-r--r--contrib/bc/dc/stack.c46
-rw-r--r--contrib/bc/dc/string.c12
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);
}
OpenPOWER on IntegriCloud