/* ptabs.c */

#ifndef	lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/ptabs.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $";
#endif

/* 
 * $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/pepsy/ptabs.c,v 1.1.1.1 2018/04/24 16:12:56 root Exp $
 *
 *
 * $Log: ptabs.c,v $
 * Revision 1.1.1.1  2018/04/24 16:12:56  root
 * BSD 4.3reno
 *
 * Revision 7.2  90/07/27  08:49:29  mrose
 * update
 * 
 * Revision 7.1  90/07/09  14:53:16  mrose
 * sync
 * 
 */

/*
 *				  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"

extern FILE *fptab;
extern char *c_tag(), *c_class();
extern char *ec_tag(), *ec_class(), *pec_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 tprnt_loop();

extern char *concat();
extern char *my_strcat();

/*
extern int explicit;
*/

static int cons_type = 0;

s_table *ptr;
s_table *save_ptr;

#define WORDSIZE	20

/*
 * Marshall's three extra conditions for changing the printing output
 */
static int	mrose1;	/* if NamedType */
static int	mrose2;	/* !mrose1 && -h && DefinedType */
static int	mrose3; /* (mrose1 || !mrose2) && TAG && (OPTIONAL|DEFAULT) */

/*
 * table printe a type. generate tables for the printing of a type
 */
tprnt_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_REAL)
	ferrd(1, "tdec_typ: unimplemented type %d\n", yp->yp_code);

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

    if (yp->yp_flags & YP_ID)
	mrose1 = 1;
    else
	mrose1 = 0;

    if (!mrose1 && hflag && yp->yp_code == YP_IDEFINED)
	mrose2 = 1;
    else
	mrose2 = 0;

    if ((mrose1 || !mrose2) && yp->yp_flags & YP_TAG
       && yp->yp_flags & (YP_OPTIONAL|YP_DEFAULT))
        mrose3 = 1;
    else
	mrose3 = 0;

    if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) {
	prte_enoff("ETAG", yp);
    }
    if (type)
	t = type;
    else
	t = my_strcat("struct ", modsym(mymodule, id, "type"));
    f = yp->yp_varexp;
    switch (yp->yp_code) {

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

    case YP_BOOL:
	p1 = "BOOLEAN";
	if (yp->yp_varexp) {
	} else
	    t = NULL;
	break;

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

    case YP_INT:

    case YP_ENUMLIST:
	p1 = "INTEGER";
	if (yp->yp_varexp) {
	} else
	    t = NULL;
	break;

    case YP_REAL:
	p1 = "REALTYPE";
	if (yp->yp_varexp) {
	} else
	    t = NULL;
	break;


    case YP_BIT:
    case YP_BITLIST:
	if (yp->yp_varexp) {
	    p1 = "BITSTRING";
	    break;
	}
	t = NULL;
	p1 = NULL;
	(void) fprintf(fptab, "\t{ SBITSTRING, 0, %s, %s, NULL },\n",
		c_tag(yp), c_class(yp));
	break;

    case YP_OCT:
	if (yp->yp_varexp) {
	    p1 = "OCTETSTRING";
	    break;
	}
	t = NULL;
	p1 = NULL;
	prte_noff("SOCTETSTRING", yp);
	break;

    case YP_OID:
	if (yp->yp_varexp) {
	    p1 = "OBJID";
	    break;
	}
	t = NULL;
	p1 = NULL;
	prte_noff("SOBJID", 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;
	}
	t = NULL;
	p1 = NULL;
	prte_noff("SANY", yp);
	break;

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

    case YP_IDEFINED:
	p1 = NULL;
	pr_deftyp(yp, t, f);
	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(yp, G_DEC);
	break;

    case YP_SEQLIST:
	p1 = NULL;
	/* support for -h flag */
	cons_type++;
	save_ptr = ptr;
	if (yp->yp_varexp == NULL && type != NULL)
	    ferr(1, "tprnt_typ:YP_SEQLIST:NULL varexp pointer\n");
	if (type != NULL)
	    prte_off("SEQ_START", yp, t, f);
	else 
	    prte_noff("SEQ_START", yp);

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(yp, G_DEC);
	if (y = yp->yp_type) {
	    if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tprnt_typ:YP_SEQLIST:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    if (optfield(y)) {
		(void) fprintf(fptab,
		"\t{ OPTL, OFFSET(%s, optionals), 0, 0, NULL },\n",
				    yp->yp_structname);
	    }
	    tprnt_loop(y, id, yp->yp_structname);
	}
	(void) fprintf(fptab, "\t{ PE_END, 0, 0, 0, NULL },\n");
	ptr = save_ptr;
	cons_type--;
	break;

    case YP_SETLIST:
	p1 = NULL;
	/* support for -h flag */
	cons_type++;
	if (yp->yp_varexp == NULL && type != NULL)
	    ferr(1, "tprnt_typ:YP_SETLIST:NULL varexp pointer\n");
	if (type != NULL)
	    prte_off("SET_START", yp, t, f);
	else 
	    prte_noff("SET_START", yp);

	if (yp->yp_flags & YP_DEFAULT)
	    ddflt(yp);
	if (y = yp->yp_type) {
	    if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tprnt_typ:YP_SETLIST:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    if (optfield(y)) {
		(void) fprintf(fptab,
		    "\t{ OPTL, OFFSET(%s, optionals), 0, 0, NULL },\n",
					yp->yp_structname);
	    }
	    tprnt_loop(y, id, yp->yp_structname);
	}
	(void) fprintf(fptab, "\t{ PE_END, 0, 0, 0, NULL },\n");
	ptr = save_ptr;
	cons_type--;
	break;

    case YP_SEQTYPE:		/* What is the difference ?? */
	p1 = NULL;
	cons_type++;
	save_ptr = ptr;
	if (type != NULL)
	    prte_off("SEQOF_START", yp, t, f);
	else
	    prte_noff("SEQOF_START", yp);
	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(yp, G_DEC);

	if (y = yp->yp_type) {
	    if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tprnt_typ:YP_SEQTYPE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    tprnt_loop(y, id, yp->yp_structname);
	}
	if (yp->yp_structname != NULL)
	    (void) fprintf(fptab,
		"\t{ PE_END, OFFSET(%s, next), 0, 0, NULL },\n",
		    yp->yp_structname);
	else
	    (void) fprintf(fptab, "\t{ PE_END, 0, 0, 0, NULL },\n");
	ptr = save_ptr;
	cons_type--;
	break;

    case YP_SETTYPE:
	p1 = NULL;
	cons_type++;
	save_ptr = ptr;
	if (type != NULL)
	    prte_off("SETOF_START", yp, t, f);
	else
	    prte_noff("SETOF_START", yp);

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

	if (y = yp->yp_type) {
	    if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tprnt_typ:YP_SETTYPE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    tprnt_loop(y, id, yp->yp_structname);
	}
	if (yp->yp_structname != NULL)
	    (void) fprintf(fptab,
		"\t{ PE_END, OFFSET(%s, next), 0, 0, NULL },\n",
		    yp->yp_structname);
	else
	    (void) fprintf(fptab, "\t{ PE_END, 0, 0, 0, NULL },\n");
	ptr = save_ptr;
	cons_type--;
	break;

    case YP_CHOICE:
	p1 = NULL;
	/* support for -h flag */
	if (hflag && (y = yp->yp_type) && !y->yp_next) {
	    tprnt_typ(y, id, yp->yp_structname);
	    break;
	}
	cons_type++;
	save_ptr = ptr;
	/* Generates an unused tags field - so beware */
	if (type != NULL)
	    prte_off("CHOICE_START", yp, t, f);
	else
	    prte_noff("CHOICE_START", yp);

	if (yp->yp_flags & YP_DEFAULT)
	    gdflt(yp, G_DEC);
	if (y = yp->yp_type) {
	    if ((yp->yp_flags & YP_ID) && yp->yp_id)
		(void) fprintf(fptab,
		    "\t{ SCTRL, OFFSET(%s, offset), 0, 0, \"%s\" },\n",
		    yp->yp_structname, yp->yp_id);
	    else
		(void) fprintf(fptab,
		    "\t{ SCTRL, OFFSET(%s, offset), 0, 0, NULL },\n",
		    yp->yp_structname);
	    if (type) {
		if (yp->yp_declexp == NULL)
		    ferr(1, "tprnt_typ:YP_CHOICE:no declexp\n");
		yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
	    } else
		yp->yp_structname = t;
	    tprnt_loop(y, id, yp->yp_structname);
	}
	(void) fprintf(fptab, "\t{ PE_END, 0, 0, 0, NULL },\n");
	ptr = save_ptr;
	cons_type--;
	break;

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

    if (p1 != NULL) {
	if (t != NULL)
	    prte_off(p1, yp, t, f);
	else
	    prte_noff(p1, yp);

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


}

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

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


ddflt(yp)
YP      yp;
{
    switch (yp->yp_code) {
    case YP_BOOL:
    case YP_INT:
    case YP_INTLIST:
	(void) fprintf(fptab, "\t{DFLT_B,      %d,     0,      0 },\n",
		yp->yp_default->yv_number);
	break;
    case YP_BIT:
    case YP_BITLIST:
    case YP_OCT:
    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_IDEFINED:
    case YP_ENUMLIST:
    case YP_REAL:
	(void) fprintf(fptab, "\t{DFLT_B,      0,      0,      0 },\n");
	break;

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

}

/*
 * print a Non offset table entry
 */
prte_noff(type, yp)
char	*type;
YP	yp;
{
    char	*tag;
    char	*flags;
    char	*typename;
    char	buf1[BUFSIZ];

    tag = c_tag(yp);
    flags = c_class(yp);
    if (mrose3) {		/* need to append FL_PRTAG flag */
	strncpy(buf1, flags, BUFSIZ);
	strncat(buf1, "|FL_PRTAG", BUFSIZ);
	flags = buf1;
    }
    if (mrose1)
	typename = yp->yp_id;
    else if (mrose2)
	typename = yp->yp_identifier;
    else
	typename = (char *)0;
    if (typename)
	(void) fprintf(fptab, "\t{ %s, 0, %s, %s, \"%s\" },\n",
				    type, tag, flags, typename);
    else
	(void) fprintf(fptab, "\t{ %s, 0, %s, %s, NULL},\n",
				    type, tag, flags);
}

/*
 * print a Non offset table entry for an ETAG - special case
 */
prte_enoff(type, yp)
char	*type;
YP	yp;
{
    char	*tag;
    char	*flags;
    char	*typename;
    char	buf1[BUFSIZ];

    tag = ec_tag(yp);
    flags = ec_class(yp);
    if (mrose3) {		/* need to append FL_PRTAG flag */
	strncpy(buf1, flags, BUFSIZ);
	strncat(buf1, "|FL_PRTAG", BUFSIZ);
	flags = buf1;
	mrose3 = 0;	/* don't want the next tag */
    }
    if (mrose1) {
	typename = yp->yp_id;
	mrose1 = 0;
    } else if (mrose2) {
	typename = yp->yp_identifier;
	mrose2 = 0;
    } else
	typename = NULL;
    if (typename)
	(void) fprintf(fptab, "\t{ %s, 0, %s, %s, \"%s\" },\n",
				    type, tag, flags, typename);
    else
	(void) fprintf(fptab, "\t{ %s, 0, %s, %s, NULL },\n",
				    type, tag, flags);
}

/*
 * print an offset table entry
 */
prte_off(type, yp, t, f)
char	*type;
YP	yp;
char	*t, *f;
{
    char	*tag;
    char	*flags;
    char	*typename;
    char	buf1[BUFSIZ];

    tag = c_tag(yp);
    flags = c_class(yp);
    if (mrose3) {		/* need to append FL_PRTAG flag */
	strncpy(buf1, flags, BUFSIZ);
	strncat(buf1, "|FL_PRTAG", BUFSIZ);
	flags = buf1;
    }
    if (mrose1)
	typename = yp->yp_id;
    else if (mrose2)
	typename = yp->yp_identifier;
    else
	typename = (char *)0;
    if (typename)
	(void) fprintf(fptab, "\t{ %s, OFFSET(%s, %s), %s, %s, \"%s\" },\n",
				    type, 	t, f, 	tag, flags, typename);
    else
	(void) fprintf(fptab, "\t{ %s, OFFSET(%s, %s), %s, %s, NULL},\n",
				    type, 	t, f,	 tag, flags);
}

/*
 * handle the very complex task of defined types.
 * Basically generating object calls
 */
pr_deftyp(yp, t, f)
YP	yp;
char	*t;
char	*f;
{
    /* 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;
	}
	prte_univt(p, yp, t, f);
	return;
    }

do_obj:
    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
	prte_noff("IMP_OBJ", yp);
    if (yp->yp_parm) {
	ferr(1, "tenc_typ:YP_IDEFINED:yp_parm found\n");
    }
	prte_obj(yp, t, f);
}

/*
 * print an offset table entry for an OBJECT type entry
 */
prte_obj(yp, t, f)
YP	yp;
char	*t, *f;
{
    char	*type;
    char	*obj;
    char	*flags;
    char	*typename;
    char	*off;
    char	buf1[BUFSIZ];
    char	buf2[BUFSIZ];
    int		extflag;

#if 1
    if (yp->yp_module == NULL || strcmp(yp->yp_module, mymodule) == 0) {
	if (f)
	    type = "OBJECT";
	else
	    type = "SOBJECT";
	obj = proc_name(yp->yp_identifier, 0);
	extflag = 0;
    } else {
	if (f)
	    type = "EXTOBJ";
	else
	    type = "SEXTOBJ";
	obj = strp2name(yp->yp_identifier, yp->yp_module);
	extflag = 1;
    }
#else
    if (f)
	type = "OBJECT";
    else
	type = "SOBJECT";
    obj = proc_name(yp->yp_identifier, 0);
#endif
    flags = c_class(yp);
    if (mrose3) {		/* need to append FL_PRTAG flag */
	strncpy(buf1, flags, BUFSIZ);
	strncat(buf1, "|FL_PRTAG", BUFSIZ);
	flags = buf1;
    }
    if (mrose1)
	typename = yp->yp_id;
    else if (mrose2)
	typename = yp->yp_identifier;
    else
	typename = (char *)0;
    if (f) {
	sprintf(buf2, "OFFSET(%s, %s)", t, f);
	off = buf2;
    } else
        off = "0";
    if (typename)
	(void) fprintf(fptab, "\t{ %s, %s, _Z%s, %s, \"%s\" },\n",
				    type, off, obj, flags, typename);
    else
	(void) fprintf(fptab, "\t{ %s, %s, _Z%s, %s, NULL},\n",
				    type, off, obj, flags);
    if (extflag)
	(void) fprintf(fptab, "\t{ EXTMOD, %d, 0, 0, NULL },\n",
		gen_modref(yp->yp_module));
}

/*
 * print an table entry for Universal type with the given entry
 */
prte_univt(p, yp, t, f)
struct univ_typ *p;
YP	yp;
char	*t, *f;
{
    char	*type;
    int		tag;
    int		class;
    char	*flags;
    char	*typename;
    char	*off;
    char	buf1[BUFSIZ];
    char	buf2[BUFSIZ];
    char	buf3[BUFSIZ];

    if (f == NULL)  {
	sprintf(buf3, "S%s", p->univ_tab);
	type = buf3;
    } else
	type = p->univ_tab;

    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
	tag = yp->yp_tag->yt_value->yv_number;
	class = yp->yp_tag->yt_class;
    } else {
	tag = p->univ_id;
	class = p->univ_class;
    }
    
    strncpy(buf1, c_flags(yp, class), BUFSIZ);
#if 0
    sprintf(buf1, "%d", class);
#endif
    flags = buf1;
    if (mrose3) {		/* need to append FL_PRTAG flag */
	strncat(buf1, "|FL_PRTAG", BUFSIZ);
    }
    if (mrose1)
	typename = yp->yp_id;
    else if (mrose2)
	typename = yp->yp_identifier;
    else
	typename = (char *)0;
    if (f) {
	sprintf(buf2, "OFFSET(%s, %s)", t, f);
	off = buf2;
    } else
        off = "0";
    if (typename)
	(void) fprintf(fptab, "\t{ %s, %s, %d, %s, \"%s\" },\n",
				    type, off, tag, flags, typename);
    else
	(void) fprintf(fptab, "\t{ %s, %s, %d, %s, NULL},\n",
				    type, off, tag, flags);
}
