|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 12701 (0x319d)
Types: TextFile
Names: »fr.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦041b9c0f8⟧ »EurOpenD22/isode/pepsy.system-6.0.Z«
└─⟦d49939f05⟧
└─⟦6a28ec38e⟧ »pepsy.tar«
└─⟦this⟧ »pepsy/fr.c«
/* Copyright 1989 CSIRO Division of Information Technology
* May be given away but not sold for profit - See Copyright file for details
*/
/*
* These routines are the driving routines for freeing of the data
*/
#include <stdio.h>
#include "../h/psap.h"
#include "pep.h"
#include "pepdefs.h"
extern tpe *next_tpe();
extern int _pverbose;
#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)
ferrd(1, "fre_f:Illegal typ %d\n", typ);
p = mod->md_dtab[typ];
if (p->pe_type != PE_START)
ferr(1, "fre_f: missing PE_START\n");
if ((pe = fre_obj(parm, p, mod)) == NULLPE)
return (NOTOK);
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 (p->pe_type != PE_START)
ferr(1, "fre_obj: missing PE_START\n");
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) {
dmp_tpe("fr_obj: missing EXTMOD", p, mod);
ferr(1, "fr_obj:internal error\n");
}
fre_obj(parm, ((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
case IMP_OBJ:
p++;
if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
fre_obj(parm, ((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
} 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:
break;
case ETAG:
p++;
goto again;
default:
fre_type(parm, p, mod);
break;
}
}
if (malptr) /* If we saw a malloc free item */
free(malptr);
}
/*
* 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
*/
fre_type(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
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),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
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) {
dmp_tpe("fre_type: missing EXTMOD", p, mod);
ferr(1, "fre_type:internal error\n");
}
fre_obj(parm, ((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("fre_seq: missing EXTMOD", p, mod);
ferr(1, "fre_seq:internal error\n");
}
fre_obj(*(char **) (parm + p->pe_ucode),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
case INTEGER:
case BOOLEAN:
case T_NULL:
break;
case SCONS_ANY:
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 CONS_ANY:
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:
dmp_tpe("fre_type: type not implemented", p, mod);
ferrd(1, "fre_type: %d not implemented\n", p->pe_type);
break;
}
}
/*
* free elements of a sequential type. e.g. sequence or set
*/
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 (p->pe_type != SEQ_START && p->pe_type != SET_START)
ferrd(1, "fre_seq: bad starting item %d\n", p->pe_type);
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:
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)
ferr(1, "fre_seq:illegal table: no bitmap for optionals\n");
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),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
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) {
dmp_tpe("fre_seq: missing EXTMOD", p, mod);
ferr(1, "fre_seq:internal error\n");
}
fre_obj(parm, ((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("fre_seq: missing EXTMOD", p, mod);
ferr(1, "fre_seq:internal error\n");
}
fre_obj(*(char **) (parm + p->pe_ucode),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
default:
fre_type(parm, p, mod);
break;
}
next:
NEXT_TPE(p);
}
if (malptr) /* If we saw a malloc free item */
free(malptr);
}
/*
* free all the fields in a SET OF/SEQUENCE OF type structure. We must follow
* the linked list until the end
*/
fre_seqof(parm, p, mod)
char *parm;
tpe *p;
modtyp *mod; /* Module it is from */
{
tpe *start; /* first entry in list */
char *oparm;
if (p->pe_type != SEQOF_START && p->pe_type != SETOF_START) {
dmp_tpe("fre_seqof: illegal field", p, mod);
ferr(1, "fre_seqof: First field not xOF_START\n");
}
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),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
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) {
dmp_tpe("fre_seqof: missing EXTMOD", p, mod);
ferr(1, "fre_seqof:internal error\n");
}
fre_obj(parm, ((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
break;
case EXTOBJ:
if (p[1].pe_type != EXTMOD) {
dmp_tpe("fre_seqof: missing EXTMOD", p, mod);
ferr(1, "fre_seqof:internal error\n");
}
fre_obj(*(char **) (parm + p->pe_ucode),
((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag],
(modtyp *)p[1].pe_ucode);
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
*/
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 (p->pe_type != CHOICE_START) {
dmp_tpe("fre_choice:missing CHOICE_START", p, mod);
ferrd(1, "fre_choice:illegal table entry %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) {
dmp_tpe("fre_choice:missing SCTRL", p, mod);
ferr(1, "fre_choice: missing SCTRL information\n");
}
cnt = *(int *) (parm + p->pe_ucode);
if (_pverbose > 5)
printf("cnt is %d\n",cnt);
if (cnt != 0)
cnt--;
if (cnt < 0) {
dmp_tpe("fre_choice:offset negative", p, mod);
return;
}
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--;
}
}
dmp_tpe("fre_choice: no choice taken", p, mod);
}