diff --git a/CHANGES b/CHANGES index b12d24d..bb23973 100644 --- a/CHANGES +++ b/CHANGES @@ -118,6 +118,21 @@ Following is the change from calc version 2.11.0t7 to date: Converted start_done into a general calc run state enum called run_state within the calc source. + Removed README.OLD. + + Added the Makefile variable ${LCC} to invoke the local c compiler. + By default, ${CC} also run the ${LCC} compiler. The distinction is + useful when using something such as purify. In the case of ${LCC}, + only the local C compiler is invoked. In the case of ${CC} a purify + compile is invoked. Only the source that must be compiled and run + on the local machine use ${LCC}; everything else uses ${CC}. + + Fixed memory buffer ovreread problem in eatstring() in token.c. + + Fixed memory leaks related to putenv(). + + Fixed memory leaks realted to srandom(). + Misc calc man page fixes. diff --git a/Makefile b/Makefile index 33106ba..7f98db3 100644 --- a/Makefile +++ b/Makefile @@ -352,7 +352,7 @@ CALCPAGER= more #CALCPAGER= cat #CALCPAGER= less -# Debug/Optimize options for ${CC} +# Debug/Optimize options for ${CC} and ${LCC} # #DEBUG= -O #DEBUG= -O -g @@ -393,7 +393,7 @@ NO_SHARED= #NO_SHARED= -non_shared # On some systems where you are disabling dynamic shared libs, you may -# need to pass a special flag to ${CC} during linking stage. +# need to pass a special flag to ${CC} and ${LCC} during linking stage. # # System type NO_SHARED recommendation # @@ -522,7 +522,8 @@ ALLOW_CUSTOM= -DCUSTOM # LDFLAGS are flags given to ${CC} for linking .o files # ILDFLAGS are flags given to ${CC} for linking .o files for intermediate progs # -# CC is how the the C compiler is invoked +# LCC how the the C compiler is invoked on locally executed intermediate progs +# CC is how the the C compiler is invoked (with an optional Purify) # ### # @@ -546,7 +547,8 @@ LCFLAGS= LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} ILDFLAGS= # -CC= ${PURIFY} gcc +LCC= gcc +CC= ${PURIFY} ${LCC} # ### # @@ -568,8 +570,9 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} gcc -#CC= ${PURIFY} gcc2 +#LCC= gcc +#LCC= gcc2 +#CC= ${PURIFY} ${LCC} # ### # @@ -588,7 +591,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc +#LCC= cc +#CC= ${PURIFY} ${LCC} # ### # @@ -619,7 +623,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc -n32 -xansi +#LCC= cc -n32 -xansi +#CC= ${PURIFY} ${LCC} # ### # @@ -644,7 +649,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc +#LCC= cc +#CC= ${PURIFY} ${LCC} # ### # @@ -663,7 +669,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc +#LCC= cc +#CC= ${PURIFY} ${LCC} # ### # @@ -688,7 +695,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc +#LCC= cc +#CC= ${PURIFY} ${LCC} # ### # @@ -710,7 +718,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} gcc +#LCC= gcc +#CC= ${PURIFY} ${LCC} # ### # @@ -732,7 +741,8 @@ CC= ${PURIFY} gcc #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #ILDFLAGS= # -#CC= ${PURIFY} cc +#LCC= cc +#CC= ${PURIFY} ${LCC} ############################################################################## #-=-=-=-=-=-=-=-=- Be careful if you change something below -=-=-=-=-=-=-=-=-# @@ -887,6 +897,7 @@ CUSTOM_PASSDOWN= Q="${Q}" \ LCFLAGS="${LCFLAGS}" \ LDFLAGS="${LDFLAGS}" \ ILDFLAGS="${ILDFLAGS}" \ + LCC="${LCC}" \ CC="${CC}" \ MAKE_FILE=${MAKE_FILE} \ SED=${SED} \ @@ -914,6 +925,7 @@ SAMPLE_PASSDOWN= Q="${Q}" \ LDFLAGS="${LDFLAGS}" \ ILDFLAGS="${ILDFLAGS}" \ CALC_LIBS="../libcalc.a ../custom/libcustcalc.a" \ + LCC="${LCC}" \ CC="${CC}" \ MAKE_FILE=${MAKE_FILE} \ SED=${SED} \ @@ -931,7 +943,7 @@ C_SRC= ${LIBSRC} ${CALCSRC} ${UTIL_C_SRC} # These files are found (but not built) in the distribution # DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} BUGS CHANGES LIBRARY README \ - calc.man lint.sed README.OLD HOWTO.INSTALL ${UTIL_MISC_SRC} + calc.man lint.sed HOWTO.INSTALL ${UTIL_MISC_SRC} # complete list of .o files # @@ -1379,8 +1391,8 @@ longlong.h: longlong.c have_stdlib.h have_string.h ${MAKE_FILE} ${Q}echo '' >> longlong.h ${Q}echo '/* do we have/want to use a long long type? */' >> longlong.h -${Q}rm -f longlong.o longlong - -${Q}${CC} ${CCMAIN} longlong.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} longlong.o -o longlong 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} longlong.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} longlong.o -o longlong 2>/dev/null; true -${Q}${SHELL} -c "./longlong ${LONGLONG_BITS} > ll_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s ll_tmp ]; then \ @@ -1418,8 +1430,8 @@ have_fpos.h: have_fpos.c ${MAKE_FILE} ${Q}echo '' >> have_fpos.h ${Q}echo '/* do we have fgetpos & fsetpos functions? */' >> have_fpos.h -${Q}rm -f have_fpos.o have_fpos - -${Q}${CC} ${HAVE_FPOS} ${CCMAIN} have_fpos.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_fpos.o -o have_fpos 2>/dev/null; true + -${Q}${LCC} ${HAVE_FPOS} ${CCMAIN} have_fpos.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_fpos.o -o have_fpos 2>/dev/null; true -${Q}${SHELL} -c "./have_fpos > fpos_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s fpos_tmp ]; then \ @@ -1459,8 +1471,8 @@ fposval.h: fposval.c have_fpos.h have_offscl.h have_posscl.h \ ${Q}echo '' >> fposval.h ${Q}echo '/* what are our file position & size types? */' >> fposval.h -${Q}rm -f fposval.o fposval - -${Q}${CC} ${CCMAIN} fposval.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} fposval.o -o fposval 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} fposval.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} fposval.o -o fposval 2>/dev/null; true ${Q}${SHELL} -c "./fposval fposv_tmp >> fposval.h 2>/dev/null" \ >/dev/null 2>&1; true ${Q}echo '' >> fposval.h @@ -1492,8 +1504,8 @@ have_const.h: have_const.c ${MAKE_FILE} ${Q}echo '' >> have_const.h ${Q}echo '/* do we have or want const? */' >> have_const.h -${Q}rm -f have_const.o have_const - -${Q}${CC} ${CCMAIN} ${HAVE_CONST} have_const.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_const.o -o have_const 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_CONST} have_const.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_const.o -o have_const 2>/dev/null; true -${Q}${SHELL} -c "./have_const > const_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s const_tmp ]; then \ @@ -1531,8 +1543,8 @@ have_offscl.h: have_offscl.c ${MAKE_FILE} ${Q}echo '' >> have_offscl.h ${Q}echo '' >> have_offscl.h -${Q}rm -f have_offscl.o have_offscl - -${Q}${CC} ${CCMAIN} ${HAVE_OFFSCL} have_offscl.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_offscl.o -o have_offscl 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_OFFSCL} have_offscl.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_offscl.o -o have_offscl 2>/dev/null; true -${Q}${SHELL} -c "./have_offscl > offscl_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s offscl_tmp ]; then \ @@ -1569,8 +1581,8 @@ have_posscl.h: have_posscl.c have_fpos.h ${MAKE_FILE} ${Q}echo '' >> have_posscl.h ${Q}echo '' >> have_posscl.h -${Q}rm -f have_posscl.o have_posscl - -${Q}${CC} ${CCMAIN} ${HAVE_POSSCL} have_posscl.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_posscl.o -o have_posscl 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_POSSCL} have_posscl.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_posscl.o -o have_posscl 2>/dev/null; true -${Q}${SHELL} -c "./have_posscl > posscl_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s posscl_tmp ]; then \ @@ -1621,8 +1633,8 @@ align32.h: align32.c longbits.h have_unistd.h ${MAKE_FILE} fi -${Q}if [ X = X${ALIGN32} ]; then \ rm -f align32.o align32; \ - ${CC} ${CCMAIN} ${ALIGN32} align32.c -c 2>/dev/null; \ - ${CC} ${ILDFLAGS} align32.o -o align32 2>/dev/null; \ + ${LCC} ${CCMAIN} ${ALIGN32} align32.c -c 2>/dev/null; \ + ${LCC} ${ILDFLAGS} align32.o -o align32 2>/dev/null; \ ${SHELL} -c "./align32 >align32_tmp 2>/dev/null" >/dev/null 2>&1; \ if [ -s align32_tmp ]; then \ cat align32_tmp >> align32.h; \ @@ -1662,8 +1674,8 @@ have_uid_t.h: have_uid_t.c have_unistd.h ${MAKE_FILE} ${Q}echo '' >> have_uid_t.h ${Q}echo '/* do we have or want uid_t? */' >> have_uid_t.h -${Q}rm -f have_uid_t.o have_uid_t - -${Q}${CC} ${CCMAIN} ${HAVE_UID_T} have_uid_t.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_uid_t.o -o have_uid_t 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_UID_T} have_uid_t.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_uid_t.o -o have_uid_t 2>/dev/null; true -${Q}${SHELL} -c "./have_uid_t > uid_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s uid_tmp ]; then \ @@ -1701,8 +1713,8 @@ have_newstr.h: have_newstr.c ${MAKE_FILE} ${Q}echo '/* do we have or want memcpy(), memset() & strchr()? */' \ >> have_newstr.h -${Q}rm -f have_newstr.o have_newstr - -${Q}${CC} ${CCMAIN} ${HAVE_NEWSTR} have_newstr.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_newstr.o -o have_newstr 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_NEWSTR} have_newstr.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_newstr.o -o have_newstr 2>/dev/null; true -${Q}${SHELL} -c "./have_newstr > newstr_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s newstr_tmp ]; then \ @@ -1739,8 +1751,8 @@ have_memmv.h: have_memmv.c ${MAKE_FILE} ${Q}echo '' >> have_memmv.h ${Q}echo '/* do we have or want memmove()? */' >> have_memmv.h -${Q}rm -f have_memmv.o have_memmv - -${Q}${CC} ${CCMAIN} ${HAVE_MEMMOVE} have_memmv.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_memmv.o -o have_memmv 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_MEMMOVE} have_memmv.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_memmv.o -o have_memmv 2>/dev/null; true -${Q}${SHELL} -c "./have_memmv > newstr_tmp 2>/dev/null" \ >/dev/null 2>&1; true -${Q}if [ -s newstr_tmp ]; then \ @@ -1776,8 +1788,8 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h ${Q}echo '' >> args.h ${Q}echo '' >> args.h -${Q}rm -f have_stdvs.o have_stdvs - -${Q}${CC} ${CCMAIN} ${HAVE_VSPRINTF} have_stdvs.c -c 2>/dev/null; true - -${Q}${CC} ${ILDFLAGS} have_stdvs.o -o have_stdvs 2>/dev/null; true + -${Q}${LCC} ${CCMAIN} ${HAVE_VSPRINTF} have_stdvs.c -c 2>/dev/null; true + -${Q}${LCC} ${ILDFLAGS} have_stdvs.o -o have_stdvs 2>/dev/null; true -${Q}if ./have_stdvs >>args.h 2>/dev/null; then \ touch have_args; \ else \ @@ -1785,8 +1797,8 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h fi -${Q}if [ ! -f have_args ] && [ X"${HAVE_VSPRINTF}" = X ]; then \ rm -f have_stdvs.o have_stdvs have_varvs.o have_varvs; \ - ${CC} ${CCMAIN} -DDONT_HAVE_VSPRINTF have_varvs.c -c 2>/dev/null; \ - ${CC} ${ILDFLAGS} have_varvs.o -o have_varvs 2>/dev/null; \ + ${LCC} ${CCMAIN} -DDONT_HAVE_VSPRINTF have_varvs.c -c 2>/dev/null; \ + ${LCC} ${ILDFLAGS} have_varvs.o -o have_varvs 2>/dev/null; \ if ./have_varvs >>args.h 2>/dev/null; then \ touch have_args; \ else \ @@ -1865,17 +1877,17 @@ calc_errno.h: calc_errno.c ${MAKE_FILE} echo 'extern int sys_nerr; ' \ '/* number of system errors */' >> calc_errno.h; \ else \ - ${CC} ${CCMAIN} -DTRY_ERRNO_NO_DECL \ + ${LCC} ${CCMAIN} -DTRY_ERRNO_NO_DECL \ calc_errno.c -o calc_errno 2>calc_errno_tmp; \ if [ -x ./calc_errno ]; then \ ./calc_errno >> calc_errno.h; \ else \ - ${CC} ${CCMAIN} -DTRY_ERRNO_STD_DECL \ + ${LCC} ${CCMAIN} -DTRY_ERRNO_STD_DECL \ calc_errno.c -o calc_errno 2>calc_errno_tmp; \ if [ -x ./calc_errno ]; then \ ./calc_errno >> calc_errno.h; \ else \ - ${CC} ${CCMAIN} -DTRY_ERRNO_OLD_DECL \ + ${LCC} ${CCMAIN} -DTRY_ERRNO_OLD_DECL \ calc_errno.c -o calc_errno 2>calc_errno_tmp; \ if [ -x ./calc_errno ]; then \ ./calc_errno >> calc_errno.h; \ @@ -1971,16 +1983,16 @@ calcerr.c: calcerr.tbl calcerr_c.sed calcerr_c.awk ${MAKE_FILE} ## endian.o: endian.c have_unistd.h - ${CC} ${CCMAIN} endian.c -c + ${LCC} ${CCMAIN} endian.c -c endian: endian.o - ${CC} ${ILDFLAGS} endian.o -o endian + ${LCC} ${ILDFLAGS} endian.o -o endian longbits.o: longbits.c longlong.h have_unistd.h - ${CC} ${CCMAIN} longbits.c -c + ${LCC} ${CCMAIN} longbits.c -c longbits: longbits.o - ${CC} ${ILDFLAGS} longbits.o -o longbits + ${LCC} ${ILDFLAGS} longbits.o -o longbits ## # @@ -2336,6 +2348,7 @@ env: @echo "LCFLAGS=${LCFLAGS}"; echo "" @echo "LDFLAGS=${LDFLAGS}"; echo "" @echo "ILDFLAGS=${ILDFLAGS}"; echo "" + @echo "LCC=${LCC}"; echo "" @echo "CC=${CC}"; echo "" @echo "SHELL=${SHELL}"; echo "" @echo "MAKE=${MAKE}"; echo "" diff --git a/README.OLD b/README.OLD deleted file mode 100644 index 0c2fb3b..0000000 --- a/README.OLD +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 1997 David I. Bell -# Permission is granted to use, distribute, or modify this source, -# provided that this copyright notice remains intact. -# -# Arbitrary precision calculator. - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NOTE: This is an old historic README. We recommend that - you read README and HOWTO.INSTALL for more info. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -I am allowing this calculator to be freely distributed for your enjoyment. -Like all multi-precision programs, you should not depend absolutely on -its results, since bugs in such programs can be insidious and only rarely -show up. - --dbell- - -p.s. By Landon Curt Noll: - -Building calc in 3 easy steps: - - 1) Look at the makefile, and adjust it to suit your needs. - - Here are some Makefile hints: - - In the past, some people have had to adjust the VARARG or - TERMCONTROL because the Makefile cannot always guess - correctly for certain systems. You may need to play with - these values if you experience problems. - - The default compiler used is 'cc'. The default compiler flag - is '-O'. If you have gcc, or gcc v2 (or better) you should use - that instead. Some compilers allow for optimization beyond - just -O (gcc v2 has -O2, mips cc has -O3). You should select - the best flag for speed optimization. Calc can be cpu intensive - so selecting a quality compiler and good optimization level can - really pay off. - - 2) build calc: - - make all - - 3) test calc: - - make check - - ==>>>If you run into problems, follow the instructions in the BUGS file<<<== - -=-= - -For further reading: - - LIBRARY - explains how programs can use libcalc.a to take advantage - of the calc multi-precision routines. - - help/todo - current wish list for calc - - CHANGES - recent changes to calc - - BUGS - known bugs, mis-features and how to report problems - - help/full - full set of calc documentation - -=-= - -David I. Bell dbell@auug.org.au -chongo /\../\ diff --git a/calc.h b/calc.h index 6902f74..b295cff 100644 --- a/calc.h +++ b/calc.h @@ -127,7 +127,6 @@ extern long linenumber(void); extern void runrcfiles(void); extern void closeinput(void); - /* * Other routines. */ @@ -141,7 +140,6 @@ extern void libcalc_call_me_first(void); extern void libcalc_call_me_last(void); extern void showerrors(void); - /* * Initialization */ diff --git a/func.c b/func.c index 1e2906c..fa83754 100644 --- a/func.c +++ b/func.c @@ -72,6 +72,7 @@ static int strscan(char *s, int count, VALUE **vals); static int filescan(FILEID id, int count, VALUE **vals); static VALUE f_eval(VALUE *vp); static VALUE f_fsize(VALUE *vp); +static int malloced_putenv(char *str); @@ -87,6 +88,19 @@ extern int idungetc(FILEID id, int ch); extern int stoponerror; +/* + * malloced environment storage + */ +#define ENV_POOL_CHUNK 10 /* env_pool elements to allocate at a time */ +struct env_pool { + char *getenv; /* what getenv() would return, NULL => unused */ + char *putenv; /* pointer given to putenv() */ +}; +static int env_pool_cnt = 0; /* number of env_pool elements in use */ +static int env_pool_max = 0; /* number of env_pool elements allocated */ +static struct env_pool *e_pool = NULL; /* env_pool elements */ + + /* * if HZ & CLK_TCK are not defined, pick typical values, hope for the best */ @@ -5977,8 +5991,7 @@ f_putenv(int count, VALUE **vals) /* return putenv result */ result.v_type = V_NUM; - result.v_num = itoq((long) putenv(putenv_str)); - free(putenv_str); + result.v_num = itoq((long) malloced_putenv(putenv_str)); return result; } @@ -7522,4 +7535,145 @@ showerrors(void) } +/* + * malloced_putenv - Keep track of malloced environment variable storage + * + * given: + * str a malloced string which will be given to putenv + * + * returns: + * putenv() return value + * + * NOTE: The caller MUST pass a string that the caller has previously malloced. + */ +static int +malloced_putenv(char *str) +{ + char *value; /* location of the value part of the str argument */ + char *old_val; /* previously stored (or inherited) env value */ + int found_cnt; /* number of active env_pool entries found */ + struct env_pool *new; /* new e_pool */ + int i; + + /* + * firewall + */ + if (str == NULL) { + math_error("malloced_putenv given a NULL pointer!!"); + /*NOTREACHED*/ + } + if (str[0] == '=') { + math_error("malloced_putenv = is first character in string!!"); + /*NOTREACHED*/ + } + + /* + * determine the place where getenv would return + */ + value = strchr(str, '='); + if (value == NULL) { + math_error("malloced_putenv = not found in string!!"); + /*NOTREACHED*/ + } + ++value; + + /* + * lookup for an existing environment value + */ + *(value-1) = '\0'; + old_val = getenv(str); + *(value-1) = '='; + + /* + * If we have the value in our environment, look for a + * previously malloced string and free it + */ + if (old_val != NULL && env_pool_cnt > 0) { + for (i=0, found_cnt=0; + i < env_pool_max && found_cnt < env_pool_cnt; + ++i) { + + /* skip an unused entry */ + if (e_pool[i].getenv == NULL) { + continue; + } + ++found_cnt; + + /* look for the 1st match */ + if (e_pool[i].getenv == value) { + + /* found match, free the storage */ + if (e_pool[i].putenv != NULL) { + free(e_pool[i].putenv); + } + e_pool[i].getenv = NULL; + --env_pool_cnt; + break; + } + } + } + + /* + * ensure that we have room in the e_pool + */ + if (env_pool_max == 0) { + + /* allocate an initial pool (with one extra guard value) */ + new = (struct env_pool *)malloc((ENV_POOL_CHUNK+1) * + sizeof(struct env_pool)); + if (new == NULL) { + math_error("malloced_putenv malloc failed"); + /*NOTREACHED*/ + } + e_pool = new; + env_pool_max = ENV_POOL_CHUNK; + for (i=0; i <= ENV_POOL_CHUNK; ++i) { + e_pool[i].getenv = NULL; + } + + } else if (env_pool_cnt >= env_pool_max) { + + /* expand the current pool (with one extra guard value) */ + new = (struct env_pool *)realloc(e_pool, + (env_pool_max+ENV_POOL_CHUNK+1) * + sizeof(struct env_pool)); + if (new == NULL) { + math_error("malloced_putenv realloc failed"); + /*NOTREACHED*/ + } + e_pool = new; + for (i=env_pool_max; i <= env_pool_max + ENV_POOL_CHUNK; ++i) { + e_pool[i].getenv = NULL; + } + env_pool_max += ENV_POOL_CHUNK; + } + + /* + * store our data into the first e_pool entry + */ + for (i=0; i < env_pool_max; ++i) { + + /* skip used entries */ + if (e_pool[i].getenv != NULL) { + continue; + } + + /* store in this free entry and stop looping */ + e_pool[i].getenv = value; + e_pool[i].putenv = str; + ++env_pool_cnt; + break; + } + if (i >= env_pool_max) { + math_error("malloced_putenv missed unused entry!!"); + /*NOTREACHED*/ + } + + /* + * finally, do the putenv action + */ + return putenv(str); +} + + #endif /* FUNCLIST */ diff --git a/lib/regress.cal b/lib/regress.cal index 9c11ac7..cb86e4f 100644 --- a/lib/regress.cal +++ b/lib/regress.cal @@ -4223,7 +4223,7 @@ define test_random() /* test range interface some more */ tmp = srandom(state1); - print '5369: tmp = srandom(0)'; + print '5369: tmp = srandom(state1)'; vrfy(random(-46,46) == -0x7, '5370: random(-46,46) == -0x7'); vrfy(random(21701,23209) == 23061, '5371: random(21701,23209) == 23061'); diff --git a/string.c b/string.c index 9047e08..f5895f1 100644 --- a/string.c +++ b/string.c @@ -1142,7 +1142,7 @@ initstrings(void) /* * addstring is called only from token.c - * When called, len is length if string including '\0' + * When called, len is length of string including '\0' */ long addstring(char *str, long len) diff --git a/token.c b/token.c index 98ab8c7..a6ce6bb 100644 --- a/token.c +++ b/token.c @@ -458,6 +458,7 @@ eatstring(int quotechar) } memcpy(str + totlen, buf, len); totlen += len; + len = 0; } } curtoken.t_strindex = addstring(str, totlen + len); diff --git a/version.c b/version.c index 9765d67..c5b1c9e 100644 --- a/version.c +++ b/version.c @@ -12,7 +12,7 @@ #define MAJOR_VER 2 /* major version */ #define MINOR_VER 11 /* minor version */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */ -#define MINOR_PATCH "7.2" /* test number or empty string if no patch */ +#define MINOR_PATCH "7.3" /* test number or empty string if no patch */ /* * calc version constants diff --git a/zrandom.c b/zrandom.c index 3249b55..8191e44 100644 --- a/zrandom.c +++ b/zrandom.c @@ -1571,6 +1571,12 @@ static RANDOM random_pregen[BLUM_PREGEN] = { }; +/* + * forward static declarations + */ +static void zfree_random(ZVALUE z); + + /* * zsrandom1 - seed the Blum generator 1 arg style * @@ -1647,7 +1653,7 @@ zsrandom1(CONST ZVALUE seed, BOOL need_ret) do { /* free temp storage */ if (last_r.v != NULL) { - zfree(last_r); + zfree_random(last_r); } /* @@ -1657,10 +1663,10 @@ zsrandom1(CONST ZVALUE seed, BOOL need_ret) last_r = r; zsquaremod(last_r, blum.n, &r); } while (zrel(r, last_r) > 0); - zfree(blum.r); + zfree_random(blum.r); blum.r = r; /* free temp storage */ - zfree(last_r); + zfree_random(last_r); /* * reserved seed @@ -1741,7 +1747,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn) math_error("srandom small newn must be [1,20]"); /*NOTREACHED*/ } - zfree(blum.n); + zfree_random(blum.n); zcopy(random_pregen[set-1].n, &blum.n); blum.loglogn = random_pregen[set-1].loglogn; blum.mask = random_pregen[set-1].mask; @@ -1750,7 +1756,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn) * reset initial seed as well if seed is 0 */ if (ziszero(seed)) { - zfree(blum.r); + zfree_random(blum.r); zcopy(random_pregen[set-1].r, &blum.r); /* @@ -1785,7 +1791,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn) * of two primes. */ /* load modulus */ - zfree(blum.n); + zfree_random(blum.n); zcopy(newn, &blum.n); /* @@ -1894,11 +1900,11 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials) /* * form the Blum modulus */ - zfree(blum.n); + zfree_random(blum.n); zmul(p, q, &blum.n); /* free temp storage */ - zfree(p); - zfree(q); + zfree_random(p); + zfree_random(q); /* * form the loglogn and mask @@ -2045,7 +2051,7 @@ zrandomskip(long cnt) /* turn the Blum-Blum-Shub crank */ zsquaremod(blum.r, blum.n, &new_r); - zfree(blum.r); + zfree_random(blum.r); blum.r = new_r; cnt -= blum.loglogn; } @@ -2057,7 +2063,7 @@ zrandomskip(long cnt) /* turn the Blum-Blum-Shub crank */ zsquaremod(blum.r, blum.n, &new_r); - zfree(blum.r); + zfree_random(blum.r); blum.r = new_r; /* fill the buffer with the unused bits */ @@ -2197,7 +2203,7 @@ zrandom(long cnt, ZVALUE *res) * turn the Blum-Blum-Shub crank */ zsquaremod(blum.r, blum.n, &new_r); - zfree(blum.r); + zfree_random(blum.r); blum.r = new_r; /* peal off the bottom loglogn bits */ blum.buffer = (blum.r.v[0] & mask); @@ -2228,7 +2234,7 @@ zrandom(long cnt, ZVALUE *res) */ /* turn the Blum-Blum-Shub crank */ zsquaremod(blum.r, blum.n, &new_r); - zfree(blum.r); + zfree_random(blum.r); blum.r = new_r; /* peal off the bottom loglogn bits */ blum.buffer = (blum.r.v[0] & mask); @@ -2282,13 +2288,13 @@ zrandomrange(CONST ZVALUE low, CONST ZVALUE high, ZVALUE *res) */ zsub(high, low, &range); if (zisone(range)) { - zfree(range); + zfree_random(range); *res = low; return; } zsub(range, _one_, &rangem1); bitlen = 1+zhighbit(rangem1); - zfree(rangem1); + zfree_random(rangem1); /* * generate a random value between [0, diff) @@ -2302,7 +2308,7 @@ zrandomrange(CONST ZVALUE low, CONST ZVALUE high, ZVALUE *res) rval.v = NULL; do { if (rval.v != NULL) { - zfree(rval); + zfree_random(rval); } zrandom(bitlen, &rval); } while (zrel(rval, range) >= 0); @@ -2312,8 +2318,8 @@ zrandomrange(CONST ZVALUE low, CONST ZVALUE high, ZVALUE *res) * which is the range [low, high) */ zadd(rval, low, res); - zfree(rval); - zfree(range); + zfree_random(rval); + zfree_random(range); } @@ -2341,8 +2347,8 @@ irandom(long s) itoz(s, &z1); zrandomrange(_zero_, z1, &z2); res = ztoi(z2); - zfree(z1); - zfree(z2); + zfree_random(z1); + zfree_random(z2); return res; } @@ -2377,12 +2383,20 @@ randomcopy(CONST RANDOM *state) if (state->r.v == NULL) { ret->r.v = NULL; } else { - zcopy(state->r, &ret->r); + if (state->r.v == h_rdefvec) { + ret->r.v = state->r.v; + } else { + zcopy(state->r, &ret->r); + } } if (state->n.v == NULL) { ret->n.v = NULL; } else { - zcopy(state->n, &ret->n); + if (state->n.v == h_ndefvec) { + ret->n.v = state->n.v; + } else { + zcopy(state->n, &ret->n); + } } /* @@ -2414,12 +2428,8 @@ randomfree(RANDOM *state) } /* free the values */ - if (state->n.v != h_ndefvec) { - zfree(state->n); - } - if (state->r.v != h_rdefvec) { - zfree(state->r); - } + zfree_random(state->n); + zfree_random(state->r); /* free it if it is not pre-defined */ state->seeded = 0; @@ -2505,9 +2515,43 @@ randomprint(CONST RANDOM *state, int flags) void random_libcalc_cleanup(void) { - /* free if we are seeded now */ - if (blum.seeded) { - randomfree(&blum); + /* free our state - let zfree_random protect the default state */ + randomfree(&blum); + return; +} + + +/* + * zfree_random - perform a zfree if we are not trying to free static data + * + * given: + * z the ZVALUE to zfree(z) if not pointing to static data + */ +static void +zfree_random(ZVALUE z) +{ + if (z.v != h_ndefvec && z.v != h_rdefvec && z.v != h_rdefvec_2 && + z.v != h_nvec01 && z.v != h_rvec01 && + z.v != h_nvec02 && z.v != h_rvec02 && + z.v != h_nvec03 && z.v != h_rvec03 && + z.v != h_nvec04 && z.v != h_rvec04 && + z.v != h_nvec05 && z.v != h_rvec05 && + z.v != h_nvec06 && z.v != h_rvec06 && + z.v != h_nvec07 && z.v != h_rvec07 && + z.v != h_nvec08 && z.v != h_rvec08 && + z.v != h_nvec09 && z.v != h_rvec09 && + z.v != h_nvec10 && z.v != h_rvec10 && + z.v != h_nvec11 && z.v != h_rvec11 && + z.v != h_nvec12 && z.v != h_rvec12 && + z.v != h_nvec13 && z.v != h_rvec13 && + z.v != h_nvec14 && z.v != h_rvec14 && + z.v != h_nvec15 && z.v != h_rvec15 && + z.v != h_nvec16 && z.v != h_rvec16 && + z.v != h_nvec17 && z.v != h_rvec17 && + z.v != h_nvec18 && z.v != h_rvec18 && + z.v != h_nvec19 && z.v != h_rvec19 && + z.v != h_nvec20 && z.v != h_rvec20) { + zfree(z); } return; }