4 * Operations to dump SMIng module information in Perl format.
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 * Copyright (c) 2000 Martin Schulz martin.schulz@myrealbox.com
11 * See the file "COPYING" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * @(#) $Id: dump-perl.c 8090 2008-04-18 12:56:29Z strauss $
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 */
43 typedef struct PerlEscape {
48 static PerlEscape perlEscapes [] = {
55 static int current_column = 0;
57 static char* currentModuleName = NULL;
59 static char *getStringLanguage(SmiLanguage lang)
62 (lang == SMI_LANGUAGE_SMIV1) ? "SMIv1" :
63 (lang == SMI_LANGUAGE_SMIV2) ? "SMIv2" :
64 (lang == SMI_LANGUAGE_SMING) ? "SMIng" :
70 static char *getStringStatus(SmiStatus status)
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" :
83 static char *getAccessString(SmiAccess access)
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" :
95 static char *getStringBasetype(SmiBasetype basetype)
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" :
115 static char *getTimeString(time_t 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);
129 static void fprint(FILE *f, char *fmt, ...)
136 current_column += smiVasprintf(&s, fmt, ap);
139 if ((p = strrchr(s, '\n'))) {
140 current_column = strlen(p) - 1;
147 static void fprintSegment(FILE *f, int column, char *string, int length)
149 fprint(f, "%*c%s", column, ' ', string);
151 fprint(f, "%*c", length - strlen(string) - column, ' ');
157 static void fprintMultilineString(FILE *f, int column, const char *s)
162 fprintSegment(f, column + INDENTTEXTS, "", 0);
168 for (i=0; i < len; i++) {
169 for (j = 0; perlEscapes[j].character; j++) {
170 if (perlEscapes[j].character == s[i]) break;
172 if (perlEscapes[j].character) {
173 fputs(perlEscapes[j].escape, f);
174 current_column += strlen(perlEscapes[j].escape);
191 static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
201 switch (valuePtr->basetype) {
202 case SMI_BASETYPE_UNSIGNED32:
203 sprintf(s, "%lu", valuePtr->value.unsigned32);
205 case SMI_BASETYPE_INTEGER32:
206 sprintf(s, "%ld", valuePtr->value.integer32);
208 case SMI_BASETYPE_UNSIGNED64:
209 sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
211 case SMI_BASETYPE_INTEGER64:
212 sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
214 case SMI_BASETYPE_FLOAT32:
215 case SMI_BASETYPE_FLOAT64:
216 case SMI_BASETYPE_FLOAT128:
218 case SMI_BASETYPE_ENUM:
219 for (nn = smiGetFirstNamedNumber(typePtr); nn;
220 nn = smiGetNextNamedNumber(nn)) {
221 if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
225 sprintf(s, "%s", nn->name);
227 sprintf(s, "%ld", valuePtr->value.integer32);
230 case SMI_BASETYPE_OCTETSTRING:
231 for (i = 0; i < valuePtr->len; i++) {
232 if (!isprint((int)valuePtr->value.ptr[i])) break;
234 if (i == valuePtr->len) {
235 sprintf(s, "%s", valuePtr->value.ptr);
237 sprintf(s, "0x%*s", 2 * valuePtr->len, "");
238 for (i=0; i < valuePtr->len; i++) {
239 sprintf(ss, "%02x", valuePtr->value.ptr[i]);
240 strncpy(&s[2+2*i], ss, 2);
244 case SMI_BASETYPE_BITS:
246 for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
247 if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
249 sprintf(&s[strlen(s)], ", ");
251 for (nn = smiGetFirstNamedNumber(typePtr); nn;
252 nn = smiGetNextNamedNumber(nn)) {
253 if (nn->value.value.unsigned32 == i)
257 sprintf(&s[strlen(s)], "%s", nn->name);
263 sprintf(&s[strlen(s)], ")");
265 case SMI_BASETYPE_UNKNOWN:
267 case SMI_BASETYPE_POINTER:
269 case SMI_BASETYPE_OBJECTIDENTIFIER:
270 for (i = 0; i < valuePtr->len; i++) {
271 sprintf(&s[strlen(s)], i ? ".%u" : "%u", valuePtr->value.oid[i]);
281 static void fprintNodeStartTag(FILE *f, int indent, const char *tag,
286 fprintSegment(f, indent, "", 0);
287 fprint(f, "{\n", smiNode->name);
288 fprintSegment(f, indent + INDENT, "", 0);
289 fprint(f, "\"name\" => \"%s\",\n", smiNode->name);
290 fprintSegment(f, indent + INDENT, "", 0);
291 fprint(f, "\"type\" => \"%s\",\n", tag);
292 fprintSegment(f, indent + INDENT, "", 0);
293 fprint(f, "\"module\" => \"%s\",\n", currentModuleName);
294 fprintSegment(f, indent + INDENT, "", 0);
295 fprint(f, "\"oid\" => \"");
296 for (i = 0; i < smiNode->oidlen; i++) {
297 fprint(f, i ? ".%u" : "%u", smiNode->oid[i]);
301 if (smiNode->create) {
303 fprintSegment(f, indent + INDENT, "\"create\" => \"true\"", 0);
305 if (smiNode->status != SMI_STATUS_UNKNOWN) {
307 fprintSegment(f, indent + INDENT, "", 0);
308 fprint(f, "\"status\" => \"%s\"", getStringStatus(smiNode->status));
310 if (smiNode->implied) {
312 fprintSegment(f, indent + INDENT, "\"implied\" => \"true\"", 0);
319 static void fprintNodeEndTag(FILE *f, int indent, const char *tag,
322 fprintSegment(f, indent, "", 0);
323 fprint(f, "}, # %s\n", name);
328 static void fprintRanges(FILE *f, int indent, SmiType *smiType)
334 if (! smiGetFirstRange(smiType)) {
338 fprintSegment(f, indent, "\"ranges\" => (\n", 0);
339 for (range = smiGetFirstRange(smiType);
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);
351 fprintSegment(f, indent, "),\n", 0);
353 rc = smiGetMinMaxRange(smiType, &min, &max);
356 && min.basetype != SMI_BASETYPE_UNKNOWN
357 && max.basetype != SMI_BASETYPE_UNKNOWN) {
358 fprintSegment(f, indent, "\"range\" => {\n", 0);
359 fprintSegment(f, indent + INDENT, "", 0);
360 fprint(f, "\"min\" => \"%s\",\n",
361 getValueString(&min, smiType));
362 fprintSegment(f, indent + INDENT, "", 0);
363 fprint(f, "\"max\" => \"%s\"\n",
364 getValueString(&max, smiType));
365 fprintSegment(f, indent, "},\n", 0);
371 static void fprintNamedNumbers(FILE *f, int indent, SmiType *smiType)
375 if ((smiType->basetype != SMI_BASETYPE_ENUM) &&
376 (smiType->basetype != SMI_BASETYPE_BITS)) {
380 for (nn = smiGetFirstNamedNumber(smiType);
382 nn = smiGetNextNamedNumber(nn)) {
383 fprintSegment(f, indent, "\"", 0);
384 fprint(f, "%s\" => ", nn->name);
385 fprint(f, "\"%s\",\n", getValueString(&nn->value, smiType));
391 static void fprintValue(FILE *f, int indent, SmiValue *smiValue,
394 if (smiType && smiValue && smiValue->basetype != SMI_BASETYPE_UNKNOWN) {
395 fprintSegment(f, indent, "\"DEFVAL\" => ", 0);
396 fprint(f, "\"%s\"", getValueString(smiValue, smiType));
403 static void fprintDescription(FILE *f, int indent, const char *description)
406 fprintSegment(f, indent, "\"description\" =>\n", 0);
407 fprintMultilineString(f, indent, description);
414 static void fprintReference(FILE *f, int indent, const char *reference)
417 fprintSegment(f, indent, "\"reference>\" =>\n", 0);
418 fprintMultilineString(f, indent, reference);
425 static void fprintFormat(FILE *f, int indent, const char *format)
428 fprintSegment(f, indent, "", 0);
429 fprint(f, "\"DISPLAY-HINT\" => \"%s\",\n", format);
435 static void fprintUnits(FILE *f, int indent, const char *units)
438 fprintSegment(f, indent, "", 0);
439 fprint(f, "\"UNITS\" => \"%s\",\n", units);
445 static void fprintAccess(FILE *f, int indent, SmiAccess smiAccess)
447 if (smiAccess != SMI_ACCESS_UNKNOWN) {
448 fprintSegment(f, indent, "", 0);
449 fprint(f, "\"access\" => \"%s\",\n", getAccessString(smiAccess));
455 static void fprintElementList(FILE *f, int indent, const char *tag,
456 SmiElement *smiElement, int asArray)
458 SmiModule *smiModule;
461 for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
462 smiNode = smiGetElementNode(smiElement);
463 smiModule = smiGetNodeModule(smiNode);
464 fprintSegment(f, indent, "", 0);
468 fprintSegment(f, indent + INDENT, "", 0);
469 fprint(f, "\"name\" => \"%s\",\n", smiNode->name);
471 fprint(f, "\"%s\" => {\n", smiNode->name);
473 fprintSegment(f, indent + INDENT, "", 0);
474 fprint(f, "\"type\" => \"%s\",\n", tag);
475 fprintSegment(f, indent + INDENT, "", 0);
476 fprint(f, "\"module\" => \"%s\"\n", smiModule->name);
477 fprintSegment(f, indent, "},\n", 0);
480 fprint(f, "{ \"module\" => \"%s\", ", smiModule->name);
481 fprint(f, "\"name\" => \"%s\" },\n", smiNode->name);
483 fprint(f, "\"%s\" => \"%s\",\n", smiNode->name, smiModule->name);
491 static void fprintIndexModule(FILE *f, int indent, const char *modname,
492 const char *nodename, const char *indexkind)
494 fprintSegment(f, indent, "", 0);
495 fprint(f, "\"%s\" => {\n", indexkind);
496 fprintSegment(f, indent + INDENT, "", 0);
497 fprint(f, "\"module\" => \"%s\",\n", modname);
498 fprintSegment(f, indent + INDENT, "", 0);
499 fprint(f, "\"name\" => \"%s\",\n", nodename);
500 fprintSegment(f, indent, "},\n", 0);
505 static void fprintIndex(FILE *f, int indent, SmiNode *smiNode)
507 SmiNode *relatedNode;
508 SmiModule *relatedModule = NULL;
510 if (smiNode->implied) {
511 fprintSegment(f, indent, "\"indeximplied\" => \"true\",\n", 0);
514 relatedNode = smiGetRelatedNode(smiNode);
516 relatedModule = smiGetNodeModule(relatedNode);
518 switch (smiNode->indexkind) {
519 case SMI_INDEX_INDEX:
520 fprintSegment(f, indent, "\"index\" => [\n", 0);
521 fprintElementList(f, indent + INDENT, NULL,
522 smiGetFirstElement(smiNode), 1);
523 fprintSegment(f, indent, "], #index\n", 0);
525 case SMI_INDEX_AUGMENT:
526 if (relatedNode && relatedModule) {
527 fprintIndexModule(f, indent, relatedModule->name,
528 relatedNode->name, "augments");
529 } /* TODO: else print error */
531 case SMI_INDEX_REORDER:
532 if (relatedNode && relatedModule) {
533 fprintIndexModule(f, indent, relatedModule->name,
534 relatedNode->name, "reorders");
535 fprintSegment(f, indent, "\"index\" => [\n", 0);
536 fprintElementList(f, indent + INDENT, NULL,
537 smiGetFirstElement(smiNode), 1);
538 fprintSegment(f, indent, "], #index\n", 0);
539 } /* TODO: else print error */
541 case SMI_INDEX_SPARSE:
542 if (relatedNode && relatedModule) {
543 fprintIndexModule(f, indent, relatedModule->name,
544 relatedNode->name, "sparse");
545 } /* TODO: else print error */
547 case SMI_INDEX_EXPAND:
548 if (relatedNode && relatedModule) {
549 fprintIndexModule(f, indent, relatedModule->name,
550 relatedNode->name, "expands");
551 } /* TODO: else print error */
553 case SMI_INDEX_UNKNOWN:
560 static void fprintModule(FILE *f, SmiModule *smiModule)
562 SmiRevision *smiRevision;
565 int there_were_revisions = 0;
567 currentModuleName = smiModule->name;
569 if (smiModule->organization) {
570 fprintSegment(f, INDENT, "\"organization\" =>", INDENTVALUE);
572 fprintMultilineString(f, INDENT, smiModule->organization);
576 if (smiModule->contactinfo) {
577 fprintSegment(f, INDENT, "\"contact\" =>", INDENTVALUE);
579 fprintMultilineString(f, INDENT, smiModule->contactinfo);
582 fprintDescription(f, INDENT, smiModule->description);
583 fprintReference(f, INDENT, smiModule->reference);
585 for(i = 0, smiRevision = smiGetFirstRevision(smiModule);
586 smiRevision; smiRevision = smiGetNextRevision(smiRevision)) {
588 fprintSegment(f, INDENT, "\"revisions\" => [\n", 0);
589 there_were_revisions = 1;
591 fprintSegment(f, 2 * INDENT, "{\n", 0);
592 fprintSegment(f, 3 * INDENT, "", 0);
593 fprint(f, "\"date\" => \"%s\",\n",
594 getTimeString(smiRevision->date));
595 fprintDescription(f, 3 * INDENT, smiRevision->description);
596 fprintSegment(f, 2 * INDENT, "},\n", 0);
599 if (there_were_revisions) {
600 fprintSegment(f, INDENT, "],\n", 0);
603 smiNode = smiGetModuleIdentityNode(smiModule);
605 fprintSegment(f, INDENT, "", 0);
606 fprint(f, "\"identity\" => \"%s\",\n", smiNode->name);
613 static void fprintImports(FILE *f, SmiModule *smiModule)
615 SmiImport *smiImport;
616 SmiIdentifier lastModule = NULL;
619 for (i = 0, smiImport = smiGetFirstImport(smiModule);
622 smiImport = smiGetNextImport(smiImport)) {
624 fprintSegment(f, INDENT, "\"imports\" => [\n", 0);
626 if (smiImport->module == NULL)
629 if ( lastModule == NULL || strcmp(lastModule, smiImport->module)) {
631 fprintSegment(f, 3 * INDENT, "]\n", 0);
632 fprintSegment(f, 2 * INDENT, "},\n", 0);
634 fprintSegment(f, 2 * INDENT, "{\n", 0);
635 fprintSegment(f, 3 * INDENT, "", 0);
636 fprint(f, "\"module\" => \"%s\",\n",
638 fprintSegment(f, 3 * INDENT, "\"names\" => [\n", 0);
640 fprintSegment(f, 4 * INDENT, "", 0);
641 fprint(f, "\"%s\",\n", smiImport->name);
642 lastModule = smiImport->module;
645 fprintSegment(f, 3 * INDENT, "],\n", 0);
646 fprintSegment(f, 2 * INDENT, "}\n", 0);
650 fprintSegment(f, INDENT, "], # imports\n\n", 0);
656 static void fprintTypedef(FILE *f, int indent, SmiType *smiType)
658 SmiModule *parentModule;
661 fprintSegment(f, indent, "", 0);
663 fprint(f, "\"%s\" => ", smiType->name);
666 fprintSegment(f, indent + INDENT, "", 0);
667 fprint(f, "\"basetype\" => \"%s\",\n",
668 getStringBasetype(smiType->basetype));
669 if (smiType->name && smiType->status != SMI_STATUS_UNKNOWN) {
670 fprintSegment(f, indent + INDENT, "", 0);
671 fprint(f, "\"status\" => \"%s\",\n", getStringStatus(smiType->status));
674 parentType = smiGetParentType(smiType);
675 parentModule = smiGetTypeModule(parentType);
676 if (parentType && parentModule && strlen(parentModule->name)) {
677 fprintSegment(f, indent + INDENT, "\"parent\" => {\n", 0);
678 fprintSegment(f, indent + (2 * INDENT), "", 0);
679 fprint(f, "\"module\" => \"%s\",\n", parentModule->name);
680 fprintSegment(f, indent + (2 * INDENT), "", 0);
681 fprint(f, "\"name\" => \"%s\",\n", parentType->name);
682 fprintSegment(f, indent + INDENT, "},\n", 0);
684 fprintRanges(f, indent + INDENT, smiType);
685 fprintNamedNumbers(f, indent + INDENT, smiType);
686 fprintValue(f, indent + INDENT, &smiType->value, smiType);
687 fprintFormat(f, indent + INDENT, smiType->format);
688 fprintUnits(f, indent + INDENT, smiType->units);
689 fprintDescription(f, indent + INDENT, smiType->description);
690 fprintReference(f, indent + INDENT, smiType->reference);
692 fprintSegment(f, indent, "},", 0);
694 fprint(f, " # %s\n", smiType->name);
696 fprint(f, "\n", smiType->name);
702 static void fprintTypedefs(FILE *f, SmiModule *smiModule)
707 for(i = 0, smiType = smiGetFirstType(smiModule);
709 i++, smiType = smiGetNextType(smiType)) {
712 fprintSegment(f, INDENT, "\"typedefs\" => {\n", 0);
714 fprintTypedef(f, 2 * INDENT, smiType);
718 fprintSegment(f, INDENT, "}, # typedefs\n\n", 0);
724 static void fprintNode(FILE *f, int indent, SmiNode *smiNode,
725 SmiNode *lastSmiNode)
727 SmiModule *smiModule;
731 if (smiNode->nodekind == SMI_NODEKIND_NODE) {
733 } else if (smiNode->nodekind == SMI_NODEKIND_CAPABILITIES) {
734 tag = "capabilities";
735 } else if (smiNode->nodekind == SMI_NODEKIND_TABLE) {
737 } else if (smiNode->nodekind == SMI_NODEKIND_ROW) {
738 /* indent += INDENT; */
740 } else if (smiNode->nodekind == SMI_NODEKIND_COLUMN) {
741 /* indent += 2 * INDENT; */
743 } else if (smiNode->nodekind == SMI_NODEKIND_SCALAR) {
747 /* if (lastSmiNode */
748 /* && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN */
749 /* && smiNode->nodekind != SMI_NODEKIND_COLUMN) { */
750 /* printNodeEndTag(indent + INDENT, "row", smiNode->name); */
751 /* printNodeEndTag(indent, "table", smiNode->name); */
754 smiType = smiGetNodeType(smiNode);
756 fprintNodeStartTag(f, indent, tag, smiNode);
757 fprintDescription(f, indent + INDENT, smiNode->description);
758 fprintReference(f, indent + INDENT, smiNode->reference);
760 if (smiType && (smiType->basetype != SMI_BASETYPE_UNKNOWN)) {
761 fprintSegment(f, indent + INDENT, "\"syntax\" => {\n", 0);
762 smiModule = smiGetTypeModule(smiType);
763 fprintSegment(f, indent + 2 *INDENT, "", 0);
764 fprint(f, "\"type\" => ");
765 if (smiType->name && smiModule) {
766 fprint(f, "{ \"module\" => \"%s\", \"name\" => \"%s\"},\n",
767 smiModule->name, smiType->name);
770 fprintTypedef(f, indent + 2 * INDENT, smiType);
772 fprintSegment(f, indent + INDENT, "},\n", 0);
774 if ((smiNode->nodekind != SMI_NODEKIND_TABLE) &&
775 (smiNode->nodekind != SMI_NODEKIND_ROW) &&
776 (smiNode->nodekind != SMI_NODEKIND_CAPABILITIES) &&
777 (smiNode->nodekind != SMI_NODEKIND_NODE)) {
778 fprintAccess(f, indent + INDENT, smiNode->access);
781 fprintValue(f, indent + INDENT, &smiNode->value, smiType);
783 fprintFormat(f, indent + INDENT, smiNode->format);
784 fprintUnits(f, indent + INDENT, smiNode->units);
785 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
786 fprintIndex(f, indent + INDENT, smiNode);
789 fprintNodeEndTag(f, indent, tag, smiNode->name);
794 static void fprintNodes(FILE *f, SmiModule *smiModule)
797 SmiNode *smiNode, *lastSmiNode;
798 SmiNodekind nodekinds;
800 nodekinds = SMI_NODEKIND_NODE | SMI_NODEKIND_TABLE |
801 SMI_NODEKIND_ROW | SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR |
802 SMI_NODEKIND_CAPABILITIES;
806 smiNode = smiGetFirstNode(smiModule, nodekinds);
809 lastSmiNode = smiNode,
810 smiNode = smiGetNextNode(smiNode, nodekinds)) {
813 fprintSegment(f, INDENT, "\"nodes\" => [\n", 0);
816 fprintNode(f, 2 * INDENT, smiNode, lastSmiNode);
819 /* if (lastSmiNode */
820 /* && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN) { */
821 /* printNodeEndTag(3 * INDENT, "row", smiNode->name); */
822 /* printNodeEndTag(2 * INDENT, "table", smiNode->name); */
826 fprintSegment(f, INDENT, "], # nodes\n\n", 0);
832 static void fprintNotification(FILE *f, int indent, SmiNode *smiNode)
834 fprintNodeStartTag(f, indent, "notification", smiNode);
835 fprintDescription(f, indent + INDENT, smiNode->description);
836 fprintReference(f, indent + INDENT, smiNode->reference);
838 fprintSegment(f, indent + INDENT, "\"objects\" => [\n", 0);
839 fprintElementList(f, indent + 2 * INDENT, NULL,
840 smiGetFirstElement(smiNode), 1);
841 fprintSegment(f, indent + INDENT, "],\n", 0);
843 fprintNodeEndTag(f, indent, "notification", smiNode->name);
848 static void fprintNotifications(FILE *f, SmiModule *smiModule)
853 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
855 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
858 fprintSegment(f, INDENT, "\"notifications\" => [\n", 0);
860 fprintNotification(f, 2 * INDENT, smiNode);
864 fprintSegment(f, INDENT, "], # notifications\n\n", 0);
870 static void fprintGroup(FILE *f, int indent, SmiNode *smiNode)
872 fprintNodeStartTag(f, indent, "group", smiNode);
873 fprintDescription(f, indent + INDENT, smiNode->description);
874 fprintReference(f, indent + INDENT, smiNode->reference);
876 fprintSegment(f, indent + INDENT, "\"members\" => [\n", 0);
877 fprintElementList(f, indent + 2 * INDENT, NULL,
878 smiGetFirstElement(smiNode), 1);
879 fprintSegment(f, indent + INDENT, "], # members\n", 0);
881 fprintNodeEndTag(f, indent, "group", smiNode->name);
886 static void fprintGroups(FILE *f, SmiModule *smiModule)
891 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
893 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
896 fprintSegment(f, INDENT, "\"groups\" => [\n", 0);
898 fprintGroup(f, 2 * INDENT, smiNode);
902 fprintSegment(f, INDENT, "], # groups\n\n", 0);
908 static void fprintComplGroups(FILE *f, int indent, SmiNode *smiNode)
911 SmiModule *optSmiModule;
912 SmiOption *smiOption;
914 if (! smiGetFirstElement(smiNode) && !smiGetFirstOption(smiNode)) {
918 fprintSegment(f, indent, "\"requires\" => [\n", 0);
919 fprintElementList(f, indent + INDENT, "mandatory",
920 smiGetFirstElement(smiNode), 1);
922 for(smiOption = smiGetFirstOption(smiNode);
924 smiOption = smiGetNextOption(smiOption)) {
925 optSmiNode = smiGetOptionNode(smiOption);
926 optSmiModule = smiGetNodeModule(optSmiNode);
927 fprintSegment(f, indent + INDENT, "", 0);
928 fprint(f, "\"%s\" => {\n", optSmiNode->name);
929 fprintSegment(f, indent + 2*INDENT, "\"type\" => \"optional\",\n", 0);
930 fprintSegment(f, indent + 2*INDENT, "", 0);
931 fprint(f, "\"module\" => \"%s\",\n", optSmiModule->name);
932 fprintDescription(f, indent + 2 * INDENT, smiOption->description);
933 fprintSegment(f, indent + INDENT, "},\n", 0);
936 fprintSegment(f, indent, "], # requires\n", 0);
941 static void fprintRefinement(FILE *f, int indent, SmiRefinement *smiRefinement)
943 SmiModule *smiModule;
947 smiNode = smiGetRefinementNode(smiRefinement);
948 smiModule = smiGetNodeModule(smiNode);
950 fprintSegment(f, indent, "", 0);
951 fprint(f, "\"%s\" => {\n", smiNode->name);
952 fprintSegment(f, indent + INDENT, "", 0);
953 fprint(f, "\"module\" => \"%s\",\n", smiModule->name);
955 smiType = smiGetRefinementType(smiRefinement);
957 fprintSegment(f, indent + INDENT, "\"syntax\" => {\n", 0);
958 fprintSegment(f, indent + 2*INDENT, "\"type\" => ", 0);
959 fprintTypedef(f, indent + 2 * INDENT, smiType);
960 fprintSegment(f, indent + INDENT, "},\n", 0);
963 smiType = smiGetRefinementWriteType(smiRefinement);
965 fprintSegment(f, indent + INDENT, "\"writesyntax\" => {\n", 0);
966 fprintSegment(f, indent + 2*INDENT, "\"type\" => ", 0);
967 fprintTypedef(f, indent + 2 * INDENT, smiType);
968 fprintSegment(f, indent + INDENT, "},\n", 0);
971 if (smiRefinement->access != SMI_ACCESS_UNKNOWN) {
972 fprintAccess(f, indent + INDENT, smiRefinement->access);
974 fprintDescription(f, indent + INDENT, smiRefinement->description);
975 fprintSegment(f, indent, "},\n", 0);
980 static void fprintRefinements(FILE *f, int indent, SmiNode *smiNode)
982 SmiRefinement *smiRefinement;
985 for(i = 0, smiRefinement = smiGetFirstRefinement(smiNode);
987 i++, smiRefinement = smiGetNextRefinement(smiRefinement)) {
990 fprintSegment(f, indent, "\"refinements\" => {\n", 0);
993 fprintRefinement(f, indent + INDENT, smiRefinement);
997 fprintSegment(f, indent, "}, # refinements\n\n", 0);
1003 static void fprintCompliance(FILE *f, int indent, SmiNode *smiNode)
1005 fprintNodeStartTag(f, indent, "compliance", smiNode);
1006 fprintDescription(f, indent + INDENT, smiNode->description);
1007 fprintReference(f, indent + INDENT, smiNode->reference);
1009 fprintComplGroups(f, indent + INDENT, smiNode);
1010 fprintRefinements(f, indent + INDENT, smiNode);
1012 fprintNodeEndTag(f, indent, "compliance", smiNode->name);
1017 static void fprintCompliances(FILE *f, SmiModule *smiModule)
1022 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
1024 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
1027 fprintSegment(f, INDENT, "\"compliances\" => [\n", 0);
1030 fprintCompliance(f, 2 * INDENT, smiNode);
1034 fprintSegment(f, INDENT, "], # compliances\n\n", 0);
1040 static void dumpPerlModule(FILE *f, SmiModule *smiModule)
1046 fprint(f, "# Perl version 5\t\t\t\t\t\tDO NOT EDIT\n#\n");
1047 fprint(f, "# Generated by smidump " SMI_VERSION_STRING ":\n#\n");
1048 fprintf(f, "# smidump -f perl %s\n\n", smiModule->name);
1052 fprint(f, "\"%s\" => {\n", smiModule->name);
1053 fprintSegment(f, INDENT, "", 0);
1054 fprint(f, "\"name\" => \"%s\",\n\n", smiModule->name);
1056 fprintSegment(f, INDENT, "# Compiler Info\n", 0);
1058 fprintSegment(f, INDENT, "", 0);
1059 fprint(f, "\"path\" => \"%s\",\n", smiModule->path);
1061 lang = getStringLanguage(smiModule->language);
1063 fprintSegment(f, INDENT, "", 0);
1064 fprint(f, "\"language\" => \"%s\",\n", lang);
1068 fprintSegment(f, INDENT, "# Module Identity\n", 0);
1069 fprintModule(f, smiModule);
1071 fprintSegment(f, INDENT, "# Imports\n", 0);
1072 fprintImports(f, smiModule);
1073 fprintSegment(f, INDENT, "# Module Body\n", 0);
1074 fprintTypedefs(f, smiModule);
1075 fprintNodes(f, smiModule);
1076 fprintNotifications(f, smiModule);
1077 fprintGroups(f, smiModule);
1078 fprintCompliances(f, smiModule);
1080 fprint(f, " } # %s\n", smiModule->name);
1086 static void dumpPerl(int modc, SmiModule **modv, int flags, char *output)
1092 f = fopen(output, "w");
1094 fprintf(stderr, "smidump: cannot open %s for writing: ", output);
1100 for (i = 0; i < modc; i++) {
1101 dumpPerlModule(f, modv[i]);
1104 if (fflush(f) || ferror(f)) {
1105 perror("smidump: write error");
1118 static SmidumpDriver driver = {
1122 SMIDUMP_DRIVER_CANT_UNITE,
1123 "Perl MIB dictionaries",
1128 smidumpRegisterDriver(&driver);