diff --git a/lib-src/libnyquist/nyquist/nyqsrc/add.c b/lib-src/libnyquist/nyquist/nyqsrc/add.c index 24ae7e42a..1a4e284d5 100644 --- a/lib-src/libnyquist/nyquist/nyqsrc/add.c +++ b/lib-src/libnyquist/nyquist/nyqsrc/add.c @@ -565,7 +565,25 @@ D nyquist_printf("add_s_nn_fetch: special return, susp %p\n", susp); /* check if we've seen the logical stop from s2. If so then log_stop_cnt is max of s1 and s2 stop times */ (susp->logical_stop_bits & 2)) { +D nyquist_printf("add_s2_nn_fetch: susp->susp.log_stop_cnt %d\n", + susp->susp.log_stop_cnt); +D nyquist_printf("add_s2_nn_fetch: susp->susp.current %d\n", + susp->susp.current); int to_stop = susp->susp.log_stop_cnt - susp->susp.current; + // to_stop can be less than zero if we've been adding in sounds with + // t0 less than the time when the sound is added. E.g. if the user + // wants a sequence of two sounds that start at 0, the second sound + // will be spliced onto the first because we don't look at it until + // the first finishes -- we cannot go back in time and start adding + // from time 0. This creates a mismatch between the sample count and + // the logical time, so we could actually set a logical stop time that + // is back in history, and therefore before susp.current, resulting + // in a negative to_stop. The problem is really with trying to + // sequence two sounds rather than two behaviors, and a warning has + // already been issued, so we'll just try not to crash here. It's too + // late to compute the correct answer, which would respect t0 of both + // sounds. + if (to_stop < 0) to_stop = 0; if (to_stop < togo) { if (to_stop == 0) { susp->logically_stopped = true; diff --git a/lib-src/libnyquist/nyquist/nyqsrc/falloc.c b/lib-src/libnyquist/nyquist/nyqsrc/falloc.c index 5b1c2edb1..30b51fbde 100644 --- a/lib-src/libnyquist/nyquist/nyqsrc/falloc.c +++ b/lib-src/libnyquist/nyquist/nyqsrc/falloc.c @@ -4,6 +4,7 @@ */ #include +#include #include "xlisp.h" #include "sound.h" #include "falloc.h" @@ -75,7 +76,7 @@ void new_pool(void) poolp = (char *) round_size(((long) poolp)); } -/* new_pool -- allocate a new pool from which mem is allocated */ +/* new_spool -- allocate a new spool from which sample blocks are allocated */ /**/ void new_spool(void) { @@ -165,7 +166,12 @@ char *get_from_pool(size_t siz) #if defined(TRACK_POOLS) && TRACK_POOLS /* falloc_gc -- return empty pools to the system */ -/**/ +/* + * Algorithm: for each pool, move all free sample blocks + * (on the sample_block_free list) to tlist. If tlist + * has ALL of the blocks in the pool (determined by + * byte counts), the pool is returned to the heap. + */ void falloc_gc() { CQUE *lp = NULL; @@ -241,8 +247,18 @@ void falloc_gc() cp = NULL; } else { - if (lp) - lp->qnext = np; + /* lp cannot be null here: On 1st iteration, lp == NULL, but + * cp == pools, so code above is executed. Before the for-loop + * iterates, pools == np (assigned above), and cp == NULL. The + * for-loop update (lp=cp,cp=np) produces lp == NULL, cp == pools. + * Since cp == pools, this else branch will not be taken. + * The other path to this code is via the "continue" above. In that + * case, the update (lp=cp,cp=np) makes lp a valid pointer or else + * the loop exits. + * The assert(lp) is here to possibly make static analyzers happy. + */ + assert(lp); + lp->qnext = np; cp = lp; } } diff --git a/lib-src/libnyquist/nyquist/nyqsrc/sound.c b/lib-src/libnyquist/nyquist/nyqsrc/sound.c index 2cbc07b27..9892d10da 100644 --- a/lib-src/libnyquist/nyquist/nyqsrc/sound.c +++ b/lib-src/libnyquist/nyquist/nyqsrc/sound.c @@ -861,7 +861,8 @@ sample_block_type SND_flush(sound_type snd, long * cnt) { long mycnt; sample_block_type block = SND_get_first(snd, &mycnt); - while (snd->current < 0) { + /* changed from < to <= because we want to read at least the first sample */ + while (snd->current <= 0) { block = SND_get_next(snd, &mycnt); } /* at this point, we've read to and including the block with diff --git a/lib-src/libnyquist/nyquist/xlisp/xlbfun.c b/lib-src/libnyquist/nyquist/xlisp/xlbfun.c index 26b59a2bb..cfdea508a 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlbfun.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlbfun.c @@ -603,6 +603,9 @@ LVAL xcleanup(void) { xllastarg(); xlcleanup(); + /* this point will never be reached because xlcleanup() does a + longjmp(). The return is added to avoid false positive + error messages from static analyzers and compilers */ return (NIL); } @@ -611,7 +614,10 @@ LVAL xtoplevel(void) { xllastarg(); xltoplevel(); - return (NIL); + /* this point will never be reached because xltoplevel() does a + longjmp(). The return is added to avoid false positive + error messages from static analyzers and compilers */ + return (NIL); } /* xcontinue - special form 'continue' */ diff --git a/lib-src/libnyquist/nyquist/xlisp/xlftab.c b/lib-src/libnyquist/nyquist/xlisp/xlftab.c index 074deba1d..07f65170c 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlftab.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlftab.c @@ -62,7 +62,7 @@ extern LVAL xflatsize(void),xflatc(void), xopen(void),xbopen(void),xclose(void),xrdchar(void),xpkchar(void),xwrchar(void),xreadline(void), xrdint(void),xwrint(void),xrdfloat(void),xwrfloat(void), - xload(void),xtranscript(void), + xget_env(void), xload(void),xtranscript(void), xtype(void),xquit(void),xexit(void),xpeek(void),xpoke(void),xaddrs(void), xvector(void),xblock(void),xrtnfrom(void),xtagbody(void), xpsetq(void),xflet(void),xlabels(void),xmacrolet(void),xunwindprotect(void),xpp(void), @@ -485,6 +485,7 @@ FUNDEF funtab[] = { { "GET-TEMP-PATH", S, xget_temp_path }, /* 305 */ { "GET-USER", S, xget_user }, /* 306 */ { "FIND-IN-XLISP-PATH", S, xfind_in_xlisp_path }, /* 307 */ +{ "GET-ENV", S, xget_env }, /* 308 */ #ifdef MACINTOSH #include "macptrs.h" diff --git a/lib-src/libnyquist/nyquist/xlisp/xlimage.c b/lib-src/libnyquist/nyquist/xlisp/xlimage.c index a23707633..f26075a0e 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlimage.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlimage.c @@ -397,6 +397,9 @@ LOCAL OFFTYPE cvoptr(LVAL p) /* pointer not within any segment */ xlerror("bad pointer found during image save",p); + /* this point will never be reached because xlerror() does a + longjmp(). The return is added to avoid false positive + error messages from static analyzers and compilers */ return ((OFFTYPE)NIL); } diff --git a/lib-src/libnyquist/nyquist/xlisp/xlio.c b/lib-src/libnyquist/nyquist/xlisp/xlio.c index 659b5d8ff..8ee2ca09d 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlio.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlio.c @@ -72,10 +72,10 @@ void xlungetc(LVAL fptr, int ch) /* check for ungetc from nil */ if (fptr == NIL) - ; //ANSWER-ME: Return? "else if"? + ; /* otherwise, check for ungetc to a stream */ - if (ustreamp(fptr)) { + else if (ustreamp(fptr)) { if (ch != EOF) { lptr = cons(cvchar(ch),gethead(fptr)); if (gethead(fptr) == NIL) diff --git a/lib-src/libnyquist/nyquist/xlisp/xlisp.h b/lib-src/libnyquist/nyquist/xlisp/xlisp.h index 0e4610351..3f21252a2 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlisp.h +++ b/lib-src/libnyquist/nyquist/xlisp/xlisp.h @@ -961,6 +961,7 @@ LVAL findprop(LVAL sym, LVAL prp); /* xlsys.c */ +LVAL xget_env(void); LVAL xload(void); LVAL xtranscript(void); LVAL xtype(void); diff --git a/lib-src/libnyquist/nyquist/xlisp/xlread.c b/lib-src/libnyquist/nyquist/xlisp/xlread.c index 8d841b698..c97047ca9 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlread.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlread.c @@ -333,9 +333,11 @@ int readone(LVAL fptr, LVAL *pval) } /* handle illegal characters */ - else - { + else { xlerror("illegal character",cvfixnum((FIXTYPE)ch)); + /* this point will never be reached because xlerror() does a + longjmp(). The return is added to avoid false positive + error messages from static analyzers and compilers */ return (FALSE); } } diff --git a/lib-src/libnyquist/nyquist/xlisp/xlsys.c b/lib-src/libnyquist/nyquist/xlisp/xlsys.c index fe74d9377..99a1b4ed7 100644 --- a/lib-src/libnyquist/nyquist/xlisp/xlsys.c +++ b/lib-src/libnyquist/nyquist/xlisp/xlsys.c @@ -4,6 +4,9 @@ Permission is granted for unrestricted non-commercial use */ /* HISTORY + * + * 11-Dec-09 Roger Dannenberg + * Added getenv * * 28-Apr-03 Dominic Mazzoni * Eliminated some compiler warnings @@ -49,6 +52,20 @@ extern LVAL s_true; extern FILE *osaopen(); extern LVAL exttype(); +/* xget_env - get the value of an environment variable */ +LVAL xget_env(void) +{ + const char *name = (char *) getstring(xlgetfname()); + char *val; + + /* check for too many arguments */ + xllastarg(); + + /* get the value of the environment variable */ + val = getenv(name); + return (val ? cvstring(val) : NULL); +} + /* xload - read and evaluate expressions from a file */ LVAL xload(void) {