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 e

⟦c59473fa4⟧ TextFile

    Length: 42108 (0xa47c)
    Types: TextFile
    Names: »etabs.c«

Derivation

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

TextFile

/* Copyright 1989 CSIRO Division of Information Technology 
 * May be given away but not sold for profit - See Copyright file for details
 */
#include <stdio.h>
#include <ctype.h>
#include "pepy.h"
#include "posy.h"
#include "pass2.h"
#include "mine.h"

s_table *head;

extern s_table *lookup_list(), *proc_def();

extern	FILE	*fptab;
extern	char	*c_tag(), *c_class();
extern	char	*ec_tag(), *ec_class();
extern	char	*strip_last();
extern	char	*get_val(), *get_comp(), *get_string();
extern	s_table	*get_offset();
extern	char	*my_strcat(), *strp2name();
extern	char	*my_new_str();
extern	char	*mymodule;
extern	char	*modsym();
extern	char	*concat();
extern  char	*genlabel();
extern char	*notidtoid();
extern YV	calc_yv();
extern SY	syfind();
static	s_table	*en_ptr;
extern	s_table	*ptr;

static	int	cons_type = 0;
int	explicit;

s_table	*save_ptr;

#define WORDSIZE	20
#define MAXNAME		256	/* maximum size of a identifier */

#ifdef	DEB
char	*str_yp_code[] = {
	"Undefined", "Boolean", "Integer", "Named number list", "Bitstring",
	"Named Bitstring list", "Octet String", "Null", "Sequence",
	"Sequence of", "Sequence list", "Set", "Set of", "Set list",
	"Choice", "Any", "Object Identifier",
	"", "", "", "", "", "", "", "",
	"", "", "", "", "", "", "", "Identifier",

	};
#endif

/*
 * table encode a type. generate tables for the encoding of a type
 */
tenc_typ(yp, id, type)
YP      yp;
char	*id;
char	*type;
{

	char	*t, *f;
	char	*p1;
	char	*s1, *s2, *s3;
	char 	*s;
	s_table	*ptr1, *ptr2;
	YP	y;


	if (yp->yp_code < 0 || yp->yp_code > YP_IDEFINED)
		ferrd(1, "tenc_typ: bad code %d\n", yp->yp_code);
#ifdef DEB
	Printf(1, ("tenc_typ code = %s\n", str_yp_code[yp->yp_code]));
#endif

#if 0
	Printf(2, ("\n**** %s ****\n",yp->yp_param_type));
	Printf(2, ("**** %s ****\n",yp->yp_intexp));
	Printf(2, ("**** %s ****\n",yp->yp_strexp));
	if (yp->yp_prfexp != NULL)
		Printf(2, ("**** %c ****\n",yp->yp_prfexp));
#endif
	if (yp->yp_id != NULL)
		Printf(2, ("**** %s ****\n",yp->yp_id));

	if (yp == NULL) {
		ferr(0, "tenc_typ:NULL argument\n");
		return;
	}
#if 0
	if (yp->yp_param_type) {
		add_list(yp->yp_param_type, "parm");
		head->defined++;
		en_ptr = head;
	}
	if (yp->yp_action0) {
		s = new_string(yp->yp_action0);
		parse_decl(&s, &s1, &s2);
		while (*s != '\0') {
			add_list(s1, s2);
			parse_decl(&s, &s1, &s2);
		}
	}
#endif

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

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

	/* Preserve the type of the containing object */
	if (type)
	    t = type;
	else
	    t = my_strcat("struct ", modsym(mymodule, id, "type"));
#if 0
	if (yp->yp_ptrname)
	    f = yp->yp_ptrname;
	else
#endif
	f = yp->yp_varexp;
	switch (yp->yp_code) {

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

	case YP_BOOL:
		p1 = "BOOLEAN";
		if (yp->yp_varexp) {
#if 0
			s = new_string(yp->yp_varexp);
			get_val(&s); /* skip */
			f = get_val(&s);
			t = concat("struct ", modsym(mymodule, id, "type"));
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1)
				ferr(0, "tenc_typ: Offset is incorrect (Boolean)\n");
			t = ptr1->type;
#endif
		}
		else
			t = NULL;
		break;

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

	case YP_INT:
		if (yp->yp_varexp) {
		    p1 = "INTEGER";
		    break;
#if 0
			s = new_string(yp->yp_varexp);
			get_val(&s); /* skip */
			f = get_val(&s);
			t = concat("struct ", modsym(mymodule, id, "type"));
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1)
				ferr(0, "tenc_typ: Offset is incorrect (Integer)\n");
			t = ptr1->type;
#endif
		}
		t = NULL;
		p1 = NULL;
		fprintf(fptab,"\t{ SINTEGER, 0, %s, %s },\n",
		    c_tag(yp), c_class(yp));
		break;
	
	case YP_BIT:
	case YP_BITLIST:
		if (yp->yp_varexp) {
		    p1 = "BITSTRING";
		    break;
#if 0
			s = new_string(yp->yp_varexp);
			get_val(&s); /* skip */
			f = get_val(&s);
			t = concat("struct ", modsym(mymodule, id, "type"));
			s1 = get_val(&s);
			s1 = get_val(&s);
			if (strcmp(f = get_val(&s), "len")) {
				ptr1 = lookup_list(s1);
				t = ptr1->type;
			}
			else
				t = NULL;
#endif
		}
		t = NULL;
		p1 = NULL;
		fprintf(fptab,"\t{ SBITSTRING, 0, %s, %s },\n",
		    c_tag(yp), c_class(yp));
		break;
	
	case YP_OCT:
		if (yp->yp_varexp) {
		    p1 = "OCTETSTRING";
		    break;
#if 0
			s = new_string(yp->yp_varexp);
			get_val(&s); /* skip */
			f = get_val(&s);
			t = concat("struct ", modsym(mymodule, id, "type"));
			s1 = get_val(&s);
			if ((f = get_val(&s)) == NULL) {
				if (en_ptr != head)
					ferr(0, "tenc_typ: Offset is incorrect Octet String\n");
				t = NULL;
				break;
			}
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1)
				ferr(0, "tenc_typ: Offset is incorrect (Octet String)\n");
			t = ptr1->type;
#endif
		}
		t = NULL;
		p1 = NULL;
		fprintf(fptab,"\t{ SOCTETSTRING, 0, %s, %s },\n",
		    c_tag(yp), c_class(yp));
		break;

	case YP_OID:
		if (yp->yp_varexp) {
		    p1 = "OBJID";
		    break;
#if 0
			s = new_string(yp->yp_varexp);
			s1 = get_val(&s);
			if ((f = get_val(&s)) == NULL) {
				if (en_ptr != head)
					ferr(0, "tenc_typ: Offset is incorrect Object Identifier\n");
				t = NULL;
				break;
			}
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1)
				ferr(0, "tenc_typ: Offset is incorrect (Object Identifier)\n");
			t = ptr1->type;
#endif
		}
		t = NULL;
		p1 = NULL;
		fprintf(fptab,"\t{ SOBJID, 0, %s, %s },\n",
		    c_tag(yp), c_class(yp));
		break;
	

	case YP_SEQ:
	case YP_SET:
	case YP_ANY:
		/*
		if (cons_type)
			p1 = "CONS_ANY";
		else
		*/
		if (yp->yp_varexp) {
		    p1 = "ANY";
		    break;
#if 0
			s = new_string(yp->yp_varexp);
			s1 = get_val(&s);
			if ((f = get_val(&s)) == NULL) {
				if (en_ptr != head)
					ferr(0, "tenc_typ: Offset is incorrect (Seq/Set/Any)\n");
				if (cons_type)
					ferr(1, "tenc_typ: variable cons_type incorrectly used\n");
				t = NULL;
				break;
			}
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1)
				ferr(0, "tenc_typ: Offset is incorrect (Seq/Set/Any)\n");
			t = ptr1->type;
#endif
		}
		t = NULL;
		p1 = NULL;
		fprintf(fptab,"\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;
		{
		    /* 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) { /* No offset type */
			    if (yp->yp_flags & YP_TAG
			      && yp->yp_flags & YP_IMPLICIT)
				fprintf(fptab,"\t{ S%s, 0, %d, %s },\n",
				    p->univ_tab, 
				    yp->yp_tag->yt_value->yv_number,
				    c_flags(yp, yp->yp_tag->yt_class));
			    else
				fprintf(fptab,"\t{ S%s, 0, %d, %s },\n",
				    p->univ_tab, p->univ_id,
				    c_flags(yp, p->univ_class));
			    break;
			}

			if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
			    fprintf(fptab,"\t{ %s, OFFSET(%s, %s), %d, %s },\n",
				p->univ_tab, t, f,
				yp->yp_tag->yt_value->yv_number,
				c_flags(yp, yp->yp_tag->yt_class));
			else
			    fprintf(fptab,"\t{ %s, OFFSET(%s, %s), %d, %s },\n",
				p->univ_tab, t, f, p->univ_id,
				c_flags(yp, p->univ_class));
			break;
		    }
		}
	    do_obj:
		if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
			fprintf(fptab, "\t{ IMP_OBJ, 0, %s, %s },\n", c_tag(yp), c_class(yp));
		if (yp->yp_parm) {
			ferr(1, "tenc_typ:YP_IDEFINED:yp_parm found\n");
#if 0
			Printf(2, ("yp parm is %s \n",yp->yp_parm));
			Printf(2, ("yp identifier is %s \n",yp->yp_identifier));
			s = new_string(yp->yp_parm);
			s1 = get_val(&s);
			if ((f = get_val(&s)) == NULL) {
				if (en_ptr != head)
					ferr(0, "tenc_typ: Offset is incorrect (Idefined)\n");
				fprintf(fptab, "\t{ OBJECT, 0, _Z%s, 0 },\n", proc_name(yp->yp_identifier, 0));
				break;
			}
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1) {
				ferr(0, "tenc_typ: Offset is incorrect (Idefined)\n");
				fprintf(fptab, "\t{ OBJECT, 0, _Z%s, 0 },\n", proc_name(yp->yp_identifier, 0));
			}
			else
				fprintf(fptab, "\t{ OBJECT, OFFSET(%s, %s), _Z%s, 0 },\n", ptr1->type, f, proc_name(yp->yp_identifier, 0));
#endif
		}
		if (yp->yp_module == NULL
		|| strcmp(yp->yp_module, mymodule) == 0) {
		    if (f == NULL) { /* No offset type */
			fprintf(fptab,"\t{ SOBJECT, 0, _Z%s, %s },\n",
			    proc_name(yp->yp_identifier, 0), c_class(yp));
		    } else
			fprintf(fptab,
			"\t{ OBJECT, OFFSET(%s, %s), _Z%s, %s },\n",
			t, f, proc_name(yp->yp_identifier, 0), c_class(yp));
		} else {
		    if (f == NULL) { /* No offset type */
			fprintf(fptab,"\t{ SEXTOBJ, 0, _Z%s, %s },\n",
			    strp2name(yp->yp_identifier, yp->yp_module),
			    c_class(yp));
		    } else 
			fprintf(fptab,
			"\t{ EXTOBJ, OFFSET(%s, %s), _Z%s, %s },\n",
			t, f, strp2name(yp->yp_identifier, yp->yp_module),
			c_class(yp));

		    fprintf(fptab,"\t{ EXTMOD, (int )&%s%s%s, 0, 0 },\n",
			PREFIX, yp->yp_module, MODTYP_SUFFIX);
		}
		break;
	
	case YP_SEQLIST:
		p1 = NULL;
		cons_type++;
		save_ptr = en_ptr;
		if (yp->yp_varexp == NULL && type != NULL) 
		    ferr(1, "tenc_typ:YP_SEQLIST:NULL varexp pointer\n"); 
#if 0
                s = new_string(yp->yp_varexp);
                get_val(&s);
                f = get_val(&s);
                t = concat("struct ", modsym(mymodule, id, "type"));
#endif
		if (type != NULL)
		    fprintf(fptab,"\t{ SEQ_START, OFFSET(%s, %s), %s, %s },\n",
			t, f, c_tag(yp),c_class(yp));
		else
		    fprintf(fptab,"\t{ SEQ_START, 0, %s, %s },\n",
			c_tag(yp),c_class(yp));
#if 0
		if ((en_ptr = get_offset(yp, 0)) != NULL) 
			if (strcmp(en_ptr->name, "parm")) {
				Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->parent->type, en_ptr->field));
				fprintf(fptab,"\t{ SEQ_START, OFFSET(%s, %s), %s, %s },\n", en_ptr->parent->type, en_ptr->field, c_tag(yp),c_class(yp));
			}
			else
				fprintf(fptab,"\t{ SEQ_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
		else
			fprintf(fptab,"\t{ SEQ_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
#endif
		if (y = yp->yp_type) {
		    if (type) {
			if (yp->yp_declexp == NULL)
			    ferr(1, "tenc_typ:YP_SEQLIST:no declexp\n");
			yp -> yp_structname = my_strcat("struct ", yp->yp_declexp);
		    } else
			yp->yp_structname = t;
		    if (optfield(y)) {
			fprintf(fptab,
			"\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
			yp->yp_structname);
		    }
		    tenc_loop(y, id, yp->yp_structname);
		}
		fprintf(fptab, "\t{ PE_END, 0, 0, 0 },\n");
		en_ptr = save_ptr;
		cons_type--;
		break;
	
	case YP_SETLIST:
		p1 = NULL;
		cons_type++;
		if (yp->yp_varexp == NULL && type != NULL) 
		    ferr(1, "tenc_typ:YP_SETLIST:NULL varexp pointer\n"); 
#if 0
                s = new_string(yp->yp_varexp);
                get_val(&s);
                f = get_val(&s);
                t = concat("struct ", modsym(mymodule, id, "type"));
#endif
		if (type != NULL)
		    fprintf(fptab,"\t{ SET_START, OFFSET(%s, %s), %s, %s },\n",
			t, f, c_tag(yp),c_class(yp));
		else
		    fprintf(fptab,"\t{ SET_START, 0, %s, %s },\n",
			c_tag(yp),c_class(yp));
#if 0
		save_ptr = en_ptr;
		if ((en_ptr = get_offset(yp, 0)) != NULL)
			if (strcmp(en_ptr->name, "parm")) {
				Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->parent->type, en_ptr->field));
				fprintf(fptab,"\t{ SET_START, OFFSET(%s, %s), %s, %s },\n", en_ptr->parent->type, en_ptr->field, c_tag(yp),c_class(yp));
			}
			else
				fprintf(fptab,"\t{ SET_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
		else
			fprintf(fptab,"\t{ SET_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
#endif
		if (y = yp->yp_type) {
		    if (type) {
			if (yp->yp_declexp == NULL)
			    ferr(1, "tenc_typ:YP_SETLIST:no declexp\n");
			yp -> yp_structname = my_strcat("struct ", yp->yp_declexp);
		    } else
			yp->yp_structname = t;
		    if (optfield(y)) {
			fprintf(fptab,
			"\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
			yp->yp_structname);
		    }
		    tenc_loop(y, id, yp->yp_structname);
		}
		fprintf(fptab, "\t{ PE_END, 0, 0, 0 },\n");
		en_ptr = save_ptr;
		cons_type--;
		break;
	
	case YP_SEQTYPE:
		p1 = NULL;
		cons_type++;
		save_ptr = en_ptr;
		if (type != NULL)
		    fprintf(fptab,"\t{ SEQOF_START, OFFSET(%s, %s), %s, %s },\n",
			t, f, c_tag(yp),c_class(yp));
		else
		    fprintf(fptab,"\t{ SEQOF_START, 0, %s, %s },\n",
			c_tag(yp),c_class(yp));
#if 0
		if ((en_ptr = get_offset(yp, 0)) != NULL) 
			if (strcmp(en_ptr->name, "parm")) {
				Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->parent->type, en_ptr->field));
				fprintf(fptab,"\t{ SEQOF_START, OFFSET(%s, %s), %s, %s },\n", en_ptr->parent->type, en_ptr->field, c_tag(yp),c_class(yp));
			}
			else
				fprintf(fptab,"\t{ SEQOF_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
		else
			fprintf(fptab,"\t{ SEQOF_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));

		if (yp->yp_flags & YP_CONTROLLED) { /* encode for loop */
			Printf(2, ("control = %s\n",yp->yp_control));
			fprintf(fptab,"\t{ SCTRL, ");
			s = new_string(yp->yp_control);
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(get_val(&s1));
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Sequence of)\n");
				}
				else
					fprintf(fptab, "0, ");
			}
			else
				fprintf(fptab, "0, ");
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(s1);
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Sequence of)\n");
				}
				else
					fprintf(fptab, "0, ");
			}
			else
				fprintf(fptab, "0, ");
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(get_val(&s1));
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Sequence of)\n");
				}
				else
					fprintf(fptab, "OFFSET(%s, %s) },\n", ptr1->type, "next");
			}
			else
				fprintf(fptab, "0 },\n");
		}
		else
			ferr(0, "tenc_typ: no SCTRL information (Sequence of)\n");
#endif
		if (y = yp->yp_type) {
		    if (type) {
			if (yp->yp_declexp == NULL)
			    ferr(1, "tenc_typ:YP_SEQTYPE:no declexp\n");
			yp -> yp_structname = my_strcat("struct ", yp->yp_declexp);
		    } else
			yp->yp_structname = t;
		    tenc_loop(y, id, yp->yp_structname);
		}
		if (yp->yp_structname != NULL)
		    fprintf(fptab, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
		    yp->yp_structname);
		else
		    fprintf(fptab,"\t{ PE_END, 0, 0, 0 },\n");
		en_ptr = save_ptr;
		cons_type--;
		break;
	
	case YP_SETTYPE:
		p1 = NULL;
		cons_type++;
		save_ptr = en_ptr;
		if (type != NULL)
		    fprintf(fptab,"\t{ SETOF_START, OFFSET(%s, %s), %s, %s },\n",
			t, f, c_tag(yp),c_class(yp));
		else
		    fprintf(fptab,"\t{ SETOF_START, 0, %s, %s },\n",
			c_tag(yp),c_class(yp));
#if 0
		if ((en_ptr = get_offset(yp, 0)) != NULL) 
			if (strcmp(en_ptr->name, "parm")) {
				Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->parent->type, en_ptr->field));
				fprintf(fptab,"\t{ SETOF_START, OFFSET(%s, %s), %s, %s },\n", en_ptr->parent->type, en_ptr->field, c_tag(yp),c_class(yp));
			}
			else
				fprintf(fptab,"\t{ SETOF_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));
		else
			fprintf(fptab,"\t{ SETOF_START, 0, %s, %s },\n", c_tag(yp),c_class(yp));

		if (yp->yp_flags & YP_CONTROLLED) { /* encode for loop */
			Printf(2, ("control = %s\n",yp->yp_control));
			fprintf(fptab,"\t{ SCTRL, ");
			s = new_string(yp->yp_control);
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(get_val(&s1));
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Set of)\n");
				}
				else
					fprintf(fptab, "0, ");
			}
			else
				fprintf(fptab, "0, ");
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(s1);
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Set of)\n");
				}
				else
					fprintf(fptab, "0, ");
			}
			else 
				fprintf(fptab, "0, ");
			if (strcmp(s1 = get_comp(&s), "")) {
				ptr1 = lookup_list(get_val(&s1));
				if (en_ptr != ptr1) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->name, en_ptr->field));
					ferr(1, "tenc_typ: Need more work with generating for loop (Set of)\n");
				}
				else
					fprintf(fptab, "OFFSET(%s, %s) },\n", ptr1->type, "next");
			}
			else
				fprintf(fptab, "0 },\n");
		}
		else
			ferr(0, "tenc_typ: no SCTRL information (Set of)\n");
#endif

		if (y = yp->yp_type) {
		    if (type) {
			if (yp->yp_declexp == NULL)
			    ferr(1, "tenc_typ:YP_SETTYPE:no declexp\n");
			yp -> yp_structname = my_strcat("struct ", yp->yp_declexp);
		    } else
			yp->yp_structname = t;
		    tenc_loop(y, id, yp->yp_structname);
		}
		if (yp->yp_structname != NULL)
		    fprintf(fptab, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
		    yp->yp_structname);
		else
		    fprintf(fptab,"\t{ PE_END, 0, 0, 0 },\n");
		en_ptr = save_ptr;
		cons_type--;
		break;
	
	case YP_CHOICE:
		p1 = NULL;
		cons_type++;
		save_ptr = en_ptr;
		if (type != NULL)
		    fprintf(fptab,"\t{ CHOICE_START, OFFSET(%s, %s), 0, %s },\n",
			t, f, c_class(yp));
		else
		    fprintf(fptab,"\t{ CHOICE_START, 0, 0, 0 },\n");
#if 0
		if (yp->yp_flags & YP_CONTROLLED) {
			if ((en_ptr = get_offset(yp, 0)) != NULL)
				if (strcmp(en_ptr->name, "parm")) {
					Printf(3, ("arg1 = %s, arg2 = %s\n",en_ptr->parent->type, en_ptr->field));
					fprintf(fptab,"\t{ CHOICE_START, OFFSET(%s, %s), 0, 0 },\n", en_ptr->parent->type, en_ptr->field);
				}
				else
					fprintf(fptab,"\t{ CHOICE_START, 0, 0, 0 },\n");
			else
				fprintf(fptab,"\t{ CHOICE_START, 0, 0, 0 },\n");
			s = new_string(yp->yp_control);
			s1 = get_val(&s);
			ptr1 = lookup_list(s1);
			if (en_ptr != ptr1) {
				Printf(3, ("ptrname = %s and ptr1name = %s\n",en_ptr->name, en_ptr->name));
				ferr(1, "tenc_typ: Need more work with generating offset(Choice)\n");
			}
			s2 = get_val(&s);
			fprintf(fptab,"\t{ SCTRL, OFFSET(%s, %s), 0, 0 },\n", en_ptr->type, s2);
		}
		else
			ferr(0, "tenc_typ: no SCTRL information (Choice)\n");
		yp -> yp_structname =
		    my_strcat("struct ", yp->yp_declexp);
		tenc_loop(yp->yp_type, id, yp->yp_declexp);
		fprintf(fptab, "\t{ PE_END, 0, 0, 0 },\n");
#endif
		if (y = yp->yp_type) {
		    if (type) {
			if (yp->yp_declexp == NULL)
			    ferr(1, "tenc_typ:YP_CHOICE:no declexp\n");
			yp -> yp_structname = my_strcat("struct ", yp->yp_declexp);
		    } else
			yp->yp_structname = t;
		    fprintf(fptab, "\t{ SCTRL, OFFSET(%s, offset), 0, 0 },\n",
			yp->yp_structname);
		    tenc_loop(y, id, yp->yp_structname);
		}
		fprintf(fptab,"\t{ PE_END, 0, 0, 0 },\n");
		en_ptr = save_ptr;
		cons_type--;
		break;
	
	default:
		ferrd(1, "tenc_typ: yp_code = %d  not implemented\n", yp->yp_code);
	}

	if (p1 != NULL)
		if (t != NULL)
			fprintf(fptab, "\t{ %s, OFFSET(%s, %s), %s, %s },\n",
					    p1, t, f, c_tag(yp), c_class(yp));
		else
			fprintf(fptab, "\t{ %s, 0, %s, %s },\n",
					    p1, c_tag(yp), c_class(yp));
}

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

/*
 * calculate the tag string of the given type and return it
 */
char	*
c_tag(yp)
YP	yp;
{
	static	char	buf[WORDSIZE];
	int	i;

	if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
		i = yp->yp_tag->yt_value->yv_number;
	} else {
		if (yp->yp_code < 0 || yp->yp_code > YP_OID)
			i = 0;
		else
			i = fflags[yp->yp_code];
		if (i == 0)
			return ("No Tag available");
	}
	
	sprintf(buf, "%d", i);

	return (buf);
}

/*
 * calculate the tag string of the explicit tag and return it
 */
char	*
ec_tag(yp)
YP	yp;
{
	static	char	buf[WORDSIZE];
	int	i;

	if (!(yp->yp_flags & YP_TAG) || yp->yp_flags & YP_IMPLICIT)
	    ferr(1, "ec_tag:internal error:called with out explicit tag\n");

	i = yp->yp_tag->yt_value->yv_number;
	
	sprintf(buf, "%d", i);

	return (buf);
}

#define STRSIZE 50
/*
 * produce a string that represents the class/flags field for a given yp
 * entry taking the class to be that given in cl
 */
char *
c_flags(yp, cl)
YP	yp;
int	cl;
{
	char	*p1;
	static char    buf[STRSIZE];

	switch (yp->yp_code) {
	case YP_IDEFINED:
	case YP_CHOICE:
	    if (yp->yp_flags & YP_TAG)
		break;
	    if (yp->yp_flags & YP_OPTIONAL) {
		p1 = "FL_OPTIONAL";
	    } else if (yp->yp_flags & YP_DEFAULT) {
		p1 = "FL_DEFAULT";
	    } else
		p1 = "0";
	    return (p1);
	
	default:
	    break;
	}
	switch (cl) {
	case PE_CLASS_UNIV:
		p1 = "FL_UNIVERSAL";
		break;

	case PE_CLASS_APPL:
		p1 = "FL_APPLICATION";
		break;

	case PE_CLASS_PRIV:
		p1 = "FL_PRIVATE";
		break;

	case PE_CLASS_CONT:
		p1 = "FL_CONTEXT";
		break;

	default:
		ferrd(1, "c_flags: illegal class found %d\n", cl);
		
	}
	if (yp->yp_flags & YP_OPTIONAL) {
	    strncpy(buf, p1, STRSIZE);
	    p1 = strncat(buf, "|FL_OPTIONAL", STRSIZE);
	} else if (yp->yp_flags & YP_DEFAULT) {
	    strncpy(buf, p1, STRSIZE);
	    p1 = strncat(buf, "|FL_DEFAULT", STRSIZE);
	}

	return (p1);
}
/*
 * calculate a string specifying the class for the given type and return it
 */
char	*
c_class(yp)
YP	yp;
{
	int	i;

	if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
		i =  yp->yp_tag->yt_class;
	} else {
		i = PE_CLASS_UNIV;
	}
	return (c_flags(yp, i));
	
}
/*
 * calculate a string specifying the class for the explicit tag and return it
 */
char	*
ec_class(yp)
YP	yp;
{
	int	i;
	char	*p1;
	static char    buf[STRSIZE];

	if (!(yp->yp_flags & YP_TAG) || yp->yp_flags & YP_IMPLICIT)
	    ferr(1, "ec_class:internal error:called with out explicit tag\n");
	switch (yp->yp_code) {
	case YP_IDEFINED:
	case YP_CHOICE:
	    if (yp->yp_flags & YP_TAG)
		break;
	    if (yp->yp_flags & YP_OPTIONAL) {
		p1 = "FL_OPTIONAL";
	    } else if (yp->yp_flags & YP_DEFAULT) {
		p1 = "FL_DEFAULT";
	    } else
		p1 = "0";
	    return (p1);
	
	default:
	    break;
	}

	i =  yp->yp_tag->yt_class;
	
	switch (i) {
	case PE_CLASS_UNIV:
		p1 = "FL_UNIVERSAL";
		break;

	case PE_CLASS_APPL:
		p1 = "FL_APPLICATION";
		break;

	case PE_CLASS_PRIV:
		p1 = "FL_PRIVATE";
		break;

	case PE_CLASS_CONT:
		p1 = "FL_CONTEXT";
		break;

	default:
		ferrd(1, "c_class: illegal class found %d\n", i);
		
	}
	if (yp->yp_flags & YP_OPTIONAL) {
	    strncpy(buf, p1, STRSIZE);
	    p1 = strncat(buf, "|FL_OPTIONAL", STRSIZE);
	} else if (yp->yp_flags & YP_DEFAULT) {
	    strncpy(buf, p1, STRSIZE);
	    p1 = strncat(buf, "|FL_DEFAULT", STRSIZE);
	}

	return (p1);
}

/*
 * generate tables for encoding a contructed type
 */
tenc_loop(yp, id, type)
YP	yp;
char	*id;
char	*type;
{
	for (; yp != NULL; yp = yp->yp_next) {
		tenc_typ(yp, id, type);
	}
}

/*
 * Print the string and exit if argument greater than zero
 */
ferr(i, s)
int	i;
char	*s;
{
	fprintf(stderr, "%s", s);
	if (i > 0)
		exit(i);
}

/*
 * Print the integer and exit if argument greater than zero
 */
ferrd(i, s, d)
int	i;
char	*s;
int	d;
{
	fprintf(stderr, s, d);
	if (i > 0)
		exit(i);
}

/*
 * Print the string and exit if argument greater than zero
 */
ferrs(i, s, d)
int	i;
char	*s;
char	*d;
{
	fprintf(stderr, s, d);
	if (i > 0)
		exit(i);
}

/*
	return a copy of the string s minus its last character
*/
char *strip_last(s)
char *s;
{
	char *t, *r;

	if (s) {
		t = new_string(s);
		for (r = t; *r != '\0'; r++);
			;
		*--r = '\0';
		return t;
		}
	else
		return NULL;
}

/*
	add the declaration specified by the strings type and id to the start
	of the declaration list
*/
add_list(type, id)
char *type, *id;
{

	s_table *prev;

	if ((prev = (s_table *) malloc(sizeof(s_table))) == NULL)
		ferr(1, "add_list: Out of memory\n");
	prev->type = type;
	prev->name = id;
	prev->parent = NULL;
	prev->defined = 0;
	prev->next = head;
	head = prev;
}

/*
	return the element in the declaration list whose name field is id
*/
s_table *lookup_list(id)
char *id;
{
	s_table *prev;

	for (prev = head; prev != NULL; prev=prev->next)
		if (!strcmp(prev->name, id))
			return prev;
	return (NULL);
	/* ferrs(1, "lookup_list: the id %s is not present\n",id); */
}

/*
	print the declaration list
*/
print_list()
{
	s_table *prev;

	for (prev = head; prev != NULL; prev=prev->next) {
		printf("type is %s\n",prev->type);
		printf("name is %s\n",prev->name);
		printf("\n");
	}
}

/*
	parse the declaration in the string s returning the type in v1
	and the name in v2
*/
parse_decl(s, v1, v2)
char **s, **v1, **v2;
{
	char *t;

	for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_'); t++)
		;

	*s = t;	
	if (*t != '\0') {
		for (; *t != '*'; t++)
			;
		*t = '\0';
		*v1 = my_strcat(*s, "*");
		Printf(3, ("the type is %s\n",*v1));
		if (*++t == '*')
			t++;
		for (*s = t; isalnum(*t) || *t == '_'; t++)
			;
		if (*t != '\0') {
			*t = '\0';
			t++;
		}
		*v2 = new_string(*s); /* don't really need new_string */
		Printf(2, ("the name is %s\n",*v2));
		*s = t;
	}
}

/*
	return the next identifier in the string s
*/
char *get_val(s)
char **s;
{
	char *t, *r;

	for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_' || *t == '.'); t++)
		;

	if (*t != '\0') {
		for (*s = t; isalnum(*t) || *t == '_' || *t == '.'; t++)
			;
		*t = '\0';
		r = *s;
		Printf(3, ("arg is |%s|\n",r));
		*s = ++t;
		return r;
	}
	else
		return NULL;
}

/*
	add the definition contained in s to the start of the
	declaration list
*/
s_table *proc_def(s)
char *s;
{
	char	*s1, *s2, *s3;
	s_table	*ptr1, *ptr2;

	s1 = get_val(&s);
	ptr1 = lookup_list(s1);
	if (! ptr1->defined) {
		s2 = get_val(&s);
		ptr2 = lookup_list(s2);
		ptr1->parent= ptr2;
		s3 = get_val(&s);
		ptr1->field = s3;
		ptr1->defined++;
	}
	return ptr1;
}

/*
	return the next component (sequence of characters up to the next ';'
	or '\0') of the string s
*/
char *get_comp(s)
char **s;
{
	char *t, *r;

	for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_' || *t == ';'); t++)
		;

	if (*t != '\0') {
		for (*s = t; *t != '\0' && *t != ';'; t++)
			;
		*t = '\0';
		r = *s;
		Printf(3, ("component is |%s|\n",r));
		*s = ++t;
		return r;
	}
	else
		return NULL;
}

/*
	work out what the offset for the type yp should be
	and return a pointer to the element in the declaration list
	which can be used to calculate the offset
*/
s_table *get_offset(yp, level)
YP yp;
int level;
{
	char	*s, *s1;
	s_table	*ptr1;

	switch (yp->yp_code) {

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

		case YP_BOOL:
		case YP_INT:
		case YP_INTLIST:
		case YP_NULL:
			if (yp->yp_varexp) {
				s = new_string(yp->yp_intexp);		
				s1 = get_val(&s);
				ptr1 = lookup_list(s1);
				return ptr1;
			}
			else {
				ferr(0, "get_offset: No intexp\n");
				return NULL;
			}
			break;

		case YP_BIT:
		case YP_BITLIST:
			if (yp->yp_direction & YP_DECODER)
				if (yp->yp_action2) {
					s = new_string(yp->yp_action2);
					s1 = get_val(&s);
					if (strcmp(s1, "if"))
						ferrs(1,"get_offset: What to do, action2 = %s\n",yp->yp_action2);
					else {
						s1 = get_val(&s);
						ptr1 = lookup_list(s1);
						return ptr1;
					}
				}
				else
					return NULL;
			else if (yp->yp_varexp) {
				s = new_string(yp->yp_varexp);		
				s1 = get_val(&s);
				s1 = get_val(&s);
				ptr1 = lookup_list(s1);
				return ptr1;
			}
			else {
				ferr(0, "get_offset: No strexp (BIT)\n");
				return NULL;
			}
			break;
		case YP_OCT:
		case YP_OID:
		case YP_SEQ:
		case YP_SET:
		case YP_ANY:
			if (yp->yp_varexp) {
				s = new_string(yp->yp_varexp);		
				s1 = get_val(&s);
				ptr1 = lookup_list(s1);
				return ptr1;
			}
			else {
				ferr(0, "get_offset: No strexp\n");
				return NULL;
			}
			break;

		case YP_IDEFINED:
			if (yp->yp_parm) {
				s = new_string(yp->yp_parm);
				s1 = get_val(&s);
				ptr1 = lookup_list(s1);
				return ptr1;
			}
			else {
				ferr(0, "get_offset: No parm\n");
				return NULL;
			}
			break;

		case YP_SEQLIST:
		case YP_SETLIST:
		case YP_CHOICE:
			if (yp->yp_action1) {
				s = get_string(yp->yp_action1, yp->yp_direction);
				while ((s1 = get_comp(&s)) != NULL)
					(void) proc_def(s1);
			}
			if (yp->yp_type == NULL) {
				if (level > 0)
					ferr(0, "get_offset: There exists an embeded empty SEQUENCE/SET/CHOICE\n");
				return (yp->yp_direction & YP_ENCODER ? en_ptr : ptr);
			}
			if ((ptr1 = get_offset(yp->yp_type, level + 1)) != NULL)
				if (ptr1->parent != NULL && level > 0)
					return ptr1->parent;
				else
					return ptr1;
			else {
				ferr(0, "get_offset: returning NULL (SEQLIST/SETLIST/CHOICE)\n");
				return NULL;
			}
			break;

		case YP_SEQTYPE:
		case YP_SETTYPE:
			if (yp->yp_action3) {
				s = get_string(yp->yp_action3, yp->yp_direction);
				while ((s1 = get_comp(&s)) != NULL)
					(void) proc_def(s1);
			}
			if ((ptr1 = get_offset(yp->yp_type, level + 1)) != NULL)
				if (ptr1->parent != NULL && level > 0)
					return ptr1->parent;
				else
					return ptr1;
			else {
				ferr(0, "get_offset: returning NULL (SEQTYPE/SETTYPE)\n");
				return NULL;
			}
			break;

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

/*
	return a copy of that part of the string s which may contain
	definitions for the variables generated by posy
*/
char *get_string(s, direction)
char *s;
int direction;
{
	char	*t ,*t1;

	if (direction & YP_ENCODER)
		return new_string(s);
	if (direction & YP_DECODER) {
		t = new_string(s);
		for (t1 = t; !(isalnum(*t1) || *t1 == '_'); t1++)
			;
		if (*t1 == 'i' && *++t1 == 'f' && *++t1 == ' ') { /* MALLOC code */
			for(; *t1 != '}'; t1++) /* skip MALLOC code */
				;
			t1++;
			Printf(4, ("returning the string %s\n",t1));
			return t1;
		}
		else
			return t;
	}
}

c_type(yp)
YP yp;
{
	switch (yp->yp_code) {

		case YP_IDEFINED:
			return T_OBJ;
			break;

#if 0
			/*
			 * Don't think we should ever return T_CONS this - but
			 * in case we do here is the code
			 */
		case YP_SEQ:
		case YP_SEQTYPE:
		case YP_SEQLIST:
		case YP_SET:
		case YP_SETTYPE:
		case YP_SETLIST:
		case YP_CHOICE:
			return T_CONS;
			break;
#endif

		default:
			return T_PRIM;
			break;
	}
}

/*
 * Determine wether this list contains any items that will generate an
 * optional field. If so return non zero
 */
optfield(yp)
YP	yp;
{
    for (; yp; yp = yp->yp_next) {
	if (yp->yp_flags & YP_OPTIONAL)
	    switch (yp->yp_code) {
		case YP_BOOL:
		case YP_INT:
		case YP_INTLIST:
		case YP_ENUMLIST:
		case YP_NULL:
		    return (1);
	    }
    }
    return (0);
}

extincl(yp, type)
YP      yp;
char	*type;
{
    YP	y;

    if (yp == NULL)
	return;
    switch (yp->yp_code) {
    case YP_IDEFINED:
	if (yp->yp_module == NULL
	|| strcmp(yp->yp_module, mymodule) == 0)
	    break;
	if (lookup_list(yp->yp_module))
	    break;	/*already done */
	/* Got an external reference */
	fprintf(fptab,"#include \"%s%s\"\n", yp->yp_module, HFILE2);
	add_list("module", yp->yp_module);
	break;

    case YP_CHOICE:
    case YP_SEQTYPE:
    case YP_SETTYPE:
    case YP_SEQLIST:
    case YP_SETLIST:
	for (y = yp->yp_type; y != NULL; y = y->yp_next) {
	    extincl(y, type);
	}
	break;

    default:
	break;
    }
    /* Output definitions for default entries */
    if (yp->yp_flags & YP_DEFAULT)
	    defdflt(yp, type);
}
/*
 * Compute the concatenation into a temporary buffer of two strings after
 * having run notid on them first
 */
char	*
strp2name(s1, s2)
char	*s1, *s2;
{
    char	*p;
    static char buf[STRSIZE*2 + 5];

    if (strlen(s1) > STRSIZE || strlen(s2) > STRSIZE)
	ferr(1, "strp2name:string to big\n");
    strcpy(buf, p = notidtoid(s1));
    free(p);
    strcat(buf, p = notidtoid(s2));
    free(p);

    return (buf);
}

/*
 * Output the definitions for default entries and initialise the yp's to have
 * pointers which reference these definitions for use by gdflt routine.
 */
defdflt(yp, name)
YP	yp;
char	*name;
{
    YV	yv;
    YV	yv1;
    SY	sy;
    YP	yp1;
    int	size, i;
    char	*str;
    char	*label;

    if ((yp->yp_flags & YP_DEFAULT) == 0)
	ferrd(1, "defdflt:called with out a default code = %d\n", yp->yp_code);
    yv = yp->yp_default;

   yp1 = yp;

   /* Find the bottom definition */
   while (yp1->yp_code == YP_IDEFINED) {
       if ((sy = syfind(yp1->yp_identifier)) == NULL) {
	   ferrs(1, "defdflt:IDEFINED:cannot find definition of symbol %s\n",
	       yp1->yp_identifier);
	}
	yp1 = sy->sy_type;
    }

    switch (yp1->yp_code) {
    case YP_BOOL:
    case YP_INT:
    case YP_INTLIST:
	switch  (yv->yv_code) {
	case YV_NUMBER:
	case YV_BOOL:
	    /* None needed */
	    break;
	
	case YV_IDEFINED:
	   if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
	       ferrs(1, "defdflt:BOOL/INT:cannot find definition of %s\n",
		   yv->yv_identifier);
	    }
	    /* None Needed */
	    break;

	default:
	    ferrd(1, "defdflt:INT/BOOL:unimplemented value code = %d\n",
		yv->yv_code);
	}
	break;

    case YP_BIT:
    case YP_BITLIST:
	switch  (yv->yv_code) {
	/* This is an illegal value for a bit string ! - BUT ACSE uses it !*/
	/* gdflt also patched to support it */
	case YV_IDEFINED:
	   ferrs(0,
	   "warning:bitstring default specified illegally with identifier %s\n",
	       yv->yv_identifier);
	   if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
	       ferrs(1, "defdflt:BIT:cannot find definition of %s\n",
		   yv->yv_identifier);
	    }
	    /* doesn't work fix posy-yacc.y */
	    size = numtobstr(yv1, &str);
	    goto dumpdef1;
	
	case YV_NUMBER:
	    /* doesn't work fix posy-yacc.y */
	    size = numtobstr(yv, &str);
	    goto dumpdef1;
	
	case YV_VALIST:
	   if ((size = valisttobs(yp1, yv, &str)) < 0) {
	       ferrs(1, "defdflt:bad default value for bistring %s\n",
		   yp->yp_flags & YP_ID ? yp->yp_identifier : "");
	    }
	    goto dumpdef1;

	default:
	    /* Could be a syntax error */
	    ferrd(1, "defdflt:BIT:illegal value code = %d\n", yv->yv_code);
	}
	break;

    case YP_IDEFINED:
	   ferrs(1, "defdflt:IDEFINED:internal error on symbol %s\n",
		   yp1->yp_identifier);
	    break;

    case YP_OCT:
	switch  (yv->yv_code) {
	case YV_NUMBER:
	    /* doesn't work fix posy-yacc.y */
	    size = numtobstr(yv, &str);
	    goto dumpdef2;
	
	case YV_STRING:
	   str = yv->yv_string;
	   size = strlen(str);
	   goto dumpdef2;

	default:
	    /* Could be a syntax error */
	    ferrd(1, "defdflt:OCT:illegal value code = %d\n", yv->yv_code);
	}
	break;

    case YP_NULL:
    case YP_SEQ:
    case YP_SEQTYPE:
    case YP_SEQLIST:
    case YP_SET:
    case YP_SETTYPE:
    case YP_SETLIST:
    case YP_CHOICE:
    case YP_ANY:
    case YP_OID:
    case YP_ENUMLIST:
    case YP_REAL:
	/* None yet */
	break;

    default:
	ferrd(1, "defdflt:unknown type %d\n", yp->yp_code);
    }

    return;

dumpdef1:
    label = genlabel(name, yp);
    yp->yp_action0 = label;
    yp->yp_act0_lineno = size;
    i = (size + NBPC - 1)/NBPC;
    fprintf(fptab, "\nstatic char %s[] = ", label);
    if (printable(str, i))
	prstr(fptab, str, i);
    else
	prhstr(fptab, str, i);
    fprintf(fptab, ";\n");
    return;

dumpdef2:
    label = genlabel(name, yp);
    yp->yp_action0 = label;
    yp->yp_act0_lineno = size;
    fprintf(fptab, "\nstatic char %s[] = ", label);
    if (printable(str, size))
	prstr(fptab, str, size);
    else
	prhstr(fptab, str, size);
    fprintf(fptab, ";\n");
    return;

}
/*
 * generate the default entry for encoding/decoding fields. This should
 * contain the default value which the encoder will know means default encoding
 */
gdflt(yp, which)
YP	yp;
int	which; /* Which type of entries to generate G_ENC encode G_DEC decode */
{
YV	yv;
YV	yv1;
SY	sy;
YP	yp1;
int	size;
char	*str;

char *ndflt;

    if (which == G_ENC)
	ndflt = "DFLT_F";
    else 
	ndflt = "DFLT_B";

    if ((yp->yp_flags & YP_DEFAULT) == 0)
	ferrd(1, "gdflt:called with out a default code = %d\n", yp->yp_code);
    yv = yp->yp_default;

   yp1 = yp;

   /* Find the bottom definition */
   while (yp1->yp_code == YP_IDEFINED) {
       if ((sy = syfind(yp1->yp_identifier)) == NULL) {
	   ferrs(1, "gdflt:IDEFINED:cannot find definition of symbol %s\n",
	       yp1->yp_identifier);
	}
	yp1 = sy->sy_type;
    }

    switch (yp1->yp_code) {
    case YP_BOOL:
    case YP_INT:
    case YP_INTLIST:
	switch  (yv->yv_code) {
	case YV_NUMBER:
	case YV_BOOL:
	    fprintf(fptab, "\t{ %s,	%d,	0,	0 },\n", ndflt,
		yp->yp_default->yv_number);
	    break;
	
	case YV_IDEFINED:
	   if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
	       ferrs(1, "gdflt:BOOL/INT:cannot find definition of %s\n",
		   yv->yv_identifier);
	    }
	    fprintf(fptab, "\t{ %s,	%d,	0,	0 },\n", ndflt,
		yv1->yv_number);
	    break;

	default:
	    ferrd(1, "gdflt:INT/BOOL:unimplemented value code = %d\n",
		yv->yv_code);
	}
	break;

    case YP_BIT:
    case YP_BITLIST:
	switch  (yv->yv_code) {
	case YV_IDEFINED:	/* supporting illegal default specification */
	case YV_NUMBER:
	case YV_VALIST:
	    fprintf(fptab, "\t{ %s,	%d,	(int )%s,	0 },\n", ndflt, 
		yp->yp_act0_lineno, yp->yp_action0);
	    break;
	
	default:
	    /* Could be a syntax error */
	    ferrd(1, "gdflt:BIT:illegal value code = %d\n", yv->yv_code);
	}
	break;

    case YP_IDEFINED:
	   ferrs(1, "gdflt:IDEFINED:internal error on symbol %s\n",
		   yp1->yp_identifier);
	    break;

    case YP_OCT:
	switch  (yv->yv_code) {
	case YV_NUMBER:
	case YV_STRING:
	    fprintf(fptab, "\t{ %s,	%d,	(int )%s,	0 },\n", ndflt, 
		yp->yp_act0_lineno, yp->yp_action0);
	    break;
	
	default:
	    /* Could be a syntax error */
	    ferrd(1, "gdflt:OCT:illegal value code = %d\n", yv->yv_code);
	}
	break;

    case YP_NULL:
    case YP_SEQ:
    case YP_SEQTYPE:
    case YP_SEQLIST:
    case YP_SET:
    case YP_SETTYPE:
    case YP_SETLIST:
    case YP_CHOICE:
    case YP_ANY:
    case YP_OID:
    case YP_ENUMLIST:
    case YP_REAL:
	fprintf(fptab, "\t{ %s,	0,	0,	0 },\n", ndflt);
	break;

    default:
	ferrd(1, "gdflt:unknown type %d\n", yp->yp_code);
    }

}
/*
 * Calculate the value associated with the given identifier id by looking at the
 * value definitions associated with type definition yp. Returns the value
 * definition if found or NULL if not.
 */
YV
calc_yv(yp, id)
YP	yp;
char	*id;
{
    YV	yv;

    for (yv = yp->yp_value; yv != NULL; yv = yv->yv_next) {
	if (yv->yv_flags & YV_NAMED && strcmp(yv->yv_named, id) == 0)
		return (yv);
    }

    return (NULL);
}

/*
 * ******* This does not work. posy needs to be fixed for case of '01'b *****
 * Turn a Literal number value in yv into a bistring initialisation. Return
 * the length of the bit string or less than zero on error. Set the
 * (char *) pointer, whose address is in ppstr, to point to a string containing
 * the a reference to a character array which contains the bits.
 */

numtobstr(yv, ppstr)
YV	yv;
char    **ppstr;
{

    int	ibits, lastb, i;
    char *buf;

    buf = malloc(NBPI/NBPC + 1);
    bzero(buf, NBPI/NBPC + 1);
    lastb = -1;
    ibits = yv->yv_number;
    for (i = 0; i < NBPI; i++) {
	if ((1 << i) & ibits) {
	    buf[i/NBPC] |= 1 << (NBPC - 1 - (i % NBPC));
	    lastb = i;
	}
    }

    *ppstr = buf;
    return (lastb + 1);
}
#define ROUNDUP		10
/*
 * Take a list of Values (YV_VALIST) which should contain a list of bits
 * and convert them into a bitstring initialisation. As in numtobstr return
 * the size of the bit string or a negative number if there is an error. Put
 * a reference to a character array which contains the definition of the bits in
 * the character pointer whose address is in ppstr. yp is the definition of the
 * type which contains the names of all the defined bits.
 */
valisttobs(yp, yv, ppstr)
YP	yp;
YV	yv;
char	**ppstr;
{

    YV   yv1, yv2;
    int	lastb, val, nsize, size;
    char *buf;

    lastb = -1;
    size = ROUNDUP;
    if ((buf = malloc(size)) == NULL) {
	ferrd(1, "valisttobs:malloc:failed on %d\n", size);
    }
    bzero(buf, size);
    for (yv1 = yv->yv_idlist; yv1 != NULL; yv1 = yv1->yv_next) {
	if ((yv2 = calc_yv(yp, yv1->yv_identifier)) == NULL) {
		return (-1);
	}
	val = yv2->yv_number;
	/* Bug here probably */
	if (size < val/NBPC) {
	    nsize = val/NBPC + ROUNDUP;
	    if ((buf = realloc(buf, nsize)) == NULL) {
		ferrd(1, "valisttobs:realloc:failed on %d\n", nsize);
	    }
	    bzero(buf + size, nsize - size);
	    size = nsize;
	}
	buf[val/NBPC] |= 1 << (NBPC - 1 - (val % NBPC));
	if (val > lastb)
	    lastb = val;
    }
    *ppstr = buf;
    return (lastb + 1);
}
/*
 * Print the string out in a format acceptable as a quoted string in a C program
 * including the quotes. Using \ escapes for unprintable characters
 */
prstr(fp, str, len)
FILE	*fp;
char	*str;
int	len;
{
    fputc('"', fp);
    while (len-- > 0) {
	if (isprint(*str & 0xff)) {
	    fputc(*str & 0xff, fptab);
	    str++;
	    continue;
	}
	fprintf(fptab, "\\%0o", *str);
    }
    fputc('"', fp);
#define MAXPLINE	16
}
/*
 * output a initialisation for a character array as unsigned hex numbers
 */
prhstr(fptab, str, len)
FILE	*fptab;
char	*str;
int	len;
{
    int	npline;	/* number on this line */

    fprintf(fptab, "{\n");
    npline = 0;
    while (len > 0) {
	if (npline >= MAXPLINE) {
	    fputc('\n', fptab);
	    npline = 0;
	}
	npline++;
	fprintf(fptab, " 0x%02x,", *str++ & 0xff);
	len--;
    }
    fprintf(fptab, "}");
}
/*
 * determine if the string is printable i.e. only sensible to be read as
 * a character string. 1 (true) if it is 0, if it isn't
 */
printable(str, i)
char	*str;
int	i;
{
    while (i-- > 0) {
       if (!isprint(*str & 0xff))
	   return (0);	/* look for the first non printable character */
    }
    return (1);
}
/*
 * generate a unique identifier  using the name given and the name if
 * present in yp. Return a pointer to it in a space malloc'ed out
 */
char	*
genlabel(name, yp)
char	*name;
YP	yp;
{
    char buf[MAXNAME];
    static int	cnt;
    char	*p1, *p2;

    p1 = notidtoid(name);
    if (yp->yp_flags & YP_ID) {
	p2 = notidtoid(yp->yp_id);
	sprintf(buf, "L%s_%s_%d", p1, p2, cnt++);
	free(p2);
    } else
	sprintf(buf, "L%s_X_%d", p1, cnt++);
    free(p1);
 
    return (my_new_str(buf));
}