1 /*
2 * dump-python.c --
3 *
4 * Operations to dump SMIng module information in Python format.
5 *
6 * Copyright (c) 2000 Frank Strauss, Technical University of Braunschweig.
7 * Copyright (c) 2000 J. Schoenwaelder, Technical University of Braunschweig.
8 * Copyright (c) 2000 WideAwake Ltd.
9 *
10 * See the file "COPYING" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * @(#) $Id: dump-python.c 8090 2008-04-18 12:56:29Z strauss $
14 */
15
16 /*
17 * TODO:
18 *
19 * - value representations (getValueString())
20 */
21
22 #include <config.h>
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <time.h>
30
31 #include "smi.h"
32 #include "smidump.h"
33
34
35
36 #define INDENT 4 /* indent factor */
37 #define INDENTVALUE 20 /* column to start values, except multiline */
38 #define INDENTTEXTS 4 /* column to start multiline texts */
39 #define INDENTMAX 64 /* max column to fill, break lines otherwise */
40
41
42 static int silent = 0;
43
44
45 typedef struct PythonEscape {
46 char character;
47 char *escape;
48 } PythonEscape;
49
50 static PythonEscape pythonEscapes [] = {
51 { 0, NULL }
52 };
53
54
55 static int current_column = 0;
56
57 static char* currentModuleName = NULL;
58
getStringLanguage(SmiLanguage lang)59 static char *getStringLanguage(SmiLanguage lang)
60 {
61 return
62 (lang == SMI_LANGUAGE_SMIV1) ? "SMIv1" :
63 (lang == SMI_LANGUAGE_SMIV2) ? "SMIv2" :
64 (lang == SMI_LANGUAGE_SMING) ? "SMIng" :
65 NULL;
66 }
67
68
69
getStringStatus(SmiStatus status)70 static char *getStringStatus(SmiStatus status)
71 {
72 return
73 (status == SMI_STATUS_CURRENT) ? "current" :
74 (status == SMI_STATUS_DEPRECATED) ? "deprecated" :
75 (status == SMI_STATUS_OBSOLETE) ? "obsolete" :
76 (status == SMI_STATUS_MANDATORY) ? "current" :
77 (status == SMI_STATUS_OPTIONAL) ? "current" :
78 "<unknown>";
79 }
80
81
82
getAccessString(SmiAccess access)83 static char *getAccessString(SmiAccess access)
84 {
85 return
86 (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "noaccess" :
87 (access == SMI_ACCESS_NOTIFY) ? "notifyonly" :
88 (access == SMI_ACCESS_READ_ONLY) ? "readonly" :
89 (access == SMI_ACCESS_READ_WRITE) ? "readwrite" :
90 "<unknown>";
91 }
92
93
94
getStringBasetype(SmiBasetype basetype)95 static char *getStringBasetype(SmiBasetype basetype)
96 {
97 return
98 (basetype == SMI_BASETYPE_UNKNOWN) ? "<UNKNOWN>" :
99 (basetype == SMI_BASETYPE_OCTETSTRING) ? "OctetString" :
100 (basetype == SMI_BASETYPE_OBJECTIDENTIFIER) ? "ObjectIdentifier" :
101 (basetype == SMI_BASETYPE_UNSIGNED32) ? "Unsigned32" :
102 (basetype == SMI_BASETYPE_INTEGER32) ? "Integer32" :
103 (basetype == SMI_BASETYPE_UNSIGNED64) ? "Unsigned64" :
104 (basetype == SMI_BASETYPE_INTEGER64) ? "Integer64" :
105 (basetype == SMI_BASETYPE_FLOAT32) ? "Float32" :
106 (basetype == SMI_BASETYPE_FLOAT64) ? "Float64" :
107 (basetype == SMI_BASETYPE_FLOAT128) ? "Float128" :
108 (basetype == SMI_BASETYPE_ENUM) ? "Enumeration" :
109 (basetype == SMI_BASETYPE_BITS) ? "Bits" :
110 "<unknown>";
111 }
112
113
114
getTimeString(time_t t)115 static char *getTimeString(time_t t)
116 {
117 static char s[27];
118 struct tm *tm;
119
120 tm = gmtime(&t);
121 sprintf(s, "%04d-%02d-%02d %02d:%02d",
122 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
123 tm->tm_hour, tm->tm_min);
124 return s;
125 }
126
127
128
fprint(FILE * f,char * fmt,...)129 static void fprint(FILE *f, char *fmt, ...)
130 {
131 va_list ap;
132 char *s;
133 char *p;
134
135 va_start(ap, fmt);
136 current_column += smiVasprintf(&s, fmt, ap);
137 va_end(ap);
138 fputs(s, f);
139 if ((p = strrchr(s, '\n'))) {
140 current_column = strlen(p) - 1;
141 }
142 free(s);
143 }
144
145
146
fprintSegment(FILE * f,int column,char * string,int length)147 static void fprintSegment(FILE *f, int column, char *string, int length)
148 {
149 fprint(f, "%*c%s", column, ' ', string);
150 if (length) {
151 fprint(f, "%*c", length - strlen(string) - column, ' ');
152 }
153 }
154
155
156
fprintMultilineString(FILE * f,int column,const char * s)157 static void fprintMultilineString(FILE *f, int column, const char *s)
158 {
159 int i, j, len;
160
161 #ifdef INDENTTEXTS
162 fprintSegment(f, column + INDENTTEXTS, "", 0);
163 #endif
164 if (s) {
165 fputs("\"\"\"", f);
166 current_column += 3;
167 len = strlen(s);
168 for (i=0; i < len; i++) {
169 for (j = 0; pythonEscapes[j].character; j++) {
170 if (pythonEscapes[j].character == s[i]) break;
171 }
172 if (pythonEscapes[j].character) {
173 fputs(pythonEscapes[j].escape, f);
174 current_column += strlen(pythonEscapes[j].escape);
175 } else {
176 putc(s[i], f);
177 current_column++;
178 }
179 if (s[i] == '\n') {
180 current_column = 0;
181 #ifdef INDENTTEXTS
182 /* printSegment(column + INDENTTEXTS, "", 0); */
183 #endif
184 }
185 }
186 fputs("\"\"\"", f);
187 current_column += 3;
188 }
189 current_column++;
190 }
191
192
193
getValueString(SmiValue * valuePtr,SmiType * typePtr)194 static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
195 {
196 static char s[1024];
197 char ss[9];
198 int n;
199 unsigned int i;
200 SmiNamedNumber *nn;
201
202 s[0] = 0;
203
204 switch (valuePtr->basetype) {
205 case SMI_BASETYPE_UNSIGNED32:
206 sprintf(s, "%lu", valuePtr->value.unsigned32);
207 break;
208 case SMI_BASETYPE_INTEGER32:
209 sprintf(s, "%ld", valuePtr->value.integer32);
210 break;
211 case SMI_BASETYPE_UNSIGNED64:
212 sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
213 break;
214 case SMI_BASETYPE_INTEGER64:
215 sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
216 break;
217 case SMI_BASETYPE_FLOAT32:
218 case SMI_BASETYPE_FLOAT64:
219 case SMI_BASETYPE_FLOAT128:
220 break;
221 case SMI_BASETYPE_ENUM:
222 for (nn = smiGetFirstNamedNumber(typePtr); nn;
223 nn = smiGetNextNamedNumber(nn)) {
224 if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
225 break;
226 }
227 if (nn) {
228 sprintf(s, "%s", nn->name);
229 } else {
230 sprintf(s, "%ld", valuePtr->value.integer32);
231 }
232 break;
233 case SMI_BASETYPE_OCTETSTRING:
234 for (i = 0; i < valuePtr->len; i++) {
235 if (!isprint((int)valuePtr->value.ptr[i])) break;
236 }
237 if (i == valuePtr->len) {
238 sprintf(s, "%s", valuePtr->value.ptr);
239 } else {
240 sprintf(s, "0x%*s", 2 * valuePtr->len, "");
241 for (i=0; i < valuePtr->len; i++) {
242 sprintf(ss, "%02x", valuePtr->value.ptr[i]);
243 strncpy(&s[2+2*i], ss, 2);
244 }
245 }
246 break;
247 case SMI_BASETYPE_BITS:
248 sprintf(s, "(");
249 for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
250 if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
251 if (n)
252 sprintf(&s[strlen(s)], ", ");
253 n++;
254 for (nn = smiGetFirstNamedNumber(typePtr); nn;
255 nn = smiGetNextNamedNumber(nn)) {
256 if (nn->value.value.unsigned32 == i)
257 break;
258 }
259 if (nn) {
260 sprintf(&s[strlen(s)], "%s", nn->name);
261 } else {
262 sprintf(s, "%d", i);
263 }
264 }
265 }
266 sprintf(&s[strlen(s)], ")");
267 break;
268 case SMI_BASETYPE_UNKNOWN:
269 break;
270 case SMI_BASETYPE_POINTER:
271 break;
272 case SMI_BASETYPE_OBJECTIDENTIFIER:
273 for (i = 0; i < valuePtr->len; i++) {
274 sprintf(&s[strlen(s)], i ? ".%u" : "%u", valuePtr->value.oid[i]);
275 }
276 break;
277 }
278
279 return s;
280 }
281
282
283
fprintNodeStartTag(FILE * f,int indent,const char * tag,SmiNode * smiNode)284 static void fprintNodeStartTag(FILE *f, int indent, const char *tag,
285 SmiNode *smiNode)
286 {
287 unsigned int i;
288
289 fprintSegment(f, indent, "", 0);
290 fprint(f, "\"%s\" : {\n", smiNode->name);
291 fprintSegment(f, indent + INDENT, "", 0);
292 fprint(f, "\"nodetype\" : \"%s\",\n", tag);
293 fprintSegment(f, indent + INDENT, "", 0);
294 fprint(f, "\"moduleName\" : \"%s\",\n", currentModuleName);
295 fprintSegment(f, indent + INDENT, "", 0);
296 fprint(f, "\"oid\" : \"");
297 for (i = 0; i < smiNode->oidlen; i++) {
298 fprint(f, i ? ".%u" : "%u", smiNode->oid[i]);
299 }
300 fprint(f, "\"");
301
302 if (smiNode->create) {
303 fprint(f, ",\n");
304 fprintSegment(f, indent + INDENT, "\"create\" : \"true\"", 0);
305 }
306 if (smiNode->status != SMI_STATUS_UNKNOWN) {
307 fprint(f, ",\n");
308 fprintSegment(f, indent + INDENT, "", 0);
309 fprint(f, "\"status\" : \"%s\"", getStringStatus(smiNode->status));
310 }
311 if (smiNode->implied) {
312 fprint(f, ",\n");
313 fprintSegment(f, indent + INDENT, "\"implied\" : \"true\"", 0);
314 }
315 fprint(f, ",\n");
316 }
317
318
319
fprintNodeEndTag(FILE * f,int indent,const char * tag)320 static void fprintNodeEndTag(FILE *f, int indent, const char *tag)
321 {
322 fprintSegment(f, indent, "", 0);
323 fprint(f, "}, # %s\n", tag);
324 }
325
326
327
fprintRanges(FILE * f,int indent,SmiType * smiType)328 static void fprintRanges(FILE *f, int indent, SmiType *smiType)
329 {
330 SmiRange *range;
331 SmiValue min, max;
332 int rc;
333
334 if (! smiGetFirstRange(smiType)) {
335 return;
336 }
337
338 fprintSegment(f, indent, "\"ranges\" : [\n", 0);
339 for (range = smiGetFirstRange(smiType);
340 range;
341 range = smiGetNextRange(range)) {
342 fprintSegment(f, indent, "{\n", 0);
343 fprintSegment(f, indent + INDENT, "", 0);
344 fprint(f, "\"min\" : \"%s\",\n",
345 getValueString(&range->minValue, smiType));
346 fprintSegment(f, indent + INDENT, "", 0);
347 fprint(f, "\"max\" : \"%s\"\n",
348 getValueString(&range->maxValue, smiType));
349 fprintSegment(f, indent, "},\n", 0);
350 }
351 fprintSegment(f, indent, "],\n", 0);
352
353 rc = smiGetMinMaxRange(smiType, &min, &max);
354
355 if (rc == 0
356 && min.basetype != SMI_BASETYPE_UNKNOWN
357 && max.basetype != SMI_BASETYPE_UNKNOWN) {
358
359 fprintSegment(f, indent, "\"range\" : {\n", 0);
360 fprintSegment(f, indent + INDENT, "", 0);
361 fprint(f, "\"min\" : \"%s\",\n", getValueString(&min, smiType));
362 fprintSegment(f, indent + INDENT, "", 0);
363 fprint(f, "\"max\" : \"%s\"\n", getValueString(&max, smiType));
364 fprintSegment(f, indent, "},\n", 0);
365 }
366 }
367
368
369
fprintNamedNumbers(FILE * f,int indent,SmiType * smiType)370 static void fprintNamedNumbers(FILE *f, int indent, SmiType *smiType)
371 {
372 SmiNamedNumber *nn;
373
374 if ((smiType->basetype != SMI_BASETYPE_ENUM) &&
375 (smiType->basetype != SMI_BASETYPE_BITS)) {
376 return;
377 }
378
379 for (nn = smiGetFirstNamedNumber(smiType);
380 nn;
381 nn = smiGetNextNamedNumber(nn)) {
382 fprintSegment(f, indent, "\"", 0);
383 fprint(f, "%s\" : {\n", nn->name);
384 fprintSegment(f, indent + INDENT,
385 "\"nodetype\" : \"namednumber\",\n", 0);
386 fprintSegment(f, indent + INDENT, "", 0);
387 fprint(f, "\"number\" : \"%s\"\n",
388 getValueString(&nn->value, smiType));
389 fprintSegment(f, indent, "},\n", 0);
390 }
391 }
392
393
394
fprintValue(FILE * f,int indent,SmiValue * smiValue,SmiType * smiType)395 static void fprintValue(FILE *f, int indent, SmiValue *smiValue,
396 SmiType *smiType)
397 {
398 if (smiType && smiValue && smiValue->basetype != SMI_BASETYPE_UNKNOWN) {
399 fprintSegment(f, indent, "\"default\" : ", 0);
400 fprint(f, "\"%s\"", getValueString(smiValue, smiType));
401 fprint(f, ",\n");
402 }
403 }
404
405
406
fprintDescription(FILE * f,int indent,const char * description)407 static void fprintDescription(FILE *f, int indent, const char *description)
408 {
409 if (description) {
410 fprintSegment(f, indent, "\"description\" :\n", 0);
411 fprintMultilineString(f, indent, description);
412 fprint(f, ",\n");
413 }
414 }
415
416
417
fprintReference(FILE * f,int indent,const char * reference)418 static void fprintReference(FILE *f, int indent, const char *reference)
419 {
420 if (reference) {
421 fprintSegment(f, indent, "\"reference>\" :\n", 0);
422 fprintMultilineString(f, indent, reference);
423 fprint(f, ",\n");
424 }
425 }
426
427
428
fprintFormat(FILE * f,int indent,const char * format)429 static void fprintFormat(FILE *f, int indent, const char *format)
430 {
431 if (format) {
432 fprintSegment(f, indent, "", 0);
433 fprint(f, "\"format\" : \"%s\",\n", format);
434 }
435 }
436
437
438
fprintUnits(FILE * f,int indent,const char * units)439 static void fprintUnits(FILE *f, int indent, const char *units)
440 {
441 if (units) {
442 fprintSegment(f, indent, "", 0);
443 fprint(f, "\"units\" : \"%s\",\n", units);
444 }
445 }
446
447
448
fprintAccess(FILE * f,int indent,SmiAccess smiAccess)449 static void fprintAccess(FILE *f, int indent, SmiAccess smiAccess)
450 {
451 if (smiAccess != SMI_ACCESS_UNKNOWN) {
452 fprintSegment(f, indent, "", 0);
453 fprint(f, "\"access\" : \"%s\",\n", getAccessString(smiAccess));
454 }
455 }
456
457
458
fprintElementList(FILE * f,int indent,const char * tag,SmiElement * smiElement)459 static void fprintElementList(FILE *f, int indent, const char *tag,
460 SmiElement *smiElement)
461 {
462 SmiModule *smiModule;
463 SmiNode *smiNode;
464
465 for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
466 smiNode = smiGetElementNode(smiElement);
467 smiModule = smiGetNodeModule(smiNode);
468 fprintSegment(f, indent, "", 0);
469 fprint(f, "\"%s\" : {\n", smiNode->name);
470 fprintSegment(f, indent + INDENT, "", 0);
471 fprint(f, "\"nodetype\" : \"%s\",\n", tag);
472 fprintSegment(f, indent + INDENT, "", 0);
473 fprint(f, "\"module\" : \"%s\"\n", smiModule->name);
474 fprintSegment(f, indent, "},\n", 0);
475 }
476 }
477
fprintListElement(FILE * f,int indent,const char * tag,SmiElement * smiElement)478 static void fprintListElement(FILE *f, int indent, const char *tag,
479 SmiElement *smiElement)
480 {
481 SmiNode *smiNode;
482
483 for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
484 smiNode = smiGetElementNode(smiElement);
485 fprintSegment(f, indent, "", 0);
486 fprint(f, "\"%s\",\n", smiNode->name);
487 }
488 }
489
490
491
fprintIndexModule(FILE * f,int indent,const char * modname,const char * nodename,const char * indexkind)492 static void fprintIndexModule(FILE *f, int indent, const char *modname,
493 const char *nodename, const char *indexkind)
494 {
495 fprintSegment(f, indent + INDENT, "", 0);
496 fprint(f, "{ \"%s\" : {\n", modname);
497 fprintSegment(f, indent + (2 * INDENT), "", 0);
498 fprint(f, "\"indexkind\" : \"%s\",\n", indexkind);
499 fprintSegment(f, indent + (2 * INDENT), "", 0);
500 fprint(f, "\"relatedNode\" : \"%s\",\n", nodename);
501 fprintSegment(f, indent + INDENT, "}},\n", 0);
502 }
503
504
505
fprintIndex(FILE * f,int indent,SmiNode * smiNode)506 static void fprintIndex(FILE *f, int indent, SmiNode *smiNode)
507 {
508 SmiNode *relatedNode;
509 SmiModule *relatedModule = NULL;
510
511 fprintSegment(f, indent, "\"linkage\" : [\n", 0);
512 if (smiNode->implied) {
513 /* fprintSegment(f, indent + INDENT, "\"implied\" : \"true\",\n", 0); */
514 }
515
516 relatedNode = smiGetRelatedNode(smiNode);
517 if (relatedNode) {
518 relatedModule = smiGetNodeModule(relatedNode);
519 }
520 switch (smiNode->indexkind) {
521 case SMI_INDEX_INDEX:
522 fprintListElement(f, indent + INDENT, "index",
523 smiGetFirstElement(smiNode));
524 break;
525 case SMI_INDEX_AUGMENT:
526 if (relatedNode && relatedModule) {
527 fprintIndexModule(f, indent, relatedModule->name,
528 relatedNode->name, "augments");
529 } /* TODO: else print error */
530 break;
531 case SMI_INDEX_REORDER:
532 if (relatedNode && relatedModule) {
533 fprintIndexModule(f, indent, relatedModule->name,
534 relatedNode->name, "reorders");
535 fprintElementList(f, indent + INDENT, "index",
536 smiGetFirstElement(smiNode));
537 } /* TODO: else print error */
538 break;
539 case SMI_INDEX_SPARSE:
540 if (relatedNode && relatedModule) {
541 fprintIndexModule(f, indent, relatedModule->name,
542 relatedNode->name, "sparse");
543 } /* TODO: else print error */
544 break;
545 case SMI_INDEX_EXPAND:
546 if (relatedNode && relatedModule) {
547 fprintIndexModule(f, indent, relatedModule->name,
548 relatedNode->name, "expands");
549 } /* TODO: else print error */
550 break;
551 case SMI_INDEX_UNKNOWN:
552 break;
553 }
554 fprintSegment(f, indent, "],\n", 0);
555 }
556
557
558
fprintModule(FILE * f,SmiModule * smiModule)559 static void fprintModule(FILE *f, SmiModule *smiModule)
560 {
561 SmiRevision *smiRevision;
562 SmiNode *smiNode;
563 int i;
564 char *lang;
565 int there_were_revisions = 0;
566
567 lang = getStringLanguage(smiModule->language);
568 currentModuleName = smiModule->name;
569
570 fprintSegment(f, INDENT, "", 0);
571 fprint(f, "\"%s\" : {\n", smiModule->name);
572 fprintSegment(f, 2 * INDENT, "\"nodetype\" : \"module\",\n", 0);
573 if (lang) {
574 fprintSegment(f, 2 * INDENT, "", 0);
575 fprint(f, "\"language\" : \"%s\",\n", lang);
576 }
577
578 if (smiModule->organization) {
579 fprintSegment(f, 2 * INDENT, "\"organization\" :", INDENTVALUE);
580 fprint(f, "\n");
581 fprintMultilineString(f, 2 * INDENT, smiModule->organization);
582 fprint(f, ",\n");
583 }
584
585 if (smiModule->contactinfo) {
586 fprintSegment(f, 2 * INDENT, "\"contact\" :", INDENTVALUE);
587 fprint(f, "\n");
588 fprintMultilineString(f, 2 * INDENT, smiModule->contactinfo);
589 fprint(f, ",\n");
590 }
591 fprintDescription(f, 2 * INDENT, smiModule->description);
592 fprintReference(f, 2 * INDENT, smiModule->reference);
593
594 for(i = 0, smiRevision = smiGetFirstRevision(smiModule);
595 smiRevision; smiRevision = smiGetNextRevision(smiRevision)) {
596 if (i == 0) {
597 fprintSegment(f, 2 * INDENT, "\"revisions\" : (\n", 0);
598 there_were_revisions = 1;
599 }
600 fprintSegment(f, 3 * INDENT, "{\n", 0);
601 fprintSegment(f, 4 * INDENT, "", 0);
602 fprint(f, "\"date\" : \"%s\",\n",
603 getTimeString(smiRevision->date));
604 fprintDescription(f, 4 * INDENT, smiRevision->description);
605 fprintSegment(f, 3 * INDENT, "},\n", 0);
606 i++;
607 }
608 if (there_were_revisions) {
609 fprintSegment(f, 2 * INDENT, "),\n", 0);
610 }
611
612 smiNode = smiGetModuleIdentityNode(smiModule);
613 if (smiNode) {
614 fprintSegment(f, 2 * INDENT, "", 0);
615 fprint(f, "\"identity node\" : \"%s\",\n", smiNode->name);
616 }
617
618 fprintSegment(f, INDENT, "},\n\n", 0);
619 }
620
621
622
fprintImport(FILE * f,int indent,SmiImport * smiImport)623 static void fprintImport(FILE *f, int indent, SmiImport *smiImport)
624 {
625 fprintSegment(f, indent, "", 0);
626 fprint(f, "{\"module\" : \"%s\", \"name\" : \"%s\"},\n",
627 smiImport->module, smiImport->name);
628 }
629
630
631
fprintImports(FILE * f,SmiModule * smiModule)632 static void fprintImports(FILE *f, SmiModule *smiModule)
633 {
634 SmiImport *smiImport;
635 int i;
636
637 for (i = 0, smiImport = smiGetFirstImport(smiModule);
638 smiImport;
639 i++, smiImport = smiGetNextImport(smiImport)) {
640 if (i == 0) {
641 fprintSegment(f, INDENT, "\"imports\" : (\n", 0);
642 }
643 fprintImport(f, 2 * INDENT, smiImport);
644 }
645
646 if (i) {
647 fprintSegment(f, INDENT, "),\n\n", 0);
648 }
649 }
650
651
652
fprintTypedef(FILE * f,int indent,SmiType * smiType)653 static void fprintTypedef(FILE *f, int indent, SmiType *smiType)
654 {
655 SmiModule *parentModule;
656 SmiType *parentType;
657
658 fprintSegment(f, indent, "", 0);
659 if (smiType->name) {
660 fprint(f, "\"%s\" : ", smiType->name);
661 }
662 fprint(f, "{\n");
663 fprintSegment(f, indent + INDENT, "", 0);
664 fprint(f, "\"basetype\" : \"%s\",\n",
665 getStringBasetype(smiType->basetype));
666 if (smiType->name && smiType->status != SMI_STATUS_UNKNOWN) {
667 fprintSegment(f, indent + INDENT, "", 0);
668 fprint(f, "\"status\" : \"%s\",\n", getStringStatus(smiType->status));
669 }
670
671 parentType = smiGetParentType(smiType);
672 parentModule = smiGetTypeModule(parentType);
673 if (parentType && parentType->name &&
674 parentModule && strlen(parentModule->name)) {
675 fprintSegment(f, indent + INDENT, "\"parent module\" : {\n", 0);
676 fprintSegment(f, indent + (2 * INDENT), "", 0);
677 fprint(f, "\"name\" : \"%s\",\n", parentModule->name);
678 fprintSegment(f, indent + (2 * INDENT), "", 0);
679 fprint(f, "\"type\" : \"%s\",\n", parentType->name);
680 fprintSegment(f, indent + INDENT, "},\n", 0);
681 }
682 fprintRanges(f, indent + INDENT, smiType);
683 fprintNamedNumbers(f, indent + INDENT, smiType);
684 fprintValue(f, indent + INDENT, &smiType->value, smiType);
685 fprintFormat(f, indent + INDENT, smiType->format);
686 fprintUnits(f, indent + INDENT, smiType->units);
687 fprintDescription(f, indent + INDENT, smiType->description);
688 fprintReference(f, indent + INDENT, smiType->reference);
689
690 fprintSegment(f, indent, "},\n", 0);
691 }
692
693
694
fprintTypedefs(FILE * f,SmiModule * smiModule)695 static void fprintTypedefs(FILE *f, SmiModule *smiModule)
696 {
697 int i;
698 SmiType *smiType;
699
700 for(i = 0, smiType = smiGetFirstType(smiModule);
701 smiType;
702 i++, smiType = smiGetNextType(smiType)) {
703
704 if (i == 0) {
705 fprintSegment(f, INDENT, "\"typedefs\" : {\n", 0);
706 }
707 fprintTypedef(f, 2 * INDENT, smiType);
708 }
709
710 if (i) {
711 fprintSegment(f, INDENT, "}, # typedefs\n\n", 0);
712 }
713 }
714
715
716
fprintNode(FILE * f,int indent,SmiNode * smiNode,SmiNode * lastSmiNode)717 static void fprintNode(FILE *f, int indent, SmiNode *smiNode,
718 SmiNode *lastSmiNode)
719 {
720 SmiModule *smiModule;
721 SmiType *smiType;
722 char *tag = NULL;
723
724 if (smiNode->nodekind == SMI_NODEKIND_NODE) {
725 tag = "node";
726 } else if (smiNode->nodekind == SMI_NODEKIND_CAPABILITIES) {
727 tag = "capabilities";
728 } else if (smiNode->nodekind == SMI_NODEKIND_TABLE) {
729 tag = "table";
730 } else if (smiNode->nodekind == SMI_NODEKIND_ROW) {
731 /* indent += INDENT; */
732 tag = "row";
733 } else if (smiNode->nodekind == SMI_NODEKIND_COLUMN) {
734 /* indent += 2 * INDENT; */
735 tag = "column";
736 } else if (smiNode->nodekind == SMI_NODEKIND_SCALAR) {
737 tag = "scalar";
738 }
739
740 /* if (lastSmiNode */
741 /* && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN */
742 /* && smiNode->nodekind != SMI_NODEKIND_COLUMN) { */
743 /* printNodeEndTag(indent + INDENT, "row"); */
744 /* printNodeEndTag(indent, "table"); */
745 /* } */
746
747 smiType = smiGetNodeType(smiNode);
748
749 fprintNodeStartTag(f, indent, tag, smiNode);
750 if (smiType && (smiType->basetype != SMI_BASETYPE_UNKNOWN)) {
751 fprintSegment(f, indent + INDENT, "\"syntax\" : {\n", 0);
752 smiModule = smiGetTypeModule(smiType);
753 fprintSegment(f, indent + 2 *INDENT, "", 0);
754 fprint(f, "\"type\" : ");
755 if (smiType->name && smiModule) {
756 fprintf(f, "{ \"module\" :\"%s\", \"name\" : \"%s\"},\n",
757 smiModule->name, smiType->name);
758 } else {
759 fprintTypedef(f, indent + 2 * INDENT, smiType);
760 }
761 fprintSegment(f, indent + INDENT, "},\n", 0);
762 }
763 if ((smiNode->nodekind != SMI_NODEKIND_TABLE) &&
764 (smiNode->nodekind != SMI_NODEKIND_ROW) &&
765 (smiNode->nodekind != SMI_NODEKIND_CAPABILITIES) &&
766 (smiNode->nodekind != SMI_NODEKIND_NODE)) {
767 fprintAccess(f, indent + INDENT, smiNode->access);
768 }
769 if (smiType) {
770 fprintValue(f, indent + INDENT, &smiNode->value, smiType);
771 }
772 fprintFormat(f, indent + INDENT, smiNode->format);
773 fprintUnits(f, indent + INDENT, smiNode->units);
774 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
775 fprintIndex(f, indent + INDENT, smiNode);
776 }
777 fprintDescription(f, indent + INDENT, smiNode->description);
778 fprintReference(f, indent + INDENT, smiNode->reference);
779
780 #if 0
781 if (smiNode->nodekind != SMI_NODEKIND_ROW
782 && smiNode->nodekind != SMI_NODEKIND_TABLE) {
783 fprintNodeEndTag(f, indent, tag);
784 }
785 #else
786 fprintNodeEndTag(f, indent, tag);
787 #endif
788 }
789
790
791
fprintNodes(FILE * f,SmiModule * smiModule)792 static void fprintNodes(FILE *f, SmiModule *smiModule)
793 {
794 int i;
795 SmiNode *smiNode, *lastSmiNode;
796 SmiNodekind nodekinds;
797
798 nodekinds = SMI_NODEKIND_NODE | SMI_NODEKIND_TABLE |
799 SMI_NODEKIND_ROW | SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR |
800 SMI_NODEKIND_CAPABILITIES;
801
802 for (i = 0,
803 lastSmiNode = NULL,
804 smiNode = smiGetFirstNode(smiModule, nodekinds);
805 smiNode;
806 i++,
807 lastSmiNode = smiNode,
808 smiNode = smiGetNextNode(smiNode, nodekinds)) {
809
810 if (i == 0) {
811 fprintSegment(f, INDENT, "\"nodes\" : {\n", 0);
812 }
813
814 fprintNode(f, 2 * INDENT, smiNode, lastSmiNode);
815 }
816
817 /* if (lastSmiNode */
818 /* && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN) { */
819 /* printNodeEndTag(3 * INDENT, "row"); */
820 /* printNodeEndTag(2 * INDENT, "table"); */
821 /* } */
822
823 if (i) {
824 fprintSegment(f, INDENT, "}, # nodes\n\n", 0);
825 }
826 }
827
828
829
fprintNotification(FILE * f,int indent,SmiNode * smiNode)830 static void fprintNotification(FILE *f, int indent, SmiNode *smiNode)
831 {
832 fprintNodeStartTag(f, indent, "notification", smiNode);
833
834 fprintSegment(f, indent + INDENT, "\"objects\" : {\n", 0);
835 fprintElementList(f, indent + 2 * INDENT, "object",
836 smiGetFirstElement(smiNode));
837 fprintSegment(f, indent + INDENT, "},\n", 0);
838 fprintDescription(f, indent + INDENT, smiNode->description);
839 fprintReference(f, indent + INDENT, smiNode->reference);
840
841 fprintNodeEndTag(f, indent, "notification");
842 }
843
844
845
fprintNotifications(FILE * f,SmiModule * smiModule)846 static void fprintNotifications(FILE *f, SmiModule *smiModule)
847 {
848 SmiNode *smiNode;
849 int i;
850
851 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
852 smiNode;
853 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
854
855 if (i == 0) {
856 fprintSegment(f, INDENT, "\"notifications\" : {\n", 0);
857 }
858 fprintNotification(f, 2 * INDENT, smiNode);
859 }
860
861 if (i) {
862 fprintSegment(f, INDENT, "}, # notifications\n\n", 0);
863 }
864 }
865
866
867
fprintGroup(FILE * f,int indent,SmiNode * smiNode)868 static void fprintGroup(FILE *f, int indent, SmiNode *smiNode)
869 {
870 fprintNodeStartTag(f, indent, "group", smiNode);
871
872 fprintSegment(f, indent + INDENT, "\"members\" : {\n", 0);
873 fprintElementList(f, indent + 2 * INDENT, "member",
874 smiGetFirstElement(smiNode));
875 fprintSegment(f, indent + INDENT, "}, # members\n", 0);
876 fprintDescription(f, indent + INDENT, smiNode->description);
877 fprintReference(f, indent + INDENT, smiNode->reference);
878
879 fprintNodeEndTag(f, indent, "group");
880 }
881
882
883
fprintGroups(FILE * f,SmiModule * smiModule)884 static void fprintGroups(FILE *f, SmiModule *smiModule)
885 {
886 SmiNode *smiNode;
887 int i;
888
889 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
890 smiNode;
891 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
892
893 if (i == 0) {
894 fprintSegment(f, INDENT, "\"groups\" : {\n", 0);
895 }
896 fprintGroup(f, 2 * INDENT, smiNode);
897 }
898
899 if (i) {
900 fprintSegment(f, INDENT, "}, # groups\n\n", 0);
901 }
902 }
903
904
905
fprintComplGroups(FILE * f,int indent,SmiNode * smiNode)906 static void fprintComplGroups(FILE *f, int indent, SmiNode *smiNode)
907 {
908 SmiNode *optSmiNode;
909 SmiModule *optSmiModule;
910 SmiOption *smiOption;
911
912 if (! smiGetFirstElement(smiNode) && !smiGetFirstOption(smiNode)) {
913 return;
914 }
915
916 fprintSegment(f, indent, "\"requires\" : {\n", 0);
917 fprintElementList(f, indent + INDENT, "mandatory",
918 smiGetFirstElement(smiNode));
919
920 for(smiOption = smiGetFirstOption(smiNode);
921 smiOption;
922 smiOption = smiGetNextOption(smiOption)) {
923 optSmiNode = smiGetOptionNode(smiOption);
924 optSmiModule = smiGetNodeModule(optSmiNode);
925 fprintSegment(f, indent + INDENT, "", 0);
926 fprint(f, "\"%s\" : {\n", optSmiNode->name);
927 fprintSegment(f, indent + 2*INDENT,
928 "\"nodetype\" : \"optional\",\n", 0);
929 fprintSegment(f, indent + 2*INDENT, "", 0);
930 fprint(f, "\"module\" : \"%s\",\n", optSmiModule->name);
931 fprintDescription(f, indent + 2 * INDENT, smiOption->description);
932 fprintSegment(f, indent + INDENT, "},\n", 0);
933 }
934
935 fprintSegment(f, indent, "}, # requires\n", 0);
936 }
937
938
939
fprintRefinement(FILE * f,int indent,SmiRefinement * smiRefinement)940 static void fprintRefinement(FILE *f, int indent, SmiRefinement *smiRefinement)
941 {
942 SmiModule *smiModule;
943 SmiNode *smiNode;
944 SmiType *smiType;
945
946 smiNode = smiGetRefinementNode(smiRefinement);
947 smiModule = smiGetNodeModule(smiNode);
948
949 fprintSegment(f, indent, "", 0);
950 fprint(f, "\"%s\" : {\n", smiNode->name);
951 fprintSegment(f, indent + INDENT, "", 0);
952 fprint(f, "\"module\" : \"%s\",\n", smiModule->name);
953
954 smiType = smiGetRefinementType(smiRefinement);
955 if (smiType) {
956 fprintSegment(f, indent + INDENT, "\"syntax\" : {\n", 0);
957 fprintSegment(f, indent + 2*INDENT, "\"type\" : ", 0);
958 fprintTypedef(f, indent + 2 * INDENT, smiType);
959 fprintSegment(f, indent + INDENT, "}, # syntax\n", 0);
960 }
961
962 smiType = smiGetRefinementWriteType(smiRefinement);
963 if (smiType) {
964 fprintSegment(f, indent + INDENT, "\"writesyntax\" : {\n", 0);
965 fprintSegment(f, indent + 2*INDENT, "\"type\" : ", 0);
966 fprintTypedef(f, indent + 2 * INDENT, smiType);
967 fprintSegment(f, indent + INDENT, "}, # writesyntax\n", 0);
968 }
969
970 if (smiRefinement->access != SMI_ACCESS_UNKNOWN) {
971 fprintAccess(f, indent + INDENT, smiRefinement->access);
972 }
973 fprintDescription(f, indent + INDENT, smiRefinement->description);
974 fprintSegment(f, indent, "},\n", 0);
975 }
976
977
978
fprintRefinements(FILE * f,int indent,SmiNode * smiNode)979 static void fprintRefinements(FILE *f, int indent, SmiNode *smiNode)
980 {
981 SmiRefinement *smiRefinement;
982 int i;
983
984 for(i = 0, smiRefinement = smiGetFirstRefinement(smiNode);
985 smiRefinement;
986 i++, smiRefinement = smiGetNextRefinement(smiRefinement)) {
987
988 if (!i) {
989 fprintSegment(f, indent, "\"refinements\" : {\n", 0);
990 }
991
992 fprintRefinement(f, indent + INDENT, smiRefinement);
993 }
994
995 if (i) {
996 fprintSegment(f, indent, "}, # refinements\n\n", 0);
997 }
998 }
999
1000
1001
fprintCompliance(FILE * f,int indent,SmiNode * smiNode)1002 static void fprintCompliance(FILE *f, int indent, SmiNode *smiNode)
1003 {
1004 fprintNodeStartTag(f, indent, "compliance", smiNode);
1005
1006 fprintDescription(f, indent + INDENT, smiNode->description);
1007 fprintReference(f, indent + INDENT, smiNode->reference);
1008 fprintComplGroups(f, indent + INDENT, smiNode);
1009 fprintRefinements(f, indent + INDENT, smiNode);
1010
1011 fprintNodeEndTag(f, indent, "compliance");
1012 }
1013
1014
1015
fprintCompliances(FILE * f,SmiModule * smiModule)1016 static void fprintCompliances(FILE *f, SmiModule *smiModule)
1017 {
1018 SmiNode *smiNode;
1019 int i;
1020
1021 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
1022 smiNode;
1023 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
1024
1025 if (!i) {
1026 fprintSegment(f, INDENT, "\"compliances\" : {\n", 0);
1027 }
1028
1029 fprintCompliance(f, 2 * INDENT, smiNode);
1030 }
1031
1032 if (i) {
1033 fprintSegment(f, INDENT, "}, # compliances\n\n", 0);
1034 }
1035 }
1036
1037
1038
dumpPythonModule(FILE * f,SmiModule * smiModule)1039 static void dumpPythonModule(FILE *f, SmiModule *smiModule)
1040 {
1041 if (! silent) {
1042 fprint(f, "# python version 1.0\t\t\t\t\t\tDO NOT EDIT\n#\n");
1043 fprint(f, "# Generated by smidump version "
1044 SMI_VERSION_STRING ":\n#\n");
1045 fprintf(f, "# smidump -f python %s\n\n", smiModule->name);
1046 }
1047
1048 fprint(f, "FILENAME = \"%s\"\n\n", smiModule->path);
1049
1050 fprint(f, "MIB = {\n");
1051 fprintSegment(f, INDENT, "", 0);
1052 fprint(f, "\"moduleName\" : \"%s\",\n\n", smiModule->name);
1053
1054 fprintModule(f, smiModule);
1055 fprintImports(f, smiModule);
1056 fprintTypedefs(f, smiModule);
1057 fprintNodes(f, smiModule);
1058 fprintNotifications(f, smiModule);
1059 fprintGroups(f, smiModule);
1060 fprintCompliances(f, smiModule);
1061
1062 fprint(f, "}\n");
1063 }
1064
1065
1066
dumpPython(int modc,SmiModule ** modv,int flags,char * output)1067 static void dumpPython(int modc, SmiModule **modv, int flags, char *output)
1068 {
1069 int i;
1070 FILE *f = stdout;
1071
1072 silent = (flags & SMIDUMP_FLAG_SILENT);
1073
1074 if (output) {
1075 f = fopen(output, "w");
1076 if (!f) {
1077 fprintf(stderr, "smidump: cannot open %s for writing: ", output);
1078 perror(NULL);
1079 exit(1);
1080 }
1081 }
1082
1083 for (i = 0; i < modc; i++) {
1084 dumpPythonModule(f, modv[i]);
1085 }
1086
1087 if (fflush(f) || ferror(f)) {
1088 perror("smidump: write error");
1089 exit(1);
1090 }
1091
1092 if (output) {
1093 fclose(f);
1094 }
1095 }
1096
1097
1098
initPython()1099 void initPython()
1100 {
1101 static SmidumpDriver driver = {
1102 "python",
1103 dumpPython,
1104 0,
1105 SMIDUMP_DRIVER_CANT_UNITE,
1106 "Python MIB dictionaries",
1107 NULL,
1108 NULL
1109 };
1110
1111 smidumpRegisterDriver(&driver);
1112 }
1113