- }
-
- if (inputstr[0]=='\0') {
- return NULL;
- }
-
- /* Only count calls that actually did something */
- getcalls++;
-
- length=strlen(inputstr)+1;
- if (length>maxlen) {
- length=maxlen+1;
- }
- assert(length<=SSTRING_MAXLEN);
-
- /* Check to see if an approximately correct
- * sized string is available */
- for(i=0;i<SSTRING_SLACK;i++) {
- if (length+i>SSTRING_MAXLEN)
- break;
-
- if (freelist[length+i]!=NULL) {
- retval=freelist[length+i];
- freelist[length+i]=retval->u.next;
- retval->u.l.alloc=(length+i);
- break;
- }
- }
-
- /* None found, allocate a new one */
- if (retval==NULL) {
-getstruct:
- if (structfree < sizeof(sstring)) {
- /* We always allocate an exact multiple of these.
- * Therefore, if there is enough for a partial structure we broke something */
- assert(structfree==0);
-
- /* Allocate more RAM */
- allocstruct++;
- structmem=(sstring *)nsmalloc(POOL_SSTRING,SSTRING_STRUCTALLOC);
- assert(structmem!=NULL);
- structfree=SSTRING_STRUCTALLOC;
- }
-
- retval=structmem;
- structmem++;
- structfree-=sizeof(sstring);
-
- if (stringfree < length) {
- /* Not enough left for what we want.
- * Allocate the remainder of our chunk (if any)
- * to something and immediately free it.
- * Decrement the freecalls counter to fix the stats */
- if (stringfree > 0) {
- retval->content=stringmem;
- retval->u.l.alloc=stringfree;
- stringfree=0;
- freecalls--;
- freesstring(retval);
-
- /* GOTO GOTO GOTO: We need to allocate
- * another new struct here. Goto is the cleanest
- * way to do this */
- goto getstruct;
- } else {
- /* Grab some more string space */
- allocstring++;
- stringmem=(char *)nsmalloc(POOL_SSTRING,SSTRING_DATAALLOC);
- assert(stringmem!=NULL);
- stringfree=SSTRING_DATAALLOC;
- }
- }
-
- retval->content=stringmem;
- retval->u.l.alloc=length;
- stringfree-=length;
- stringmem+=length;
- }
-
- /*
- * At this point, retval points to a valid structure which is at
- * least the right size and has the "alloc" value set correctly
- */
-
- retval->u.l.length=(length-1);
- strncpy(retval->content,inputstr,(length-1));
- retval->content[length-1]='\0';
-
- return retval;
-}
-
-void freesstring(sstring *inval) {
- int alloc;
-
- /* Allow people to call this with a NULL value */
- if (inval==NULL)
- return;
-
- /* Only count calls that actually did something */
- freecalls++;
-
- alloc=inval->u.l.alloc;
- assert(alloc<=SSTRING_MAXLEN);
- inval->u.next=freelist[alloc];
- freelist[alloc]=inval;
-}