DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦5b586afe7⟧ TextFile

    Length: 38054 (0x94a6)
    Types: TextFile
    Names: »dec.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦041b9c0f8⟧ »EurOpenD22/isode/pepsy.system-6.0.Z« 
        └─⟦d49939f05⟧ 
            └─⟦6a28ec38e⟧ »pepsy.tar« 
                └─⟦this⟧ »pepsy/dec.c« 

TextFile

/* 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 parsing encoding and printing
 * data
 */
#include	<stdio.h>
#include	"../h/psap.h"
#include	"pep.h"
#include	"pepdefs.h"

#define PEPYPARM	char **
#ifndef	PEPYPARM
#define PEPYPARM	char **
#endif
extern	PEPYPARM	NullParm;



extern	PE	pr_seq(), pr_seqof(), pr_set(), pr_setof(), pr_type();
extern	PE	en_seq(), en_seqof(), en_set(), en_setof(), en_type();
extern	PE	pr_choice(), en_choice(), en_etype(), pr_etype(), pr_obj();
extern	PE	setpresent();

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) 

/* Have we got an optional object which we have allocated sapce for */
#define ALLOC_MEM(p, parm)	(p->pe_type == SOBJECT \
	&& p[-1].pe_type == MALLOC)

/*SUPPRESS 36*/ /* for Saber C */

/*
 * decode the specified type of the specified module into the given pe
 */
dec_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;
PEPYPARM parm;
{
    tpe	*p;

    if (typ < 0 || typ >= mod->md_nentries)
	ferrd(1, "dec_f:Illegal typ %d\n", typ);
    
    p = mod->md_dtab[typ];
    if (p->pe_type != PE_START)
	ferr(1, "dec_f: missing PE_START\n");
    p++;
    if ((pe = pr_obj(explicit, pe, parm, p, mod)) == NULLPE)
		return (NOTOK);

    return (OK);
}

/*
 * Parse an object. The top level of an object does not have any offset field
 * which makes it different to pr_type routine which must assume that it
 * has an offset.
 */
PE
pr_obj(expl, pe, parm, p, mod)
int	expl;	/* do we look at the tag */
PE      pe;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
	int	cnt = 0;


    if (_pverbose > 6) {
	printf("1st Decoding the type %d \n",p->pe_type);
    }
    while (p->pe_type != PE_END) {

	if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
		if (DEFAULT(p))
		    ferr(1, "pr_obj:Default not implemented\n");
		else if (OPTIONAL(p)) {
			if (ALLOC_MEM(p, parm))
			    fix_mem(parm, p);
			goto next;
		} else {
			dmp_tpe("pr_obj:missing mandatory parameter", p, mod);
			return (NULLPE);
		}
	}

	if (_pverbose > 6) {
	    printf("2nd Decoding the type %d \n",p->pe_type);
	}

	switch (p->pe_type) {
	case PE_END:
	case PE_START:
		return (NULLPE);

	case UCODE:
		if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
			return (NULLPE);
		break;

	case ETAG:
	    switch (p->pe_ucode) {
	    default:
		p++;
		if (pr_obj(1, pe->pe_cons, parm, p, mod) == NULLPE)
		    return (NULLPE);
	    }
	    break;

	case MALLOC:
		if ((*(parm) = (char *)  calloc(1, p->pe_tag)) == NULL)
			return NULLPE;
		break;

	case SEQ_START:
		if ((pe = pr_seq(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SEQOF_START:
		if ((pe = pr_seqof(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SET_START:
		if ((pe = pr_set(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SETOF_START:
		if ((pe = pr_setof(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case IMP_OBJ:
		p++;
		if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
		    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL,
		       (char **) 0, parm);
		} else {
		    if (p->pe_type == SOBJECT) {
			if ((pe = pr_obj(0, pe, parm,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		    } else
			if ((pe = pr_obj(0, pe, *parm + p->pe_ucode,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		}
		break;

	case SOBJECT:
	case OBJECT:
		if ((pe = pr_obj(expl, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
		break;

	case CHOICE_START:
		if ((pe = pr_choice(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SEXTOBJ:
	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_type: missing EXTMOD", p, mod);
		ferr(1, "pr_type:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, parm);
	    break;

	default:
		if ((pe = pr_type(expl, pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;
	}
	if (ISDTYPE(p) && cnt > 0)
		ferr(1, "pr_obj:compound type found\n"); 
	if (ISDTYPE(p) && pe != NULLPE)
		return (pe);
next:
	NEXT_TPE(p);
    }

    return (pe);
}
/*
 * Parse a single type.
 * If a basic type parse it, if a compound type call the appropriate
 * parsing routine
 */
PE
pr_type(expl, pe, parm, p, mod)
int	expl;	/* do we look at the tag */
PE      pe;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
	int	cnt = 0;
	OID	oid;


    if (_pverbose > 6) {
	printf("1st Decoding the type %d \n",p->pe_type);
    }
    while (p->pe_type != PE_END) {
/*
print_pe (pe, 1);
*/

	if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
		if (DEFAULT(p)) {
		    setdval(p, p + 1, parm, mod);
		    goto next;
		} else if (OPTIONAL(p)) {
			if (ALLOC_MEM(p, parm))
			    fix_mem(parm, p);
			goto next;
		} else {
			dmp_tpe("pr_type:missing mandatory parameter", p, mod);
			return (NULLPE);
		}
	}

	if (_pverbose > 6) {
	    printf("2nd Decoding the type %d \n",p->pe_type);
	}

	switch (p->pe_type) {
	case PE_END:
	case PE_START:
		return (NULLPE);

	case UCODE:
		if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
			return (NULLPE);
		break;

	case ETAG:
	    switch (p->pe_ucode) {
	    default:
		p++;
		if (pr_etype(pe->pe_cons, parm, p, mod) == NULLPE)
		    return (NULLPE);
	    }
	    break;

	case MALLOC:
		if ((*(parm) = (char *)  calloc(1, p->pe_tag)) == NULL)
			return NULLPE;
		break;

	case SEQ_START:
		if ((pe = pr_seq(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SEQOF_START:
		if ((pe = pr_seqof(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SET_START:
		if ((pe = pr_set(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SETOF_START:
		if ((pe = pr_setof(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case IMP_OBJ:
		p++;
		if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
		    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL,
		       (char **) 0, parm);
		} else {
		    if (p->pe_type == SOBJECT) {
			if ((pe = pr_obj(0, pe, parm,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		    } else
			if ((pe = pr_obj(0, pe, *parm + p->pe_ucode,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		}
		break;

	case SOBJECT:
	case OBJECT:
		if ((pe = pr_obj(expl, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
		break;

	case CHOICE_START:
		if ((pe = pr_choice(pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SEXTOBJ:
	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_type: missing EXTMOD", p, mod);
		ferr(1, "pr_type:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, parm);
	    break;

	case INTEGER:
		if (pe != NULLPE) {
		    if (_pverbose > 6) {
			printf("integer value is %d\n",prim2num(pe));
		    }
		    if (((*(int *)(*parm + p->pe_ucode)) = prim2num(pe))
		      == NOTOK && pe->pe_errno != PE_ERR_NONE) {
			printf("pr_type:bad integer %s",
			pe_error(pe->pe_errno));
			return (NULLPE);
		    }
		}
		break;

	case BOOLEAN:
		if (pe != NULLPE) {
			    if (_pverbose > 6) {
				printf("boolean value is %d\n",prim2flag(pe));
			    }
			if (((* (char *)(*parm + p->pe_ucode)) = prim2flag(pe))==NOTOK && pe->pe_errno != PE_ERR_NONE) {
					printf("pr_type:bad integer %s",
					pe_error(pe->pe_errno));
				return (NULLPE);
			}
		}
		break;

	case T_NULL:
		break;

	case SCONS_ANY:
	case SANY:
		if (pe != NULLPE) {
			((* (PE *) parm) = pe)->pe_refcnt++;
			if (pe->pe_errno != PE_ERR_NONE) {
				printf("pr_type:bad integer %s",
					pe_error(pe->pe_errno));
				return (NULLPE);
			}
		}
		break;


	case CONS_ANY:
	case ANY:
		if (pe != NULLPE) {
			(* (PE *) (*parm + p->pe_ucode) = pe) ->pe_refcnt++;
			if (pe->pe_errno != PE_ERR_NONE) {
				printf("pr_type:bad integer %s",
					pe_error(pe->pe_errno));
				return (NULLPE);
			}
		}
		break;

	case SOCTETSTRING:
		if (pe != NULLPE) {
		    if ((*((struct qbuf **) parm) = prim2qb(pe)) ==
		    (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE) {
				printf("pr_type:bad octet string %s",
					pe_error(pe->pe_errno));
				return (NULLPE);
			}
		}
		break;

	case OCTETSTRING:
		if (pe != NULLPE) {
		    if ((*((struct qbuf **) (*parm + p->pe_ucode))
			= prim2qb(pe)) == (struct qbuf *) NULL
			&& pe->pe_errno != PE_ERR_NONE) {
				printf("pr_type:bad octet string %s",
					pe_error(pe->pe_errno));
				return (NULLPE);
			}
		}
		break;

	case SBITSTRING:
		if (pe != NULLPE) {
		    /*
		    if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe))== NULLPE) 
    I think this is a bug in ISODE's routines prim2bit
		    does the wrong thing
		    */
		    if ((*((PE *)parm)=prim2bit(pe_cpy(pe))) == NULLPE) {
			printf("pr_type:out of memory");
			return (NULLPE);
		    }
		}
		break;

	case BITSTRING:
		if (pe != NULLPE) {
		    /*
		    if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe))== NULLPE) 
    I think this is a bug in ISODE's routines prim2bit
		    does the wrong thing
		    */
		    if ((*((PE *)(*parm + p->pe_ucode))=prim2bit(pe_cpy(pe))) == NULLPE) {
			printf("pr_type:out of memory");
			return (NULLPE);
		    }
		}
		break;

	case SOBJID:
	/* This is messy because ISODE's library routine uses a static. Don't
	 * know why they do
	 */
	    if ((oid = prim2oid(pe)) == NULLOID
	    || (*(OID *)parm = oid_cpy(oid)) == NULLOID) {
		    printf("pr_type:Object Identifier: out of memory");
		    if (oid && oid->oid_elements) {
			free(oid->oid_elements);
			oid->oid_elements = NULL;
		    }
		    return (NULLPE);
	    }
	    if (oid && oid->oid_elements) {
		free(oid->oid_elements);
		oid->oid_elements = NULL;
	    }
	    break;

	case OBJID:
	    if ((oid = prim2oid(pe)) == NULLOID
	    || (*(OID *)(*parm + p->pe_ucode) = oid_cpy(oid)) == NULLOID) {
		    printf("pr_type:Object Identifier: out of memory");
		    if (oid && oid->oid_elements) {
			free(oid->oid_elements);
			oid->oid_elements = NULL;
		    }
		    return (NULLPE);
	    }
	    if (oid && oid->oid_elements) {
		free(oid->oid_elements);
		oid->oid_elements = NULL;
	    }
	    break;

	default:
		dmp_tpe("pr_type: type not implemented", p, mod);
		ferrd(1, "pr_type: %d not implemented\n", p->pe_type);
		break;
	}
	if (ISDTYPE(p) && cnt > 0)
		ferr(1, "pr_type:compound type found\n"); 
	if (ISDTYPE(p) && pe != NULLPE)
		return (pe);
next:
	NEXT_TPE(p);
    }

    return (pe);
}

/*
 * Parse a sequence, calling appropriate routines to parse each sub type
 */
PE
pr_seq(head, parm, p, mod)
PE      head;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
    PE      pe;
    int	*popt = NULL;	/* Pointer to optional field */
    int	optcnt = 0;	/* Number of optionals bits so far */

    if (p->pe_type != SEQ_START)
	    ferr(1, "pr_seq: missing SEQ_START\n");
    p++;

    if (p->pe_type == DFLT_B)
	p++;

    pe = first_member(head);
    while (p->pe_type != PE_END) {
	if (_pverbose > 6) {
	    printf("dec_seq with the type %d\n",p->pe_type);
	}


	if (ISDTYPE(p) && OPTIONAL(p)) {
	    switch (p->pe_type) {
	    case INTEGER:
	    case BOOLEAN:
	    case T_NULL:
		if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
		    optcnt++;
		    goto next;
		}
		SETBIT(*popt, optcnt++);
		break;

#if 0
	    case ANY:
	    case CONS_ANY:
	    case SANY:
	    case SCONS_ANY:
		dmp_tpe("pr_seq:optional/default ANY", p, mod);
		ferr(1, "unable to distinguish tags");
#endif

	    default:
		if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
		    if (ALLOC_MEM(p, parm))
			fix_mem(parm, p);
		    goto next;
		}
		break;
	    }
	} else if (ISDTYPE(p) && (pe == NULLPE || CHKTAG(mod, p, pe) == 0)) {
	    if (DEFAULT(p)) {
		setdval(p, p + 1, parm, mod);
		goto next;
	    } else {
		dmp_tpe("pr_seq:missing mandatory parameter", p, mod);
		return (NULLPE);
	    }
	}

	switch (p->pe_type) {
	case OPTL:
	    popt = (int *) (*parm + p->pe_ucode);
	    break;

	case UCODE:
	    if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
		    return (NULLPE);
	    break;

	case ETAG:
	    if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
		return NULLPE;
	    break;

	case MALLOC:
	    if ((*parm = (char *)  calloc(1, p->pe_tag)) == NULL)
		return NULLPE;
	    break;

	case SEQ_START:
	    if ((pe = pr_seq(pe, (char **)(*parm + p->pe_ucode), p, mod))
	      == NULLPE)
		return (NULLPE);
	    break;

	case SEQOF_START:
		if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;

	case SET_START:
		if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SETOF_START:
		if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case IMP_OBJ:
		p++;
		if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
		    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL,
		       (char **) 0, *parm + p->pe_ucode);
		} else {
		    if (p->pe_type == SOBJECT) {
			if ((pe = pr_obj(0, pe, parm,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		    } else
			if ((pe = pr_obj(0, pe, *parm + p->pe_ucode,
			  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		}
		break;

	case SOBJECT:
		if ((pe = pr_obj(1, pe, parm,
		    mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
		break;

	case OBJECT:
		if ((pe = pr_obj(1, pe, *parm + p->pe_ucode,
		    mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
		break;

	case CHOICE_START:
		if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			return (NULLPE);
		break;

	case SEXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_seq: missing EXTMOD", p, mod);
		ferr(1, "pr_seq:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, parm);
	    break;

	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_seq: missing EXTMOD", p, mod);
		ferr(1, "pr_seq:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, *parm + p->pe_ucode);
	    break;

	default:
		if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
			return (NULLPE);
		break;
		/*
		ferrd(1, "pr_seq: unknown type %d\n", p->pe_type);
		*/
	}

	if (ISDTYPE(p) && pe != NULLPE)
		pe = next_member(head, pe);
    next:
	    NEXT_TPE(p);
    }

    return (head);

}


/*
 * Parse a set, calling appropriate routines to parse each sub type
 */
PE
pr_set(head, parm, p, mod)
PE      head;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
	PE      pe;
	int	*popt = NULL;	/* Pointer to optional field */
	int	optcnt = 0;	/* Number of optionals bits so far */

	if (p->pe_type != SET_START)
		ferr(1, "pr_seq: missing SET_START\n");
	p++;

    if (p->pe_type == DFLT_B)
	p++;

	while (p->pe_type != PE_END) {

	    if (_pverbose > 6) {
		printf("dec_set with the type %d\n",p->pe_type);
	    }

	    if (ISDTYPE(p) && OPTIONAL(p)) {
		switch (p->pe_type) {
		case INTEGER:
		case BOOLEAN:
		case T_NULL:
		    if ((pe = setpresent(head, p, mod)) == NULLPE) {
			optcnt++;
			goto next;
		    }
		    SETBIT(*popt, optcnt++);
		    break;

#if 0
		case ANY:
		case CONS_ANY:
		case SANY:
		case SCONS_ANY:
		    dmp_tpe("pr_set:optional/default ANY\n", p, mod);
		    ferr(1, "unable to distinguish tags");
#endif

		default:
		    if ((pe = setpresent(head, p, mod)) == NULLPE) {
			if (ALLOC_MEM(p, parm))
			    fix_mem(parm, p);
			goto next;
		    }
		    break;
		}
	    } else if (ISDTYPE(p) && (pe = setpresent(head, p, mod)) == NULLPE) {
		if (DEFAULT(p)) {
		    setdval(p, p + 1, parm, mod);
		    goto next;
		} else {
		    dmp_tpe("pr_set:missing mandatory parameter", p, mod);
		    return (NULLPE);
		}
	    }

	    switch (p->pe_type) {
	    case OPTL:
		popt = (int *) (*parm + p->pe_ucode);
		break;

	    case UCODE:
		    if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
			    return (NULLPE);
		    break;

	    case ETAG:
		    if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
			    return NULLPE;
		    break;

	    case MALLOC:
		    if ((*parm = (char *)  calloc(1, p->pe_tag)) == NULL)
			    return NULLPE;
		    break;

	    case SEQ_START:
		    if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;
    
	    case SEQOF_START:
		    if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;
    
	    case SET_START:
		    if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;
    
	    case SETOF_START:
		    if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;

	    case IMP_OBJ:
		    p++;
		    if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
			dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL,
			   (char **) 0, *parm + p->pe_ucode);
		    } else {
			if (p->pe_type == SOBJECT) {
			    if ((pe = pr_obj(0, pe, parm,
			      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
				return (NULLPE);
			} else
			    if ((pe = pr_obj(0, pe, *parm + p->pe_ucode,
			      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
				return (NULLPE);
		    }
		    break;
    
	    case SOBJECT:
		    if ((pe = pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1,
			mod)) == NULLPE)
			    return (NULLPE);
		    break;
    
	    case OBJECT:
		    if ((pe = pr_obj(1, pe, *parm + p->pe_ucode,
			mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			    return (NULLPE);
		    break;
    
	    case CHOICE_START:
		    if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;

	    case SEXTOBJ:
		if (p[1].pe_type != EXTMOD) {
		    dmp_tpe("pr_set: missing EXTMOD", p, mod);
		    ferr(1, "pr_set:internal error\n");
		}
		dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		    (char **) 0, parm);
		break;

	    case EXTOBJ:
		if (p[1].pe_type != EXTMOD) {
		    dmp_tpe("pr_set: missing EXTMOD", p, mod);
		    ferr(1, "pr_set:internal error\n");
		}
		dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		    (char **) 0, *parm + p->pe_ucode);
		break;

	    default:
		    if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
			    return (NULLPE);
		    break;
		    /*
		    ferrd(1, "pr_set: unknown type %d\n", p->pe_type);
		    */
	    }

	next:
		NEXT_TPE(p);
	}

	return (head);

}


/*
 * Parse a sequence of calling appropriate routines to parse each sub type
 */
PE
pr_seqof(head, parm, p, mod)
PE      head;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
    PE      pe;
    tpe  *start;		/* first entry in list */
    int	dflt = 0;

    if (p->pe_type != SEQOF_START) {
	    dmp_tpe("pr_seqof:missing SEQOF_START", p, mod);
	    ferr(1, "pr_seqof: missing SEQOF_START\n");
    }
    p++;

    if (p->pe_type == DFLT_B)
	p++;

    start = p;

    pe = first_member(head);
    while (pe != NULLPE) {
	while (p->pe_type != PE_END) {

	    if (_pverbose > 6) {
		printf("dec_seqof with the type %d\n",p->pe_type);
	    }

	    if (ISDTYPE(p) && CHKTAG(mod, p, pe) == 0) {
		if (DEFAULT(p)) {
		    setdval(p, p + 1, parm, mod);
		    goto next;
		} else if (OPTIONAL(p)) {
		    if (ALLOC_MEM(p, parm))
			fix_mem(parm, p);
		    goto next;
		} else {
		    dmp_tpe( "pr_seqof:missing mandatory parameter", p,
		      mod);
		    return (NULLPE);
		}
	    }

	    switch (p->pe_type) {
	    case UCODE:
		if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
		    return (NULLPE);
		break;

	    case ETAG:
		if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
		    return NULLPE;
		break;

	    case MALLOC:
		if ((*parm = (char *)  calloc(1, p->pe_tag)) == NULL)
		    return NULLPE;
		break;

	    case SCTRL:
		parm = (char **) ((char *)*parm + p->pe_ucode);
		break;

	    case SEQ_START:
		if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case SEQOF_START:
		if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case SET_START:
		if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case SETOF_START:
		if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case SOBJECT:
		if ((pe = pr_obj(1, pe, parm,
		  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case OBJECT:
		if ((pe = pr_obj(1, pe, *parm + p->pe_ucode,
		  mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
		    return (NULLPE);
		break;
    
	    case CHOICE_START:
		if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
		break;

	case SEXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_seqof: missing EXTMOD", p, mod);
		ferr(1, "pr_seqof:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, parm);
	    break;

	case EXTOBJ:
	    if (p[1].pe_type != EXTMOD) {
		dmp_tpe("pr_seqof: missing EXTMOD", p, mod);
		ferr(1, "pr_seqof:internal error\n");
	    }
	    dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
		(char **) 0, *parm + p->pe_ucode);
	    break;

	    default:
		if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
		    return (NULLPE);
		break;
	    }

	    if (ISDTYPE(p) && dflt == 0)
		pe = next_member(head, pe);
	next:
	    NEXT_TPE(p);
	}
	parm = (char **)(*parm + p->pe_ucode);
	p = start;
    }

    return (head);

}

/*
 * Parse a setof, calling appropriate routines to parse each sub type
 */
PE
pr_setof(head, parm, p, mod)
PE      head;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
	PE      pe;
	int	dflt;
	tpe	*start;

	if (p->pe_type != SETOF_START)
		ferr(1, "pr_setof: missing SETOF_START\n");
    p++;

    if (p->pe_type == DFLT_B)
	p++;

	start = p;
	pe = first_member(head);

	for (pe = first_member(head); pe; pe = next_member(head, pe)) {
		while (p->pe_type != PE_END) {
		    if (_pverbose > 6) {
			printf("dec_seqof with the type %d\n", p->pe_type);
		    }

		    if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
			if (DEFAULT(p)) {
			    setdval(p, p + 1, parm, mod);
			    goto next;
			} else {
			    dmp_tpe( "pr_setof:missing mandatory parameter",
			     p, mod);
				return (NULLPE);
			}
		    }
			else
			    dflt = 0;

		    switch (p->pe_type) {
		    case UCODE:
			    if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
				    return (NULLPE);
			    break;

		    case ETAG:
			    if ((pe = pr_type(1, pe->pe_cons, parm, p, mod)) == NULLPE)
				    return NULLPE;
			    break;

		    case MALLOC:
			    if ((*parm = (char *)  calloc(1, p->pe_tag)) == NULL)
				    return NULLPE;
			    break;

		    case SCTRL:
			    parm = (char **) (*parm + p->pe_ucode);
			    break;

		    case SEQ_START:
			    if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case SEQOF_START:
			    if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case SET_START:
			    if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case SETOF_START:
			    if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case SOBJECT:
			    if ((pe = pr_obj(1, pe, parm,
			    mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case OBJECT:
			    if ((pe = pr_obj(1, pe, *parm + p->pe_ucode,
			    mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
				    return (NULLPE);
			    break;
	    
		    case CHOICE_START:
			    if ((pe = pr_choice(pe, *parm + p->pe_ucode,
			    p, mod)) == NULLPE)
				    return (NULLPE);
			    break;

		    case SEXTOBJ:
			if (p[1].pe_type != EXTMOD) {
			    dmp_tpe("pr_setof: missing EXTMOD", p, mod);
			    ferr(1, "pr_setof:internal error\n");
			}
			dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1,
			    NULL, (char **) 0, parm);
			break;

		    case EXTOBJ:
			if (p[1].pe_type != EXTMOD) {
			    dmp_tpe("pr_setof: missing EXTMOD", p, mod);
			    ferr(1, "pr_setof:internal error\n");
			}
			dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1,
			    NULL, (char **) 0, *parm + p->pe_ucode);
			break;

		    default:
			    if ((pe = pr_type(1, pe, parm, p, mod)) == NULLPE)
				    return (NULLPE);
			    break;
			    /*
			    ferrd(1, "pr_setof: unknown type %d\n", p->pe_type);
			    */
		    }

#if 0
		    /* fixup - we only delete in this function */	
		    if (ISDTYPE(p) && dflt == 0)
			set_del(head, pe->pe_class, pe->pe_id);
#endif
		    next:
			NEXT_TPE(p);
		}
		parm = (char **)(*parm + p->pe_ucode);
		p = start;
	}

	return (head);

}

/*
 * parse a choice field. This means find which choice is taken
 */
PE
pr_choice(head, parm, p, mod)
PE      head;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
    int	*poffset;
    int	cnt;
    PE  pe;

	if (p->pe_type != CHOICE_START) {
	    dmp_tpe("pr_choice:missing CHOICE_START", p, mod);
	    ferrd(1, "pr_choice:illegal table entry %d\n", p->pe_type);
	}
	
	p++;

    if (p->pe_type == DFLT_B)
	p++;

	if (p->pe_type == MALLOC) {
	    if ((*parm = (char *) calloc(1, p->pe_tag)) == NULL)
		return NULLPE;
	    p++;
	}
	if (p->pe_type == SCTRL) {
	    if ((poffset = (int *) (*parm + p->pe_ucode)) == NULL)
		return NULLPE;
	    p++;
	}

	for (cnt = 1; p->pe_type != PE_END; NEXT_TPE(p), cnt++) {
	    if (ISDTYPE(p) && ismatch(p, mod, head->pe_class, head->pe_id)) {
		pe = pr_etype(head, parm, p, mod);
		*poffset = cnt;
		return (pe);
	    }
	}
	dmp_tpe("pr_choice: no choice taken", p, mod);
	return (NULLPE);
}

/*
 * Calculate the next tpe entry in the sequence. Count a sequence as one element
 */
tpe	*
next_tpe(p)
tpe	*p;
{
	int	level;



	level = 0;
	if (p->pe_type == PE_END)
		ferr(1, "next_tpe:PE_END");
	do {
	    again:
		switch (p->pe_type) {
		case SEQ_START:
		case SEQOF_START:
		case SET_START:
		case SETOF_START:
		case CHOICE_START:
			level++;
			break;

		case UCODE:
		case MALLOC:
		case SCTRL:
		case CH_ACT:
		case INTEGER:
		case BOOLEAN:
		case SANY:
		case SCONS_ANY:
		case ANY:
		case CONS_ANY:
		case T_NULL:
		case OBJECT:
		case SOBJECT:
		case BITSTRING:
		case SBITSTRING:
		case OCTETSTRING:
		case SOCTETSTRING:
		case OBJID:
		case SOBJID:
		case OPTL:
		case EXTMOD:
		case DFLT_B:
			break;

		case IMP_OBJ:
		case ETAG:
		case EXTOBJ:
		case SEXTOBJ:
		case DFLT_F:
			p++;
			goto again;

		case PE_END:
			level--;
			break;

		default:
			ferrd(1, "next_tpe: unknown type %d\n", p->pe_type);
		}
		p++;
	} while (level > 0 || p->pe_type == DFLT_B);

	return (p);
}

/*
 * check that pe is non null and that the tag and class match and return
 * zero if the don't
 */
chktag(mod, p, pe)
modtyp  *mod;   /* Module it is from */
tpe	*p;
PE	pe;
{
	int	cl, tag;

	if (pe == NULLPE)
		return (0);
#if 0
	if (p->pe_type == OBJECT && skip_next_tag) /* first time we find skip */
		return (1);
	if (skip_next_tag) {	/* 2nd time reset skip */
	    skip_next_tag = 0;
	    return (1);
	}
#endif
	if (!findcltag(p, mod, &cl, &tag))
		return (0);
	if (pe->pe_id != tag || pe->pe_class != cl)
		return (0);
	
	return (1);
}

#if 0
/*
	test if we need to check the tag associated with the tpe entry p
*/
legal_tag(p)
tpe *p;
{
	int	ret;

	switch (p->pe_type) {
		
		case MALLOC:
		case SCTRL:
		case CH_ACT:
		case ANY:
		case OBJECT:
		case CHOICE_START:
		case CONS_ANY:
	/*	case ETAG:  don't think we should have this here */
			ret = 0;
			break;

		default:
#if 0
			if (skip_next_tag) {
				skip_next_tag = 0;
				ret = 0;
			}
			else
#endif
				ret = 1;
			break;
	}
	return ret;
}
#endif

/*
 * Parse a single type for explicit tag
 * If a basic type parse it, if a compound type call the appropriate
 * parsing routine
 */
PE
pr_etype(pe, parm, p, mod)
PE      pe;
PEPYPARM parm;
tpe	*p;
modtyp	*mod;	/* Module it is from */
{
    switch (p->pe_type) {
    case PE_END:
    case PE_START:
	    return (NULLPE);

    case UCODE:
	    if ((*mod->md_ducode)(pe, parm, p, mod) != OK)
		    return (NULLPE);
	    break;

    case ETAG:
	switch (p->pe_ucode) {

	default:
	    p++;
	    if (pr_etype(pe->pe_cons, parm, p, mod) == NULLPE)
		return (NULLPE);
	}
	break;

    case MALLOC:
	    if ((*(parm) = (char *)  calloc(1, p->pe_tag)) == NULL)
		    return NULLPE;
	    break;

    case SEQ_START:
	    if ((pe = pr_seq(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case SEQOF_START:
	    if ((pe = pr_seqof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case SET_START:
	    if ((pe = pr_set(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case SETOF_START:
	    if ((pe = pr_setof(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case IMP_OBJ:
	    p++;
	    if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
		dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 0, NULL,
		   (char **) 0, *parm + p->pe_ucode);
	    } else {
		if (p->pe_type == SOBJECT) {
		    if ((pe = pr_obj(0, pe, parm,
		      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
		} else
		    if ((pe = pr_obj(0, pe, *parm + p->pe_ucode,
		      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
			return (NULLPE);
	    }
	    break;

    case SOBJECT:
	    if ((pe = pr_obj(1, pe, parm,
	      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case OBJECT:
	    if ((pe = pr_obj(1, pe, *parm + p->pe_ucode,
	      mod->md_dtab[p->pe_tag] + 1, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case CHOICE_START:
	    if ((pe = pr_choice(pe, *parm + p->pe_ucode, p, mod)) == NULLPE)
		    return (NULLPE);
	    break;

    case SEXTOBJ:
	if (p[1].pe_type != EXTMOD) {
	    dmp_tpe("pr_etype: missing EXTMOD", p, mod);
	    ferr(1, "pr_etype:internal error\n");
	}
	dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
	    (char **) 0, parm);
	break;

    case EXTOBJ:
	if (p[1].pe_type != EXTMOD) {
	    dmp_tpe("pr_etype: missing EXTMOD", p, mod);
	    ferr(1, "pr_etype:internal error\n");
	}
	dec_f(p->pe_tag, (modtyp *)p[1].pe_ucode, pe, 1, NULL,
	    (char **) 0, *parm + p->pe_ucode);
	break;

    case INTEGER:
	    if (pe != NULLPE) {
			if (_pverbose > 6) {
			    printf("integer value is %d\n",prim2num(pe));
			}
		    if (((*(int *)(*parm + p->pe_ucode)) = prim2num(pe))== NOTOK && pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad integer %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case BOOLEAN:
	    if (pe != NULLPE) {
			if (_pverbose > 6) {
			    printf("boolean value is %d\n",prim2flag(pe));
			}
		    if (((* (char *)(*parm + p->pe_ucode)) = prim2flag(pe))==NOTOK && pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad integer %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case T_NULL:
	    break;

    case ANY:
    case CONS_ANY:
	    if (pe != NULLPE) {
		    (* (PE *) (*parm + p->pe_ucode) = pe) ->pe_refcnt++;
		    if (pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad integer %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case SANY:
    case SCONS_ANY:
	    /* This could require changes when I find out what the CONS_ANY type
	     * is really for
	     */
	    if (pe != NULLPE) {
		    ((PE) (*parm ) = pe) ->pe_refcnt++;
		    if (pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad integer %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case SOCTETSTRING:
	    if (pe != NULLPE) {
		if ((*((struct qbuf **) parm)
		    = prim2qb(pe)) == (struct qbuf *) NULL
		    && pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad octet string %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case OCTETSTRING:
	    if (pe != NULLPE) {
		if ((*((struct qbuf **) (*parm + p->pe_ucode))
		    = prim2qb(pe)) == (struct qbuf *) NULL
		    && pe->pe_errno != PE_ERR_NONE) {
			    printf("pr_etype:bad octet string %s",
				    pe_error(pe->pe_errno));
			    return (NULLPE);
		    }
	    }
	    break;

    case SBITSTRING:
	    if (pe != NULLPE) {
		if (((*(PE *) parm) = pe_cpy(pe)) == NULLPE) {
			    printf("pr_etype:out of memory");
			    return (NULLPE);
		    }
	    }
	    break;

    case BITSTRING:
	    if (pe != NULLPE) {
		if ((*((PE *) (*parm + p->pe_ucode))= pe_cpy(pe)) == NULLPE) {
			    printf("pr_etype:out of memory");
			    return (NULLPE);
		    }
	    }
	    break;

    case SOBJID:
	if ((*(OID *)parm = oid_cpy(prim2oid(pe))) == NULLOID) {
		printf("pr_etype:Object Identifier: out of memory");
		return (NULLPE);
	}
	break;

    case OBJID:
	if ((*(OID *)(*parm + p->pe_ucode) = oid_cpy(prim2oid(pe))) == NULLOID) {
		printf("en_etype:Object Identifier: out of memory");
		return (NULLPE);
	}
	break;

    default:
	    ferrd(1, "pr_etype: %d not implemented\n", p->pe_type);
	    break;
    }

    return (pe);
}

/*
 * determine what the class and tag must be of the given object
 */
findcltag(p, mod, pcl, ptag)
tpe	*p;
modtyp	*mod;	/* Module it is from */
int	*pcl, *ptag;
{
    if (!ISDTYPE(p))
	return (0);
    if (p->pe_type != OBJECT) {
	*pcl = CLASS(p);
	*ptag = TAG(p);
	return (1);
    }
    p = mod->md_dtab[p->pe_tag] + 1;
    while (p->pe_type != PE_END) {
	if (ISDTYPE(p))
            return (findcltag(p, mod, pcl, ptag));
    }
    dmp_tpe("findcltag:warning:object with no data in it", p, mod);
    return (0);
}

/*
 * Is there a match at for this tag and class pair. Return 1 if yes 0 if no
 * We will search through contained objects and through choices
 */
ismatch(p, mod, cl, tag)
tpe     *p;
modtyp  *mod;   /* Module it is from */
unsigned int     cl, tag;
{
    while (!ISDTYPE(p))
	p++;

    switch (p->pe_type) {
    case SOBJECT:
    case OBJECT:
	/* Needs to be changed for optional and default */
	return (ismatch(p = mod->md_dtab[p->pe_tag] + 1, mod, cl, tag));

    case SEXTOBJ:
    case EXTOBJ:
	if (p[1].pe_type != EXTMOD) {
	    dmp_tpe("ismatch: missing EXTMOD", p, mod);
	    ferr(1, "ismatch:internal error\n");
	}
	return(ismatch(((modtyp *)p[1].pe_ucode)->md_dtab[p->pe_tag] + 1,
	    (modtyp *)p[1].pe_ucode, cl, tag));

    case CHOICE_START:
	for (p++; p->pe_type != PE_END; p = NEXT_TPE(p)) {
	    if (!ISDTYPE(p))
		continue;
	    if (ismatch(p, mod, cl, tag))
		return (1);
	}
	return (0);

    case SANY:
    case SCONS_ANY:
	return (1);

    default:
        return (tag == TAG(p) && cl == CLASS(p));
    }
}

/*
 * determine if the given field is present in the data
 * This is simple if the field is a simple type with an obvious tag but
 * in the case of an object or a CHOICE type the tag is not obvious. If the
 * object is a CHOICE there are more than one possible tag that could match
 * and in this case we must try to match each one of them.
 */
PE
setpresent(head, p, mod)
PE	head;
tpe	*p;
modtyp	*mod;
{
    PE	pe;

    if (!ISDTYPE(p))
	return (NULLPE);
    switch (p->pe_type) {
    case OBJECT:
    case SOBJECT:
	/* Needs to be changed for optional and default */
	return (setpresent(head, p = mod->md_dtab[p->pe_tag] + 1, mod));

    case CHOICE_START:
	for (p++; p->pe_type != PE_END; p = NEXT_TPE(p)) {
	    if (!ISDTYPE(p))
		continue;
	    if ((pe = setpresent(head, p, mod)))
		return (pe);
	}
	return (NULLPE);

    default:
        return (set_find(head, CLASS(p), TAG(p)));
    }
}

/*
 * set the default value to that value in the structure
 */
setdval(typ, dflt, parm, mod)
tpe	*typ, *dflt;
char 	**parm;
modtyp	*mod;
{

again:
    switch (typ->pe_type) {
    case MALLOC:
	if ((*(parm) = (char *)  calloc(1, typ->pe_tag)) == NULL)
	    ferrd(1, "setdval:calloc failed on %d\n", typ->pe_tag);
	typ++;
	goto again;

    case INTEGER:
	    *(int *)(*parm + typ->pe_ucode) = IVAL(dflt);
	    break;

    case BOOLEAN:
	     *(char *)(*parm + typ->pe_ucode) = IVAL(dflt);
	    break;

    case T_NULL:
	    /* Only one value */
	    break;	

    case SBITSTRING:
	*(PE *)parm = strb2bitstr(PVAL(dflt), IVAL(dflt), 0, 0);
	break;

    case BITSTRING:
	*(PE *)(*parm + typ->pe_ucode) =
	    strb2bitstr(PVAL(dflt), IVAL(dflt), 0, 0);
	break;

    case SOCTETSTRING:
	*(struct qbuf **)parm = str2qb(PVAL(dflt), IVAL(dflt), 1);
	break;

    case OCTETSTRING:
	*(struct qbuf **)(*parm + typ->pe_ucode) =
	    str2qb(PVAL(dflt), IVAL(dflt), 1);
	break;

    case OBJECT:
	    setdval(mod->md_dtab[typ->pe_tag] + 1, dflt,
	      (char **) (*parm + typ->pe_ucode), mod);
	      break;

    case SOBJECT:
	    setdval(mod->md_dtab[typ->pe_tag] + 1, dflt, parm, mod);
	    break;

    case IMP_OBJ:
	typ++;

    case SCONS_ANY:
    case ANY:
    case CONS_ANY:
    case SANY:
    case SEXTOBJ:
    case EXTOBJ:
    case OBJID:
    case SOBJID:
    case SEQ_START:
    case SET_START:
    case -1:	/* Just use the pepy method of null pointers */
	/* This is the posy/pepy hack way of doing things at the moment */
	    *(char **)(*parm + typ->pe_ucode) = NULL;
	    break;

    default:
	/* dmp_tpe("setdval: type not implemented", typ, mod); - need mod*/
	ferrd(1, "setdval: %d not implemented\n", typ->pe_type);
	break;
    }

}
/*
 * fix up the allocation of memory. We have allocated memory for an optional
 * object that is not present. ISODE routines get upset if this is present
 * because it then believes the object is present and tries to process it ...
 */
fix_mem(parm, p)
char	**parm;
tpe	*p;
{
    if (p->pe_type != SOBJECT || p[-1].pe_type != MALLOC
	|| p[1].pe_type != PE_END)
	ferr(1, "fix_mem:inconsistency\n");
    if (*parm)
	free(*parm);
    *parm = NULL;
}