|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T e
Length: 42108 (0xa47c) Types: TextFile Names: »etabs.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦041b9c0f8⟧ »EurOpenD22/isode/pepsy.system-6.0.Z« └─⟦d49939f05⟧ └─⟦6a28ec38e⟧ »pepsy.tar« └─⟦this⟧ »pepy/etabs.c«
/* 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)); }