|
|
1.1 root 1: /* fr.c */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/pepsy/RCS/fr.c,v 7.2 90/07/27 08:48:48 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/pepsy/RCS/fr.c,v 7.2 90/07/27 08:48:48 mrose Exp $
9: *
10: *
11: * $Log: fr.c,v $
12: * Revision 7.2 90/07/27 08:48:48 mrose
13: * update
14: *
15: * Revision 7.1 90/07/09 14:52:38 mrose
16: * sync
17: *
18: * Revision 7.0 90/07/01 19:54:20 mrose
19: * *** empty log message ***
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /*
35: * These routines are the driving routines for freeing of the data
36: */
37: #include <stdio.h>
38: #include "psap.h"
39: #include "pepsy.h"
40:
41:
42: extern tpe *next_tpe();
43: extern PE pepsylose ();
44: #define NEXT_TPE(p) p = next_tpe(p)
45: #define CHKTAG(mod, p, pe) ismatch(p, mod, pe->pe_class, pe->pe_id)
46:
47: /*
48: * don't need this fre_f we just generate macros of the form
49: * fre_obj(parm, mod->md_dtab[CONST], mod)
50: */
51: #if 0
52: /*
53: * free the data of specified type of the specified module
54: */
55: fre_f(typ, mod, pe, explicit, len, buf, parm)
56: /* ARGSUSED */
57: int typ; /* which type it is */
58: modtyp *mod; /* Module it is from */
59: PE pe;
60: int explicit;
61: int *len;
62: char **buf;
63: char **parm;
64: {
65: tpe *p;
66:
67: if (typ < 0 || typ >= mod->md_nentries) {
68: (void) pepsylose (mod, p, pe, "fre_f:Illegal type %d\n", typ);
69: return (NOTOK);
70: }
71:
72: if (parm == 0)
73: return (OK);
74:
75: p = mod->md_dtab[typ];
76: if (p->pe_type != PE_START) {
77: (void) pepsylose (mod, p, pe, "fre_f: missing PE_START\n");
78: return (NOTOK);
79: }
80: fre_obj(parm, p, mod)
81:
82: return (OK);
83: }
84: #endif
85:
86: /*
87: * free an objects data. Basic algorithm is to walk through it twice
88: * first time freeing all the "children" of the data structure - then
89: * the second time free the structure itself
90: */
91: fre_obj(parm, p, mod)
92: modtyp *mod;
93: tpe *p;
94: char *parm;
95: {
96: char *malptr = NULL; /* Have we seen a malloc */
97:
98: if (parm == 0)
99: return (OK);
100:
101: if (p->pe_type != PE_START) {
102: (void) pepsylose (mod, p, NULLPE, "fre_obj: missing PE_START\n");
103: return (NOTOK);
104: }
105:
106: for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
107:
108: again:
109: switch (p->pe_type) {
110: case MALLOC:
111: malptr = parm;
112: break;
113:
114: case SET_START:
115: case SEQ_START:
116: fre_seq(parm, p, mod);
117: break;
118:
119: case SETOF_START:
120: case SEQOF_START:
121: fre_seqof(parm, p, mod);
122: break;
123:
124: case CHOICE_START:
125: fre_choice(parm, p, mod);
126: break;
127:
128: case OBJECT:
129: case SOBJECT:
130: fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
131: break;
132:
133: case SEXTOBJ:
134: case EXTOBJ:
135: if (p[1].pe_type != EXTMOD) {
136: (void) pepsylose (mod, p, NULLPE, "fre_obj: missing EXTMOD");
137: return (NOTOK);
138: }
139: fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
140: EXT2MOD(mod, (p + 1)));
141: break;
142:
143: case IMP_OBJ:
144: p++;
145: if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
146: fre_obj(parm, EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag],
147: EXT2MOD(mod, (p + 1)));
148: } else {
149: if (p->pe_type == SOBJECT) {
150: fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
151: } else
152: fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
153: }
154: break;
155:
156: case INTEGER:
157: case BOOLEAN:
158: case UCODE:
159: case REALTYPE:
160: break;
161:
162: case ETAG:
163: p++;
164: goto again;
165:
166: default:
167: fre_type(parm, p, mod);
168: break;
169: }
170: }
171:
172: if (malptr) /* If we saw a malloc free item */
173: free(malptr);
174:
175: return (OK);
176: }
177:
178: /*
179: * Handle freeing of single type field. All the more general routines
180: * fall back to this so we can put the code to free something just
181: * here once and it will handle all the cases else where
182: */
183: static fre_type(parm, p, mod)
184: char *parm;
185: tpe *p;
186: modtyp *mod; /* Module it is from */
187: {
188:
189: if (parm == 0)
190: return;
191:
192: again:
193: switch (p->pe_type) {
194: case MALLOC:
195: break;
196:
197: case PE_END:
198: case PE_START:
199: case UCODE:
200: break;
201:
202: case DFLT_F:
203: p++;
204: goto again;
205:
206: case ETAG:
207: switch (p->pe_ucode) {
208:
209: default:
210: p++;
211: fre_type(parm, p, mod);
212: }
213: break;
214:
215: case SEQ_START:
216: case SET_START:
217: fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
218: break;
219:
220: case SEQOF_START:
221: case SETOF_START:
222: fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
223: break;
224:
225: case IMP_OBJ:
226: p++;
227: if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
228: fre_obj(*(char **) (parm + p->pe_ucode),
229: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
230: EXT2MOD(mod, (p + 1)));
231: else if (p->pe_type == SOBJECT) {
232: fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
233: } else
234: fre_obj(*(char **) (parm + p->pe_ucode),
235: mod->md_dtab[p->pe_tag], mod);
236: break;
237:
238: case SOBJECT:
239: fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
240: break;
241:
242: case OBJECT:
243: fre_obj(*(char **) (parm + p->pe_ucode),
244: mod->md_dtab[p->pe_tag], mod);
245: break;
246:
247: case CHOICE_START:
248: fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
249: break;
250:
251: case SEXTOBJ:
252: if (p[1].pe_type != EXTMOD) {
253: (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
254: return (NOTOK);
255: }
256: fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
257: EXT2MOD(mod, (p + 1)));
258: break;
259:
260: case EXTOBJ:
261: if (p[1].pe_type != EXTMOD) {
262: (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
263: return (NOTOK);
264: }
265: fre_obj(*(char **) (parm + p->pe_ucode),
266: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
267: EXT2MOD(mod, (p + 1)));
268: break;
269:
270: case INTEGER:
271: case BOOLEAN:
272: case T_NULL:
273: case REALTYPE:
274: break;
275:
276: case SANY:
277: /*
278: * These tests of the pointer don't appear necessary from the
279: * definition of encoding and decoding but ISODE generates
280: * freeing code that does these checks and ISODE's ps layer
281: * definitely requires it
282: */
283: if (parm != NULL)
284: pe_free((PE) parm);
285: break;
286:
287: case ANY:
288: if (*(char **) (parm + p->pe_ucode) != NULL)
289: pe_free(*(PE *) (parm + p->pe_ucode));
290: break;
291:
292: case SOCTETSTRING:
293: if (parm != NULL)
294: qb_free((struct qbuf *) parm);
295: break;
296:
297: case OCTETSTRING:
298: if (*(char **) (parm + p->pe_ucode) != NULL)
299: qb_free(*(struct qbuf **) (parm + p->pe_ucode));
300: break;
301:
302: case SBITSTRING:
303: if (parm != NULL)
304: pe_free((PE) parm);
305: break;
306:
307: case BITSTRING:
308: if (*(char **) (parm + p->pe_ucode) != NULL)
309: pe_free(*(PE *) (parm + p->pe_ucode));
310: break;
311:
312: case SOBJID:
313: if (parm != NULL)
314: oid_free((OID) parm);
315: break;
316:
317: case OBJID:
318: if (*(char **) (parm + p->pe_ucode) != NULL)
319: oid_free(*(OID *) (parm + p->pe_ucode));
320: break;
321:
322: default:
323: (void) pepsylose (mod, p, NULLPE, "fre_type: %d not implemented\n",
324: p->pe_type);
325: return (NOTOK);
326: }
327:
328: return (OK);
329: }
330:
331: /*
332: * free elements of a sequential type. e.g. sequence or set
333: */
334: static fre_seq(parm, p, mod)
335: char *parm;
336: tpe *p;
337: modtyp *mod; /* Module it is from */
338: {
339: int *popt = NULL; /* Pointer to optional field */
340: int optcnt = 0; /* Number of optionals bits so far */
341: char *malptr = NULL; /* Have we seen a malloc */
342:
343:
344: if (parm == 0)
345: return;
346:
347: if (p->pe_type != SEQ_START && p->pe_type != SET_START) {
348: (void) pepsylose (mod, p, NULLPE, "fre_seq: bad starting item %d\n",
349: p->pe_type);
350: return (NOTOK);
351: }
352: p++;
353:
354: if (p->pe_type == DFLT_B)
355: p++;
356:
357: while (p->pe_type != PE_END) {
358:
359: if (ISDTYPE(p) && (OPTIONAL(p) || DEFAULT(p))) {
360: switch (p->pe_type) {
361: case INTEGER:
362: case BOOLEAN:
363: case T_NULL:
364: case REALTYPE:
365: if (DEFAULT(p)) {
366: /* ISODE doesn't use bit map for defaults */
367: if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
368: || p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
369: goto next;
370: break;
371: }
372: if (popt == NULL) {
373: (void) pepsylose (mod, p, NULLPE,
374: "fre_seq:illegal table: no bitmap for optionals\n");
375: return (NOTOK);
376: }
377: if (!TESTBIT(*popt, optcnt++))
378: goto next; /* Missing so skip */
379: break;
380:
381: case ETAG:
382: if (!hasdata(parm, p + 1, mod, popt, optcnt))
383: goto next;
384: break;
385:
386: case IMP_OBJ:
387: if (p[1].pe_type == SOBJECT && parm == NULL
388: || *((char **) (parm + p[1].pe_ucode)) == NULL)
389: goto next;
390: break;
391:
392: case SOBJECT:
393: if (((char *) parm) == NULL)
394: goto next;
395: break;
396:
397: default:
398: if (*((char **) (parm + p->pe_ucode)) == NULL)
399: goto next;
400: break;
401: }
402: }
403: switch (p->pe_type) {
404: case MALLOC:
405: malptr = parm;
406: break;
407:
408: case OPTL:
409: popt = (int *) (parm + p->pe_ucode);
410: break;
411:
412: case ETAG:
413: p++;
414: continue;
415:
416: case UCODE:
417: break;
418:
419: case SET_START:
420: case SEQ_START:
421: fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
422: break;
423:
424: case SETOF_START:
425: case SEQOF_START:
426: fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
427: break;
428:
429: case IMP_OBJ:
430: p++;
431: if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
432: fre_obj(*(char **) (parm + p->pe_ucode),
433: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
434: EXT2MOD(mod, (p + 1)));
435:
436: else if (p->pe_type == SOBJECT) {
437: fre_obj((char *) parm, mod->md_dtab[p->pe_tag],
438: mod);
439: } else
440: fre_obj(*(char **) (parm + p->pe_ucode),
441: mod->md_dtab[p->pe_tag], mod);
442: break;
443:
444: case SOBJECT:
445: fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
446: break;
447:
448: case OBJECT:
449: fre_obj(*(char **) (parm + p->pe_ucode),
450: mod->md_dtab[p->pe_tag], mod);
451: break;
452:
453: case CHOICE_START:
454: fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
455: break;
456:
457: case SEXTOBJ:
458: if (p[1].pe_type != EXTMOD) {
459: (void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
460: return (NOTOK);
461: }
462: fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
463: EXT2MOD(mod, (p + 1)));
464: break;
465:
466: case EXTOBJ:
467: if (p[1].pe_type != EXTMOD) {
468: (void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
469: return (NOTOK);
470: }
471: fre_obj(*(char **) (parm + p->pe_ucode),
472: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
473: EXT2MOD(mod, (p + 1)));
474: break;
475:
476: default:
477: fre_type(parm, p, mod);
478: break;
479: }
480:
481: next:
482: NEXT_TPE(p);
483: }
484: if (malptr) /* If we saw a malloc free item */
485: free(malptr);
486:
487: return (OK);
488:
489: }
490:
491: /*
492: * free all the fields in a SET OF/SEQUENCE OF type structure. We
493: * must follow the linked list until the end
494: */
495: static fre_seqof(parm, p, mod)
496: char *parm;
497: tpe *p;
498: modtyp *mod; /* Module it is from */
499: {
500: tpe *start; /* first entry in list */
501: char *oparm;
502:
503: if (parm == 0)
504: return;
505:
506: if (p->pe_type != SEQOF_START && p->pe_type != SETOF_START) {
507: (void) pepsylose (mod, p, NULLPE, "fre_seqof: illegal field");
508: return (NOTOK);
509: }
510: for (start = p; (char *) parm != NULL; p = start) {
511: p++;
512:
513: if (p->pe_type == DFLT_B)
514: p++;
515:
516: while (p->pe_type != PE_END) {
517:
518: switch (p->pe_type) {
519: case ETAG:
520: p++;
521: continue;
522:
523: case UCODE:
524: break;
525:
526: case SEQ_START:
527: case SET_START:
528: fre_seq(*(char **) (parm + p->pe_ucode), p, mod);
529: break;
530:
531: case SEQOF_START:
532: case SETOF_START:
533: fre_seqof(*(char **) (parm + p->pe_ucode), p, mod);
534: break;
535:
536: case IMP_OBJ:
537: p++;
538: if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ)
539: fre_obj(*(char **) (parm + p->pe_ucode),
540: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
541: EXT2MOD(mod, (p + 1)));
542:
543: else if (p->pe_type == SOBJECT) {
544: fre_obj((char *) parm, mod->md_dtab[p->pe_tag], mod);
545: } else
546: fre_obj(*(char **) (parm + p->pe_ucode),
547: mod->md_dtab[p->pe_tag], mod);
548: break;
549:
550: case SOBJECT:
551: fre_obj(parm, mod->md_dtab[p->pe_tag], mod);
552: break;
553:
554: case OBJECT:
555: fre_obj(*(char **) (parm + p->pe_ucode),
556: mod->md_dtab[p->pe_tag], mod);
557: break;
558:
559: case CHOICE_START:
560: fre_choice(*(char **) (parm + p->pe_ucode), p, mod);
561: break;
562:
563: case SEXTOBJ:
564: if (p[1].pe_type != EXTMOD) {
565: (void) pepsylose (mod, p, NULLPE,
566: "fre_seqof: missing EXTMOD");
567: return (NOTOK);
568: }
569: fre_obj(parm, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
570: EXT2MOD(mod, (p + 1)));
571: break;
572:
573: case EXTOBJ:
574: if (p[1].pe_type != EXTMOD) {
575: (void) pepsylose (mod, p, NULLPE,
576: "fre_seqof: missing EXTMOD");
577: return (NOTOK);
578: }
579: fre_obj(*(char **) (parm + p->pe_ucode),
580: (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
581: EXT2MOD(mod, (p + 1)));
582: break;
583:
584: default:
585: fre_type(parm, p, mod);
586: break;
587: }
588:
589: NEXT_TPE(p);
590: }
591: oparm = parm;
592: parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
593: free(oparm);
594: }
595:
596: }
597:
598: /*
599: * free the item of the choice. Use the SCTRL field to determine
600: * which item is present and then call the appropriate routine to
601: * free it
602: */
603: static fre_choice(parm, p, mod)
604: char *parm;
605: tpe *p;
606: modtyp *mod; /* Module it is from */
607: {
608: int cnt;
609: char *malptr = NULL; /* Have we seen a malloc */
610:
611: if (parm == 0)
612: return;
613:
614: if (p->pe_type != CHOICE_START) {
615: (void) pepsylose (mod, p, NULLPE,
616: "fre_choice:CHOICE_START missing found %d\n", p->pe_type);
617: }
618: p++;
619:
620: if (p->pe_type == DFLT_B)
621: p++;
622:
623: if (p->pe_type == MALLOC) {
624: malptr = parm;
625: p++;
626: }
627: if (p->pe_type != SCTRL) {
628: (void) pepsylose (mod, p, NULLPE,
629: "fre_choice: missing SCTRL information\n");
630: return (NOTOK);
631: }
632: cnt = *(int *) (parm + p->pe_ucode);
633: if (cnt != 0)
634: cnt--;
635: if (cnt < 0) {
636: (void) pepsylose (mod, p, NULLPE,"fre_choice:offset negative %d", cnt);
637: return (NOTOK);
638: }
639: for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
640: if (ISDTYPE(p)) {
641: if (cnt == 0) {
642: fre_type(parm, p, mod);
643: if (malptr) /* If we saw a malloc free item */
644: free(malptr);
645: return;
646: }
647: cnt--;
648: }
649: }
650:
651: (void) pepsylose (mod, p, NULLPE, "fre_choice: no choice taken");
652: return (NOTOK);
653: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.