4 * Operations to generate MIB module stubs for the scli package.
6 * Copyright (c) 2001 J. Schoenwaelder, Technical University of Braunschweig.
7 * Copyright (c) 2002 J. Schoenwaelder, University of Osnabrueck.
8 * Copyright (c) 2004 J. Schoenwaelder, International University Bremen.
10 * See the file "COPYING" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * @(#) $Id: dump-scli.c 8090 2008-04-18 12:56:29Z strauss $
18 * - range checks for 64 bit numbers
38 #include <sys/types.h>
44 #define regcomp(a, b, c) 1
45 #define regexec(a, b, c, d, e) 0
46 #define regerror(a,b,c,d) strncpy(c, "regex not supported", d)
50 static char *prefix = NULL;
51 static char *include = NULL;
52 static char *exclude = NULL;
56 static regex_t _incl_regex, *incl_regex = NULL;
57 static regex_t _excl_regex, *excl_regex = NULL;
59 static char *keywords_c99[] = {
60 "auto", "enum", "restrict", "unsigned",
61 "break", "extern", "return", "void",
62 "case", "float", "short", "volatile",
63 "char", "for", "signed", "while",
64 "const", "goto", "sizeof", "_Bool",
65 "continue", "if", "static", "_Complex",
66 "default", "inline", "struct", "_Imaginary",
67 "do", "int", "switch",
68 "double", "long", "typedef",
69 "else", "register", "union",
80 for (i = 0; keywords_c99[i]; i++) {
81 if (strcmp(m, keywords_c99[i]) == 0) {
91 getStringTime(time_t t)
97 sprintf(s, "%04d-%02d-%02d %02d:%02d",
98 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
99 tm->tm_hour, tm->tm_min);
106 fprintCommentString(FILE *f, char *s)
113 for (i = 0; i < len; i++) {
126 fprintTopComment(FILE *f, SmiModule *smiModule)
128 SmiRevision *smiRevision;
132 "/* \t\t\t\t\t\t-- DO NOT EDIT --\n"
133 " * Generated by smidump version " SMI_VERSION_STRING ":\n");
135 fprintf(f, " * smidump -f scli");
137 fprintf(f, " --scli-set");
140 fprintf(f, " --scli-create");
143 fprintf(f, " --scli-delete");
146 fprintf(f, " \\\n * --scli-prefix='%s'", prefix);
149 fprintf(f, " \\\n * --scli-include='%s'", include);
152 fprintf(f, " \\\n * --scli-exclude='%s'", exclude);
154 fprintf(f, " %s\n *\n", smiModule->name);
157 " * Derived from %s:\n", smiModule->name);
158 fprintCommentString(f, smiModule->description);
160 for (smiRevision = smiGetFirstRevision(smiModule);
162 smiRevision = smiGetNextRevision(smiRevision)) {
163 date = getStringTime(smiRevision->date);
166 " * Revision %s:\n", date);
167 fprintCommentString(f, smiRevision->description);
171 if (smiModule->organization || smiModule->contactinfo) {
172 fprintf(f, " *\n * Contact:\n");
173 printCommentString(f, smiModule->organization);
175 printCommentString(f, smiModule->contactinfo);
194 for (i = 0; s[i]; i++) {
195 if (s[i] == '-') s[i] = '_';
198 while (isKeyword(s)) {
199 s = xrealloc(s, strlen(s) + 2);
209 translateUpper(char *m)
215 for (i = 0; s[i]; i++) {
216 if (s[i] == '-') s[i] = '_';
217 if (islower((int) s[i])) {
218 s[i] = toupper(s[i]);
222 while (isKeyword(s)) {
223 s = xrealloc(s, strlen(s) + 2);
233 translateLower(char *m)
239 for (i = 0; s[i]; i++) {
240 if (s[i] == '-') s[i] = '_';
241 if (isupper((int) s[i])) {
242 s[i] = tolower(s[i]);
246 while (isKeyword(s)) {
247 s = xrealloc(s, strlen(s) + 2);
257 translateFileName(char *m)
263 for (i = 0; s[i]; i++) {
264 if (s[i] == '_') s[i] = '-';
265 if (isupper((int) s[i])) {
266 s[i] = tolower(s[i]);
276 createFile(char *name, char *suffix)
281 fullname = xmalloc(strlen(name) + (suffix ? strlen(suffix) : 0) + 2);
282 strcpy(fullname, name);
284 strcat(fullname, suffix);
286 if (!access(fullname, R_OK)) {
287 fprintf(stderr, "smidump: %s already exists\n", fullname);
291 f = fopen(fullname, "w");
293 fprintf(stderr, "smidump: cannot open %s for writing: ", fullname);
305 isGroup(SmiNode *smiNode, SmiNodekind memberkind)
311 if (! smiNode->name) {
314 status = regexec(incl_regex, smiNode->name, (size_t) 0, NULL, 0);
321 if (! smiNode->name) {
324 status = regexec(excl_regex, smiNode->name, (size_t) 0, NULL, 0);
330 for (childNode = smiGetFirstChildNode(smiNode);
332 childNode = smiGetNextChildNode(childNode)) {
333 if (childNode->nodekind & memberkind) {
344 isAccessible(SmiNode *groupNode)
349 for (smiNode = smiGetFirstChildNode(groupNode);
351 smiNode = smiGetNextChildNode(smiNode)) {
352 if ((smiNode->nodekind == SMI_NODEKIND_SCALAR
353 || smiNode->nodekind == SMI_NODEKIND_COLUMN)
354 && (smiNode->access == SMI_ACCESS_READ_ONLY
355 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
366 isIndex(SmiNode *groupNode, SmiNode *smiNode)
368 SmiElement *smiElement;
371 * Perhaps this test needs to be more sophisticated if you have
372 * really creative cross-table indexing constructions...
375 for (smiElement = smiGetFirstElement(groupNode);
376 smiElement; smiElement = smiGetNextElement(smiElement)) {
377 if (smiNode == smiGetElementNode(smiElement)) {
388 isWritable(SmiNode *treeNode, SmiNodekind nodekind)
392 for (smiNode = smiGetFirstChildNode(treeNode);
394 smiNode = smiGetNextChildNode(smiNode)) {
395 if (smiNode->nodekind & (nodekind)
396 && (smiNode->access >= SMI_ACCESS_READ_WRITE)) {
401 return (smiNode != NULL);
407 getSnmpType(SmiType *smiType)
414 { "RFC1155-SMI","Counter", "GNET_SNMP_VARBIND_TYPE_COUNTER32" },
415 { "SNMPv2-SMI", "Counter32", "GNET_SNMP_VARBIND_TYPE_COUNTER32" },
416 { "RFC1155-SMI","TimeTicks", "GNET_SNMP_VARBIND_TYPE_TIMETICKS" },
417 { "SNMPv2-SMI", "TimeTicks", "GNET_SNMP_VARBIND_TYPE_TIMETICKS" },
418 { "RFC1155-SMI","Opaque", "GNET_SNMP_VARBIND_TYPE_OPAQUE" },
419 { "SNMPv2-SMI", "Opaque", "GNET_SNMP_VARBIND_TYPE_OPAQUE" },
420 { "RFC1155-SMI","IpAddress", "GNET_SNMP_VARBIND_TYPE_IPADDRESS" },
421 { "SNMPv2-SMI", "IpAddress", "GNET_SNMP_VARBIND_TYPE_IPADDRESS" },
425 SmiBasetype basetype = smiType->basetype;
429 for (i = 0; typemap[i].name; i++) {
431 && (strcmp(smiType->name, typemap[i].name) == 0)) {
432 return typemap[i].tag;
435 } while ((smiType = smiGetParentType(smiType)));
438 case SMI_BASETYPE_INTEGER32:
439 case SMI_BASETYPE_ENUM:
440 return "GNET_SNMP_VARBIND_TYPE_INTEGER32";
441 case SMI_BASETYPE_UNSIGNED32:
442 return "GNET_SNMP_VARBIND_TYPE_UNSIGNED32";
443 case SMI_BASETYPE_INTEGER64:
445 case SMI_BASETYPE_UNSIGNED64:
446 return "GNET_SNMP_VARBIND_TYPE_COUNTER64";
447 case SMI_BASETYPE_OCTETSTRING:
448 return "GNET_SNMP_VARBIND_TYPE_OCTETSTRING";
449 case SMI_BASETYPE_BITS:
450 return "GNET_SNMP_VARBIND_TYPE_OCTETSTRING";
451 case SMI_BASETYPE_OBJECTIDENTIFIER:
452 return "GNET_SNMP_VARBIND_TYPE_OBJECTID";
453 case SMI_BASETYPE_FLOAT32:
454 case SMI_BASETYPE_FLOAT64:
455 case SMI_BASETYPE_FLOAT128:
457 case SMI_BASETYPE_UNKNOWN:
459 case SMI_BASETYPE_POINTER:
467 typedef void (*ForEachIndexFunc) (FILE *f, SmiNode *groupNode, SmiNode *smiNode, int flags, int maxlen, char *name);
471 * Check whether we have duplicate nodes in the INDEX. If yes,
472 * generate a unique name.
476 getIndexName(SmiNode *indexNode, SmiNode *iNode, SmiElement *smiElement)
480 int n = 0, m = 0, tail = 0;
483 for (se = smiGetFirstElement(indexNode);
484 se; se = smiGetNextElement(se)) {
485 sn = smiGetElementNode(se);
486 if (strcmp(sn->name, iNode->name) == 0) {
490 if (se == smiElement) tail = 1;
493 smiAsprintf(&name, "%s%d", iNode->name, m);
495 name = xstrdup(iNode->name);
502 foreachIndexDo(FILE *f, SmiNode *smiNode, ForEachIndexFunc func,
503 int flags, int maxlen)
505 SmiNode *indexNode = NULL, *iNode;
506 SmiElement *smiElement;
508 switch (smiNode->indexkind) {
509 case SMI_INDEX_INDEX:
510 case SMI_INDEX_REORDER:
513 case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
515 case SMI_INDEX_AUGMENT:
516 case SMI_INDEX_SPARSE:
517 indexNode = smiGetRelatedNode(smiNode);
519 case SMI_INDEX_UNKNOWN:
523 for (smiElement = smiGetFirstElement(indexNode);
524 smiElement; smiElement = smiGetNextElement(smiElement)) {
525 iNode = smiGetElementNode(smiElement);
527 char *name = getIndexName(indexNode, iNode, smiElement);
528 (func) (f, smiNode, iNode, flags, maxlen, name);
529 if (name) xfree(name);
538 printIndexParamsFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
539 int flags, int maxlen, char *name)
543 unsigned minSize, maxSize;
545 iType = smiGetNodeType(iNode);
550 cName = translate(name ? name : iNode->name);
551 switch (iType->basetype) {
552 case SMI_BASETYPE_OBJECTIDENTIFIER:
553 maxSize = smiGetMaxSize(iType);
554 minSize = smiGetMinSize(iType);
555 fprintf(f, ", %s%s", flags ? "guint32 *" : "", cName);
556 if (minSize != maxSize) {
557 fprintf(f, ", %s_%sLength",
558 flags ? "guint16 " : "", cName);
561 case SMI_BASETYPE_OCTETSTRING:
562 case SMI_BASETYPE_BITS:
563 maxSize = smiGetMaxSize(iType);
564 minSize = smiGetMinSize(iType);
565 fprintf(f, ", %s%s", flags ? "guchar *" : "", cName);
566 if (minSize != maxSize) {
567 fprintf(f, ", %s_%sLength",
568 flags ? "guint16 " : "", cName);
571 case SMI_BASETYPE_ENUM:
572 case SMI_BASETYPE_INTEGER32:
573 fprintf(f, ", %s%s", flags ? "gint32 " : "", cName);
575 case SMI_BASETYPE_UNSIGNED32:
576 fprintf(f, ", %s%s", flags ? "guint32 " : "", cName);
579 fprintf(f, "/* ?? %s */", cName);
588 printIndexParamsPassFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
589 int flags, int maxlen, char *name)
593 unsigned minSize, maxSize;
595 iType = smiGetNodeType(iNode);
600 gName = translate(smiNode->name);
601 cName = translate(iNode->name);
602 fprintf(f, ", %s->%s", gName, cName);
603 switch (iType->basetype) {
604 case SMI_BASETYPE_BITS:
605 case SMI_BASETYPE_OCTETSTRING:
606 case SMI_BASETYPE_OBJECTIDENTIFIER:
607 maxSize = smiGetMaxSize(iType);
608 minSize = smiGetMinSize(iType);
609 if (minSize != maxSize) {
610 fprintf(f, ", %s->_%sLength", gName, cName);
623 printIndexAssignmentFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
624 int flags, int maxlen, char *name)
627 char *cName, *gName, *dName, *dModuleName;
628 unsigned minSize, maxSize;
630 iType = smiGetNodeType(iNode);
635 gName = translate(smiNode->name);
636 cName = translate(iNode->name);
637 dName = translateUpper(iNode->name);
638 dModuleName = translateUpper(smiGetNodeModule(iNode)->name);
639 switch (iType->basetype) {
640 case SMI_BASETYPE_OBJECTIDENTIFIER:
641 fprintf(f, " memcpy(%s->%s, %s, _%sLength * sizeof(guint32));\n",
642 gName, cName, cName, cName);
644 case SMI_BASETYPE_OCTETSTRING:
645 case SMI_BASETYPE_BITS:
646 maxSize = smiGetMaxSize(iType);
647 minSize = smiGetMinSize(iType);
648 if (minSize != maxSize) {
649 fprintf(f, " memcpy(%s->%s, %s, _%sLength);\n",
650 gName, cName, cName, cName);
652 fprintf(f, " memcpy(%s->%s, %s, %s_%sLENGTH);\n",
653 gName, cName, cName, dModuleName, dName);
656 case SMI_BASETYPE_ENUM:
657 case SMI_BASETYPE_INTEGER32:
658 case SMI_BASETYPE_UNSIGNED32:
659 fprintf(f, " %s->%s = %s;\n",
660 gName, cName, cName);
663 fprintf(f, " /* ?? %s */\n", cName);
675 printHeaderEnumeration(FILE *f, SmiModule *smiModule,
676 SmiNode * smiNode, SmiType *smiType)
679 char *cName, *cPrefix;
680 char *dName, *dModuleName;
684 if (smiType && smiType->name) {
685 name = smiType->name;
686 } else if (smiNode && smiNode->name) {
687 name = smiNode->name;
692 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
693 dModuleName = translateUpper(smiModule->name);
694 cName = translate(name);
695 dName = translateUpper(name);
697 for (len = 0, nn = smiGetFirstNamedNumber(smiType); nn;
698 nn = smiGetNextNamedNumber(nn)) {
699 if (len < strlen(nn->name)) {
700 len = strlen(nn->name);
703 for (nn = smiGetFirstNamedNumber(smiType); nn;
704 nn = smiGetNextNamedNumber(nn)) {
705 char *dEnum = translateUpper(nn->name);
706 fprintf(f, "#define %s_%s_%-*s %d\n",
707 dModuleName, dName, len, dEnum,
708 (int) nn->value.value.integer32);
711 fprintf(f, "\nextern GNetSnmpEnum const %s_enums_%s[];\n\n",
723 printHeaderEnumerations(FILE *f, SmiModule *smiModule)
725 SmiNode *smiNode, *parentNode;
728 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
732 " * Tables to map enumerations to strings and vice versa.\n"
736 for (smiNode = smiGetFirstNode(smiModule, groupkind);
738 smiNode = smiGetNextNode(smiNode, groupkind)) {
739 parentNode = smiGetParentNode(smiNode);
740 if (! parentNode || ! isGroup(parentNode, groupkind)) {
743 smiType = smiGetNodeType(smiNode);
744 if (smiType && !smiType->name
745 && smiType->basetype == SMI_BASETYPE_ENUM
746 && smiGetTypeModule(smiType) == smiModule) {
751 printHeaderEnumeration(f, smiModule, smiNode, smiType);
755 for (smiType = smiGetFirstType(smiModule);
757 smiType = smiGetNextType(smiType)) {
758 if (smiType->basetype == SMI_BASETYPE_ENUM
759 && smiGetTypeModule(smiType) == smiModule) {
764 printHeaderEnumeration(f, smiModule, NULL, smiType);
776 printHeaderIdentities(FILE *f, SmiModule *smiModule)
778 SmiNode *smiNode, *moduleIdentityNode, *parentNode;
781 char *dName, *dModuleName;
784 moduleIdentityNode = smiGetModuleIdentityNode(smiModule);
786 dModuleName = translateUpper(smiModule->name);
788 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
790 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
791 parentNode = smiGetParentNode(smiNode);
792 if (! parentNode || ! isGroup(parentNode, SMI_NODEKIND_NODE)) {
795 if (smiNode->status == SMI_STATUS_UNKNOWN) {
798 if (smiNode == moduleIdentityNode) {
804 " * Tables to map identities to strings and vice versa.\n"
809 dName = translateUpper(smiNode->name);
810 fprintf(f, "#define %s_%s\t", dModuleName, dName);
811 for (i = 0; i < smiNode->oidlen; i++) {
812 fprintf(f, "%s%u", i ? "," : "", smiNode->oid[i]);
819 cModuleName = translateLower(smiModule->name);
822 "extern GNetSnmpIdentity const %s_identities[];\n"
834 printHeaderNotifications(FILE *f, SmiModule *smiModule)
839 char *dName, *dModuleName;
842 dModuleName = translateUpper(smiModule->name);
844 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
846 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
847 if (smiNode->status == SMI_STATUS_UNKNOWN) {
853 " * Tables to map notifications to strings and vice versa.\n"
858 dName = translateUpper(smiNode->name);
859 fprintf(f, "#define %s_%s\t", dModuleName, dName);
860 for (i = 0; i < smiNode->oidlen; i++) {
861 fprintf(f, "%s%u", i ? "," : "", smiNode->oid[i]);
868 cModuleName = translateLower(smiModule->name);
871 "extern GNetSnmpIdentity const %s_notifications[];\n"
883 printParam(FILE *f, SmiNode *smiNode)
885 char *cName, *dNodeName, *dModuleName;
886 unsigned minSize, maxSize;
888 SmiModule *smiModule;
890 smiModule = smiGetNodeModule(smiNode);
891 smiType = smiGetNodeType(smiNode);
896 cName = translate(smiNode->name);
897 dNodeName = translateUpper(smiNode->name);
898 dModuleName = translateUpper(smiModule ? smiModule->name : "");
899 switch (smiType->basetype) {
900 case SMI_BASETYPE_OBJECTIDENTIFIER:
901 maxSize = smiGetMaxSize(smiType);
902 minSize = smiGetMinSize(smiType);
904 ", guint32 *%s", cName);
905 if (maxSize != minSize) {
907 ", guint16 _%sLength", cName);
910 case SMI_BASETYPE_OCTETSTRING:
911 case SMI_BASETYPE_BITS:
912 maxSize = smiGetMaxSize(smiType);
913 minSize = smiGetMinSize(smiType);
915 ", guchar *%s", cName);
916 if (maxSize != minSize) {
918 ", guint16 _%sLength", cName);
921 case SMI_BASETYPE_ENUM:
922 case SMI_BASETYPE_INTEGER32:
924 ", gint32 %s", cName);
926 case SMI_BASETYPE_UNSIGNED32:
928 ", guint32 %s", cName);
930 case SMI_BASETYPE_INTEGER64:
932 ", gint64 %s", cName);
934 case SMI_BASETYPE_UNSIGNED64:
936 ", guint64 %s", cName);
940 " /* ?? */ _%s", cName);
949 printCreateMethodPrototype(FILE *f, SmiNode *groupNode)
951 SmiModule *smiModule;
952 char *cPrefix, *cNodeName;
954 smiModule = smiGetNodeModule(groupNode);
955 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
956 cNodeName = translate(groupNode->name);
960 "%s_create_%s(GNetSnmp *s", cPrefix, cNodeName);
961 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
962 fprintf(f, ");\n\n");
971 printDeleteMethodPrototype(FILE *f, SmiNode *groupNode)
973 SmiModule *smiModule;
974 char *cPrefix, *cNodeName;
976 smiModule = smiGetNodeModule(groupNode);
977 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
978 cNodeName = translate(groupNode->name);
982 "%s_delete_%s(GNetSnmp *s", cPrefix, cNodeName);
984 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
986 fprintf(f, ");\n\n");
995 printSetMethodPrototype(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
997 SmiModule *smiModule;
998 char *cPrefix, *cNodeName;
1000 smiModule = smiGetNodeModule(smiNode);
1001 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
1002 cNodeName = translate(smiNode->name);
1006 "%s_set_%s(GNetSnmp *s",
1007 cPrefix, cNodeName);
1009 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
1010 printParam(f, smiNode);
1012 fprintf(f, ");\n\n");
1021 printMethodPrototypes(FILE *f, SmiNode *groupNode)
1026 for (smiNode = smiGetFirstChildNode(groupNode);
1028 smiNode = smiGetNextChildNode(smiNode)) {
1029 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
1030 && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
1031 if (smiNode->access == SMI_ACCESS_READ_WRITE) {
1032 smiType = smiGetNodeType(smiNode);
1033 if (smiType && smiType->name
1034 && strcmp(smiType->name, "RowStatus") == 0) {
1035 if (cflag) printCreateMethodPrototype(f, groupNode);
1036 if (dflag) printDeleteMethodPrototype(f, groupNode);
1038 if (! isIndex(groupNode, smiNode)) {
1039 if (sflag) printSetMethodPrototype(f, groupNode, smiNode);
1050 printHeaderTypedefMemberComment(FILE *f, SmiNode *smiNode, SmiType *smiType)
1054 switch (smiNode->access) {
1055 case SMI_ACCESS_READ_WRITE:
1058 case SMI_ACCESS_READ_ONLY:
1061 case SMI_ACCESS_NOT_ACCESSIBLE:
1064 case SMI_ACCESS_NOTIFY:
1070 if (s) fprintf(f, "%s", s);
1071 s = smiRenderType(smiType, SMI_RENDER_NAME | SMI_RENDER_QUALIFIED);
1073 fprintf(f, " %s", s);
1076 if (smiNode->units) {
1077 fprintf(f, " [%s]", smiNode->units);
1078 } else if (smiType->units) {
1079 fprintf(f, " [%s]", smiNode->units);
1086 printHeaderTypedefMember(FILE *f, SmiNode *smiNode,
1087 SmiType *smiType, int isIndex, int maxlen, char *name)
1089 char *cName, *dNodeName, *dModuleName;
1090 unsigned minSize, maxSize;
1091 SmiModule *smiModule;
1093 smiModule = smiGetNodeModule(smiNode);
1095 cName = translate(name ? name : smiNode->name);
1096 dNodeName = translateUpper(name ? name : smiNode->name);
1097 dModuleName = translateUpper(smiModule ? smiModule->name : "");
1098 switch (smiType->basetype) {
1099 case SMI_BASETYPE_OBJECTIDENTIFIER:
1100 maxSize = smiGetMaxSize(smiType);
1101 minSize = smiGetMinSize(smiType);
1102 if (isIndex && maxSize > 128 - smiNode->oidlen) {
1103 maxSize = 128 - smiNode->oidlen;
1106 fprintf(f, " guint32 %s[%u];", cName, maxSize);
1107 fprintf(f, "%*s/* ", maxlen-strlen(cName)+2, "");
1108 printHeaderTypedefMemberComment(f, smiNode, smiType);
1109 fprintf(f, " */\n");
1111 fprintf(f, " guint32 *%s;", cName);
1112 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
1113 printHeaderTypedefMemberComment(f, smiNode, smiType);
1114 fprintf(f, " */\n");
1116 if (maxSize == minSize) {
1118 "#define %s_%sLENGTH %u\n",
1119 dModuleName, dNodeName, maxSize);
1122 "#define %s_%sMINLENGTH %u\n",
1123 dModuleName, dNodeName, minSize);
1125 "#define %s_%sMAXLENGTH %u\n",
1126 dModuleName, dNodeName, maxSize);
1128 " guint16 _%sLength;\n", cName);
1131 case SMI_BASETYPE_OCTETSTRING:
1132 case SMI_BASETYPE_BITS:
1133 maxSize = smiGetMaxSize(smiType);
1134 minSize = smiGetMinSize(smiType);
1135 if (isIndex && maxSize > 128 - smiNode->oidlen) {
1136 maxSize = 128 - smiNode->oidlen;
1139 fprintf(f, " guchar %s[%u];", cName, maxSize);
1140 fprintf(f, "%*s/* ", maxlen-strlen(cName)+2, "");
1141 printHeaderTypedefMemberComment(f, smiNode, smiType);
1142 fprintf(f, " */\n");
1144 fprintf(f, " guchar *%s;", cName);
1145 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
1146 printHeaderTypedefMemberComment(f, smiNode, smiType);
1147 fprintf(f, " */\n");
1149 if (maxSize == minSize) {
1151 "#define %s_%sLENGTH %u\n",
1152 dModuleName, dNodeName, maxSize);
1155 "#define %s_%sMINLENGTH %u\n",
1156 dModuleName, dNodeName, minSize);
1158 "#define %s_%sMAXLENGTH %u\n",
1159 dModuleName, dNodeName, maxSize);
1161 " guint16 _%sLength;\n", cName);
1164 case SMI_BASETYPE_ENUM:
1165 case SMI_BASETYPE_INTEGER32:
1166 fprintf(f, " gint32 %s%s;", isIndex ? "" : "*", cName);
1167 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5+isIndex, "");
1168 printHeaderTypedefMemberComment(f, smiNode, smiType);
1169 fprintf(f, " */\n");
1171 case SMI_BASETYPE_UNSIGNED32:
1172 fprintf(f, " guint32 %s%s;", isIndex ? "" : "*", cName);
1173 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5+isIndex, "");
1174 printHeaderTypedefMemberComment(f, smiNode, smiType);
1175 fprintf(f, " */\n");
1177 case SMI_BASETYPE_INTEGER64:
1178 fprintf(f, " gint64 *%s;", cName);
1179 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
1180 printHeaderTypedefMemberComment(f, smiNode, smiType);
1181 fprintf(f, " */\n");
1183 case SMI_BASETYPE_UNSIGNED64:
1184 fprintf(f, " guint64 *%s;", cName);
1185 fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
1186 printHeaderTypedefMemberComment(f, smiNode, smiType);
1187 fprintf(f, " */\n");
1191 " /* ?? */ _%s; \n", cName);
1202 printHeaderTypedefMemberIndex(FILE *f, SmiNode *smiNode, SmiNode *iNode,
1203 int flags, int maxlen, char *name)
1207 iType = smiGetNodeType(iNode);
1212 printHeaderTypedefMember(f, iNode, iType, 1, maxlen, name);
1218 printHeaderTypedef(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
1222 char *cPrefix, *dModuleName, *cGroupName, *dGroupName, *dNodeName;
1223 int writable = 0, count = 0, len = 0;
1225 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
1226 dModuleName = translateUpper(smiModule->name);
1227 cGroupName = translate(groupNode->name);
1228 dGroupName = translateUpper(groupNode->name);
1232 " * C type definitions for %s::%s.\n"
1234 smiModule->name, groupNode->name);
1236 for (smiNode = smiGetFirstChildNode(groupNode);
1238 smiNode = smiGetNextChildNode(smiNode)) {
1239 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
1240 && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
1241 if (len < strlen(smiNode->name)) {
1242 len = strlen(smiNode->name);
1247 for (smiNode = smiGetFirstChildNode(groupNode);
1249 smiNode = smiGetNextChildNode(smiNode)) {
1250 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
1251 && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
1252 dNodeName = translateUpper(smiNode->name);
1253 fprintf(f, "#define %s_%-*s (1 << %d) \n", dModuleName, len, dNodeName, count);
1263 fprintf(f, "typedef struct {\n");
1265 foreachIndexDo(f, groupNode, printHeaderTypedefMemberIndex, 0, len);
1267 for (smiNode = smiGetFirstChildNode(groupNode);
1269 smiNode = smiGetNextChildNode(smiNode)) {
1270 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
1271 && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
1272 if (isIndex(groupNode, smiNode)) {
1275 if (smiNode->access == SMI_ACCESS_READ_WRITE) {
1278 smiType = smiGetNodeType(smiNode);
1282 printHeaderTypedefMember(f, smiNode, smiType, 0, len, 0);
1286 fprintf(f, "} %s_%s_t;\n\n", cPrefix, cGroupName);
1288 if (groupNode->nodekind == SMI_NODEKIND_ROW) {
1292 tableNode = smiGetParentNode(groupNode);
1294 cTableName = translate(tableNode->name);
1295 fprintf(f, "extern void\n"
1296 "%s_get_%s(GNetSnmp *s, %s_%s_t ***%s, gint64 mask);\n\n",
1297 cPrefix, cTableName,
1298 cPrefix, cGroupName, cGroupName);
1299 fprintf(f, "extern void\n"
1300 "%s_free_%s(%s_%s_t **%s);\n\n",
1301 cPrefix, cTableName,
1302 cPrefix, cGroupName, cGroupName);
1306 fprintf(f, "extern %s_%s_t *\n"
1307 "%s_new_%s(void);\n\n",
1308 cPrefix, cGroupName, cPrefix, cGroupName);
1309 fprintf(f, "extern void\n"
1310 "%s_get_%s(GNetSnmp *s, %s_%s_t **%s",
1311 cPrefix, cGroupName,
1312 cPrefix, cGroupName,
1314 if (groupNode->nodekind == SMI_NODEKIND_ROW) {
1315 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
1317 fprintf(f, ", gint64 mask);\n\n");
1319 fprintf(f, "extern void\n"
1320 "%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask);\n\n",
1321 cPrefix, cGroupName,
1322 cPrefix, cGroupName, cGroupName);
1324 fprintf(f, "extern void\n"
1325 "%s_free_%s(%s_%s_t *%s);\n\n",
1326 cPrefix, cGroupName,
1327 cPrefix, cGroupName, cGroupName);
1329 printMethodPrototypes(f, groupNode);
1340 printHeaderTypedefs(FILE *f, SmiModule *smiModule)
1344 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
1346 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1348 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1349 if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
1351 printHeaderTypedef(f, smiModule, smiNode);
1363 dumpHeader(SmiModule *smiModule, char *baseName)
1368 pModuleName = translateUpper(smiModule->name);
1370 f = createFile(baseName, ".h");
1375 fprintTopComment(f, smiModule);
1381 "#include \"gsnmp.h\"\n"
1385 pModuleName, pModuleName);
1387 printHeaderEnumerations(f, smiModule);
1388 printHeaderIdentities(f, smiModule);
1389 printHeaderNotifications(f, smiModule);
1390 printHeaderTypedefs(f, smiModule);
1395 "#endif /* _%s_H_ */\n",
1398 if (fflush(f) || ferror(f)) {
1399 perror("smidump: write error");
1410 printStubEnumeration(FILE *f, SmiModule *smiModule,
1411 SmiNode *smiNode, SmiType *smiType)
1414 char *cName, *cPrefix;
1415 char *dName, *dModuleName;
1419 if (smiType && smiType->name) {
1420 name = smiType->name;
1421 } else if (smiNode && smiNode->name) {
1422 name = smiNode->name;
1427 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
1428 dModuleName = translateUpper(smiModule->name);
1429 cName = translate(name);
1430 dName = translateUpper(name);
1432 fprintf(f, "GNetSnmpEnum const %s_enums_%s[] = {\n",
1434 for (len = 0, nn = smiGetFirstNamedNumber(smiType); nn;
1435 nn = smiGetNextNamedNumber(nn)) {
1436 if (len < strlen(nn->name)) {
1437 len = strlen(nn->name);
1440 for (nn = smiGetFirstNamedNumber(smiType); nn;
1441 nn = smiGetNextNamedNumber(nn)) {
1442 char *dEnum = translateUpper(nn->name);
1443 fprintf(f, " { %s_%s_%s,%*s \"%s\" },\n",
1444 dModuleName, dName, dEnum,
1445 len - strlen(dEnum), "", nn->name);
1462 printStubEnumerations(FILE *f, SmiModule *smiModule)
1464 SmiNode *smiNode, *parentNode;
1467 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
1469 for (smiNode = smiGetFirstNode(smiModule, groupkind);
1471 smiNode = smiGetNextNode(smiNode, groupkind)) {
1472 parentNode = smiGetParentNode(smiNode);
1473 if (! parentNode || ! isGroup(parentNode, groupkind)) {
1476 smiType = smiGetNodeType(smiNode);
1477 if (smiType && !smiType->name
1478 && smiType->basetype == SMI_BASETYPE_ENUM
1479 && smiGetTypeModule(smiType) == smiModule) {
1481 printStubEnumeration(f, smiModule, smiNode, smiType);
1485 for (smiType = smiGetFirstType(smiModule);
1487 smiType = smiGetNextType(smiType)) {
1488 if (smiType->basetype == SMI_BASETYPE_ENUM
1489 && smiGetTypeModule(smiType) == smiModule) {
1491 printStubEnumeration(f, smiModule, NULL, smiType);
1503 printStubIdentities(FILE *f, SmiModule *smiModule)
1505 SmiNode *smiNode, *moduleIdentityNode, *parentNode;
1506 char *cName, *cModuleName;
1507 char *dName, *dModuleName;
1510 moduleIdentityNode = smiGetModuleIdentityNode(smiModule);
1512 cModuleName = translateLower(smiModule->name);
1513 dModuleName = translateUpper(smiModule->name);
1515 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
1517 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
1518 parentNode = smiGetParentNode(smiNode);
1519 if (! parentNode || ! isGroup(parentNode, SMI_NODEKIND_NODE)) {
1522 if (smiNode->status == SMI_STATUS_UNKNOWN) {
1525 if (smiNode == moduleIdentityNode) {
1529 cName = translate(smiNode->name);
1530 dName = translateUpper(smiNode->name);
1532 "static guint32 const %s[]\n\t= { %s_%s };\n",
1533 cName, dModuleName, dName);
1541 "GNetSnmpIdentity const %s_identities[] = {\n",
1544 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
1546 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
1547 if (smiNode->status == SMI_STATUS_UNKNOWN) {
1550 if (smiNode == moduleIdentityNode) {
1553 cName = translate(smiNode->name);
1554 fprintf(f, " { %s,\n"
1555 " G_N_ELEMENTS(%s),\n"
1557 cName, cName, smiNode->name);
1575 printStubNotifications(FILE *f, SmiModule *smiModule)
1578 char *cName, *cModuleName;
1579 char *dName, *dModuleName;
1582 cModuleName = translateLower(smiModule->name);
1583 dModuleName = translateUpper(smiModule->name);
1585 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1587 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1588 if (smiNode->status == SMI_STATUS_UNKNOWN) {
1592 cName = translate(smiNode->name);
1593 dName = translateUpper(smiNode->name);
1595 "static guint32 const %s[]\n\t= { %s_%s };\n",
1596 cName, dModuleName, dName);
1604 "GNetSnmpIdentity const %s_notifications[] = {\n",
1607 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1609 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1610 if (smiNode->status == SMI_STATUS_UNKNOWN) {
1613 cName = translate(smiNode->name);
1614 fprintf(f, " { %s,\n"
1615 " G_N_ELEMENTS(%s),\n"
1617 cName, cName, smiNode->name);
1635 printSizeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
1638 unsigned int minSize, maxSize;
1642 cName = translate(smiNode->name);
1644 for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
1645 for (smiRange = smiGetFirstRange(smiType);
1646 smiRange ; smiRange = smiGetNextRange(smiRange)) {
1647 minSize = smiRange->minValue.value.unsigned32;
1648 maxSize = smiRange->maxValue.value.unsigned32;
1649 if (minSize == 0 && maxSize >= 65535) continue;
1652 fprintf(f, ", %u, %u", minSize, maxSize);
1654 fprintf(f, "static guint16 %s_constraints[] = {%uU, %uU",
1655 cName, minSize, maxSize);
1663 if (f && cnt) fprintf(f, ", 0, 0};\n");
1670 printInteger32RangeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
1673 long minSize, maxSize;
1677 cName = translate(smiNode->name);
1679 for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
1680 for (smiRange = smiGetFirstRange(smiType);
1681 smiRange ; smiRange = smiGetNextRange(smiRange)) {
1682 minSize = smiRange->minValue.value.integer32;
1683 maxSize = smiRange->maxValue.value.integer32;
1684 if (minSize < -2147483647 && maxSize > 2147483646) continue;
1687 fprintf(f, ", %ldL, %ldL", minSize, maxSize);
1689 fprintf(f, "static gint32 %s_constraints[] = {%ldL, %ldL",
1690 cName, minSize, maxSize);
1698 if (f && cnt) fprintf(f, ", 0, 0};\n");
1705 printUnsigned32RangeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
1708 unsigned long minSize, maxSize;
1712 cName = translate(smiNode->name);
1714 for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
1715 for (smiRange = smiGetFirstRange(smiType);
1716 smiRange ; smiRange = smiGetNextRange(smiRange)) {
1717 minSize = smiRange->minValue.value.unsigned32;
1718 maxSize = smiRange->maxValue.value.unsigned32;
1719 if (minSize == 0 && maxSize >= 4294967295UL) continue;
1722 fprintf(f, ", %luUL, %luUL", minSize, maxSize);
1724 fprintf(f, "static guint32 %s_constraints[] = {%luUL, %luUL",
1725 cName, minSize, maxSize);
1733 if (f && cnt) fprintf(f, ", 0, 0};\n");
1740 printConstraints(FILE *f, SmiNode *smiNode, SmiNode *groupNode, int flags)
1745 smiType = smiGetNodeType(smiNode);
1751 * Generally suppress all INDEX objects (treat them as if they
1752 * were not-accessible). This is a cheap optimization for SMIv1
1753 * MIBs where these objects were generally read-only.
1756 if (flags && isIndex(groupNode, smiNode)) {
1760 if (smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE
1761 || smiNode->access == SMI_ACCESS_NOTIFY) {
1765 switch (smiType->basetype) {
1766 case SMI_BASETYPE_OCTETSTRING:
1767 cnt = printSizeConstraints(f, smiNode, smiType);
1769 case SMI_BASETYPE_INTEGER32:
1770 cnt = printInteger32RangeConstraints(f, smiNode, smiType);
1772 case SMI_BASETYPE_UNSIGNED32:
1773 cnt = printUnsigned32RangeConstraints(f, smiNode, smiType);
1786 printScalarsAttributesContraints(FILE *f, SmiNode *groupNode)
1791 for (smiNode = smiGetFirstChildNode(groupNode);
1793 smiNode = smiGetNextChildNode(smiNode)) {
1794 n += printConstraints(f, smiNode, groupNode, 0);
1802 printTableAttributesConstraints(FILE *f, SmiNode *rowNode)
1805 int idx, cnt, n = 0;
1807 for (smiNode = smiGetFirstChildNode(rowNode), idx = 0, cnt = 0;
1809 smiNode = smiGetNextChildNode(smiNode)) {
1810 if (isIndex(rowNode, smiNode)) idx++;
1814 for (smiNode = smiGetFirstChildNode(rowNode);
1816 smiNode = smiGetNextChildNode(smiNode)) {
1817 n += printConstraints(f, smiNode, rowNode, cnt > idx);
1825 printStubContraints(FILE *f, SmiModule *smiModule)
1829 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
1831 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1833 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1834 if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
1835 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
1836 cnt += printTableAttributesConstraints(f, smiNode);
1838 cnt += printScalarsAttributesContraints(f, smiNode);
1851 printAttribute(FILE *f, SmiNode *smiNode, SmiNode *groupNode, int flags)
1855 char *dModuleName, *dNodeName;
1856 char *cPrefix, *cGroupName, *cNodeName;
1857 unsigned maxSize = 0, minSize = 0;
1860 smiType = smiGetNodeType(smiNode);
1865 snmpType = getSnmpType(smiType);
1871 * Generally suppress all INDEX objects (treat them as if they
1872 * were not-accessible). This is a cheap optimization for SMIv1
1873 * MIBs where these objects were generally read-only.
1876 if (flags && isIndex(groupNode, smiNode)) {
1880 if (smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE
1881 || smiNode->access == SMI_ACCESS_NOTIFY) {
1885 dModuleName = translateUpper(smiGetNodeModule(smiNode)->name);
1886 dNodeName = translateUpper(smiNode->name);
1887 cNodeName = translate(smiNode->name);
1888 cGroupName = translate(groupNode->name);
1889 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiGetNodeModule(smiNode)->name);
1893 " %s_%s, \"%s\",\n",
1894 smiNode->oid[smiNode->oidlen-1], snmpType,
1895 dModuleName, dNodeName, smiNode->name);
1897 switch (smiType->basetype) {
1898 case SMI_BASETYPE_OCTETSTRING:
1899 cnt = printSizeConstraints(NULL, smiNode, smiType);
1901 case SMI_BASETYPE_INTEGER32:
1902 cnt = printInteger32RangeConstraints(NULL, smiNode, smiType);
1904 case SMI_BASETYPE_UNSIGNED32:
1905 cnt = printUnsigned32RangeConstraints(NULL, smiNode, smiType);
1912 fprintf(f, " %s_constraints,\n", cNodeName);
1914 fprintf(f, " NULL,\n");
1917 if (! flags && isIndex(groupNode, smiNode)) {
1918 fprintf(f, " -1,\n");
1921 " G_STRUCT_OFFSET(%s_%s_t, %s),\n",
1922 cPrefix, cGroupName, cNodeName);
1925 switch (smiType->basetype) {
1926 case SMI_BASETYPE_OCTETSTRING:
1927 case SMI_BASETYPE_BITS:
1928 case SMI_BASETYPE_OBJECTIDENTIFIER:
1929 maxSize = smiGetMaxSize(smiType);
1930 minSize = smiGetMinSize(smiType);
1935 if (minSize != maxSize) {
1937 " G_STRUCT_OFFSET(%s_%s_t, _%sLength)",
1938 cPrefix, cGroupName, cNodeName);
1947 (smiNode->access > SMI_ACCESS_READ_ONLY) ? "GSNMP_ATTR_FLAG_WRITABLE" : "0");
1959 printScalarsAttributes(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
1963 for (smiNode = smiGetFirstChildNode(groupNode);
1965 smiNode = smiGetNextChildNode(smiNode)) {
1966 printAttribute(f, smiNode, groupNode, 0);
1973 printTableAttributes(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
1978 for (smiNode = smiGetFirstChildNode(rowNode), idx = 0, cnt = 0;
1980 smiNode = smiGetNextChildNode(smiNode)) {
1981 if (isIndex(rowNode, smiNode)) idx++;
1985 for (smiNode = smiGetFirstChildNode(rowNode);
1987 smiNode = smiGetNextChildNode(smiNode)) {
1988 printAttribute(f, smiNode, rowNode, cnt > idx);
1995 printStubAttributes(FILE *f, SmiModule *smiModule)
2001 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
2003 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
2005 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
2006 if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
2008 cName = translate(smiNode->name);
2010 fprintf(f, "static guint32 const %s_oid[] = {", cName);
2011 for (i = 0; i < smiNode->oidlen; i++) {
2012 fprintf(f, "%s%u", i ? ", " : "", smiNode->oid[i]);
2014 fprintf(f, "};\n\n");
2017 "static GNetSnmpAttribute %s_attr[] = {\n",
2019 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
2020 printTableAttributes(f, smiModule, smiNode);
2022 printScalarsAttributes(f, smiModule, smiNode);
2025 " { 0, 0, 0, NULL }\n"
2040 printInteger32RangeChecks(FILE *f, char *cGroupName, char *cName,
2044 long int minSize, maxSize;
2047 for (c = 0; smiType; smiType = smiGetParentType(smiType)) {
2048 for (smiRange = smiGetFirstRange(smiType);
2049 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2050 minSize = smiRange->minValue.value.integer32;
2051 maxSize = smiRange->maxValue.value.integer32;
2053 fprintf(f, " if (");
2055 fprintf(f, "\n && ");
2057 if (minSize == -2147483647 - 1) {
2058 fprintf(f, "(%s->%s > %ld)", cGroupName, cName, maxSize);
2059 } else if (maxSize == 2147483647) {
2060 fprintf(f, "(%s->%s < %ld)", cGroupName, cName, minSize);
2061 } else if (minSize == maxSize) {
2062 fprintf(f, "(%s->%s != %ld)", cGroupName, cName, maxSize);
2064 fprintf(f, "(%s->%s < %ld || %s->%s > %ld)",
2065 cGroupName, cName, minSize,
2066 cGroupName, cName, maxSize);
2082 printUnsigned32RangeChecks(FILE *f, char *cGroupName, char *cName,
2086 unsigned long minSize, maxSize;
2089 for (c = 0; smiType; smiType = smiGetParentType(smiType)) {
2090 for (smiRange = smiGetFirstRange(smiType);
2091 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2092 minSize = smiRange->minValue.value.unsigned32;
2093 maxSize = smiRange->maxValue.value.unsigned32;
2094 if (minSize == 0 && maxSize == 4294967295U) {
2098 fprintf(f, " if (");
2100 fprintf(f, "\n && ");
2103 fprintf(f, "(%s->%s > %lu)", cGroupName, cName, maxSize);
2104 } else if (maxSize == 4294967295U) {
2105 fprintf(f, "(%s->%s < %lu)", cGroupName, cName, minSize);
2106 } else if (minSize == maxSize) {
2107 fprintf(f, "(%s->%s != %lu)", cGroupName, cName, maxSize);
2109 fprintf(f, "(%s->%s < %lu || %s->%s > %lu)",
2110 cGroupName, cName, minSize,
2111 cGroupName, cName, maxSize);
2126 printUnpackMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
2128 SmiElement *smiElement;
2129 SmiNode *indexNode = NULL;
2132 char *cPrefix, *cGroupName, *cName, *name;
2133 unsigned maxSize, minSize;
2136 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2137 cGroupName = translate(groupNode->name);
2139 switch (groupNode->indexkind) {
2140 case SMI_INDEX_INDEX:
2141 case SMI_INDEX_REORDER:
2142 indexNode = groupNode;
2144 case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
2147 case SMI_INDEX_AUGMENT:
2148 case SMI_INDEX_SPARSE:
2149 indexNode = smiGetRelatedNode(groupNode);
2151 case SMI_INDEX_UNKNOWN:
2157 * First check if there are OID or string types so that we
2158 * know whether we need some additional variables.
2161 for (smiElement = smiGetFirstElement(indexNode);
2162 smiElement; smiElement = smiGetNextElement(smiElement)) {
2163 iNode = smiGetElementNode(smiElement);
2165 iType = smiGetNodeType(iNode);
2167 && (iType->basetype == SMI_BASETYPE_OCTETSTRING
2168 || iType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER)) {
2175 "static inline int\n"
2176 "unpack_%s(GNetSnmpVarBind *vb, %s_%s_t *%s)\n"
2178 " guint8 idx = %u;\n"
2181 cGroupName, cPrefix, cGroupName, cGroupName,
2182 groupNode->oidlen + 1,
2183 smiElement ? " guint16 i, len;\n" : "");
2185 for (smiElement = smiGetFirstElement(indexNode);
2186 smiElement; smiElement = smiGetNextElement(smiElement)) {
2187 iNode = smiGetElementNode(smiElement);
2188 last = (smiGetNextElement(smiElement) == NULL);
2190 iType = smiGetNodeType(iNode);
2194 name = getIndexName(indexNode, iNode, smiElement);
2195 cName = translate(name ? name : iNode->name);
2196 switch (iType->basetype) {
2197 case SMI_BASETYPE_ENUM:
2198 case SMI_BASETYPE_INTEGER32:
2200 " if (vb->oid_len < idx) return -1;\n"
2201 " %s->%s = vb->oid[idx++];\n",
2203 printInteger32RangeChecks(f, cGroupName, cName, iType);
2205 case SMI_BASETYPE_UNSIGNED32:
2207 " if (vb->oid_len < idx) return -1;\n"
2208 " %s->%s = vb->oid[idx++];\n",
2210 printUnsigned32RangeChecks(f, cGroupName, cName, iType);
2212 case SMI_BASETYPE_OCTETSTRING:
2213 maxSize = smiGetMaxSize(iType);
2214 minSize = smiGetMinSize(iType);
2215 if (maxSize > 128 - iNode->oidlen) {
2216 maxSize = 128 - iNode->oidlen;
2218 if (minSize == maxSize) {
2222 } else if (last && indexNode->implied) {
2224 " if (vb->oid_len < idx) return -1;\n"
2225 " len = vb->oid_len - idx;\n");
2228 " if (vb->oid_len < idx) return -1;\n"
2229 " len = vb->oid[idx++];\n");
2231 if (minSize != maxSize) {
2232 if (minSize > 0 && maxSize < 65535) {
2234 " if (len < %u || len > %u) return -1;\n",
2236 } else if (minSize > 0 && maxSize == 65535) {
2238 " if (len < %u) return -1;\n", minSize);
2239 } else if (minSize == 0 && maxSize < 65535) {
2241 " if (len > %u) return -1;\n", maxSize);
2245 " if (vb->oid_len < idx + len) return -1;\n"
2246 " for (i = 0; i < len; i++) {\n"
2247 " %s->%s[i] = vb->oid[idx++];\n"
2250 if (minSize != maxSize) {
2252 " %s->_%sLength = len;\n", cGroupName, cName);
2255 case SMI_BASETYPE_OBJECTIDENTIFIER:
2256 maxSize = smiGetMaxSize(iType);
2257 minSize = smiGetMinSize(iType);
2258 if (maxSize > 128 - iNode->oidlen) {
2259 maxSize = 128 - iNode->oidlen;
2261 if (minSize == maxSize) {
2264 " if (vb->oid_len < idx + len) return -1;\n",
2266 } else if (last && indexNode->implied) {
2268 " if (vb->oid_len < idx) return -1;\n"
2269 " len = vb->oid_len - idx;\n");
2272 " if (vb->oid_len < idx) return -1;\n"
2273 " len = vb->oid[idx++];\n"
2274 " if (vb->oid_len < idx + len) return -1;\n");
2276 if (minSize != maxSize) {
2277 if (minSize > 0 && maxSize < 65535) {
2279 " if (len < %u || len > %u) return -1;\n",
2281 } else if (minSize > 0 && maxSize == 65535) {
2283 " if (len < %u) return -1;\n", minSize);
2284 } else if (minSize == 0 && maxSize < 65535) {
2286 " if (len > %u) return -1;\n", maxSize);
2290 " for (i = 0; i < len; i++) {\n"
2291 " %s->%s[i] = vb->oid[idx++];\n"
2294 if (minSize != maxSize) {
2296 " %s->_%sLength = len;\n", cGroupName, cName);
2301 " /* XXX how to unpack %s->%s ? */\n",
2306 if (name) xfree(name);
2311 " if (vb->oid_len > idx) return -1;\n"
2322 printPackMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
2324 SmiElement *smiElement;
2325 SmiNode *indexNode = NULL;
2328 char *cGroupName, *cName, *name;
2329 unsigned maxSize, minSize;
2332 cGroupName = translate(groupNode->name);
2334 switch (groupNode->indexkind) {
2335 case SMI_INDEX_INDEX:
2336 case SMI_INDEX_REORDER:
2337 indexNode = groupNode;
2339 case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
2342 case SMI_INDEX_AUGMENT:
2343 case SMI_INDEX_SPARSE:
2344 indexNode = smiGetRelatedNode(groupNode);
2346 case SMI_INDEX_UNKNOWN:
2352 * First check if there are OID or string types so that we
2353 * know whether we need some additional variables.
2356 for (smiElement = smiGetFirstElement(indexNode);
2357 smiElement; smiElement = smiGetNextElement(smiElement)) {
2358 iNode = smiGetElementNode(smiElement);
2360 iType = smiGetNodeType(iNode);
2362 && (iType->basetype == SMI_BASETYPE_OCTETSTRING
2363 || iType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER)) {
2370 "static inline gint8\n"
2371 "pack_%s(guint32 *base",
2373 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
2377 " guint8 idx = %u;\n"
2380 groupNode->oidlen + 1,
2381 smiElement ? " guint16 i, len;\n" : "");
2383 for (smiElement = smiGetFirstElement(indexNode);
2384 smiElement; smiElement = smiGetNextElement(smiElement)) {
2385 iNode = smiGetElementNode(smiElement);
2386 last = (smiGetNextElement(smiElement) == NULL);
2388 iType = smiGetNodeType(iNode);
2392 name = getIndexName(indexNode, iNode, smiElement);
2393 cName = translate(name ? name : iNode->name);
2394 switch (iType->basetype) {
2395 case SMI_BASETYPE_ENUM:
2396 case SMI_BASETYPE_INTEGER32:
2398 " base[idx++] = %s;\n",
2401 case SMI_BASETYPE_UNSIGNED32:
2403 " base[idx++] = %s;\n",
2406 case SMI_BASETYPE_OCTETSTRING:
2407 maxSize = smiGetMaxSize(iType);
2408 minSize = smiGetMinSize(iType);
2409 if (maxSize > 128 - iNode->oidlen) {
2410 maxSize = 128 - iNode->oidlen;
2412 if (minSize == maxSize) {
2416 } else if (last && indexNode->implied) {
2418 " len = _%sLength;\n",
2422 " len = _%sLength;\n"
2423 " base[idx++] = len;\n",
2426 if (minSize == maxSize) {
2428 " if (len != %u) return -1;\n",
2431 if (minSize > 0 && maxSize < 65535) {
2433 " if (len < %u || len > %u) return -1;\n",
2435 } else if (minSize > 0 && maxSize == 65535) {
2437 " if (len < %u) return -1;\n", minSize);
2438 } else if (minSize == 0 && maxSize < 65535) {
2440 " if (len > %u) return -1;\n", maxSize);
2444 " for (i = 0; i < len; i++) {\n"
2445 " base[idx++] = %s[i];\n"
2446 " if (idx >= 128) return -1;\n"
2450 case SMI_BASETYPE_OBJECTIDENTIFIER:
2451 maxSize = smiGetMaxSize(iType);
2452 minSize = smiGetMinSize(iType);
2453 if (maxSize > 128 - iNode->oidlen) {
2454 maxSize = 128 - iNode->oidlen;
2456 if (minSize == maxSize) {
2460 } else if (last && indexNode->implied) {
2462 " len = _%sLength;\n",
2466 " len = _%sLength;\n"
2467 " base[idx++] = len;\n",
2470 if (minSize == maxSize) {
2472 " if (len != %u) return -1;\n",
2475 if (minSize > 0 && maxSize < 65535) {
2477 " if (len < %u || len > %u) return -1;\n",
2479 } else if (minSize > 0 && maxSize == 65535) {
2481 " if (len < %u) return -1;\n", minSize);
2482 } else if (minSize == 0 && maxSize < 65535) {
2484 " if (len > %u) return -1;\n", maxSize);
2488 " for (i = 0; i < len; i++) {\n"
2489 " base[idx++] = %s[i];\n"
2490 " if (idx >= 128) return -1;\n"
2496 " /* XXX how to pack %s ? */\n", cGroupName);
2500 if (name) xfree(name);
2514 printAssignMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
2516 char *cPrefix, *cGroupName;
2518 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2519 cGroupName = translate(groupNode->name);
2521 if (groupNode->nodekind == SMI_NODEKIND_ROW) {
2522 printUnpackMethod(f, smiModule, groupNode);
2523 printPackMethod(f, smiModule, groupNode);
2527 "static inline %s_%s_t *\n"
2528 "assign_%s(GList *vbl)\n"
2533 cPrefix, cGroupName, cGroupName,
2534 cPrefix, cGroupName, cGroupName);
2537 " %s = %s_new_%s();\n"
2538 " p = (char *) %s + sizeof(%s_%s_t);\n"
2539 " * (GList **) p = vbl;\n"
2541 cGroupName, cPrefix, cGroupName,
2542 cGroupName, cPrefix, cGroupName);
2544 if (groupNode->nodekind == SMI_NODEKIND_ROW) {
2546 " if (unpack_%s((GNetSnmpVarBind *) vbl->data, %s) < 0) {\n"
2547 " g_warning(\"%%s: invalid instance identifier\", \"%s\");\n"
2551 cGroupName, cGroupName, cGroupName, cGroupName);
2555 " gnet_snmp_attr_assign(vbl, %s_oid, G_N_ELEMENTS(%s_oid),\n"
2560 "\n", cGroupName, cGroupName, cGroupName, cGroupName, cGroupName);
2570 printGetTableMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
2573 char *cPrefix, *cModuleName, *cRowName, *cTableName;
2576 tableNode = smiGetParentNode(rowNode);
2581 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2582 cModuleName = translateLower(smiModule->name);
2583 cRowName = translate(rowNode->name);
2584 cTableName = translate(tableNode->name);
2588 "%s_get_%s(GNetSnmp *s, %s_%s_t ***%s, gint64 mask)\n"
2590 " GList *in = NULL, *out = NULL;\n",
2591 cPrefix, cTableName, cPrefix, cRowName, cRowName);
2597 fprintf(f, " static guint32 const _base[] = {");
2598 for (i = 0; i < rowNode->oidlen; i++) {
2599 fprintf(f, "%u, ", rowNode->oid[i]);
2601 fprintf(f, "0};\n");
2602 fprintf(f, " guint32 base[128];\n");
2607 " memcpy(base, _base, sizeof(_base));\n"
2612 " gnet_snmp_attr_get(s, &in, base, %u, %u, %s_attr, mask);\n",
2613 rowNode->oidlen+1, rowNode->oidlen, cRowName);
2617 " out = gnet_snmp_sync_table(s, in);\n"
2618 " /* gnet_snmp_varbind_list_free(in); */\n"
2622 " *%s = (%s_%s_t **) g_malloc0((g_list_length(out) + 1) * sizeof(%s_%s_t *));\n"
2623 " for (row = out, i = 0; row; row = g_list_next(row), i++) {\n"
2624 " (*%s)[i] = assign_%s(row->data);\n"
2629 cRowName, cPrefix, cRowName,
2631 cRowName, cRowName);
2642 printGetRowMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
2644 char *cPrefix, *cRowName;
2646 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2647 cRowName = translate(rowNode->name);
2651 "%s_get_%s(GNetSnmp *s, %s_%s_t **%s",
2652 cPrefix, cRowName, cPrefix, cRowName, cRowName);
2653 foreachIndexDo(f, rowNode, printIndexParamsFunc, 1, 0);
2657 " GList *in = NULL, *out = NULL;\n");
2660 " guint32 base[128];\n"
2663 " memcpy(base, %s_oid, sizeof(%s_oid));\n",
2664 cRowName, cRowName);
2667 " len = pack_%s(base",
2670 foreachIndexDo(f, rowNode, printIndexParamsFunc, 0, 0);
2675 " g_warning(\"%%s: invalid index values\", \"%s\");\n"
2676 " s->error_status = GNET_SNMP_PDU_ERR_INTERNAL;\n"
2688 " gnet_snmp_attr_get(s, &in, base, len, %u, %s_attr, mask);\n",
2689 rowNode->oidlen, cRowName);
2693 " out = gnet_snmp_sync_get(s, in);\n"
2694 " g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
2695 " g_list_free(in);\n"
2697 " if (s->error_status != GNET_SNMP_PDU_ERR_NOERROR) {\n"
2698 " g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
2699 " g_list_free(out);\n"
2702 " *%s = assign_%s(out);\n"
2705 "\n", cRowName, cRowName);
2714 printSetRowMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
2716 char *cPrefix, *cRowName, *cTableName;
2719 tableNode = smiGetParentNode(rowNode);
2724 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2725 cRowName = translate(rowNode->name);
2726 cTableName = translate(tableNode->name);
2730 "%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask)\n"
2732 " GList *in = NULL, *out = NULL;\n",
2733 cPrefix, cRowName, cPrefix, cRowName, cRowName);
2736 " guint32 base[128];\n"
2739 " memcpy(base, %s_oid, sizeof(%s_oid));\n",
2740 cRowName, cRowName);
2743 " len = pack_%s(base", cRowName);
2745 foreachIndexDo(f, rowNode, printIndexParamsPassFunc, 0, 0);
2750 " g_warning(\"%%s: invalid index values\", \"%s\");\n"
2751 " s->error_status = GNET_SNMP_PDU_ERR_INTERNAL;\n"
2758 " gnet_snmp_attr_set(s, &in, base, len, %u, %s_attr, mask, %s);\n",
2759 rowNode->oidlen, cRowName, cRowName);
2763 " out = gnet_snmp_sync_set(s, in);\n"
2764 " g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
2765 " g_list_free(in);\n"
2767 " g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
2768 " g_list_free(out);\n"
2781 printCreateMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
2783 char *cPrefix, *cNodeName, *cGroupName;
2784 char *dModuleName, *dNodeName;
2785 SmiModule *smiModule;
2787 smiModule = smiGetNodeModule(smiNode);
2789 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2790 dModuleName = translateUpper(smiModule->name);
2791 cGroupName = translate(groupNode->name);
2792 cNodeName = translate(smiNode->name);
2793 dNodeName = translateUpper(smiNode->name);
2797 "%s_create_%s(GNetSnmp *s",
2798 cPrefix, cGroupName);
2800 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
2806 " gint32 create = 4; /* SNMPv2-TC::RowStatus createAndGo */\n"
2808 cPrefix, cGroupName, cGroupName);
2811 " %s = %s_new_%s();\n",
2812 cGroupName, cPrefix, cGroupName);
2814 foreachIndexDo(f, groupNode, printIndexAssignmentFunc, 0, 0);
2816 fprintf(f, " %s->%s = &create;\n",
2817 cGroupName, cNodeName);
2820 " %s_set_%s(s, %s, %s_%s);\n"
2821 " %s_free_%s(%s);\n",
2822 cPrefix, cGroupName, cGroupName,
2823 dModuleName, dNodeName,
2824 cPrefix, cGroupName, cGroupName);
2840 printDeleteMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
2842 char *cPrefix, *cNodeName, *cGroupName;
2843 char *dModuleName, *dNodeName;
2844 SmiModule *smiModule;
2846 smiModule = smiGetNodeModule(smiNode);
2848 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2849 dModuleName = translateUpper(smiModule->name);
2850 cGroupName = translate(groupNode->name);
2851 cNodeName = translate(smiNode->name);
2852 dNodeName = translateUpper(smiNode->name);
2856 "%s_delete_%s(GNetSnmp *s",
2857 cPrefix, cGroupName);
2859 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
2865 " gint32 destroy = 6; /* SNMPv2-TC::RowStatus destroy */\n"
2867 cPrefix, cGroupName, cGroupName);
2870 " %s_get_%s(s, &%s",
2871 cPrefix, cGroupName, cGroupName);
2873 foreachIndexDo(f, groupNode, printIndexParamsFunc, 0, 0);
2877 " if (s->error_status || !%s) return;\n",
2878 dModuleName, dNodeName,
2881 fprintf(f, " %s->%s = &destroy;\n",
2882 cGroupName, cNodeName);
2885 " %s_set_%s(s, %s, %s_%s);\n"
2886 " %s_free_%s(%s);\n",
2887 cPrefix, cGroupName, cGroupName,
2888 dModuleName, dNodeName,
2889 cPrefix, cGroupName, cGroupName);
2905 printSetMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
2907 char *cPrefix, *cNodeName, *cGroupName;
2908 char *dModuleName, *dNodeName;
2910 SmiModule *smiModule;
2911 unsigned minSize, maxSize;
2913 smiModule = smiGetNodeModule(smiNode);
2914 smiType = smiGetNodeType(smiNode);
2919 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
2920 dModuleName = translateUpper(smiModule->name);
2921 cGroupName = translate(groupNode->name);
2922 cNodeName = translate(smiNode->name);
2923 dNodeName = translateUpper(smiNode->name);
2927 "%s_set_%s(GNetSnmp *s",
2928 cPrefix, cNodeName);
2930 foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
2931 printParam(f, smiNode);
2937 "\n", cPrefix, cGroupName, cGroupName);
2940 " %s_get_%s(s, &%s",
2941 cPrefix, cGroupName, cGroupName);
2943 foreachIndexDo(f, groupNode, printIndexParamsFunc, 0, 0);
2947 " if (s->error_status || !%s) return;\n",
2948 dModuleName, dNodeName,
2951 switch (smiType->basetype) {
2952 case SMI_BASETYPE_OBJECTIDENTIFIER:
2953 case SMI_BASETYPE_OCTETSTRING:
2954 maxSize = smiGetMaxSize(smiType);
2955 minSize = smiGetMinSize(smiType);
2956 fprintf(f, " %s->%s = %s;\n",
2957 cGroupName, cNodeName, cNodeName);
2958 if (minSize != maxSize) {
2959 fprintf(f, " %s->_%sLength = _%sLength;\n",
2960 cGroupName, cNodeName, cNodeName);
2963 case SMI_BASETYPE_UNSIGNED32:
2964 case SMI_BASETYPE_ENUM:
2965 case SMI_BASETYPE_INTEGER32:
2966 fprintf(f, " %s->%s = &%s;\n",
2967 cGroupName, cNodeName, cNodeName);
2970 fprintf(f, " /* ?? */\n");
2975 " %s_set_%s(s, %s, %s_%s);\n"
2976 " %s_free_%s(%s);\n",
2977 cPrefix, cGroupName, cGroupName,
2978 dModuleName, dNodeName,
2979 cPrefix, cGroupName, cGroupName);
2995 printGetScalarsMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
2997 char *cPrefix, *cGroupName;
3000 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
3001 cGroupName = translate(groupNode->name);
3005 "%s_get_%s(GNetSnmp *s, %s_%s_t **%s, gint64 mask)\n"
3007 " GList *in = NULL, *out = NULL;\n",
3008 cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
3010 fprintf(f, " static const guint32 _base[] = {");
3011 for (i = 0; i < groupNode->oidlen; i++) {
3012 fprintf(f, "%u, ", groupNode->oid[i]);
3014 fprintf(f, "0};\n");
3015 fprintf(f, " guint32 base[128];\n");
3020 " memcpy(base, _base, sizeof(_base));\n"
3025 " gnet_snmp_attr_get(s, &in, base, %u, %u, %s_attr, mask);\n",
3026 groupNode->oidlen + 1, groupNode->oidlen, cGroupName);
3030 " out = gnet_snmp_sync_getnext(s, in);\n"
3031 " g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
3032 " g_list_free(in);\n"
3034 " if (s->error_status != GNET_SNMP_PDU_ERR_NOERROR) {\n"
3035 " g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
3036 " g_list_free(out);\n"
3039 " *%s = assign_%s(out);\n"
3042 "\n", cGroupName, cGroupName);
3051 printSetScalarsMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
3053 char *cPrefix, *cGroupName;
3056 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
3057 cGroupName = translate(groupNode->name);
3061 "%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask)\n"
3063 " GList *in = NULL, *out = NULL;\n",
3064 cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
3066 fprintf(f, " static guint32 base[] = {");
3067 for (i = 0; i < groupNode->oidlen; i++) {
3068 fprintf(f, "%u, ", groupNode->oid[i]);
3070 fprintf(f, "0, 0};\n\n");
3073 " gnet_snmp_attr_set(s, &in, base, %u, %u, %s_attr, mask, %s);\n",
3074 groupNode->oidlen + 2, groupNode->oidlen, cGroupName, cGroupName);
3078 " out = gnet_snmp_sync_set(s, in);\n"
3079 " g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
3080 " g_list_free(in);\n"
3082 " g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
3083 " g_list_free(out);\n"
3095 printNewMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
3097 char *cPrefix, *cGroupName;
3099 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
3100 cGroupName = translate(groupNode->name);
3108 cPrefix, cGroupName,
3109 cPrefix, cGroupName,
3110 cPrefix, cGroupName, cGroupName);
3113 " %s = (%s_%s_t *) g_malloc0(sizeof(%s_%s_t) + sizeof(gpointer));\n"
3117 cGroupName, cPrefix, cGroupName,
3118 cPrefix, cGroupName, cGroupName);
3127 printFreeTableMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
3130 char *cPrefix, *cGroupName, *cTableName;
3132 tableNode = smiGetParentNode(groupNode);
3137 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
3138 cGroupName = translate(groupNode->name);
3139 cTableName = translate(tableNode->name);
3143 "%s_free_%s(%s_%s_t **%s)\n"
3147 cPrefix, cTableName, cPrefix, cGroupName, cGroupName);
3151 " for (i = 0; %s[i]; i++) {\n"
3152 " %s_free_%s(%s[i]);\n"
3158 cGroupName, cGroupName, cPrefix,
3159 cGroupName, cGroupName, cGroupName);
3170 printFreeMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
3172 char *cPrefix, *cGroupName;
3174 cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
3175 cGroupName = translate(groupNode->name);
3179 "%s_free_%s(%s_%s_t *%s)\n"
3184 cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
3188 " p = (char *) %s + sizeof(%s_%s_t);\n"
3189 " vbl = * (GList **) p;\n"
3190 " g_list_foreach(vbl, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
3191 " g_list_free(vbl);\n"
3196 cGroupName, cGroupName, cPrefix, cGroupName, cGroupName);
3206 printStubMethod2(FILE *f, SmiNode *groupNode)
3211 for (smiNode = smiGetFirstChildNode(groupNode);
3213 smiNode = smiGetNextChildNode(smiNode)) {
3214 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
3215 && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
3216 if (smiNode->access == SMI_ACCESS_READ_WRITE) {
3217 smiType = smiGetNodeType(smiNode);
3218 if (smiType && smiType->name
3219 && strcmp(smiType->name, "RowStatus") == 0) {
3220 if (cflag) printCreateMethod(f, groupNode, smiNode);
3221 if (dflag) printDeleteMethod(f, groupNode, smiNode);
3223 if (! isIndex(groupNode, smiNode)) {
3224 if (sflag) printSetMethod(f, groupNode, smiNode);
3235 printStubMethods(FILE *f, SmiModule *smiModule)
3239 const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
3241 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
3243 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
3244 if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
3246 printNewMethod(f, smiModule, smiNode);
3247 printAssignMethod(f, smiModule, smiNode);
3248 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
3249 printGetTableMethod(f, smiModule, smiNode);
3250 printGetRowMethod(f, smiModule, smiNode);
3251 if (isWritable(smiNode, SMI_NODEKIND_COLUMN)) {
3252 printSetRowMethod(f, smiModule, smiNode);
3255 printGetScalarsMethod(f, smiModule, smiNode);
3256 if (isWritable(smiNode, SMI_NODEKIND_SCALAR)) {
3257 printSetScalarsMethod(f, smiModule, smiNode);
3260 printFreeMethod(f, smiModule, smiNode);
3261 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
3262 printFreeTableMethod(f, smiModule, smiNode);
3264 printStubMethod2(f, smiNode);
3276 dumpStubs(SmiModule *smiModule, char *baseName)
3280 f = createFile(baseName, ".c");
3285 fprintTopComment(f, smiModule);
3288 "#include \"%s.h\"\n"
3292 printStubEnumerations(f, smiModule);
3293 printStubIdentities(f, smiModule);
3294 printStubNotifications(f, smiModule);
3296 printStubContraints(f, smiModule);
3297 printStubAttributes(f, smiModule);
3298 printStubMethods(f, smiModule);
3300 if (fflush(f) || ferror(f)) {
3301 perror("smidump: write error");
3311 dumpScli(int modc, SmiModule **modv, int flags, char *output)
3317 incl_regex = &_incl_regex;
3318 code = regcomp(incl_regex, include, REG_EXTENDED|REG_NOSUB);
3321 regerror(code, incl_regex, buffer, sizeof(buffer));
3322 fprintf(stderr, "smidump: regular expression error: %s\n", buffer);
3328 excl_regex = &_excl_regex;
3329 code = regcomp(excl_regex, exclude, REG_EXTENDED|REG_NOSUB);
3332 regerror(code, excl_regex, buffer, sizeof(buffer));
3333 fprintf(stderr, "smidump: regular expression error: %s\n", buffer);
3335 regfree(incl_regex);
3341 if (flags & SMIDUMP_FLAG_UNITE) {
3342 /* not implemented yet */
3344 for (i = 0; i < modc; i++) {
3345 baseName = output ? output : translateFileName(modv[i]->name);
3346 dumpHeader(modv[i], baseName);
3347 dumpStubs(modv[i], baseName);
3348 if (! output) xfree(baseName);
3353 regfree(incl_regex);
3357 regfree(excl_regex);
3366 static SmidumpDriverOption opt[] = {
3367 { "prefix", OPT_STRING, &prefix, 0,
3368 "use prefix instead of module name in stubs"},
3369 { "include", OPT_STRING, &include, 0,
3370 "include stubs for groups matching a regex"},
3371 { "exclude", OPT_STRING, &exclude, 0,
3372 "exclude stubs for groups matching a regex"},
3373 { "set", OPT_FLAG, &sflag, 0,
3374 "generate set stubs for writable objects"},
3375 { "create", OPT_FLAG, &cflag, 0,
3376 "generate create stubs for tables using RowStatus"},
3377 { "delete", OPT_FLAG, &dflag, 0,
3378 "generate delete stubs for tables using RowStatus"},
3379 { 0, OPT_END, 0, 0 }
3382 static SmidumpDriver driver = {
3386 SMIDUMP_DRIVER_CANT_UNITE,
3387 "ANSI C manager stubs for the gsnmp package",
3392 smidumpRegisterDriver(&driver);