Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / tools / dump-mosy.c
1 /*
2  * dump-mosy.c --
3  *
4  *      Operations to dump MIB modules in the MOSY output format.
5  *
6  * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7  * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
8  *
9  * See the file "COPYING" for information on usage and redistribution
10  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11  *
12  * @(#) $Id: dump-mosy.c 8090 2008-04-18 12:56:29Z strauss $
13  */
14
15 #include <config.h>
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include "smi.h"
21 #include "smidump.h"
22
23
24 static char *ignoreTypeRanges[] = {
25     "TimeTicks",
26     "Counter32",
27     "Gauge32",
28     "Counter64",
29     NULL
30 };
31
32
33 static char *getStatusString(SmiStatus status)
34 {
35     return
36         (status == SMI_STATUS_CURRENT)     ? "current" :
37         (status == SMI_STATUS_DEPRECATED)  ? "deprecated" :
38         (status == SMI_STATUS_OBSOLETE)    ? "obsolete" :
39         (status == SMI_STATUS_MANDATORY)   ? "mandatory" :
40         (status == SMI_STATUS_OPTIONAL)    ? "optional" :
41                                              "<unknown>";
42 }
43
44
45 static char *getAccessString(SmiAccess access, int create)
46 {
47     return
48         (create && (access == SMI_ACCESS_READ_WRITE)) ? "read-create" :
49         (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" :
50         (access == SMI_ACCESS_NOTIFY)         ? "accessible-for-notify" :
51         (access == SMI_ACCESS_READ_ONLY)      ? "read-only" :
52         (access == SMI_ACCESS_READ_WRITE)     ? "read-write" :
53                                                 "<unknown>";
54 }
55
56
57 static char *getBasetypeString(SmiBasetype basetype)
58 {
59     return
60         (basetype == SMI_BASETYPE_UNKNOWN)           ? "<UNKNOWN>" :
61         (basetype == SMI_BASETYPE_OCTETSTRING)       ? "OctetString" :
62         (basetype == SMI_BASETYPE_OBJECTIDENTIFIER)  ? "ObjectID" :
63         (basetype == SMI_BASETYPE_UNSIGNED32)        ? "Unsigned32" :
64         (basetype == SMI_BASETYPE_INTEGER32)         ? "Integer32" :
65         (basetype == SMI_BASETYPE_UNSIGNED64)        ? "Unsigned64" :
66         (basetype == SMI_BASETYPE_INTEGER64)         ? "Integer64" :
67         (basetype == SMI_BASETYPE_FLOAT32)           ? "Float32" :
68         (basetype == SMI_BASETYPE_FLOAT64)           ? "Float64" :
69         (basetype == SMI_BASETYPE_FLOAT128)          ? "Float128" :
70         (basetype == SMI_BASETYPE_ENUM)              ? "INTEGER" :
71         (basetype == SMI_BASETYPE_BITS)              ? "Bits" :
72                                                    "<unknown>";
73 }
74
75
76
77 static char *getOidString(SmiNode *smiNode, int importedParent)
78 {
79     SmiNode      *parentNode;
80     SmiModule    *smiModule;
81     static char  s[200];
82     char         append[200];
83     unsigned int i;
84     
85     append[0] = 0;
86
87     parentNode = smiNode;
88     smiModule = smiGetNodeModule(smiNode);
89     
90     do {
91
92         if (parentNode->oidlen <= 1) {
93             break;
94         }
95         
96         /* prepend the cut-off subidentifier to `append'. */
97         strcpy(s, append);
98         sprintf(append, ".%u%s", parentNode->oid[parentNode->oidlen-1], s);
99
100         /* retrieve the parent SmiNode */
101         parentNode = smiGetParentNode(parentNode);
102
103         if (!parentNode) {
104             sprintf(s, "%s", append);
105             return s;
106         }
107         
108         /* found an imported or a local parent node? */
109         if ((parentNode->decl != SMI_DECL_IMPL_OBJECT) 
110             && ((parentNode->name && strlen(parentNode->name)) 
111                 && (smiIsImported(smiModule, NULL, parentNode->name) 
112                     || (!importedParent 
113                         && (smiGetNodeModule(parentNode) == smiModule)) 
114                     || (parentNode->oidlen == 1)))) {
115             sprintf(s, "%s%s", parentNode->name, append);
116             return s;
117         }
118         
119     } while (parentNode);
120
121     s[0] = 0;
122     for (i=0; i < smiNode->oidlen; i++) {
123         if (i) strcat(s, ".");
124         sprintf(&s[strlen(s)], "%u", smiNode->oid[i]);
125     }
126     return s;
127 }
128
129
130
131 static char *getValueString(SmiValue *valuePtr)
132 {
133     static char    s[1024];
134
135     s[0] = 0;
136     
137     switch (valuePtr->basetype) {
138     case SMI_BASETYPE_UNSIGNED32:
139         sprintf(s, "%lu", valuePtr->value.unsigned32);
140         break;
141     case SMI_BASETYPE_INTEGER32:
142         sprintf(s, "%ld", valuePtr->value.integer32);
143         break;
144     case SMI_BASETYPE_UNSIGNED64:
145         sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
146         break;
147     case SMI_BASETYPE_INTEGER64:
148         sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
149         break;
150     case SMI_BASETYPE_FLOAT32:
151     case SMI_BASETYPE_FLOAT64:
152     case SMI_BASETYPE_FLOAT128:
153         break;
154     case SMI_BASETYPE_ENUM:
155     case SMI_BASETYPE_OCTETSTRING:
156     case SMI_BASETYPE_BITS:
157     case SMI_BASETYPE_OBJECTIDENTIFIER:
158         /* not required in MOSY format */
159         break;
160     case SMI_BASETYPE_UNKNOWN:
161         break;
162     case SMI_BASETYPE_POINTER:
163         break;
164     }
165
166     return s;
167 }
168
169
170
171 static void printIndex(FILE *f, SmiNode *smiNode)
172 {
173     char *indexname;
174     int  i;
175     SmiElement *smiElement;
176     
177     fprintf(f, "%%%-19s %-16s \"", "ei", smiNode->name);
178     indexname = NULL;
179     for (i = -1, smiElement = smiGetFirstElement(smiNode);
180          smiElement; smiElement = smiGetNextElement(smiElement), i++) {
181         if (i > 0) fprintf(f, " ");
182         if (indexname) {
183             fprintf(f, "%s", indexname);
184         }
185         indexname = smiGetElementNode(smiElement)->name;
186     }
187     if (indexname) {
188         fprintf(f, "%s%s%s",
189                 (i > 0) ? " " : "",
190                 (smiNode->implied) ? "*" : "",
191                 indexname);
192     }
193     fprintf(f, "\"\n");
194 }
195
196
197
198 static void printAssignements(FILE *f, SmiModule *smiModule)
199 {
200     int          cnt = 0;
201     SmiNode      *smiNode;
202
203     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
204          smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
205
206         cnt++;
207
208         if (smiNode->status == SMI_STATUS_UNKNOWN &&
209             smiNode != smiGetModuleIdentityNode(smiModule)) {
210             fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0));
211             fprintf(f, "%%n0 %-16s object-id\n", smiNode->name);
212         }
213     }
214
215     if (cnt) {
216         fprintf(f, "\n");
217     }
218 }
219
220
221
222 static void printTypedefs(FILE *f, SmiModule *smiModule)
223 {
224     int            i;
225     SmiType        *smiType, *smiParentType;
226     SmiNamedNumber *nn;
227     char           *type_name;
228     
229     for (i = 0, smiType = smiGetFirstType(smiModule);
230          smiType; smiType = smiGetNextType(smiType)) {
231         
232         smiParentType = smiGetParentType(smiType);
233         type_name = smiParentType->name;
234         
235         if (smiParentType->decl == SMI_DECL_IMPLICIT_TYPE) {
236             smiParentType = smiGetParentType(smiParentType);
237             type_name = smiParentType->name;
238         }
239         if (smiParentType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) {
240             type_name = "ObjectID";
241         }
242         if (smiParentType->basetype == SMI_BASETYPE_ENUM) {
243             type_name = "INTEGER";
244         }
245
246         fprintf(f, "%%%-19s %-16s %-15s \"%s\"\n", "tc",
247                 smiType->name, type_name,
248                 smiType->format ? smiType->format : "");
249         
250         for (i = 0, nn = smiGetFirstNamedNumber(smiType);
251              nn ; i++, nn = smiGetNextNamedNumber(nn)) {
252             fprintf(f, "%%%-19s %-16s %-15s %s\n", "es",
253                     smiType->name, nn->name,
254                     getValueString(&nn->value));
255         }
256     }
257 }
258
259
260
261 static void printObjects(FILE *f, SmiModule *smiModule)
262 {
263     int            i, j, ignore, cnt = 0, aggregate, create;
264     char           *type_name;
265     SmiNode        *smiNode, *relatedNode;
266     SmiType        *smiType;
267     SmiNamedNumber *smiNamedNumber;
268     SmiRange       *smiRange;
269     
270     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
271          smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
272
273         if (smiNode->nodekind != SMI_NODEKIND_NODE
274             && smiNode->nodekind != SMI_NODEKIND_SCALAR
275             && smiNode->nodekind != SMI_NODEKIND_TABLE
276             && smiNode->nodekind != SMI_NODEKIND_ROW
277             && smiNode->nodekind != SMI_NODEKIND_COLUMN) {
278             continue;
279         }
280         
281         cnt++;
282
283         if (smiNode->nodekind == SMI_NODEKIND_NODE) {
284             if (smiNode->status != SMI_STATUS_UNKNOWN &&
285                 smiNode != smiGetModuleIdentityNode(smiModule)) {
286                 fprintf(f, "%-20s %s\n", smiNode->name,
287                         getOidString(smiNode, 0));
288                 fprintf(f, "%%n0 %-16s object-id\n", smiNode->name);
289             }
290             continue;
291         }
292
293         aggregate = smiNode->nodekind == SMI_NODEKIND_TABLE
294             || smiNode->nodekind == SMI_NODEKIND_ROW;
295
296         type_name = NULL;
297         smiType = smiGetNodeType(smiNode);
298         if (!aggregate) {
299             if (! smiType) {
300                 continue;
301             }
302             type_name = getBasetypeString(smiType->basetype);
303             if (smiType && (smiType->decl != SMI_DECL_IMPLICIT_TYPE)) {
304                 type_name = smiType->name;
305                 if (!strcmp(type_name, "ObjectIdentifier")) {
306                     type_name = "ObjectID";
307                 }
308             }
309         
310             if (smiType && smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
311                 type_name = smiGetParentType(smiType)->name;
312                 if (smiType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER) {
313                     type_name = "ObjectID";
314                 }
315                 if (smiType->basetype == SMI_BASETYPE_ENUM) {
316                     type_name = "INTEGER";
317                 }
318             }
319         } else {
320             type_name = "Aggregate";
321         }
322
323         if (smiNode->nodekind == SMI_NODEKIND_COLUMN) {
324             create = smiGetParentNode(smiNode)->create;
325         } else {
326             create = 0;
327         }
328         
329         fprintf(f, "%-20s %-16s ", smiNode->name, getOidString(smiNode, 0));
330         fprintf(f, "%-15s %-15s %s\n", type_name,
331                 getAccessString(smiNode->access, create),
332                 getStatusString(smiNode->status));
333
334         relatedNode = smiGetRelatedNode(smiNode);
335         switch (smiNode->indexkind) {
336         case SMI_INDEX_INDEX:
337         case SMI_INDEX_REORDER:
338             printIndex(f, smiNode);
339             break;
340         case SMI_INDEX_EXPAND:  /* TODO: we have to do more work here! */
341             break;
342         case SMI_INDEX_AUGMENT:
343             if (relatedNode) {
344                 fprintf(f, "%%%-19s %-16s %s\n", "ea",
345                         smiNode->name, relatedNode->name);
346             }
347             break;
348         case SMI_INDEX_SPARSE:
349             if (relatedNode) {
350                 printIndex(f, relatedNode);
351             }
352             break;
353         case SMI_INDEX_UNKNOWN:
354             break;          
355         }
356
357         if (smiType && smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
358             for (i = 0, smiNamedNumber = smiGetFirstNamedNumber(smiType);
359                 smiNamedNumber;
360                 i++, smiNamedNumber = smiGetNextNamedNumber(smiNamedNumber)) {
361                 fprintf(f, "%%%-19s %-16s %-15s %s\n", "ev",
362                         smiNode->name, smiNamedNumber->name,
363                         getValueString(&smiNamedNumber->value));
364             }
365
366             for (ignore = 0, j = 0; ignoreTypeRanges[j]; j++) {
367                 if (strcmp(type_name, ignoreTypeRanges[j]) == 0) {
368                     ignore++;
369                     break;
370                 }
371             }
372
373             if (! ignore) {
374                 for (smiRange = smiGetFirstRange(smiType);
375                      smiRange;
376                      smiRange = smiGetNextRange(smiRange)) {
377                     fprintf(f, "%%%-19s %-16s %-15s ", "er",
378                             smiNode->name,
379                             getValueString(&smiRange->minValue));
380                     fprintf(f, "%s\n", getValueString(&smiRange->maxValue));
381                 }
382             }
383         }
384     }
385
386     if (cnt) {
387         fprintf(f, "\n");
388     }
389 }
390
391
392
393 static void printNotifications(FILE *f, SmiModule *smiModule)
394 {
395     int          cnt = 0;
396     SmiNode      *smiNode;
397     
398     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
399          smiNode; 
400          smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
401
402         cnt++;
403         
404         fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0));
405         fprintf(f, "%%n0 %-16s notification\n", smiNode->name);
406     }
407
408     if (cnt) {
409         fprintf(f, "\n");
410     }
411 }
412
413
414
415 static void printGroups(FILE *f, SmiModule *smiModule)
416 {
417     SmiNode     *smiNode, *smiNodeMember;
418     SmiElement  *smiElement;
419     int         cnt = 0, objects, notifications;
420     
421     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
422          smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
423
424         cnt ++;
425
426         for (objects = 0, notifications = 0,
427              smiElement = smiGetFirstElement(smiNode);
428              smiElement;
429              smiElement = smiGetNextElement(smiElement)) {
430
431             smiNodeMember = smiGetElementNode(smiElement);
432             
433             objects += 
434                 (smiNodeMember->nodekind == SMI_NODEKIND_SCALAR)
435                 || (smiNodeMember->nodekind == SMI_NODEKIND_COLUMN);
436             notifications +=
437                 (smiNodeMember->nodekind == SMI_NODEKIND_NOTIFICATION);
438         }
439
440         fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0));
441         fprintf(f, "%%n0 %-16s %s\n", smiNode->name,
442                 (objects && ! notifications) ? "object-group" :
443                 (! objects && notifications) ? "notification-group" : "group");
444     }
445
446     if (cnt) {
447         fprintf(f, "\n");
448     }
449 }
450
451
452
453 static void printCompliances(FILE *f, SmiModule *smiModule)
454 {
455     int           cnt = 0;
456     SmiNode       *smiNode;
457     
458     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
459          smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
460         
461         cnt++;
462
463         fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, 0));
464         fprintf(f, "%%n0 %-16s module-compliance\n", smiNode->name);
465     }
466             
467     if (cnt) {
468         fprintf(f, "\n");
469     }
470 }
471
472
473
474 static void dumpMosy(int modc, SmiModule **modv, int flags, char *output)
475 {
476     SmiNode     *smiNode;
477     int         i;
478     FILE        *f = stdout;
479
480     if (output) {
481         f = fopen(output, "w");
482         if (!f) {
483             fprintf(stderr, "smidump: cannot open %s for writing: ", output);
484             perror(NULL);
485             exit(1);
486         }
487     }
488
489     for (i = 0; i < modc; i++) {
490
491         if (! (flags & SMIDUMP_FLAG_SILENT)) {
492             fprintf(f,
493                     "-- automatically generated by smidump %s, do not edit!\n",
494                     SMI_VERSION_STRING);
495             fprintf(f,
496                     "\n-- object definitions compiled from %s\n\n",
497                     modv[i]->name);
498         }
499
500         if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
501             fprintf(f, "-- WARNING: this output may be incorrect due to "
502                     "significant parse errors\n\n");
503         }
504         
505         smiNode = smiGetModuleIdentityNode(modv[i]);
506         if (smiNode) {
507             SmiNode *parent = smiGetParentNode(smiNode);
508             fprintf(f, "%-20s %s\n", smiNode->name, getOidString(smiNode, !parent || parent->nodekind == SMI_NODEKIND_UNKNOWN ));
509             fprintf(f, "%%n0 %-16s module-identity\n", smiNode->name);
510             fprintf(f, "\n");
511         }
512         
513         printAssignements(f, modv[i]);
514         printTypedefs(f, modv[i]);
515         printObjects(f, modv[i]);
516         printNotifications(f, modv[i]);
517         printGroups(f, modv[i]);
518         printCompliances(f, modv[i]);
519     }
520
521     if (fflush(f) || ferror(f)) {
522         perror("smidump: write error");
523         exit(1);
524     }
525
526     if (output) {
527         fclose(f);
528     }
529 }
530
531
532
533 void initMosy()
534 {
535     
536     static SmidumpDriver driver = {
537         "mosy",
538         dumpMosy,
539         SMI_FLAG_NODESCR,
540         SMIDUMP_DRIVER_CANT_UNITE,
541         "intermediate format generated by the mosy compiler",
542         NULL,
543         NULL
544     };
545     
546     smidumpRegisterDriver(&driver);
547 }