Net2/usr/src/contrib/isode/pepsy/dtabs.c

/* dtabs.c */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/pepsy/RCS/dtabs.c,v 7.10 91/02/22 09:48:47 mrose Interim $";
#endif

/* 
 * $Header: /f/osi/pepsy/RCS/dtabs.c,v 7.10 91/02/22 09:48:47 mrose Interim $
 *
 *
 * $Log:	dtabs.c,v $
 * Revision 7.10  91/02/22  09:48:47  mrose
 * Interim 6.8
 * 
 * Revision 7.9  91/01/08  12:49:21  mrose
 * update
 * 
 * Revision 7.8  90/12/23  17:24:26  mrose
 * patches
 * 
 * Revision 7.7  90/12/11  10:33:19  mrose
 * sync
 * 
 * Revision 7.5  90/11/11  09:58:51  mrose
 * touch-up
 * 
 * Revision 7.4  90/11/04  19:18:21  mrose
 * update
 * 
 * Revision 7.3  90/08/18  00:44:15  mrose
 * touch-up
 * 
 * Revision 7.2  90/07/27  08:49:09  mrose
 * update
 * 
 * Revision 7.1  90/07/09  14:52:25  mrose
 * sync
 * 
 * Revision 7.0  90/07/01  19:54:15  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.
 *
 */


#include <stdio.h>
#include "pepsydefs.h"
#include "pass2.h"
#include "mine.h"
#include <ctype.h>


extern FILE *fp;
extern char *c_tag(), *c_class();
extern char *ec_tag(), *ec_class();
extern char *strip_last();
extern char *str_yp_code[];
extern char *get_val(), *get_comp(), *strp2name();
extern s_table *lookup_list(), *get_offset();
extern YP tdec_loop();

extern char *concat();
extern char *my_strcat();
extern char	*rm_indirect();
extern char	*getfield();
extern char	*setfield();

extern int	gen_sentry();

/* extern int explicit; */

#define WORDSIZE	20

/*
 * table encode a type. generate tables for the encoding of a type
 */
tdec_typ(fp, yp, id, type)
FILE	*fp;
YP      yp;
char   *id;
char   *type;
{
    char   *t, *f;
    char   *p1;
    char   *s1, *s2, *s3;
    char   *s;
    s_table *ptr1, *ptr2;
    YP      y;
    YAL	yal;

    if (yp->yp_code < 0 || yp->yp_code > YP_REAL)
	ferrd(1, "tdec_typ: unimplemented type %d\n", yp->yp_code);

    if (yp == NULL) {
	ferr(0, "tdec_typ:NULL arguement\n");
	return;
    }

    if (type)
	t = type;
    else if (yp->yp_param_type) {
	char *t1;
	/* we have a [[ P type ]] specification */
	if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
	    fprintf(stderr,
	    "\ntdec_typ:SETLIST can't extract direct type from %s\n",
		yp->yp_param_type);
	    exit(1);
	}
	t = strdup(t1);
    } else
	t = my_strcat("struct ", modsym(mymodule, id, "type"));

    if (yal = yp->yp_bef_alist) {
	yal->yal_type = t;
	if (yal->yal_dec)
	    gen_act(fp, yp->yp_bef_alist->yal_dec);
    }
    if (yal = yp->yp_aft_alist) {
	yal->yal_type = t;
    }
    if (yal = yp->yp_control_act)
	yal -> yal_type = t;

    if (yal = yp->yp_optional_act)
	yal -> yal_type = t;

    if (type == NULLCP) {
	switch (yp->yp_code) {
	    /*
	     * These generate MEMALLOC entries inside *_START ..
	     * PE_END fields for historical reasons. One day we might
	     * fix this to be all done the same way.
	     */
	case YP_SEQLIST:
	case YP_SEQTYPE:
	case YP_SETLIST:
	case YP_SETTYPE:
	case YP_CHOICE:
	    break;

	default:
	    if (yp->yp_varexp == NULL)
		break;		/* S* type entry - doesn't need a
				 * malloc */

	    (void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n", t);
	    break;
	}
    }


    if ((yp->yp_flags & YP_PARMVAL) && yp->yp_parm) {
	if ((f = getfield(yp->yp_parm)) == NULLCP) {
	    fprintf(stderr, "\ntdec_typ: can't extract field from %s\n",
		yp->yp_parm);
	    exit(1);
	}
	f = strdup(f);
    } else
	f = yp->yp_varexp;

    if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
	== (YP_OPTIONAL|YP_OPTCONTROL)) {
	char *f1;
	char *bitno;

	if (yp -> yp_optional_act && yp -> yp_optional_act -> yal_dec) {
	    (void) fprintf (fp, "\t{ BOPTIONAL, %d, 0, FL_USELECT},\n",
			    control_act(yp -> yp_optional_act -> yal_dec));
	}
	else {
	    if ((f1 = getfldbit(yp->yp_optcontrol, &bitno)) == NULLCP) {
		fprintf(stderr,
			"\ntdec_typ:BOPTIONAL: can't extract field from %s\n",
			yp->yp_optcontrol);
		exit(1);
	    }
	    (void) fprintf(fp, "\t{ BOPTIONAL, AOFFSET(%s, %s), %s, 0},\n", t,
			   f1, bitno);
	}
    }

    if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) {
	(void) fprintf(fp, "\t{ ETAG, 0, ");
	(void) fprintf(fp, "%s, %s },\n", ec_tag(yp), ec_class(yp));
    }

    if (yp->yp_yfn && yp->yp_yfn->yfn_dec) {

	gen_fn(fp, yp, yp->yp_yfn->yfn_dec);

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);

	if (gen_freefn(fp, yp)) {
	    if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec)
		gen_act(fp, yp->yp_aft_alist->yal_dec);
	    return;
	}
    }

    switch (yp->yp_code) {

    case YP_UNDF:
	ferr(1, "tdec_typ:Undefined type\n");

    case YP_BOOL:
	if (yp->yp_intexp)
	    f = setfield(yp->yp_intexp);
	if (noindirect(f))
	    ferr(1, "tdec_typ:BOOL: must specify a field for boolean\n");
	p1 = "BOOLEAN";
	if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f)))
	    break;
	ferr(1, "tdec_typ:BOOL: couldn't determine type\n");

	/* This needs to be fixed up in the action generating area */
    case YP_INTLIST:

    case YP_INT:

    case YP_ENUMLIST:
	if (yp->yp_intexp)
	    f = setfield(yp->yp_intexp);
	if (noindirect(f))
	    ferr(1, "tdec_typ:INT: must specify a field for an integer\n");
	if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
	    p1 = "INTEGER";
	    break;
	}
	ferr(1, "tdec_typ:INT: couldn't determine type\n");
	break;

    case YP_REAL:
	if (yp->yp_strexp)
	    f = setfield(yp->yp_strexp);
	if (noindirect(f))
	    ferr(1, "tdec_typ:REAL: must specify a field for a REAL\n");
	if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
	    p1 = "REALTYPE";
	    break;
	}
	ferr(1, "tdec_typ:REAL: couldn't determine type\n");
	break;


    case YP_BIT:
    case YP_BITLIST:
	if (yp->yp_strexp && yp->yp_intexp) {
	    if (yp->yp_strexp)
		f = setfield(yp->yp_strexp);
	    if (noindirect(f))
		ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n");
	    p1 = "BITSTR_PTR";
	    prnte(fp, t, f, yp, p1);
	    if (yp->yp_intexp)
		f = setfield(yp->yp_intexp);
	    if (noindirect(f))
		ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n");
	    p1 = "BITSTR_LEN";
	    break;
	}
	if (yp->yp_strexp == NULLCP && yp->yp_intexp)
	    f = setfield(yp->yp_intexp);
	if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
	    p1 = "BITSTRING";
	    break;
	}
	t = NULL;
	p1 = NULL;
	(void) fprintf(fp, "\t{ SBITSTRING, 0, %s, %s },\n",
		c_tag(yp), c_class(yp));
	break;

    case YP_OCT:
	if (yp->yp_strexp) {
	    switch (yp->yp_prfexp) {
	    case 'q': /* [[ q parm->qbufptr ]] */
		if (yp->yp_strexp)
		    f = setfield(yp->yp_strexp);
		if (noindirect(f))
		    p1 = "SOCTETSTRING";
		else
		    p1 = "OCTETSTRING";
		break;

	    case 's': /* [[ s ptr ]] */
		if (yp->yp_strexp)
		    f = setfield(yp->yp_strexp);
		if (noindirect(f))
		    ferr(1, "tdec_typ:OCTET: must specify a field [[ s .. ]]\n");
		p1 = "T_STRING";
		break;
		
	    case 'o': /* [[ o ptr $ length ]] */
		if (yp->yp_strexp)
		    f = setfield(yp->yp_strexp);
		if (noindirect(f))
		    ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. ]]\n");
		p1 = "OCTET_PTR";
		prnte(fp, t, f, yp, p1);
		if (yp->yp_intexp)
		    f = setfield(yp->yp_intexp);
		if (noindirect(f))
		    ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. $ .. ]]\n");
		p1 = "OCTET_LEN";
		break;

	    default:
	       fprintf(stderr,"\ntdec_typ: Unknown Octet string specifier %c\n",
		   yp->yp_prfexp);
		exit(1);
	    }
	    break;
	}
	if (f) {
	    p1 = "OCTETSTRING";
	    break;
	}
	t = NULL;
	p1 = NULL;
	(void) fprintf(fp, "\t{ SOCTETSTRING, 0, %s, %s },\n",
		c_tag(yp), c_class(yp));
	break;

    case YP_OID:
	if (yp->yp_strexp)
	    f = setfield(yp->yp_strexp);
	if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
	    p1 = "OBJID";
	    break;
	}
	t = NULL;
	p1 = NULL;
	(void) fprintf(fp, "\t{ SOBJID, 0, %s, %s },\n",
		c_tag(yp), c_class(yp));
	break;

    case YP_SEQ:
    case YP_SET:
    case YP_ANY:
	if (yp->yp_strexp)
	    f = setfield(yp->yp_strexp);
	if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
	    p1 = "ANY";
	    break;
	}
	t = NULL;
	p1 = NULL;
	(void) fprintf(fp, "\t{ SANY, 0, %s, %s },\n",
		c_tag(yp), c_class(yp));
	break;

    case YP_NULL:
	p1 = "T_NULL";
	t = NULL;
	break;

    case YP_IDEFINED:
	p1 = NULL;

	if ((yp->yp_flags & YP_PARMVAL) && yp->yp_prfexp)
		ferr(1,
    "\n[[ ? reference ]] [[ p reference ]] is illegal\n\t only one allowed\n");

	if (yp->yp_prfexp) { /* [[ ? parm->field ]] - complex to process */
	    gen_identry(fp, t, f, yp, gen_ventry);

	    if (yp->yp_flags & YP_DEFAULT)
		gdflt(fp, yp, G_DEC);

	    break;
	}

	{
	    /* Predefined Universal Type */
	    struct univ_typ *p, *univtyp();

	    if ((p = univtyp(yp->yp_identifier))) {
		if (p->univ_flags & UNF_EXTMOD) {
		    yp->yp_module = p->univ_mod;
		    goto do_obj;
		}
		if (f == NULL || noindirect(f)) {/* No offset type */
		    if (yp->yp_flags & YP_TAG
			&& yp->yp_flags & YP_IMPLICIT)
				prstfield(fp, p->univ_tab, t, f,
                                int2tstr(yp->yp_tag->yt_value->yv_number),
                                c_flags(yp, yp->yp_tag->yt_class));
		    else
                        prstfield(fp, p->univ_tab, t, f, int2tstr(p->univ_id),
                                c_flags(yp, p->univ_class));
		    goto out;
		}
		if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
                        prtfield(fp, p->univ_tab, t, f,
                            int2tstr(yp->yp_tag->yt_value->yv_number),
                            c_flags(yp, yp->yp_tag->yt_class));
		else
                    prtfield(fp, p->univ_tab, t, f, int2tstr(p->univ_id),
                            c_flags(yp, p->univ_class));
		goto out;
	    }
	}
do_obj:
	if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
	    (void) fprintf(fp, "\t{ IMP_OBJ, 0, %s, %s },\n", c_tag(yp), c_class(yp));
	if (yp->yp_module == NULL
	    || strcmp(yp->yp_module, mymodule) == 0) {
	    if (f == NULL || noindirect(f))
                  prstfield(fp, "OBJECT", t, f,
                      concat("_Z", proc_name(yp->yp_identifier, 0)),
                      c_class(yp));
	    else
                  prtfield(fp, "OBJECT", t, f,
                      concat("_Z", proc_name(yp->yp_identifier, 0)),
                      c_class(yp));

	} else {
	    if (f == NULL || noindirect(f))
                  prstfield(fp, "EXTOBJ", t, f,
                      concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
                        c_class(yp));
	    else
                  prtfield(fp, "EXTOBJ", t, f,
                      concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
                        c_class(yp));
	    (void) fprintf(fp, "\t{ EXTMOD, %d, 0, 0 },\n",
		    gen_modref(yp->yp_module));
	}
    out:
	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);
	break;

    case YP_SEQLIST:
	p1 = NULL;
	/* support for -h flag */
	if (yp->yp_varexp == NULL && type != NULL)
	    ferr(1, "tdec_typ:YP_SEQLIST:NULL varexp pointer\n");
	prcte(fp, type, t, f, yp, "SEQ_START");

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);
	if (y = yp->yp_type) {
	    char *t1;

	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
		    "\ntdec_typ:SEQLIST can't extract direct type from %s\n",
			yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_SEQLIST:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;

	    if (!type || !noindirect(f))
		genmalloc(fp, yp);

	    if (optfield(y)) {
		(void) fprintf(fp,
			"\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
			yp->yp_structname);
	    }
	    tdec_loop(fp, y, id, yp->yp_structname);
	}
	(void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
	break;

    case YP_SETLIST:
	p1 = NULL;
	/* support for -h flag */
	p1 = NULL;
	if (yp->yp_varexp == NULL && type != NULL)
	    ferr(1, "tdec_typ:YP_SETLIST:NULL varexp pointer\n");
	prcte(fp, type, t, f, yp, "SET_START");

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);
	if (y = yp->yp_type) {
	    char *t1;

	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
		    "\ntdec_typ:SETLIST can't extract direct type from %s\n",
			yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_SETLIST:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;

	    if (!type || !noindirect(f))
		genmalloc(fp, yp);

	    if (optfield(y)) {
		(void) fprintf(fp,
			"\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
			yp->yp_structname);
	    }
	    tdec_loop(fp, y, id, yp->yp_structname);
	}
	(void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
	break;

    case YP_SEQTYPE:		/* What is the difference ?? */
	p1 = NULL;
	prcte(fp, type, t, f, yp, "SEQOF_START");

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);

	if (y = yp->yp_type) {
	    char *t1;

	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
		    "\ntdec_typ:SEQTYPE can't extract direct type from %s\n",
			yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_SEQTYPE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;

	    if (!type || !noindirect(f))
		genmalloc(fp, yp);

	    tdec_loop(fp, y, id, yp->yp_structname);
	}
	if (yp->yp_flags & YP_CONTROLLED) {
	    char *f1;

	    if ((f1 = getfield(yp->yp_control)) == NULLCP) {
		fprintf(stderr, "\ntdec_typ:SEQ OF: can't extract field from %s\n",
		    yp->yp_control);
		exit(1);
	    }
	    (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
		    yp->yp_structname, f1);
	} else if (yp->yp_structname != NULL)
	    (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
		    yp->yp_structname);
	else
	    (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
	break;

    case YP_SETTYPE:
	p1 = NULL;
	prcte(fp, type, t, f, yp, "SETOF_START");

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);

	if (y = yp->yp_type) {
	    char *t1;


	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
		    "\ntdec_typ:SETTYPE can't extract direct type from %s\n",
			yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_SETTYPE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;

	    if (!type || !noindirect(f))
		genmalloc(fp, yp);

	    tdec_loop(fp, y, id, yp->yp_structname);
	}
	if (yp->yp_flags & YP_CONTROLLED) {
	    char *f1;

	    if ((f1 = getfield(yp->yp_control)) == NULLCP) {
		fprintf(stderr, "\ntdec_typ:SET OF: can't extract field from %s\n",
		    yp->yp_control);
		exit(1);
	    }
	    (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
		    yp->yp_structname, f1);
	} else if (yp->yp_structname != NULL)
	    (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
		    yp->yp_structname);
	else
	    (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
	break;

    case YP_CHOICE:
	p1 = NULL;
	/* support for -h flag */
	if (hflag && (y = yp->yp_type) && !y->yp_next) {
	    tdec_typ(fp, y, id, yp->yp_structname);
	    break;
	}
	if (type == NULL || type && noindirect(f))
	    prstfield(fp, "CHOICE_START", t, f, 0, c_class(yp));
	else
	    prtfield(fp, "CHOICE_START", t, type ? f : NULLCP, 0, c_class(yp));

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);
	if (y = yp->yp_type) {
	    char *t1;

	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
		    "\ntdec_typ:CHOICE can't extract direct type from %s\n",
			yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_CHOICE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;

	    if (!type || !noindirect(f))
		genmalloc(fp, yp);


	    if (yp -> yp_control_act && yp->yp_control_act->yal_dec) {
		(void) fprintf (fp, "\t{ SCTRL, %d, 0, FL_USELECT },\n",
				control_act(yp->yp_control_act -> yal_dec));
	    }
	    else if (yp->yp_flags & YP_CONTROLLED) {
		char *f1;

		if ((f1 = getfield(yp->yp_control)) == NULLCP) {
		    fprintf(stderr, "\ntdec_typ:CHOICE: can't extract field from %s\n",
			    yp->yp_control);
		    exit(1);
		}
		(void) fprintf(fp, "\t{ SCTRL, OFFSET(%s, %s), 0, 0 },\n",
			       yp->yp_structname, f1);
	    } else if (yp->yp_structname != NULL)
	        (void) fprintf(fp,"\t{ SCTRL, OFFSET(%s, offset), 0, 0 },\n",
			       yp->yp_structname);
	    else
		ferr(1, "\nCHOICE missing SCTRL\n");

	    if (yp->yp_param_type) {
		/* we have a [[ P type ]] specification */
		if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
		    fprintf(stderr,
			    "\ntdec_typ:CHOICE can't extract direct type from %s\n",
			    yp->yp_param_type);
		    exit(1);
		}
		yp->yp_structname = strdup(t1);
	    } else if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tdec_typ:YP_CHOICE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    tdec_loop(fp, y, id, yp->yp_structname);
	}
	(void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
	break;

    default:
	ferrd(1, "tdec_typ: yp_code = %d  not implemented\n", yp->yp_code);
    }

    if (p1 != NULL) {
	prnte(fp, t, f, yp, p1);

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(fp, yp, G_DEC);
    }

    if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec)
	gen_act(fp, yp->yp_aft_alist->yal_dec);

}

static int fflags[] = {
    0, 1, 2, 2, 3, 3, 4, 5, 16, 16, 16, 17, 17, 17,
0, -1, 7,};

/*
 * generate tables for encoding a contructed type
 */
YP 
tdec_loop(fp, yp, id, type)
FILE	*fp;
YP      yp;
char   *id;
char   *type;
{
    for (; yp != NULL; yp = yp->yp_next) {
	tdec_typ(fp, yp, id, type);
    }
}
/*
 * Generate a malloc of for the given object
 */
genmalloc(fp, yp)
FILE	*fp;
YP      yp;
{
    if (hasdatstr(yp))
	(void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n",
	    yp->yp_structname);
}
/*
 * Has Data Structure,
 * determine if this type needs a data structure allocated to it - calls
 * itself recursively to handle the cases of pulled up types
 * returns non zero if it does need a type allocated for it
 */
hasdatstr(yp)
YP      yp;
{
    YP	    y;
    YP	yp1;
    struct univ_typ	*p;

   switch (yp -> yp_code) {
 	case YP_BIT: 
	case YP_BITLIST: 
	case YP_SEQ: 
	case YP_SET: 
	case YP_ANY: 
	case YP_OCT: 
	case YP_OID: 
	    break;

	case YP_IDEFINED: 

	yp1 = lkup(yp);

	if (yp1->yp_code == YP_IDEFINED) {
	    if ((p = univtyp(yp1->yp_identifier)) == NULL
	      || p->univ_type <= YP_UNDF) {
		    return (1);	/* we can't tell unless we know what this is */
		    /* ferr(0, "\tcomptag:treated as implicit\n"); */
		}
		if (p->univ_flags & UNF_HASDATA)
		    return (1);
		return (0);
	} else
	    return (hasdatstr(yp1));

	case YP_SEQLIST: 
	case YP_SETLIST: 
	case YP_CHOICE: 
	    if (hflag && (y = yp -> yp_type) && !y -> yp_next) {
		return (hasdatstr(y));
	    }
	    /* else fall */

	default: 
	    return (1);
    }
    return (0);
}

int control_act (act)
Action act;
{
    register char *p;

    for (p = act -> a_data; *p; p++)
	if (!isspace (*p) && *p == '0')
	    return -1;
    return act -> a_num;
}

/*
 * generate an entry for the freeing routines
 * if there is a freeing function just call that
 * if not specify the type and offset so the free routines know how to free it
 * return non zero if we don't want the normal decoding entry to be
 * generated after us for freeing purposes.
 */
gen_freefn(fp, yp)
FILE	*fp;
YP	yp;
{
    char	*p1;
    char	*fn;

    if (yp->yp_yfn && (fn = yp->yp_yfn->yfn_fre)) {
	(void) fprintf(fp, "\t{ FFN_CALL, %d, 0, 0, },\n", addptr(fn));
	return (1);	/* don't free as per normal */
    }

    (void) fprintf(fp, "\t{ FREE_ONLY, 0, 0, 0, },\n");
    return (0);
    
}