Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / lib / data.c
1 /*
2  * data.c --
3  *
4  *      Operations on the main data structures.
5  *
6  * Copyright (c) 1999-2002 Frank Strauss, Technical University of Braunschweig.
7  *
8  * See the file "COPYING" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  * @(#) $Id: data.c 7822 2008-03-01 13:22:42Z schoenw $
12  */
13
14 #include <config.h>
15
16 #include <string.h>
17 #include <errno.h>
18 #include <ctype.h>
19 #include <sys/types.h>
20 #if !defined(_MSC_VER) && !defined(__MINGW32__)
21 #include <sys/wait.h>
22 #endif
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 #ifdef HAVE_WIN_H
27 #include "win.h"
28 #endif
29
30 #include "error.h"
31 #include "util.h"
32 #include "data.h"
33 #include "smi.h"
34
35 #ifdef HAVE_DMALLOC_H
36 #include <dmalloc.h>
37 #endif
38
39
40
41 #ifdef BACKEND_SMI
42 #include "scanner-smi.h"
43 extern int smiparse();
44 #endif
45
46 #ifdef BACKEND_SMING
47 #include "scanner-sming.h"
48 extern int smingparse();
49 #endif
50
51 #define stringKind(kind) ( \
52         (kind == KIND_ANY)                 ? "ANY" : \
53         (kind == KIND_MODULE)              ? "MODULE" : \
54         (kind == KIND_MACRO)               ? "MACRO" : \
55         (kind == KIND_TYPE)                ? "TYPE" : \
56         (kind == KIND_OBJECT)              ? "OBJECT" : \
57         (kind == KIND_IMPORT)              ? "IMPORT" : \
58                                              "unknown" )
59
60
61 int             smiDepth = 0;
62 static Handle   *firstHandlePtr = NULL;
63 static Handle   *lastHandlePtr  = NULL;
64
65
66 /*
67  *----------------------------------------------------------------------
68  *
69  * addHandle --
70  *
71  *      Adds a libsmi handle with a given name.
72  *
73  * Results:
74  *      0 on success or -1 on an error.
75  *
76  * Side effects:
77  *      None.
78  *
79  *----------------------------------------------------------------------
80  */
81
82 Handle *addHandle(const char *name)
83 {
84     Handle *handlePtr;
85
86     handlePtr = (Handle *) smiMalloc(sizeof(Handle));
87
88     handlePtr->name    = smiStrdup(name);
89
90     handlePtr->nextPtr = NULL;
91     handlePtr->prevPtr = lastHandlePtr;
92     if (!firstHandlePtr) firstHandlePtr = handlePtr;
93     if (lastHandlePtr) lastHandlePtr->nextPtr = handlePtr;
94     lastHandlePtr = handlePtr;
95
96     return (handlePtr);
97 }
98
99
100
101 /*
102  *----------------------------------------------------------------------
103  *
104  * removeHandle --
105  *
106  *      Removes a given libsmi handle.
107  *
108  * Results:
109  *      None.
110  *
111  * Side effects:
112  *      None.
113  *
114  *----------------------------------------------------------------------
115  */
116
117 void removeHandle(Handle *handlePtr)
118 {
119     if (handlePtr->prevPtr) {
120         handlePtr->prevPtr->nextPtr = handlePtr->nextPtr;
121     } else {
122         firstHandlePtr = handlePtr->nextPtr;
123     }
124     if (handlePtr->nextPtr) {
125         handlePtr->nextPtr->prevPtr = handlePtr->prevPtr;
126     } else {
127         lastHandlePtr = handlePtr->prevPtr;
128     }
129
130     smiFree(handlePtr->name);
131     smiFree(handlePtr);
132 }
133
134
135
136 /*
137  *----------------------------------------------------------------------
138  *
139  * findHandleByName --
140  *
141  *      Lookup an libsmi handle by its name.
142  *
143  * Results:
144  *      A pointer to the Handle structure or
145  *      NULL if it is not found.
146  *
147  * Side effects:
148  *      None.
149  *
150  *----------------------------------------------------------------------
151  */
152
153 Handle *findHandleByName(const char *name)
154 {
155     Handle *handlePtr;
156
157     if (!name)
158         return NULL;
159     
160     for (handlePtr = firstHandlePtr; handlePtr;
161          handlePtr = handlePtr->nextPtr) {
162         if (!strcmp(handlePtr->name, name)) {
163                 return (handlePtr);
164         }
165     }
166
167     return NULL;
168     
169 }
170
171
172
173 /*
174  *----------------------------------------------------------------------
175  *
176  * addView --
177  *
178  *      Add a module to the `view' (the list of modules, seen by the user).
179  *
180  * Results:
181  *      A pointer to the new View structure or
182  *      NULL if terminated due to an error.
183  *
184  * Side effects:
185  *      None.
186  *
187  *----------------------------------------------------------------------
188  */
189
190 View *addView(const char *modulename)
191 {
192     View              *viewPtr;
193
194     viewPtr = (View *) smiMalloc(sizeof(View));
195
196     viewPtr->name                               = smiStrdup(modulename);
197     viewPtr->nextPtr                            = NULL;
198     viewPtr->prevPtr                            = smiHandle->lastViewPtr;
199     if (!smiHandle->firstViewPtr) smiHandle->firstViewPtr               = viewPtr;
200     if (smiHandle->lastViewPtr) smiHandle->lastViewPtr->nextPtr = viewPtr;
201     smiHandle->lastViewPtr                                      = viewPtr;
202     
203     return (viewPtr);
204 }
205
206
207
208 /*
209  *----------------------------------------------------------------------
210  *
211  * isInView --
212  *
213  *      Check, whether a given module is in the current view.
214  *
215  * Results:
216  *      != 0 if in view, 0 otherwise.
217  *
218  * Side effects:
219  *      None.
220  *
221  *----------------------------------------------------------------------
222  */
223
224 int isInView(const char *modulename)
225 {
226     View              *viewPtr;
227
228 #if 0
229     if (smiHandle->flags & SMI_FLAG_VIEWALL) {
230         return 1;
231     }
232 #endif
233     
234     for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = viewPtr->nextPtr) {
235         if (!strcmp(modulename, viewPtr->name)) {
236             return 1;
237         }
238     }
239     return 0;
240 }
241
242
243 /*
244  *----------------------------------------------------------------------
245  *
246  * addModule --
247  *
248  *      Create a new MIB module.
249  *
250  * Results:
251  *      A pointer to the new Module structure or
252  *      NULL if terminated due to an error.
253  *
254  * Side effects:
255  *      None.
256  *
257  *----------------------------------------------------------------------
258  */
259
260 Module *addModule(char *modulename, char *path, ModuleFlags flags,
261                   Parser *parserPtr)
262 {
263     Module            *modulePtr;
264
265     modulePtr = (Module *) smiMalloc(sizeof(Module));
266
267     modulePtr->export.name                      = modulename;
268     modulePtr->export.path                      = path;
269     modulePtr->export.language                  = SMI_LANGUAGE_UNKNOWN;
270     modulePtr->export.organization              = NULL;
271     modulePtr->export.contactinfo               = NULL;
272     modulePtr->export.description               = NULL;
273     modulePtr->export.reference                 = NULL;
274     modulePtr->export.conformance               = 0;
275     
276     modulePtr->lastUpdated                      = 0;
277     modulePtr->flags                            = flags;
278     modulePtr->objectPtr                        = NULL;
279     
280     modulePtr->prefixNodePtr                    = NULL;
281     modulePtr->firstObjectPtr                   = NULL;
282     modulePtr->lastObjectPtr                    = NULL;
283     modulePtr->firstTypePtr                     = NULL;
284     modulePtr->lastTypePtr                      = NULL;
285     modulePtr->firstMacroPtr                    = NULL;
286     modulePtr->lastMacroPtr                     = NULL;
287     modulePtr->firstImportPtr                   = NULL;
288     modulePtr->lastImportPtr                    = NULL;
289     modulePtr->firstRevisionPtr                 = NULL;
290     modulePtr->lastRevisionPtr                  = NULL;
291     
292     modulePtr->numImportedIdentifiers           = 0;
293     modulePtr->numStatements                    = 0;
294     modulePtr->numModuleIdentities              = 0;
295
296     modulePtr->nextPtr                          = NULL;
297     modulePtr->prevPtr                          = smiHandle->lastModulePtr;
298     if (!smiHandle->firstModulePtr) smiHandle->firstModulePtr           = modulePtr;
299     if (smiHandle->lastModulePtr) smiHandle->lastModulePtr->nextPtr     = modulePtr;
300     smiHandle->lastModulePtr                            = modulePtr;
301     
302     return (modulePtr);
303 }
304
305
306
307 /*
308  *----------------------------------------------------------------------
309  *
310  * setModuleIdentityObject --
311  *
312  *      Set the objectPtr of a given Module to the OBJECT-IDENTITY object.
313  *
314  * Results:
315  *      None.
316  *
317  * Side effects:
318  *      None.
319  *
320  *----------------------------------------------------------------------
321  */
322
323 void setModuleIdentityObject(Module *modulePtr, Object *objectPtr)
324 {
325     modulePtr->objectPtr = objectPtr;
326 }
327
328
329
330 /*
331  *----------------------------------------------------------------------
332  *
333  * setModuleLastUpdated --
334  *
335  *      Set the lastUpdated time_t value of a given Module.
336  *
337  * Results:
338  *      None.
339  *
340  * Side effects:
341  *      None.
342  *
343  *----------------------------------------------------------------------
344  */
345
346 void setModuleLastUpdated(Module *modulePtr, time_t lastUpdated)
347 {
348     modulePtr->lastUpdated = lastUpdated;
349 }
350
351
352
353 /*
354  *----------------------------------------------------------------------
355  *
356  * setModuleOrganization --
357  *
358  *      Set the organization string of a given Module.
359  *
360  * Results:
361  *      None.
362  *
363  * Side effects:
364  *      None.
365  *
366  *----------------------------------------------------------------------
367  */
368
369 void setModuleOrganization(Module *modulePtr, char *organization)
370 {
371     modulePtr->export.organization = organization;
372     while (strlen(organization) && organization[strlen(organization)-1] == '\n') {
373             organization[strlen(organization) - 1] = 0;
374     }
375 }
376
377
378
379 /*
380  *----------------------------------------------------------------------
381  *
382  * setModuleContactInfo --
383  *
384  *      Set the contactInfo string of a given Module.
385  *
386  * Results:
387  *      None.
388  *
389  * Side effects:
390  *      None.
391  *
392  *----------------------------------------------------------------------
393  */
394
395 void setModuleContactInfo(Module *modulePtr, char *contactinfo)
396 {
397     modulePtr->export.contactinfo = contactinfo;
398 }
399
400
401
402 /*
403  *----------------------------------------------------------------------
404  *
405  * setModuleDescription --
406  *
407  *      Set the description string of a given Module.
408  *
409  * Results:
410  *      None.
411  *
412  * Side effects:
413  *      None.
414  *
415  *----------------------------------------------------------------------
416  */
417
418 void setModuleDescription(Module *modulePtr, char *description,
419                           Parser *parserPtr)
420 {
421     if (modulePtr->export.description)
422         smiFree(modulePtr->export.description);
423     if (parserPtr->flags & SMI_FLAG_NODESCR) {
424         smiFree(description);
425         modulePtr->export.description = NULL;
426     } else {
427         modulePtr->export.description = description;
428     }
429 }
430
431
432
433 /*
434  *----------------------------------------------------------------------
435  *
436  * setModuleReference --
437  *
438  *      Set the reference string of a given Module.
439  *
440  * Results:
441  *      None.
442  *
443  * Side effects:
444  *      None.
445  *
446  *----------------------------------------------------------------------
447  */
448
449 void setModuleReference(Module *modulePtr, char *reference, Parser *parserPtr)
450 {
451     if (modulePtr->export.reference)
452         smiFree(modulePtr->export.reference);
453     if (parserPtr->flags & SMI_FLAG_NODESCR) {
454         smiFree(reference);
455         modulePtr->export.reference = NULL;
456     } else {
457         modulePtr->export.reference = reference;
458     }
459 }
460
461
462
463 /*
464  *----------------------------------------------------------------------
465  *
466  * findModuleByName --
467  *
468  *      Lookup a Module by a given name.
469  *
470  * Results:
471  *      A pointer to the Module structure or
472  *      NULL if it is not found.
473  *
474  * Side effects:
475  *      None.
476  *
477  *----------------------------------------------------------------------
478  */
479
480 Module *findModuleByName(const char *modulename)
481 {
482     Module      *modulePtr;
483
484     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
485          modulePtr = modulePtr->nextPtr) {
486         if ((modulePtr->export.name) &&
487             !strcmp(modulePtr->export.name, modulename)) {
488             return (modulePtr);
489         }
490     }
491
492     return (NULL);
493 }
494
495
496
497 /*
498  *----------------------------------------------------------------------
499  *
500  * addRevision --
501  *
502  *      Adds a revision entry for the given module.
503  *
504  * Results:
505  *      0 on success or -1 on an error.
506  *
507  * Side effects:
508  *      None.
509  *
510  *----------------------------------------------------------------------
511  */
512
513 Revision *addRevision(time_t date, char *description, Parser *parserPtr)
514 {
515     Revision      *revisionPtr, *r;
516     Module        *modulePtr;
517
518     revisionPtr = (Revision *) smiMalloc(sizeof(Revision));
519
520     modulePtr = parserPtr->modulePtr;
521
522     revisionPtr->modulePtr               = modulePtr;
523     revisionPtr->export.date             = date;
524     if (parserPtr->flags & SMI_FLAG_NODESCR) {
525         smiFree(description);
526         revisionPtr->export.description  = NULL;
527     } else {
528         revisionPtr->export.description  = description;
529     }
530     revisionPtr->line                    = parserPtr ? parserPtr->line : -1;
531
532     for (r = modulePtr->lastRevisionPtr; r; r = r->prevPtr) {
533         if (r->export.date > date) break;
534     }
535     if (r) {
536         revisionPtr->nextPtr = r->nextPtr;
537         revisionPtr->prevPtr = r;
538         if (r->nextPtr) {
539             r->nextPtr->prevPtr = revisionPtr;
540         } else {
541             modulePtr->lastRevisionPtr = revisionPtr;
542         }
543         r->nextPtr = revisionPtr;
544     } else {
545         revisionPtr->prevPtr = NULL;
546         if (modulePtr->firstRevisionPtr) {
547             modulePtr->firstRevisionPtr->prevPtr = revisionPtr;
548             revisionPtr->nextPtr = modulePtr->firstRevisionPtr;
549         } else {
550             modulePtr->lastRevisionPtr = revisionPtr;
551             revisionPtr->nextPtr = NULL;
552         }
553         modulePtr->firstRevisionPtr = revisionPtr;
554     }
555
556     return (revisionPtr);
557 }
558
559
560
561 /*
562  *----------------------------------------------------------------------
563  *
564  * setRevisionLine --
565  *
566  *      Set the line of definition of a given Revision.
567  *
568  * Results:
569  *      None.
570  *
571  * Side effects:
572  *      None.
573  *
574  *----------------------------------------------------------------------
575  */
576
577 void setRevisionLine(Revision *revisionPtr, int line, Parser *parserPtr)
578 {
579     if (line) {
580         revisionPtr->line = line;
581     } else {
582         revisionPtr->line = parserPtr ? parserPtr->line : -1;
583     }
584 }
585
586
587
588 /*
589  *----------------------------------------------------------------------
590  *
591  * addImport --
592  *
593  *      Adds a descriptor to the actual module's list of imported
594  *      descriptors. This list may be checked by checkImports()
595  *      afterwards.
596  *
597  * Results:
598  *      0 on success or -1 on an error.
599  *
600  * Side effects:
601  *      None.
602  *
603  *----------------------------------------------------------------------
604  */
605
606 Import *addImport(char *name, Parser *parserPtr)
607 {
608     Import        *importPtr;
609     Module        *modulePtr;
610
611     importPtr = (Import *) smiMalloc(sizeof(Import));
612
613     modulePtr = parserPtr->modulePtr;
614
615     importPtr->modulePtr                 = modulePtr;
616     importPtr->export.name               = name;
617     importPtr->export.module             = NULL; /* not yet known */
618     importPtr->kind                      = KIND_UNKNOWN; /* not yet known */
619     importPtr->use                       = 0;
620     importPtr->flags                     = 0;
621     importPtr->line                      = parserPtr ? parserPtr->line : -1;
622     
623     importPtr->nextPtr                   = NULL;
624     importPtr->prevPtr                   = modulePtr->lastImportPtr;
625     if (!modulePtr->firstImportPtr)
626         modulePtr->firstImportPtr        = importPtr;
627     if (modulePtr->lastImportPtr)
628         modulePtr->lastImportPtr->nextPtr = importPtr;
629     modulePtr->lastImportPtr             = importPtr;
630     
631     return (importPtr);
632 }
633
634
635
636 /*
637  *----------------------------------------------------------------------
638  *
639  * addImportFlags --
640  *
641  *      Add flags to the flags of a given Import struct.
642  *
643  * Results:
644  *      None.
645  *
646  * Side effects:
647  *      None.
648  *
649  *----------------------------------------------------------------------
650  */
651
652 void addImportFlags(Import *importPtr, ImportFlags flags)
653 {
654     importPtr->flags |= flags;
655 }
656
657
658
659 /*
660  *----------------------------------------------------------------------
661  *
662  * setImportModulename --
663  *
664  *      Set the modulename part of a given Import struct.
665  *
666  * Results:
667  *      None.
668  *
669  * Side effects:
670  *      None.
671  *
672  *----------------------------------------------------------------------
673  */
674
675 void setImportModulename(Import *importPtr, char *modulename)
676 {
677     if (importPtr->export.module) {
678         smiFree(importPtr->export.module);
679     }
680     importPtr->export.module = modulename;
681 }
682
683
684
685 /*
686  *----------------------------------------------------------------------
687  *
688  * checkImports --
689  *
690  *      Check wheather all descriptors in the actual module's list
691  *      are imported by a given Module. Implicitly set all Imports'
692  *      module names.
693  *
694  * Results:
695  *      0 on success or -1 on an error or number of descriptors not found.
696  *
697  * Side effects:
698  *      None.
699  *
700  *----------------------------------------------------------------------
701  */
702
703 int checkImports(Module *modulePtr, Parser *parserPtr)
704 {
705     int         n = 0;
706     Import      *importPtr;
707     SmiNode     *smiNode;
708     SmiType     *smiType;
709     SmiMacro    *smiMacro;
710     
711     for (importPtr = parserPtr->modulePtr->firstImportPtr;
712          importPtr; importPtr = importPtr->nextPtr) {
713
714         if (importPtr->kind == KIND_UNKNOWN) {
715             if (modulePtr) {
716                 if ((smiNode = smiGetNode(&modulePtr->export,
717                                           importPtr->export.name))) {
718                     importPtr->export.module =
719                         smiStrdup(modulePtr->export.name);
720                     importPtr->kind     = KIND_OBJECT;
721                 } else if ((smiType = smiGetType(&modulePtr->export,
722                                                  importPtr->export.name))) {
723                     importPtr->export.module =
724                         smiStrdup(modulePtr->export.name);
725                     importPtr->kind     = KIND_TYPE;
726                 } else if ((smiMacro = smiGetMacro(&modulePtr->export,
727                                                    importPtr->export.name))) {
728                     importPtr->export.module =
729                         smiStrdup(modulePtr->export.name);
730                     importPtr->kind = KIND_MACRO;
731                 } else {
732                     n++;
733                     importPtr->export.module =
734                         smiStrdup(modulePtr->export.name);
735                     smiPrintError(parserPtr, ERR_IDENTIFIER_NOT_IN_MODULE,
736                                   importPtr->export.name,
737                                   modulePtr->export.name);
738                     importPtr->kind   = KIND_NOTFOUND;
739                 }
740             } else {
741                     n++;
742                     importPtr->export.module = smiStrdup("");
743                     importPtr->kind   = KIND_NOTFOUND;
744             }
745         }
746     }
747
748     return (n);
749 }
750
751
752
753 /*
754  *----------------------------------------------------------------------
755  *
756  * findImportByName --
757  *
758  *      Lookup an import descriptor by its name and the module to look in.
759  *
760  * Results:
761  *      A pointer to the Import structure or
762  *      NULL if it is not found.
763  *
764  * Side effects:
765  *      None.
766  *
767  *----------------------------------------------------------------------
768  */
769
770 Import *findImportByName(const char *name, Module *modulePtr)
771 {
772     Import           *importPtr;
773
774     if (!name)
775         return NULL;
776     
777     for (importPtr = modulePtr->firstImportPtr; importPtr;
778          importPtr = importPtr->nextPtr) {
779         if ((!strcmp(importPtr->export.name, name)) &&
780             (!(importPtr->flags & FLAG_INCOMPLIANCE))) {
781                 return (importPtr);
782         }
783     }
784
785     return NULL;
786     
787 }
788
789
790
791 /*
792  *----------------------------------------------------------------------
793  *
794  * findImportByModulenameAndName --
795  *
796  *      Lookup an import descriptor by its name and the modulename
797  *      it is imported from and the module to look in.
798  *
799  * Results:
800  *      A pointer to the Import structure or
801  *      NULL if it is not found.
802  *
803  * Side effects:
804  *      None.
805  *
806  *----------------------------------------------------------------------
807  */
808
809 Import *findImportByModulenameAndName(const char *modulename,
810                                       const char *name, Module *modulePtr)
811 {
812     Import           *importPtr;
813
814     for (importPtr = modulePtr->firstImportPtr; importPtr;
815          importPtr = importPtr->nextPtr) {
816         if ((!strcmp(importPtr->export.name, name)) &&
817             (!strcmp(importPtr->export.module, modulename))) {
818             return (importPtr);
819         }
820     }
821
822     return (NULL);
823 }
824
825
826
827 /*
828  *----------------------------------------------------------------------
829  *
830  * addObject --
831  *
832  *      Create a new Object and Node or update an existing one.
833  *      Also updates other Objects and Nodes according
834  *      to the PendingNode information.
835  *
836  * Results:
837  *      A pointer to the new Object structure or
838  *      NULL if terminated due to an error.
839  *
840  * Side effects:
841  *      None.
842  *
843  *----------------------------------------------------------------------
844  */
845
846 Object *addObject(char *objectname, Node *parentNodePtr, SmiSubid subid,
847                   ObjectFlags flags, Parser *parserPtr)
848 {
849     Object           *objectPtr;
850     Node             *nodePtr;
851     Module           *modulePtr;
852
853
854     objectPtr = (Object *) smiMalloc(sizeof(Object));
855
856     modulePtr = parserPtr ? parserPtr->modulePtr : NULL;
857
858     objectPtr->export.name              = objectname;
859     objectPtr->export.decl              = SMI_DECL_UNKNOWN;
860     objectPtr->export.access            = SMI_ACCESS_UNKNOWN;
861     objectPtr->export.status            = SMI_STATUS_UNKNOWN;
862     objectPtr->export.format            = NULL;
863     objectPtr->export.value.basetype    = SMI_BASETYPE_UNKNOWN;
864     objectPtr->export.units             = NULL;
865     objectPtr->export.description       = NULL;
866     objectPtr->export.reference         = NULL;
867     objectPtr->export.indexkind         = SMI_INDEX_UNKNOWN;
868     objectPtr->export.implied           = 0;
869     objectPtr->export.create            = 0;
870     objectPtr->export.nodekind          = SMI_NODEKIND_UNKNOWN;
871                                         
872     objectPtr->modulePtr                = modulePtr;
873     objectPtr->nodePtr                  = NULL;
874     objectPtr->prevSameNodePtr          = NULL;
875     objectPtr->nextSameNodePtr          = NULL;
876     objectPtr->typePtr                  = NULL;
877     objectPtr->listPtr                  = NULL;
878     objectPtr->flags                    = flags;
879     objectPtr->line                     = parserPtr ? parserPtr->line : -1;
880     
881     objectPtr->uniquenessPtr            = NULL;
882                                         
883     objectPtr->export.oidlen            = 0;     /* filled in by  */
884     objectPtr->export.oid               = NULL;  /* second pass.  */
885     
886     objectPtr->nextPtr                          = NULL;
887     if (modulePtr) {
888         objectPtr->prevPtr                      = modulePtr->lastObjectPtr;
889         if (!modulePtr->firstObjectPtr)
890             modulePtr->firstObjectPtr           = objectPtr;
891         if (modulePtr->lastObjectPtr)
892             modulePtr->lastObjectPtr->nextPtr   = objectPtr;
893         modulePtr->lastObjectPtr                = objectPtr;
894     } else {
895         objectPtr->prevPtr                      = NULL;
896     }
897
898     /*
899      * Link it into the tree.
900      */
901     nodePtr = findNodeByParentAndSubid(parentNodePtr, subid);
902     if ((parentNodePtr == parserPtr->pendingNodePtr) || (!nodePtr)) {
903
904         /* a new Node has to be created for this Object */
905         nodePtr = addNode(parentNodePtr, subid, flags, parserPtr);
906         nodePtr->firstObjectPtr                       = objectPtr;
907         nodePtr->lastObjectPtr                        = objectPtr;
908     } else {
909
910         objectPtr->prevSameNodePtr                    = nodePtr->lastObjectPtr;
911         if (!nodePtr->firstObjectPtr)
912             nodePtr->firstObjectPtr                   = objectPtr;
913         if (nodePtr->lastObjectPtr)
914             nodePtr->lastObjectPtr->nextSameNodePtr   = objectPtr;
915         nodePtr->lastObjectPtr                        = objectPtr;
916     }
917     objectPtr->nodePtr                                = nodePtr;
918     
919     return (objectPtr);
920 }
921
922
923
924 /*
925  *----------------------------------------------------------------------
926  *
927  * duplicateObject --
928  *
929  *      Create a new Object as a duplicate of a given one but with
930  *      an affiliation to another module with new flags and with
931  *      uninitialzied values.
932  *
933  * Results:
934  *      A pointer to the new Object structure or
935  *      NULL if terminated due to an error.
936  *
937  * Side effects:
938  *      None.
939  *
940  *----------------------------------------------------------------------
941  */
942
943 Object *duplicateObject(Object *templatePtr, ObjectFlags flags,
944                         Parser *parserPtr)
945 {
946     Object                *objectPtr;
947     Node                  *nodePtr;
948     Module                *modulePtr;
949     
950     objectPtr = (Object *) smiMalloc(sizeof(Object));
951
952     modulePtr = parserPtr->modulePtr;
953     nodePtr   = templatePtr->nodePtr;
954     
955     objectPtr->export.name                      = NULL;
956     objectPtr->export.decl                      = SMI_DECL_UNKNOWN;
957     objectPtr->export.access                    = SMI_ACCESS_UNKNOWN;
958     objectPtr->export.status                    = SMI_STATUS_UNKNOWN;
959     objectPtr->export.format                    = NULL;
960     objectPtr->export.value.basetype            = SMI_BASETYPE_UNKNOWN;
961     objectPtr->export.units                     = NULL;
962     objectPtr->export.description               = NULL;
963     objectPtr->export.reference                 = NULL;
964     objectPtr->export.indexkind                 = SMI_INDEX_UNKNOWN;
965     objectPtr->export.implied                   = 0;
966     objectPtr->export.create                    = 0;
967     objectPtr->export.nodekind                  = SMI_NODEKIND_UNKNOWN;
968                                                 
969     objectPtr->modulePtr                        = modulePtr;
970     objectPtr->nodePtr                          = nodePtr;
971     objectPtr->prevSameNodePtr                  = NULL;
972     objectPtr->nextSameNodePtr                  = NULL;
973     objectPtr->typePtr                          = NULL;
974     objectPtr->listPtr                          = NULL;
975     objectPtr->flags                            = flags;
976     objectPtr->line                             = parserPtr ? parserPtr->line : -1;
977
978     objectPtr->export.oidlen                    = 0;     /* filled in by  */
979     objectPtr->export.oid                       = NULL;  /* second pass.  */
980     
981     objectPtr->nextPtr                          = NULL;
982     if (modulePtr) {
983         objectPtr->prevPtr                      = modulePtr->lastObjectPtr;
984         if (!modulePtr->firstObjectPtr)
985             modulePtr->firstObjectPtr           = objectPtr;
986         if (modulePtr->lastObjectPtr)
987             modulePtr->lastObjectPtr->nextPtr   = objectPtr;
988         modulePtr->lastObjectPtr                = objectPtr;
989     } else {
990         objectPtr->prevPtr                      = NULL;
991     }
992     
993     objectPtr->prevSameNodePtr                        = nodePtr->lastObjectPtr;
994     if (!nodePtr->firstObjectPtr)
995         nodePtr->firstObjectPtr                       = objectPtr;
996     if (nodePtr->lastObjectPtr)
997         nodePtr->lastObjectPtr->nextSameNodePtr       = objectPtr;
998     nodePtr->lastObjectPtr                            = objectPtr;
999     objectPtr->nodePtr                                = nodePtr;
1000     
1001     return (objectPtr);
1002 }
1003
1004
1005
1006 /*
1007  *----------------------------------------------------------------------
1008  *
1009  * addNode --
1010  *
1011  *      Create a new Node by a given parent Node and subid.
1012  *
1013  * Results:
1014  *      A pointer to the new Node structure or
1015  *      NULL if terminated due to an error.
1016  *
1017  * Side effects:
1018  *      None.
1019  *
1020  *----------------------------------------------------------------------
1021  */
1022
1023 Node *addNode (Node *parentNodePtr, SmiSubid subid, NodeFlags flags,
1024                Parser *parserPtr)
1025 {
1026     Node            *nodePtr;
1027     Node            *c;
1028
1029     nodePtr = (Node *) smiMalloc(sizeof(Node));
1030     
1031     nodePtr->flags                              = flags;
1032     nodePtr->subid                              = subid;
1033     nodePtr->parentPtr                          = parentNodePtr;
1034     nodePtr->firstChildPtr                      = NULL;
1035     nodePtr->lastChildPtr                       = NULL;
1036     nodePtr->firstObjectPtr                     = NULL;
1037     nodePtr->lastObjectPtr                      = NULL;
1038
1039     /*
1040      * this cannot be set in all situations (pending sub trees).
1041      * we delay it to the second pass.
1042      */
1043     nodePtr->oidlen                             = 0;
1044     nodePtr->oid                                = NULL;
1045
1046     if (parentNodePtr) {
1047         if (parentNodePtr->firstChildPtr) {
1048             for (c = parentNodePtr->firstChildPtr;
1049                  c && (c->subid < subid);
1050                  c = c->nextPtr);
1051             if (c) {
1052                 if (c != parentNodePtr->firstChildPtr) {
1053                     c->prevPtr->nextPtr = nodePtr;
1054                     nodePtr->prevPtr = c->prevPtr;
1055                     c->prevPtr = nodePtr;
1056                     nodePtr->nextPtr = c;
1057                 } else {
1058                     c->prevPtr = nodePtr;
1059                     nodePtr->nextPtr = c;
1060                     nodePtr->prevPtr = NULL;
1061                     parentNodePtr->firstChildPtr = nodePtr;
1062                 }
1063             } else {
1064                 nodePtr->nextPtr = NULL;
1065                 nodePtr->prevPtr = parentNodePtr->lastChildPtr;
1066                 parentNodePtr->lastChildPtr->nextPtr = nodePtr;
1067                 parentNodePtr->lastChildPtr = nodePtr;
1068             }
1069         } else {
1070             parentNodePtr->firstChildPtr = nodePtr;
1071             parentNodePtr->lastChildPtr = nodePtr;
1072             nodePtr->nextPtr = NULL;
1073             nodePtr->prevPtr = NULL;
1074         }
1075     }
1076
1077     return nodePtr;
1078 }
1079
1080
1081
1082 /*
1083  *----------------------------------------------------------------------
1084  *
1085  * createNodes --
1086  *
1087  *      Create all missing Nodes down the tree along all subids of
1088  *      a given Oid.
1089  *
1090  * Results:
1091  *      A pointer to the leaf Node structure or
1092  *      NULL if terminated due to an error.
1093  *
1094  * Side effects:
1095  *      None.
1096  *
1097  *----------------------------------------------------------------------
1098  */
1099
1100 Node *createNodes(unsigned int oidlen, SmiSubid *oid)
1101 {
1102     Node         *parentNodePtr, *nodePtr;
1103     unsigned int i;
1104
1105     parentNodePtr = smiHandle->rootNodePtr;
1106
1107     for(i = 0; i < oidlen; i++) {
1108         if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr, oid[i]))) {
1109             nodePtr = addNode(parentNodePtr, oid[i], 0, NULL);
1110         }
1111         parentNodePtr = nodePtr;
1112     }
1113
1114     return parentNodePtr;    
1115 }
1116
1117
1118
1119 /*
1120  *----------------------------------------------------------------------
1121  *
1122  * createNodesByOidString --
1123  *
1124  *      Create all missing Nodes down the tree along all subids of
1125  *      a given Oid.
1126  *
1127  * Results:
1128  *      A pointer to the leaf Node structure or
1129  *      NULL if terminated due to an error.
1130  *
1131  * Side effects:
1132  *      None.
1133  *
1134  *----------------------------------------------------------------------
1135  */
1136
1137 Node *createNodesByOidString(const char *oid)
1138 {
1139     char                *p, *elements;
1140     Node                *parentNodePtr, *nodePtr;
1141     SmiSubid            subid;
1142
1143     parentNodePtr = smiHandle->rootNodePtr;
1144     elements = smiStrdup(oid);
1145
1146     p = strtok(elements, ".");
1147     do {
1148         subid = (unsigned int)strtoul(p, NULL, 0);
1149         if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr,
1150                                                  subid))) {
1151             nodePtr = addNode(parentNodePtr, subid, 0, NULL);
1152         }
1153         parentNodePtr = nodePtr;
1154     } while ((p = strtok(NULL, ".")));
1155
1156     smiFree(elements);
1157
1158     return parentNodePtr;
1159 }
1160
1161
1162
1163 /*
1164  *----------------------------------------------------------------------
1165  *
1166  * getParentNode --
1167  *
1168  *      Return the parent of a given Node.
1169  *
1170  * Results:
1171  *      A pointer to the parent Node structure.
1172  *
1173  * Side effects:
1174  *      None.
1175  *
1176  *----------------------------------------------------------------------
1177  */
1178
1179 Node *getParentNode(Node *nodePtr)
1180 {
1181     return nodePtr->parentPtr;
1182 }
1183
1184
1185
1186 /*
1187  *----------------------------------------------------------------------
1188  *
1189  * mergeNodeTrees --
1190  *
1191  *      Merge the subtree rooted at `from' into the `to' tree recursively
1192  *      and release the `from' tree.
1193  *
1194  * Results:
1195  *      None.
1196  *
1197  * Side effects:
1198  *      None.
1199  *
1200  *----------------------------------------------------------------------
1201  */
1202
1203 static void mergeNodeTrees(Node *toNodePtr, Node *fromNodePtr,
1204                            Parser *parserPtr)
1205 {
1206     Node              *nodePtr, *toChildPtr, *nextPtr;
1207     Object            *objectPtr;
1208
1209     /* (1) merge lists of Objects for this node */
1210     if (fromNodePtr->firstObjectPtr) {
1211         if (!toNodePtr->firstObjectPtr) {
1212             toNodePtr->firstObjectPtr = fromNodePtr->firstObjectPtr;
1213             toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr;
1214         } else {
1215             fromNodePtr->firstObjectPtr->prevSameNodePtr =
1216                 toNodePtr->lastObjectPtr;
1217             toNodePtr->lastObjectPtr->nextSameNodePtr =
1218                 fromNodePtr->firstObjectPtr;
1219             toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr;
1220         }
1221     }
1222     for (objectPtr = fromNodePtr->firstObjectPtr;
1223          objectPtr; objectPtr = objectPtr->nextSameNodePtr) {
1224         objectPtr->nodePtr = toNodePtr;
1225
1226     }
1227     
1228     /* (2) loop: merge all first-level `from' sub-trees to `to' */
1229     /* adjust all `from' sub-nodes' parentPtrs */
1230     for (nodePtr = fromNodePtr->firstChildPtr; nodePtr;
1231          nodePtr = nodePtr->nextPtr) {
1232         nodePtr->parentPtr = toNodePtr;
1233     }
1234     if (!toNodePtr->firstChildPtr) {
1235         /*
1236          * if `to' has no sub-nodes, just move the `from' sub-nodes.
1237          */
1238         toNodePtr->firstChildPtr = fromNodePtr->firstChildPtr;
1239         toNodePtr->lastChildPtr = fromNodePtr->lastChildPtr;
1240     } else {
1241         /*
1242          * otherwise, we really have to merge both trees...
1243          */
1244         for (nodePtr = fromNodePtr->firstChildPtr; nodePtr; ) {
1245             nextPtr = nodePtr->nextPtr;
1246             if ((toChildPtr = findNodeByParentAndSubid(toNodePtr,
1247                                                        nodePtr->subid))) {
1248                 /*
1249                  * if a sub-node with the same subid is already present
1250                  * in `to', merge them recursively.
1251                  */
1252                 mergeNodeTrees(toChildPtr, nodePtr, parserPtr);
1253             } else {
1254                 /*
1255                  * otherwise, move the sub-tree from `from' to `to'.
1256                  */
1257                 if (nodePtr->subid < toNodePtr->firstChildPtr->subid) {
1258                     /* move to the head. */
1259                     nodePtr->nextPtr = toNodePtr->firstChildPtr;
1260                     toNodePtr->firstChildPtr = nodePtr;
1261                 } else if (nodePtr->subid > toNodePtr->lastChildPtr->subid) {
1262                     /* move to the end. */
1263                     nodePtr->prevPtr = toNodePtr->lastChildPtr;
1264                     toNodePtr->lastChildPtr->nextPtr = nodePtr;
1265                     toNodePtr->lastChildPtr = nodePtr;
1266                 } else {
1267                     /* move to the appropriate place in the `to' list. */
1268                     for (toChildPtr = toNodePtr->firstChildPtr;
1269                          toChildPtr->nextPtr->subid < nodePtr->subid;
1270                          toChildPtr = toChildPtr->nextPtr);
1271                     toChildPtr->nextPtr->prevPtr = nodePtr;
1272                     nodePtr->nextPtr = toChildPtr->nextPtr;
1273                     nodePtr->prevPtr = toChildPtr;
1274                     toChildPtr->nextPtr = nodePtr;
1275                 }
1276             }
1277             nodePtr = nextPtr;
1278         }
1279     }
1280
1281     smiFree(fromNodePtr);
1282 }
1283
1284
1285
1286 /*
1287  *----------------------------------------------------------------------
1288  *
1289  * setObjectName --
1290  *
1291  *      Set the name of a given Object. Combine two Objects if the name
1292  *      already exists.
1293  *
1294  * Results:
1295  *      (Object *) of the potentially combined object.
1296  *
1297  * Side effects:
1298  *      None.
1299  *
1300  *----------------------------------------------------------------------
1301  */
1302
1303 Object *setObjectName(Object *objectPtr, char *name, Parser *parserPtr)
1304 {
1305     Node              *nodePtr, *nextPtr;
1306     Module            *modulePtr;
1307     Object            *newObjectPtr;
1308
1309     if (objectPtr->export.name) {
1310         smiFree(objectPtr->export.name);
1311     }
1312     objectPtr->export.name = name;
1313     /*
1314      * If this name is found on the pending list (at depth==1 in
1315      * pendingRootNode), we have to move the corresponding subtree to
1316      * the main tree.
1317      */
1318     for (nodePtr = parserPtr->pendingNodePtr->firstChildPtr; nodePtr;
1319          nodePtr = nextPtr) {
1320
1321         /*
1322          * probably we change the contents of `pending', so remember
1323          * the next pointer.
1324          */
1325         nextPtr = nodePtr->nextPtr;
1326
1327         if (!strcmp(nodePtr->firstObjectPtr->export.name, name)) {
1328
1329             /*
1330              * remove nodePtr from the pendingRootNode tree.
1331              */
1332             if (nodePtr->prevPtr) {
1333                 nodePtr->prevPtr->nextPtr = nodePtr->nextPtr;
1334             } else {
1335                 parserPtr->pendingNodePtr->firstChildPtr = nodePtr->nextPtr;
1336             }
1337             if (nodePtr->nextPtr) {
1338                 nodePtr->nextPtr->prevPtr = nodePtr->prevPtr;
1339             } else {
1340                 parserPtr->pendingNodePtr->lastChildPtr = nodePtr->prevPtr;
1341             }
1342
1343 #if 0
1344             objectPtr->nodePtr->firstObjectPtr = NULL;
1345             objectPtr->nodePtr->lastObjectPtr = NULL;
1346 #else
1347             if (objectPtr->nodePtr->lastObjectPtr != NULL) {
1348                 if (objectPtr->nodePtr->lastObjectPtr->export.oid == NULL) {
1349                     objectPtr->nodePtr->lastObjectPtr = 
1350                         objectPtr->nodePtr->lastObjectPtr->prevSameNodePtr;
1351                     if (objectPtr->nodePtr->lastObjectPtr == NULL) {
1352                         objectPtr->nodePtr->firstObjectPtr = NULL;
1353                     }
1354                 }
1355             }
1356 #endif
1357             
1358             newObjectPtr = nodePtr->firstObjectPtr;
1359             if (newObjectPtr) {
1360                 modulePtr = newObjectPtr->modulePtr;
1361                 if (modulePtr->objectPtr == objectPtr) {
1362                     modulePtr->objectPtr = newObjectPtr;
1363                 }
1364                 if (modulePtr->firstObjectPtr == objectPtr) {
1365                     modulePtr->firstObjectPtr = objectPtr->nextPtr;
1366                     modulePtr->firstObjectPtr->prevPtr = NULL;
1367                 }
1368                 if (modulePtr->lastObjectPtr == objectPtr) {
1369                     modulePtr->lastObjectPtr = objectPtr->prevPtr;
1370                     modulePtr->lastObjectPtr->nextPtr = NULL;
1371                 }
1372
1373                 mergeNodeTrees(objectPtr->nodePtr, nodePtr, parserPtr);
1374                 smiFree(objectPtr->export.name);
1375                 smiFree(objectPtr);
1376                 return newObjectPtr;
1377             } else {
1378                 return objectPtr;
1379             }
1380         }
1381     }
1382     return objectPtr;
1383 }
1384
1385
1386
1387 /*
1388  *----------------------------------------------------------------------
1389  *
1390  * setObjectType --
1391  *
1392  *      Set the type (pointer to a Type struct) of a given Object.
1393  *
1394  * Results:
1395  *      None.
1396  *
1397  * Side effects:
1398  *      None.
1399  *
1400  *----------------------------------------------------------------------
1401  */
1402
1403 void setObjectType(Object *objectPtr, Type *typePtr)
1404 {
1405     objectPtr->typePtr = typePtr;
1406 }
1407
1408
1409
1410 /*
1411  *----------------------------------------------------------------------
1412  *
1413  * setObjectAccess --
1414  *
1415  *      Set the access of a given Object.
1416  *
1417  * Results:
1418  *      None.
1419  *
1420  * Side effects:
1421  *      None.
1422  *
1423  *----------------------------------------------------------------------
1424  */
1425
1426 void setObjectAccess(Object *objectPtr, SmiAccess access)
1427 {
1428     objectPtr->export.access = access;
1429 }
1430
1431
1432
1433 /*
1434  *----------------------------------------------------------------------
1435  *
1436  * setObjectStatus --
1437  *
1438  *      Set the status of a given Object.
1439  *
1440  * Results:
1441  *      None.
1442  *
1443  * Side effects:
1444  *      None.
1445  *
1446  *----------------------------------------------------------------------
1447  */
1448
1449 void setObjectStatus(Object *objectPtr, SmiStatus status)
1450 {
1451     objectPtr->export.status = status;
1452 }
1453
1454
1455
1456 /*
1457  *----------------------------------------------------------------------
1458  *
1459  * setObjectDescription --
1460  *
1461  *      Set the description of a given Object.
1462  *
1463  * Results:
1464  *      None.
1465  *
1466  * Side effects:
1467  *      None.
1468  *
1469  *----------------------------------------------------------------------
1470  */
1471
1472 void setObjectDescription(Object *objectPtr, char *description,
1473                           Parser *parserPtr)
1474 {
1475     if (objectPtr->export.description)
1476         smiFree(objectPtr->export.description);
1477     if (parserPtr->flags & SMI_FLAG_NODESCR) {
1478         smiFree(description);
1479         objectPtr->export.description = NULL;
1480     } else {
1481         objectPtr->export.description = description;
1482     }
1483 }
1484
1485
1486
1487 /*
1488  *----------------------------------------------------------------------
1489  *
1490  * setObjectReference --
1491  *
1492  *      Set the reference of a given Object.
1493  *
1494  * Results:
1495  *      None.
1496  *
1497  * Side effects:
1498  *      None.
1499  *
1500  *----------------------------------------------------------------------
1501  */
1502
1503 void setObjectReference(Object *objectPtr, char *reference, Parser *parserPtr)
1504 {
1505     if (objectPtr->export.reference)
1506         smiFree(objectPtr->export.reference);
1507     if (parserPtr->flags & SMI_FLAG_NODESCR) {
1508         smiFree(reference);
1509         objectPtr->export.reference = NULL;
1510     } else {
1511         objectPtr->export.reference = reference;
1512     }
1513 }
1514
1515
1516 /*
1517  *----------------------------------------------------------------------
1518  *
1519  * setObjectFormat --
1520  *
1521  *      Set the format of a given Object.
1522  *
1523  * Results:
1524  *      None.
1525  *
1526  * Side effects:
1527  *      None.
1528  *
1529  *----------------------------------------------------------------------
1530  */
1531
1532 void setObjectFormat(Object *objectPtr, char *format)
1533 {
1534     if (objectPtr->export.format) smiFree(objectPtr->export.format);
1535     objectPtr->export.format = format;
1536 }
1537
1538
1539
1540 /*
1541  *----------------------------------------------------------------------
1542  *
1543  * setObjectUnits --
1544  *
1545  *      Set the units of a given Object.
1546  *
1547  * Results:
1548  *      None.
1549  *
1550  * Side effects:
1551  *      None.
1552  *
1553  *----------------------------------------------------------------------
1554  */
1555
1556 void setObjectUnits(Object *objectPtr, char *units)
1557 {
1558     if (objectPtr->export.units) smiFree(objectPtr->export.units);
1559     objectPtr->export.units = units;
1560 }
1561
1562
1563
1564 /*
1565  *----------------------------------------------------------------------
1566  *
1567  * setObjectDecl --
1568  *
1569  *      Set the declaring macro of a given Object.
1570  *
1571  * Results:
1572  *      None.
1573  *
1574  * Side effects:
1575  *      None.
1576  *
1577  *----------------------------------------------------------------------
1578  */
1579
1580 void setObjectDecl(Object *objectPtr, SmiDecl decl)
1581 {
1582     objectPtr->export.decl = decl;
1583 }
1584
1585
1586
1587 /*
1588  *----------------------------------------------------------------------
1589  *
1590  * setObjectLine --
1591  *
1592  *      Set the line of definition of a given Object.
1593  *
1594  * Results:
1595  *      None.
1596  *
1597  * Side effects:
1598  *      None.
1599  *
1600  *----------------------------------------------------------------------
1601  */
1602
1603 void setObjectLine(Object *objectPtr, int line, Parser *parserPtr)
1604 {
1605     if (line) {
1606         objectPtr->line = line;
1607     } else {
1608         objectPtr->line = parserPtr ? parserPtr->line : -1;
1609     }
1610 }
1611
1612
1613
1614 /*
1615  *----------------------------------------------------------------------
1616  *
1617  * setObjectNodekind --
1618  *
1619  *      Set the language independant SmiNodekind of a given Object.
1620  *
1621  * Results:
1622  *      None.
1623  *
1624  * Side effects:
1625  *      None.
1626  *
1627  *----------------------------------------------------------------------
1628  */
1629
1630 void setObjectNodekind(Object *objectPtr, SmiNodekind nodekind)
1631 {
1632     objectPtr->export.nodekind = nodekind;
1633 }
1634
1635
1636
1637 /*
1638  *----------------------------------------------------------------------
1639  *
1640  * addObjectFlags --
1641  *
1642  *      Add flags to the flags of a given Object.
1643  *
1644  * Results:
1645  *      None.
1646  *
1647  * Side effects:
1648  *      None.
1649  *
1650  *----------------------------------------------------------------------
1651  */
1652
1653 void addObjectFlags(Object *objectPtr, ObjectFlags flags)
1654 {
1655     objectPtr->flags |= flags;
1656 }
1657
1658
1659
1660 /*
1661  *----------------------------------------------------------------------
1662  *
1663  * deleteObjectFlags --
1664  *
1665  *      Delete flags from the flags of a given Object.
1666  *
1667  * Results:
1668  *      None.
1669  *
1670  * Side effects:
1671  *      None.
1672  *
1673  *----------------------------------------------------------------------
1674  */
1675
1676 void deleteObjectFlags(Object *objectPtr, ObjectFlags flags)
1677 {
1678     objectPtr->flags &= ~flags;
1679 }
1680
1681
1682
1683 /*
1684  *----------------------------------------------------------------------
1685  *
1686  * checkObjectFlag --
1687  *
1688  *      Check whether a given set of flags of a given Object are all set.
1689  *
1690  * Results:
1691  *      true if all named flags are set.
1692  *
1693  * Side effects:
1694  *      None.
1695  *
1696  *----------------------------------------------------------------------
1697  */
1698
1699 int checkObjectFlags(Object *objectPtr, ObjectFlags flags)
1700 {
1701     return ((objectPtr->flags & flags) == flags);
1702 }
1703
1704
1705
1706 /*
1707  *----------------------------------------------------------------------
1708  *
1709  * setObjectIndex --
1710  *
1711  *      Set the list of INDEX elements of a given Object.
1712  *
1713  * Results:
1714  *      None.
1715  *
1716  * Side effects:
1717  *      None.
1718  *
1719  *----------------------------------------------------------------------
1720  */
1721
1722 /* TODO remove me
1723 void setObjectIndex(Object *objectPtr, Index *indexPtr)
1724     Object       *objectPtr;
1725     Index        *indexPtr;
1726 {
1727     objectPtr->indexPtr = indexPtr;
1728 }
1729 */
1730
1731
1732 /*
1733  *----------------------------------------------------------------------
1734  *
1735  * setObjectList --
1736  *
1737  *      Set the list of objects of a notification type or object group
1738  *      or the list of notifications of a notification group.
1739  *
1740  * Results:
1741  *      None.
1742  *
1743  * Side effects:
1744  *      None.
1745  *
1746  *----------------------------------------------------------------------
1747  */
1748
1749 void setObjectList(Object *objectPtr, List *listPtr)
1750 {
1751     objectPtr->listPtr = listPtr;
1752 }
1753
1754
1755
1756 /*
1757  *----------------------------------------------------------------------
1758  *
1759  * setObjectRelated --
1760  *
1761  *      Set the related object of a given object (e.g. SMIv2 AUGMENTS)
1762  *
1763  * Results:
1764  *      None.
1765  *
1766  * Side effects:
1767  *      None.
1768  *
1769  *----------------------------------------------------------------------
1770  */
1771
1772 void setObjectRelated(Object *objectPtr, Object *relatedPtr)
1773 {
1774     objectPtr->relatedPtr = relatedPtr;
1775 }
1776
1777
1778
1779 /*
1780  *----------------------------------------------------------------------
1781  *
1782  * setObjectImplied --
1783  *
1784  *      Set the implied flag of a given object
1785  *
1786  * Results:
1787  *      None.
1788  *
1789  * Side effects:
1790  *      None.
1791  *
1792  *----------------------------------------------------------------------
1793  */
1794
1795 void setObjectImplied(Object *objectPtr, int implied)
1796 {
1797     objectPtr->export.implied = implied;
1798 }
1799
1800
1801
1802 /*
1803  *----------------------------------------------------------------------
1804  *
1805  * setObjectCreate --
1806  *
1807  *      Set the create flag of a given (table entry) object
1808  *
1809  * Results:
1810  *      None.
1811  *
1812  * Side effects:
1813  *      None.
1814  *
1815  *----------------------------------------------------------------------
1816  */
1817
1818 void setObjectCreate(Object *objectPtr, int create)
1819 {
1820     objectPtr->export.create = create;
1821 }
1822
1823
1824
1825 /*
1826  *----------------------------------------------------------------------
1827  *
1828  * setObjectIndexkind --
1829  *
1830  *      Set the indexkind of a given (table entry) object
1831  *
1832  * Results:
1833  *      None.
1834  *
1835  * Side effects:
1836  *      None.
1837  *
1838  *----------------------------------------------------------------------
1839  */
1840
1841 void setObjectIndexkind(Object *objectPtr, SmiIndexkind indexkind)
1842 {
1843     objectPtr->export.indexkind = indexkind;
1844 }
1845
1846
1847
1848 /*
1849  *----------------------------------------------------------------------
1850  *
1851  * setObjectValue --
1852  *
1853  *      Set the default value pointer of a given Object.
1854  *
1855  * Results:
1856  *      None.
1857  *
1858  * Side effects:
1859  *      None.
1860  *
1861  *----------------------------------------------------------------------
1862  */
1863
1864 void setObjectValue(Object *objectPtr, SmiValue *valuePtr)
1865 {
1866     objectPtr->export.value = *valuePtr;
1867     smiFree(valuePtr);
1868 }
1869
1870
1871
1872 /*
1873  *----------------------------------------------------------------------
1874  *
1875  * setObjectUniqueness --
1876  *
1877  *      Set the uniqueness entry of an object
1878  *
1879  * Results:
1880  *      None.
1881  *
1882  * Side effects:
1883  *      None.
1884  *
1885  *----------------------------------------------------------------------
1886  */
1887
1888 void setObjectUniqueness(Object *objectPtr, List *listPtr)
1889 {
1890     objectPtr->uniquenessPtr = listPtr;
1891 }
1892
1893
1894
1895 /*
1896  *----------------------------------------------------------------------
1897  *
1898  * setObjectInstallErrors --
1899  *
1900  *      Set the install errors entry of an object
1901  *
1902  * Results:
1903  *      None.
1904  *
1905  * Side effects:
1906  *      None.
1907  *
1908  *----------------------------------------------------------------------
1909  */
1910
1911 /*void setObjectInstallErrors(Object *objectPtr, List *listPtr)
1912 {
1913     objectPtr->installErrorsPtr = listPtr;
1914 }*/
1915
1916
1917
1918 /*
1919  *----------------------------------------------------------------------
1920  *
1921  * findNodeByParentAndSubid --
1922  *
1923  *      Lookup a Node by a given parent and subid value.
1924  *
1925  * Results:
1926  *      A pointer to the Node structure or
1927  *      NULL if it is not found.
1928  *
1929  * Side effects:
1930  *      None.
1931  *
1932  *----------------------------------------------------------------------
1933  */
1934
1935 Node *findNodeByParentAndSubid(Node *parentNodePtr, SmiSubid subid)
1936 {
1937     Node *nodePtr;
1938     
1939     if (parentNodePtr &&
1940         (parentNodePtr != smiHandle->parserPtr->pendingNodePtr)) {
1941         for (nodePtr = parentNodePtr->firstChildPtr; nodePtr;
1942              nodePtr = nodePtr->nextPtr) {
1943             if (nodePtr->subid == subid) {
1944                 return (nodePtr);
1945             }
1946         }
1947     }
1948     
1949     return (NULL);
1950 }
1951
1952
1953
1954 /*
1955  *----------------------------------------------------------------------
1956  *
1957  * findNodeByOid --
1958  *
1959  *      Lookup a Node by a given array of numerical subids.
1960  *
1961  * Results:
1962  *      A pointer to the Node structure or
1963  *      NULL if it is not found.
1964  *
1965  * Side effects:
1966  *      None.
1967  *
1968  *----------------------------------------------------------------------
1969  */
1970
1971 Node *findNodeByOid(unsigned int oidlen, SmiSubid *oid)
1972 {
1973     Node          *nodePtr;
1974     unsigned int  i;
1975     
1976     nodePtr = smiHandle->rootNodePtr;
1977     for(i = 0; i < oidlen && nodePtr; i++) {
1978         nodePtr = findNodeByParentAndSubid(nodePtr, oid[i]);
1979     }
1980     
1981     return (nodePtr);
1982 }
1983
1984
1985
1986 /*
1987  *----------------------------------------------------------------------
1988  *
1989  * findNodeByOidString --
1990  *
1991  *      Lookup a Node by a given string of concatinated numerical subids.
1992  *
1993  * Results:
1994  *      A pointer to the Node structure or
1995  *      NULL if it is not found.
1996  *
1997  * Side effects:
1998  *      None.
1999  *
2000  *----------------------------------------------------------------------
2001  */
2002
2003 Node *findNodeByOidString(char *oid)
2004 {
2005     Node *nodePtr;
2006     char *s;
2007     char *p;
2008     
2009     s = smiStrdup(oid);
2010     nodePtr = smiHandle->rootNodePtr;
2011     for(p = strtok(s, ". "); p && nodePtr; p = strtok(NULL, ". ")) {
2012         nodePtr = findNodeByParentAndSubid(nodePtr, atoi(p));
2013     }
2014     
2015     smiFree(s);
2016     return (nodePtr);
2017 }
2018
2019
2020
2021 /*
2022  *----------------------------------------------------------------------
2023  *
2024  * findObjectByNode --
2025  *
2026  *      Lookup an Object by a given Node. Note, that there might be
2027  *      multiple definitions for one node.
2028  *
2029  * Results:
2030  *      A pointer to the first Object structure in the current View or
2031  *      a pointer to the first Object if none is in the current View or
2032  *      NULL if it is not found.
2033  *
2034  * Side effects:
2035  *      None.
2036  *
2037  *----------------------------------------------------------------------
2038  */
2039
2040 Object *findObjectByNode(Node *nodePtr)
2041 {
2042     Object    *objectPtr;
2043     Object    *goodObjectPtr = NULL;
2044
2045     /* first, try to find an object in the current view. */
2046     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2047          objectPtr = objectPtr->nextSameNodePtr) {
2048         if (isInView(objectPtr->modulePtr->export.name)) {
2049             if (! goodObjectPtr) {
2050                 goodObjectPtr = objectPtr;
2051             } else if (objectPtr->modulePtr->export.language
2052                        > goodObjectPtr->modulePtr->export.language) {
2053                 goodObjectPtr = objectPtr;
2054             }
2055         }
2056     }
2057
2058     return goodObjectPtr ? goodObjectPtr : nodePtr->firstObjectPtr;
2059 }
2060
2061
2062
2063 /*
2064  *----------------------------------------------------------------------
2065  *
2066  * findObjectByModuleAndNode --
2067  *
2068  *      Lookup an Object by a given Node and Module. This is necessary
2069  *      since there might be different declarations in different modules
2070  *      for the same OID.
2071  *
2072  * Results:
2073  *      A pointer to the Object structure or
2074  *      NULL if it is not found.
2075  *
2076  * Side effects:
2077  *      None.
2078  *
2079  *----------------------------------------------------------------------
2080  */
2081
2082 Object *findObjectByModuleAndNode(Module *modulePtr, Node *nodePtr)
2083 {
2084     Object    *objectPtr;
2085
2086     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2087          objectPtr = objectPtr->nextSameNodePtr) {
2088         if (objectPtr->modulePtr == modulePtr) {
2089             return (objectPtr);
2090         }
2091     }
2092
2093     return (NULL);
2094 }
2095
2096
2097
2098 /*
2099  *----------------------------------------------------------------------
2100  *
2101  * findObjectByModulenameAndNode --
2102  *
2103  *      Lookup an Object by a given Node and Modulename. This is necessary
2104  *      since there might be different declarations in different modules
2105  *      for the same OID.
2106  *
2107  * Results:
2108  *      A pointer to the Object structure or
2109  *      NULL if it is not found.
2110  *
2111  * Side effects:
2112  *      None.
2113  *
2114  *----------------------------------------------------------------------
2115  */
2116
2117 Object *findObjectByModulenameAndNode(const char *modulename, Node *nodePtr)
2118 {
2119     Object     *objectPtr;
2120
2121     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2122          objectPtr = objectPtr->nextSameNodePtr) {
2123         if (!strcmp(objectPtr->modulePtr->export.name, modulename)) {
2124             return (objectPtr);
2125         }
2126     }
2127
2128     return (NULL);
2129 }
2130
2131
2132
2133 /*
2134  *----------------------------------------------------------------------
2135  *
2136  * findObjectByName --
2137  *
2138  *      Lookup an Object by a given name. Note, that
2139  *      there might be more than one Object with the same name.
2140  *      In this case, it is undefined which Object is returned.
2141  *
2142  * Results:
2143  *      A pointer to the Object structure or
2144  *      NULL if it is not found.
2145  *
2146  * Side effects:
2147  *      None.
2148  *
2149  *----------------------------------------------------------------------
2150  */
2151
2152 Object *findObjectByName(const char *objectname)
2153 {
2154     Module           *modulePtr;
2155     Object           *objectPtr;
2156
2157     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
2158          modulePtr = modulePtr->nextPtr) {
2159         for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2160              objectPtr = objectPtr->nextPtr) {
2161             if ((objectPtr->export.name) &&
2162                 !strcmp(objectPtr->export.name, objectname)) {
2163                 /*
2164                  * We return the first matching object.
2165                  * TODO: probably we should check if there are more matching
2166                  *       objects, and give a warning if there's another one.
2167                  */
2168                 return (objectPtr);
2169             }
2170         }
2171     }
2172
2173     return (NULL);
2174 }
2175
2176
2177
2178 /*
2179  *----------------------------------------------------------------------
2180  *
2181  * findNextObjectByName --
2182  *
2183  *      Lookup the next Object by a given name. Note, that
2184  *      there might be more than one Object with the same name.
2185  *
2186  * Results:
2187  *      A pointer to the Object structure or
2188  *      NULL if it is not found.
2189  *
2190  * Side effects:
2191  *      None.
2192  *
2193  *----------------------------------------------------------------------
2194  */
2195
2196 Object *findNextObjectByName(const char *objectname, Object *prevObjectPtr)
2197 {
2198     Module           *modulePtr;
2199     Object           *objectPtr;
2200
2201     for (modulePtr = prevObjectPtr->modulePtr->nextPtr; modulePtr;
2202          modulePtr = modulePtr->nextPtr) {
2203         for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2204              objectPtr = objectPtr->nextPtr) {
2205             if ((objectPtr->export.name)
2206                 && !strcmp(objectPtr->export.name, objectname)) {
2207                 /*
2208                  * We return the first matching object.
2209                  * TODO: probably we should check if there are more matching
2210                  *       objects, and give a warning if there's another one.
2211                  */
2212                 return (objectPtr);
2213             }
2214         }
2215     }
2216
2217     return (NULL);
2218 }
2219
2220
2221
2222 /*
2223  *----------------------------------------------------------------------
2224  *
2225  * findObjectByModulenameAndName --
2226  *
2227  *      Lookup a Object by a given Module and name.
2228  *
2229  * Results:
2230  *      A pointer to the Object structure or
2231  *      NULL if it is not found.
2232  *
2233  * Side effects:
2234  *      None.
2235  *
2236  *----------------------------------------------------------------------
2237  */
2238
2239 Object *findObjectByModulenameAndName(const char *modulename,
2240                                       const char *objectname)
2241 {
2242     Module           *modulePtr;
2243     Object           *objectPtr;
2244
2245     modulePtr = findModuleByName(modulename);
2246
2247     if (modulePtr) {
2248         for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2249              objectPtr = objectPtr->nextPtr) {
2250             if ((objectPtr->export.name) &&
2251                 !strcmp(objectPtr->export.name, objectname)) {
2252                 return (objectPtr);
2253             }
2254         }
2255     }
2256
2257     /*
2258      * Some toplevel Objects seem to be always known.
2259      */
2260     if ((!strcmp(objectname, "iso")) ||
2261         (!strcmp(objectname, "ccitt")) ||
2262         (!strcmp(objectname, "joint-iso-ccitt"))) {
2263         return findObjectByName(objectname);
2264     }
2265
2266     return (NULL);
2267 }
2268
2269
2270
2271 /*
2272  *----------------------------------------------------------------------
2273  *
2274  * findObjectByModuleAndName --
2275  *
2276  *      Lookup a Object by a given Module and name.
2277  *
2278  * Results:
2279  *      A pointer to the Object structure or
2280  *      NULL if it is not found.
2281  *
2282  * Side effects:
2283  *      None.
2284  *
2285  *----------------------------------------------------------------------
2286  */
2287
2288 Object *findObjectByModuleAndName(Module *modulePtr, const char *objectname)
2289 {
2290     Object        *objectPtr;
2291
2292     if (! objectname) {
2293         return NULL;
2294     }
2295     
2296     if (modulePtr) {
2297         for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2298              objectPtr = objectPtr->nextPtr) {
2299             if ((objectPtr->export.name) &&
2300                 !strcmp(objectPtr->export.name, objectname)) {
2301                 return (objectPtr);
2302             }
2303         }
2304     }
2305     
2306     /*
2307      * Some toplevel Objects seem to be always known.
2308      */
2309     if ((!strcmp(objectname, "iso")) ||
2310         (!strcmp(objectname, "ccitt")) ||
2311         (!strcmp(objectname, "joint-iso-ccitt"))) {
2312         return findObjectByName(objectname);
2313     }
2314     
2315     return (NULL);
2316 }
2317
2318
2319
2320 /*
2321  *----------------------------------------------------------------------
2322  *
2323  * addType --
2324  *
2325  *      Create a new Type structure.
2326  *
2327  * Results:
2328  *      A pointer to the new Type structure or
2329  *      NULL if terminated due to an error.
2330  *
2331  * Side effects:
2332  *      None.
2333  *
2334  *----------------------------------------------------------------------
2335  */
2336
2337 Type *addType(char *type_name, SmiBasetype basetype, TypeFlags flags,
2338               Parser *parserPtr)
2339 {
2340     Type           *typePtr;
2341     Module         *modulePtr;
2342     
2343     modulePtr = parserPtr ? parserPtr->modulePtr : NULL;
2344     
2345     typePtr = smiMalloc(sizeof(Type));
2346
2347     typePtr->export.name                = type_name;
2348     typePtr->export.basetype            = basetype;
2349     typePtr->export.decl                = SMI_DECL_UNKNOWN;
2350     typePtr->export.format              = NULL;
2351     typePtr->export.value.basetype      = SMI_BASETYPE_UNKNOWN;
2352     typePtr->export.units               = NULL;
2353     typePtr->export.status              = SMI_STATUS_UNKNOWN;
2354     typePtr->export.description         = NULL;
2355     typePtr->export.reference           = NULL;
2356
2357     typePtr->modulePtr                  = modulePtr;
2358     typePtr->listPtr                    = NULL;
2359     typePtr->flags                      = flags;
2360     typePtr->parentPtr                  = NULL;
2361     typePtr->line                       = parserPtr ? parserPtr->line : -1;
2362     
2363     typePtr->nextPtr                    = NULL;
2364     if (modulePtr) {
2365         typePtr->prevPtr                = modulePtr->lastTypePtr;
2366         if (!modulePtr->firstTypePtr)
2367             modulePtr->firstTypePtr     = typePtr;
2368         if (modulePtr->lastTypePtr)
2369             modulePtr->lastTypePtr->nextPtr = typePtr;
2370         modulePtr->lastTypePtr          = typePtr;
2371     } else {
2372         typePtr->prevPtr                = NULL;
2373     }
2374         
2375     return (typePtr);
2376 }
2377
2378
2379
2380 /*
2381  *----------------------------------------------------------------------
2382  *
2383  * duplicateType --
2384  *
2385  *      Create a new Type as a duplicate of a given one but with
2386  *      an affiliation to the current module.
2387  *
2388  * Results:
2389  *      A pointer to the new Type structure or
2390  *      NULL if terminated due to an error.
2391  *
2392  * Side effects:
2393  *      None.
2394  *
2395  *----------------------------------------------------------------------
2396  */
2397
2398 Type *duplicateType(Type *templatePtr, TypeFlags flags, Parser *parserPtr)
2399 {
2400     Type                  *typePtr;
2401     Module                *modulePtr;
2402     
2403     typePtr = (Type *) smiMalloc(sizeof(Type));
2404
2405     modulePtr = parserPtr->modulePtr;
2406     
2407     typePtr->export.name                = NULL;
2408     typePtr->export.basetype            = templatePtr->export.basetype;
2409     typePtr->export.decl                = SMI_DECL_IMPLICIT_TYPE;
2410     typePtr->export.format              = NULL;
2411     typePtr->export.value.basetype      = SMI_BASETYPE_UNKNOWN;
2412     typePtr->export.units               = NULL;
2413     typePtr->export.status              = templatePtr->export.status;
2414     typePtr->export.description         = NULL;
2415     typePtr->export.reference           = NULL;
2416
2417     typePtr->modulePtr                  = modulePtr;
2418     typePtr->listPtr                    = NULL;
2419     typePtr->flags                      = templatePtr->flags;
2420     typePtr->line                       = parserPtr ? parserPtr->line : -1;
2421
2422     typePtr->nextPtr                    = NULL;
2423     typePtr->prevPtr                    = modulePtr->lastTypePtr;
2424     if (!modulePtr->firstTypePtr)
2425         modulePtr->firstTypePtr         = typePtr;
2426     if (modulePtr->lastTypePtr)
2427         modulePtr->lastTypePtr->nextPtr = typePtr;
2428     modulePtr->lastTypePtr              = typePtr;
2429
2430     setTypeParent(typePtr, templatePtr);
2431     
2432     return (typePtr);
2433 }
2434
2435
2436
2437 /*
2438  *----------------------------------------------------------------------
2439  *
2440  * setTypeName --
2441  *
2442  *      Set the name of a given Type. If it already exists, merge the
2443  *      two types.
2444  *
2445  * Results:
2446  *      None.
2447  *
2448  * Side effects:
2449  *      None.
2450  *
2451  *----------------------------------------------------------------------
2452  */
2453
2454 Type *setTypeName(Type *typePtr, char *name)
2455 {
2456     Type              *type2Ptr;
2457     List              *listPtr;
2458     
2459     if (typePtr->export.name) {
2460         smiFree(typePtr->export.name);
2461     }
2462     typePtr->export.name = smiStrdup(name);
2463
2464     if (! typePtr->export.name) {
2465         return typePtr;
2466     }
2467         
2468     /*
2469      * If a type with this name already exists, it must be a forward
2470      * reference and both types have to be merged.
2471      */
2472     for (type2Ptr = typePtr->modulePtr->firstTypePtr; type2Ptr;
2473          type2Ptr = type2Ptr->nextPtr) {
2474
2475         if (type2Ptr->export.name &&
2476             (!strcmp(type2Ptr->export.name, name)) &&
2477             (type2Ptr != typePtr)) {
2478
2479             /*
2480              * remove typePtr from the type list.
2481              */
2482             if (typePtr->prevPtr) {
2483                 typePtr->prevPtr->nextPtr = typePtr->nextPtr;
2484             } else {
2485                 typePtr->modulePtr->firstTypePtr = typePtr->nextPtr;
2486             }
2487             if (typePtr->nextPtr) {
2488                 typePtr->nextPtr->prevPtr = typePtr->prevPtr;
2489             } else {
2490                 typePtr->modulePtr->lastTypePtr = typePtr->prevPtr;
2491             }
2492
2493             type2Ptr->export.basetype     = typePtr->export.basetype;
2494             type2Ptr->export.decl         = typePtr->export.decl;
2495             type2Ptr->export.format       = typePtr->export.format;
2496             type2Ptr->export.value        = typePtr->export.value;
2497             type2Ptr->export.units        = typePtr->export.units;
2498             type2Ptr->export.status       = typePtr->export.status;
2499             type2Ptr->export.description  = typePtr->export.description;
2500             type2Ptr->export.reference    = typePtr->export.reference;
2501             
2502             type2Ptr->parentPtr    = typePtr->parentPtr;
2503             type2Ptr->listPtr      = typePtr->listPtr;
2504             type2Ptr->flags        = typePtr->flags;
2505             type2Ptr->line         = typePtr->line;
2506
2507             /*
2508              * if it's an enum or bits type, we also have to adjust
2509              * the references from the named numbers back to the type.
2510              */
2511             if ((type2Ptr->export.basetype == SMI_BASETYPE_ENUM) ||
2512                 (type2Ptr->export.basetype == SMI_BASETYPE_BITS)) {
2513                 for (listPtr = type2Ptr->listPtr; listPtr;
2514                      listPtr = listPtr->nextPtr) {
2515                     ((NamedNumber *)(listPtr->ptr))->typePtr = type2Ptr;
2516                 }
2517             }
2518             
2519             smiFree(typePtr->export.name);
2520             smiFree(typePtr);
2521
2522             return type2Ptr;
2523         }
2524     }
2525     return typePtr;
2526 }
2527
2528
2529
2530 /*
2531  *----------------------------------------------------------------------
2532  *
2533  * setTypeParent --
2534  *
2535  *      Set the parent of a given Type.
2536  *
2537  * Results:
2538  *      None.
2539  *
2540  * Side effects:
2541  *      None.
2542  *
2543  *----------------------------------------------------------------------
2544  */
2545
2546 void setTypeParent(Type *typePtr, Type *parentPtr)
2547 {
2548     typePtr->parentPtr = parentPtr;
2549 }
2550
2551
2552
2553 /*
2554  *----------------------------------------------------------------------
2555  *
2556  * setTypeStatus --
2557  *
2558  *      Set the status of a given Type.
2559  *
2560  * Results:
2561  *      None.
2562  *
2563  * Side effects:
2564  *      None.
2565  *
2566  *----------------------------------------------------------------------
2567  */
2568
2569 void setTypeStatus(Type *typePtr, SmiStatus status)
2570 {
2571     typePtr->export.status = status;
2572 }
2573
2574
2575
2576 /*
2577  *----------------------------------------------------------------------
2578  *
2579  * setTypeBasetype --
2580  *
2581  *      Set the basetype of a given Type.
2582  *
2583  * Results:
2584  *      None.
2585  *
2586  * Side effects:
2587  *      None.
2588  *
2589  *----------------------------------------------------------------------
2590  */
2591
2592 void setTypeBasetype(Type *typePtr, SmiBasetype basetype)
2593 {
2594     typePtr->export.basetype = basetype;
2595 }
2596
2597
2598
2599 /*
2600  *----------------------------------------------------------------------
2601  *
2602  * setTypeDescription --
2603  *
2604  *      Set the description of a given Type.
2605  *
2606  * Results:
2607  *      None.
2608  *
2609  * Side effects:
2610  *      None.
2611  *
2612  *----------------------------------------------------------------------
2613  */
2614
2615 void setTypeDescription(Type *typePtr, char *description, Parser *parserPtr)
2616 {
2617     if (typePtr->export.description)
2618         smiFree(typePtr->export.description);
2619     if (parserPtr->flags & SMI_FLAG_NODESCR) {
2620         smiFree(description);
2621         typePtr->export.description = NULL;
2622     } else {
2623         typePtr->export.description = description;
2624     }
2625 }
2626
2627
2628
2629 /*
2630  *----------------------------------------------------------------------
2631  *
2632  * setTypeReference --
2633  *
2634  *      Set the reference of a given Type.
2635  *
2636  * Results:
2637  *      None.
2638  *
2639  * Side effects:
2640  *      None.
2641  *
2642  *----------------------------------------------------------------------
2643  */
2644
2645 void setTypeReference(Type *typePtr, char *reference, Parser *parserPtr)
2646 {
2647     if (typePtr->export.reference)
2648         smiFree(typePtr->export.reference);
2649     if (parserPtr->flags & SMI_FLAG_NODESCR) {
2650         smiFree(reference);
2651         typePtr->export.reference = NULL;
2652     } else {
2653         typePtr->export.reference = reference;
2654     }
2655 }
2656
2657
2658
2659 /*
2660  *----------------------------------------------------------------------
2661  *
2662  * setTypeList --
2663  *
2664  *      Set the pointer to a struct list. This used for
2665  *      - columns of a SEQUENCE type,
2666  *      - enumeration items of an enumeration integer type,
2667  *      - min-max pair items of a range restricted type,
2668  *      - min-max pars items of a size restricted type.
2669  *
2670  * Results:
2671  *      None.
2672  *
2673  * Side effects:
2674  *      None.
2675  *
2676  *----------------------------------------------------------------------
2677  */
2678
2679 void setTypeList(Type *typePtr, List *listPtr)
2680 {
2681     if (!typePtr->listPtr) {
2682         typePtr->listPtr  = listPtr;
2683     }
2684 }
2685
2686
2687
2688 /*
2689  *----------------------------------------------------------------------
2690  *
2691  * setTypeFormat --
2692  *
2693  *      Set the format (displayHint) of a given Type.
2694  *
2695  * Results:
2696  *      None.
2697  *
2698  * Side effects:
2699  *      None.
2700  *
2701  *----------------------------------------------------------------------
2702  */
2703
2704 void setTypeFormat(Type *typePtr, char *format)
2705 {
2706     if (typePtr->export.format) smiFree(typePtr->export.format);
2707     typePtr->export.format = format;
2708 }
2709
2710
2711
2712 /*
2713  *----------------------------------------------------------------------
2714  *
2715  * setTypeUnits --
2716  *
2717  *      Set the units of a given Type. Note: units of types are only
2718  *      present in SMIng, not in SMIv2.
2719  *
2720  * Results:
2721  *      None.
2722  *
2723  * Side effects:
2724  *      None.
2725  *
2726  *----------------------------------------------------------------------
2727  */
2728
2729 void setTypeUnits(Type *typePtr, char *units)
2730 {
2731     if (typePtr->export.units) smiFree(typePtr->export.units);
2732     typePtr->export.units = units;
2733 }
2734
2735
2736
2737 /*
2738  *----------------------------------------------------------------------
2739  *
2740  * setTypeDecl --
2741  *
2742  *      Set the declaring macro of a given Type.
2743  *
2744  * Results:
2745  *      None.
2746  *
2747  * Side effects:
2748  *      None.
2749  *
2750  *----------------------------------------------------------------------
2751  */
2752
2753 void setTypeDecl(Type *typePtr, SmiDecl decl)
2754 {
2755     typePtr->export.decl = decl;
2756 }
2757
2758
2759
2760 /*
2761  *----------------------------------------------------------------------
2762  *
2763  * setTypeLine --
2764  *
2765  *      Set the line of definition of a given Type.
2766  *
2767  * Results:
2768  *      None.
2769  *
2770  * Side effects:
2771  *      None.
2772  *
2773  *----------------------------------------------------------------------
2774  */
2775
2776 void setTypeLine(Type *typePtr, int line, Parser *parserPtr)
2777 {
2778     if (line) {
2779         typePtr->line = line;
2780     } else {
2781         typePtr->line = parserPtr ? parserPtr->line : -1;
2782     }
2783 }
2784
2785
2786
2787 /*
2788  *----------------------------------------------------------------------
2789  *
2790  * setTypeValue --
2791  *
2792  *      Set the default value pointer of a given Type.
2793  *
2794  * Results:
2795  *      None.
2796  *
2797  * Side effects:
2798  *      None.
2799  *
2800  *----------------------------------------------------------------------
2801  */
2802
2803 void setTypeValue(Type *typePtr, SmiValue *valuePtr)
2804 {
2805     typePtr->export.value = *valuePtr;
2806 }
2807
2808
2809
2810 /*
2811  *----------------------------------------------------------------------
2812  *
2813  * addTypeFlags --
2814  *
2815  *      Add flags to the flags of a given Type.
2816  *
2817  * Results:
2818  *      None.
2819  *
2820  * Side effects:
2821  *      None.
2822  *
2823  *----------------------------------------------------------------------
2824  */
2825
2826 void addTypeFlags(Type *typePtr, TypeFlags flags)
2827 {
2828     typePtr->flags |= flags;
2829 }
2830
2831
2832
2833 /*
2834  *----------------------------------------------------------------------
2835  *
2836  * deleteTypeFlags --
2837  *
2838  *      Delete flags from the flags of a given Type.
2839  *
2840  * Results:
2841  *      None.
2842  *
2843  * Side effects:
2844  *      None.
2845  *
2846  *----------------------------------------------------------------------
2847  */
2848
2849 void deleteTypeFlags(Type *typePtr, TypeFlags flags)
2850 {
2851     typePtr->flags &= ~flags;
2852 }
2853
2854
2855
2856 /*
2857  *----------------------------------------------------------------------
2858  *
2859  * findTypeByName --
2860  *
2861  *      Lookup a Type by a given name.
2862  *
2863  * Results:
2864  *      A pointer to the Type structure or
2865  *      NULL if it is not found.
2866  *
2867  * Side effects:
2868  *      None.
2869  *
2870  *----------------------------------------------------------------------
2871  */
2872
2873 Type * findTypeByName(const char *type_name)
2874 {
2875     Module *modulePtr;
2876     Type   *typePtr;
2877     
2878     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
2879          modulePtr = modulePtr->nextPtr) {
2880         for (typePtr = modulePtr->firstTypePtr; typePtr;
2881              typePtr = typePtr->nextPtr) {
2882             if ((typePtr->export.name) &&
2883                 !strcmp(typePtr->export.name, type_name)) {
2884                 return (typePtr);
2885             }
2886         }
2887     }
2888
2889     return (NULL);
2890 }
2891
2892
2893
2894 /*
2895  *----------------------------------------------------------------------
2896  *
2897  * findNextTypeByName --
2898  *
2899  *      Lookup the next Type by a given name.
2900  *
2901  * Results:
2902  *      A pointer to the Type structure or
2903  *      NULL if it is not found.
2904  *
2905  * Side effects:
2906  *      None.
2907  *
2908  *----------------------------------------------------------------------
2909  */
2910
2911 Type *findNextTypeByName(const char *type_name, Type *prevTypePtr)
2912 {
2913     Module *modulePtr;
2914     Type   *typePtr;
2915     
2916     for (modulePtr = prevTypePtr->modulePtr->nextPtr; modulePtr;
2917          modulePtr = modulePtr->nextPtr) {
2918         for (typePtr = modulePtr->firstTypePtr; typePtr;
2919              typePtr = typePtr->nextPtr) {
2920             if ((typePtr->export.name) &&
2921                 !strcmp(typePtr->export.name, type_name)) {
2922                 return (typePtr);
2923             }
2924         }
2925     }
2926
2927     return (NULL);
2928 }
2929
2930
2931
2932 /*
2933  *----------------------------------------------------------------------
2934  *
2935  * findTypeByModulenameAndName --
2936  *
2937  *      Lookup a Type by a given Module and name.
2938  *
2939  * Results:
2940  *      A pointer to the Type structure or
2941  *      NULL if it is not found.
2942  *
2943  * Side effects:
2944  *      None.
2945  *
2946  *----------------------------------------------------------------------
2947  */
2948
2949 Type *findTypeByModulenameAndName(const char *modulename,
2950                                   const char *type_name)
2951 {
2952     Type       *typePtr;
2953     Module     *modulePtr;
2954
2955     modulePtr = findModuleByName(modulename);
2956
2957     if (modulePtr) {
2958         for (typePtr = modulePtr->firstTypePtr; typePtr;
2959              typePtr = typePtr->nextPtr) {
2960             if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) {
2961                 return (typePtr);
2962             }
2963         }
2964     }
2965         
2966     return (NULL);
2967 }
2968
2969
2970
2971 /*
2972  *----------------------------------------------------------------------
2973  *
2974  * findTypeByModuleAndName --
2975  *
2976  *      Lookup a Type by a given Module and name.
2977  *
2978  * Results:
2979  *      A pointer to the Type structure or
2980  *      NULL if it is not found.
2981  *
2982  * Side effects:
2983  *      None.
2984  *
2985  *----------------------------------------------------------------------
2986  */
2987
2988 Type *findTypeByModuleAndName(Module *modulePtr, const char *type_name)
2989 {
2990     Type        *typePtr;
2991
2992     if (modulePtr) {
2993         for (typePtr = modulePtr->firstTypePtr; typePtr;
2994              typePtr = typePtr->nextPtr) {
2995             if ((typePtr->export.name) &&
2996                 !strcmp(typePtr->export.name, type_name)) {
2997                 return (typePtr);
2998             }
2999         }
3000     }
3001
3002     return (NULL);
3003 }
3004
3005
3006
3007 /*
3008  *----------------------------------------------------------------------
3009  *
3010  * findTypeNamedNumber --
3011  *
3012  *      
3013  *
3014  * Results:
3015  *
3016  * Side effects:
3017  *
3018  *---------------------------------------------------------------------- */
3019
3020 NamedNumber *findTypeNamedNumber(Type *typePtr,
3021                                  SmiInteger32 number)
3022 {
3023     List *listPtr;
3024     
3025     for (listPtr = typePtr->listPtr;
3026          listPtr; listPtr = listPtr->nextPtr) {
3027         if (((NamedNumber *)(listPtr->ptr))->export.value.value.integer32 ==
3028             number)
3029             break;
3030     }
3031
3032     return (NamedNumber *)(listPtr->ptr);
3033 }
3034
3035
3036
3037 /*
3038  *----------------------------------------------------------------------
3039  *
3040  * addIdentity --
3041  *
3042  *      Create a new Identity structure.
3043  *
3044  * Results:
3045  *      A pointer to the new Identity structure or
3046  *      NULL if terminated due to an error.
3047  *
3048  * Side effects:
3049  *      None.
3050  *
3051  *---------------------------------------------------------------------- */
3052
3053 Identity *addIdentity(char *identityname, Parser *parserPtr)
3054 {
3055         Identity  *identityPtr;
3056     Module        *modulePtr;
3057     
3058     modulePtr = parserPtr->modulePtr;
3059     
3060     identityPtr = (Identity*) smiMalloc(sizeof(Identity));
3061     
3062     identityPtr->export.name = identityname;
3063     identityPtr->export.status      = SMI_STATUS_UNKNOWN;
3064     identityPtr->export.description = NULL;
3065     identityPtr->export.reference   = NULL;
3066         identityPtr->parentPtr   = NULL;
3067         
3068     identityPtr->modulePtr              = parserPtr->modulePtr;
3069     identityPtr->line                           = parserPtr ? parserPtr->line : -1;
3070     
3071     identityPtr->nextPtr                        = NULL;
3072     identityPtr->prevPtr                        = modulePtr->lastIdentityPtr;
3073     if (!modulePtr->firstIdentityPtr)
3074                 modulePtr->firstIdentityPtr     = identityPtr;
3075     if (modulePtr->lastIdentityPtr)
3076                 modulePtr->lastIdentityPtr->nextPtr     = identityPtr;
3077     modulePtr->lastIdentityPtr          = identityPtr;
3078     
3079     return (identityPtr);
3080     
3081 }
3082
3083 /*
3084  *----------------------------------------------------------------------
3085  *
3086  * setIdentityDecl --
3087  *
3088  *      Set the declaring macro of a given Identity.
3089  *
3090  * Results:
3091  *      None.
3092  *
3093  * Side effects:
3094  *      None.
3095  *
3096  *----------------------------------------------------------------------
3097  */
3098
3099 void setIdentityDecl(Identity *identityPtr, SmiDecl decl)
3100 {
3101     identityPtr->export.decl = decl;
3102 }
3103
3104 /*
3105  *----------------------------------------------------------------------
3106  *
3107  * setIdentityStatus --
3108  *
3109  *      Set the status of a given Identity.
3110  *
3111  * Results:
3112  *      None.
3113  *
3114  * Side effects:
3115  *      None.
3116  *
3117  *----------------------------------------------------------------------
3118  */
3119
3120 void setIdentityStatus(Identity *identityPtr, SmiStatus status)
3121 {
3122     identityPtr->export.status = status;
3123 }
3124
3125
3126
3127 /*
3128  *----------------------------------------------------------------------
3129  *
3130  * setIdentityDescription --
3131  *
3132  *      Set the description of a given Identity.
3133  *
3134  * Results:
3135  *      None.
3136  *
3137  * Side effects:
3138  *      None.
3139  *
3140  *----------------------------------------------------------------------
3141  */
3142
3143 void setIdentityDescription(Identity *identityPtr, char *description, Parser *parserPtr)
3144 {
3145     if (identityPtr->export.description) smiFree(identityPtr->export.description);
3146     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3147         smiFree(description);
3148         identityPtr->export.description = NULL;
3149     } else {
3150         identityPtr->export.description = description;
3151     }
3152 }
3153
3154
3155
3156 /*
3157  *----------------------------------------------------------------------
3158  *
3159  * setIdentityReference --
3160  *
3161  *      Set the reference of a given Identity.
3162  *
3163  * Results:
3164  *      None.
3165  *
3166  * Side effects:
3167  *      None.
3168  *
3169  *----------------------------------------------------------------------
3170  */
3171
3172 void setIdentityReference(Identity *identityPtr, char *reference, Parser *parserPtr)
3173 {
3174     if (identityPtr->export.reference)
3175         smiFree(identityPtr->export.reference);
3176     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3177         smiFree(reference);
3178         identityPtr->export.reference = NULL;
3179     } else {
3180         identityPtr->export.reference = reference;
3181     }
3182 }
3183
3184 /*
3185  *----------------------------------------------------------------------
3186  *
3187  * setIdentityParent --
3188  *
3189  *      Set the parent of a given Identity to given Identity pointer.
3190  *
3191  * Results:
3192  *      None.
3193  *
3194  * Side effects:
3195  *      None.
3196  *
3197  *----------------------------------------------------------------------
3198  */
3199
3200 void setIdentityParent(Identity *identityPtr, Identity *parentPtr)
3201 {
3202     if(identityPtr) identityPtr->parentPtr = parentPtr;
3203 }
3204
3205
3206 /*
3207  *----------------------------------------------------------------------
3208  *
3209  * findIdentityByName --
3210  *
3211  *      Lookup a Identity by a given name.
3212  *
3213  * Results:
3214  *      A pointer to the Identity structure or
3215  *      NULL if it is not found.
3216  *
3217  * Side effects:
3218  *      None.
3219  *
3220  *----------------------------------------------------------------------
3221  */
3222
3223 Identity *findIdentityByName(const char *identityname)
3224 {
3225     Module *modulePtr;
3226     Identity   *identityPtr;
3227     
3228     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
3229          modulePtr = modulePtr->nextPtr) {
3230         for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3231              identityPtr = identityPtr->nextPtr) {
3232             if ((identityPtr->export.name) &&
3233                 !strcmp(identityPtr->export.name, identityname)) {
3234                 return (identityPtr);
3235             }
3236         }
3237     }
3238
3239     return (NULL);
3240 }
3241
3242 /*
3243  *----------------------------------------------------------------------
3244  *
3245  * findIdentityByModuleAndName --
3246  *
3247  *      Lookup a Identity by a given name and Module.
3248  *
3249  * Results:
3250  *      A pointer to the Identity structure or
3251  *      NULL if it is not found.
3252  *
3253  * Side effects:
3254  *      None.
3255  *
3256  *----------------------------------------------------------------------
3257  */
3258
3259 Identity *findIdentityByModuleAndName(Module *modulePtr,
3260                                                                         const char *identityname)
3261 {
3262     Identity   *identityPtr;
3263     
3264     
3265         for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3266              identityPtr = identityPtr->nextPtr) {
3267             if ((identityPtr->export.name) &&
3268                 !strcmp(identityPtr->export.name, identityname)) {
3269                 return (identityPtr);
3270             }
3271         }
3272
3273
3274     return (NULL);
3275 }
3276
3277 /*
3278  *----------------------------------------------------------------------
3279  *
3280  * findIdentityByModulenameAndName --
3281  *
3282  *      Lookup a Identity by a given Module and name.
3283  *
3284  * Results:
3285  *      A pointer to the Identity structure or
3286  *      NULL if it is not found.
3287  *
3288  * Side effects:
3289  *      None.
3290  *
3291  *----------------------------------------------------------------------
3292  */
3293
3294 Identity *findIdentityByModulenameAndName(const char *modulename,
3295                                   const char *identity_name)
3296 {
3297     Identity       *identityPtr;
3298     Module     *modulePtr;
3299
3300     modulePtr = findModuleByName(modulename);
3301
3302     if (modulePtr) {
3303         for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3304              identityPtr = identityPtr->nextPtr) {
3305             if ((identityPtr->export.name) && !strcmp(identityPtr->export.name, identity_name)) {
3306                 return (identityPtr);
3307             }
3308         }
3309     }
3310         
3311     return (NULL);
3312 }
3313
3314
3315
3316 /*
3317  *----------------------------------------------------------------------
3318  *
3319  * addClass --
3320  *
3321  *      Create a new Class structure.
3322  *
3323  * Results:
3324  *      A pointer to the new Class structure or
3325  *      NULL if terminated due to an error.
3326  *
3327  * Side effects:
3328  *      None.
3329  *
3330  *---------------------------------------------------------------------- */
3331
3332 Class *addClass(char *classname, Parser *parserPtr)
3333 {
3334         Class  *classPtr;
3335     Module        *modulePtr;
3336     
3337     modulePtr = parserPtr->modulePtr;
3338     
3339     classPtr = (Class*) smiMalloc(sizeof(Class));
3340     
3341     classPtr->export.name = classname;
3342     classPtr->export.status      = SMI_STATUS_UNKNOWN;
3343     classPtr->export.description = NULL;
3344     classPtr->export.reference   = NULL;
3345    
3346     classPtr->modulePtr                 = parserPtr->modulePtr;
3347     classPtr->line                              = parserPtr ? parserPtr->line : -1;
3348     
3349     classPtr->parentPtr                 = NULL;
3350     classPtr->firstAttributePtr = NULL;
3351     classPtr->lastAttributePtr  = NULL;
3352     classPtr->firstEventPtr     = NULL;
3353     classPtr->lastEventPtr              = NULL;
3354     
3355     classPtr->nextPtr                   = NULL;
3356     classPtr->prevPtr                   = modulePtr->lastClassPtr;
3357     if (!modulePtr->firstClassPtr)
3358                 modulePtr->firstClassPtr        = classPtr;
3359     if (modulePtr->lastClassPtr)
3360                 modulePtr->lastClassPtr->nextPtr        = classPtr;
3361     modulePtr->lastClassPtr             = classPtr;
3362     
3363     return (classPtr);
3364     
3365 }
3366
3367 /*
3368  *----------------------------------------------------------------------
3369  *
3370  * setClassDecl --
3371  *
3372  *      Set the declaring macro of a given Class.
3373  *
3374  * Results:
3375  *      None.
3376  *
3377  * Side effects:
3378  *      None.
3379  *
3380  *----------------------------------------------------------------------
3381  */
3382
3383 void setClassDecl(Class *classPtr, SmiDecl decl)
3384 {
3385     classPtr->export.decl = decl;
3386 }
3387
3388 /*
3389  *----------------------------------------------------------------------
3390  *
3391  * setClassStatus --
3392  *
3393  *      Set the status of a given Class.
3394  *
3395  * Results:
3396  *      None.
3397  *
3398  * Side effects:
3399  *      None.
3400  *
3401  *----------------------------------------------------------------------
3402  */
3403
3404 void setClassStatus(Class *classPtr, SmiStatus status)
3405 {
3406     classPtr->export.status = status;
3407 }
3408
3409
3410
3411 /*
3412  *----------------------------------------------------------------------
3413  *
3414  * setClassDescription --
3415  *
3416  *      Set the description of a given Class.
3417  *
3418  * Results:
3419  *      None.
3420  *
3421  * Side effects:
3422  *      None.
3423  *
3424  *----------------------------------------------------------------------
3425  */
3426
3427 void setClassDescription(Class *classPtr, char *description, Parser *parserPtr)
3428 {
3429     if (classPtr->export.description) smiFree(classPtr->export.description);
3430     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3431         smiFree(description);
3432         classPtr->export.description = NULL;
3433     } else {
3434         classPtr->export.description = description;
3435     }
3436 }
3437
3438
3439
3440 /*
3441  *----------------------------------------------------------------------
3442  *
3443  * setClassReference --
3444  *
3445  *      Set the reference of a given Class.
3446  *
3447  * Results:
3448  *      None.
3449  *
3450  * Side effects:
3451  *      None.
3452  *
3453  *----------------------------------------------------------------------
3454  */
3455
3456 void setClassReference(Class *classPtr, char *reference, Parser *parserPtr)
3457 {
3458     if (classPtr->export.reference)
3459         smiFree(classPtr->export.reference);
3460     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3461         smiFree(reference);
3462         classPtr->export.reference = NULL;
3463     } else {
3464         classPtr->export.reference = reference;
3465     }
3466 }
3467
3468 /*
3469  *----------------------------------------------------------------------
3470  *
3471  * setClassParent --
3472  *
3473  *      Set the parent of a given Class to given Class pointer.
3474  *
3475  * Results:
3476  *      None.
3477  *
3478  * Side effects:
3479  *      None.
3480  *
3481  *----------------------------------------------------------------------
3482  */
3483
3484 void setClassParent(Class *classPtr, Class *parentPtr)
3485 {
3486     if(classPtr) classPtr->parentPtr = parentPtr;
3487 }
3488
3489 /*
3490  *----------------------------------------------------------------------
3491  *
3492  * findClassByModuleAndName --
3493  *
3494  *      Lookup a Class by a given name.
3495  *
3496  * Results:
3497  *      A pointer to the Class structure or
3498  *      NULL if it is not found.
3499  *
3500  * Side effects:
3501  *      None.
3502  *
3503  *----------------------------------------------------------------------
3504  */
3505 Class *findClassByModuleAndName(Module *modulePtr,char *name)
3506 {
3507     Class   *classPtr;
3508     
3509         for (classPtr = modulePtr->firstClassPtr; classPtr;
3510              classPtr = classPtr->nextPtr) {
3511             if ((classPtr->export.name) &&
3512                 !strcmp(classPtr->export.name, name)) {
3513                 return (classPtr);
3514             }
3515         }
3516
3517     return NULL;
3518 }
3519
3520 /*
3521  *----------------------------------------------------------------------
3522  *
3523  * findClassByModulenameAndName --
3524  *
3525  *      Lookup a Class by a given Module and name.
3526  *
3527  * Results:
3528  *      A pointer to the Class structure or
3529  *      NULL if it is not found.
3530  *
3531  * Side effects:
3532  *      None.
3533  *
3534  *----------------------------------------------------------------------
3535  */
3536
3537 Class *findClassByModulenameAndName(const char *modulename,
3538                                   const char *class_name)
3539 {
3540     Class       *classPtr;
3541     Module     *modulePtr;
3542
3543     modulePtr = findModuleByName(modulename);
3544
3545     if (modulePtr) {
3546         for (classPtr = modulePtr->firstClassPtr; classPtr;
3547              classPtr = classPtr->nextPtr) {
3548             if ((classPtr->export.name) && !strcmp(classPtr->export.name, class_name)) {
3549                 return (classPtr);
3550             }
3551         }
3552     }
3553         
3554     return (NULL);
3555 }
3556
3557 /*
3558  *----------------------------------------------------------------------
3559  *
3560  * duplicateTypeToAttribute --
3561  *
3562  *      Create a new Attribute as a duplicate of a given type but with
3563  *      an affiliation to the given Class.
3564  *
3565  * Results:
3566  *      A pointer to the new Attribute structure or
3567  *      NULL if terminated due to an error.
3568  *
3569  * Side effects:
3570  *      None.
3571  *
3572  *----------------------------------------------------------------------
3573  */
3574
3575 Attribute *duplicateTypeToAttribute(Type *templatePtr, Class *classPtr, Parser *parserPtr)
3576 {
3577     Attribute             *attributePtr;
3578     
3579     if(!classPtr) return NULL;
3580     
3581     attributePtr = (Attribute *) smiMalloc(sizeof(Attribute));
3582
3583     
3584     attributePtr->export.name           = NULL;
3585     attributePtr->export.basetype               = templatePtr->export.basetype;
3586     attributePtr->export.decl           = SMI_DECL_ATTRIBUTE;
3587     attributePtr->export.format         = NULL;
3588     attributePtr->export.value.basetype = templatePtr->export.basetype;
3589     attributePtr->export.units          = NULL;
3590     attributePtr->export.status         = templatePtr->export.status;
3591     attributePtr->export.description            = NULL;
3592     attributePtr->export.reference              = NULL;
3593
3594     attributePtr->classPtr                      = classPtr;
3595     attributePtr->listPtr                       = NULL;
3596     attributePtr->line                  = parserPtr ? parserPtr->line : -1;
3597
3598     attributePtr->nextPtr                       = NULL;
3599     attributePtr->prevPtr                       = classPtr->lastAttributePtr;
3600     if (!classPtr->firstAttributePtr)
3601         classPtr->firstAttributePtr             = attributePtr;
3602     if (classPtr->lastAttributePtr)
3603         classPtr->lastAttributePtr->nextPtr     = attributePtr;
3604     classPtr->lastAttributePtr          = attributePtr;
3605
3606     setAttributeParentType(attributePtr, templatePtr);
3607     
3608     return (attributePtr);
3609 }
3610
3611
3612 /*
3613  *----------------------------------------------------------------------
3614  *
3615  * addAttribute --
3616  *
3617  *      Create a new Attribute structure and tie it to the given Class.
3618  *
3619  * Results:
3620  *      A pointer to the new Attribute structure or
3621  *      NULL if terminated due to an error.
3622  *
3623  * Side effects:
3624  *      None.
3625  *
3626  *----------------------------------------------------------------------
3627  */
3628
3629 Attribute *addAttribute(char *attribute_name,
3630               Class *classPtr, Parser *parserPtr)
3631 {
3632     Attribute      *attributePtr;
3633     
3634     attributePtr = smiMalloc(sizeof(Attribute));
3635
3636     attributePtr->export.name           = attribute_name;
3637         attributePtr->export.basetype           = SMI_BASETYPE_UNKNOWN;
3638     attributePtr->export.decl           = SMI_DECL_UNKNOWN;
3639     attributePtr->export.format         = NULL;
3640     attributePtr->export.value.basetype = SMI_BASETYPE_UNKNOWN;
3641     attributePtr->export.units          = NULL;
3642     attributePtr->export.status         = SMI_STATUS_UNKNOWN;
3643     attributePtr->export.description            = NULL;
3644     attributePtr->export.reference              = NULL;
3645
3646     attributePtr->classPtr                      = classPtr;
3647     attributePtr->listPtr                       = NULL;
3648     attributePtr->parentTypePtr     = NULL;
3649     attributePtr->parentClassPtr    = NULL;
3650     attributePtr->line                  = parserPtr ? parserPtr->line : -1;
3651     
3652     attributePtr->nextPtr                       = NULL;
3653     if (classPtr) {
3654         attributePtr->prevPtr           = classPtr->lastAttributePtr;
3655         if (!classPtr->firstAttributePtr)
3656             classPtr->firstAttributePtr = attributePtr;
3657         if (classPtr->lastAttributePtr)
3658             classPtr->lastAttributePtr->nextPtr = attributePtr;
3659         classPtr->lastAttributePtr              = attributePtr;
3660     } else {
3661         attributePtr->prevPtr           = NULL;
3662     }
3663         
3664     return (attributePtr);
3665 }
3666
3667 /*
3668  *----------------------------------------------------------------------
3669  *
3670  * setAttributeDecl --
3671  *
3672  *      Set the declaring macro of a given Attribute.
3673  *
3674  * Results:
3675  *      None.
3676  *
3677  * Side effects:
3678  *      None.
3679  *
3680  *----------------------------------------------------------------------
3681  */
3682
3683 void setAttributeDecl(Attribute *attributePtr, SmiDecl decl)
3684 {
3685     attributePtr->export.decl = decl;
3686 }
3687
3688 /*
3689  *----------------------------------------------------------------------
3690  *
3691  * setAttributeParentType --
3692  *
3693  *      Set the parent of a given attribute.
3694  *
3695  * Results:
3696  *      None.
3697  *
3698  * Side effects:
3699  *      None.
3700  *
3701  *----------------------------------------------------------------------
3702  */
3703
3704 void setAttributeParentType(Attribute *attributePtr, Type *parentPtr)
3705 {
3706     attributePtr->parentTypePtr = parentPtr;
3707 }
3708
3709 /*
3710  *----------------------------------------------------------------------
3711  *
3712  * setAttributeParentClass --
3713  *
3714  *      Set the parent Class of a given attribute.
3715  *
3716  * Results:
3717  *      None.
3718  *
3719  * Side effects:
3720  *      None.
3721  *
3722  *----------------------------------------------------------------------
3723  */
3724
3725 void setAttributeParentClass(Attribute *attributePtr, Class *parentPtr)
3726 {
3727     attributePtr->parentClassPtr = parentPtr;
3728 }
3729
3730 /*
3731  *----------------------------------------------------------------------
3732  *
3733  * setAttributeList --
3734  *
3735  *      Set the pointer to a struct list. This used for
3736  *      - enumeration items of an enumeration integer type,
3737  *      - min-max pair items of a range restricted type,
3738  *      - min-max pars items of a size restricted type.
3739  *
3740  * Results:
3741  *      None.
3742  *
3743  * Side effects:
3744  *      None.
3745  *
3746  *----------------------------------------------------------------------
3747  */
3748
3749 void setAttributeList(Attribute *attributePtr, List *listPtr)
3750 {
3751     if (!attributePtr->listPtr) {
3752         attributePtr->listPtr  = listPtr;
3753     }
3754 }
3755
3756 /*
3757  *----------------------------------------------------------------------
3758  *
3759  * setAttributeName --
3760  *
3761  *      Set the name of a given Attribute. 
3762  *
3763  * Results:
3764  *      None.
3765  *
3766  * Side effects:
3767  *      None.
3768  *
3769  *----------------------------------------------------------------------
3770  */
3771
3772 void setAttributeName(Attribute *attributePtr, char *name)
3773 {
3774     
3775     attributePtr->export.name = smiStrdup(name);
3776 }
3777
3778 /*
3779  *----------------------------------------------------------------------
3780  *
3781  * setAttributeAccess --
3782  *
3783  *      Set the access of a given Attribute. 
3784  *
3785  * Results:
3786  *      None.
3787  *
3788  * Side effects:
3789  *      None.
3790  *
3791  *----------------------------------------------------------------------
3792  */
3793 void setAttributeAccess(Attribute *attributePtr,SmiAccess access)
3794 {
3795         attributePtr->export.access = access;
3796 }
3797
3798
3799 /*
3800  *----------------------------------------------------------------------
3801  *
3802  * addEvent --
3803  *
3804  *      Create a new Event structure and tie it to the given Class.
3805  *
3806  * Results:
3807  *      A pointer to the new Event structure or
3808  *      NULL if terminated due to an error.
3809  *
3810  * Side effects:
3811  *      None.
3812  *
3813  *----------------------------------------------------------------------
3814  */
3815 Event *addEvent(char *eventname, Class *classPtr, 
3816                              Parser *parserPtr)
3817 {
3818     Event          *eventPtr;
3819     
3820    eventPtr = smiMalloc(sizeof(Event));
3821
3822         eventPtr->export.name       = eventname;
3823     eventPtr->export.decl               = SMI_DECL_EVENT;
3824     eventPtr->export.status     = SMI_STATUS_UNKNOWN;
3825     eventPtr->export.description                = NULL;
3826     eventPtr->export.reference          = NULL;
3827
3828     eventPtr->classPtr                  = classPtr;
3829     eventPtr->line                      = parserPtr ? parserPtr->line : -1;
3830     
3831     eventPtr->nextPtr                   = NULL;
3832     if (classPtr) {
3833         eventPtr->prevPtr               = classPtr->lastEventPtr;
3834         if (!classPtr->firstEventPtr)
3835             classPtr->firstEventPtr     = eventPtr;
3836         if (classPtr->lastEventPtr)
3837             classPtr->lastEventPtr->nextPtr = eventPtr;
3838         classPtr->lastEventPtr          = eventPtr;
3839     } else {
3840         eventPtr->prevPtr               = NULL;
3841     }
3842         
3843     return (eventPtr);
3844 }
3845
3846
3847
3848 /*
3849  *----------------------------------------------------------------------
3850  *
3851  * addMacro --
3852  *
3853  *      Create a new Macro structure.
3854  *
3855  * Results:
3856  *      A pointer to the new Macro structure or
3857  *      NULL if terminated due to an error.
3858  *
3859  * Side effects:
3860  *      None.
3861  *
3862  *---------------------------------------------------------------------- */
3863
3864 Macro *addMacro(char *macroname, MacroFlags flags, Parser *parserPtr)
3865 {
3866     Macro         *macroPtr;
3867     Module        *modulePtr;
3868     
3869     modulePtr = parserPtr->modulePtr;
3870     
3871     /* TODO: Check wheather this macro already exists?? */
3872
3873     macroPtr = (Macro *) smiMalloc(sizeof(Macro));
3874             
3875     macroPtr->export.name        = macroname;
3876     macroPtr->export.status      = SMI_STATUS_UNKNOWN;
3877     macroPtr->export.description = NULL;
3878     macroPtr->export.reference   = NULL;
3879
3880     macroPtr->modulePtr          = parserPtr->modulePtr;
3881     macroPtr->flags              = flags;
3882     macroPtr->line               = parserPtr ? parserPtr->line : -1;
3883     
3884     macroPtr->nextPtr                           = NULL;
3885     macroPtr->prevPtr                           = modulePtr->lastMacroPtr;
3886     if (!modulePtr->firstMacroPtr)
3887         modulePtr->firstMacroPtr                = macroPtr;
3888     if (modulePtr->lastMacroPtr)
3889         modulePtr->lastMacroPtr->nextPtr        = macroPtr;
3890     modulePtr->lastMacroPtr                     = macroPtr;
3891     
3892     return (macroPtr);
3893 }
3894
3895
3896
3897 /*
3898  *----------------------------------------------------------------------
3899  *
3900  * setMacroStatus --
3901  *
3902  *      Set the status of a given Macro.
3903  *
3904  * Results:
3905  *      None.
3906  *
3907  * Side effects:
3908  *      None.
3909  *
3910  *----------------------------------------------------------------------
3911  */
3912
3913 void setMacroStatus(Macro *macroPtr, SmiStatus status)
3914 {
3915     macroPtr->export.status = status;
3916 }
3917
3918
3919
3920 /*
3921  *----------------------------------------------------------------------
3922  *
3923  * setMacroDescription --
3924  *
3925  *      Set the description of a given Macro.
3926  *
3927  * Results:
3928  *      None.
3929  *
3930  * Side effects:
3931  *      None.
3932  *
3933  *----------------------------------------------------------------------
3934  */
3935
3936 void setMacroDescription(Macro *macroPtr, char *description, Parser *parserPtr)
3937 {
3938     if (macroPtr->export.description) smiFree(macroPtr->export.description);
3939     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3940         smiFree(description);
3941         macroPtr->export.description = NULL;
3942     } else {
3943         macroPtr->export.description = description;
3944     }
3945 }
3946
3947
3948
3949 /*
3950  *----------------------------------------------------------------------
3951  *
3952  * setMacroReference --
3953  *
3954  *      Set the reference of a given Macro.
3955  *
3956  * Results:
3957  *      None.
3958  *
3959  * Side effects:
3960  *      None.
3961  *
3962  *----------------------------------------------------------------------
3963  */
3964
3965 void setMacroReference(Macro *macroPtr, char *reference, Parser *parserPtr)
3966 {
3967     if (macroPtr->export.reference)
3968         smiFree(macroPtr->export.reference);
3969     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3970         smiFree(reference);
3971         macroPtr->export.reference = NULL;
3972     } else {
3973         macroPtr->export.reference = reference;
3974     }
3975 }
3976
3977 /*
3978  *----------------------------------------------------------------------
3979  *
3980  * setMacroAbnf --
3981  *
3982  *      Set the abnf string of a given extension(SMIng only).
3983  *
3984  * Results:
3985  *      None.
3986  *
3987  * Side effects:
3988  *      None.
3989  *
3990  *----------------------------------------------------------------------
3991  */
3992
3993 void setMacroAbnf(Macro *macroPtr, char *abnf, Parser *parserPtr)
3994 {
3995     if (macroPtr->export.abnf)
3996         smiFree(macroPtr->export.abnf);
3997     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3998         smiFree(abnf);
3999         macroPtr->export.abnf = NULL;
4000     } else {
4001         macroPtr->export.abnf = abnf;
4002     }
4003 }
4004
4005
4006
4007 /*
4008  *----------------------------------------------------------------------
4009  *
4010  * setMacroDecl --
4011  *
4012  *      Set the declaring macro of a given Macro.
4013  *
4014  * Results:
4015  *      None.
4016  *
4017  * Side effects:
4018  *      None.
4019  *
4020  *----------------------------------------------------------------------
4021  */
4022
4023 void setMacroDecl(Macro *macroPtr, SmiDecl decl)
4024 {
4025     macroPtr->export.decl = decl;
4026 }
4027
4028
4029
4030 /*
4031  *----------------------------------------------------------------------
4032  *
4033  * setMacroLine --
4034  *
4035  *      Set the line of definition of a given Macro.
4036  *
4037  * Results:
4038  *      None.
4039  *
4040  * Side effects:
4041  *      None.
4042  *
4043  *----------------------------------------------------------------------
4044  */
4045
4046 void setMacroLine(Macro *macroPtr, int line, Parser *parserPtr)
4047 {
4048     if (line) {
4049         macroPtr->line = line;
4050     } else {
4051         macroPtr->line = parserPtr ? parserPtr->line : -1;
4052     }
4053 }
4054
4055
4056
4057 /*
4058  *----------------------------------------------------------------------
4059  *
4060  * findMacroByName --
4061  *
4062  *      Lookup a Macro by a given name.
4063  *
4064  * Results:
4065  *      A pointer to the Macro structure or
4066  *      NULL if it is not found.
4067  *
4068  * Side effects:
4069  *      None.
4070  *
4071  *----------------------------------------------------------------------
4072  */
4073
4074 Macro *findMacroByName(const char *macroname)
4075 {
4076     Module *modulePtr;
4077     Macro   *macroPtr;
4078     
4079     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4080          modulePtr = modulePtr->nextPtr) {
4081         for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4082              macroPtr = macroPtr->nextPtr) {
4083             if ((macroPtr->export.name) &&
4084                 !strcmp(macroPtr->export.name, macroname)) {
4085                 return (macroPtr);
4086             }
4087         }
4088     }
4089
4090     return (NULL);
4091 }
4092
4093
4094
4095 /*
4096  *----------------------------------------------------------------------
4097  *
4098  * findMacroByModuleAndName --
4099  *
4100  *      Lookup a Macro by a given Module and name.
4101  *
4102  * Results:
4103  *      A pointer to the Macro structure or
4104  *      NULL if it is not found.
4105  *
4106  * Side effects:
4107  *      None.
4108  *
4109  *----------------------------------------------------------------------
4110  */
4111
4112 Macro *findMacroByModuleAndName(Module *modulePtr, const char *macroname)
4113 {
4114     Macro      *macroPtr;
4115     
4116     if (modulePtr) {
4117         for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4118              macroPtr = macroPtr->nextPtr) {
4119             if (!strcmp(macroPtr->export.name, macroname)) {
4120                 return (macroPtr);
4121             }
4122         }
4123     }
4124
4125     return (NULL);
4126 }
4127
4128
4129
4130 /*
4131  *----------------------------------------------------------------------
4132  *
4133  * findNamedNumberByName --
4134  *
4135  *      Lookup the value of a namev nuber in a given typ.
4136  *
4137  * Results:
4138  *      A pointer to the NamedNumber structure or
4139  *      NULL if it is not found.
4140  *
4141  * Side effects:
4142  *      None.
4143  *
4144  *----------------------------------------------------------------------
4145  */
4146
4147 NamedNumber *findNamedNumberByName(Type *typePtr,const char *name)
4148 {
4149         List *listPtr;
4150     
4151     if(typePtr->export.basetype != SMI_BASETYPE_ENUM && 
4152         typePtr->export.basetype != SMI_BASETYPE_BITS) return NULL;
4153         
4154     for (listPtr = typePtr->listPtr;
4155          listPtr; listPtr = listPtr->nextPtr) {
4156         if (!strcmp(((NamedNumber *)(listPtr->ptr))->export.name 
4157             , name))
4158             return (NamedNumber *)(listPtr->ptr);
4159     }
4160
4161     return NULL;
4162 }
4163
4164
4165
4166
4167
4168 /*
4169  *----------------------------------------------------------------------
4170  *
4171  * smiInitData --
4172  *
4173  *      Initialize all need data structures at program start.
4174  *
4175  * Results:
4176  *      0 on success or -1 on an error.
4177  *
4178  * Side effects:
4179  *      None.
4180  *
4181  *----------------------------------------------------------------------
4182  */
4183
4184 int smiInitData()
4185 {
4186     Object          *objectPtr;
4187     Parser          parser;
4188     
4189     smiHandle->flags = 0;
4190     
4191     smiHandle->firstModulePtr = NULL;
4192     smiHandle->lastModulePtr = NULL;
4193     smiHandle->firstViewPtr = NULL;
4194     smiHandle->lastViewPtr = NULL;
4195     
4196     /*
4197      * Initialize a root Node for the main MIB tree.
4198      */
4199     smiHandle->rootNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4200
4201     /*
4202      * Initialize a root Node for pending (forward referenced) nodes.
4203      */
4204     smiHandle->parserPtr = &parser;
4205     parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4206
4207     /*
4208      * Initialize the top level well-known nodes, ccitt, iso, joint-iso-ccitt
4209      * belonging to a dummy module "". This is needed for SMIv1/v2. SMIng
4210      * defines it in a special SMIng module.
4211      */
4212     parser.path                 = NULL;
4213     parser.flags                = smiHandle->flags;
4214     parser.file                 = NULL;
4215     parser.line                 = -1;
4216     parser.modulePtr = addModule(smiStrdup(""), smiStrdup(""), 0, NULL);
4217
4218     addView("");
4219
4220     objectPtr = addObject(smiStrdup("ccitt"), smiHandle->rootNodePtr, 0, 0, &parser);
4221     objectPtr->export.oid = objectPtr->nodePtr->oid =
4222         smiMalloc(sizeof(int));
4223     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4224     objectPtr->nodePtr->oid[0] = 0;
4225     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4226     objectPtr = addObject(smiStrdup("iso"), smiHandle->rootNodePtr, 1, 0, &parser);
4227     objectPtr->export.oid = objectPtr->nodePtr->oid =
4228         smiMalloc(sizeof(int));
4229     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4230     objectPtr->nodePtr->oid[0] = 1;
4231     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4232     objectPtr = addObject(smiStrdup("joint-iso-ccitt"), smiHandle->rootNodePtr, 2, 0, &parser);
4233     objectPtr->export.oid = objectPtr->nodePtr->oid =
4234         smiMalloc(sizeof(int));
4235     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4236     objectPtr->nodePtr->oid[0] = 2;
4237     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4238     
4239     
4240     smiHandle->typeOctetStringPtr =
4241         addType(smiStrdup("OctetString"),
4242                 SMI_BASETYPE_OCTETSTRING, 0, &parser);
4243     smiHandle->typeObjectIdentifierPtr =
4244         addType(smiStrdup("ObjectIdentifier"),
4245                 SMI_BASETYPE_OBJECTIDENTIFIER, 0, &parser);
4246     smiHandle->typeInteger32Ptr =
4247         addType(smiStrdup("Integer32"),
4248                 SMI_BASETYPE_INTEGER32, 0, &parser);
4249     smiHandle->typeUnsigned32Ptr =
4250         addType(smiStrdup("Unsigned32"),
4251                 SMI_BASETYPE_UNSIGNED32, 0, &parser);
4252     smiHandle->typeInteger64Ptr =
4253         addType(smiStrdup("Integer64"),
4254                 SMI_BASETYPE_INTEGER64, 0, &parser);
4255     smiHandle->typeUnsigned64Ptr =
4256         addType(smiStrdup("Unsigned64"),
4257                 SMI_BASETYPE_UNSIGNED64, 0, &parser);
4258     smiHandle->typeFloat32Ptr =
4259         addType(smiStrdup("Float32"),
4260                 SMI_BASETYPE_FLOAT32, 0, &parser);
4261     smiHandle->typeFloat64Ptr =
4262         addType(smiStrdup("Float64"),
4263                 SMI_BASETYPE_FLOAT64, 0, &parser);
4264     smiHandle->typeFloat128Ptr =
4265         addType(smiStrdup("Float128"),
4266                 SMI_BASETYPE_FLOAT128, 0, &parser);
4267     smiHandle->typeEnumPtr =
4268         addType(smiStrdup("Enumeration"),
4269                 SMI_BASETYPE_ENUM, 0, &parser);
4270     smiHandle->typeBitsPtr =
4271         addType(smiStrdup("Bits"),
4272                 SMI_BASETYPE_BITS, 0, &parser);
4273         smiHandle->typePointerPtr =
4274         addType(smiStrdup("Pointer"),
4275                 SMI_BASETYPE_POINTER, 0, &parser);
4276
4277     return (0);
4278 }
4279
4280
4281
4282 /*
4283  *----------------------------------------------------------------------
4284  *
4285  * freeNodeTree --
4286  *
4287  *      Free all node of a node (sub)tree.
4288  *
4289  * Results:
4290  *      0 on success or -1 on an error.
4291  *
4292  * Side effects:
4293  *      None.
4294  *
4295  *----------------------------------------------------------------------
4296  */
4297
4298 static void freeNodeTree(Node *rootPtr)
4299 {
4300     Node       *nodePtr, *nextPtr;
4301     
4302     for (nodePtr = rootPtr->firstChildPtr; nodePtr; nodePtr = nextPtr) {
4303         nextPtr = nodePtr->nextPtr;
4304         freeNodeTree(nodePtr);
4305         smiFree(nodePtr->oid);
4306         smiFree(nodePtr);
4307     }
4308     rootPtr->firstChildPtr = NULL;
4309     rootPtr->lastChildPtr = NULL;
4310     rootPtr->firstObjectPtr = NULL;
4311     rootPtr->lastObjectPtr = NULL;
4312     rootPtr->nextPtr = NULL;
4313     rootPtr->prevPtr = NULL;
4314     rootPtr->parentPtr = NULL;
4315 }
4316
4317
4318
4319 /*
4320  *----------------------------------------------------------------------
4321  *
4322  * smiFreeData --
4323  *
4324  *      Free all data structures.
4325  *
4326  * Results:
4327  *      0 on success or -1 on an error.
4328  *
4329  * Side effects:
4330  *      None.
4331  *
4332  *----------------------------------------------------------------------
4333  */
4334
4335 void smiFreeData()
4336 {
4337     View       *viewPtr, *nextViewPtr;
4338     Macro      *macroPtr, *nextMacroPtr;
4339     Module     *modulePtr, *nextModulePtr;
4340     Import     *importPtr, *nextImportPtr;
4341     Identity     *identityPtr, *nextIdentityPtr;
4342     Revision   *revisionPtr, *nextRevisionPtr;
4343     List       *listPtr, *nextListPtr;
4344     Type       *typePtr, *nextTypePtr;
4345     Class          *classPtr, *nextClassPtr;
4346     Attribute  *attributePtr, *nextAttributePtr;
4347     Event          *eventPtr,   *nextEventPtr;
4348     Object     *objectPtr, *nextObjectPtr;
4349
4350     for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = nextViewPtr) {
4351         nextViewPtr = viewPtr->nextPtr;
4352         smiFree(viewPtr->name);
4353         smiFree(viewPtr);
4354     }
4355
4356     /*
4357      * In this first module loop we remove each module's imports,
4358      * revisions, macros, and objects.
4359      */
4360     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4361          modulePtr = nextModulePtr) {
4362         nextModulePtr = modulePtr->nextPtr;
4363
4364         for (importPtr = modulePtr->firstImportPtr; importPtr;
4365              importPtr = nextImportPtr) {
4366             nextImportPtr = importPtr->nextPtr;
4367             smiFree(importPtr->export.module);
4368             smiFree(importPtr->export.name);
4369             smiFree(importPtr);
4370         }
4371
4372         for (revisionPtr = modulePtr->firstRevisionPtr; revisionPtr;
4373              revisionPtr = nextRevisionPtr) {
4374             nextRevisionPtr = revisionPtr->nextPtr;
4375             smiFree(revisionPtr->export.description);
4376             smiFree(revisionPtr);
4377         }
4378         
4379         for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4380              macroPtr = nextMacroPtr) {
4381             nextMacroPtr = macroPtr->nextPtr;
4382             smiFree(macroPtr->export.name);
4383             smiFree(macroPtr->export.abnf);
4384             smiFree(macroPtr->export.reference);
4385             smiFree(macroPtr->export.description);
4386             smiFree(macroPtr);
4387             
4388         }
4389         for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
4390              identityPtr = nextIdentityPtr) {
4391             nextIdentityPtr = identityPtr->nextPtr;
4392             smiFree(identityPtr->export.name);
4393             smiFree(identityPtr->export.reference);
4394             smiFree(identityPtr->export.description);
4395             smiFree(identityPtr);
4396         }
4397
4398         for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
4399              objectPtr = nextObjectPtr) {
4400
4401             nextObjectPtr = objectPtr->nextPtr;
4402             smiFree(objectPtr->export.name);
4403             smiFree(objectPtr->export.description);
4404             smiFree(objectPtr->export.reference);
4405             smiFree(objectPtr->export.format);
4406             smiFree(objectPtr->export.units);
4407             for (listPtr = objectPtr->listPtr; listPtr;
4408                  listPtr = nextListPtr) {
4409                 nextListPtr = listPtr->nextPtr;
4410                 smiFree(listPtr);
4411             }
4412             for (listPtr = objectPtr->optionlistPtr; listPtr;
4413                  listPtr = nextListPtr) {
4414                 nextListPtr = listPtr->nextPtr;
4415                 smiFree(((Option *)(listPtr->ptr))->export.description);
4416                 smiFree((Option *)(listPtr->ptr));
4417                 smiFree(listPtr);
4418             }
4419             for (listPtr = objectPtr->refinementlistPtr; listPtr;
4420                  listPtr = nextListPtr) {
4421                 nextListPtr = listPtr->nextPtr;
4422                 smiFree(((Refinement *)(listPtr->ptr))->export.description);
4423                 smiFree((Refinement *)(listPtr->ptr));
4424                 smiFree(listPtr);
4425             }
4426             if (objectPtr->typePtr) {
4427                 if ((objectPtr->typePtr->export.basetype ==
4428                      SMI_BASETYPE_OCTETSTRING ||
4429                      objectPtr->typePtr->export.basetype ==
4430                      SMI_BASETYPE_BITS)) {
4431                     smiFree(objectPtr->export.value.value.ptr);
4432                 } else if ((objectPtr->typePtr->export.basetype ==
4433                             SMI_BASETYPE_OBJECTIDENTIFIER) &&
4434                            (objectPtr->export.value.basetype ==
4435                             objectPtr->typePtr->export.basetype)) {
4436                     smiFree(objectPtr->export.value.value.oid);
4437                 } 
4438                 
4439             }
4440             smiFree(objectPtr);
4441             
4442             
4443             
4444             
4445         }
4446         
4447
4448         for (classPtr = modulePtr->firstClassPtr; classPtr;
4449              classPtr = nextClassPtr) {
4450
4451             nextClassPtr = classPtr->nextPtr;
4452                 for (attributePtr = classPtr->firstAttributePtr; attributePtr;
4453              attributePtr = nextAttributePtr) {
4454
4455             nextAttributePtr = attributePtr->nextPtr;
4456             
4457             for (listPtr = attributePtr->listPtr; listPtr;
4458                  listPtr = nextListPtr) {
4459                 nextListPtr = listPtr->nextPtr;
4460                 if ((attributePtr->export.basetype == SMI_BASETYPE_BITS) ||
4461                     (attributePtr->export.basetype == SMI_BASETYPE_ENUM)) {
4462                     smiFree(((NamedNumber *)(listPtr->ptr))->export.name);
4463                     smiFree((NamedNumber *)(listPtr->ptr));
4464                 } else if ((attributePtr->export.basetype == SMI_BASETYPE_INTEGER32) ||
4465                            (attributePtr->export.basetype == SMI_BASETYPE_INTEGER64) ||
4466                            (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) ||
4467                            (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) ||
4468                            (attributePtr->export.basetype == SMI_BASETYPE_FLOAT32) ||
4469                            (attributePtr->export.basetype == SMI_BASETYPE_FLOAT64) ||
4470                            (attributePtr->export.basetype == SMI_BASETYPE_FLOAT128) ||
4471                            (attributePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) {
4472                     smiFree((Range *)(listPtr->ptr));
4473                 }
4474                 smiFree(listPtr);
4475             }
4476             smiFree(attributePtr->export.name);
4477             smiFree(attributePtr->export.format);
4478             smiFree(attributePtr->export.units);
4479             smiFree(attributePtr->export.description);
4480             smiFree(attributePtr->export.reference);
4481             smiFree(attributePtr);
4482             
4483             }
4484             
4485             for (eventPtr = classPtr->firstEventPtr; eventPtr;
4486              eventPtr = nextEventPtr) {
4487              
4488                 nextEventPtr = eventPtr->nextPtr;
4489                 smiFree(eventPtr->export.name);
4490             smiFree(eventPtr->export.reference);
4491             smiFree(eventPtr->export.description);
4492             }
4493            
4494                 
4495             for (listPtr = classPtr->uniqueList; listPtr;
4496                  listPtr = nextListPtr) {
4497                 nextListPtr = listPtr->nextPtr;
4498                         smiFree(listPtr);
4499             }
4500             
4501             smiFree(classPtr->export.name);
4502             smiFree(classPtr->export.description);
4503             smiFree(classPtr->export.reference);
4504             smiFree(classPtr);
4505         
4506         }
4507     }
4508
4509     /*
4510      * In this second module loop we remove each module's types
4511      * and the modules themselves. This separation is required, because
4512      * we reference some types of foreign modules in the first loop.
4513      */
4514     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4515          modulePtr = nextModulePtr) {
4516         nextModulePtr = modulePtr->nextPtr;
4517
4518         for (typePtr = modulePtr->firstTypePtr; typePtr;
4519              typePtr = nextTypePtr) {
4520             nextTypePtr = typePtr->nextPtr;
4521             for (listPtr = typePtr->listPtr; listPtr;
4522                  listPtr = nextListPtr) {
4523                 nextListPtr = listPtr->nextPtr;
4524                 if ((typePtr->export.basetype == SMI_BASETYPE_BITS) ||
4525                     (typePtr->export.basetype == SMI_BASETYPE_ENUM)) {
4526                     smiFree(((NamedNumber *)(listPtr->ptr))->export.name);
4527                     smiFree((NamedNumber *)(listPtr->ptr));
4528                 } else if ((typePtr->export.basetype == SMI_BASETYPE_INTEGER32) ||
4529                            (typePtr->export.basetype == SMI_BASETYPE_INTEGER64) ||
4530                            (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) ||
4531                            (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) ||
4532                            (typePtr->export.basetype == SMI_BASETYPE_FLOAT32) ||
4533                            (typePtr->export.basetype == SMI_BASETYPE_FLOAT64) ||
4534                            (typePtr->export.basetype == SMI_BASETYPE_FLOAT128) ||
4535                            (typePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) {
4536                     smiFree((Range *)(listPtr->ptr));
4537                 }
4538                 smiFree(listPtr);
4539             }
4540             smiFree(typePtr->export.name);
4541             smiFree(typePtr->export.format);
4542             smiFree(typePtr->export.units);
4543             smiFree(typePtr->export.description);
4544             smiFree(typePtr->export.reference);
4545             smiFree(typePtr);
4546         }
4547
4548         smiFree(modulePtr->export.name);
4549         smiFree(modulePtr->export.path);
4550         smiFree(modulePtr->export.organization);
4551         smiFree(modulePtr->export.contactinfo);
4552         smiFree(modulePtr->export.description);
4553         smiFree(modulePtr->export.reference);
4554         smiFree(modulePtr);
4555     }
4556
4557     freeNodeTree(smiHandle->rootNodePtr);
4558     smiFree(smiHandle->rootNodePtr);
4559     
4560     return;
4561 }
4562
4563
4564
4565 /*
4566  *----------------------------------------------------------------------
4567  *
4568  * loadModule --
4569  *
4570  *      Load a MIB module. If modulename is a plain name, the file is
4571  *      search along the SMIPATH environment variable. If modulename
4572  *      contains a `.' or DIR_SEPARATOR it is assumed to be the path.
4573  *
4574  * Results:
4575  *      0 on success or -1 on an error.
4576  *
4577  * Side effects:
4578  *      None.
4579  *
4580  *----------------------------------------------------------------------
4581  */
4582
4583 Module *loadModule(const char *modulename, Parser *parserPtr)
4584 {
4585     Parser          parser;
4586     Parser          *parentParserPtr;
4587     char            *path = NULL, *dir, *smipath;
4588     int             sming = 0;
4589     int             c, i;
4590     FILE            *file;
4591     char            sep[2];
4592
4593     static const char *ext[] = {
4594         "", ".my", ".smiv1", ".smiv2", ".sming", ".mib", ".txt", NULL
4595     };
4596     
4597     if ((!modulename) || !strlen(modulename)) {
4598         return NULL;
4599     }
4600
4601     if (!smiIsPath(modulename)) {
4602         /*
4603          * A plain modulename. Lookup the path along SMIPATH...
4604          */
4605         if (!smiHandle->path) {
4606             return NULL;
4607         }
4608         
4609         smipath = smiStrdup(smiHandle->path);
4610         sep[0] = PATH_SEPARATOR; sep[1] = 0;
4611         for (dir = strtok(smipath, sep);
4612              dir; dir = strtok(NULL, sep)) {
4613             for (i = 0; ext[i]; i++) {
4614                 smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR,
4615                             modulename, ext[i]);
4616                 if (! access(path, R_OK)) {
4617                     break;
4618                 }
4619                 smiFree(path);
4620             }
4621             if (ext[i]) break;
4622             {
4623                 char *newmodulename = smiStrdup(modulename);
4624                 for (i = 0; newmodulename[i]; i++) {
4625                     newmodulename[i] = tolower(newmodulename[i]);
4626                 }
4627                 for (i = 0; ext[i]; i++) {
4628                     smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR,
4629                                 newmodulename, ext[i]);
4630                     if (! access(path, R_OK)) {
4631                         break;
4632                     }
4633                     smiFree(path);
4634                 }
4635                 smiFree(newmodulename);
4636                 if (ext[i]) break;
4637             }
4638             
4639             path = NULL;
4640         }
4641         smiFree(smipath);
4642     } else {
4643         /*
4644          * A full path. Take it.
4645          */
4646         path = smiStrdup(modulename);
4647     }
4648
4649 #if !defined(_MSC_VER) && !defined(__MINGW32__)
4650     if (!path && smiHandle->cache && smiHandle->cacheProg) {
4651         /* Not found in the path; now try to fetch & cache the module. */
4652         int  pid;
4653         char *argv[4];
4654         char *cmd;
4655         int  status;
4656         smiAsprintf(&path, "%s%c%s",
4657                     smiHandle->cache, DIR_SEPARATOR, modulename);
4658         if (access(path, R_OK)) {
4659             smiAsprintf(&cmd, "%s %s", smiHandle->cacheProg, modulename);
4660             pid = fork();
4661             if (pid != -1) {
4662                 if (!pid) {
4663                     argv[0] = "sh"; argv[1] = "-c"; argv[2] = cmd; argv[3] = 0;
4664                     execv("/bin/sh", argv);
4665                     exit(127);
4666                 }
4667                 waitpid(pid, &status, 0);
4668             }
4669             smiFree(cmd);
4670             if (access(path, R_OK)) {
4671                 smiFree(path);
4672                 path = NULL;
4673             }
4674         }
4675     }
4676 #endif
4677     
4678     if (!path) {
4679         smiPrintError(parserPtr, ERR_MODULE_NOT_FOUND, modulename);
4680         return NULL;
4681     }
4682
4683     parser.path                 = path;
4684
4685     /*
4686      * Look into the file to determine whether it contains
4687      * SMIv1/SMIv2 or SMIng definitions.
4688      */
4689
4690     file = fopen(path, "r");
4691     if (! file) {
4692         smiPrintError(parserPtr, ERR_OPENING_INPUTFILE, path, strerror(errno));
4693         smiFree(path);
4694         return NULL;
4695     }
4696     while ((c = fgetc(file))) {
4697         if (c == '-' || isupper(c)) {
4698             sming = 0;
4699             break;
4700         } else if (c == '/' || c == 'm') {
4701             sming = 1;
4702             break;
4703         } else if (c == EOF || ! isspace(c)) {
4704             smiPrintError(parserPtr, ERR_ILLEGAL_INPUTFILE, path);
4705             smiFree(path);
4706             fclose(file);
4707             return NULL;
4708         }
4709     }
4710     rewind(file);
4711
4712     
4713     if (sming == 0) {
4714 #ifdef BACKEND_SMI
4715         parentParserPtr = smiHandle->parserPtr;
4716         smiHandle->parserPtr = &parser;
4717         parser.path                     = path;
4718         parser.flags                    = smiHandle->flags;
4719         parser.modulePtr                = NULL;
4720         parser.complianceModulePtr      = NULL;
4721         parser.capabilitiesModulePtr    = NULL;
4722         parser.currentDecl              = SMI_DECL_UNKNOWN;
4723         parser.firstStatementLine       = 0;
4724         parser.firstNestedStatementLine = 0;
4725         parser.firstRevisionLine        = 0;
4726         parser.file                     = file;
4727
4728         /*
4729          * Initialize a root Node for pending (forward referenced) nodes.
4730          */
4731         parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4732     
4733         if (smiEnterLexRecursion(parser.file) < 0) {
4734             smiPrintError(&parser, ERR_MAX_LEX_DEPTH);
4735             fclose(parser.file);
4736         }
4737         smiDepth++;
4738         parser.line                     = 1;
4739         smiparse((void *)&parser);
4740         freeNodeTree(parser.pendingNodePtr);
4741         smiFree(parser.pendingNodePtr);
4742         smiLeaveLexRecursion();
4743         smiDepth--;
4744         fclose(parser.file);
4745         smiFree(path);
4746         smiHandle->parserPtr = parentParserPtr;
4747         return parser.modulePtr;
4748 #else
4749         smiPrintError(parserPtr, ERR_SMI_NOT_SUPPORTED, path);
4750         smiFree(path);
4751         fclose(file);
4752         return NULL;
4753 #endif
4754     }
4755     
4756     if (sming == 1) {
4757 #ifdef BACKEND_SMING
4758         parentParserPtr = smiHandle->parserPtr;
4759         smiHandle->parserPtr = &parser;
4760         parser.path                     = path;
4761         parser.flags                    = smiHandle->flags;
4762         parser.modulePtr                = NULL;
4763         parser.complianceModulePtr      = NULL;
4764         parser.capabilitiesModulePtr    = NULL;
4765         parser.currentDecl              = SMI_DECL_UNKNOWN;
4766         parser.firstStatementLine       = 0;
4767         parser.firstNestedStatementLine = 0;
4768         parser.firstRevisionLine        = 0;
4769         parser.file                     = file;
4770
4771         /*
4772          * Initialize a root Node for pending (forward referenced) nodes.
4773          */
4774         parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4775     
4776         if (smingEnterLexRecursion(parser.file) < 0) {
4777             smiPrintError(&parser, ERR_MAX_LEX_DEPTH);
4778             fclose(parser.file);
4779         }
4780         smiDepth++;
4781         parser.line                     = 1;
4782         smingparse((void *)&parser);
4783         freeNodeTree(parser.pendingNodePtr);
4784         smiFree(parser.pendingNodePtr);
4785         smingLeaveLexRecursion();
4786         smiDepth--;
4787         fclose(parser.file);
4788         smiFree(path);
4789         smiHandle->parserPtr = parentParserPtr;
4790         return parser.modulePtr;
4791 #else
4792         smiPrintError(parserPtr, ERR_SMING_NOT_SUPPORTED, path);
4793         smiFree(path);
4794         fclose(file);
4795         return NULL;
4796 #endif
4797     }
4798
4799     smiFree(path);
4800     fclose(file);
4801     return NULL;
4802 }