4 * Operations to dump SMIng module information in XML format.
6 * Copyright (c) 2000 Frank Strauss, Technical University of Braunschweig.
7 * Copyright (c) 2000 J. Schoenwaelder, Technical University of Braunschweig.
9 * See the file "COPYING" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * @(#) $Id: dump-xml.c 8090 2008-04-18 12:56:29Z strauss $
18 * - value representations (getValueString())
19 * - finish DTD and check against it
20 * - shall we nest tables like in SMIng?
37 #define INDENT 2 /* indent factor */
38 #define INDENTVALUE 20 /* column to start values, except multiline */
39 #define INDENTTEXTS 4 /* column to start multiline texts */
40 #define INDENTMAX 64 /* max column to fill, break lines otherwise */
44 static int disableschema = 0;
45 static int disabledoctype = 0;
49 typedef struct XmlEscape {
54 static XmlEscape xmlEscapes [] = {
62 static int current_column = 0;
66 static char *getStringLanguage(SmiLanguage lang)
69 (lang == SMI_LANGUAGE_SMIV1) ? "SMIv1" :
70 (lang == SMI_LANGUAGE_SMIV2) ? "SMIv2" :
71 (lang == SMI_LANGUAGE_SMING) ? "SMIng" :
77 static char *getStringStatus(SmiStatus status)
80 (status == SMI_STATUS_CURRENT) ? "current" :
81 (status == SMI_STATUS_DEPRECATED) ? "deprecated" :
82 (status == SMI_STATUS_OBSOLETE) ? "obsolete" :
83 (status == SMI_STATUS_MANDATORY) ? "mandatory" :
84 (status == SMI_STATUS_OPTIONAL) ? "optional" :
90 static char *getAccessString(SmiAccess access)
93 (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "noaccess" :
94 (access == SMI_ACCESS_NOTIFY) ? "notifyonly" :
95 (access == SMI_ACCESS_READ_ONLY) ? "readonly" :
96 (access == SMI_ACCESS_READ_WRITE) ? "readwrite" :
102 static char *getStringBasetype(SmiBasetype basetype)
105 (basetype == SMI_BASETYPE_UNKNOWN) ? "<UNKNOWN>" :
106 (basetype == SMI_BASETYPE_OCTETSTRING) ? "OctetString" :
107 (basetype == SMI_BASETYPE_OBJECTIDENTIFIER) ? "ObjectIdentifier" :
108 (basetype == SMI_BASETYPE_UNSIGNED32) ? "Unsigned32" :
109 (basetype == SMI_BASETYPE_INTEGER32) ? "Integer32" :
110 (basetype == SMI_BASETYPE_UNSIGNED64) ? "Unsigned64" :
111 (basetype == SMI_BASETYPE_INTEGER64) ? "Integer64" :
112 (basetype == SMI_BASETYPE_FLOAT32) ? "Float32" :
113 (basetype == SMI_BASETYPE_FLOAT64) ? "Float64" :
114 (basetype == SMI_BASETYPE_FLOAT128) ? "Float128" :
115 (basetype == SMI_BASETYPE_ENUM) ? "Enumeration" :
116 (basetype == SMI_BASETYPE_BITS) ? "Bits" :
122 static char *getTimeString(time_t t)
124 static char *s = NULL;
130 smiAsprintf(&s, "%04d-%02d-%02d %02d:%02d",
131 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
132 tm->tm_hour, tm->tm_min);
138 static void fprint(FILE *f, char *fmt, ...)
145 current_column += smiVasprintf(&s, fmt, ap);
148 if ((p = strrchr(s, '\n'))) {
149 current_column = strlen(p) - 1;
156 static void fprintSegment(FILE *f, int column, char *string, int length)
158 fprint(f, "%*c%s", column, ' ', string);
160 fprint(f, "%*c", length - strlen(string) - column, ' ');
166 static void fprintMultilineString(FILE *f, int column, const char *s)
171 fprintSegment(f, column + INDENTTEXTS, "", 0);
175 for (i=0; i < len; i++) {
176 for (j = 0; xmlEscapes[j].character; j++) {
177 if (xmlEscapes[j].character == s[i]) break;
179 if (xmlEscapes[j].character) {
180 fputs(xmlEscapes[j].escape, f);
181 current_column += strlen(xmlEscapes[j].escape);
189 fprintSegment(f, column + INDENTTEXTS, "", 0);
199 static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
209 switch (valuePtr->basetype) {
210 case SMI_BASETYPE_UNSIGNED32:
211 sprintf(s, "%lu", valuePtr->value.unsigned32);
213 case SMI_BASETYPE_INTEGER32:
214 sprintf(s, "%ld", valuePtr->value.integer32);
216 case SMI_BASETYPE_UNSIGNED64:
217 sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
219 case SMI_BASETYPE_INTEGER64:
220 sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
222 case SMI_BASETYPE_FLOAT32:
223 case SMI_BASETYPE_FLOAT64:
224 case SMI_BASETYPE_FLOAT128:
226 case SMI_BASETYPE_ENUM:
227 for (nn = smiGetFirstNamedNumber(typePtr); nn;
228 nn = smiGetNextNamedNumber(nn)) {
229 if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
233 sprintf(s, "%s", nn->name);
235 sprintf(s, "%ld", valuePtr->value.integer32);
238 case SMI_BASETYPE_OCTETSTRING:
239 for (i = 0; i < valuePtr->len; i++) {
240 if (!isprint((int)valuePtr->value.ptr[i])) break;
242 if (i == valuePtr->len) {
243 sprintf(s, "\"%s\"", valuePtr->value.ptr);
245 sprintf(s, "0x%*s", 2 * valuePtr->len, "");
246 for (i=0; i < valuePtr->len; i++) {
247 sprintf(ss, "%02x", valuePtr->value.ptr[i]);
248 strncpy(&s[2+2*i], ss, 2);
252 case SMI_BASETYPE_BITS:
254 for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
255 if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
257 sprintf(&s[strlen(s)], ", ");
259 for (nn = smiGetFirstNamedNumber(typePtr); nn;
260 nn = smiGetNextNamedNumber(nn)) {
261 if (nn->value.value.unsigned32 == i)
265 sprintf(&s[strlen(s)], "%s", nn->name);
271 sprintf(&s[strlen(s)], ")");
273 case SMI_BASETYPE_UNKNOWN:
275 case SMI_BASETYPE_POINTER:
277 case SMI_BASETYPE_OBJECTIDENTIFIER:
278 for (i = 0; i < valuePtr->len; i++) {
279 sprintf(&s[strlen(s)], i ? ".%u" : "%u", valuePtr->value.oid[i]);
289 static void fprintNodeStartTag(FILE *f, int indent,
290 const char *tag, SmiNode *smiNode)
294 fprintSegment(f, indent, "", 0);
295 fprint(f, "<%s name=\"%s\"", tag, smiNode->name);
296 fprint(f, " oid=\"");
297 for (i = 0; i < smiNode->oidlen; i++) {
298 fprint(f, i ? ".%u" : "%u", smiNode->oid[i]);
301 if (smiNode->create) {
302 fprint(f, " create=\"true\"");
304 if (smiNode->status != SMI_STATUS_UNKNOWN) {
305 fprint(f, " status=\"%s\"", getStringStatus(smiNode->status));
312 static void fprintNodeEndTag(FILE *f, int indent, const char *tag)
314 fprintSegment(f, indent, "", 0);
315 fprint(f, "</%s>\n", tag);
320 static void fprintRanges(FILE *f, int indent, SmiType *smiType)
324 for(range = smiGetFirstRange(smiType);
326 range = smiGetNextRange(range)) {
327 fprintSegment(f, indent, "<range", 0);
328 fprint(f, " min=\"%s\"", getValueString(&range->minValue, smiType));
329 fprint(f, " max=\"%s\"", getValueString(&range->maxValue, smiType));
336 static void fprintNamedNumbers(FILE *f, int indent, SmiType *smiType)
340 if ((smiType->basetype != SMI_BASETYPE_ENUM) &&
341 (smiType->basetype != SMI_BASETYPE_BITS)) {
345 for (nn = smiGetFirstNamedNumber(smiType);
347 nn = smiGetNextNamedNumber(nn)) {
348 fprintSegment(f, indent, "<namednumber", 0);
349 fprint(f, " name=\"%s\"", nn->name);
350 fprint(f, " number=\"%s\"", getValueString(&nn->value, smiType));
357 static void fprintValue(FILE *f, int indent, SmiValue *smiValue,
360 if (smiType && smiValue && smiValue->basetype != SMI_BASETYPE_UNKNOWN) {
361 fprintSegment(f, indent, "<default>", 0);
362 fprint(f, "%s", getValueString(smiValue, smiType));
363 fprint(f, "</default>\n");
369 static void fprintDescription(FILE *f, int indent, const char *description)
372 fprintSegment(f, indent, "<description>\n", 0);
373 fprintMultilineString(f, indent, description);
375 fprintSegment(f, indent, "</description>\n", 0);
381 static void fprintReference(FILE *f, int indent, const char *reference)
384 fprintSegment(f, indent, "<reference>\n", 0);
385 fprintMultilineString(f, indent, reference);
387 fprintSegment(f, indent, "</reference>\n", 0);
393 static void fprintFormat(FILE *f, int indent, const char *format)
396 fprintSegment(f, indent, "", 0);
397 fprint(f, "<format>%s</format>\n", format);
403 static void fprintUnits(FILE *f, int indent, const char *units)
406 fprintSegment(f, indent, "", 0);
407 fprint(f, "<units>%s</units>\n", units);
413 static void fprintAccess(FILE *f, int indent, SmiAccess smiAccess)
415 if (smiAccess != SMI_ACCESS_UNKNOWN) {
416 fprintSegment(f, indent, "", 0);
417 fprint(f, "<access>%s</access>\n", getAccessString(smiAccess));
423 static void fprintElementList(FILE *f, int indent, const char *tag,
424 SmiElement *smiElement)
426 SmiModule *smiModule;
429 for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
430 smiNode = smiGetElementNode(smiElement);
431 smiModule = smiGetNodeModule(smiNode);
432 fprintSegment(f, indent, "", 0);
433 fprint(f, "<%s module=\"%s\" name=\"%s\"/>\n",
434 tag, smiModule->name, smiNode->name);
440 static void fprintIndex(FILE *f, int indent, SmiNode *smiNode)
442 SmiNode *relatedNode;
443 SmiModule *relatedModule = NULL;
445 fprintSegment(f, indent, "<linkage", 0);
446 if (smiNode->implied) {
447 fprint(f, " implied=\"true\"");
451 relatedNode = smiGetRelatedNode(smiNode);
453 relatedModule = smiGetNodeModule(relatedNode);
455 switch (smiNode->indexkind) {
456 case SMI_INDEX_INDEX:
457 fprintElementList(f, indent + INDENT, "index",
458 smiGetFirstElement(smiNode));
460 case SMI_INDEX_AUGMENT:
461 if (relatedNode && relatedModule) {
462 fprintSegment(f, indent + INDENT, "", 0);
463 fprint(f, "<augments module=\"%s\" name=\"%s\"/>\n",
464 relatedModule->name, relatedNode->name);
465 } /* TODO: else print error */
467 case SMI_INDEX_REORDER:
468 if (relatedNode && relatedModule) {
469 fprintSegment(f, indent + INDENT, "", 0);
470 fprint(f, "<reorders module=\"%s\" name=\"%s\"/>\n",
471 relatedModule->name, relatedNode->name);
472 fprintElementList(f, indent + INDENT, "index",
473 smiGetFirstElement(smiNode));
474 } /* TODO: else print error */
476 case SMI_INDEX_SPARSE:
477 if (relatedNode && relatedModule) {
478 fprintSegment(f, indent + INDENT, "", 0);
479 fprint(f, "<sparse module=\"%s\" name=\"%s\"/>\n",
480 relatedModule->name, relatedNode->name);
481 } /* TODO: else print error */
483 case SMI_INDEX_EXPAND:
484 if (relatedNode && relatedModule) {
485 fprintSegment(f, indent + INDENT, "", 0);
486 fprint(f, "<expands module=\"%s\" name=\"%s\"/>\n",
487 relatedModule->name, relatedNode->name);
488 fprintElementList(f, indent + INDENT, "index",
489 smiGetFirstElement(smiNode));
490 } /* TODO: else print error */
492 case SMI_INDEX_UNKNOWN:
495 fprintSegment(f, indent, "</linkage>\n", 0);
500 static void fprintModule(FILE *f, SmiModule *smiModule)
502 SmiRevision *smiRevision;
507 lang = getStringLanguage(smiModule->language);
509 fprintSegment(f, INDENT, "", 0);
511 fprint(f, "<module name=\"%s\" language=\"%s\">\n",
512 smiModule->name, lang);
514 fprint(f, "<module name=\"%s\">\n", smiModule->name);
517 if (smiModule->organization) {
518 fprintSegment(f, 2 * INDENT, "<organization>", INDENTVALUE);
520 fprintMultilineString(f, 2 * INDENT, smiModule->organization);
522 fprintSegment(f, 2 * INDENT, "</organization>\n", 0);
525 if (smiModule->contactinfo) {
526 fprintSegment(f, 2 * INDENT, "<contact>", INDENTVALUE);
528 fprintMultilineString(f, 2 * INDENT, smiModule->contactinfo);
530 fprintSegment(f, 2 * INDENT, "</contact>\n", 0);
532 fprintDescription(f, 2 * INDENT, smiModule->description);
533 fprintReference(f, 2 * INDENT, smiModule->reference);
535 for(i = 0, smiRevision = smiGetFirstRevision(smiModule);
536 smiRevision; smiRevision = smiGetNextRevision(smiRevision)) {
537 fprintSegment(f, 2 * INDENT, "", 0);
538 fprint(f, "<revision date=\"%s\">\n",
539 getTimeString(smiRevision->date));
540 fprintDescription(f, 3 * INDENT, smiRevision->description);
541 fprintSegment(f, 2 * INDENT, "</revision>\n", 0);
545 smiNode = smiGetModuleIdentityNode(smiModule);
547 fprintSegment(f, 2 * INDENT, "", 0);
548 fprint(f, "<identity node=\"%s\"/>\n", smiNode->name);
551 fprintSegment(f, INDENT, "</module>\n\n", 0);
556 static void fprintImport(FILE *f, int indent, SmiImport *smiImport)
558 fprintSegment(f, indent, "", 0);
559 fprint(f, "<import module=\"%s\" name=\"%s\"/>\n",
560 smiImport->module, smiImport->name);
565 static void fprintImports(FILE *f, SmiModule *smiModule)
567 SmiImport *smiImport;
570 for (i = 0, smiImport = smiGetFirstImport(smiModule);
572 i++, smiImport = smiGetNextImport(smiImport)) {
574 fprintSegment(f, INDENT, "<imports>\n", 0);
576 fprintImport(f, 2 * INDENT, smiImport);
580 fprintSegment(f, INDENT, "</imports>\n\n", 0);
586 static void fprintTypedef(FILE *f, int indent, SmiType *smiType)
588 SmiModule *parentModule;
591 fprintSegment(f, indent, "<typedef", 0);
593 fprint(f, " name=\"%s\"", smiType->name);
595 fprint(f, " basetype=\"%s\"", getStringBasetype(smiType->basetype));
596 if (smiType->name && smiType->status != SMI_STATUS_UNKNOWN) {
597 fprint(f, " status=\"%s\"", getStringStatus(smiType->status));
601 parentType = smiGetParentType(smiType);
602 parentModule = smiGetTypeModule(parentType);
603 if (parentType && parentType->name &&
604 parentModule && strlen(parentModule->name)) {
605 fprintSegment(f, indent + INDENT, "<parent ", 0);
606 fprintf(f, "module=\"%s\" name=\"%s\"/>\n",
607 parentModule->name, parentType->name);
609 fprintRanges(f, indent + INDENT, smiType);
610 fprintNamedNumbers(f, indent + INDENT, smiType);
611 fprintValue(f, indent + INDENT, &smiType->value, smiType);
612 fprintFormat(f, indent + INDENT, smiType->format);
613 fprintUnits(f, indent + INDENT, smiType->units);
614 fprintDescription(f, indent + INDENT, smiType->description);
615 fprintReference(f, indent + INDENT, smiType->reference);
617 fprintSegment(f, indent, "</typedef>\n", 0);
622 static void fprintTypedefs(FILE *f, SmiModule *smiModule)
627 for(i = 0, smiType = smiGetFirstType(smiModule);
629 i++, smiType = smiGetNextType(smiType)) {
632 fprintSegment(f, INDENT, "<typedefs>\n", 0);
634 fprintTypedef(f, 2 * INDENT, smiType);
638 fprintSegment(f, INDENT, "</typedefs>\n\n", 0);
644 static void fprintNode(FILE *f, int indent, SmiNode *smiNode,
645 SmiNode *lastSmiNode)
647 SmiModule *smiModule;
651 if (smiNode->nodekind == SMI_NODEKIND_NODE) {
653 } else if (smiNode->nodekind == SMI_NODEKIND_CAPABILITIES) {
655 } else if (smiNode->nodekind == SMI_NODEKIND_TABLE) {
657 } else if (smiNode->nodekind == SMI_NODEKIND_ROW) {
660 } else if (smiNode->nodekind == SMI_NODEKIND_COLUMN) {
661 indent += 2 * INDENT;
663 } else if (smiNode->nodekind == SMI_NODEKIND_SCALAR) {
668 && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN
669 && smiNode->nodekind != SMI_NODEKIND_COLUMN) {
670 fprintNodeEndTag(f, indent + INDENT, "row");
671 fprintNodeEndTag(f, indent, "table");
674 smiType = smiGetNodeType(smiNode);
676 fprintNodeStartTag(f, indent, tag, smiNode);
677 if (smiType && (smiType->basetype != SMI_BASETYPE_UNKNOWN)) {
678 fprintSegment(f, indent + INDENT, "<syntax>\n", 0);
679 smiModule = smiGetTypeModule(smiType);
680 if (smiType->name && smiModule) {
681 fprintSegment(f, indent + 2 *INDENT, "", 0);
683 fprintf(f, "module=\"%s\" name=\"%s\"/>\n",
684 smiModule->name, smiType->name);
686 fprintTypedef(f, indent + 2 * INDENT, smiType);
688 fprintSegment(f, indent + INDENT, "</syntax>\n", 0);
690 if ((smiNode->nodekind != SMI_NODEKIND_TABLE) &&
691 (smiNode->nodekind != SMI_NODEKIND_ROW) &&
692 (smiNode->nodekind != SMI_NODEKIND_CAPABILITIES) &&
693 (smiNode->nodekind != SMI_NODEKIND_NODE)) {
694 fprintAccess(f, indent + INDENT, smiNode->access);
697 fprintValue(f, indent + INDENT, &smiNode->value, smiType);
699 fprintFormat(f, indent + INDENT, smiNode->format);
700 fprintUnits(f, indent + INDENT, smiNode->units);
701 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
702 fprintIndex(f, indent + INDENT, smiNode);
704 fprintDescription(f, indent + INDENT, smiNode->description);
705 fprintReference(f, indent + INDENT, smiNode->reference);
707 if (smiNode->nodekind != SMI_NODEKIND_ROW
708 && smiNode->nodekind != SMI_NODEKIND_TABLE) {
709 fprintNodeEndTag(f, indent, tag);
715 static void fprintNodes(FILE *f, SmiModule *smiModule)
718 SmiNode *smiNode, *lastSmiNode;
719 SmiNodekind nodekinds;
721 nodekinds = SMI_NODEKIND_NODE | SMI_NODEKIND_TABLE |
722 SMI_NODEKIND_ROW | SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR |
723 SMI_NODEKIND_CAPABILITIES;
725 for (i = 0, lastSmiNode = NULL,
726 smiNode = smiGetFirstNode(smiModule, nodekinds);
728 i++, lastSmiNode = smiNode,
729 smiNode = smiGetNextNode(smiNode, nodekinds)) {
732 fprintSegment(f, INDENT, "<nodes>\n", 0);
735 fprintNode(f, 2 * INDENT, smiNode, lastSmiNode);
739 && lastSmiNode->nodekind == SMI_NODEKIND_COLUMN) {
740 fprintNodeEndTag(f, 3 * INDENT, "row");
741 fprintNodeEndTag(f, 2 * INDENT, "table");
745 fprintSegment(f, INDENT, "</nodes>\n\n", 0);
751 static void fprintNotification(FILE *f, int indent, SmiNode *smiNode)
753 fprintNodeStartTag(f, indent, "notification", smiNode);
755 fprintSegment(f, indent + INDENT, "<objects>\n", 0);
756 fprintElementList(f, indent + 2 * INDENT, "object",
757 smiGetFirstElement(smiNode));
758 fprintSegment(f, indent + INDENT, "</objects>\n", 0);
759 fprintDescription(f, indent + INDENT, smiNode->description);
760 fprintReference(f, indent + INDENT, smiNode->reference);
762 fprintNodeEndTag(f, indent, "notification");
767 static void fprintNotifications(FILE *f, SmiModule *smiModule)
772 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
774 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
777 fprintSegment(f, INDENT, "<notifications>\n", 0);
779 fprintNotification(f, 2 * INDENT, smiNode);
783 fprintSegment(f, INDENT, "</notifications>\n\n", 0);
789 static void fprintGroup(FILE *f, int indent, SmiNode *smiNode)
791 fprintNodeStartTag(f, indent, "group", smiNode);
793 fprintSegment(f, indent + INDENT, "<members>\n", 0);
794 fprintElementList(f, indent + 2 * INDENT, "member",
795 smiGetFirstElement(smiNode));
796 fprintSegment(f, indent + INDENT, "</members>\n", 0);
797 fprintDescription(f, indent + INDENT, smiNode->description);
798 fprintReference(f, indent + INDENT, smiNode->reference);
800 fprintNodeEndTag(f, indent, "group");
805 static void fprintGroups(FILE *f, SmiModule *smiModule)
810 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
812 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
815 fprintSegment(f, INDENT, "<groups>\n", 0);
817 fprintGroup(f, 2 * INDENT, smiNode);
821 fprintSegment(f, INDENT, "</groups>\n\n", 0);
827 static void fprintComplGroups(FILE *f, int indent, SmiNode *smiNode)
830 SmiModule *optSmiModule;
831 SmiOption *smiOption;
833 if (! smiGetFirstElement(smiNode) && !smiGetFirstOption(smiNode)) {
837 fprintSegment(f, indent, "<requires>\n", 0);
838 fprintElementList(f, indent + INDENT, "mandatory",
839 smiGetFirstElement(smiNode));
841 for(smiOption = smiGetFirstOption(smiNode);
843 smiOption = smiGetNextOption(smiOption)) {
844 optSmiNode = smiGetOptionNode(smiOption);
845 optSmiModule = smiGetNodeModule(optSmiNode);
846 fprintSegment(f, indent + INDENT, "", 0);
847 fprint(f, "<option module=\"%s\" name=\"%s\">\n",
848 optSmiModule->name, optSmiNode->name);
849 fprintDescription(f, indent + 2 * INDENT, smiOption->description);
850 fprintSegment(f, indent + INDENT, "</option>\n", 0);
853 fprintSegment(f, indent, "</requires>\n", 0);
858 static void fprintRefinement(FILE *f, int indent, SmiRefinement *smiRefinement)
860 SmiModule *smiModule;
864 smiNode = smiGetRefinementNode(smiRefinement);
865 smiModule = smiGetNodeModule(smiNode);
867 fprintSegment(f, indent, "<refinement ", 0);
868 fprintf(f, "module=\"%s\" name=\"%s\">\n", smiModule->name, smiNode->name);
870 smiType = smiGetRefinementType(smiRefinement);
872 fprintSegment(f, indent + INDENT, "<syntax>\n", 0);
873 fprintTypedef(f, indent + 2 * INDENT, smiType);
874 fprintSegment(f, indent + INDENT, "</syntax>\n", 0);
877 smiType = smiGetRefinementWriteType(smiRefinement);
879 fprintSegment(f, indent + INDENT, "<writesyntax>\n", 0);
880 fprintTypedef(f, indent + 2 * INDENT, smiType);
881 fprintSegment(f, indent + INDENT, "</writesyntax>\n", 0);
884 if (smiRefinement->access != SMI_ACCESS_UNKNOWN) {
885 fprintAccess(f, indent + INDENT, smiRefinement->access);
887 fprintDescription(f, indent + INDENT, smiRefinement->description);
888 fprintSegment(f, indent, "</refinement>\n", 0);
893 static void fprintRefinements(FILE *f, int indent, SmiNode *smiNode)
895 SmiRefinement *smiRefinement;
898 for(i = 0, smiRefinement = smiGetFirstRefinement(smiNode);
900 i++, smiRefinement = smiGetNextRefinement(smiRefinement)) {
903 fprintSegment(f, indent, "<refinements>\n", 0);
906 fprintRefinement(f, indent + INDENT, smiRefinement);
910 fprintSegment(f, indent, "</refinements>\n\n", 0);
916 static void fprintCompliance(FILE *f, int indent, SmiNode *smiNode)
918 fprintNodeStartTag(f, indent, "compliance", smiNode);
920 fprintDescription(f, indent + INDENT, smiNode->description);
921 fprintReference(f, indent + INDENT, smiNode->reference);
922 fprintComplGroups(f, indent + INDENT, smiNode);
923 fprintRefinements(f, indent + INDENT, smiNode);
925 fprintNodeEndTag(f, indent, "compliance");
930 static void fprintCompliances(FILE *f, SmiModule *smiModule)
935 for(i = 0, smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
937 i++, smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
940 fprintSegment(f, INDENT, "<compliances>\n", 0);
943 fprintCompliance(f, 2 * INDENT, smiNode);
947 fprintSegment(f, INDENT, "</compliances>\n\n", 0);
953 static void dumpXml(int modc, SmiModule **modv, int flags, char *output)
959 f = fopen(output, "w");
961 fprintf(stderr, "smidump: cannot open %s for writing: ", output);
967 for (i = 0; i < modc; i++) {
969 fprint(f, "<?xml version=\"1.0\"?>\n");
970 if (!disabledoctype) {
971 fprint(f, "<!DOCTYPE smi SYSTEM \"http://www.ibr.cs.tu-bs.de/projects/nmrg/smi.dtd\">\n");
974 fprint(f, "<!-- This module has been generated by smidump "
975 SMI_VERSION_STRING ". Do not edit. -->\n");
978 if (!disableschema) {
979 fprint(f, "<smi xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
980 fprint(f, " xsi:noNamespaceSchemaLocation=\"http://www.ibr.cs.tu-bs.de/projects/nmrg/smi.xsd\">\n");
982 fprint(f, "<smi>\n");
985 fprintModule(f, modv[i]);
986 fprintImports(f, modv[i]);
987 fprintTypedefs(f, modv[i]);
988 fprintNodes(f, modv[i]);
989 fprintNotifications(f, modv[i]);
990 fprintGroups(f, modv[i]);
991 fprintCompliances(f, modv[i]);
993 fprint(f, "</smi>\n");
996 if (fflush(f) || ferror(f)) {
997 perror("smidump: write error");
1011 static SmidumpDriverOption opt[] = {
1012 { "no-schema", OPT_FLAG, &disableschema, 0,
1013 "disable XML Schema spec in the toplevel element"},
1014 { "no-doctype", OPT_FLAG, &disabledoctype, 0,
1015 "disable DOCTYPE spec in the XML prolog"},
1016 { 0, OPT_END, 0, 0 }
1019 static SmidumpDriver driver = {
1023 SMIDUMP_DRIVER_CANT_UNITE,
1024 "intermediate SMI XML exchange format",
1029 smidumpRegisterDriver(&driver);