|
|
BSD 4.3reno
/* fr.c */
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/fr.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif
/*
* $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/fr.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
*
*
* $Log: fr.c,v $
* Revision 1.1.1.1 2018/04/24 16:12:56 root
* BSD 4.3reno
*
* Revision 7.2 90/07/27 08:48:48 mrose
* update
*
* Revision 7.1 90/07/09 14:52:38 mrose
* sync
*
* Revision 7.0 90/07/01 19:54:20 mrose
* *** empty log message ***
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
/*
* These routines are the driving routines for freeing of the data
*/
#include <stdio.h>
#include "psap.h"
#include "pepsy.h"
extern tpe *next_tpe();
extern PE pepsylose ();
#define NEXT_TPE(p) p = next_tpe(p)
#define CHKTAG(mod, p, pe) ismatch(p, mod, pe->pe_class, pe->pe_id)
/*
* don't need this fre_f we just generate macros of the form
* fre_obj(parm, mod->md_dtab[CONST], mod)
*/
#if 0
/*
* free the data of specified type of the specified module
*/
fre_f(typ, mod, pe, explicit, len, buf, parm)
/* ARGSUSED */
int typ; /* which type it is */
modtyp *mod; /* Module it is from */
PE pe;
int explicit;
int *len;
char **buf;
char **parm;
{
tpe *p;
if (typ < 0 || typ >= mod->md_nentries) {
(void) pepsylose (mod, p, pe, "fre_f:Illegal type %d\n", typ);
return (NOTOK);
}
if (parm == 0)
return (OK);
p = mod->md_dtab[typ];
if (p->pe_type != PE_START) {
(void) pepsylose (mod, p, pe, "fre_f: missing PE_START\n");
return (NOTOK);
}
fre_obj(parm, p, mod)
return (OK);
}
#endif
/*
* free an objects data. Basic algorithm is to walk through it twice
* first time freeing all the "children" of the data structure - then
* the second time free the structure itself
*/
fre_obj(parm, p, mod)
modtyp *mod;
tpe *p;
char *parm;
{
char *malptr = NULL; /* Have we seen a malloc */
if (parm == 0)
return (OK);
if (p->pe_type != PE_START) {
(void) pepsylose (mod, p, NULLPE, "fre_obj: missing PE_START\n");
return (NOTOK);
}
for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
again:
switch (p->pe_type) {
case MALLOC:
malptr = parm;
break;
case SET_START:
case SEQ_START:
fre_seq(parm, p, mod);
break;
case SETOF_START:
case SEQOF_START:
fre_seqof(parm, p, mod);
break;
case CHOICE_START:
fre_choice(parm, p, mod);
break;
case OBJECT:
case SOBJECT:
fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
break;
case SEXTOBJ:
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE, "fre_obj: missing EXTMOD");
return (NOTOK);
}
fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
case IMP_OBJ:
p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
} else {
if (p->pe_type == SOBJECT) {
fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
} else
fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
}
break;
case INTEGER:
case BOOLEAN:
case UCODE:
case REALTYPE:
break;
case ETAG:
p++;
goto again;
default:
fre_type(parm, p, mod);
break;
}
}
if (malptr) /* If we saw a malloc free item */
free(malptr);
return (OK);
}
/*
* Handle freeing of single type field. All the more general routines
* fall back to this so we can put the code to free something just
* here once and it will handle all the cases else where
*/
static fre_type(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
if (parm == 0)
return;
again:
switch (p->pe_type) {
case MALLOC:
break;
case PE_END:
case PE_START:
case UCODE:
break;
case DFLT_F:
p++;
goto again;
case ETAG:
switch (p->pe_ucode) {
default:
p++;
fre_type(parm, p, mod);
}
break;
case SEQ_START:
case SET_START:
fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
case SETOF_START:
fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
else if (p->pe_type == SOBJECT) {
fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
} else
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case SOBJECT:
fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
break;
case OBJECT:
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case CHOICE_START:
fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
return (NOTOK);
}
fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
return (NOTOK);
}
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
case INTEGER:
case BOOLEAN:
case T_NULL:
case REALTYPE:
break;
case SANY:
/*
* These tests of the pointer don't appear necessary from the
* definition of encoding and decoding but ISODE generates
* freeing code that does these checks and ISODE's ps layer
* definitely requires it
*/
if (parm != NULL)
pe_free((PE) parm);
break;
case ANY:
if (*(char **) (parm + p->pe_ucode) != NULL)
pe_free(*(PE *) (parm + p->pe_ucode));
break;
case SOCTETSTRING:
if (parm != NULL)
qb_free((struct qbuf *) parm);
break;
case OCTETSTRING:
if (*(char **) (parm + p->pe_ucode) != NULL)
qb_free(*(struct qbuf **) (parm + p->pe_ucode));
break;
case SBITSTRING:
if (parm != NULL)
pe_free((PE) parm);
break;
case BITSTRING:
if (*(char **) (parm + p->pe_ucode) != NULL)
pe_free(*(PE *) (parm + p->pe_ucode));
break;
case SOBJID:
if (parm != NULL)
oid_free((OID) parm);
break;
case OBJID:
if (*(char **) (parm + p->pe_ucode) != NULL)
oid_free(*(OID *) (parm + p->pe_ucode));
break;
default:
(void) pepsylose (mod, p, NULLPE, "fre_type: %d not implemented\n",
p->pe_type);
return (NOTOK);
}
return (OK);
}
/*
* free elements of a sequential type. e.g. sequence or set
*/
static fre_seq(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
int *popt = NULL; /* Pointer to optional field */
int optcnt = 0; /* Number of optionals bits so far */
char *malptr = NULL; /* Have we seen a malloc */
if (parm == 0)
return;
if (p->pe_type != SEQ_START && p->pe_type != SET_START) {
(void) pepsylose (mod, p, NULLPE, "fre_seq: bad starting item %d\n",
p->pe_type);
return (NOTOK);
}
p++;
if (p->pe_type == DFLT_B)
p++;
while (p->pe_type != PE_END) {
if (ISDTYPE(p) && (OPTIONAL(p) || DEFAULT(p))) {
switch (p->pe_type) {
case INTEGER:
case BOOLEAN:
case T_NULL:
case REALTYPE:
if (DEFAULT(p)) {
/* ISODE doesn't use bit map for defaults */
if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
|| p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
goto next;
break;
}
if (popt == NULL) {
(void) pepsylose (mod, p, NULLPE,
"fre_seq:illegal table: no bitmap for optionals\n");
return (NOTOK);
}
if (!TESTBIT(*popt, optcnt++))
goto next; /* Missing so skip */
break;
case ETAG:
if (!hasdata(parm, p + 1, mod, popt, optcnt))
goto next;
break;
case IMP_OBJ:
if (p[1].pe_type == SOBJECT && parm == NULL
|| *((char **) (parm + p[1].pe_ucode)) == NULL)
goto next;
break;
case SOBJECT:
if (((char *) parm) == NULL)
goto next;
break;
default:
if (*((char **) (parm + p->pe_ucode)) == NULL)
goto next;
break;
}
}
switch (p->pe_type) {
case MALLOC:
malptr = parm;
break;
case OPTL:
popt = (int *) (parm + p->pe_ucode);
break;
case ETAG:
p++;
continue;
case UCODE:
break;
case SET_START:
case SEQ_START:
fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SETOF_START:
case SEQOF_START:
fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
else if (p->pe_type == SOBJECT) {
fre_obj((char *) parm, mod->md_dtab[p->pe_tag],
mod);
} else
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case SOBJECT:
fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
break;
case OBJECT:
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case CHOICE_START:
fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
return (NOTOK);
}
fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
return (NOTOK);
}
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
default:
fre_type(parm, p, mod);
break;
}
next:
NEXT_TPE(p);
}
if (malptr) /* If we saw a malloc free item */
free(malptr);
return (OK);
}
/*
* free all the fields in a SET OF/SEQUENCE OF type structure. We
* must follow the linked list until the end
*/
static fre_seqof(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
tpe *start; /* first entry in list */
char *oparm;
if (parm == 0)
return;
if (p->pe_type != SEQOF_START && p->pe_type != SETOF_START) {
(void) pepsylose (mod, p, NULLPE, "fre_seqof: illegal field");
return (NOTOK);
}
for (start = p; (char *) parm != NULL; p = start) {
p++;
if (p->pe_type == DFLT_B)
p++;
while (p->pe_type != PE_END) {
switch (p->pe_type) {
case ETAG:
p++;
continue;
case UCODE:
break;
case SEQ_START:
case SET_START:
fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEQOF_START:
case SETOF_START:
fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
break;
case IMP_OBJ:
p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
else if (p->pe_type == SOBJECT) {
fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
} else
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case SOBJECT:
fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
break;
case OBJECT:
fre_obj(*(char **) (parm + p->pe_ucode),
mod->md_dtab[p->pe_tag], mod);
break;
case CHOICE_START:
fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
break;
case SEXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE,
"fre_seqof: missing EXTMOD");
return (NOTOK);
}
fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
(void) pepsylose (mod, p, NULLPE,
"fre_seqof: missing EXTMOD");
return (NOTOK);
}
fre_obj(*(char **) (parm + p->pe_ucode),
(EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
EXT2MOD(mod, (p + 1)));
break;
default:
fre_type(parm, p, mod);
break;
}
NEXT_TPE(p);
}
oparm = parm;
parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
free(oparm);
}
}
/*
* free the item of the choice. Use the SCTRL field to determine
* which item is present and then call the appropriate routine to
* free it
*/
static fre_choice(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
int cnt;
char *malptr = NULL; /* Have we seen a malloc */
if (parm == 0)
return;
if (p->pe_type != CHOICE_START) {
(void) pepsylose (mod, p, NULLPE,
"fre_choice:CHOICE_START missing found %d\n", p->pe_type);
}
p++;
if (p->pe_type == DFLT_B)
p++;
if (p->pe_type == MALLOC) {
malptr = parm;
p++;
}
if (p->pe_type != SCTRL) {
(void) pepsylose (mod, p, NULLPE,
"fre_choice: missing SCTRL information\n");
return (NOTOK);
}
cnt = *(int *) (parm + p->pe_ucode);
if (cnt != 0)
cnt--;
if (cnt < 0) {
(void) pepsylose (mod, p, NULLPE,"fre_choice:offset negative %d", cnt);
return (NOTOK);
}
for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
if (ISDTYPE(p)) {
if (cnt == 0) {
fre_type(parm, p, mod);
if (malptr) /* If we saw a malloc free item */
free(malptr);
return;
}
cnt--;
}
}
(void) pepsylose (mod, p, NULLPE, "fre_choice: no choice taken");
return (NOTOK);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.