Start development on 386BSD 0.0
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / contrib / isode / pepsy / pass2.c
CommitLineData
459ebbd7
C
1/* pass2.c */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/pepsy/RCS/pass2.c,v 7.10 91/02/22 09:49:18 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/pepsy/RCS/pass2.c,v 7.10 91/02/22 09:49:18 mrose Interim $
9 *
10 *
11 * $Log: pass2.c,v $
12 * Revision 7.10 91/02/22 09:49:18 mrose
13 * Interim 6.8
14 *
15 * Revision 7.9 91/01/08 12:49:45 mrose
16 * update
17 *
18 * Revision 7.8 90/12/23 17:24:52 mrose
19 * patches
20 *
21 * Revision 7.7 90/12/11 10:33:43 mrose
22 * sync
23 *
24 * Revision 7.6 90/11/20 15:27:14 mrose
25 * update
26 *
27 * Revision 7.5 90/11/11 10:53:58 mrose
28 * update
29 *
30 * Revision 7.4 90/11/04 19:18:57 mrose
31 * update
32 *
33 * Revision 7.3 90/08/08 14:02:27 mrose
34 * stuff
35 *
36 * Revision 7.2 90/07/27 08:49:22 mrose
37 * update
38 *
39 * Revision 7.1 90/07/01 20:00:32 mrose
40 * update
41 *
42 */
43
44/*
45 * NOTICE
46 *
47 * Acquisition, use, and distribution of this module and related
48 * materials are subject to the restrictions of a license agreement.
49 * Consult the Preface in the User's Manual for the full terms of
50 * this agreement.
51 *
52 */
53
54
55#include <stdio.h>
56#include <ctype.h>
57#include "pepsydefs.h"
58#include "pass2.h"
59#include "mine.h"
60#include "sym.h"
61
62extern int doexternals;
63extern int sflag, mflag;
64
65extern char *eval;
66
67extern int Aflag;
68extern SY mysymbols;
69extern char *modsym();
70extern char *my_strcat();
71extern char *notidtoid();
72extern char *rm_indirect();
73extern char *getid();
74extern char *getidordot();
75extern char *getfield();
76extern char *sym2type();
77extern YP lookup_type();
78
79char *tab; /* mymodule - with - changed to _ */
80
81Action start_action, final_action;
82int e_actions, d_actions, p_actions; /* number of actions of each type */
83
84FILE *ffopen();
85
86peri_pass2()
87{
88 char *inc; /* *_pre_defs.h file */
89
90 if (!sflag)
91 (void) fflush(stderr);
92
93 tab = notidtoid(mymodule);
94
95 if (strcmp(mymodule, "UNIV"))
96 (void) lookup_module("UNIV", NULLOID);
97
98 inc = my_strcat (mymodule, HFILE2);
99
100 gen_typesfile(inc);
101
102 gen_tablefile(inc);
103
104}
105
106/*
107 * generate the table file which contains:
108 * #include types file
109 * #include - types files for other (external) modules referenced
110 * definitions of data structures used: strings and stuff for defaults
111 * declaractions of functions referenced.
112 * tpe tables - one per type assignment for each of
113 * encoding, decoding and printing
114 * tables of pointers to all the above tpe tables - one for
115 * type of tpe table
116 * pointer table - used to hold pointers as tpe table cannot
117 * hold pointers but only integers which index into this table
118 * module definition - the key to all the data structures os this
119 * module. contains references to all the tables.
120 * lint declaractions for the "pepy" functions
121 */
122gen_tablefile(inc)
123char *inc;
124{
125
126 int nentries;
127 int encflag = 1, decflag = 1, prntflag = 1;
128 char *buf, *act;
129 SY sy;
130 YP yp;
131 FILE *fphh, *fptab;
132
133 fptab = ffopen(my_strcat(mymodule, TBLNAME));
134
135 /* Only need two files <stdio.h> and our types file which includes
136 * everything else we need
137 * Assumption. types file in the same directory as the _tables
138 */
139 (void) fprintf(fptab, "#include <stdio.h>\n");
140 (void) fprintf(fptab, "#include \"%s%s\"\n\n", mymodule, GENTYPES);
141
142
143
144#ifdef ACT_CODE
145 (void) fprintf(fptab, "#include \"%s\"\n", act);
146#endif
147
148 if (start_action) {
149 (void) fprintf (fptab, "\n# line %d \"%s\"\n", start_action->a_line, sysin);
150 fputs (start_action->a_data, fptab);
151 }
152
153
154 /*
155 * loop through and generate all the default values definitions
156 * and what ever else needs to be processed for all the entries
157 * e.g. external module references and coding function declarations
158 */
159 for (sy = mysymbols; sy; sy = sy->sy_next) {
160 yp = sy->sy_type;
161 if (yp->yp_flags & YP_IMPORTED)
162 continue;
163 if (yp->yp_direction & (YP_ENCODER | YP_DECODER | YP_PRINTER)
164 || Aflag) {
165 gen_dflts(fptab, sy->sy_type, sy->sy_name);
166 }
167 }
168
169 (void) fprintf(fptab, "\n#define OFFSET(t,f)\t((int ) &(((t *)0)->f))\n\n");
170 (void) fprintf(fptab, "\n#define AOFFSET(t,f)\t((int ) (((t *)0)->f))\n\n");
171 nentries = 0;
172 /*
173 * generate tpe tables
174 */
175 for (sy = mysymbols; sy; sy = sy->sy_next) {
176 yp = sy->sy_type;
177 if (yp->yp_flags & YP_IMPORTED)
178 continue;
179 if (yp->yp_direction & YP_ENCODER || Aflag) {
180 nentries++;
181 gen_enctbl(fptab, sy);
182 }
183 }
184 for (sy = mysymbols; sy; sy = sy->sy_next) {
185 yp = sy->sy_type;
186 if (yp->yp_flags & YP_IMPORTED)
187 continue;
188 if (yp->yp_direction & YP_DECODER || Aflag)
189 gen_dectbl(fptab, sy);
190 }
191
192 for (sy = mysymbols; sy; sy = sy->sy_next) {
193 yp = sy->sy_type;
194 if (yp->yp_flags & YP_IMPORTED)
195 continue;
196 if (yp->yp_direction & YP_PRINTER || Aflag)
197 gen_prnttbl(fptab, sy);
198 }
199
200 fphh = ffopen(inc);
201 (void) fprintf(fphh, "\nextern modtyp %s%s%s;\n",
202 PREFIX, tab, MODTYP_SUFFIX);
203 out_final_defs(fphh);
204 close(fphh);
205
206 gen_actfunct(fptab);
207
208 gen_tpe(fptab); /* generate table of pointers to tpe tables */
209
210 gen_modtype(fptab, nentries, encflag, decflag, prntflag);
211
212 if (final_action) {
213 (void) fprintf (fptab, "\n# line %d \"%s\"\n", final_action->a_line, sysin);
214 fputs (final_action->a_data, fptab);
215 }
216
217 gen_lint(fptab);
218
219 fclose(fptab);
220}
221
222/*
223 * generate the *-types.h file
224 */
225gen_typesfile(inc)
226char *inc;
227{
228 int encflag = 1, decflag = 1, prntflag = 1;
229 char *buf, *act;
230 SY sy;
231 YP yp;
232 FILE *fph, *fpe, *fpd, *fpp;
233 FILE *fpa;
234
235 fph = ffopen(my_strcat(mymodule, HFILE1));
236 if (mflag) {
237 (void) fprintf (fph, "#ifndef\tPEPYPATH\n");
238 (void) fprintf (fph, "#include <isode/pepsy/%s>\n", inc);
239 (void) fprintf (fph, "#else\n");
240 (void) fprintf (fph, "#include \"%s\"\n", inc);
241 (void) fprintf (fph, "#endif\n\n\n");
242 }
243 else {
244 if (is_stand (inc))
245 (void) fprintf (fph, "#include <isode/pepsy/%s>\n", inc);
246 else
247 (void) fprintf (fph, "#include \"%s\"\n", inc);
248 }
249
250#ifdef ACT_CODE
251 act = my_strcat(mymodule, ACTIONDEFS);
252
253 fpe = ffopen(my_strcat(mymodule, ENCFILENAME));
254 file_header(fpe, act);
255 fpd = ffopen(my_strcat(mymodule, DECFILENAME));
256 file_header(fpd, act);
257 fpp = ffopen(my_strcat(mymodule, PRNTFILENAME));
258 file_header(fpp, act);
259 fpa = ffopen(act);
260#endif
261
262 /* define the macros to support posy functions */
263
264 fprintf(fph, "\n#ifndef\tlint\n");
265 for (sy = mysymbols; sy; sy = sy->sy_next) {
266 eval = sy->sy_name;
267 yp = sy->sy_type;
268
269 if (sy->sy_module == NULLCP)
270 yyerror("no module name associated with symbol");
271 if (yp->yp_flags & YP_IMPORTED)
272 continue;
273 if (strcmp(sy->sy_module, mymodule)) {
274 fprintf(stderr, "mymodule unsuitable for module name e.g %s and %s(mymodule)\n", sy->sy_module, mymodule);
275 exit(1);
276 }
277 if (yp->yp_direction & YP_ENCODER || Aflag) {
278 buf = modsym (sy -> sy_module, sy -> sy_name, yyencdflt);
279 fprintf(fph, "#define %s", buf);
280 fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
281 fprintf(fph, " %s(%s%s, ", ENCFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
282 fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
283 fprintf(fph, "pe, top, len, buffer, (char *) parm)\n\n");
284#ifdef ACT_CODE
285 if (encflag) {
286 fprintf(fpe, "%s%s", ENC_FNCNAME, tab);
287 open_func(fpe);
288 encflag--;
289 }
290#endif
291 if (bflag)
292 init_new_file();
293 if (bflag)
294 end_file();
295 }
296 if (yp->yp_direction & YP_DECODER || Aflag) {
297 buf = modsym (sy -> sy_module, sy -> sy_name, yydecdflt);
298 if (bflag)
299 init_new_file();
300 fprintf(fph, "#define %s", buf);
301 fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
302 fprintf(fph, " %s(%s%s, ", DECFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
303 fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
304 fprintf(fph, "pe, top, len, buffer, (char **) parm)\n\n");
305#if ACT_CODE
306 if (decflag) {
307 fprintf(fpd, "%s%s", DEC_FNCNAME, tab);
308 open_func(fpd);
309 decflag--;
310 }
311#endif
312 if (bflag)
313 end_file();
314 }
315 if (yp->yp_direction & YP_PRINTER || Aflag) {
316 buf = modsym (sy -> sy_module, sy -> sy_name, yyprfdflt);
317 if (bflag)
318 init_new_file();
319 fprintf(fph, "#define %s", buf);
320 fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
321 fprintf(fph, " %s(%s%s, ", PRNTFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
322 fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
323 fprintf(fph, "pe, top, len, buffer)\n");
324 fprintf(fph, "#define %s_P", buf);
325 fprintf(fph, " %s%s, ", PREFIX,
326 proc_name(sy->sy_name, 1));
327 fprintf(fph, "&%s%s%s\n\n", PREFIX, tab, MODTYP_SUFFIX);
328#ifdef ACT_CODE
329 if (prntflag) {
330 fprintf(fpp, "%s%s", PRNT_FNCNAME, tab);
331 open_func(fpp);
332 prntflag--;
333 }
334#endif
335 if (bflag)
336 end_file();
337 }
338 if (!bflag && ferror(stdout))
339 myyerror("write error - %s", sys_errname(errno));
340 }
341 fprintf(fph, "\n#endif /* lint */\n");
342
343#ifdef ACT_CODE
344 if (!encflag) {
345 close_func(fpe);
346 }
347 if (!decflag) {
348 close_func(fpd);
349 }
350 if (!prntflag) {
351 close_func(fpp);
352 }
353#endif
354
355 close(fph);
356#ifdef ACT_CODE
357 close(fpe);
358 close(fpd);
359 close(fpp);
360 close(fpa);
361#endif
362}
363
364
365gen_enctbl(fp, sy)
366FILE *fp;
367SY sy;
368{
369 YP yp;
370
371 yp = sy->sy_type;
372 fprintf(fp,"static tpe %s%s[] = {\n", ETABLE, proc_name(sy->sy_name, 0));
373 fprintf(fp, "\t{ PE_START, 0, 0, 0 },\n");
374
375 tenc_typ(fp, yp, sy->sy_name, NULLCP);
376
377 fprintf(fp, "\t{ PE_END, 0, 0, 0 }\n");
378 fprintf(fp, "\t};\n");
379 fprintf(fp, "\n");
380}
381
382gen_dectbl(fp, sy)
383FILE *fp;
384SY sy;
385{
386 YP yp;
387
388 yp = sy->sy_type;
389 fprintf(fp,"static tpe %s%s[] = {\n", DTABLE, proc_name(sy->sy_name, 0));
390 fprintf(fp, "\t{ PE_START, 0, 0, 0 },\n");
391
392 tdec_typ(fp, sy->sy_type, sy->sy_name, NULLCP);
393
394 fprintf(fp, "\t{ PE_END, 0, 0, 0 }\n");
395 fprintf(fp, "\t};\n");
396 fprintf(fp, "\n");
397}
398
399
400gen_prnttbl(fp, sy)
401FILE *fp;
402SY sy;
403{
404 YP yp;
405
406 yp = sy->sy_type;
407
408 fprintf(fp,"static ptpe %s%s[] = {\n",PTABLE, proc_name(sy->sy_name, 0));
409 fprintf(fp, "\t{ PE_START, 0, 0, 0, \"%s\" },\n", sy->sy_name);
410
411 tprnt_typ(fp, sy->sy_type, sy->sy_name, NULLCP);
412
413 fprintf(fp, "\t{ PE_END, 0, 0, 0, NULL }\n");
414 fprintf(fp, "\t};\n");
415 fprintf(fp, "\n");
416}
417
418
419/*
420 * define the tpe index tables and the pointer table
421 */
422gen_tpe(fp)
423FILE *fp;
424{
425 SY sy;
426
427 fprintf(fp, "static tpe *etabl[] = {\n");
428 for (sy = mysymbols; sy; sy = sy->sy_next) {
429 if (sy->sy_type->yp_flags & YP_IMPORTED)
430 continue;
431 if (sy->sy_type->yp_direction & YP_ENCODER || Aflag)
432 fprintf(fp, "\t%s%s,\n", ETABLE, proc_name(sy->sy_name, 0));
433 }
434 fprintf(fp, "\t};\n\n");
435
436 fprintf(fp, "static tpe *dtabl[] = {\n");
437 for (sy = mysymbols; sy; sy = sy->sy_next) {
438 if (sy->sy_type->yp_flags & YP_IMPORTED)
439 continue;
440 if (sy->sy_type->yp_direction & YP_DECODER || Aflag)
441 fprintf(fp, "\t%s%s,\n", DTABLE, proc_name(sy->sy_name, 0));
442 }
443 fprintf(fp, "\t};\n\n");
444
445 fprintf(fp, "static ptpe *ptabl[] = {\n");
446 for (sy = mysymbols; sy; sy = sy->sy_next) {
447 if (sy->sy_type->yp_flags & YP_IMPORTED)
448 continue;
449 if (sy->sy_type->yp_direction & YP_PRINTER || Aflag)
450 fprintf(fp, "\t%s%s,\n", PTABLE, proc_name(sy->sy_name, 0));
451 }
452 fprintf(fp, "\t};\n\n");
453
454 /* produce pointer table */
455 dump_ptrtab(fp);
456}
457
458/*
459 * output the module structure for this module
460 */
461gen_modtype(fp, no, f1, f2, f3)
462FILE *fp;
463int no;
464int f1, f2, f3;
465{
466 if (!f1)
467 fprintf(fp, "extern PE\t%s%s();\n", ENC_FNCNAME, tab);
468 if (!f2)
469 fprintf(fp, "extern PE\t%s%s();\n", DEC_FNCNAME, tab);
470 if (!f3)
471 fprintf(fp, "extern PE\t%s%s();\n", PRNT_FNCNAME, tab);
472 fprintf(fp, "\n");
473 fprintf(fp, "modtyp %s%s%s = {\n", PREFIX, tab, MODTYP_SUFFIX);
474 fprintf(fp, "\t\"%s\",\n", mymodule); /* name */
475 fprintf(fp, "\t%d,\n", no); /* number of entries */
476 /* coding tables */
477 fprintf(fp, "\tetabl,\n");
478 fprintf(fp, "\tdtabl,\n");
479 fprintf(fp, "\tptabl,\n");
480 /* action tables */
481 if (e_actions > 0)
482 fprintf(fp, "\tefn_%s,\n", tab);
483 else
484 fprintf(fp, "\t0,\n"); /* no action code */
485
486 if (d_actions > 0)
487 fprintf(fp, "\tdfn_%s,\n", tab);
488 else
489 fprintf(fp, "\t0,\n"); /* no action code */
490
491 if (p_actions > 0)
492 fprintf(fp, "\tpfn_%s,\n", tab);
493 else
494 fprintf(fp, "\t0,\n"); /* no action code */
495
496 fprintf(fp, "\t%s%s%s,\n", PREFIX, PTR_TABNAME, tab);
497 fprintf(fp, "\t};\n\n");
498}
499
500/*
501 * open a file called name
502 */
503FILE *
504ffopen(name)
505char *name;
506{
507 FILE *fp;
508
509 if ((fp = fopen(name, "w")) == NULL) {
510 fprintf(stderr, "Can't create the file %s", name);
511 exit(1);
512 }
513 return fp;
514}
515
516#ifdef ACT_CODE
517/*
518 * output the file prologue to the file specified by fp
519 */
520file_header(fp, act)
521FILE *fp;
522char *act;
523{
524 fprintf(fp, "#include %s\n", PSAP_DOT_H);
525 fprintf(fp, "#include \"%s\"\n", INCFILE1);
526 fprintf(fp, "#include \"%s\"\n", act);
527 fprintf(fp, "#include \"%s%s\"\n\n", mymodule, GENTYPES);
528 fprintf(fp, "#ifndef PEPYPARM\n");
529 fprintf(fp, "#define PEPYPARM char *\n");
530 fprintf(fp, "#endif\n");
531 fprintf(fp, "extern PEPYPARM NullParm;\n\n");
532}
533
534#endif
535
536/*
537 * output the function prologue to the file specified by fp
538 */
539open_func(fp)
540FILE *fp;
541{
542
543 fprintf(fp, "(pe, parm, p, mod)\n");
544 fprintf(fp, "PE\tpe;\n");
545 fprintf(fp, "PEPYPARM\tparm;\n");
546 fprintf(fp, "tpe\t*p;\n");
547 fprintf(fp, "modtyp\t*mod;\n");
548 fprintf(fp, "{\n");
549 /* action 0 ???? */
550 fprintf(fp, "\tswitch (p->pe_ucode) {\n");
551}
552
553/*
554 * output the function epilogue to the file specified by fp
555 */
556close_func(fp)
557FILE *fp;
558{
559 fprintf(fp, "\t\tdefault:\n");
560 fprintf(fp, "\t\t\tbreak;\n");
561 fprintf(fp, "\t}\n");
562 fprintf(fp, "\treturn OK;\n}\n\n");
563}
564
565/*
566 * print the table id_table
567 */
568print_table()
569{
570 int i;
571 id_entry *t;
572
573 for (i = 0; i < TABLESIZE; i++) {
574 for (t = id_table[i]; t != NULL; t = t->next)
575 (void) printf("%s(%d) --> ", t->r_value, t->def_value);
576 if (id_table[i] != NULL)
577 (void) printf("NULL -- %d\n", i);
578 }
579}
580static struct univ_typ univ_tab[] = {
581 {"EXTERNAL", "struct type_UNIV_EXTERNAL *", "EXTERNAL", 8, 0,
582 "UNIV", UNF_EXTMOD|UNF_HASDATA, YP_SEQLIST, },
583 {"GeneralString", "struct qbuf *", "OCTETSTRING", 27, 0,
584 "UNIV", 0, YP_OCT, },
585 {"GeneralisedTime", "struct qbuf *", "OCTETSTRING", 24, 0,
586 "UNIV", 0, YP_OCT, },
587 {"GeneralizedTime", "struct qbuf *", "OCTETSTRING", 24, 0,
588 "UNIV", 0, YP_OCT, },
589 {"GraphicString", "struct qbuf *", "OCTETSTRING", 25, 0,
590 "UNIV", 0, YP_OCT, },
591 {"IA5String", "struct qbuf *", "OCTETSTRING", 22, 0,
592 "UNIV", 0, YP_OCT, },
593 {"ISO646String", "struct qbuf *", "OCTETSTRING", 26, 0,
594 "UNIV", 0, YP_OCT, },
595 {"NumericString", "struct qbuf *", "OCTETSTRING", 18, 0,
596 "UNIV", 0, YP_OCT, },
597 {"PrintableString", "struct qbuf *", "OCTETSTRING", 19, 0,
598 "UNIV", 0, YP_OCT, },
599 {"TeletexString", "struct qbuf *", "OCTETSTRING", 20, 0,
600 "UNIV", 0, YP_OCT, },
601 {"T61String", "struct qbuf *", "OCTETSTRING", 20, 0,
602 "UNIV", 0, YP_OCT, },
603 {"UTCTime", "struct qbuf *", "OCTETSTRING", 23, 0,
604 "UNIV", 0, YP_OCT, },
605 {"UniversalTime", "struct qbuf *", "OCTETSTRING", 23, 0,
606 "UNIV", 0, YP_OCT, },
607 {"VideotexString", "struct qbuf *", "OCTETSTRING", 21, 0,
608 "UNIV", 0, YP_OCT, },
609 {"VisibleString", "struct qbuf *", "OCTETSTRING", 26, 0,
610 "UNIV", 0, YP_OCT, },
611};
612
613extern struct univ_typ *simptyp();
614
615/*
616 * Determine wether the type name matches one of the Universal types
617 * which are to be treated specially. If so return a pointer to the
618 * data structure which contains the parameters describing how it
619 * should be processed
620 */
621struct univ_typ *
622univtyp(name)
623char *name;
624{
625 int low, high, i;
626 struct univ_typ *p;
627
628 low = 0;
629 high = NENTRIES(univ_tab) - 1;
630 while (low <= high) {
631 p = univ_tab + (low + high) / 2;
632 if ((i = scmp(name, p->univ_name)) == 0)
633 return (p);
634 if (low == high)
635 return (NULL);
636 if (i < 0)
637 high = p - univ_tab - 1;
638 else
639 low = p - univ_tab + 1;
640 }
641
642#if OPTIMISED
643 if ((p = simptyp(name)) == NULL)
644 return (p);
645#endif
646
647 return (NULL);
648}
649
650/*
651 * Compare two strings returning a number representing the character
652 * where they differ or 0 if are the same - I wrote this because I
653 * couldn't trust strcmp to work the same way between numbers and
654 * letters everywhere. longer strings are greater shorter strings
655 * numbers are greater then all letters lower case are greater then
656 * upper case There must be a better way !
657 */
658scmp(s1, s2)
659char *s1, *s2;
660{
661 while (*s1 == *s2 && *s2)
662 s1++, s2++;
663 if (*s1 == '\0' && *s2 == '\0')
664 return (0);
665 if (*s1 == '\0')
666 return (-1);
667 if (*s2 == '\0')
668 return (1);
669 if (isalpha(*s1) && isalpha(*s2)) {
670 if (isupper(*s1) && isupper(*s2))
671 return (*s1 - *s2);
672 if (islower(*s1) && islower(*s1))
673 return (*s1 - *s2);
674 if (isupper(*s1))
675 return (-1);
676 if (islower(*s1))
677 return (1);
678 }
679 if (isdigit(*s1) && isdigit(*s2))
680 return (*s1 - *s2);
681 if (isdigit(*s1))
682 return (1);
683 if (isdigit(*s2))
684 return (-1);
685 return (*s1 - *s2);
686}
687
688/*
689 * lookup a symbol and return a pointer to it
690 */
691SY
692syfind(name)
693char *name;
694{
695 SY sy;
696
697 for (sy = mysymbols; sy; sy = sy->sy_next) {
698 if (sy->sy_type->yp_flags & YP_IMPORTED)
699 continue;
700 if (strcmp(name, sy->sy_name) == 0)
701 return (sy);
702 }
703 return (NULL);
704}
705/*
706 * determine if the symbol is a simple type that is optimised
707 */
708struct univ_typ *
709simptyp(yp)
710YP yp;
711{
712 struct univ_typ *p;
713 YP y;
714
715 static struct univ_typ bitstring =
716 {"Bitstring", "struct PElement *", "BITSTRING", 3, 0},
717 octetstring =
718 {"GeneralString", "struct qbuf *", "OCTETSTRING", 4, 0},
719 oid =
720 {"Object Identifier", "struct OIDentifier *", "OBJIDENT", 6, 0},
721 obj =
722 {"Module", "struct OIDentifier *",
723 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 27, 0};
724
725#define MSTRING 30 /* number of Xs in the above string */
726
727 switch (yp->yp_code) {
728 case YP_BIT:
729 case YP_BITLIST:
730 return (&bitstring);
731
732 case YP_SEQ:
733 case YP_SET:
734 case YP_ANY:
735 return (&bitstring);
736
737 case YP_OCT:
738 return (&octetstring);
739
740 case YP_OID:
741 return (&oid);
742
743 case YP_IDEFINED:
744 strncpy(p->univ_tab, yp->yp_identifier, MSTRING);
745 return (&obj);
746
747
748 case YP_SEQLIST:
749 case YP_SETLIST:
750 case YP_CHOICE:
751
752 default:
753 return (NULL);
754 }
755}
756
757/*
758 * lookup a type name until you get something that is not a name
759 */
760YP
761lkup(yp)
762YP yp;
763{
764 YP yp1;
765
766 if (yp == NULLYP)
767 return (yp);
768
769 while (yp->yp_code == YP_IDEFINED) {
770 if ((yp1 = lookup_type(yp->yp_module, yp->yp_identifier)) == NULLYP)
771 return (yp);
772 yp = yp1;
773 }
774
775 return (yp);
776}
777/*
778 * compute the type of tag it should be given the tag and the type it is
779 * being applied to
780 */
781comptag(tag, yp)
782int tag;
783YP yp;
784{
785 static int warned = 0;
786 YP yp1;
787 struct univ_typ *p;
788 int code;
789
790 if (tag == 0)
791 return (0);
792
793 yp1 = lkup(yp);
794
795 if (yp1->yp_code == YP_IDEFINED) {
796 if ((p = univtyp(yp1->yp_identifier)) == NULL
797 || p->univ_type <= YP_UNDF) {
798 switch (chkil(yp1->yp_identifier)) {
799 case ER_NORMAL:
800 return (tag);
801
802 case ER_EXPLICIT:
803 return (0);
804
805 default:
806 break;
807 }
808
809 if (warned++ <= 3) {
810 ferrs(0, "\ncomptag:warning implicit tag of unknown type %s\n",
811 yp1->yp_identifier);
812 ferr(0, "\tcomptag:treated as implicit\n");
813 }
814 return (tag);
815 }
816 code = p->univ_type;
817 } else {
818 code = yp1->yp_code;
819 if (code == YP_ANY && yp1->yp_flags & YP_WANTIMPLICIT)
820 return (tag);
821 }
822
823 if (code == YP_CHOICE || code == YP_ANY)
824 return (0);
825
826 return (tag);
827}
828
829/*
830 * Generate function definitions for all the macros so that lint
831 * can type check all thier uses
832 */
833gen_lint(fp)
834FILE *fp;
835{
836 char *buf;
837 SY sy;
838 YP yp;
839
840 fprintf(fp, "\n#ifdef\tlint\n");
841 for (sy = mysymbols; sy; sy = sy->sy_next) {
842 eval = sy->sy_name;
843 yp = sy->sy_type;
844
845 if (sy->sy_module == NULLCP)
846 yyerror("no module name associated with symbol");
847 if (yp->yp_flags & YP_IMPORTED)
848 continue;
849 if (strcmp(sy->sy_module, mymodule)) {
850 fprintf(stderr,
851 "mymodule unsuitable for module name e.g %s and %s(mymodule)\n",
852 sy->sy_module, mymodule);
853 exit(1);
854 }
855 /* Encoding routine */
856 buf = modsym (sy -> sy_module, sy -> sy_name, yyencdflt);
857 fprintf(fp, "\n#undef %s\n", buf);
858 fprintf(fp, "int %s", buf);
859 fprintf(fp, "(pe, top, len, buffer, parm)\n");
860 fprintf(fp, "PE *pe;\n");
861 fprintf(fp, "int\ttop,\n\tlen;\n");
862 fprintf(fp, "char *buffer;\n");
863 fprintf(fp, "%s *parm;\n", sym2type(sy));
864 fprintf(fp, "{\n return (%s(%s%s, ",
865 ENCFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
866 fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
867 fprintf(fp, "pe, top, len, buffer,\n\t\t(char *) parm));\n}\n");
868
869 /* Decoding routine */
870 buf = modsym (sy -> sy_module, sy -> sy_name, yydecdflt);
871 fprintf(fp, "\n#undef %s\n", buf);
872 fprintf(fp, "int %s", buf);
873 fprintf(fp, "(pe, top, len, buffer, parm)\n");
874 fprintf(fp, "PE\tpe;\n");
875 fprintf(fp, "int\ttop,\n *len;\n");
876 fprintf(fp, "char **buffer;\n");
877 fprintf(fp, "%s **parm;\n", sym2type(sy));
878 fprintf(fp, "{\n return (%s(%s%s, ",
879 DECFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
880 fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
881 fprintf(fp, "pe, top, len, buffer,\n\t\t(char **) parm));\n}\n");
882
883 /* Printing routine */
884 buf = modsym (sy -> sy_module, sy -> sy_name, yyprfdflt);
885 fprintf(fp, "\n#undef %s\n/* ARGSUSED */\n", buf);
886 fprintf(fp, "int %s", buf);
887 fprintf(fp, "(pe, top, len, buffer, parm)\n");
888 fprintf(fp, "PE\tpe;\n");
889 fprintf(fp, "int\ttop,\n *len;\n");
890 fprintf(fp, "char **buffer;\n");
891 fprintf(fp, "%s *parm;\n", sym2type(sy));
892 fprintf(fp, "{\n return (%s(%s%s, ",
893 PRNTFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
894 fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
895 fprintf(fp, "pe, top, len, buffer));\n}\n");
896
897 if (ferror(fp))
898 myyerror("write error - %s", sys_errname(errno));
899 }
900 fprintf(fp, "\n#endif\t/* lint */\n");
901}
902
903/*
904 * pointer table support routines
905 */
906static char *ptr_tab[MAXPTRS]; /* reference of the pointer */
907static int ptr_cnt = 0;
908
909/*
910 * add the given pointer to the pointer table and return its index
911 */
912addptr(p)
913char *p;
914{
915 int ind;
916 register int i;
917 register char *s;
918
919 /*
920 * try to eliminate common pointers by returning a ponter if it matches
921 * previously
922 */
923 for (i = 0; i < ptr_cnt; i++)
924 if (strcmp(p, ptr_tab[i]) == 0)
925 return (i);
926
927 if (ptr_cnt >= MAXPTRS) {
928 fprintf(stderr, "\npointer table overflow %d\n", ptr_cnt);
929 exit(1);
930 }
931
932 if ((s = malloc ((unsigned) (strlen (p) + 1))) == NULLCP) {
933 fprintf(stderr, "\naddptr:out of memory\n");
934 exit(1);
935 }
936 (void) strcpy (s, p);
937
938 ptr_tab[ind = ptr_cnt++] = s;
939
940 return (ind);
941}
942
943
944dump_ptrtab(fp)
945FILE *fp;
946{
947 int i;
948
949
950 fprintf(fp, "\n/* Pointer table %d entries */\n", ptr_cnt);
951 fprintf(fp, "static caddr_t %s%s%s[] = {\n", PREFIX, PTR_TABNAME, tab);
952
953 for (i = 0; i < ptr_cnt; i++)
954 fprintf(fp, " (caddr_t ) %s,\n", ptr_tab[i]);
955
956 if (ptr_cnt <= 0)
957 fprintf(fp, " (caddr_t ) 0,\n"); /* for fussy C compilers */
958
959 fprintf(fp, "};\n");
960}
961
962/*
963 * routines to parse and analyse C types to support the pepy-like extensions
964 * of pepsy
965 */
966
967/*
968 * remove a level of indirection from the given type. If possible. if not
969 * return NULLCP, otherwise return the new type in a temporary buffer
970 */
971char *
972rm_indirect(p)
973char *p;
974{
975 static char buf[STRSIZE];
976 int i;
977
978 if (p == NULLCP || *p == '\0' || (i = strlen(p)) >= STRSIZE)
979 return (NULLCP);
980
981 strncpy(buf, p, STRSIZE);
982
983 for (; i >= 0; i--) {
984 if (buf[i] == '*') {
985 buf[i] = '\0';
986 return (buf);
987 }
988 }
989
990 return (NULLCP);
991
992}
993
994/*
995 * extract the field from the C arguement and the following constant
996 * expression for the bit number.
997 * if it fails return NULLCP
998 */
999char *
1000getfldbit(p, pstr)
1001register char *p;
1002char **pstr;
1003{
1004 static char buf[STRSIZE];
1005
1006 if (p == NULLCP || pstr == (char **)0)
1007 return (NULLCP);
1008
1009 if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
1010 return (NULLCP);
1011
1012 while (*p && isspace(*p))
1013 p++;
1014
1015 if (*p != '$') { /* must be a -> */
1016
1017 if (strncmp(p, "->", 2) != 0)
1018 return (NULLCP);
1019
1020 p += 2;
1021
1022 if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
1023 return (NULLCP);
1024
1025 while (*p && isspace(*p))
1026 p++;
1027
1028 if (*p != '$')
1029 return (NULLCP);
1030 }
1031
1032 *pstr = p + 1; /* have to leave it up to the compiler to verify the
1033 * constant expression for the bit number
1034 */
1035 return (buf);
1036}
1037
1038/* return a pointer after the current batch of white space if any */
1039char *
1040skipspace(p)
1041char *p;
1042{
1043 if (p == NULLCP)
1044 return (NULLCP);
1045
1046 while (*p && isspace(*p))
1047 p++;
1048
1049 return (p);
1050}
1051
1052/*
1053 * extract the field from the C arguement and return it in a static buffer
1054 * else return NULLCP
1055 */
1056char *
1057getfield(p)
1058register char *p;
1059{
1060 static char buf[STRSIZE];
1061 char *buf1;
1062
1063 if (p == NULLCP)
1064 return (NULLCP);
1065
1066 while (*p && isspace(*p))
1067 p++;
1068
1069 if (*p == '*') /* to support *parm field */
1070 return (p);
1071
1072 if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
1073 return (NULLCP);
1074
1075 while (*p && isspace(*p))
1076 p++;
1077
1078 if (*p == '\0')
1079 return (buf);
1080
1081 if (strncmp(p, "->", 2) != 0)
1082 return (NULLCP);
1083
1084 p += 2;
1085
1086 /* if we have an & keep it on the field */
1087 if (*buf == '&')
1088 buf1 = buf + 1;
1089 else
1090 buf1 = buf;
1091
1092 if ((p = getidordot(p, buf1, STRSIZE)) == NULLCP)
1093 return (NULLCP);
1094
1095 while (*p && isspace(*p))
1096 p++;
1097
1098 if (*p == '\0')
1099 return (buf);
1100
1101 return (NULLCP);
1102}
1103
1104/*
1105 * get an identifier into the given buffer [A-Za-z_] are legal chars
1106 */
1107char *
1108getid(p, buf, len)
1109register char *p;
1110register char *buf;
1111register int len;
1112{
1113 char *fbuf;
1114
1115 fbuf = buf;
1116
1117 while (*p && isspace(*p))
1118 p++;
1119
1120 while (*p && (isalnum(*p) || *p == '_')) {
1121 if (len-- >= 0)
1122 *buf++ = *p;
1123 p++;
1124 }
1125
1126 if (fbuf == buf)
1127 return (NULLCP);
1128
1129 *buf = '\0';
1130
1131 return (p);
1132
1133}
1134
1135/*
1136 * get an identifier into the given buffer - '.' are considered part of an
1137 * identifier - should really be called get field reference
1138 */
1139char *
1140getidordot(p, buf, len)
1141register char *p;
1142register char *buf;
1143register int len;
1144{
1145 char *fbuf;
1146
1147 fbuf = buf;
1148
1149 while (*p && isspace(*p))
1150 p++;
1151
1152 if (*p == '&') {
1153 len--;
1154 *buf++ = *p++;
1155
1156 while (*p && isspace(*p))
1157 p++;
1158 }
1159
1160 while (*p && (isalnum(*p) || *p == '_' || *p == '.')) {
1161 if (len-- >= 0)
1162 *buf++ = *p;
1163 p++;
1164 }
1165
1166 if (fbuf == buf)
1167 return (NULLCP);
1168
1169 *buf = '\0';
1170
1171 return (p);
1172
1173}
1174static char *noindstr[] = {
1175 "*", "*parm", "&", "&parm",
1176 NULLCP
1177 };
1178
1179/*
1180 * determine if the given field means no indirection wanted and so return 1
1181 * else return 0
1182 */
1183noindirect(f)
1184char *f;
1185{
1186 char *p, **ps;
1187 int l;
1188
1189 if (f == NULLCP)
1190 return (1);
1191
1192 f = skipspace(f);
1193
1194 if (f == NULLCP)
1195 return (1);
1196
1197 if (*f == '&')
1198 return (1);
1199
1200 for (p = f; *p && !isspace(*p); p++)
1201 ;
1202 l = p - f;
1203
1204 for (ps = noindstr; *ps; ps++)
1205 if (l == strlen(*ps) && strncmp(f, *ps, l) == 0)
1206 return (1);
1207
1208 return (0);
1209}
1210
1211/*
1212 * process the T - the Type and field specifier
1213 * the given YP to the appropriate values for VALTYPE string
1214 * Namely the yp_parm_type to contain the (Parameter) type string.
1215 * then if there is a $ the yp_parm to the part after the $, the field
1216 */
1217setvaltype(yp, str)
1218YP yp;
1219char *str;
1220{
1221 char *p;
1222
1223 if (str == NULLCP || *(str = skipspace(str)) == '\0')
1224 return (0);
1225
1226 if (p = index(str, '$')) {
1227 *p++ = '\0';
1228 p = skipspace(p);
1229 yp->yp_parm = strdup(p);
1230 yp->yp_flags |= YP_PARMVAL;
1231 }
1232
1233 yp->yp_param_type = strdup(str);
1234
1235 return (1);
1236
1237}
1238
1239
1240/*
1241 * generate the functions that carry out the action statements
1242 */
1243gen_actfunct(fp)
1244FILE *fp;
1245{
1246 SY sy;
1247 YP yp;
1248 Action act;
1249
1250 if (e_actions > 0) {
1251 (void) fprintf(fp, "\n/*VARARGS*/");
1252 (void) fprintf(fp, "\nstatic\tint\nefn_%s(__p, ppe, _Zp)\ncaddr_t __p;\n", tab);
1253 (void) fprintf(fp, "PE *ppe;\ntpe *_Zp;\n{\n");
1254 (void) fprintf(fp, "\t\t\n\t/* %d cases */\n switch(_Zp->pe_ucode) {\n",
1255 e_actions);
1256 for (sy = mysymbols; sy; sy = sy->sy_next) {
1257 yp = sy->sy_type;
1258 if (yp->yp_flags & YP_IMPORTED)
1259 continue;
1260
1261 if (yp->yp_direction & YP_ENCODER || Aflag)
1262 gen_actions(fp, yp, G_ENC);
1263
1264 }
1265 (void) fprintf(fp,
1266" default:\n return (pepsylose(NULLMODTYP, _Zp, *ppe, \"enf_%s:Bad table entry: %%d\",\n _Zp->pe_ucode));\n",
1267 tab);
1268 (void) fprintf(fp, "\t\t}\t/* switch */\n return (OK);\n}\n");
1269 }
1270 if (d_actions > 0) {
1271 (void) fprintf(fp, "\n/*VARARGS*/");
1272 (void) fprintf(fp, "\nstatic\tint\ndfn_%s(__p, pe, _Zp, _val)\ncaddr_t __p;\n", tab);
1273 (void) fprintf(fp, "PE pe;\ntpe *_Zp;\nint _val;\n{\n");
1274 (void) fprintf(fp, "\t\t\n\t/* %d cases */\n switch(_Zp->pe_ucode) {\n",
1275 d_actions);
1276 for (sy = mysymbols; sy; sy = sy->sy_next) {
1277 yp = sy->sy_type;
1278 if (yp->yp_flags & YP_IMPORTED)
1279 continue;
1280
1281 if (yp->yp_direction & YP_DECODER || Aflag)
1282 gen_actions(fp, yp, G_DEC);
1283
1284 }
1285 (void) fprintf(fp,
1286" default:\n return (pepsylose(NULLMODTYP, _Zp, pe, \"dnf_%s:Bad table entry: %%d\",\n _Zp->pe_ucode));\n",
1287 tab);
1288 (void) fprintf(fp, "\t\t}\t/* switch */\n return (OK);\n}\n");
1289 }
1290 if (p_actions > 0) {
1291 (void) fprintf(fp, "\n/*VARARGS*/");
1292 (void) fprintf(fp, "\nstatic\tint\npfn_%s(pe, _Zp)\n", tab);
1293 (void) fprintf(fp, "PE pe;\ntpe *_Zp;\n{\n");
1294 (void) fprintf(fp, "\t\t\n\t/* %d cases */\n switch(_Zp->pe_ucode) {\n",
1295 p_actions);
1296 for (sy = mysymbols; sy; sy = sy->sy_next) {
1297 yp = sy->sy_type;
1298
1299 if (yp->yp_flags & YP_IMPORTED)
1300 continue;
1301
1302 if (yp->yp_direction & YP_PRINTER || Aflag)
1303 gen_actions(fp, yp, G_PNT);
1304
1305 }
1306 (void) fprintf(fp,
1307" default:\n return (pepsylose(NULLMODTYP, _Zp, NULLPE, \"pnf_%s:Bad table entry: %%d\",\n _Zp->pe_ucode));\n",
1308 tab);
1309 (void) fprintf(fp, "\t\t}\t/* switch */\n return (OK);\n}\n");
1310 }
1311}
1312
1313#define GEN_RETURN 1
1314#define GEN_ASSIGN 2
1315/*
1316 * generate the actions for this YP unit and all its children
1317 */
1318gen_actions(fp, oyp, form)
1319FILE *fp;
1320YP oyp;
1321int form; /* what type of action is it */
1322{
1323 register YP yp;
1324 register YAL yal;
1325 register Action act;
1326
1327 for (yp = oyp; yp; yp = yp->yp_next) {
1328
1329 /* do its actions first then any of its children */
1330 if (yal = yp->yp_bef_alist)
1331 dumpact(fp, yal, form, 0);
1332 if (yal = yp->yp_aft_alist)
1333 dumpact(fp, yal, form, 0);
1334 if (yal = yp -> yp_control_act) {
1335 if (form == G_ENC)
1336 dumpact (fp, yal,form, GEN_RETURN);
1337 else if (form == G_DEC)
1338 dumpact (fp, yal, form, GEN_ASSIGN);
1339 }
1340 if (yal = yp -> yp_optional_act) {
1341 if (form == G_ENC)
1342 dumpact (fp, yal,form, GEN_RETURN);
1343 else if (form == G_DEC)
1344 dumpact (fp, yal, form, 0);
1345 }
1346
1347 switch (yp->yp_code) {
1348 case YP_SEQTYPE:
1349 case YP_SEQLIST:
1350 case YP_SETTYPE:
1351 case YP_SETLIST:
1352 case YP_CHOICE:
1353 gen_actions(fp, yp->yp_type, form);
1354 break;
1355
1356 default:
1357 break;
1358 }
1359 }
1360}
1361/*
1362 * dump out a single action
1363 */
1364dumpact(fp, yal, form, ret)
1365FILE *fp;
1366YAL yal;
1367int form;
1368int ret;
1369{
1370 char *comm = yal->yal_comment;
1371 char *type = yal->yal_type;
1372 Action act;
1373 char buf[STRSIZE];
1374
1375 if (strlen(type) > STRSIZE)
1376 ferr(1, "dumpact:type too big \"%s\"\n bye\n", type);
1377 strncpy(buf, type, STRSIZE);
1378 if (form != G_DEC)
1379 strncat(buf, "*", STRSIZE);
1380 else
1381 strncat(buf, "**", STRSIZE);
1382 type = buf;
1383 switch (form) {
1384 case G_ENC:
1385 act = yal->yal_enc;
1386 break;
1387 case G_DEC:
1388 act = yal->yal_dec;
1389 break;
1390 case G_PNT:
1391 act = yal->yal_prn;
1392 break;
1393 }
1394
1395 /* can't tell wether this table has the UCODE till here */
1396 if (act == NULLAction || act -> a_line == -1)
1397 return;
1398
1399 if (form != G_PNT)
1400 (void) fprintf(fp, "\n#define parm ((%s )__p)\n\tcase %d: /* %s */\n",
1401 type, act->a_num, comm ? comm : "");
1402 else
1403 (void) fprintf(fp, "\n\tcase %d: /* %s */\n", act->a_num, comm ? comm : "");
1404
1405 (void) fprintf(fp, "\t\t{\n# line %d \"%s\"\n", act->a_line, sysin);
1406
1407 switch (ret) {
1408 case GEN_ASSIGN:
1409 if (control_act (act) == -1)
1410 fprintf (fp, "\t\t/* ignored - empty expression */\n");
1411 else fprintf (fp, "\t\t(%s) = _val;\n", act -> a_data);
1412 break;
1413 case GEN_RETURN:
1414 fprintf (fp, "\t\treturn (%s);\n",act -> a_data);
1415 break;
1416 default:
1417 fputs (act -> a_data, fp);
1418 putc (';', fp);
1419 break;
1420 }
1421
1422 (void) fprintf(fp, "\n\t\t}\n\t break;\n");
1423
1424 if (form != G_PNT)
1425 (void) fprintf(fp, "\n#undef parm\n");
1426 act -> a_line = -1; /* mark as done */
1427}
1428
1429/*
1430 * produce a temporary copy of the type specified in the ParameterType
1431 * specification
1432 * i.e. a [[ P type ]] specification
1433 */
1434char *
1435partyp2str(yp)
1436YP yp;
1437{
1438 char *p;
1439
1440 if (yp->yp_param_type == NULLCP) {
1441 fprintf(stderr, "\npartyp2str no param_type field\n");
1442 exit(1);
1443 }
1444
1445 if ((p = rm_indirect(yp->yp_param_type)) == NULLCP) {
1446 fprintf(stderr, "\npartyp2str can't extract direct type from %s\n",
1447 yp->yp_param_type);
1448 exit(1);
1449 }
1450
1451 return (p);
1452}
1453/*
1454 * produce a string giving the type of a symbol, in a static buffer
1455 */
1456char *
1457sym2type(sy)
1458SY sy;
1459{
1460 static char buffer[STRSIZE];
1461
1462 if (sy->sy_type && sy->sy_type->yp_param_type)
1463 return (partyp2str(sy->sy_type));
1464
1465 sprintf(buffer, "struct %s", modsym(sy->sy_module, sy->sy_name, "type"));
1466
1467 return (buffer);
1468}