/*
Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/
#ifndef lint
static char RCSid[] = "$Header: /home/mjr/hacks/umud/RCS/obj.c,v 1.1 92/02/09 22:59:34 mjr Exp $";
#endif
/* configure all options BEFORE including system stuff. */
#include "config.h"
#include "mud.h"
/* allocate a new object holder */
Obj
*objnew()
{
Obj *ret;
if((ret = (Obj *)malloc(sizeof(Obj))) == (Obj *)0)
return((Obj *)0);
ret->ocnt = 0;
ret->oap = (char **)0;
return(ret);
}
/* free an object, its holder, and its attributes - actual free() is deferred */
void
objfree(obj)
Obj *obj;
{
int x;
if(obj == (Obj *)0)
return;
if(obj->ocnt > 0) {
for(x = 0; x < obj->ocnt; x++)
deferfree((mall_t)obj->oap[x]);
deferfree((mall_t)obj->oap);
}
deferfree((mall_t)obj);
}
/*
search for attributes by name
*/
char *
objattr(obj,attr,slot)
Obj *obj;
char *attr;
int *slot;
{
char *p1;
char *p2;
int s = 0;
for(; s < obj->ocnt; s++) {
p2 = obj->oap[s];
/* skip the type information */
while(*p2 != ' ' && *p2 != '\0')
p2++;
if(*p2 != ' ')
continue;
p1 = attr;
/* p2 is left pointing at the ' ' after the type */
p2++;
/* check matching chars */
while(*p1 == *p2 && *p1 != '\0')
p1++, p2++;
/* validate match */
if(*p1 != '\0' || *p2 != '=')
continue;
/* match */
if(slot != (int *)0)
*slot = s;
return(obj->oap[s]);
}
if(slot != (int *)0)
*slot = -1;
return((char *)0);
}
int
objsetattr(o,aty,att,ada)
Obj *o;
char *aty;
char *att;
char *ada;
{
char **a;
char *ip;
int s;
int atlen;
int anlen;
int adlen;
if(o == (Obj *)0 || aty == (char *)0 || att == (char *)0 || ada == (char *)0)
return(-1);
(void)objattr(o,att,&s);
atlen = strlen(aty);
anlen = strlen(att);
adlen = strlen(ada);
if((ip = (char *)malloc((unsigned)(atlen + anlen + adlen + 3))) == (char *)0)
return(-1);
/* copy the type string */
(void)bcopy(aty,ip,atlen);
/* add a space */
*(ip + atlen) = ' ';
/* copy the attribute name */
(void)bcopy(att,ip + atlen + 1,anlen);
/* add the equals sign */
*(ip + atlen + anlen + 1) = '=';
/* copy the data */
(void)bcopy(ada,ip + atlen + anlen + 2,adlen);
/* terminate */
*(ip + atlen + anlen + adlen + 2) = '\0';
if(s > -1 && s < o->ocnt && o->oap != (char **)0 && o->oap[s] != (char *)0)
deferfree((mall_t)o->oap[s]);
if(o->oap == (char **)0) {
a = (char **)malloc(sizeof(char *));
if(a == (char **)0)
return(-1);
o->oap = a;
o->ocnt = 1;
s = 0;
} else
if(s == -1 || s >= o->ocnt) {
a = (char **)realloc((mall_t)o->oap,(unsigned)((o->ocnt + 1) * sizeof(char *)));
if(a == (char **)0)
return(-1);
o->oap = a;
s = o->ocnt;
o->ocnt++;
}
o->oap[s] = ip;
return(0);
}
int
objunsetattr(obj,attr)
Obj *obj;
char *attr;
{
int slot;
char **a;
if(objattr(obj,attr,&slot) == (char *)0)
return(0);
if(slot > -1 && slot < obj->ocnt && obj->oap[slot] != (char *)0)
deferfree((mall_t)obj->oap[slot]);
/* if none left, free it */
if(obj->ocnt == 1) {
deferfree((mall_t)obj->oap);
obj->oap = (char **)0;
obj->ocnt = 0;
return(0);
}
/* shift all one slot down */
while(slot < obj->ocnt - 1) {
obj->oap[slot] = obj->oap[slot + 1];
slot++;
}
/* realloc may pack memory. */
a = (char **)realloc((mall_t)obj->oap,(unsigned)((obj->ocnt - 1) * sizeof(char *)));
if(a == (char **)0)
return(-1);
obj->oap = a;
(obj->ocnt)--;
return(0);
}
objstuffattr(o,data,len)
Obj *o;
char *data;
int len;
{
char *p;
if(o->oap == (char **)0) {
o->oap = (char **)malloc(sizeof(char *));
o->ocnt = 1;
} else {
o->oap = (char **)realloc((mall_t)o->oap,(o->ocnt + 1) * sizeof(char *));
o->ocnt++;
}
if((p = (char *)malloc((unsigned)(len + 1))) == (char *)0)
return(-1);
(void)bcopy(data,p,len);
p[len] = '\0';
o->oap[o->ocnt - 1] = p;
return(0);
}
/*
return nonzero if the variable is of the given type. simple
type-checking function.
*/
int
attistype(v,vt)
char *v;
char *vt;
{
while(*v != '\0' && *v != ' ' && *vt != '\0' && *v == *vt)
v++, vt++;
if(*vt == '\0' && *v == ' ')
return(1);
return(0);
}
/*
return data part of an attribute. note that this does NOT return NULL
if the attribute is of zero-length.
*/
char *
attdata(v)
char *v;
{
while(*v != '\0' && *v != ' ')
v++;
if(*v != ' ')
return((char *)0);
while(*v != '\0' && *v != '=')
v++;
if(*v != '=')
return((char *)0);
return(++v);
}
/*
return name part of an attribute. Note! suceeds even if name is zero length.
*/
attname(a,aname)
char *a;
char *aname;
{
int i;
while(*a != '\0' && *a != ' ')
a++;
if(*a != ' ')
return(1);
for(i = 0, ++a; i < MAXOID-1 && *a != '\0' && *a != '='; ++i, ++a)
aname[i] = *a;
aname[i] = '\0';
return(0);
}