Commit | Line | Data |
---|---|---|
459ebbd7 C |
1 | /* dtabs.c */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/pepsy/RCS/dtabs.c,v 7.10 91/02/22 09:48:47 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/pepsy/RCS/dtabs.c,v 7.10 91/02/22 09:48:47 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: dtabs.c,v $ | |
12 | * Revision 7.10 91/02/22 09:48:47 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.9 91/01/08 12:49:21 mrose | |
16 | * update | |
17 | * | |
18 | * Revision 7.8 90/12/23 17:24:26 mrose | |
19 | * patches | |
20 | * | |
21 | * Revision 7.7 90/12/11 10:33:19 mrose | |
22 | * sync | |
23 | * | |
24 | * Revision 7.5 90/11/11 09:58:51 mrose | |
25 | * touch-up | |
26 | * | |
27 | * Revision 7.4 90/11/04 19:18:21 mrose | |
28 | * update | |
29 | * | |
30 | * Revision 7.3 90/08/18 00:44:15 mrose | |
31 | * touch-up | |
32 | * | |
33 | * Revision 7.2 90/07/27 08:49:09 mrose | |
34 | * update | |
35 | * | |
36 | * Revision 7.1 90/07/09 14:52:25 mrose | |
37 | * sync | |
38 | * | |
39 | * Revision 7.0 90/07/01 19:54:15 mrose | |
40 | * *** empty log message *** | |
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 "pepsydefs.h" | |
57 | #include "pass2.h" | |
58 | #include "mine.h" | |
59 | #include <ctype.h> | |
60 | ||
61 | ||
62 | extern FILE *fp; | |
63 | extern char *c_tag(), *c_class(); | |
64 | extern char *ec_tag(), *ec_class(); | |
65 | extern char *strip_last(); | |
66 | extern char *str_yp_code[]; | |
67 | extern char *get_val(), *get_comp(), *strp2name(); | |
68 | extern s_table *lookup_list(), *get_offset(); | |
69 | extern YP tdec_loop(); | |
70 | ||
71 | extern char *concat(); | |
72 | extern char *my_strcat(); | |
73 | extern char *rm_indirect(); | |
74 | extern char *getfield(); | |
75 | extern char *setfield(); | |
76 | ||
77 | extern int gen_sentry(); | |
78 | ||
79 | /* extern int explicit; */ | |
80 | ||
81 | #define WORDSIZE 20 | |
82 | ||
83 | /* | |
84 | * table encode a type. generate tables for the encoding of a type | |
85 | */ | |
86 | tdec_typ(fp, yp, id, type) | |
87 | FILE *fp; | |
88 | YP yp; | |
89 | char *id; | |
90 | char *type; | |
91 | { | |
92 | char *t, *f; | |
93 | char *p1; | |
94 | char *s1, *s2, *s3; | |
95 | char *s; | |
96 | s_table *ptr1, *ptr2; | |
97 | YP y; | |
98 | YAL yal; | |
99 | ||
100 | if (yp->yp_code < 0 || yp->yp_code > YP_REAL) | |
101 | ferrd(1, "tdec_typ: unimplemented type %d\n", yp->yp_code); | |
102 | ||
103 | if (yp == NULL) { | |
104 | ferr(0, "tdec_typ:NULL arguement\n"); | |
105 | return; | |
106 | } | |
107 | ||
108 | if (type) | |
109 | t = type; | |
110 | else if (yp->yp_param_type) { | |
111 | char *t1; | |
112 | /* we have a [[ P type ]] specification */ | |
113 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
114 | fprintf(stderr, | |
115 | "\ntdec_typ:SETLIST can't extract direct type from %s\n", | |
116 | yp->yp_param_type); | |
117 | exit(1); | |
118 | } | |
119 | t = strdup(t1); | |
120 | } else | |
121 | t = my_strcat("struct ", modsym(mymodule, id, "type")); | |
122 | ||
123 | if (yal = yp->yp_bef_alist) { | |
124 | yal->yal_type = t; | |
125 | if (yal->yal_dec) | |
126 | gen_act(fp, yp->yp_bef_alist->yal_dec); | |
127 | } | |
128 | if (yal = yp->yp_aft_alist) { | |
129 | yal->yal_type = t; | |
130 | } | |
131 | if (yal = yp->yp_control_act) | |
132 | yal -> yal_type = t; | |
133 | ||
134 | if (yal = yp->yp_optional_act) | |
135 | yal -> yal_type = t; | |
136 | ||
137 | if (type == NULLCP) { | |
138 | switch (yp->yp_code) { | |
139 | /* | |
140 | * These generate MEMALLOC entries inside *_START .. | |
141 | * PE_END fields for historical reasons. One day we might | |
142 | * fix this to be all done the same way. | |
143 | */ | |
144 | case YP_SEQLIST: | |
145 | case YP_SEQTYPE: | |
146 | case YP_SETLIST: | |
147 | case YP_SETTYPE: | |
148 | case YP_CHOICE: | |
149 | break; | |
150 | ||
151 | default: | |
152 | if (yp->yp_varexp == NULL) | |
153 | break; /* S* type entry - doesn't need a | |
154 | * malloc */ | |
155 | ||
156 | (void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n", t); | |
157 | break; | |
158 | } | |
159 | } | |
160 | ||
161 | ||
162 | if ((yp->yp_flags & YP_PARMVAL) && yp->yp_parm) { | |
163 | if ((f = getfield(yp->yp_parm)) == NULLCP) { | |
164 | fprintf(stderr, "\ntdec_typ: can't extract field from %s\n", | |
165 | yp->yp_parm); | |
166 | exit(1); | |
167 | } | |
168 | f = strdup(f); | |
169 | } else | |
170 | f = yp->yp_varexp; | |
171 | ||
172 | if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT)) | |
173 | == (YP_OPTIONAL|YP_OPTCONTROL)) { | |
174 | char *f1; | |
175 | char *bitno; | |
176 | ||
177 | if (yp -> yp_optional_act && yp -> yp_optional_act -> yal_dec) { | |
178 | (void) fprintf (fp, "\t{ BOPTIONAL, %d, 0, FL_USELECT},\n", | |
179 | control_act(yp -> yp_optional_act -> yal_dec)); | |
180 | } | |
181 | else { | |
182 | if ((f1 = getfldbit(yp->yp_optcontrol, &bitno)) == NULLCP) { | |
183 | fprintf(stderr, | |
184 | "\ntdec_typ:BOPTIONAL: can't extract field from %s\n", | |
185 | yp->yp_optcontrol); | |
186 | exit(1); | |
187 | } | |
188 | (void) fprintf(fp, "\t{ BOPTIONAL, AOFFSET(%s, %s), %s, 0},\n", t, | |
189 | f1, bitno); | |
190 | } | |
191 | } | |
192 | ||
193 | if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) { | |
194 | (void) fprintf(fp, "\t{ ETAG, 0, "); | |
195 | (void) fprintf(fp, "%s, %s },\n", ec_tag(yp), ec_class(yp)); | |
196 | } | |
197 | ||
198 | if (yp->yp_yfn && yp->yp_yfn->yfn_dec) { | |
199 | ||
200 | gen_fn(fp, yp, yp->yp_yfn->yfn_dec); | |
201 | ||
202 | if (yp->yp_flags & YP_DEFAULT) | |
203 | gdflt(fp, yp, G_DEC); | |
204 | ||
205 | if (gen_freefn(fp, yp)) { | |
206 | if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec) | |
207 | gen_act(fp, yp->yp_aft_alist->yal_dec); | |
208 | return; | |
209 | } | |
210 | } | |
211 | ||
212 | switch (yp->yp_code) { | |
213 | ||
214 | case YP_UNDF: | |
215 | ferr(1, "tdec_typ:Undefined type\n"); | |
216 | ||
217 | case YP_BOOL: | |
218 | if (yp->yp_intexp) | |
219 | f = setfield(yp->yp_intexp); | |
220 | if (noindirect(f)) | |
221 | ferr(1, "tdec_typ:BOOL: must specify a field for boolean\n"); | |
222 | p1 = "BOOLEAN"; | |
223 | if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) | |
224 | break; | |
225 | ferr(1, "tdec_typ:BOOL: couldn't determine type\n"); | |
226 | ||
227 | /* This needs to be fixed up in the action generating area */ | |
228 | case YP_INTLIST: | |
229 | ||
230 | case YP_INT: | |
231 | ||
232 | case YP_ENUMLIST: | |
233 | if (yp->yp_intexp) | |
234 | f = setfield(yp->yp_intexp); | |
235 | if (noindirect(f)) | |
236 | ferr(1, "tdec_typ:INT: must specify a field for an integer\n"); | |
237 | if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) { | |
238 | p1 = "INTEGER"; | |
239 | break; | |
240 | } | |
241 | ferr(1, "tdec_typ:INT: couldn't determine type\n"); | |
242 | break; | |
243 | ||
244 | case YP_REAL: | |
245 | if (yp->yp_strexp) | |
246 | f = setfield(yp->yp_strexp); | |
247 | if (noindirect(f)) | |
248 | ferr(1, "tdec_typ:REAL: must specify a field for a REAL\n"); | |
249 | if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) { | |
250 | p1 = "REALTYPE"; | |
251 | break; | |
252 | } | |
253 | ferr(1, "tdec_typ:REAL: couldn't determine type\n"); | |
254 | break; | |
255 | ||
256 | ||
257 | case YP_BIT: | |
258 | case YP_BITLIST: | |
259 | if (yp->yp_strexp && yp->yp_intexp) { | |
260 | if (yp->yp_strexp) | |
261 | f = setfield(yp->yp_strexp); | |
262 | if (noindirect(f)) | |
263 | ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n"); | |
264 | p1 = "BITSTR_PTR"; | |
265 | prnte(fp, t, f, yp, p1); | |
266 | if (yp->yp_intexp) | |
267 | f = setfield(yp->yp_intexp); | |
268 | if (noindirect(f)) | |
269 | ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n"); | |
270 | p1 = "BITSTR_LEN"; | |
271 | break; | |
272 | } | |
273 | if (yp->yp_strexp == NULLCP && yp->yp_intexp) | |
274 | f = setfield(yp->yp_intexp); | |
275 | if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) { | |
276 | p1 = "BITSTRING"; | |
277 | break; | |
278 | } | |
279 | t = NULL; | |
280 | p1 = NULL; | |
281 | (void) fprintf(fp, "\t{ SBITSTRING, 0, %s, %s },\n", | |
282 | c_tag(yp), c_class(yp)); | |
283 | break; | |
284 | ||
285 | case YP_OCT: | |
286 | if (yp->yp_strexp) { | |
287 | switch (yp->yp_prfexp) { | |
288 | case 'q': /* [[ q parm->qbufptr ]] */ | |
289 | if (yp->yp_strexp) | |
290 | f = setfield(yp->yp_strexp); | |
291 | if (noindirect(f)) | |
292 | p1 = "SOCTETSTRING"; | |
293 | else | |
294 | p1 = "OCTETSTRING"; | |
295 | break; | |
296 | ||
297 | case 's': /* [[ s ptr ]] */ | |
298 | if (yp->yp_strexp) | |
299 | f = setfield(yp->yp_strexp); | |
300 | if (noindirect(f)) | |
301 | ferr(1, "tdec_typ:OCTET: must specify a field [[ s .. ]]\n"); | |
302 | p1 = "T_STRING"; | |
303 | break; | |
304 | ||
305 | case 'o': /* [[ o ptr $ length ]] */ | |
306 | if (yp->yp_strexp) | |
307 | f = setfield(yp->yp_strexp); | |
308 | if (noindirect(f)) | |
309 | ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. ]]\n"); | |
310 | p1 = "OCTET_PTR"; | |
311 | prnte(fp, t, f, yp, p1); | |
312 | if (yp->yp_intexp) | |
313 | f = setfield(yp->yp_intexp); | |
314 | if (noindirect(f)) | |
315 | ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. $ .. ]]\n"); | |
316 | p1 = "OCTET_LEN"; | |
317 | break; | |
318 | ||
319 | default: | |
320 | fprintf(stderr,"\ntdec_typ: Unknown Octet string specifier %c\n", | |
321 | yp->yp_prfexp); | |
322 | exit(1); | |
323 | } | |
324 | break; | |
325 | } | |
326 | if (f) { | |
327 | p1 = "OCTETSTRING"; | |
328 | break; | |
329 | } | |
330 | t = NULL; | |
331 | p1 = NULL; | |
332 | (void) fprintf(fp, "\t{ SOCTETSTRING, 0, %s, %s },\n", | |
333 | c_tag(yp), c_class(yp)); | |
334 | break; | |
335 | ||
336 | case YP_OID: | |
337 | if (yp->yp_strexp) | |
338 | f = setfield(yp->yp_strexp); | |
339 | if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) { | |
340 | p1 = "OBJID"; | |
341 | break; | |
342 | } | |
343 | t = NULL; | |
344 | p1 = NULL; | |
345 | (void) fprintf(fp, "\t{ SOBJID, 0, %s, %s },\n", | |
346 | c_tag(yp), c_class(yp)); | |
347 | break; | |
348 | ||
349 | case YP_SEQ: | |
350 | case YP_SET: | |
351 | case YP_ANY: | |
352 | if (yp->yp_strexp) | |
353 | f = setfield(yp->yp_strexp); | |
354 | if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) { | |
355 | p1 = "ANY"; | |
356 | break; | |
357 | } | |
358 | t = NULL; | |
359 | p1 = NULL; | |
360 | (void) fprintf(fp, "\t{ SANY, 0, %s, %s },\n", | |
361 | c_tag(yp), c_class(yp)); | |
362 | break; | |
363 | ||
364 | case YP_NULL: | |
365 | p1 = "T_NULL"; | |
366 | t = NULL; | |
367 | break; | |
368 | ||
369 | case YP_IDEFINED: | |
370 | p1 = NULL; | |
371 | ||
372 | if ((yp->yp_flags & YP_PARMVAL) && yp->yp_prfexp) | |
373 | ferr(1, | |
374 | "\n[[ ? reference ]] [[ p reference ]] is illegal\n\t only one allowed\n"); | |
375 | ||
376 | if (yp->yp_prfexp) { /* [[ ? parm->field ]] - complex to process */ | |
377 | gen_identry(fp, t, f, yp, gen_ventry); | |
378 | ||
379 | if (yp->yp_flags & YP_DEFAULT) | |
380 | gdflt(fp, yp, G_DEC); | |
381 | ||
382 | break; | |
383 | } | |
384 | ||
385 | { | |
386 | /* Predefined Universal Type */ | |
387 | struct univ_typ *p, *univtyp(); | |
388 | ||
389 | if ((p = univtyp(yp->yp_identifier))) { | |
390 | if (p->univ_flags & UNF_EXTMOD) { | |
391 | yp->yp_module = p->univ_mod; | |
392 | goto do_obj; | |
393 | } | |
394 | if (f == NULL || noindirect(f)) {/* No offset type */ | |
395 | if (yp->yp_flags & YP_TAG | |
396 | && yp->yp_flags & YP_IMPLICIT) | |
397 | prstfield(fp, p->univ_tab, t, f, | |
398 | int2tstr(yp->yp_tag->yt_value->yv_number), | |
399 | c_flags(yp, yp->yp_tag->yt_class)); | |
400 | else | |
401 | prstfield(fp, p->univ_tab, t, f, int2tstr(p->univ_id), | |
402 | c_flags(yp, p->univ_class)); | |
403 | goto out; | |
404 | } | |
405 | if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) | |
406 | prtfield(fp, p->univ_tab, t, f, | |
407 | int2tstr(yp->yp_tag->yt_value->yv_number), | |
408 | c_flags(yp, yp->yp_tag->yt_class)); | |
409 | else | |
410 | prtfield(fp, p->univ_tab, t, f, int2tstr(p->univ_id), | |
411 | c_flags(yp, p->univ_class)); | |
412 | goto out; | |
413 | } | |
414 | } | |
415 | do_obj: | |
416 | if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) | |
417 | (void) fprintf(fp, "\t{ IMP_OBJ, 0, %s, %s },\n", c_tag(yp), c_class(yp)); | |
418 | if (yp->yp_module == NULL | |
419 | || strcmp(yp->yp_module, mymodule) == 0) { | |
420 | if (f == NULL || noindirect(f)) | |
421 | prstfield(fp, "OBJECT", t, f, | |
422 | concat("_Z", proc_name(yp->yp_identifier, 0)), | |
423 | c_class(yp)); | |
424 | else | |
425 | prtfield(fp, "OBJECT", t, f, | |
426 | concat("_Z", proc_name(yp->yp_identifier, 0)), | |
427 | c_class(yp)); | |
428 | ||
429 | } else { | |
430 | if (f == NULL || noindirect(f)) | |
431 | prstfield(fp, "EXTOBJ", t, f, | |
432 | concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)), | |
433 | c_class(yp)); | |
434 | else | |
435 | prtfield(fp, "EXTOBJ", t, f, | |
436 | concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)), | |
437 | c_class(yp)); | |
438 | (void) fprintf(fp, "\t{ EXTMOD, %d, 0, 0 },\n", | |
439 | gen_modref(yp->yp_module)); | |
440 | } | |
441 | out: | |
442 | if (yp->yp_flags & YP_DEFAULT) | |
443 | gdflt(fp, yp, G_DEC); | |
444 | break; | |
445 | ||
446 | case YP_SEQLIST: | |
447 | p1 = NULL; | |
448 | /* support for -h flag */ | |
449 | if (yp->yp_varexp == NULL && type != NULL) | |
450 | ferr(1, "tdec_typ:YP_SEQLIST:NULL varexp pointer\n"); | |
451 | prcte(fp, type, t, f, yp, "SEQ_START"); | |
452 | ||
453 | if (yp->yp_flags & YP_DEFAULT) | |
454 | gdflt(fp, yp, G_DEC); | |
455 | if (y = yp->yp_type) { | |
456 | char *t1; | |
457 | ||
458 | if (yp->yp_param_type) { | |
459 | /* we have a [[ P type ]] specification */ | |
460 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
461 | fprintf(stderr, | |
462 | "\ntdec_typ:SEQLIST can't extract direct type from %s\n", | |
463 | yp->yp_param_type); | |
464 | exit(1); | |
465 | } | |
466 | yp->yp_structname = strdup(t1); | |
467 | } else if (type) { | |
468 | if (yp->yp_declexp == NULL) | |
469 | ferr(1, "tdec_typ:YP_SEQLIST:no declexp\n"); | |
470 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
471 | } else | |
472 | yp->yp_structname = t; | |
473 | ||
474 | if (!type || !noindirect(f)) | |
475 | genmalloc(fp, yp); | |
476 | ||
477 | if (optfield(y)) { | |
478 | (void) fprintf(fp, | |
479 | "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n", | |
480 | yp->yp_structname); | |
481 | } | |
482 | tdec_loop(fp, y, id, yp->yp_structname); | |
483 | } | |
484 | (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n"); | |
485 | break; | |
486 | ||
487 | case YP_SETLIST: | |
488 | p1 = NULL; | |
489 | /* support for -h flag */ | |
490 | p1 = NULL; | |
491 | if (yp->yp_varexp == NULL && type != NULL) | |
492 | ferr(1, "tdec_typ:YP_SETLIST:NULL varexp pointer\n"); | |
493 | prcte(fp, type, t, f, yp, "SET_START"); | |
494 | ||
495 | if (yp->yp_flags & YP_DEFAULT) | |
496 | gdflt(fp, yp, G_DEC); | |
497 | if (y = yp->yp_type) { | |
498 | char *t1; | |
499 | ||
500 | if (yp->yp_param_type) { | |
501 | /* we have a [[ P type ]] specification */ | |
502 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
503 | fprintf(stderr, | |
504 | "\ntdec_typ:SETLIST can't extract direct type from %s\n", | |
505 | yp->yp_param_type); | |
506 | exit(1); | |
507 | } | |
508 | yp->yp_structname = strdup(t1); | |
509 | } else if (type) { | |
510 | if (yp->yp_declexp == NULL) | |
511 | ferr(1, "tdec_typ:YP_SETLIST:no declexp\n"); | |
512 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
513 | } else | |
514 | yp->yp_structname = t; | |
515 | ||
516 | if (!type || !noindirect(f)) | |
517 | genmalloc(fp, yp); | |
518 | ||
519 | if (optfield(y)) { | |
520 | (void) fprintf(fp, | |
521 | "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n", | |
522 | yp->yp_structname); | |
523 | } | |
524 | tdec_loop(fp, y, id, yp->yp_structname); | |
525 | } | |
526 | (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n"); | |
527 | break; | |
528 | ||
529 | case YP_SEQTYPE: /* What is the difference ?? */ | |
530 | p1 = NULL; | |
531 | prcte(fp, type, t, f, yp, "SEQOF_START"); | |
532 | ||
533 | if (yp->yp_flags & YP_DEFAULT) | |
534 | gdflt(fp, yp, G_DEC); | |
535 | ||
536 | if (y = yp->yp_type) { | |
537 | char *t1; | |
538 | ||
539 | if (yp->yp_param_type) { | |
540 | /* we have a [[ P type ]] specification */ | |
541 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
542 | fprintf(stderr, | |
543 | "\ntdec_typ:SEQTYPE can't extract direct type from %s\n", | |
544 | yp->yp_param_type); | |
545 | exit(1); | |
546 | } | |
547 | yp->yp_structname = strdup(t1); | |
548 | } else if (type) { | |
549 | if (yp->yp_declexp == NULL) | |
550 | ferr(1, "tdec_typ:YP_SEQTYPE:no declexp\n"); | |
551 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
552 | } else | |
553 | yp->yp_structname = t; | |
554 | ||
555 | if (!type || !noindirect(f)) | |
556 | genmalloc(fp, yp); | |
557 | ||
558 | tdec_loop(fp, y, id, yp->yp_structname); | |
559 | } | |
560 | if (yp->yp_flags & YP_CONTROLLED) { | |
561 | char *f1; | |
562 | ||
563 | if ((f1 = getfield(yp->yp_control)) == NULLCP) { | |
564 | fprintf(stderr, "\ntdec_typ:SEQ OF: can't extract field from %s\n", | |
565 | yp->yp_control); | |
566 | exit(1); | |
567 | } | |
568 | (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n", | |
569 | yp->yp_structname, f1); | |
570 | } else if (yp->yp_structname != NULL) | |
571 | (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n", | |
572 | yp->yp_structname); | |
573 | else | |
574 | (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n"); | |
575 | break; | |
576 | ||
577 | case YP_SETTYPE: | |
578 | p1 = NULL; | |
579 | prcte(fp, type, t, f, yp, "SETOF_START"); | |
580 | ||
581 | if (yp->yp_flags & YP_DEFAULT) | |
582 | gdflt(fp, yp, G_DEC); | |
583 | ||
584 | if (y = yp->yp_type) { | |
585 | char *t1; | |
586 | ||
587 | ||
588 | if (yp->yp_param_type) { | |
589 | /* we have a [[ P type ]] specification */ | |
590 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
591 | fprintf(stderr, | |
592 | "\ntdec_typ:SETTYPE can't extract direct type from %s\n", | |
593 | yp->yp_param_type); | |
594 | exit(1); | |
595 | } | |
596 | yp->yp_structname = strdup(t1); | |
597 | } else if (type) { | |
598 | if (yp->yp_declexp == NULL) | |
599 | ferr(1, "tdec_typ:YP_SETTYPE:no declexp\n"); | |
600 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
601 | } else | |
602 | yp->yp_structname = t; | |
603 | ||
604 | if (!type || !noindirect(f)) | |
605 | genmalloc(fp, yp); | |
606 | ||
607 | tdec_loop(fp, y, id, yp->yp_structname); | |
608 | } | |
609 | if (yp->yp_flags & YP_CONTROLLED) { | |
610 | char *f1; | |
611 | ||
612 | if ((f1 = getfield(yp->yp_control)) == NULLCP) { | |
613 | fprintf(stderr, "\ntdec_typ:SET OF: can't extract field from %s\n", | |
614 | yp->yp_control); | |
615 | exit(1); | |
616 | } | |
617 | (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n", | |
618 | yp->yp_structname, f1); | |
619 | } else if (yp->yp_structname != NULL) | |
620 | (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n", | |
621 | yp->yp_structname); | |
622 | else | |
623 | (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n"); | |
624 | break; | |
625 | ||
626 | case YP_CHOICE: | |
627 | p1 = NULL; | |
628 | /* support for -h flag */ | |
629 | if (hflag && (y = yp->yp_type) && !y->yp_next) { | |
630 | tdec_typ(fp, y, id, yp->yp_structname); | |
631 | break; | |
632 | } | |
633 | if (type == NULL || type && noindirect(f)) | |
634 | prstfield(fp, "CHOICE_START", t, f, 0, c_class(yp)); | |
635 | else | |
636 | prtfield(fp, "CHOICE_START", t, type ? f : NULLCP, 0, c_class(yp)); | |
637 | ||
638 | if (yp->yp_flags & YP_DEFAULT) | |
639 | gdflt(fp, yp, G_DEC); | |
640 | if (y = yp->yp_type) { | |
641 | char *t1; | |
642 | ||
643 | if (yp->yp_param_type) { | |
644 | /* we have a [[ P type ]] specification */ | |
645 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
646 | fprintf(stderr, | |
647 | "\ntdec_typ:CHOICE can't extract direct type from %s\n", | |
648 | yp->yp_param_type); | |
649 | exit(1); | |
650 | } | |
651 | yp->yp_structname = strdup(t1); | |
652 | } else if (type) { | |
653 | if (yp->yp_declexp == NULL) | |
654 | ferr(1, "tdec_typ:YP_CHOICE:no declexp\n"); | |
655 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
656 | } else | |
657 | yp->yp_structname = t; | |
658 | ||
659 | if (!type || !noindirect(f)) | |
660 | genmalloc(fp, yp); | |
661 | ||
662 | ||
663 | if (yp -> yp_control_act && yp->yp_control_act->yal_dec) { | |
664 | (void) fprintf (fp, "\t{ SCTRL, %d, 0, FL_USELECT },\n", | |
665 | control_act(yp->yp_control_act -> yal_dec)); | |
666 | } | |
667 | else if (yp->yp_flags & YP_CONTROLLED) { | |
668 | char *f1; | |
669 | ||
670 | if ((f1 = getfield(yp->yp_control)) == NULLCP) { | |
671 | fprintf(stderr, "\ntdec_typ:CHOICE: can't extract field from %s\n", | |
672 | yp->yp_control); | |
673 | exit(1); | |
674 | } | |
675 | (void) fprintf(fp, "\t{ SCTRL, OFFSET(%s, %s), 0, 0 },\n", | |
676 | yp->yp_structname, f1); | |
677 | } else if (yp->yp_structname != NULL) | |
678 | (void) fprintf(fp,"\t{ SCTRL, OFFSET(%s, offset), 0, 0 },\n", | |
679 | yp->yp_structname); | |
680 | else | |
681 | ferr(1, "\nCHOICE missing SCTRL\n"); | |
682 | ||
683 | if (yp->yp_param_type) { | |
684 | /* we have a [[ P type ]] specification */ | |
685 | if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) { | |
686 | fprintf(stderr, | |
687 | "\ntdec_typ:CHOICE can't extract direct type from %s\n", | |
688 | yp->yp_param_type); | |
689 | exit(1); | |
690 | } | |
691 | yp->yp_structname = strdup(t1); | |
692 | } else if (type) { | |
693 | if (yp->yp_declexp == NULL) | |
694 | ferr(1, "tdec_typ:YP_CHOICE:no declexp\n"); | |
695 | yp->yp_structname = my_strcat("struct ", yp->yp_declexp); | |
696 | } else | |
697 | yp->yp_structname = t; | |
698 | tdec_loop(fp, y, id, yp->yp_structname); | |
699 | } | |
700 | (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n"); | |
701 | break; | |
702 | ||
703 | default: | |
704 | ferrd(1, "tdec_typ: yp_code = %d not implemented\n", yp->yp_code); | |
705 | } | |
706 | ||
707 | if (p1 != NULL) { | |
708 | prnte(fp, t, f, yp, p1); | |
709 | ||
710 | if (yp->yp_flags & YP_DEFAULT) | |
711 | gdflt(fp, yp, G_DEC); | |
712 | } | |
713 | ||
714 | if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec) | |
715 | gen_act(fp, yp->yp_aft_alist->yal_dec); | |
716 | ||
717 | } | |
718 | ||
719 | static int fflags[] = { | |
720 | 0, 1, 2, 2, 3, 3, 4, 5, 16, 16, 16, 17, 17, 17, | |
721 | 0, -1, 7,}; | |
722 | ||
723 | /* | |
724 | * generate tables for encoding a contructed type | |
725 | */ | |
726 | YP | |
727 | tdec_loop(fp, yp, id, type) | |
728 | FILE *fp; | |
729 | YP yp; | |
730 | char *id; | |
731 | char *type; | |
732 | { | |
733 | for (; yp != NULL; yp = yp->yp_next) { | |
734 | tdec_typ(fp, yp, id, type); | |
735 | } | |
736 | } | |
737 | /* | |
738 | * Generate a malloc of for the given object | |
739 | */ | |
740 | genmalloc(fp, yp) | |
741 | FILE *fp; | |
742 | YP yp; | |
743 | { | |
744 | if (hasdatstr(yp)) | |
745 | (void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n", | |
746 | yp->yp_structname); | |
747 | } | |
748 | /* | |
749 | * Has Data Structure, | |
750 | * determine if this type needs a data structure allocated to it - calls | |
751 | * itself recursively to handle the cases of pulled up types | |
752 | * returns non zero if it does need a type allocated for it | |
753 | */ | |
754 | hasdatstr(yp) | |
755 | YP yp; | |
756 | { | |
757 | YP y; | |
758 | YP yp1; | |
759 | struct univ_typ *p; | |
760 | ||
761 | switch (yp -> yp_code) { | |
762 | case YP_BIT: | |
763 | case YP_BITLIST: | |
764 | case YP_SEQ: | |
765 | case YP_SET: | |
766 | case YP_ANY: | |
767 | case YP_OCT: | |
768 | case YP_OID: | |
769 | break; | |
770 | ||
771 | case YP_IDEFINED: | |
772 | ||
773 | yp1 = lkup(yp); | |
774 | ||
775 | if (yp1->yp_code == YP_IDEFINED) { | |
776 | if ((p = univtyp(yp1->yp_identifier)) == NULL | |
777 | || p->univ_type <= YP_UNDF) { | |
778 | return (1); /* we can't tell unless we know what this is */ | |
779 | /* ferr(0, "\tcomptag:treated as implicit\n"); */ | |
780 | } | |
781 | if (p->univ_flags & UNF_HASDATA) | |
782 | return (1); | |
783 | return (0); | |
784 | } else | |
785 | return (hasdatstr(yp1)); | |
786 | ||
787 | case YP_SEQLIST: | |
788 | case YP_SETLIST: | |
789 | case YP_CHOICE: | |
790 | if (hflag && (y = yp -> yp_type) && !y -> yp_next) { | |
791 | return (hasdatstr(y)); | |
792 | } | |
793 | /* else fall */ | |
794 | ||
795 | default: | |
796 | return (1); | |
797 | } | |
798 | return (0); | |
799 | } | |
800 | ||
801 | int control_act (act) | |
802 | Action act; | |
803 | { | |
804 | register char *p; | |
805 | ||
806 | for (p = act -> a_data; *p; p++) | |
807 | if (!isspace (*p) && *p == '0') | |
808 | return -1; | |
809 | return act -> a_num; | |
810 | } | |
811 | ||
812 | /* | |
813 | * generate an entry for the freeing routines | |
814 | * if there is a freeing function just call that | |
815 | * if not specify the type and offset so the free routines know how to free it | |
816 | * return non zero if we don't want the normal decoding entry to be | |
817 | * generated after us for freeing purposes. | |
818 | */ | |
819 | gen_freefn(fp, yp) | |
820 | FILE *fp; | |
821 | YP yp; | |
822 | { | |
823 | char *p1; | |
824 | char *fn; | |
825 | ||
826 | if (yp->yp_yfn && (fn = yp->yp_yfn->yfn_fre)) { | |
827 | (void) fprintf(fp, "\t{ FFN_CALL, %d, 0, 0, },\n", addptr(fn)); | |
828 | return (1); /* don't free as per normal */ | |
829 | } | |
830 | ||
831 | (void) fprintf(fp, "\t{ FREE_ONLY, 0, 0, 0, },\n"); | |
832 | return (0); | |
833 | ||
834 | } | |
835 |