--- ray/src/common/readobj.c 2019/05/04 00:36:58 2.23 +++ ray/src/common/readobj.c 2025/06/07 05:09:45 2.29 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: readobj.c,v 2.23 2019/05/04 00:36:58 greg Exp $"; +static const char RCSid[] = "$Id: readobj.c,v 2.29 2025/06/07 05:09:45 greg Exp $"; #endif /* * readobj.c - routines for reading in object descriptions. @@ -14,7 +14,6 @@ static const char RCSid[] = "$Id: readobj.c,v 2.23 201 #include #include "platform.h" -#include "paths.h" #include "standard.h" #include "object.h" #include "otypes.h" @@ -47,6 +46,9 @@ readobj( /* read in an object file or stream */ sprintf(errmsg, "cannot open scene file \"%s\"", inpspec); error(SYSTEM, errmsg); } +#ifdef getc_unlocked /* avoid stupid semaphores */ + flockfile(infp); +#endif while ((c = getc(infp)) != EOF) { if (isspace(c)) continue; @@ -61,10 +63,17 @@ readobj( /* read in an object file or stream */ getobject(inpspec, infp); } } - if (inpspec[0] == '!') - pclose(infp); - else if (infp != stdin) + if (inpspec[0] == '!') { + if (pclose(infp) != 0) { + sprintf(errmsg, "bad status from \"%s\"", inpspec); + error(WARNING, errmsg); + } + } else if (infp != stdin) fclose(infp); +#ifdef getc_unlocked + else + funlockfile(infp); +#endif if (nobjects == lastobj) { sprintf(errmsg, "(%s): empty file", inpspec); error(WARNING, errmsg); @@ -121,17 +130,21 @@ getobject( /* read the next object */ objp->oname = savqstr(sbuf); /* get arguments */ if (objp->otype == MOD_ALIAS) { - OBJECT alias; + OBJECT ref; + OBJREC *rfp; strcpy(sbuf, "EOF"); fgetword(sbuf, MAXSTR, fp); - if ((alias = modifier(sbuf)) == OVOID) { + if ((ref = modifier(sbuf)) == OVOID) { sprintf(errmsg, "(%s): bad reference \"%s\"", name, sbuf); objerror(objp, USER, errmsg); - } - if (objp->omod == OALIAS || - objp->omod == objptr(alias)->omod) { - objp->omod = alias; + } /* skip pass-thru aliases */ + while ((rfp=objptr(ref))->otype == MOD_ALIAS && + !rfp->oargs.nsargs & (rfp->omod != OVOID)) + ref = rfp->omod; + + if ((objp->omod == OALIAS) | (objp->omod == rfp->omod)) { + objp->omod = ref; } else { objp->oargs.sarg = (char **)malloc(sizeof(char *)); if (objp->oargs.sarg == NULL) @@ -198,16 +211,17 @@ freeobjects( /* free a range of objects */ freefargs(&o->oargs); memset((void *)o, '\0', sizeof(OBJREC)); } - clearobjndx(); /* free objects off end */ for (obj = nobjects; obj-- > 0; ) if (objptr(obj)->oname != NULL) break; - ++obj; + if (++obj >= nobjects) + return; while (nobjects > obj) /* free empty end blocks */ if ((--nobjects & (OBJBLKSIZ-1)) == 0) { int i = nobjects >> OBJBLKSHFT; free((void *)objblock[i]); objblock[i] = NULL; } + truncobjndx(); /* truncate modifier look-up */ }