:i	static char str_minstr_sccs_id[] = "%W% %G%";
#include "V_M_UC.h"
#include "str.h"
#include "mem.h"

/*
* Make sure that a string has a minimum amount of space allocated.
*/
Str* str_minstr(s,n,msg)
	Str*  s;
	int   n;
	char* msg;
{	Str*  r=0;
	char* p=0;
	char* oldp, *oldv;
	Flag  new=0;
:f	Fenter("str_minstr");
:2	if (!msg) msg = unknown;
:6	V8M "Called with s=%08X n=%d msg=%08X)",s,n,msg D;
	if (!(r = s)) {	/* If there's no s, alloc one */
:6		V7M "Get %d bytes for Str.",sizeof(Str) D;
		if (!(r = s = (Str*)GetChunk(sizeof(Str),msg)))
			Fail;
		++new;		/* New Str struct is all nulls */
	}
	oldp = s->p;
	oldv = s->v;
:6	V7M "Str: v=%08X l=%d m=%d n=%d",s->v,s->l,s->m,n D;
	if (n < s->l) {
:5		V7M "Increased %d to l=%d.",n,s->l D;
		n = s->l;
	}
	if (n <= 0) {	/* It's valid to ask for a null string */
:5		V7M "Caller asked for null string." D;
		Done;
	}
	if (!s->v || (s->m < n)) {	/* Space allocated? */
:5		V7M "xpand %s from  %d to %d bytes.",msg,s->m,n+StrPadLen D;
		if (!(p = (CP)GetChunk(n+StrPadLen,msg))) {
			if (new) IRelChunk(r,msg);
			Fail;
		}
	}
	if (p) {	/* New value allocated? */
		if (s->v && (s->l > 0)) {	/* Did caller pass us a value? */
			Bcopy(s->v,p,s->l);
		}
		if ((s->m > 0) && s->v) {	/* Was old v allocated? */
:5			V7M "Free the old value at %08X",s->v D;
			RelChunk(s->v,msg);
		}
		s->v = p;
		s->p = oldp ? (s->v + (oldp - oldv)) : 0;
		s->m = MEMUNIT(n+StrPadLen);
/*	} else { */
/*		s->p = 0;	** Deleted 96/12/06 by jc */
	}
:2	if (n = ChkStr(r))
:2		V2M "### %d errors found in new string.",n D;
done:
fail:
:f	Fexit;
	return r;
}
