diff --git a/.gitignore b/.gitignore index f222fb9..57ab997 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ calc.1 calc.usage calcerr.c calcerr.h +charbit.h conf.h cscript/.all cscript/4dsphere @@ -43,6 +44,7 @@ have_getpgid.h have_getprid.h have_getsid.h have_gettime.h +have_limits.h have_memmv.h have_newstr.h have_offscl.h diff --git a/CHANGES b/CHANGES index a5d8485..f072808 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,11 @@ The following are the changes from calc version 2.14.0.11 to date: Fixed how Makefile variable SHELL is set on macOS vs. linux. Using /bin/sh on macOS due to how zsh treats globs by default. + Added charbit.h to define CALC_CHARBIT which is either CHAR_BIT + from or 8 or a value set by the Makefile variable + CALC_CHARBIT. Added have_limits.h to determine if + is a system include file. + The following are the changes from calc version 2.14.0.9 to 2.14.0.10: diff --git a/Makefile b/Makefile index 55fefb4..101f40d 100644 --- a/Makefile +++ b/Makefile @@ -464,6 +464,10 @@ endian_calc.h: ${Q} ${MAKE} ${XARG} -f ${MAKE_FILE} $@ ${XVAR} ${V} echo '=-=-=-=-= private Makefile $@ rule end =-=-=-=-=' +charbit.h: + ${V} echo '=-=-=-=-= private Makefile $@ rule start =-=-=-=-=' + ${Q} ${MAKE} ${XARG} -f ${MAKE_FILE} $@ ${XVAR} + longbits.h: ${V} echo '=-=-=-=-= private Makefile $@ rule start =-=-=-=-=' ${Q} ${MAKE} ${XARG} -f ${MAKE_FILE} $@ ${XVAR} diff --git a/Makefile.ship b/Makefile.ship index 5c22ab3..9520e9c 100644 --- a/Makefile.ship +++ b/Makefile.ship @@ -223,6 +223,19 @@ CALC_BYTE_ORDER= #CALC_BYTE_ORDER= -DBIG_ENDIAN #CALC_BYTE_ORDER= -DLITTLE_ENDIAN +# Determine the number of bits in a byte +# +# If in doubt, leave CALC_CHARBIT empty. This Makefile will run +# the charbits program to determine the length. +# +# In order to avoid make brain damage in some systems, we avoid placing +# a space after the ='s below. +# +# Select CALC_CHARBIT= 8 for DJGPP. +# +CALC_CHARBIT= +#CALC_CHARBIT= 8 + # Determine the number of bits in a long # # If in doubt, leave LONG_BITS empty. This Makefile will run @@ -659,6 +672,20 @@ HAVE_UNISTD_H= #HAVE_UNISTD_H= YES #HAVE_UNISTD_H= NO +# Determine if we have the include file. +# +# HAVE_LIMITS_H= let the Makefile look for the include file +# HAVE_LIMITS_H= YES assume that the include file exists +# HAVE_LIMITS_H= NO assume that the include file does not exist +# +# Select HAVE_LIMITS_H= YES for DJGPP. +# +# When in doubt, leave HAVE_LIMITS_H empty. +# +HAVE_LIMITS_H= +#HAVE_LIMITS_H= YES +#HAVE_LIMITS_H= NO + # Determine if our compiler allows the unused attribute # # If HAVE_UNUSED is empty, this Makefile will run the have_unused program @@ -1945,7 +1972,8 @@ BUILD_H_SRC= align32.h args.h calcerr.h conf.h endian_calc.h \ have_posscl.h have_rusage.h have_stdlib.h have_strdup.h \ have_string.h have_strlcat.h have_strlcpy.h have_times.h \ have_uid_t.h have_unistd.h have_unused.h have_urandom.h \ - have_ustat.h longbits.h terminal.h have_environ.h have_arc4random.h + have_ustat.h longbits.h terminal.h have_environ.h \ + have_arc4random.h have_limits.h charbit.h # we build these .c files during the make # @@ -1961,7 +1989,7 @@ UTIL_C_SRC= align32.c endian.c longbits.c have_newstr.c have_uid_t.c \ have_ustat.c have_getsid.c have_getpgid.c have_environ.c \ have_gettime.c have_getprid.c have_rusage.c have_strdup.c \ have_unused.c have_ban_pragma.c have_strlcpy.c have_strlcat.c \ - have_arc4random.c + have_arc4random.c charbit.c # these awk and sed tools are used in the process of building BUILD_H_SRC # and BUILD_C_SRC @@ -1979,7 +2007,7 @@ UTIL_OBJS= endian.o longbits.o have_newstr.o have_uid_t.o \ have_ustat.o have_getsid.o have_getpgid.o have_environ.o \ have_gettime.o have_getprid.o ver_calc.o have_rusage.o have_strdup.o \ have_unused.o have_ban_pragma.o have_strlcpy.o have_strlcat.o \ - have_arc4random.o + have_arc4random.o charbit.o # these temp files may be created (and removed) during the build of BUILD_C_SRC # @@ -1997,7 +2025,8 @@ UTIL_PROGS= align32${EXT} fposval${EXT} have_uid_t${EXT} have_const${EXT} \ ver_calc${EXT} have_strdup${EXT} have_environ{EXT} \ have_unused${EXT} have_fpos${EXT} have_fpos_pos${EXT} \ have_offscl${EXT} have_rusage${EXT} have_ban_pragma${EXT} \ - have_strlcpy${EXT} have_strlcat${EXT} have_arc4random${EXT} + have_strlcpy${EXT} have_strlcat${EXT} have_arc4random${EXT} \ + charbit${EXT} # these utility files and scripts may be created in the process of building # the BUILD_H_SRC file set @@ -2673,7 +2702,43 @@ endian_calc.h: endian.c have_stdlib.h have_unistd.h \ ${TRUE}; \ fi -longbits.h: longbits.c have_unistd.h have_stdlib.h \ +charbit.h: charbit.c have_limits.h \ + banned.h have_ban_pragma.h ${MAKE_FILE} ${LOC_MKF} + ${Q} ${RM} -f charbit.o charbit${EXT} $@ + ${H} echo 'forming $@' + ${Q} echo '/*' > $@ + ${Q} echo ' * DO NOT EDIT -- generated by the Makefile' >> $@ + ${Q} echo ' */' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '#if !defined(CALC_CHARBIT_H)' >> $@ + ${Q} echo '#define CALC_CHARBIT_H' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + -@if [ -z ${CALC_CHARBIT} ]; then \ + ${LCC} ${ICFLAGS} charbit.c -c ${S}; \ + ${LCC} ${ILDFLAGS} charbit.o -o charbit${EXT} ${S}; \ + ./charbit${EXT} >> $@ ${E}; \ + else \ + echo '#define CALC_CHARBIT ${CALC_CHARBIT} ' \ + '/* set by Makefile.ship */' >> $@; \ + fi + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '#endif /* !CALC_CHARBIT_H */' >> $@ + ${H} echo '$@ formed' + ${Q} ${RM} -f charbit.o charbit${EXT} + -@if [ -z "${Q}" ]; then \ + echo ''; \ + echo '=-=-= start of $@ =-=-='; \ + ${CAT} $@; \ + echo '=-=-= end of $@ =-=-='; \ + echo ''; \ + else \ + ${TRUE}; \ + fi + +longbits.h: longbits.c charbit.h have_unistd.h have_stdlib.h \ banned.h have_ban_pragma.h ${MAKE_FILE} ${LOC_MKF} ${Q} ${RM} -f longbits.o longbits${EXT} $@ ${H} echo 'forming $@' @@ -2842,6 +2907,42 @@ have_unistd.h: ${MAKE_FILE} ${LOC_MKF} ${TRUE}; \ fi +have_limits.h: ${MAKE_FILE} ${LOC_MKF} + ${Q} ${RM} -f $@ + ${H} echo 'forming $@' + ${Q} echo '/*' > $@ + ${Q} echo ' * DO NOT EDIT -- generated by the Makefile' >> $@ + ${Q} echo ' */' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '#if !defined(CALC_HAVE_LIMITS_H)' >> $@ + ${Q} echo '#define CALC_HAVE_LIMITS_H' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '/* do we have ? */' >> $@ + -${Q} if [ X"${HAVE_LIMITS_H}" = X"YES" ]; then \ + echo '#define HAVE_LIMITS_H /* yes */' >> $@; \ + elif [ X"${HAVE_LIMITS_H}" = X"NO" ]; then \ + echo '#undef HAVE_LIMITS_H /* no */' >> $@; \ + elif echo '#include ' | ${CC} -E - ${S}; then \ + echo '#define HAVE_LIMITS_H /* yes */' >> $@; \ + else \ + echo '#undef HAVE_LIMITS_H /* no */' >> $@; \ + fi + ${Q} echo '' >> $@ + ${Q} echo '' >> $@ + ${Q} echo '#endif /* !CALC_HAVE_LIMITS_H */' >> $@ + ${H} echo '$@ formed' + -@if [ -z "${Q}" ]; then \ + echo ''; \ + echo '=-=-= start of $@ =-=-='; \ + ${CAT} $@; \ + echo '=-=-= end of $@ =-=-='; \ + echo ''; \ + else \ + ${TRUE}; \ + fi + have_string.h: ${MAKE_FILE} ${LOC_MKF} ${Q} ${RM} -f $@ ${H} echo 'forming $@' @@ -4298,7 +4399,7 @@ version: ver_calc${EXT}: version.c strl.c have_string.h have_const.h have_newstr.h \ have_strlcpy.h have_memmv.h have_strlcat.h endian_calc.h longbits.h \ - have_unused.h + have_unused.h charbit.h ${RM} -f $@ ${LCC} ${ICFLAGS} -DCALC_VER ${ILDFLAGS} version.c strl.c -o $@ @@ -4551,6 +4652,7 @@ env: @echo 'HAVE_GETRUSAGE=${HAVE_GETRUSAGE}'; echo '' @echo 'HAVE_GETSID=${HAVE_GETSID}'; echo '' @echo 'HAVE_GETTIME=${HAVE_GETTIME}'; echo '' + @echo 'HAVE_LIMITS_H=${HAVE_LIMITS_H}'; echo '' @echo 'HAVE_MEMMOVE=${HAVE_MEMMOVE}'; echo '' @echo 'HAVE_NEWSTR=${HAVE_NEWSTR}'; echo '' @echo 'HAVE_OFFSCL=${HAVE_OFFSCL}'; echo '' @@ -5655,6 +5757,10 @@ calcerr.o: calcerr.c calcerr.o: calcerr.h calcerr.o: have_ban_pragma.h calcerr.o: have_const.h +charbit.o: banned.h +charbit.o: charbit.c +charbit.o: have_ban_pragma.h +charbit.o: have_limits.h codegen.o: alloc.h codegen.o: banned.h codegen.o: block.h @@ -6226,7 +6332,9 @@ listfunc.o: value.h listfunc.o: zmath.h listfunc.o: zrand.h longbits.o: banned.h +longbits.o: charbit.h longbits.o: have_ban_pragma.h +longbits.o: have_limits.h longbits.o: have_stdlib.h longbits.o: have_unistd.h longbits.o: longbits.c diff --git a/charbit.c b/charbit.c new file mode 100644 index 0000000..7d593ad --- /dev/null +++ b/charbit.c @@ -0,0 +1,67 @@ +/* + * charbit - determine what CHAR_BIT is and define CALC_CHARBIT + * + * Copyright (C) 2021 Landon Curt Noll + * + * Calc is open software; you can redistribute it and/or modify it under + * the terms of the version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * Calc 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 Lesser General + * Public License for more details. + * + * A copy of version 2.1 of the GNU Lesser General Public License is + * distributed with calc under the filename COPYING-LGPL. You should have + * received a copy with calc; if not, write to Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Under source code control: 2021/12/07 20:57:50 + * File existed as early as: 2021 + * + * chongo /\oo/\ http://www.isthe.com/chongo/ + * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ + */ + +/* + * usage: + * charbit + * + * This prog outputs several defines: + * + * CALC_CHARBIT + * after including have_limits.h and perhaps , + * output CALC_CHARBIT as CHAR_BIT (from , or as 8. + */ + +#include +#include "have_limits.h" +#if defined(HAVE_LIMITS_H) +#include +#endif + + +#include "banned.h" /* include after system header <> includes */ + + +int +main(void) +{ + printf("#include \"have_limits.h\"\n"); + printf("#if defined(HAVE_LIMITS_H)\n"); + printf("#include \n"); + printf("#endif\n\n"); +#if defined(CHAR_BIT) + + printf("#define CALC_CHARBIT (CHAR_BIT) /* from */\n"); + +#else /* CHAR_BIT */ + + printf("#define CALC_CHARBIT (8) /* no CHAR_BIT, assume 8 */\n"); + +#endif /* CHAR_BIT */ + + /* exit(0); */ + return 0; +} diff --git a/longbits.c b/longbits.c index b78bdd8..1297f9a 100644 --- a/longbits.c +++ b/longbits.c @@ -92,6 +92,8 @@ # include #endif +#include "charbit.h" + #include "banned.h" /* include after system header <> includes */ @@ -118,7 +120,7 @@ main(int argc, char **argv) /* ignore empty or leading space args */ if (argv[1][0] == '\0' || (isascii((int)argv[1][0]) && isspace((int)argv[1][0]))) { - long_bits = sizeof(long)*8; + long_bits = sizeof(long)*CALC_CHARBIT; /* process the forced size arg */ } else { forced_size = 1; diff --git a/seed.c b/seed.c index 79f5e9f..e09f5ee 100644 --- a/seed.c +++ b/seed.c @@ -80,7 +80,8 @@ #endif #if defined(HAVE_STDLIB_H) # include -# define RANDOM_CNT (16) /* random() call repeat count */ +/* NOTE: RANDOM_CNT should remain 32 to circular shift 31-bit returns */ +# define RANDOM_CNT (32) /* random() call repeat and circular shift */ # define INITSTATE_SIZE (256) /* initstate pool size */ #endif #include @@ -464,6 +465,7 @@ pseudo_seed(void) /**/ #if defined(HAVE_STDLIB_H) + unsigned long tmp; /* temp holder of 31-bit random() */ unsigned past_hash; /* prev hash or xor-folded prev hash */ long random_before[RANDOM_CNT]; /* random() pre initstate() */ char *initstate_ret; /* return from initstate() call */ @@ -642,9 +644,10 @@ pseudo_seed(void) /* classic 31-bit random seeded with time of day, count, prev hash */ srandom((unsigned)(sdata.time) ^ (unsigned)call_count ^ past_hash); - for (j=0; j < RANDOM_CNT; j += 2) { - random_before[j] = random(); - random_before[j+1] = (random() << 1); + for (j=0; j < RANDOM_CNT; ++j) { + tmp = random(); /* 31-bit value */ + /* we 32-bit circular shift to spread 31-bit returns around */ + random_before[j] = (tmp << j) | (tmp >> (RANDOM_CNT-j)); } /* initialize random state with the FNV hash of sdata */ @@ -659,9 +662,10 @@ pseudo_seed(void) #endif /* HAVE_B64 */ /* use 31-bit random some more with the new random state */ - for (j=0; j < RANDOM_CNT; j += 2) { - random_after[j] = random(); - random_after[j+1] = (random() << 1); + for (j=0; j < RANDOM_CNT; ++j) { + tmp = random(); /* 31-bit value */ + /* we 32-bit circular shift to spread 31-bit returns around */ + random_after[j] = (tmp << j) | (tmp >> (RANDOM_CNT-j)); } /* restore previous state */ diff --git a/win32.mkdef b/win32.mkdef index 4106ad7..f1972e0 100644 --- a/win32.mkdef +++ b/win32.mkdef @@ -1,6 +1,7 @@ TERMCONTROL=-DUSE_WIN32 HAVE_VSNPRINTF=-UDONT_HAVE_VSNPRINTF BYTE_ORDER=-DLITTLE_ENDIAN +CALC_CHARBIT=8 LONG_BITS=32 HAVE_FPOS=-DHAVE_NO_FPOS HAVE_FPOS_POS=-DHAVE_NO_FPOS_POS @@ -32,6 +33,7 @@ HAVE_SYS_TIMES_H=NO HAVE_TIME_H=YES HAVE_SYS_TIME_H=NO HAVE_UNISTD_H=NO +HAVE_LIMITS_H=YES HAVE_ENVIRON=-DHAVE_NO_ENVIRON HAVE_ARC4RANDOM=-DHAVE_NO_ARC4RANDOM