diff options
author | Jari Aalto <jari.aalto@cante.net> | 2001-11-13 17:56:06 +0000 |
---|---|---|
committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:54 +0000 |
commit | f73dda092b33638d2d5e9c35375f687a607b5403 (patch) | |
tree | f21584e70a444d6a1ecba0fb5e2cf79e8cce91db /lib/sh | |
parent | 28ef6c316f1aff914bb95ac09787a3c83c1815fd (diff) | |
download | android_external_bash-f73dda092b33638d2d5e9c35375f687a607b5403.tar.gz android_external_bash-f73dda092b33638d2d5e9c35375f687a607b5403.tar.bz2 android_external_bash-f73dda092b33638d2d5e9c35375f687a607b5403.zip |
Imported from ../bash-2.05a.tar.gz.
Diffstat (limited to 'lib/sh')
-rw-r--r-- | lib/sh/Makefile.in | 134 | ||||
-rw-r--r-- | lib/sh/clock.c | 19 | ||||
-rw-r--r-- | lib/sh/fmtullong.c | 24 | ||||
-rw-r--r-- | lib/sh/fmtulong.c | 196 | ||||
-rw-r--r-- | lib/sh/getcwd.c | 34 | ||||
-rw-r--r-- | lib/sh/inet_aton.c | 7 | ||||
-rw-r--r-- | lib/sh/itos.c | 65 | ||||
-rw-r--r-- | lib/sh/mailstat.c | 159 | ||||
-rw-r--r-- | lib/sh/makepath.c | 19 | ||||
-rw-r--r-- | lib/sh/netopen.c | 112 | ||||
-rw-r--r-- | lib/sh/oslib.c | 2 | ||||
-rw-r--r-- | lib/sh/pathcanon.c | 18 | ||||
-rw-r--r-- | lib/sh/pathphys.c | 21 | ||||
-rw-r--r-- | lib/sh/setlinebuf.c | 6 | ||||
-rw-r--r-- | lib/sh/shquote.c | 20 | ||||
-rw-r--r-- | lib/sh/snprintf.c | 1665 | ||||
-rw-r--r-- | lib/sh/strcasecmp.c | 10 | ||||
-rw-r--r-- | lib/sh/strindex.c | 13 | ||||
-rw-r--r-- | lib/sh/stringlist.c | 21 | ||||
-rw-r--r-- | lib/sh/stringvec.c | 22 | ||||
-rw-r--r-- | lib/sh/strtod.c | 8 | ||||
-rw-r--r-- | lib/sh/strtoimax.c | 102 | ||||
-rw-r--r-- | lib/sh/strtol.c | 210 | ||||
-rw-r--r-- | lib/sh/strtoll.c | 26 | ||||
-rw-r--r-- | lib/sh/strtoull.c | 27 | ||||
-rw-r--r-- | lib/sh/strtoumax.c | 102 | ||||
-rw-r--r-- | lib/sh/strtrans.c | 53 | ||||
-rw-r--r-- | lib/sh/times.c | 2 | ||||
-rw-r--r-- | lib/sh/timeval.c | 15 | ||||
-rw-r--r-- | lib/sh/tmpfile.c | 78 | ||||
-rw-r--r-- | lib/sh/zread.c | 31 | ||||
-rw-r--r-- | lib/sh/zwrite.c | 2 |
32 files changed, 2884 insertions, 339 deletions
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index 1c52e0d..126f5f8 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -40,7 +40,7 @@ MV = mv SHELL = @MAKE_SHELL@ CFLAGS = @CFLAGS@ -LOCAL_CFLAGS = @LOCAL_CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ ${DEBUG} CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ @@ -54,6 +54,10 @@ INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \ $(CFLAGS) $(CPPFLAGS) +GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wstrict-prototypes -Wconversion \ + -Wmissing-prototypes -Wtraditional -Wredundant-decls -pedantic + .c.o: $(CC) -c $(CCFLAGS) $< @@ -66,18 +70,20 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ vprint.c itos.c rename.c zread.c zwrite.c shtty.c \ inet_aton.c netopen.c strpbrk.c timeval.c makepath.c pathcanon.c \ pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \ - shquote.c strtrans.c strindex.c + shquote.c strtrans.c strindex.c snprintf.c mailstat.c fmtulong.c \ + fmtullong.c strtoll.c strtoull.c strtoimax.c strtoumax.c # The header files for this library. HSOURCES = # The object files contained in $(LIBRARY_NAME) -OBJECTS = clktck.o clock.o getcwd.o getenv.o oslib.o setlinebuf.o \ - strcasecmp.o strerror.o strtod.o strtol.o strtoul.o \ - vprint.o itos.o rename.o zread.o zwrite.o shtty.o \ - inet_aton.o netopen.o strpbrk.o timeval.o makepath.o pathcanon.o \ +LIBOBJS = @LIBOBJS@ +OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o \ + itos.o zread.o zwrite.o shtty.o \ + netopen.o timeval.o makepath.o pathcanon.o \ pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \ - strtrans.o strindex.o + strtrans.o strindex.o snprintf.o mailstat.o fmtulong.o \ + fmtullong.o ${LIBOBJS} SUPPORT = Makefile @@ -108,10 +114,13 @@ mostlyclean: clean # rules for losing makes, like SunOS clktck.o: clktck.c clock.o: clock.c +fmtullong.o: fmtullong.c +fmtulong.o: fmtulong.c getcwd.o: getcwd.c getenv.o: getenv.c inet_aton.o: inet_aton.c itos.o: itos.c +mailstat.o: mailstat.c makepath.o: makepath.c netopen.o: netopen.c oslib.o: oslib.c @@ -121,6 +130,7 @@ rename.o: rename.c setlinebuf.o: setlinebuf.c shquote.o: shquote.c shtty.o: shtty.c +snprintf.o: snprintf.c spell.o: spell.c strcasecmp.o: strcasecmp.c strerror.o: strerror.c @@ -129,8 +139,12 @@ stringlist.o: stringlist.c stringvec.o: stringvec.c strpbrk.o: strpbrk.c strtod.o: strtod.c +strtoimax.o: strtoimax.c strtol.o: strtol.c +strtoll.o: strtoll.c strtoul.o: strtoul.c +strtoull.o: strtoull.c +strtoumax.o: strtoumax.c strtrans.o: strtrans.c times.o: times.c timeval.o: timeval.c @@ -139,13 +153,22 @@ vprint.o: vprint.c zread.o: zread.c zwrite.o: zwrite.c +# dependencies for c files that include other c files +fmtullong.o: fmtulong.c +strtoll.o: strtol.c +strtoul.o: strtol.c +strtoull.o: strtol.c + # all files in the library depend on config.h clktck.o: ${BUILD_DIR}/config.h clock.o: ${BUILD_DIR}/config.h +fmtullong.o: ${BUILD_DIR}/config.h +fmtulong.o: ${BUILD_DIR}/config.h getcwd.o: ${BUILD_DIR}/config.h getenv.o: ${BUILD_DIR}/config.h inet_aton.o: ${BUILD_DIR}/config.h itos.o: ${BUILD_DIR}/config.h +mailstat.o: ${BUILD_DIR}/config.h makepath.o: ${BUILD_DIR}/config.h netopen.o: ${BUILD_DIR}/config.h oslib.o: ${BUILD_DIR}/config.h @@ -155,6 +178,7 @@ rename.o: ${BUILD_DIR}/config.h setlinebuf.o: ${BUILD_DIR}/config.h shquote.o: ${BUILD_DIR}/config.h shtty.o: ${BUILD_DIR}/config.h +snprintf.o: ${BUILD_DIR}/config.h spell.o: ${BUILD_DIR}/config.h strcasecmp.o: ${BUILD_DIR}/config.h strerror.o: ${BUILD_DIR}/config.h @@ -163,8 +187,12 @@ stringlist.o: ${BUILD_DIR}/config.h stringvec.o: ${BUILD_DIR}/config.h strpbrk.o: ${BUILD_DIR}/config.h strtod.o: ${BUILD_DIR}/config.h +strtoimax.o: ${BUILD_DIR}/config.h strtol.o: ${BUILD_DIR}/config.h +strtoll.o: ${BUILD_DIR}/config.h strtoul.o: ${BUILD_DIR}/config.h +strtoull.o: ${BUILD_DIR}/config.h +strtoumax.o: ${BUILD_DIR}/config.h strtrans.o: ${BUILD_DIR}/config.h times.o: ${BUILD_DIR}/config.h timeval.o: ${BUILD_DIR}/config.h @@ -182,7 +210,7 @@ getcwd.o: ${BASHINCDIR}/memalloc.h ${BASHINCDIR}/ansi_stdlib.h getenv.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h getenv.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h getenv.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -getenv.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +getenv.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h getenv.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h getenv.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h getenv.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h @@ -194,7 +222,7 @@ inet_aton.o: ${BASHINCDIR}/stdc.h itos.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h itos.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h itos.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h itos.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h itos.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h itos.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h @@ -203,84 +231,101 @@ itos.o: ${topdir}/pathnames.h ${topdir}/externs.h makepath.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h makepath.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h makepath.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h makepath.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h makepath.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h makepath.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h makepath.o: ${topdir}/pathnames.h ${topdir}/externs.h -netopen.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +netopen.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h +netopen.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +netopen.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +netopen.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +netopen.o: ${topdir}/pathnames.h ${topdir}/externs.h oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h oslib.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h oslib.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h oslib.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h oslib.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h oslib.o: ${topdir}/pathnames.h ${topdir}/externs.h oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h -oslib.o: ${BASHINCDIR}/ansi_stdlib.h +oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h pathcanon.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h pathcanon.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h pathcanon.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h pathcanon.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h pathcanon.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h pathcanon.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h pathcanon.o: ${topdir}/pathnames.h ${topdir}/externs.h pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h -pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h +pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h pathphys.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h pathphys.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h pathphys.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h pathphys.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h pathphys.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h pathphys.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h pathphys.o: ${topdir}/pathnames.h ${topdir}/externs.h pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h -pathphys.o: ${BASHINCDIR}/ansi_stdlib.h +pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h +setlinebuf.o: ${topdir}/xmalloc.h ${topdir}/bashansi.h +setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h + +shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h +shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h + shtty.o: ${BASHINCDIR}/shtty.h shtty.o: ${BASHINCDIR}/stdc.h +snprintf.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h ${topdir}/xmalloc.h +snprintf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +snprintf.o: ${BASHINCDIR}/typemax.h + spell.o: ${topdir}/bashtypes.h spell.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/posixdir.h spell.o: ${BASHINCDIR}/ansi_stdlib.h strcasecmp.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h -strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h +strcasecmp.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h strerror.o: ${topdir}/bashtypes.h strerror.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h strerror.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h strerror.o: ${topdir}/pathnames.h ${topdir}/externs.h strindex.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h -strindex.o: ${BASHINCDIR}/ansi_stdlib.h +strindex.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h stringlist.o: ${topdir}/bashansi.h stringlist.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h stringlist.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h stringlist.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h stringlist.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h stringlist.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h stringlist.o: ${topdir}/pathnames.h ${topdir}/externs.h -stringvec.o: ${topdir}/bashansi.h +stringvec.o: ${topdir}/bashansi.h ${BASHINCDIR}/chartypes.h stringvec.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h stringvec.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h stringvec.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h @@ -289,19 +334,33 @@ stringvec.o: ${topdir}/pathnames.h ${topdir}/externs.h strpbrk.o: ${BASHINCDIR}/stdc.h strtod.o: ${topdir}/bashansi.h -strtod.o: ${BASHINCDIR}/ansi_stdlib.h +strtod.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h + +strtoimax.o: ${BASHINCDIR}/stdc.h strtol.o: ${topdir}/bashansi.h -strtol.o: ${BASHINCDIR}/ansi_stdlib.h +strtol.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtol.o: ${BASHINCDIR}/typemax.h + +strtoll.o: ${topdir}/bashansi.h +strtoll.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoll.o: ${BASHINCDIR}/typemax.h strtoul.o: ${topdir}/bashansi.h -strtoul.o: ${BASHINCDIR}/ansi_stdlib.h +strtoul.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoul.o: ${BASHINCDIR}/typemax.h + +strtoull.o: ${topdir}/bashansi.h +strtoull.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h +strtoull.o: ${BASHINCDIR}/typemax.h + +strtoumax.o: ${BASHINCDIR}/stdc.h strtrans.o: ${topdir}/bashansi.h -strtrans.o: ${BASHINCDIR}/ansi_stdlib.h +strtrans.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h strtrans.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h strtrans.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h -strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h +strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h @@ -317,3 +376,22 @@ tmpfile.o: ${BASHINCDIR}/posixstat.h tmpfile.o: ${BASHINCDIR}/filecntl.h clock.o: ${BASHINCDIR}/posixtime.h + +mailstat.o: ${topdir}/bashansi.h +mailstat.o: ${topdir}/bashtypes.h +mailstat.o: ${BASHINCDIR}/ansi_stdlib.h +mailstat.o: ${BASHINCDIR}/posixstat.h +mailstat.o: ${BASHINCDIR}/posixdir.h +mailstat.o: ${BASHINCDIR}/maxpath.h + +fmtulong.o: ${topdir}/bashansi.h +fmtulong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtulong.o: ${BASHINCDIR}/chartypes.h +fmtulong.o: ${BASHINCDIR}/stdc.h +fmtulong.o: ${BASHINCDIR}/typemax.h + +fmtullong.o: ${topdir}/bashansi.h +fmtullong.o: ${BASHINCDIR}/ansi_stdlib.h +fmtullong.o: ${BASHINCDIR}/chartypes.h +fmtullong.o: ${BASHINCDIR}/stdc.h +fmtullong.o: ${BASHINCDIR}/typemax.h diff --git a/lib/sh/clock.c b/lib/sh/clock.c index 9a91e38..1186a19 100644 --- a/lib/sh/clock.c +++ b/lib/sh/clock.c @@ -30,11 +30,14 @@ #endif #include <stdio.h> +#include <stdc.h> + +extern long get_clk_tck __P((void)); void clock_t_to_secs (t, sp, sfp) clock_t t; - long *sp; + time_t *sp; int *sfp; { static long clk_tck = -1; @@ -64,15 +67,15 @@ print_clock_t (fp, t) FILE *fp; clock_t t; { - int minutes, seconds_fraction; - long seconds; + time_t timestamp; + long minutes; + int seconds, seconds_fraction; - clock_t_to_secs (t, &seconds, &seconds_fraction); + clock_t_to_secs (t, ×tamp, &seconds_fraction); - minutes = seconds / 60; - seconds %= 60; + minutes = timestamp / 60; + seconds = timestamp % 60; - fprintf (fp, "%0dm%0ld.%03ds", minutes, seconds, seconds_fraction); + fprintf (fp, "%ldm%d.%03ds", minutes, seconds, seconds_fraction); } #endif /* HAVE_TIMES */ - diff --git a/lib/sh/fmtullong.c b/lib/sh/fmtullong.c new file mode 100644 index 0000000..8139a7e --- /dev/null +++ b/lib/sh/fmtullong.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2001 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, 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; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <config.h> + +#ifdef HAVE_LONG_LONG + +#define QUAD 1 +#include "fmtulong.c" + +#endif diff --git a/lib/sh/fmtulong.c b/lib/sh/fmtulong.c new file mode 100644 index 0000000..15e73ef --- /dev/null +++ b/lib/sh/fmtulong.c @@ -0,0 +1,196 @@ +/* fmtulong.c -- Convert unsigned long int to string. */ + +/* Copyright (C) 1998, Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + Bash 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 Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#if defined (HAVE_LIMITS_H) +# include <limits.h> +#endif + +#include <bashansi.h> +#ifdef HAVE_STDDEF_H +# include <stddef.h> +#endif + +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <chartypes.h> +#include <errno.h> + +#include "stdc.h" + +#include <typemax.h> + +#ifndef errno +extern int errno; +#endif + +#define x_digs "0123456789abcdef" +#define X_digs "0123456789ABCDEF" + +/* XXX -- assumes uppercase letters, lowercase letters, and digits are + contiguous */ +#define FMTCHAR(x) \ + ((x) < 10) ? (x) + '0' \ + : (((x) < 36) ? (x) - 10 + 'a' \ + : (((x) < 62) ? (x) - 36 + 'A' \ + : (((x) == 62) ? '@' : '_'))) + +#ifndef FL_PREFIX +# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +# define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +# define FL_UNSIGNED 0x08 /* don't add any sign */ +#endif + +#ifdef QUAD + /* fmtullong */ +# define LONG long long +# define FMTUL_LONG_MAX LLONG_MAX +# define FMTUL_ULONG_MAX ULLONG_MAX +#else +# define LONG long +# define FMTUL_LONG_MAX LONG_MAX +# define FMTUL_ULONG_MAX ULONG_MAX +#endif + +/* Set the name */ +#ifdef QUAD +# define fmtulong fmtullong +#endif + +/* `unsigned long' (or unsigned long long) to string conversion for a given + base. The caller passes the output buffer and the size. This should + check for buffer underflow, but currently does not. */ +char * +fmtulong (ui, base, buf, len, flags) + unsigned LONG ui; + int base; + char *buf; + size_t len; + int flags; +{ + char *p; + int sign; + LONG si; + + if (base == 0) + base = 10; + + if (base < 2 || base > 64) + { +#if 1 + strncpy (buf, "invalid base", len - 1); + buf[len] = '\0'; + errno = EINVAL; + return (p = buf); +#else + base = 10; +#endif + } + + sign = 0; + if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0) + { + ui = -ui; + sign = '-'; + } + + p = buf + len - 2; + p[1] = '\0'; + + /* handle common cases explicitly */ + switch (base) + { + case 10: + if (ui < 10) + { + *p-- = TOCHAR (ui); + break; + } + /* Favor signed arithmetic over unsigned arithmetic; it is faster on + many machines. */ + if (ui > FMTUL_LONG_MAX) + { + *p-- = TOCHAR (ui % 10); + si = ui / 10; + } + else + si = ui; + do + *p-- = TOCHAR (si % 10); + while (si /= 10); + break; + + case 8: + do + *p-- = TOCHAR (ui & 7); + while (ui >>= 3); + break; + + case 16: + do + *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15]; + while (ui >>= 4); + break; + + case 2: + do + *p-- = TOCHAR (ui & 1); + while (ui >>= 1); + break; + + default: + do + *p-- = FMTCHAR (ui % base); + while (ui /= base); + break; + } + + if ((flags & FL_PREFIX) && (base == 8 || base == 16)) + { + if (base == 16) + { + *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x'; + *p-- = '0'; + } + else if (p[1] != '0') + *p-- = '0'; + } + else if ((flags & FL_ADDBASE) && base != 10) + { + *p-- = '#'; + *p-- = TOCHAR (base % 10); + if (base > 10) + *p-- = TOCHAR (base / 10); + } + + if (sign) + *p-- = '-'; + + return (p + 1); +} diff --git a/lib/sh/getcwd.c b/lib/sh/getcwd.c index d39655d..0c8b1da 100644 --- a/lib/sh/getcwd.c +++ b/lib/sh/getcwd.c @@ -40,26 +40,12 @@ #include <bashansi.h> +#include <xmalloc.h> + #if !defined (errno) extern int errno; #endif /* !errno */ -#if defined (__STDC__) -# define CONST const -# define PTR void * -#else /* !__STDC__ */ -# define CONST -# define PTR char * -#endif /* !__STDC__ */ - -#if !defined (PATH_MAX) -# if defined (MAXPATHLEN) -# define PATH_MAX MAXPATHLEN -# else /* !MAXPATHLEN */ -# define PATH_MAX 1024 -# endif /* !MAXPATHLEN */ -#endif /* !PATH_MAX */ - #if !defined (HAVE_LSTAT) # define lstat stat #endif @@ -85,11 +71,11 @@ getcwd (buf, size) size_t size; #endif /* !__STDC__ */ { - static CONST char dots[] + static const char dots[] = "../../../../../../../../../../../../../../../../../../../../../../../\ ../../../../../../../../../../../../../../../../../../../../../../../../../../\ ../../../../../../../../../../../../../../../../../../../../../../../../../.."; - CONST char *dotp, *dotlist; + const char *dotp, *dotlist; size_t dotsize; dev_t rootdev, thisdev; ino_t rootino, thisino; @@ -149,7 +135,7 @@ getcwd (buf, size) } else { - new = (char *)realloc ((PTR) dotlist, dotsize * 2 + 1); + new = (char *)realloc ((PTR_T) dotlist, dotsize * 2 + 1); if (new == NULL) goto lose; } @@ -232,7 +218,7 @@ getcwd (buf, size) } else { - new = (char *)realloc ((PTR) pathbuf, (pathsize * 2)); + new = (char *)realloc ((PTR_T) pathbuf, (pathsize * 2)); if (!new) goto lose; pathp = new + space; @@ -257,7 +243,7 @@ getcwd (buf, size) *--pathp = '/'; if (dotlist != dots) - free ((PTR) dotlist); + free ((PTR_T) dotlist); { size_t len = pathbuf + pathsize - pathp; @@ -274,7 +260,7 @@ getcwd (buf, size) errno = ERANGE; goto lose2; } - (void) memcpy((PTR) buf, (PTR) pathp, len); + (void) memcpy((PTR_T) buf, (PTR_T) pathp, len); } if (pathbuf != path) @@ -286,7 +272,7 @@ getcwd (buf, size) if ((dotlist != dots) && dotlist) { int e = errno; - free ((PTR) dotlist); + free ((PTR_T) dotlist); errno = e; } @@ -294,7 +280,7 @@ getcwd (buf, size) if ((pathbuf != path) && pathbuf) { int e = errno; - free ((PTR) pathbuf); + free ((PTR_T) pathbuf); errno = e; } return ((char *)NULL); diff --git a/lib/sh/inet_aton.c b/lib/sh/inet_aton.c index 28cd979..2835d62 100644 --- a/lib/sh/inet_aton.c +++ b/lib/sh/inet_aton.c @@ -115,7 +115,7 @@ inet_aton(cp, addr) { register u_bits32_t val; register int base, n; - register char c; + register unsigned char c; u_int parts[4]; register u_int *pp = parts; @@ -126,7 +126,12 @@ inet_aton(cp, addr) * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ +#if 0 if (!isdigit(c)) +#else + if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && + c != '5' && c != '6' && c != '7' && c != '8' && c != '9') +#endif return (0); val = 0; base = 10; if (c == '0') { diff --git a/lib/sh/itos.c b/lib/sh/itos.c index dee7883..e836536 100644 --- a/lib/sh/itos.c +++ b/lib/sh/itos.c @@ -18,61 +18,56 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include <config.h> +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif -#include "bashansi.h" +#include <bashansi.h> +#include <chartypes.h> #include "shell.h" -/* Number of characters that can appear in a string representation - of an integer. 32 is larger than the string rep of 2^^31 - 1. */ -#define MAX_INT_LEN 32 - -/* Integer to string conversion. The caller passes the buffer and - the size. This should check for buffer underflow, but currently - does not. */ char * inttostr (i, buf, len) - int i; + long i; char *buf; - int len; + size_t len; { - char *p; - int negative = 0; - unsigned int ui; - - if (i < 0) - { - negative++; - i = -i; - } - - ui = (unsigned int) i; - - p = buf + len - 2; - p[1] = '\0'; + return (fmtulong (i, 10, buf, len, 0)); +} - do - *p-- = (ui % 10) + '0'; - while (ui /= 10); +/* Integer to string conversion. This conses the string; the + caller should free it. */ +char * +itos (i) + long i; +{ + char *p, lbuf[INT_STRLEN_BOUND(long) + 1]; - if (negative) - *p-- = '-'; + p = fmtulong (i, 10, lbuf, sizeof(lbuf), 0); + return (savestring (p)); +} - return (p + 1); +char * +uinttostr (i, buf, len) + unsigned long i; + char *buf; + size_t len; +{ + return (fmtulong (i, 10, buf, len, FL_UNSIGNED)); } /* Integer to string conversion. This conses the string; the caller should free it. */ char * -itos (i) - int i; +uitos (i) + unsigned long i; { - char *p, lbuf[MAX_INT_LEN]; + char *p, lbuf[INT_STRLEN_BOUND(long) + 1]; - p = inttostr (i, lbuf, sizeof(lbuf)); + p = fmtulong (i, 10, lbuf, sizeof(lbuf), FL_UNSIGNED); return (savestring (p)); } diff --git a/lib/sh/mailstat.c b/lib/sh/mailstat.c new file mode 100644 index 0000000..8005252 --- /dev/null +++ b/lib/sh/mailstat.c @@ -0,0 +1,159 @@ +/* mailstat.c -- stat a mailbox file, handling maildir-type mail directories */ + +/* Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + Bash 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 Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#include <config.h> + +#include <stdio.h> +#include <errno.h> + +#include <bashtypes.h> +#include <posixstat.h> +#include <posixdir.h> +#include <bashansi.h> + +#ifndef _MINIX +# include <sys/param.h> +#endif + +#include <maxpath.h> + +/* + * Stat a file. If it's a maildir, check all messages + * in the maildir and present the grand total as a file. + * The fields in the 'struct stat' are from the mail directory. + * The following fields are emulated: + * + * st_nlink always 1, unless st_blocks is not present, in which case it's + * the total number of messages + * st_size total number of bytes in all files + * st_blocks total number of messages, if present in struct stat + * st_atime access time of newest file in maildir + * st_mtime modify time of newest file in maildir + * st_mode S_IFDIR changed to S_IFREG + * + * This is good enough for most mail-checking applications. + */ + +int +mailstat(path, st) + const char *path; + struct stat *st; +{ + static struct stat st_new_last, st_ret_last; + struct stat st_ret, st_tmp; + DIR *dd; + struct dirent *fn; + char dir[PATH_MAX * 2], file[PATH_MAX * 2]; + int i, l; + time_t atime, mtime; + + atime = mtime = 0; + + /* First see if it's a directory. */ + if ((i = stat(path, st)) != 0 || S_ISDIR(st->st_mode) == 0) + return i; + + if (strlen(path) > sizeof(dir) - 5) + { +#ifdef ENAMETOOLONG + errno = ENAMETOOLONG; +#else + errno = EINVAL; +#endif + return -1; + } + + st_ret = *st; + st_ret.st_nlink = 1; + st_ret.st_size = 0; +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + st_ret.st_blocks = 0; +#else + st_ret.st_nlink = 0; +#endif + st_ret.st_mode &= ~S_IFDIR; + st_ret.st_mode |= S_IFREG; + + /* See if cur/ is present */ + sprintf(dir, "%s/cur", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_atime = st_tmp.st_atime; + + /* See if tmp/ is present */ + sprintf(dir, "%s/tmp", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_mtime = st_tmp.st_mtime; + + /* And new/ */ + sprintf(dir, "%s/new", path); + if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) + return 0; + st_ret.st_mtime = st_tmp.st_mtime; + + /* Optimization - if new/ didn't change, nothing else did. */ + if (st_tmp.st_dev == st_new_last.st_dev && + st_tmp.st_ino == st_new_last.st_ino && + st_tmp.st_atime == st_new_last.st_atime && + st_tmp.st_mtime == st_new_last.st_mtime) + { + *st = st_ret_last; + return 0; + } + st_new_last = st_tmp; + + /* Loop over new/ and cur/ */ + for (i = 0; i < 2; i++) + { + sprintf(dir, "%s/%s", path, i ? "cur" : "new"); + sprintf(file, "%s/", dir); + l = strlen(file); + if ((dd = opendir(dir)) == NULL) + return 0; + while ((fn = readdir(dd)) != NULL) + { + if (fn->d_name[0] == '.' || strlen(fn->d_name) + l >= sizeof(file)) + continue; + strcpy(file + l, fn->d_name); + if (stat(file, &st_tmp) != 0) + continue; + st_ret.st_size += st_tmp.st_size; +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + st_ret.st_blocks++; +#else + st_ret.st_nlink++; +#endif + if (st_tmp.st_atime != st_tmp.st_mtime && st_tmp.st_atime > atime) + atime = st_tmp.st_atime; + if (st_tmp.st_mtime > mtime) + mtime = st_tmp.st_mtime; + } + closedir(dd); + } + + if (atime) + st_ret.st_atime = atime; + if (mtime) + st_ret.st_mtime = mtime; + + *st = st_ret_last = st_ret; + return 0; +} diff --git a/lib/sh/makepath.c b/lib/sh/makepath.c index ba2bcb9..13aad3f 100644 --- a/lib/sh/makepath.c +++ b/lib/sh/makepath.c @@ -27,7 +27,7 @@ # include <unistd.h> #endif -#include "bashansi.h" +#include <bashansi.h> #include "shell.h" #include <tilde/tilde.h> @@ -56,7 +56,7 @@ extern char *get_working_directory __P((char *)); #define MAKEDOT() \ do { \ - xpath = xmalloc (2); \ + xpath = (char *)xmalloc (2); \ xpath[0] = '.'; \ xpath[1] = '\0'; \ pathlen = 1; \ @@ -64,11 +64,11 @@ extern char *get_working_directory __P((char *)); char * sh_makepath (path, dir, flags) - char *path, *dir; + const char *path, *dir; int flags; { int dirlen, pathlen; - char *ret, *xpath, *r, *s; + char *ret, *xpath, *xdir, *r, *s; if (path == 0 || *path == '\0') { @@ -91,24 +91,25 @@ sh_makepath (path, dir, flags) } else { - xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path) : path; + xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path) : (char *)path; pathlen = strlen (xpath); } - dirlen = strlen (dir); + xdir = (char *)dir; + dirlen = strlen (xdir); if ((flags & MP_RMDOT) && dir[0] == '.' && dir[1] == '/') { - dir += 2; + xdir += 2; dirlen -= 2; } - r = ret = xmalloc (2 + dirlen + pathlen); + r = ret = (char *)xmalloc (2 + dirlen + pathlen); s = xpath; while (*s) *r++ = *s++; if (s[-1] != '/') *r++ = '/'; - s = dir; + s = xdir; while (*r++ = *s++) ; if (xpath != path) diff --git a/lib/sh/netopen.c b/lib/sh/netopen.c index f0b0b9b..76a389b 100644 --- a/lib/sh/netopen.c +++ b/lib/sh/netopen.c @@ -27,6 +27,10 @@ #if defined (HAVE_NETWORK) +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + #include <stdio.h> #include <sys/types.h> @@ -47,19 +51,20 @@ #endif #include <bashansi.h> -#include <ctype.h> #include <errno.h> +#include <shell.h> +#include <xmalloc.h> + #ifndef errno extern int errno; #endif #if !defined (HAVE_INET_ATON) -extern int inet_aton (); +extern int inet_aton __P((const char *, struct in_addr *)); #endif -extern char *xmalloc (); - +#ifndef HAVE_GETADDRINFO /* Stuff the internet address corresponding to HOST into AP, in network byte order. Return 1 on success, 0 on failure. */ @@ -72,7 +77,7 @@ _getaddr (host, ap) int r; r = 0; - if (isdigit (host[0])) + if (host[0] >= '0' && host[0] <= '9') { /* If the first character is a digit, guess that it's an Internet address and return immediately if inet_aton succeeds. */ @@ -107,9 +112,9 @@ _getserv (serv, proto, pp) if (legal_number (serv, &l)) { - if (l > 65535) - return 0; s = (unsigned short)(l & 0xFFFF); + if (s != l) + return (0); s = htons (s); if (pp) *pp = s; @@ -132,8 +137,12 @@ _getserv (serv, proto, pp) #endif /* !HAVE_GETSERVBYNAME */ } +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses the + * traditional BSD mechanisms. Returns the connected socket or -1 on error. + */ static int -_netopen(host, serv, typ) +_netopen4(host, serv, typ) char *host, *serv; int typ; { @@ -141,7 +150,6 @@ _netopen(host, serv, typ) struct sockaddr_in sin; unsigned short p; int s, e; - char **cp; if (_getaddr(host, &ina) == 0) { @@ -180,6 +188,90 @@ _netopen(host, serv, typ) return(s); } +#endif /* ! HAVE_GETADDRINFO */ + +#ifdef HAVE_GETADDRINFO +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) + * which provides support for IPv6. Returns the connected socket or -1 + * on error. + */ +static int +_netopen6 (host, serv, typ) + char *host, *serv; + int typ; +{ + int s, e; + struct addrinfo hints, *res, *res0; + int gerr; + + bzero ((char *)&hints, sizeof (hints)); + /* XXX -- if problems with IPv6, set to PF_INET for IPv4 only */ +#ifdef DEBUG /* PF_INET is the one that works for me */ + hints.ai_family = PF_INET; +#else + hints.ai_family = PF_UNSPEC; +#endif + hints.ai_socktype = (typ == 't') ? SOCK_STREAM : SOCK_DGRAM; + + gerr = getaddrinfo (host, serv, &hints, &res0); + if (gerr) + { + if (gerr == EAI_SERVICE) + internal_error ("%s: %s", serv, gai_strerror (gerr)); + else + internal_error ("%s: %s", host, gai_strerror (gerr)); + errno = EINVAL; + return -1; + } + + for (res = res0; res; res = res->ai_next) + { + if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) + { + if (res->ai_next) + continue; + sys_error ("socket"); + freeaddrinfo (res0); + return -1; + } + if (connect (s, res->ai_addr, res->ai_addrlen) < 0) + { + if (res->ai_next) + { + close (s); + continue; + } + e = errno; + sys_error ("connect"); + close (s); + freeaddrinfo (res0); + errno = e; + return -1; + } + freeaddrinfo (res0); + break; + } + return s; +} +#endif /* HAVE_GETADDRINFO */ + +/* + * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) + * if available, falling back to the traditional BSD mechanisms otherwise. + * Returns the connected socket or -1 on error. + */ +static int +_netopen(host, serv, typ) + char *host, *serv; + int typ; +{ +#ifdef HAVE_GETADDRINFO + return (_netopen6 (host, serv, typ)); +#else + return (_netopen4 (host, serv, typ)); +#endif +} /* * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to @@ -192,7 +284,7 @@ netopen (path) char *np, *s, *t; int fd; - np = xmalloc (strlen (path) + 1); + np = (char *)xmalloc (strlen (path) + 1); strcpy (np, path); s = np + 9; diff --git a/lib/sh/oslib.c b/lib/sh/oslib.c index 3d58711..69a3513 100644 --- a/lib/sh/oslib.c +++ b/lib/sh/oslib.c @@ -35,7 +35,7 @@ #include <stdio.h> #include <errno.h> -#include <ctype.h> +#include <chartypes.h> #include <shell.h> diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c index 41fc727..dcde8b0 100644 --- a/lib/sh/pathcanon.c +++ b/lib/sh/pathcanon.c @@ -18,26 +18,25 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "config.h" +#include <config.h> -#include "bashtypes.h" +#include <bashtypes.h> #ifndef _MINIX # include <sys/param.h> #endif -#include "posixstat.h" +#include <posixstat.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif -#include "filecntl.h" -#include "bashansi.h" +#include <filecntl.h> +#include <bashansi.h> #include <stdio.h> +#include <chartypes.h> #include "shell.h" -#include "maxpath.h" - /* Return 1 if PATH corresponds to a directory. A function for debugging. */ static int _path_isdir (path) @@ -80,7 +79,7 @@ sh_canonpath (path, flags) { stub_char = DIRSEP; #if defined (__CYGWIN__) - base = (isalpha(result[0]) && result[1] == ':') ? result + 3 : result + 1; + base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 3 : result + 1; #else base = result + 1; #endif @@ -91,10 +90,11 @@ sh_canonpath (path, flags) { stub_char = '.'; #if defined (__CYGWIN__) - base = (isalpha(result[0]) && result[1] == ':') ? result + 2 : result; + base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 2 : result; #else base = result; #endif + double_slash_path = 0; } /* diff --git a/lib/sh/pathphys.c b/lib/sh/pathphys.c index eb58524..df69204 100644 --- a/lib/sh/pathphys.c +++ b/lib/sh/pathphys.c @@ -18,27 +18,26 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "config.h" +#include <config.h> -#include "bashtypes.h" +#include <bashtypes.h> #ifndef _MINIX # include <sys/param.h> #endif -#include "posixstat.h" +#include <posixstat.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif -#include "filecntl.h" -#include "bashansi.h" +#include <filecntl.h> +#include <bashansi.h> #include <stdio.h> +#include <chartypes.h> #include <errno.h> #include "shell.h" -#include "maxpath.h" - #if !defined (MAXSYMLINKS) # define MAXSYMLINKS 32 #endif @@ -82,9 +81,9 @@ sh_physpath (path, flags) int double_slash_path, linklen, nlink; nlink = 0; - q = result = xmalloc (PATH_MAX + 1); + q = result = (char *)xmalloc (PATH_MAX + 1); - workpath = xmalloc (PATH_MAX + 1); + workpath = (char *)xmalloc (PATH_MAX + 1); strcpy (workpath, path); /* This always gets an absolute pathname. */ @@ -92,7 +91,7 @@ sh_physpath (path, flags) /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any leading `x:' (dos drive name). */ #if defined (__CYGWIN__) - qbase = (isalpha(workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; + qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; #else qbase = workpath + 1; #endif @@ -176,7 +175,7 @@ error: q = result; /* Duplicating some code here... */ #if defined (__CYGWIN__) - qbase = (isalpha(workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; + qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; #else qbase = workpath + 1; #endif diff --git a/lib/sh/setlinebuf.c b/lib/sh/setlinebuf.c index fb097de..3c5d056 100644 --- a/lib/sh/setlinebuf.c +++ b/lib/sh/setlinebuf.c @@ -22,7 +22,7 @@ #include <stdio.h> -extern char *xmalloc(); +#include <xmalloc.h> #if defined (USING_BASH_MALLOC) # define LBUF_BUFSIZE 1008 @@ -42,7 +42,7 @@ sh_setlinebuf (stream) #endif #if defined (USING_BASH_MALLOC) - local_linebuf = xmalloc (LBUF_BUFSIZE); + local_linebuf = (char *)xmalloc (LBUF_BUFSIZE); #else local_linebuf = (char *)NULL; #endif @@ -56,7 +56,7 @@ sh_setlinebuf (stream) # endif /* !SETVBUF_REVERSED */ # else /* !HAVE_SETVBUF */ - setlinebuf (stream)); + setlinebuf (stream); return (0); #endif /* !HAVE_SETVBUF */ diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c index 981e967..4160e70 100644 --- a/lib/sh/shquote.c +++ b/lib/sh/shquote.c @@ -28,8 +28,7 @@ #include <stdio.h> #include "syntax.h" - -extern char *xmalloc (); +#include <xmalloc.h> /* **************************************************************** */ /* */ @@ -46,7 +45,7 @@ sh_single_quote (string) register int c; char *result, *r, *s; - result = xmalloc (3 + (4 * strlen (string))); + result = (char *)xmalloc (3 + (4 * strlen (string))); r = result; *r++ = '\''; @@ -73,10 +72,10 @@ char * sh_double_quote (string) char *string; { - register int c; + register unsigned char c; char *result, *r, *s; - result = xmalloc (3 + (2 * strlen (string))); + result = (char *)xmalloc (3 + (2 * strlen (string))); r = result; *r++ = '"'; @@ -103,7 +102,7 @@ sh_un_double_quote (string) register int c, pass_next; char *result, *r, *s; - r = result = xmalloc (strlen (string) + 1); + r = result = (char *)xmalloc (strlen (string) + 1); for (pass_next = 0, s = string; s && (c = *s); s++) { @@ -113,7 +112,7 @@ sh_un_double_quote (string) pass_next = 0; continue; } - if (c == '\\' && (sh_syntaxtab[s[1]] & CBSDQUOTE)) + if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE)) { pass_next = 1; continue; @@ -134,7 +133,7 @@ sh_backslash_quote (string) int c; char *result, *r, *s; - result = xmalloc (2 * strlen (string) + 1); + result = (char *)xmalloc (2 * strlen (string) + 1); for (r = result, s = string; s && (c = *s); s++) { @@ -179,10 +178,10 @@ char * sh_backslash_quote_for_double_quotes (string) char *string; { - int c; + unsigned char c; char *result, *r, *s; - result = xmalloc (2 * strlen (string) + 1); + result = (char *)xmalloc (2 * strlen (string) + 1); for (r = result, s = string; s && (c = *s); s++) { @@ -219,6 +218,7 @@ sh_contains_shell_metas (string) case '~': /* tilde expansion */ if (s == string || s[-1] == '=' || s[-1] == ':') return (1); + break; case '#': if (s == string) /* comment char */ return (1); diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c new file mode 100644 index 0000000..f84d60c --- /dev/null +++ b/lib/sh/snprintf.c @@ -0,0 +1,1665 @@ +/* + build a test version with + gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o +*/ + +/* + Unix snprintf implementation. + derived from inetutils/libinetutils/snprintf.c Version 1.1 + + Copyright (C) 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General 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 License for more details. + + You should have received a copy of the GNU General License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Revision History: + + 1.1: + * added changes from Miles Bader + * corrected a bug with %f + * added support for %#g + * added more comments :-) + 1.0: + * supporting must ANSI syntaxic_sugars + 0.0: + * support %s %c %d + + THANKS(for the patches and ideas): + Miles Bader + Cyrille Rustom + Jacek Slabocewiz + Mike Parker(mouse) + +*/ + +/* + * Currently doesn't handle (and bash/readline doesn't use): + * *M$ width, precision specifications + * %N$ numbered argument conversions + * inf, nan floating values (could use isinf(), isnan()) + * `,', `'' flags + * `C', `S' conversions + * support for `F' is imperfect, since underlying printf may not handle it + */ + +#define FLOATING_POINT + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if defined(DRIVER) && !defined(HAVE_CONFIG_H) +#define HAVE_LONG_LONG +#define HAVE_LONG_DOUBLE +#ifdef __linux__ +#define HAVE_PRINTF_A_FORMAT +#endif +#define PREFER_STDARG +#define HAVE_STRINGIZE +#define HAVE_LIMITS_H +#define HAVE_STDDEF_H +#define intmax_t long +#endif + +#if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF) + +#include <bashtypes.h> + +#if defined(PREFER_STDARG) +# include <stdarg.h> +#else +# include <varargs.h> +#endif + +#ifdef HAVE_LIMITS_H +# include <limits.h> +#endif +#include <bashansi.h> +#ifdef HAVE_STDDEF_H +# include <stddef.h> +#endif +#include <chartypes.h> + +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif + +#ifdef FLOATING_POINT +# include <stdio.h> /* for sprintf */ +#endif + +#include <typemax.h> + +#include "stdc.h" + +#ifndef DRIVER +# include "shell.h" +#else +# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ +# define FL_ADDBASE 0x02 /* add base# prefix to converted value */ +# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ +# define FL_UNSIGNED 0x08 /* don't add any sign */ +extern char *fmtulong __P((unsigned long int, int, char *, size_t, int)); +extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int)); +#endif + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* conversion flags */ +#define PF_ALTFORM 0x00001 /* # */ +#define PF_HEXPREFIX 0x00002 /* 0[Xx] */ +#define PF_LADJUST 0x00004 /* - */ +#define PF_ZEROPAD 0x00008 /* 0 */ +#define PF_PLUS 0x00010 /* + */ +#define PF_SPACE 0x00020 /* ' ' */ +#define PF_COMMA 0x00040 /* , */ + +#define PF_DOT 0x00080 /* `.precision' */ +#define PF_STAR_P 0x00100 /* `*' after precision */ +#define PF_STAR_W 0x00200 /* `*' before or without precision */ + +/* length modifiers */ +#define PF_SIGNEDCHAR 0x00400 /* hh */ +#define PF_SHORTINT 0x00800 /* h */ +#define PF_LONGINT 0x01000 /* l */ +#define PF_LONGLONG 0x02000 /* ll */ +#define PF_LONGDBL 0x04000 /* L */ +#define PF_INTMAX_T 0x08000 /* j */ +#define PF_SIZE_T 0x10000 /* z */ +#define PF_PTRDIFF_T 0x20000 /* t */ + +#define PF_ALLOCBUF 0x40000 /* for asprintf, vasprintf */ + +#define PFM_SN 0x01 /* snprintf, vsnprintf */ +#define PFM_AS 0x02 /* asprintf, vasprintf */ + +#define ASBUFSIZE 128 + +#define x_digs "0123456789abcdef" +#define X_digs "0123456789ABCDEF" + +static char intbuf[INT_STRLEN_BOUND(unsigned long) + 1]; + +/* + * For the FLOATING POINT FORMAT : + * the challenge was finding a way to + * manipulate the Real numbers without having + * to resort to mathematical function(it + * would require to link with -lm) and not + * going down to the bit pattern(not portable) + * + * so a number, a real is: + + real = integral + fraction + + integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0 + fraction = b(1)*10^-1 + b(2)*10^-2 + ... + + where: + 0 <= a(i) => 9 + 0 <= b(i) => 9 + + from then it was simple math + */ + +/* + * size of the buffer for the integral part + * and the fraction part + */ +#define MAX_INT 99 + 1 /* 1 for the null */ +#define MAX_FRACT 307 + 1 + +/* + * These functions use static buffers to store the results, + * and so are not reentrant + */ +#define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0); +#define dtoa(n, p, f) numtoa(n, 10, p, f) + +#define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;} + +/* Macros that do proper sign extension and handle length modifiers. Used + for the integer conversion specifiers. */ +#define GETSIGNED(p) \ + (((p)->flags & PF_LONGINT) \ + ? va_arg(args, long) \ + : (((p)->flags & PF_SHORTINT) ? (long)(short)va_arg(args, int) \ + : (long)va_arg(args, int))) + +#define GETUNSIGNED(p) \ + (((p)->flags & PF_LONGINT) \ + ? va_arg(args, unsigned long) \ + : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)va_arg(args, int) \ + : (unsigned long)va_arg(args, unsigned int))) + + +#ifdef HAVE_LONG_DOUBLE +#define GETLDOUBLE(p) va_arg(args, long double) +#endif +#define GETDOUBLE(p) va_arg(args, double) + +#define SET_SIZE_FLAGS(p, type) \ + if (sizeof (type) > sizeof (int)) \ + (p)->flags |= PF_LONGINT; \ + if (sizeof (type) > sizeof (long)) \ + (p)->flags |= PF_LONGLONG; + +/* this struct holds everything we need */ +struct DATA +{ + int length; + char *base; /* needed for [v]asprintf */ + char *holder; + int counter; + const char *pf; + +/* FLAGS */ + int flags; + int justify; + int width, precision; + char pad; +}; + +/* the floating point stuff */ +#ifdef FLOATING_POINT +static double pow_10 __P((int)); +static int log_10 __P((double)); +static double integral __P((double, double *)); +static char *numtoa __P((double, int, int, char **)); +#endif + +static void init_data __P((struct DATA *, char *, size_t, const char *, int)); +static void init_conv_flag __P((struct DATA *)); + +/* for the format */ +#ifdef FLOATING_POINT +static void floating __P((struct DATA *, double)); +static void exponent __P((struct DATA *, double)); +#endif +static void number __P((struct DATA *, unsigned long, int)); +#ifdef HAVE_LONG_LONG +static void lnumber __P((struct DATA *, unsigned long long, int)); +#endif +static void pointer __P((struct DATA *, unsigned long)); +static void strings __P((struct DATA *, char *)); + +#ifdef FLOATING_POINT +# define FALLBACK_FMTSIZE 32 +# define FALLBACK_BASE 4096 +# define LFALLBACK_BASE 5120 +# ifdef HAVE_LONG_DOUBLE +static void ldfallback __P((struct DATA *, const char *, const char *, long double)); +# endif +static void dfallback __P((struct DATA *, const char *, const char *, double)); +#endif + +#ifdef DRIVER +static void memory_error_and_abort (); +static void *xmalloc __P((size_t)); +static void *xrealloc __P((void *, size_t)); +static void xfree __P((void *)); +#else +# include <xmalloc.h> +#endif + +/* those are defines specific to snprintf to hopefully + * make the code clearer :-) + */ +#define RIGHT 1 +#define LEFT 0 +#define NOT_FOUND -1 +#define FOUND 1 +#define MAX_FIELD 15 + +/* round off to the precision */ +#define ROUND(d, p) \ + (d < 0.) ? \ + d - pow_10(-(p)->precision) * 0.5 : \ + d + pow_10(-(p)->precision) * 0.5 + +/* set default precision */ +#define DEF_PREC(p) \ + if ((p)->precision == NOT_FOUND) \ + (p)->precision = 6 + +/* put a char. increment the number of chars written even if we've exceeded + the vsnprintf/snprintf buffer size (for the return value) */ +#define PUT_CHAR(c, p) \ + do \ + { \ + if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \ + { \ + (p)->length += ASBUFSIZE; \ + (p)->base = (char *)xrealloc((p)->base, (p)->length); \ + (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \ + } \ + if ((p)->counter < (p)->length) \ + *(p)->holder++ = (c); \ + (p)->counter++; \ + } \ + while (0) + +#define PUT_PLUS(d, p, zero) \ + if ((d) > zero && (p)->justify == RIGHT) \ + PUT_CHAR('+', p) + +#define PUT_SPACE(d, p, zero) \ + if (((p)->flags & PF_SPACE) && (d) > zero) \ + PUT_CHAR(' ', p) + +/* pad right */ +#define PAD_RIGHT(p) \ + if ((p)->width > 0 && (p)->justify != LEFT) \ + for (; (p)->width > 0; (p)->width--) \ + PUT_CHAR((p)->pad, p) + +/* pad left */ +#define PAD_LEFT(p) \ + if ((p)->width > 0 && (p)->justify == LEFT) \ + for (; (p)->width > 0; (p)->width--) \ + PUT_CHAR((p)->pad, p) + +/* if width and prec. in the args */ +#define STAR_ARGS(p) \ + if ((p)->flags & PF_STAR_W) \ + (p)->width = va_arg(args, int); \ + if ((p)->flags & PF_STAR_P) \ + (p)->precision = va_arg(args, int) + +#ifdef FLOATING_POINT +/* + * Find the nth power of 10 + */ +static double +pow_10(n) + int n; +{ + double P; + + /* handle common cases with fast switch statement. */ + switch (n) + { + case -3: return .001; + case -2: return .01; + case -1: return .1; + case 0: return 1.; + case 1: return 10.; + case 2: return 100.; + case 3: return 1000.; + } + + if (n < 0) + { + P = .0001; + for (n += 4; n < 0; n++) + P /= 10.; + } + else + { + P = 10000.; + for (n -= 4; n > 0; n--) + P *= 10.; + } + + return P; +} + +/* + * Find the integral part of the log in base 10 + * Note: this not a real log10() + I just need and approximation(integerpart) of x in: + 10^x ~= r + * log_10(200) = 2; + * log_10(250) = 2; + */ +static int +log_10(r) + double r; +{ + int i = 0; + double result = 1.; + + if (r < 0.) + r = -r; + + if (r < 1.) + { + while (result >= r) + { + result /= 10.; + i++; + } + return (-i); + } + else + { + while (result <= r) + { + result *= 10.; + i++; + } + return (i - 1); + } +} + +/* + * This function return the fraction part of a double + * and set in ip the integral part. + * In many ways it resemble the modf() found on most Un*x + */ +static double +integral(real, ip) + double real; + double *ip; +{ + int j; + double i, s, p; + double real_integral = 0.; + + /* take care of the obvious */ + /* equal to zero ? */ + if (real == 0.) + { + *ip = 0.; + return (0.); + } + + /* negative number ? */ + if (real < 0.) + real = -real; + + /* a fraction ? */ + if ( real < 1.) + { + *ip = 0.; + return real; + } + + /* the real work :-) */ + for (j = log_10(real); j >= 0; j--) + { + p = pow_10(j); + s = (real - real_integral)/p; + i = 0.; + while (i + 1. <= s) + i++; + real_integral += i*p; + } + *ip = real_integral; + return (real - real_integral); +} + +#define PRECISION 1.e-6 +/* + * return an ascii representation of the integral part of the number + * and set fract to be an ascii representation of the fraction part + * the container for the fraction and the integral part or staticly + * declare with fix size + */ +static char * +numtoa(number, base, precision, fract) + double number; + int base, precision; + char **fract; +{ + register int i, j; + double ip, fp; /* integer and fraction part */ + double fraction; + int digits = MAX_INT - 1; + static char integral_part[MAX_INT]; + static char fraction_part[MAX_FRACT]; + double sign; + int ch; + + /* taking care of the obvious case: 0.0 */ + if (number == 0.) + { + integral_part[0] = '0'; + integral_part[1] = '\0'; + fraction_part[0] = '0'; + fraction_part[1] = '\0'; + return integral_part; + } + + /* for negative numbers */ + if ((sign = number) < 0.) + { + number = -number; + digits--; /* sign consume one digit */ + } + + fraction = integral(number, &ip); + number = ip; + + /* do the integral part */ + if (ip == 0.) + { + integral_part[0] = '0'; + i = 1; + } + else + { + for ( i = 0; i < digits && number != 0.; ++i) + { + number /= base; + fp = integral(number, &ip); + ch = (int)((fp + PRECISION)*base); /* force to round */ + integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10; + if (! ISXDIGIT((unsigned char)integral_part[i])) + break; /* bail out overflow !! */ + number = ip; + } + } + + /* Oh No !! out of bound, ho well fill it up ! */ + if (number != 0.) + for (i = 0; i < digits; ++i) + integral_part[i] = '9'; + + /* put the sign ? */ + if (sign < 0.) + integral_part[i++] = '-'; + + integral_part[i] = '\0'; + + /* reverse every thing */ + for ( i--, j = 0; j < i; j++, i--) + SWAP_INT(integral_part[i], integral_part[j]); + + /* the fractional part */ + for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--) + { + fraction_part[i] = (int)((fp + PRECISION)*10. + '0'); + if (! DIGIT(fraction_part[i])) /* underflow ? */ + break; + fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.); + } + fraction_part[i] = '\0'; + + if (fract != (char **)0) + *fract = fraction_part; + + return integral_part; +} +#endif + +/* for %d and friends, it puts in holder + * the representation with the right padding + */ +static void +number(p, d, base) + struct DATA *p; + unsigned long d; + int base; +{ + char *tmp; + long sd; + int flags; + + sd = d; /* signed for ' ' padding in base 10 */ + flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + + tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags); + p->width -= strlen(tmp); + PAD_RIGHT(p); + + switch (base) + { + case 10: + PUT_PLUS(sd, p, 0); + PUT_SPACE(sd, p, 0); + break; + case 8: + if (p->flags & PF_ALTFORM) + PUT_CHAR('0', p); + break; + case 16: + if (p->flags & PF_ALTFORM) + { + PUT_CHAR('0', p); + PUT_CHAR(*p->pf, p); + } + break; + } + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); +} + +#ifdef HAVE_LONG_LONG +/* + * identical to number() but works for `long long' + */ +static void +lnumber(p, d, base) + struct DATA *p; + unsigned long long d; + int base; +{ + char *tmp; + long long sd; + int flags; + + sd = d; /* signed for ' ' padding in base 10 */ + flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + + tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags); + p->width -= strlen(tmp); + PAD_RIGHT(p); + + switch (base) + { + case 10: + PUT_PLUS(sd, p, 0); + PUT_SPACE(sd, p, 0); + break; + case 8: + if (p->flags & PF_ALTFORM) + PUT_CHAR('0', p); + break; + case 16: + if (p->flags & PF_ALTFORM) + { + PUT_CHAR('0', p); + PUT_CHAR(*p->pf, p); + } + break; + } + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + + PAD_LEFT(p); +} +#endif + +static void +pointer(p, d) + struct DATA *p; + unsigned long d; +{ + char *tmp; + + tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0); + p->width -= strlen(tmp); + PAD_RIGHT(p); + + /* prefix '0x' for pointers */ + PUT_CHAR('0', p); + PUT_CHAR('x', p); + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + PAD_LEFT(p); +} + +/* %s strings */ +static void +strings(p, tmp) + struct DATA *p; + char *tmp; +{ + int i; + + i = strlen(tmp); + if (p->precision != NOT_FOUND) /* the smallest number */ + i = (i < p->precision ? i : p->precision); + p->width -= i; + PAD_RIGHT(p); + while (i-- > 0) + { /* put the sting */ + PUT_CHAR(*tmp, p); + tmp++; + } + PAD_LEFT(p); +} + +#ifdef FLOATING_POINT +/* %f %F %g %G floating point representation */ +static void +floating(p, d) + struct DATA *p; + double d; +{ + char *tmp, *tmp2; + int i; + + DEF_PREC(p); + d = ROUND(d, p); + tmp = dtoa(d, p->precision, &tmp2); + /* calculate the padding. 1 for the dot */ + p->width = p->width - + ((d > 0. && p->justify == RIGHT) ? 1:0) - + ((p->flags & PF_SPACE) ? 1:0) - + strlen(tmp) - p->precision - 1; + PAD_RIGHT(p); + PUT_PLUS(d, p, 0.); + PUT_SPACE(d, p, 0.); + while (*tmp) + { /* the integral */ + PUT_CHAR(*tmp, p); + tmp++; + } + if (p->precision != 0 || (p->flags & PF_ALTFORM)) + PUT_CHAR('.', p); /* put the '.' */ + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) + /* smash the trailing zeros unless altform */ + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) + tmp2[i] = '\0'; + for (; *tmp2; tmp2++) + PUT_CHAR(*tmp2, p); /* the fraction */ + + PAD_LEFT(p); +} + +/* %e %E %g %G exponent representation */ +static void +exponent(p, d) + struct DATA *p; + double d; +{ + char *tmp, *tmp2; + int j, i, nsig, ndig; + + DEF_PREC(p); + j = log_10(d); + d = d / pow_10(j); /* get the Mantissa */ + d = ROUND(d, p); + tmp = dtoa(d, p->precision, &tmp2); + /* 1 for unit, 1 for the '.', 1 for 'e|E', + * 1 for '+|-', 2 for 'exp' */ + /* calculate how much padding need */ + p->width = p->width - + ((d > 0. && p->justify == RIGHT) ? 1:0) - + ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6; + PAD_RIGHT(p); + PUT_PLUS(d, p, 0.); + PUT_SPACE(d, p, 0.); + /* + * When supplied %g or %G, an optional precision is the number of + * significant digits to print. + * + * nsig = number of significant digits we've printed (leading zeros are + * never significant) + * ndig = if non-zero, max number of significant digits to print (only + * applicable to %g/%G) + */ + nsig = ndig = 0; + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_DOT)) + ndig = (p->precision == 0) ? 1 : p->precision; + + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + if (ndig && (++nsig >= ndig)) + break; + } + + if ((p->precision != 0 || (p->flags & PF_ALTFORM)) && (ndig == 0 || nsig < ndig)) + PUT_CHAR('.', p); /* the '.' */ + if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) + /* smash the trailing zeros unless altform */ + for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) + tmp2[i] = '\0'; + for (; *tmp2; tmp2++) + { + if (ndig && (nsig++ >= ndig)) + break; + PUT_CHAR(*tmp2, p); /* the fraction */ + } + + /* the exponent put the 'e|E' */ + if (*p->pf == 'g' || *p->pf == 'e') + { + PUT_CHAR('e', p); + } + else + PUT_CHAR('E', p); + + /* the sign of the exp */ + if (j > 0) + { + PUT_CHAR('+', p); + } + else + { + PUT_CHAR('-', p); + j = -j; + } + + tmp = itoa(j); + /* pad out to at least two spaces. pad with `0' if the exponent is a + single digit. */ + if (j <= 9) + { + PUT_CHAR('0', p); + } + + /* the exponent */ + while (*tmp) + { + PUT_CHAR(*tmp, p); + tmp++; + } + PAD_LEFT(p); +} +#endif + +/* initialize the conversion specifiers */ +static void +init_conv_flag (p) + struct DATA *p; +{ + p->flags &= PF_ALLOCBUF; /* preserve PF_ALLOCBUF flag */ + p->precision = p->width = NOT_FOUND; + p->justify = NOT_FOUND; + p->pad = ' '; +} + +static void +init_data (p, string, length, format, mode) + struct DATA *p; + char *string; + size_t length; + const char *format; + int mode; +{ + p->length = length - 1; /* leave room for '\0' */ + p->holder = p->base = string; + p->pf = format; + p->counter = 0; + p->flags = (mode == PFM_AS) ? PF_ALLOCBUF : 0; +} + +static int +#if defined (__STDC__) +vsnprintf_internal(struct DATA *data, char *string, size_t length, const char *format, va_list args) +#else +vsnprintf_internal(data, string, length, format, args) + struct DATA *data; + char *string; + size_t length; + const char *format; + va_list args; +#endif +{ + double d; /* temporary holder */ +#ifdef HAVE_LONG_DOUBLE + long double ld; /* for later */ +#endif + unsigned long ul; +#ifdef HAVE_LONG_LONG + unsigned long long ull; +#endif + int state, i, c, n; + char *s; + const char *convstart; + + /* Sanity check, the string must be > 1. C99 actually says that LENGTH + can be zero here, in the case of snprintf/vsnprintf (it's never 0 in + the case of asprintf/vasprintf), and the return value is the number + of characters that would have been written. */ + if (length < 1) + return -1; + + if (format == 0) + return 0; + + for (; c = *(data->pf); data->pf++) + { + if (c != '%') + { + PUT_CHAR (c, data); + continue; + } + + convstart = data->pf; + init_conv_flag (data); /* initialise format flags */ + + state = 1; + for (state = 1; state && *data->pf; ) + { + c = *(++data->pf); + /* fmtend = data->pf */ +#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE) + if (data->flags & PF_LONGDBL) + { + switch (c) + { + case 'f': case 'F': + case 'e': case 'E': + case 'g': case 'G': +# ifdef HAVE_PRINTF_A_FORMAT + case 'a': case 'A': +# endif + STAR_ARGS (data); + ld = GETLDOUBLE (data); + ldfallback (data, convstart, data->pf, ld); + goto conv_break; + } + } +#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */ + + switch (c) + { + /* Parse format flags */ + case '\0': /* a NULL here ? ? bail out */ + *data->holder = '\0'; + return data->counter; + break; + case '#': + data->flags |= PF_ALTFORM; + continue; + case '0': + data->flags |= PF_ZEROPAD; + data->pad = '0'; + continue; + case '*': + if (data->flags & PF_DOT) + data->flags |= PF_STAR_P; + else + data->flags |= PF_STAR_W; + continue; + case '-': + data->flags |= PF_LADJUST; + data->justify = LEFT; + continue; + case ' ': + if ((data->flags & PF_PLUS) == 0) + data->flags |= PF_SPACE; + continue; + case '+': + data->flags |= PF_PLUS; + data->justify = RIGHT; + continue; + case ',': + data->flags |= PF_COMMA; /* not implemented yet */ + continue; + + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + n = 0; + do + { + n = n * 10 + TODIGIT(c); + c = *(++data->pf); + } + while (DIGIT(c)); + data->pf--; /* went too far */ + if (n < 0) + n = 0; + if (data->flags & PF_DOT) + data->precision = n; + else + data->width = n; + continue; + + /* optional precision */ + case '.': + data->flags |= PF_DOT; + data->precision = 0; + continue; + + /* length modifiers */ + case 'h': + data->flags |= (data->flags & PF_SHORTINT) ? PF_SIGNEDCHAR : PF_SHORTINT; + continue; + case 'l': + data->flags |= (data->flags & PF_LONGINT) ? PF_LONGLONG : PF_LONGINT; + continue; + case 'L': + data->flags |= PF_LONGDBL; + continue; + case 'q': + data->flags |= PF_LONGLONG; + continue; + case 'j': + data->flags |= PF_INTMAX_T; + SET_SIZE_FLAGS(data, intmax_t); + continue; + case 'z': + data->flags |= PF_SIZE_T; + SET_SIZE_FLAGS(data, size_t); + continue; + case 't': + data->flags |= PF_PTRDIFF_T; + SET_SIZE_FLAGS(data, ptrdiff_t); + continue; + + /* Conversion specifiers */ +#ifdef FLOATING_POINT + case 'f': /* float, double */ + case 'F': + STAR_ARGS(data); + d = GETDOUBLE(data); + floating(data, d); +conv_break: + state = 0; + break; + case 'g': + case 'G': + STAR_ARGS(data); + DEF_PREC(data); + d = GETDOUBLE(data); + i = log_10(d); + /* + * for '%g|%G' ANSI: use f if exponent + * is in the range or [-4,p] exclusively + * else use %e|%E + */ + if (-4 < i && i < data->precision) + floating(data, d); + else + exponent(data, d); + state = 0; + break; + case 'e': + case 'E': /* Exponent double */ + STAR_ARGS(data); + d = GETDOUBLE(data); + exponent(data, d); + state = 0; + break; +# ifdef HAVE_PRINTF_A_FORMAT + case 'a': + case 'A': + STAR_ARGS(data); + d = GETDOUBLE(data); + dfallback(data, convstart, data->pf, d); + state = 0; + break; +# endif /* HAVE_PRINTF_A_FORMAT */ +#endif /* FLOATING_POINT */ + case 'U': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ + case 'u': + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = va_arg(args, unsigned long long); + lnumber(data, ull, 10); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 10); + } + state = 0; + break; + case 'D': + data->flags |= PF_LONGINT; + /* FALLTHROUGH */ + case 'd': /* decimal */ + case 'i': + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = va_arg(args, long long); + lnumber(data, ull, 10); + } + else +#endif + { + ul = GETSIGNED(data); + number(data, ul, 10); + } + state = 0; + break; + case 'o': /* octal */ + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = va_arg(args, unsigned long long); + lnumber(data, ull, 8); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 8); + } + state = 0; + break; + case 'x': + case 'X': /* hexadecimal */ + STAR_ARGS(data); +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + { + ull = va_arg(args, unsigned long long); + lnumber(data, ull, 16); + } + else +#endif + { + ul = GETUNSIGNED(data); + number(data, ul, 16); + } + state = 0; + break; + case 'p': + STAR_ARGS(data); + ul = (unsigned long)va_arg(args, void *); + pointer(data, ul); + state = 0; + break; + case 'c': /* character */ + ul = va_arg(args, int); + PUT_CHAR(ul, data); + state = 0; + break; + case 's': /* string */ + STAR_ARGS(data); + s = va_arg(args, char *); + strings(data, s); + state = 0; + break; + case 'n': +#ifdef HAVE_LONG_LONG + if (data->flags & PF_LONGLONG) + *(va_arg(args, long long *)) = data->counter; + else +#endif + if (data->flags & PF_LONGINT) + *(va_arg(args, long *)) = data->counter; + else if (data->flags & PF_SHORTINT) + *(va_arg(args, short *)) = data->counter; + else + *(va_arg(args, int *)) = data->counter; + state = 0; + break; + case '%': /* nothing just % */ + PUT_CHAR('%', data); + state = 0; + break; + default: + /* is this an error ? maybe bail out */ + state = 0; + break; + } /* end switch */ + } /* end of `%' for loop */ + } /* end of format string for loop */ + + if (data->length >= 0) + *data->holder = '\0'; /* the end ye ! */ + + return data->counter; +} + +#if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE) +/* + * Printing floating point numbers accurately is an art. I'm not good + * at it. Fall back to sprintf for long double formats. + */ +static void +ldfallback (data, fs, fe, ld) + struct DATA *data; + const char *fs, *fe; + long double ld; +{ + register char *x; + char fmtbuf[FALLBACK_FMTSIZE], *obuf; + int fl; + + obuf = xmalloc(LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2); + fl = fe - fs + 1; + strncpy (fmtbuf, fs, fl); + fmtbuf[fl] = '\0'; + sprintf (obuf, fmtbuf, ld); + for (x = obuf; *x; x++) + PUT_CHAR (*x, data); + xfree (obuf); +} +#endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */ + +#ifdef FLOATING_POINT +/* Used for %a, %A if the libc printf supports them. */ +static void +dfallback (data, fs, fe, d) + struct DATA *data; + const char *fs, *fe; + double d; +{ + register char *x; + char fmtbuf[FALLBACK_FMTSIZE], obuf[FALLBACK_BASE]; + int fl; + + fl = fe - fs + 1; + strncpy (fmtbuf, fs, fl); + fmtbuf[fl] = '\0'; + sprintf (obuf, fmtbuf, d); + for (x = obuf; *x; x++) + PUT_CHAR (*x, data); +} +#endif /* FLOATING_POINT */ + +#ifndef HAVE_SNPRINTF + +int +#if defined (__STDC__) +vsnprintf(char *string, size_t length, const char *format, va_list args) +#else +vsnprintf(string, length, format, args) + char *string; + size_t length; + const char *format; + va_list args; +#endif +{ + struct DATA data; + + init_data (&data, string, length, format, PFM_SN); + return (vsnprintf_internal(&data, string, length, format, args)); +} + +int +#if defined(PREFER_STDARG) +snprintf(char *string, size_t length, const char * format, ...) +#else +snprintf(string, length, format, va_alist) + char *string; + size_t length; + const char *format; + va_dcl +#endif +{ + struct DATA data; + int rval; + va_list args; + +#if defined(PREFER_STDARG) + va_start(args, format); +#else + va_start(args); +#endif + + init_data (&data, string, length, format, PFM_SN); + rval = vsnprintf_internal (&data, string, length, format, args); + + va_end(args); + + return rval; +} + +#endif /* HAVE_SNPRINTF */ + +#ifndef HAVE_ASPRINTF + +int +#if defined (__STDC__) +vasprintf(char **stringp, const char *format, va_list args) +#else +vasprintf(stringp, format, args) + char **stringp; + const char *format; + va_list args; +#endif +{ + struct DATA data; + char *string; + int r; + + string = (char *)xmalloc(ASBUFSIZE); + init_data (&data, string, ASBUFSIZE, format, PFM_AS); + r = vsnprintf_internal(&data, string, ASBUFSIZE, format, args); + *stringp = data.base; /* not string in case reallocated */ + return r; +} + +int +#if defined(PREFER_STDARG) +asprintf(char **stringp, const char * format, ...) +#else +asprintf(stringp, format, va_alist) + char **stringp; + const char *format; + va_dcl +#endif +{ + int rval; + va_list args; + +#if defined(PREFER_STDARG) + va_start(args, format); +#else + va_start(args); +#endif + + rval = vasprintf (stringp, format, args); + + va_end(args); + + return rval; +} + +#endif + +#endif + +#ifdef DRIVER + +static void +memory_error_and_abort () +{ + write (2, "out of virtual memory\n", 22); + abort (); +} + +static void * +xmalloc(bytes) + size_t bytes; +{ + void *ret; + + ret = malloc(bytes); + if (ret == 0) + memory_error_and_abort (); + return ret; +} + +static void * +xrealloc (pointer, bytes) + void *pointer; + size_t bytes; +{ + void *ret; + + ret = pointer ? realloc(pointer, bytes) : malloc(bytes); + if (ret == 0) + memory_error_and_abort (); + return ret; +} + +static void +xfree(x) + void *x; +{ + if (x) + free (x); +} + +#ifdef FLOATING_POINT +# include <float.h> +#endif + +/* set of small tests for snprintf() */ +main() +{ + char holder[100]; + char *h; + int i, si, ai; + +/* + printf("Suite of test for snprintf:\n"); + printf("a_format\n"); + printf("printf() format\n"); + printf("snprintf() format\n\n"); +*/ +/* Checking the field widths */ + + printf("/%%ld %%ld/, 336, 336\n"); + snprintf(holder, sizeof holder, "/%ld %ld/\n", 336, 336); + asprintf(&h, "/%ld %ld/\n", 336, 336); + printf("/%ld %ld/\n", 336, 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%d/, 336\n"); + snprintf(holder, sizeof holder, "/%d/\n", 336); + asprintf(&h, "/%d/\n", 336); + printf("/%d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%2d/, 336\n"); + snprintf(holder, sizeof holder, "/%2d/\n", 336); + asprintf(&h, "/%2d/\n", 336); + printf("/%2d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10d/, 336\n"); + snprintf(holder, sizeof holder, "/%10d/\n", 336); + asprintf(&h, "/%10d/\n", 336); + printf("/%10d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%-10d/, 336\n"); + snprintf(holder, sizeof holder, "/%-10d/\n", 336); + asprintf(&h, "/%-10d/\n", 336); + printf("/%-10d/\n", 336); + printf("%s", holder); + printf("%s\n", h); + + +/* floating points */ + + printf("/%%f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%f/\n", 1234.56); + asprintf(&h, "/%f/\n", 1234.56); + printf("/%f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%e/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%e/\n", 1234.56); + asprintf(&h, "/%e/\n", 1234.56); + printf("/%e/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%4.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56); + asprintf(&h, "/%4.2f/\n", 1234.56); + printf("/%4.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%3.1f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56); + asprintf(&h, "/%3.1f/\n", 1234.56); + printf("/%3.1f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10.3f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56); + asprintf(&h, "/%10.3f/\n", 1234.56); + printf("/%10.3f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%10.3e/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56); + asprintf(&h, "/%10.3e/\n", 1234.56); + printf("/%10.3e/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%+4.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56); + asprintf(&h, "/%+4.2f/\n", 1234.56); + printf("/%+4.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%010.2f/, 1234.56\n"); + snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56); + asprintf(&h, "/%010.2f/\n", 1234.56); + printf("/%010.2f/\n", 1234.56); + printf("%s", holder); + printf("%s\n", h); + +#define BLURB "Outstanding acting !" +/* strings precisions */ + + printf("/%%2s/, \"%s\"\n", BLURB); + snprintf(holder, sizeof holder, "/%2s/\n", BLURB); + asprintf(&h, "/%2s/\n", BLURB); + printf("/%2s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%22s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%22s/\n", BLURB); + asprintf(&h, "/%22s/\n", BLURB); + printf("/%22s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%22.5s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB); + asprintf(&h, "/%22.5s/\n", BLURB); + printf("/%22.5s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%-22.5s/ %s\n", BLURB); + snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB); + asprintf(&h, "/%-22.5s/\n", BLURB); + printf("/%-22.5s/\n", BLURB); + printf("%s", holder); + printf("%s\n", h); + +/* see some flags */ + + printf("%%x %%X %%#x, 31, 31, 31\n"); + snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31); + asprintf(&h, "%x %X %#x\n", 31, 31, 31); + printf("%x %X %#x\n", 31, 31, 31); + printf("%s", holder); + printf("%s\n", h); + + printf("**%%d**%% d**%% d**, 42, 42, -42\n"); + snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42); + asprintf(&h, "**%d**% d**% d**\n", 42, 42, -42); + printf("**%d**% d**% d**\n", 42, 42, -42); + printf("%s", holder); + printf("%s\n", h); + +/* other flags */ + + printf("/%%g/, 31.4\n"); + snprintf(holder, sizeof holder, "/%g/\n", 31.4); + asprintf(&h, "/%g/\n", 31.4); + printf("/%g/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.6g/, 31.4\n"); + snprintf(holder, sizeof holder, "/%.6g/\n", 31.4); + asprintf(&h, "/%.6g/\n", 31.4); + printf("/%.6g/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.1G/, 31.4\n"); + snprintf(holder, sizeof holder, "/%.1G/\n", 31.4); + asprintf(&h, "/%.1G/\n", 31.4); + printf("/%.1G/\n", 31.4); + printf("%s", holder); + printf("%s\n", h); + + printf("/%%.1G/, 3100000000.4\n"); + snprintf(holder, sizeof holder, "/%.1G/\n", 3100000000.4); + asprintf(&h, "/%.1G/\n", 3100000000.4); + printf("/%.1G/\n", 3100000000.4); + printf("%s", holder); + printf("%s\n", h); + + printf("abc%%n\n"); + printf("abc%n", &i); printf("%d\n", i); + snprintf(holder, sizeof holder, "abc%n", &i); + printf("%s", holder); printf("%d\n\n", i); + asprintf(&h, "abc%n", &i); + printf("%s", h); printf("%d\n\n", i); + + printf("%%*.*s --> 10.10\n"); + snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB); + asprintf(&h, "%*.*s\n", 10, 10, BLURB); + printf("%*.*s\n", 10, 10, BLURB); + printf("%s", holder); + printf("%s\n", h); + + printf("%%%%%%%%\n"); + snprintf(holder, sizeof holder, "%%%%\n"); + asprintf(&h, "%%%%\n"); + printf("%%%%\n"); + printf("%s", holder); + printf("%s\n", h); + +#define BIG "Hello this is a too big string for the buffer" +/* printf("A buffer to small of 10, trying to put this:\n");*/ + printf("<%%>, %s\n", BIG); + i = snprintf(holder, 10, "%s\n", BIG); + i = asprintf(&h, "%s", BIG); + printf("<%s>\n", BIG); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + + printf ("<%%p> vsnprintf\n"); + i = snprintf(holder, 100, "%p", vsnprintf); + i = asprintf(&h, "%p", vsnprintf); + printf("<%p>\n", vsnprintf); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + + printf ("<%%lu> LONG_MAX+1\n"); + i = snprintf(holder, 100, "%lu", (unsigned long)(LONG_MAX)+1); + i = asprintf(&h, "%lu", (unsigned long)(LONG_MAX)+1); + printf("<%lu>\n", (unsigned long)(LONG_MAX)+1); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); + +#ifdef HAVE_LONG_LONG + printf ("<%%llu> LLONG_MAX+1\n"); + i = snprintf(holder, 100, "%llu", (unsigned long long)(LLONG_MAX)+1); + i = asprintf(&h, "%llu", (unsigned long long)(LLONG_MAX)+1); + printf("<%llu>\n", (unsigned long long)(LLONG_MAX)+1); + printf("<%s>\n", holder); + printf("<%s>\n\n", h); +#endif + +#ifdef HAVE_LONG_DOUBLE + printf ("<%%6.2LE> 42.42\n"); + i = snprintf(holder, 100, "%6.2LE", (long double)42.42); + i = asprintf(&h, "%6.2LE", (long double)42.42); + printf ("<%6.2LE>\n", (long double)42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); +#endif + +#ifdef HAVE_PRINTF_A_FORMAT + printf ("<%%6.2A> 42.42\n"); + i = snprintf(holder, 100, "%6.2A", 42.42); + i = asprintf(&h, "%6.2A", 42.42); + printf ("<%6.2A>\n", 42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); + + printf ("<%%6.2LA> 42.42\n"); + i = snprintf(holder, 100, "%6.2LA", (long double)42.42); + i = asprintf(&h, "%6.2LA", (long double)42.42); + printf ("<%6.2LA>\n", (long double)42.42); + printf ("<%s>\n", holder); + printf ("<%s>\n\n", h); +#endif + + printf ("<%%.10240f> DBL_MAX\n"); + si = snprintf(holder, 100, "%.10240f", DBL_MAX); + ai = asprintf(&h, "%.10240f", DBL_MAX); + printf ("<%.10240f>\n", DBL_MAX); + printf ("<%d> <%s>\n", si, holder); + printf ("<%d> <%s>\n\n", ai, h); + + printf ("<%%.10240Lf> LDBL_MAX\n"); + si = snprintf(holder, 100, "%.10240Lf", (long double)LDBL_MAX); + ai = asprintf(&h, "%.10240Lf", (long double)LDBL_MAX); + printf ("<%.10240Lf>\n", (long double)LDBL_MAX); + printf ("<%d> <%s>\n", si, holder); + printf ("<%d> <%s>\n\n", ai, h); + + exit (0); +} +#endif diff --git a/lib/sh/strcasecmp.c b/lib/sh/strcasecmp.c index 1e15c02..33d925b 100644 --- a/lib/sh/strcasecmp.c +++ b/lib/sh/strcasecmp.c @@ -24,11 +24,7 @@ #include <stdc.h> #include <bashansi.h> -#include <ctype.h> - -#if !defined (to_lower) -# define to_lower(c) (islower(c) ? (c) : tolower(c)) -#endif /* to_lower */ +#include <chartypes.h> /* Compare at most COUNT characters from string1 to string2. Case doesn't matter. */ @@ -49,7 +45,7 @@ strncasecmp (string1, string2, count) s2 = string2; do { - if ((r = to_lower (*s1) - to_lower (*s2)) != 0) + if ((r = TOLOWER ((unsigned char) *s1) - TOLOWER ((unsigned char) *s2)) != 0) return r; if (*s1++ == '\0') break; @@ -76,7 +72,7 @@ strcasecmp (string1, string2) if (s1 == s2) return (0); - while ((r = to_lower (*s1) - to_lower (*s2)) == 0) + while ((r = TOLOWER ((unsigned char)*s1) - TOLOWER ((unsigned char)*s2)) == 0) { if (*s1++ == '\0') return 0; diff --git a/lib/sh/strindex.c b/lib/sh/strindex.c index 9d3f302..9172862 100644 --- a/lib/sh/strindex.c +++ b/lib/sh/strindex.c @@ -22,16 +22,11 @@ #include <config.h> -#include "bashansi.h" -#include <ctype.h> +#include <bashansi.h> +#include <chartypes.h> #include <stdc.h> -#ifndef to_upper -# define to_upper(c) (islower(c) ? toupper(c) : (c)) -# define to_lower(c) (isupper(c) ? tolower(c) : (c)) -#endif - /* Determine if s2 occurs in s1. If so, return a pointer to the match in s1. The compare is case insensitive. This is a case-insensitive strstr(3). */ @@ -42,11 +37,11 @@ strindex (s1, s2) { register int i, l, len, c; - c = to_upper (s2[0]); + c = TOLOWER ((unsigned char)s2[0]); len = strlen (s1); l = strlen (s2); for (i = 0; (len - i) >= l; i++) - if ((to_upper (s1[i]) == c) && (strncasecmp (s1 + i, s2, l) == 0)) + if ((TOLOWER ((unsigned char)s1[i]) == c) && (strncasecmp (s1 + i, s2, l) == 0)) return ((char *)s1 + i); return ((char *)0); } diff --git a/lib/sh/stringlist.c b/lib/sh/stringlist.c index 8fc57cb..29937d3 100644 --- a/lib/sh/stringlist.c +++ b/lib/sh/stringlist.c @@ -25,7 +25,7 @@ #endif #include <stdio.h> -#include "bashansi.h" +#include <bashansi.h> #include "shell.h" @@ -67,6 +67,9 @@ realloc_stringlist (sl, n) { register int i; + if (sl == 0) + return (sl = alloc_stringlist(n)); + if (n > sl->list_size) { sl->list = (char **)xrealloc (sl->list, (n+1) * sizeof (char *)); @@ -95,6 +98,8 @@ copy_stringlist (sl) STRINGLIST *new; register int i; + if (sl == 0) + return ((STRINGLIST *)0); new = alloc_stringlist (sl->list_size); /* I'd like to use copy_array, but that doesn't copy everything. */ if (sl->list) @@ -129,6 +134,7 @@ merge_stringlists (m1, m2) sl->list[n] = STRDUP (m2->list[i]); sl->list_len = n; sl->list[n] = (char *)NULL; + return (sl); } /* Make STRINGLIST M1 contain everything in M1 and M2. */ @@ -139,10 +145,7 @@ append_stringlist (m1, m2) register int i, n, len1, len2; if (m1 == 0) - { - m1 = copy_stringlist (m2); - return m1; - } + return (m2 ? copy_stringlist (m2) : (STRINGLIST *)0); len1 = m1->list_len; len2 = m2 ? m2->list_len : 0; @@ -180,7 +183,7 @@ prefix_suffix_stringlist (sl, prefix, suffix) { llen = STRLEN (sl->list[i]); tlen = plen + llen + slen + 1; - t = xmalloc (tlen + 1); + t = (char *)xmalloc (tlen + 1); if (plen) strcpy (t, prefix); strcpy (t + plen, sl->list[i]); @@ -223,6 +226,12 @@ word_list_to_stringlist (list, copy, starting_index, ip) STRINGLIST *ret; int slen, len; + if (list == 0) + { + if (ip) + *ip = 0; + return ((STRINGLIST *)0); + } slen = list_length (list); ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST)); ret->list = word_list_to_argv (list, copy, starting_index, &len); diff --git a/lib/sh/stringvec.c b/lib/sh/stringvec.c index 977ef48..fa16ad4 100644 --- a/lib/sh/stringvec.c +++ b/lib/sh/stringvec.c @@ -18,17 +18,17 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "config.h" +#include <config.h> -#include "bashtypes.h" +#include <bashtypes.h> #if defined (HAVE_UNISTD_H) # include <unistd.h> #endif -#include "bashansi.h" +#include <bashansi.h> #include <stdio.h> -#include <ctype.h> +#include <chartypes.h> #include "shell.h" @@ -100,16 +100,16 @@ copy_array (array) { register int i; int len; - char **new_array; + char **ret; len = array_len (array); - new_array = (char **)xmalloc ((len + 1) * sizeof (char *)); + ret = (char **)xmalloc ((len + 1) * sizeof (char *)); for (i = 0; array[i]; i++) - new_array[i] = savestring (array[i]); - new_array[i] = (char *)NULL; + ret[i] = savestring (array[i]); + ret[i] = (char *)NULL; - return (new_array); + return (ret); } /* Comparison routine for use with qsort() on arrays of strings. Uses @@ -135,7 +135,5 @@ void sort_char_array (array) char **array; { - qsort (array, array_len (array), sizeof (char *), - (Function *)qsort_string_compare); + qsort (array, array_len (array), sizeof (char *), (QSFUNC *)qsort_string_compare); } - diff --git a/lib/sh/strtod.c b/lib/sh/strtod.c index fe0f09d..cc3bec9 100644 --- a/lib/sh/strtod.c +++ b/lib/sh/strtod.c @@ -25,7 +25,7 @@ extern int errno; #endif -#include <ctype.h> +#include <chartypes.h> #include <math.h> #if HAVE_FLOAT_H @@ -73,7 +73,7 @@ strtod (nptr, endptr) s = nptr; /* Eat whitespace. */ - while (isspace (*s)) + while (ISSPACE ((unsigned char)*s)) ++s; /* Get the sign. */ @@ -87,7 +87,7 @@ strtod (nptr, endptr) exponent = 0; for (;; ++s) { - if (isdigit (*s)) + if (DIGIT (*s)) { got_digit = 1; @@ -120,7 +120,7 @@ strtod (nptr, endptr) if (!got_digit) goto noconv; - if (tolower (*s) == 'e') + if (TOLOWER ((unsigned char)*s) == 'e') { /* Get the exponent specified after the `e' or `E'. */ int save = errno; diff --git a/lib/sh/strtoimax.c b/lib/sh/strtoimax.c new file mode 100644 index 0000000..30075ce --- /dev/null +++ b/lib/sh/strtoimax.c @@ -0,0 +1,102 @@ +/* Convert string representation of a number into an intmax_t value. + Copyright 1999, 2001 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, 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; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_INTTYPES_H +# include <inttypes.h> +#endif + +#if HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#include <stdc.h> + +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } + +#ifndef HAVE_DECL_STRTOL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOL +extern long strtol __P((const char *, char **, int)); +#endif + +#ifndef HAVE_DECL_STRTOLL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG +extern long long strtoll __P((const char *, char **, int)); +#endif + +intmax_t +strtoimax (ptr, endptr, base) + const char *ptr; + char **endptr; + int base; +{ +#if HAVE_LONG_LONG + verify(size_is_that_of_long_or_long_long, + (sizeof (intmax_t) == sizeof (long) || + sizeof (intmax_t) == sizeof (long long))); + + if (sizeof (intmax_t) != sizeof (long)) + return (strtoll (ptr, endptr, base)); +#else + verify (size_is_that_of_long, sizeof (intmax_t) == sizeof (long)); +#endif + + return (strtol (ptr, endptr, base)); +} + +#ifdef TESTING +# include <stdio.h> +int +main () +{ + char *p, *endptr; + intmax_t x; +#if HAVE_LONG_LONG + long long y; +#endif + long z; + + printf ("sizeof intmax_t: %d\n", sizeof (intmax_t)); + +#if HAVE_LONG_LONG + printf ("sizeof long long: %d\n", sizeof (long long)); +#endif + printf ("sizeof long: %d\n", sizeof (long)); + + x = strtoimax("42", &endptr, 10); +#if HAVE_LONG_LONG + y = strtoll("42", &endptr, 10); +#else + y = -1; +#endif + z = strtol("42", &endptr, 10); + + printf ("%lld %lld %ld\n", x, y, z); + + exit (0); +} +#endif diff --git a/lib/sh/strtol.c b/lib/sh/strtol.c index e990932..2adbb89 100644 --- a/lib/sh/strtol.c +++ b/lib/sh/strtol.c @@ -1,25 +1,27 @@ -/* strtol - Convert string representation of a number into an integer value. - Copyright (C) 1997 Free Software Foundation, Inc. +/* Convert string representation of a number into an integer value. + Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. - 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, or (at your option) any - later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <config.h> #if !defined (HAVE_STRTOL) -#include <ctype.h> +#include <chartypes.h> #include <errno.h> #ifndef errno @@ -34,6 +36,8 @@ extern int errno; # include <limits.h> #endif +#include <typemax.h> + #include <stdc.h> #include <bashansi.h> @@ -41,61 +45,74 @@ extern int errno; # define NULL 0 #endif -/* Nonzero if we are defining `strtoul', operating on unsigned integers. */ +/* Nonzero if we are defining `strtoul' or `strtoull', operating on + unsigned integers. */ #ifndef UNSIGNED -# define UNSIGNED 0 -# define RETTYPE long +# define UNSIGNED 0 +# define INT LONG int #else -# define RETTYPE unsigned long +# define INT unsigned LONG int #endif -/* Determine the name. */ #if UNSIGNED -# define strtol strtoul -#endif - -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif - -#ifndef ULONG_MAX -# define ULONG_MAX ((unsigned long) ~(unsigned long) 0) -# define ULONG_MIN ((unsigned long) 0 - ULONG_MAX) +# ifdef QUAD +# define strtol strtoull +# else +# define strtol strtoul +# endif +#else +# ifdef QUAD +# define strtol strtoll +# endif #endif -#ifndef LONG_MAX -# define LONG_MAX ((long) (ULONG_MAX >> 1)) -# define LONG_MIN ((long) (0 - LONG_MAX)) +/* If QUAD is defined, we are defining `strtoll' or `strtoull', + operating on `long long ints. */ + +#ifdef QUAD +# define LONG long long +# define STRTOL_LONG_MIN LLONG_MIN +# define STRTOL_LONG_MAX LLONG_MAX +# define STRTOL_ULONG_MAX ULLONG_MAX +#else /* !QUAD */ +# define LONG long +# define STRTOL_LONG_MIN LONG_MIN +# define STRTOL_LONG_MAX LONG_MAX +# define STRTOL_ULONG_MAX ULONG_MAX #endif /* Convert NPTR to an `unsigned long int' or `long int' in base BASE. If BASE is 0 the base is determined by the presence of a leading zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. - If BASE is < 2 or > 36, it is reset to 10. + If BASE is < 2 or > 36, it is no longer reset to 10; EINVAL is returned. If ENDPTR is not NULL, a pointer to the character after the last one converted is stored in *ENDPTR. */ -RETTYPE +INT strtol (nptr, endptr, base) const char *nptr; char **endptr; int base; { int negative; - register unsigned long cutoff, i; + register unsigned LONG int cutoff; register unsigned int cutlim; + register unsigned LONG int i; register const char *s; register unsigned char c; const char *save, *end; int overflow; if (base < 0 || base == 1 || base > 36) - base = 10; + { + __set_errno (EINVAL); + return 0; + } save = s = nptr; /* Skip white space. */ - while (isspace (*s)) + while (ISSPACE ((unsigned char)*s)) ++s; if (*s == '\0') goto noconv; @@ -109,58 +126,85 @@ strtol (nptr, endptr, base) else negative = 0; - if (base == 16 && *s == '0' && toupper (s[1]) == 'X') - s += 2; - - /* If BASE is zero, figure it out ourselves. */ - if (base == 0) - if (*s == '0') - { - if (toupper (s[1]) == 'X') - { - s += 2; - base = 16; - } - else - base = 8; - } - else - base = 10; + /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ + if (*s == '0') + { + if ((base == 0 || base == 16) && TOUPPER ((unsigned char) s[1]) == 'X') + { + s += 2; + base = 16; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; /* Save the pointer so we can check later if anything happened. */ save = s; end = NULL; - cutoff = ULONG_MAX / (unsigned long int) base; - cutlim = ULONG_MAX % (unsigned long int) base; + cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base; + cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base; overflow = 0; i = 0; - for (c = *s; c != '\0'; c = *++s) + c = *s; + if (sizeof (long int) != sizeof (LONG int)) { - if (s == end) - break; + unsigned long int j = 0; + unsigned long int jmax = ULONG_MAX / base; - if (c >= '0' && c <= '9') - c -= '0'; - else if (isalpha (c)) - c = toupper (c) - 'A' + 10; - else - break; - - if ((int) c >= base) - break; - - /* Check for overflow. */ - if (i > cutoff || (i == cutoff && c > cutlim)) - overflow = 1; - else + for (;c != '\0'; c = *++s) { - i *= (unsigned long int) base; - i += c; + if (s == end) + break; + if (DIGIT (c)) + c -= '0'; + else if (ISALPHA (c)) + c = TOUPPER (c) - 'A' + 10; + else + break; + + if ((int) c >= base) + break; + /* Note that we never can have an overflow. */ + else if (j >= jmax) + { + /* We have an overflow. Now use the long representation. */ + i = (unsigned LONG int) j; + goto use_long; + } + else + j = j * (unsigned long int) base + c; } + + i = (unsigned LONG int) j; } + else + for (;c != '\0'; c = *++s) + { + if (s == end) + break; + if (DIGIT (c)) + c -= '0'; + else if (ISALPHA (c)) + c = TOUPPER (c) - 'A' + 10; + else + break; + if ((int) c >= base) + break; + /* Check for overflow. */ + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + use_long: + i *= (unsigned LONG int) base; + i += c; + } + } /* Check if anything actually happened. */ if (s == save) @@ -173,11 +217,11 @@ strtol (nptr, endptr, base) #if !UNSIGNED /* Check for a value that is within the range of - `unsigned long int', but outside the range of `long int'. */ + `unsigned LONG int', but outside the range of `LONG int'. */ if (overflow == 0 && i > (negative - ? -((unsigned long) (LONG_MIN + 1)) + 1 - : (unsigned long) LONG_MAX)) + ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1 + : (unsigned LONG int) STRTOL_LONG_MAX)) overflow = 1; #endif @@ -185,23 +229,23 @@ strtol (nptr, endptr, base) { __set_errno (ERANGE); #if UNSIGNED - return ULONG_MAX; + return STRTOL_ULONG_MAX; #else - return negative ? LONG_MIN : LONG_MAX; + return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX; #endif } - /* Return the result with the appropriate sign. */ - return (negative ? -i : i); + /* Return the result of the appropriate sign. */ + return negative ? -i : i; noconv: /* We must handle a special case here: the base is 0 or 16 and the first two characters are '0' and 'x', but the rest are no hexadecimal digits. This is no error case. We return 0 and - ENDPTR points to the `x'. */ + ENDPTR points to the `x`. */ if (endptr != NULL) { - if (save - nptr >= 2 && toupper (save[-1]) == 'X' && save[-2] == '0') + if (save - nptr >= 2 && TOUPPER ((unsigned char) save[-1]) == 'X' && save[-2] == '0') *endptr = (char *) &save[-1]; else /* There was no number to convert. */ diff --git a/lib/sh/strtoll.c b/lib/sh/strtoll.c new file mode 100644 index 0000000..2000497 --- /dev/null +++ b/lib/sh/strtoll.c @@ -0,0 +1,26 @@ +/* Copyright (C) 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, 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; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <config.h> + +#if defined (HAVE_LONG_LONG) && !defined (HAVE_STRTOLL) + +#define QUAD 1 +#undef HAVE_STRTOL + +#include "strtol.c" + +#endif /* HAVE_LONG_LONG && !HAVE_STRTOLL */ diff --git a/lib/sh/strtoull.c b/lib/sh/strtoull.c new file mode 100644 index 0000000..09a2fac --- /dev/null +++ b/lib/sh/strtoull.c @@ -0,0 +1,27 @@ +/* Copyright (C) 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, 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; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include <config.h> + +#if defined (HAVE_LONG_LONG) && !defined (HAVE_STRTOULL) + +#define QUAD 1 +#define UNSIGNED 1 +#undef HAVE_STRTOL + +#include "strtol.c" + +#endif /* HAVE_LONG_LONG && !HAVE_STRTOULL */ diff --git a/lib/sh/strtoumax.c b/lib/sh/strtoumax.c new file mode 100644 index 0000000..c35461a --- /dev/null +++ b/lib/sh/strtoumax.c @@ -0,0 +1,102 @@ +/* Convert string representation of a number into an uintmax_t value. + Copyright 1999, 2001 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, 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; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_INTTYPES_H +# include <inttypes.h> +#endif + +#if HAVE_STDLIB_H +# include <stdlib.h> +#endif + +#include <stdc.h> + +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } + +#ifndef HAVE_DECL_STRTOUL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOUL +extern unsigned long strtoul __P((const char *, char **, int)); +#endif + +#ifndef HAVE_DECL_STRTOULL +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG +extern unsigned long long strtoull __P((const char *, char **, int)); +#endif + +uintmax_t +strtoumax (ptr, endptr, base) + const char *ptr; + char **endptr; + int base; +{ +#if HAVE_UNSIGNED_LONG_LONG + verify (size_is_that_of_unsigned_long_or_unsigned_long_long, + (sizeof (uintmax_t) == sizeof (unsigned long) || + sizeof (uintmax_t) == sizeof (unsigned long long))); + + if (sizeof (uintmax_t) != sizeof (unsigned long)) + return (strtoull (ptr, endptr, base)); +#else + verify (size_is_that_of_unsigned_long, sizeof (uintmax_t) == sizeof (unsigned long)); +#endif + + return (strtoul (ptr, endptr, base)); +} + +#ifdef TESTING +# include <stdio.h> +int +main () +{ + char *p, *endptr; + uintmax_t x; +#if HAVE_UNSIGNED_LONG_LONG + unsigned long long y; +#endif + unsigned long z; + + printf ("sizeof uintmax_t: %d\n", sizeof (uintmax_t)); + +#if HAVE_UNSIGNED_LONG_LONG + printf ("sizeof unsigned long long: %d\n", sizeof (unsigned long long)); +#endif + printf ("sizeof unsigned long: %d\n", sizeof (unsigned long)); + + x = strtoumax("42", &endptr, 10); +#if HAVE_LONG_LONG + y = strtoull("42", &endptr, 10); +#else + y = 0; +#endif + z = strtoul("42", &endptr, 10); + + printf ("%llu %llu %lu\n", x, y, z); + + exit (0); +} +#endif diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c index 7005c46..9192e62 100644 --- a/lib/sh/strtrans.c +++ b/lib/sh/strtrans.c @@ -26,9 +26,9 @@ # include <unistd.h> #endif -#include "bashansi.h" +#include <bashansi.h> #include <stdio.h> -#include <ctype.h> +#include <chartypes.h> #include "shell.h" @@ -37,21 +37,6 @@ #endif #define ESC '\033' /* ASCII */ -#ifndef ISOCTAL -#define ISOCTAL(c) ((c) >= '0' && (c) <= '7') -#endif - -#ifndef OCTVALUE -#define OCTVALUE(c) ((c) - '0') -#endif - -#ifndef isxdigit -# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) -#endif - -#define HEXVALUE(c) \ - ((c) >= 'a' && (c) <= 'f' ? (c)-'a'+10 : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') - /* Convert STRING by expanding the escape sequences specified by the ANSI C standard. If SAWC is non-null, recognize `\c' and use that as a string terminator. If we see \c, set *SAWC to 1 before @@ -70,7 +55,7 @@ ansicstr (string, len, for_echo, sawc, rlen) if (string == 0 || *string == '\0') return ((char *)NULL); - ret = xmalloc (len + 1); + ret = (char *)xmalloc (len + 1); for (r = ret, s = string; s && *s; ) { c = *s++; @@ -98,16 +83,18 @@ ansicstr (string, len, for_echo, sawc, rlen) case '4': case '5': case '6': case '7': for (temp = 2, c -= '0'; ISOCTAL (*s) && temp--; s++) c = (c * 8) + OCTVALUE (*s); + c &= 0xFF; break; case 'x': /* Hex digit -- non-ANSI */ - for (temp = 3, c = 0; isxdigit (*s) && temp--; s++) + for (temp = 2, c = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++) c = (c * 16) + HEXVALUE (*s); /* \x followed by non-hex digits is passed through unchanged */ - if (temp == 3) + if (temp == 2) { *r++ = '\\'; c = 'x'; } + c &= 0xFF; break; case '\\': break; @@ -143,21 +130,22 @@ ansic_quote (str, flags, rlen) int flags, *rlen; { char *r, *ret, *s, obuf[8]; - int l, c, rsize, t; + int l, rsize, t; + unsigned char c; if (str == 0 || *str == 0) return ((char *)0); l = strlen (str); rsize = 2 * l + 4; - r = ret = xmalloc (rsize); + r = ret = (char *)xmalloc (rsize); *r++ = '$'; *r++ = '\''; for (s = str, l = 0; *s; s++) { - c = *(unsigned char *)s; + c = *s; l = 1; /* 1 == add backslash; 0 == no backslash */ switch (c) { @@ -179,7 +167,7 @@ ansic_quote (str, flags, rlen) case '\'': break; default: - if (isprint (c) == 0) + if (ISPRINT (c) == 0) { sprintf (obuf, "\\%.3o", c); t = r - ret; @@ -203,3 +191,20 @@ ansic_quote (str, flags, rlen) *rlen = r - ret; return ret; } + +/* return 1 if we need to quote with $'...' because of non-printing chars. */ +ansic_shouldquote (string) + const char *string; +{ + const char *s; + unsigned char c; + + if (string == 0) + return 0; + + for (s = string; c = *s; s++) + if (ISPRINT (c) == 0) + return 1; + + return 0; +} diff --git a/lib/sh/times.c b/lib/sh/times.c index e26e41c..7136cf2 100644 --- a/lib/sh/times.c +++ b/lib/sh/times.c @@ -30,7 +30,7 @@ # include <sys/resource.h> #endif /* HAVE_SYS_RESOURCE_H && HAVE_GETRUSAGE */ -extern long get_clk_tck(); +extern long get_clk_tck __P((void)); #define CONVTCK(r) (r.tv_sec * clk_tck + r.tv_usec / (1000000 / clk_tck)) diff --git a/lib/sh/timeval.c b/lib/sh/timeval.c index 809d411..f7f624e 100644 --- a/lib/sh/timeval.c +++ b/lib/sh/timeval.c @@ -103,7 +103,7 @@ timeval_to_cpu (rt, ut, st) void timeval_to_secs (tvp, sp, sfp) struct timeval *tvp; - long *sp; + time_t *sp; int *sfp; { int rest; @@ -131,14 +131,15 @@ print_timeval (fp, tvp) FILE *fp; struct timeval *tvp; { - int minutes, seconds_fraction; - long seconds; + time_t timestamp; + long minutes; + int seconds, seconds_fraction; - timeval_to_secs (tvp, &seconds, &seconds_fraction); + timeval_to_secs (tvp, ×tamp, &seconds_fraction); - minutes = seconds / 60; - seconds %= 60; + minutes = timestamp / 60; + seconds = timestamp % 60; - fprintf (fp, "%0dm%0ld.%03ds", minutes, seconds, seconds_fraction); + fprintf (fp, "%ldm%d.%03ds", minutes, seconds, seconds_fraction); } #endif /* HAVE_TIMEVAL */ diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c index 6912e5c..d51ac2c 100644 --- a/lib/sh/tmpfile.c +++ b/lib/sh/tmpfile.c @@ -44,7 +44,7 @@ extern int errno; #define DEFAULT_TMPDIR "." /* bogus default, should be changed */ #define DEFAULT_NAMEROOT "shtmp" -extern int dollar_dollar_pid; +extern pid_t dollar_dollar_pid; static char *sys_tmpdir = (char *)NULL; static int ntmpfiles; @@ -59,6 +59,12 @@ get_sys_tmpdir () if (sys_tmpdir) return sys_tmpdir; +#ifdef P_tmpdir + sys_tmpdir = P_tmpdir; + if (stat (sys_tmpdir, &sb) == 0) + return sys_tmpdir; +#endif + sys_tmpdir = "/tmp"; if (stat (sys_tmpdir, &sb) == 0) return sys_tmpdir; @@ -71,11 +77,7 @@ get_sys_tmpdir () if (stat (sys_tmpdir, &sb) == 0) return sys_tmpdir; -#ifdef P_tmpdir - sys_tmpdir = P_tmpdir; -#else sys_tmpdir = DEFAULT_TMPDIR; -#endif return sys_tmpdir; } @@ -105,32 +107,42 @@ sh_mktmpname (nameroot, flags) char *nameroot; int flags; { - char *filename, *tdir; + char *filename, *tdir, *lroot; struct stat sb; int r, tdlen; - filename = xmalloc (PATH_MAX + 1); + filename = (char *)xmalloc (PATH_MAX + 1); tdir = get_tmpdir (flags); tdlen = strlen (tdir); - if (nameroot == 0) - nameroot = DEFAULT_NAMEROOT; + lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; +#ifdef USE_MKTEMP + sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); + if (mktemp (filename) == 0) + { + free (filename); + filename = NULL; + } +#else /* !USE_MKTEMP */ while (1) { - filenum *= (int)time ((time_t *)0) * dollar_dollar_pid * - ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, nameroot, filenum); + filenum = (filenum << 1) ^ + (unsigned long) time ((time_t *)0) ^ + (unsigned long) dollar_dollar_pid ^ + (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); + sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); if (tmpnamelen > 0 && tmpnamelen < 32) filename[tdlen + 1 + tmpnamelen] = '\0'; -#ifdef HAVE_LSTAT +# ifdef HAVE_LSTAT r = lstat (filename, &sb); -#else +# else r = stat (filename, &sb); -#endif +# endif if (r < 0 && errno == ENOENT) break; } +#endif /* !USE_MKTEMP */ return filename; } @@ -141,21 +153,34 @@ sh_mktmpfd (nameroot, flags, namep) int flags; char **namep; { - char *filename, *tdir; + char *filename, *tdir, *lroot; int fd, tdlen; - filename = xmalloc (PATH_MAX + 1); + filename = (char *)xmalloc (PATH_MAX + 1); tdir = get_tmpdir (flags); tdlen = strlen (tdir); - if (nameroot == 0) - nameroot = DEFAULT_NAMEROOT; + lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; +#ifdef USE_MKSTEMP + sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); + fd = mkstemp (filename); + if (fd < 0 || namep == 0) + { + free (filename); + filename = NULL; + } + if (namep) + *namep = filename; + return fd; +#else /* !USE_MKSTEMP */ do { - filenum *= (int)time ((time_t *)0) * dollar_dollar_pid * - ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, nameroot, filenum); + filenum = (filenum << 1) ^ + (unsigned long) time ((time_t *)0) ^ + (unsigned long) dollar_dollar_pid ^ + (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); + sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); if (tmpnamelen > 0 && tmpnamelen < 32) filename[tdlen + 1 + tmpnamelen] = '\0'; fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600); @@ -168,6 +193,7 @@ sh_mktmpfd (nameroot, flags, namep) free (filename); return fd; +#endif /* !USE_MKSTEMP */ } FILE * @@ -177,7 +203,13 @@ sh_mktmpfp (nameroot, flags, namep) char **namep; { int fd; + FILE *fp; fd = sh_mktmpfd (nameroot, flags, namep); - return ((fd >= 0) ? (fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w")) : (FILE *)NULL); + if (fd < 0) + return ((FILE *)NULL); + fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w"); + if (fp == 0) + close (fd); + return fp; } diff --git a/lib/sh/zread.c b/lib/sh/zread.c index 0d5320a..2cdfb4e 100644 --- a/lib/sh/zread.c +++ b/lib/sh/zread.c @@ -36,13 +36,13 @@ extern int errno; /* Read LEN bytes from FD into BUF. Retry the read on EINTR. Any other error causes the loop to break. */ -int +ssize_t zread (fd, buf, len) int fd; char *buf; size_t len; { - int r; + ssize_t r; while ((r = read (fd, buf, len)) < 0 && errno == EINTR) ; @@ -57,13 +57,14 @@ zread (fd, buf, len) #endif #define NUM_INTR 3 -int +ssize_t zread1 (fd, buf, len) int fd; char *buf; size_t len; { - int r, nintr; + ssize_t r; + int nintr; for (nintr = 0; ; ) { @@ -84,25 +85,29 @@ zread1 (fd, buf, len) in read(2). This does some local buffering to avoid many one-character calls to read(2), like those the `read' builtin performs. */ -static unsigned char lbuf[128]; -static int lind, lused; +static char lbuf[128]; +static size_t lind, lused; -int +ssize_t zreadc (fd, cp) int fd; char *cp; { - int r; + ssize_t nr; if (lind == lused || lused == 0) { - lused = zread (fd, lbuf, sizeof (lbuf)); + nr = zread (fd, lbuf, sizeof (lbuf)); lind = 0; - if (lused <= 0) - return (lused); + if (nr <= 0) + { + lused = 0; + return nr; + } + lused = nr; } if (cp) - *cp = (char)lbuf[lind++]; + *cp = lbuf[lind++]; return 1; } @@ -118,7 +123,7 @@ void zsyncfd (fd) int fd; { - int off; + off_t off; off = lused - lind; if (off > 0) diff --git a/lib/sh/zwrite.c b/lib/sh/zwrite.c index d36ca5f..39ffbb1 100644 --- a/lib/sh/zwrite.c +++ b/lib/sh/zwrite.c @@ -36,7 +36,7 @@ extern int errno; int zwrite (fd, buf, nb) int fd; - unsigned char *buf; + char *buf; size_t nb; { int n, i, nt; |