Blame tools/dump-scli.c

Packit 022b05
/*
Packit 022b05
 * dump-scli.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to generate MIB module stubs for the scli package.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2001 J. Schoenwaelder, Technical University of Braunschweig.
Packit 022b05
 * Copyright (c) 2002 J. Schoenwaelder, University of Osnabrueck.
Packit 022b05
 * Copyright (c) 2004 J. Schoenwaelder, International University Bremen.
Packit 022b05
 *
Packit 022b05
 * See the file "COPYING" for information on usage and redistribution
Packit 022b05
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Packit 022b05
 *
Packit 022b05
 * @(#) $Id: dump-scli.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * TODO:
Packit 022b05
 *	  - range checks for 64 bit numbers
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdlib.h>
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <string.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
#ifdef HAVE_UNISTD_H
Packit 022b05
#include <unistd.h>
Packit 022b05
#endif
Packit 022b05
#ifdef HAVE_WIN_H
Packit 022b05
#include "win.h"
Packit 022b05
#endif
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
Packit 022b05
#include <sys/types.h>
Packit 022b05
Packit 022b05
#ifdef HAVE_REGEX_H
Packit 022b05
#include <regex.h>
Packit 022b05
#else
Packit 022b05
#define regex_t int
Packit 022b05
#define regcomp(a, b, c)	1
Packit 022b05
#define regexec(a, b, c, d, e)	0
Packit 022b05
#define regerror(a,b,c,d)	strncpy(c, "regex not supported", d)
Packit 022b05
#define regfree(a)
Packit 022b05
#endif
Packit 022b05
Packit 022b05
static char *prefix = NULL;
Packit 022b05
static char *include = NULL;
Packit 022b05
static char *exclude = NULL;
Packit 022b05
static int  sflag = 0;
Packit 022b05
static int  cflag = 0;
Packit 022b05
static int  dflag = 0;
Packit 022b05
static regex_t _incl_regex, *incl_regex = NULL;
Packit 022b05
static regex_t _excl_regex, *excl_regex = NULL;
Packit 022b05
Packit 022b05
static char *keywords_c99[] = {
Packit 022b05
    "auto",        "enum",        "restrict",    "unsigned",
Packit 022b05
    "break",       "extern",      "return",      "void",
Packit 022b05
    "case",        "float",       "short",       "volatile",
Packit 022b05
    "char",        "for",         "signed",      "while",
Packit 022b05
    "const",       "goto",        "sizeof",      "_Bool",
Packit 022b05
    "continue",    "if",          "static",      "_Complex",
Packit 022b05
    "default",     "inline",      "struct",      "_Imaginary",
Packit 022b05
    "do",          "int",         "switch",
Packit 022b05
    "double",      "long",        "typedef",
Packit 022b05
    "else",        "register",    "union",
Packit 022b05
    NULL
Packit 022b05
};
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isKeyword(char *m)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
    
Packit 022b05
    for (i = 0; keywords_c99[i]; i++) {
Packit 022b05
	if (strcmp(m, keywords_c99[i]) == 0) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *
Packit 022b05
getStringTime(time_t t)
Packit 022b05
{
Packit 022b05
    static char   s[27];
Packit 022b05
    struct tm	  *tm;
Packit 022b05
Packit 022b05
    tm = gmtime(&t);
Packit 022b05
    sprintf(s, "%04d-%02d-%02d %02d:%02d",
Packit 022b05
	    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
Packit 022b05
	    tm->tm_hour, tm->tm_min);
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintCommentString(FILE *f, char *s)
Packit 022b05
{
Packit 022b05
    int i, len;
Packit 022b05
Packit 022b05
    if (s) {
Packit 022b05
	fprintf(f, " *   ");
Packit 022b05
	len = strlen(s);
Packit 022b05
	for (i = 0; i < len; i++) {
Packit 022b05
	    fputc(s[i], f);
Packit 022b05
	    if (s[i] == '\n') {
Packit 022b05
		fprintf(f, " *   ");
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	fputc('\n', f);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintTopComment(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiRevision *smiRevision;
Packit 022b05
    char *date;
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*	\t\t\t\t\t\t-- DO NOT EDIT --\n"
Packit 022b05
	    " * Generated by smidump version " SMI_VERSION_STRING ":\n");
Packit 022b05
Packit 022b05
    fprintf(f, " *   smidump -f scli");
Packit 022b05
    if (sflag) {
Packit 022b05
	fprintf(f, " --scli-set");
Packit 022b05
    }
Packit 022b05
    if (cflag) {
Packit 022b05
	fprintf(f, " --scli-create");
Packit 022b05
    }
Packit 022b05
    if (dflag) {
Packit 022b05
	fprintf(f, " --scli-delete");
Packit 022b05
    }
Packit 022b05
    if (prefix) {
Packit 022b05
	fprintf(f, " \\\n *     --scli-prefix='%s'", prefix);
Packit 022b05
    }
Packit 022b05
    if (include) {
Packit 022b05
	fprintf(f, " \\\n *     --scli-include='%s'", include);
Packit 022b05
    }
Packit 022b05
    if (exclude) {
Packit 022b05
	fprintf(f, " \\\n *     --scli-exclude='%s'", exclude);
Packit 022b05
    }
Packit 022b05
    fprintf(f, " %s\n *\n", smiModule->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    " * Derived from %s:\n", smiModule->name);
Packit 022b05
    fprintCommentString(f, smiModule->description);
Packit 022b05
Packit 022b05
    for (smiRevision = smiGetFirstRevision(smiModule);
Packit 022b05
	 smiRevision;
Packit 022b05
	 smiRevision = smiGetNextRevision(smiRevision)) {
Packit 022b05
	date = getStringTime(smiRevision->date);
Packit 022b05
	fprintf(f,
Packit 022b05
		" *\n"
Packit 022b05
		" * Revision %s:\n", date);
Packit 022b05
	fprintCommentString(f, smiRevision->description);
Packit 022b05
    }
Packit 022b05
Packit 022b05
#if 0
Packit 022b05
    if (smiModule->organization || smiModule->contactinfo) {
Packit 022b05
	fprintf(f, " *\n * Contact:\n");
Packit 022b05
	printCommentString(f, smiModule->organization);
Packit 022b05
	fprintf(f, " *\n");
Packit 022b05
	printCommentString(f, smiModule->contactinfo);
Packit 022b05
    }
Packit 022b05
#endif
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    " *\n * $I" "d$\n"
Packit 022b05
	    " */\n"
Packit 022b05
	    "\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
translate(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    while (isKeyword(s)) {
Packit 022b05
	s = xrealloc(s, strlen(s) + 2);
Packit 022b05
	strcat(s, "_");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
translateUpper(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
	if (islower((int) s[i])) {
Packit 022b05
	    s[i] = toupper(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    while (isKeyword(s)) {
Packit 022b05
	s = xrealloc(s, strlen(s) + 2);
Packit 022b05
	strcat(s, "_");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
translateLower(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
	if (isupper((int) s[i])) {
Packit 022b05
	    s[i] = tolower(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    while (isKeyword(s)) {
Packit 022b05
	s = xrealloc(s, strlen(s) + 2);
Packit 022b05
	strcat(s, "_");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
translateFileName(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '_') s[i] = '-';
Packit 022b05
	if (isupper((int) s[i])) {
Packit 022b05
	    s[i] = tolower(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static FILE *
Packit 022b05
createFile(char *name, char *suffix)
Packit 022b05
{
Packit 022b05
    char *fullname;
Packit 022b05
    FILE *f;
Packit 022b05
Packit 022b05
    fullname = xmalloc(strlen(name) + (suffix ? strlen(suffix) : 0) + 2);
Packit 022b05
    strcpy(fullname, name);
Packit 022b05
    if (suffix) {
Packit 022b05
        strcat(fullname, suffix);
Packit 022b05
    }
Packit 022b05
    if (!access(fullname, R_OK)) {
Packit 022b05
        fprintf(stderr, "smidump: %s already exists\n", fullname);
Packit 022b05
        xfree(fullname);
Packit 022b05
        return NULL;
Packit 022b05
    }
Packit 022b05
    f = fopen(fullname, "w");
Packit 022b05
    if (!f) {
Packit 022b05
        fprintf(stderr, "smidump: cannot open %s for writing: ", fullname);
Packit 022b05
        perror(NULL);
Packit 022b05
        xfree(fullname);
Packit 022b05
        exit(1);
Packit 022b05
    }
Packit 022b05
    xfree(fullname);
Packit 022b05
    return f;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isGroup(SmiNode *smiNode, SmiNodekind memberkind)
Packit 022b05
{
Packit 022b05
    SmiNode *childNode;
Packit 022b05
    int status;
Packit 022b05
Packit 022b05
    if (incl_regex) {
Packit 022b05
	if (! smiNode->name) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
	status = regexec(incl_regex, smiNode->name, (size_t) 0, NULL, 0);
Packit 022b05
	if (status != 0) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (excl_regex) {
Packit 022b05
	if (! smiNode->name) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
	status = regexec(excl_regex, smiNode->name, (size_t) 0, NULL, 0);
Packit 022b05
	if (status == 0) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (childNode = smiGetFirstChildNode(smiNode);
Packit 022b05
	 childNode;
Packit 022b05
	 childNode = smiGetNextChildNode(childNode)) {
Packit 022b05
	if (childNode->nodekind & memberkind) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isAccessible(SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int num = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if ((smiNode->nodekind == SMI_NODEKIND_SCALAR
Packit 022b05
	     || smiNode->nodekind == SMI_NODEKIND_COLUMN)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    num++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return num;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isIndex(SmiNode *groupNode, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    
Packit 022b05
    /*
Packit 022b05
     * Perhaps this test needs to be more sophisticated if you have
Packit 022b05
     * really creative cross-table indexing constructions...
Packit 022b05
     */
Packit 022b05
Packit 022b05
    for (smiElement = smiGetFirstElement(groupNode);
Packit 022b05
	 smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	if (smiNode == smiGetElementNode(smiElement)) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
isWritable(SmiNode *treeNode, SmiNodekind nodekind)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(treeNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (nodekind)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return (smiNode != NULL);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
getSnmpType(SmiType *smiType)
Packit 022b05
{
Packit 022b05
    struct {
Packit 022b05
	char *module;
Packit 022b05
	char *name;
Packit 022b05
	char *tag;
Packit 022b05
    } typemap[] = {
Packit 022b05
	{ "RFC1155-SMI","Counter",	"GNET_SNMP_VARBIND_TYPE_COUNTER32" },
Packit 022b05
	{ "SNMPv2-SMI",	"Counter32",	"GNET_SNMP_VARBIND_TYPE_COUNTER32" },
Packit 022b05
	{ "RFC1155-SMI","TimeTicks",	"GNET_SNMP_VARBIND_TYPE_TIMETICKS" },
Packit 022b05
	{ "SNMPv2-SMI",	"TimeTicks",	"GNET_SNMP_VARBIND_TYPE_TIMETICKS" },
Packit 022b05
	{ "RFC1155-SMI","Opaque",	"GNET_SNMP_VARBIND_TYPE_OPAQUE" },
Packit 022b05
	{ "SNMPv2-SMI",	"Opaque",	"GNET_SNMP_VARBIND_TYPE_OPAQUE" },
Packit 022b05
	{ "RFC1155-SMI","IpAddress",	"GNET_SNMP_VARBIND_TYPE_IPADDRESS" },
Packit 022b05
	{ "SNMPv2-SMI",	"IpAddress",	"GNET_SNMP_VARBIND_TYPE_IPADDRESS" },
Packit 022b05
	{ NULL, NULL, NULL }
Packit 022b05
    };
Packit 022b05
Packit 022b05
    SmiBasetype basetype = smiType->basetype;
Packit 022b05
    
Packit 022b05
    do {
Packit 022b05
	int i;
Packit 022b05
	for (i = 0; typemap[i].name; i++) {
Packit 022b05
	    if (smiType->name
Packit 022b05
		&& (strcmp(smiType->name, typemap[i].name) == 0)) {
Packit 022b05
		return typemap[i].tag;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    } while ((smiType = smiGetParentType(smiType)));
Packit 022b05
Packit 022b05
    switch (basetype) {
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_INTEGER32";
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_UNSIGNED32";
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	return NULL;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_COUNTER64";
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_OCTETSTRING";
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_OCTETSTRING";
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	return "GNET_SNMP_VARBIND_TYPE_OBJECTID";
Packit 022b05
    case SMI_BASETYPE_FLOAT32:
Packit 022b05
    case SMI_BASETYPE_FLOAT64:
Packit 022b05
    case SMI_BASETYPE_FLOAT128:
Packit 022b05
	return NULL;
Packit 022b05
    case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	return NULL;
Packit 022b05
    case SMI_BASETYPE_POINTER:
Packit 022b05
	return NULL;
Packit 022b05
    }
Packit 022b05
    return NULL;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef void	(*ForEachIndexFunc)	(FILE *f, SmiNode *groupNode, SmiNode *smiNode, int flags, int maxlen, char *name);
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Check whether we have duplicate nodes in the INDEX.  If yes,
Packit 022b05
 * generate a unique name.
Packit 022b05
 */
Packit 022b05
Packit 022b05
static char*
Packit 022b05
getIndexName(SmiNode *indexNode, SmiNode *iNode, SmiElement *smiElement)
Packit 022b05
{
Packit 022b05
    SmiElement *se;
Packit 022b05
    SmiNode *sn;
Packit 022b05
    int n = 0, m = 0, tail = 0;
Packit 022b05
    char *name;
Packit 022b05
    
Packit 022b05
    for (se = smiGetFirstElement(indexNode);
Packit 022b05
	 se; se = smiGetNextElement(se)) {
Packit 022b05
	sn = smiGetElementNode(se);
Packit 022b05
	if (strcmp(sn->name, iNode->name) == 0) {
Packit 022b05
	    n++;
Packit 022b05
	    if (! tail) m++;
Packit 022b05
	}
Packit 022b05
	if (se == smiElement) tail = 1;
Packit 022b05
    }
Packit 022b05
    if (n > 1) {
Packit 022b05
	smiAsprintf(&name, "%s%d", iNode->name, m);
Packit 022b05
    } else {
Packit 022b05
	name = xstrdup(iNode->name);
Packit 022b05
    }
Packit 022b05
    return name;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
foreachIndexDo(FILE *f, SmiNode *smiNode, ForEachIndexFunc func,
Packit 022b05
	       int flags, int maxlen)
Packit 022b05
{
Packit 022b05
    SmiNode *indexNode = NULL, *iNode;
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    
Packit 022b05
    switch (smiNode->indexkind) {
Packit 022b05
    case SMI_INDEX_INDEX:
Packit 022b05
    case SMI_INDEX_REORDER:
Packit 022b05
	indexNode = smiNode;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_EXPAND:	/* TODO: we have to do more work here! */
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_AUGMENT:
Packit 022b05
    case SMI_INDEX_SPARSE:
Packit 022b05
	indexNode = smiGetRelatedNode(smiNode);
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    if (indexNode) {
Packit 022b05
	for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
	     smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	    iNode = smiGetElementNode(smiElement);
Packit 022b05
	    if (iNode) {
Packit 022b05
		char *name = getIndexName(indexNode, iNode, smiElement);
Packit 022b05
		(func) (f, smiNode, iNode, flags, maxlen, name);
Packit 022b05
		if (name) xfree(name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printIndexParamsFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
Packit 022b05
		     int flags, int maxlen, char *name)
Packit 022b05
{
Packit 022b05
    SmiType *iType;
Packit 022b05
    char *cName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
Packit 022b05
    iType = smiGetNodeType(iNode);
Packit 022b05
    if (! iType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cName = translate(name ? name : iNode->name);
Packit 022b05
    switch (iType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	maxSize = smiGetMaxSize(iType);
Packit 022b05
	minSize = smiGetMinSize(iType);
Packit 022b05
	fprintf(f, ", %s%s", flags ? "guint32 *" : "", cName);
Packit 022b05
	if (minSize != maxSize) {
Packit 022b05
	    fprintf(f, ", %s_%sLength",
Packit 022b05
		    flags ? "guint16 " : "", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	maxSize = smiGetMaxSize(iType);
Packit 022b05
	minSize = smiGetMinSize(iType);
Packit 022b05
	fprintf(f, ", %s%s", flags ? "guchar *" : "", cName);
Packit 022b05
	if (minSize != maxSize) {
Packit 022b05
	    fprintf(f, ", %s_%sLength",
Packit 022b05
		    flags ? "guint16 " : "", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	fprintf(f, ", %s%s", flags ? "gint32 " : "", cName);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	fprintf(f, ", %s%s", flags ? "guint32 " : "", cName);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	fprintf(f, "/* ?? %s */", cName);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    xfree(cName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printIndexParamsPassFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
Packit 022b05
			 int flags, int maxlen, char *name)
Packit 022b05
{
Packit 022b05
    SmiType *iType;
Packit 022b05
    char *cName, *gName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
Packit 022b05
    iType = smiGetNodeType(iNode);
Packit 022b05
    if (! iType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    gName = translate(smiNode->name);
Packit 022b05
    cName = translate(iNode->name);
Packit 022b05
    fprintf(f, ", %s->%s", gName, cName);
Packit 022b05
    switch (iType->basetype) {
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	maxSize = smiGetMaxSize(iType);
Packit 022b05
	minSize = smiGetMinSize(iType);
Packit 022b05
	if (minSize != maxSize) {
Packit 022b05
	    fprintf(f, ", %s->_%sLength", gName, cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    xfree(cName);
Packit 022b05
    xfree(gName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printIndexAssignmentFunc(FILE *f, SmiNode *smiNode, SmiNode *iNode,
Packit 022b05
			 int flags, int maxlen, char *name)
Packit 022b05
{
Packit 022b05
    SmiType *iType;
Packit 022b05
    char *cName, *gName, *dName, *dModuleName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
Packit 022b05
    iType = smiGetNodeType(iNode);
Packit 022b05
    if (! iType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    gName = translate(smiNode->name);
Packit 022b05
    cName = translate(iNode->name);
Packit 022b05
    dName = translateUpper(iNode->name);
Packit 022b05
    dModuleName = translateUpper(smiGetNodeModule(iNode)->name);
Packit 022b05
    switch (iType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	fprintf(f, "    memcpy(%s->%s, %s, _%sLength * sizeof(guint32));\n",
Packit 022b05
	    gName, cName, cName, cName);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	maxSize = smiGetMaxSize(iType);
Packit 022b05
	minSize = smiGetMinSize(iType);
Packit 022b05
	if (minSize != maxSize) {
Packit 022b05
	    fprintf(f, "    memcpy(%s->%s, %s, _%sLength);\n",
Packit 022b05
		    gName, cName, cName, cName);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "    memcpy(%s->%s, %s, %s_%sLENGTH);\n",
Packit 022b05
		    gName, cName, cName, dModuleName, dName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	fprintf(f, "    %s->%s = %s;\n",
Packit 022b05
		gName, cName, cName);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	fprintf(f, "    /* ?? %s */\n", cName);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(dName);
Packit 022b05
    xfree(cName);
Packit 022b05
    xfree(gName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderEnumeration(FILE *f, SmiModule *smiModule,
Packit 022b05
		       SmiNode * smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    char *cName, *cPrefix;
Packit 022b05
    char *dName, *dModuleName;
Packit 022b05
    char *name;
Packit 022b05
    int len;
Packit 022b05
Packit 022b05
    if (smiType && smiType->name) {
Packit 022b05
	name = smiType->name;
Packit 022b05
    } else if (smiNode && smiNode->name) {
Packit 022b05
	name = smiNode->name;
Packit 022b05
    } else {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cName = translate(name);
Packit 022b05
    dName = translateUpper(name);
Packit 022b05
    
Packit 022b05
    for (len = 0, nn = smiGetFirstNamedNumber(smiType); nn;
Packit 022b05
	 nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	if (len < strlen(nn->name)) {
Packit 022b05
	    len = strlen(nn->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    for (nn = smiGetFirstNamedNumber(smiType); nn;
Packit 022b05
		 nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	char *dEnum = translateUpper(nn->name);
Packit 022b05
	fprintf(f, "#define %s_%s_%-*s %d\n",
Packit 022b05
		dModuleName, dName, len, dEnum,
Packit 022b05
		(int) nn->value.value.integer32);
Packit 022b05
	xfree(dEnum);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "\nextern GNetSnmpEnum const %s_enums_%s[];\n\n",
Packit 022b05
	    cPrefix, cName);
Packit 022b05
    
Packit 022b05
    xfree(dName);
Packit 022b05
    xfree(cName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderEnumerations(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode  *smiNode, *parentNode;
Packit 022b05
    SmiType  *smiType;
Packit 022b05
    int      cnt = 0;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
Packit 022b05
    const char *header =
Packit 022b05
	"/*\n"
Packit 022b05
	" * Tables to map enumerations to strings and vice versa.\n"
Packit 022b05
	" */\n"
Packit 022b05
	"\n";
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, groupkind);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, groupkind)) {
Packit 022b05
	parentNode = smiGetParentNode(smiNode);
Packit 022b05
	if (! parentNode || ! isGroup(parentNode, groupkind)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
	if (smiType && !smiType->name
Packit 022b05
	    && smiType->basetype == SMI_BASETYPE_ENUM
Packit 022b05
	    && smiGetTypeModule(smiType) == smiModule) {
Packit 022b05
	    if (! cnt) {
Packit 022b05
		fputs(header, f);
Packit 022b05
	    }
Packit 022b05
	    cnt++;
Packit 022b05
	    printHeaderEnumeration(f, smiModule, smiNode, smiType);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (smiType = smiGetFirstType(smiModule);
Packit 022b05
	 smiType;
Packit 022b05
	 smiType = smiGetNextType(smiType)) {
Packit 022b05
	if (smiType->basetype == SMI_BASETYPE_ENUM
Packit 022b05
	    && smiGetTypeModule(smiType) == smiModule) {
Packit 022b05
	    if (! cnt) {
Packit 022b05
		fputs(header, f);
Packit 022b05
	    }
Packit 022b05
	    cnt++;
Packit 022b05
	    printHeaderEnumeration(f, smiModule, NULL, smiType);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderIdentities(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode      *smiNode, *moduleIdentityNode, *parentNode;
Packit 022b05
    int          cnt = 0;
Packit 022b05
    unsigned int i;
Packit 022b05
    char         *dName, *dModuleName;
Packit 022b05
    char         *cModuleName;
Packit 022b05
Packit 022b05
    moduleIdentityNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
    
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	parentNode = smiGetParentNode(smiNode);
Packit 022b05
	if (! parentNode || ! isGroup(parentNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (smiNode == moduleIdentityNode) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (! cnt) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "/*\n"
Packit 022b05
		    " * Tables to map identities to strings and vice versa.\n"
Packit 022b05
		    " */\n"
Packit 022b05
		    "\n");
Packit 022b05
	}
Packit 022b05
	cnt++;
Packit 022b05
	dName = translateUpper(smiNode->name);
Packit 022b05
	fprintf(f, "#define %s_%s\t", dModuleName, dName);
Packit 022b05
	for (i = 0; i < smiNode->oidlen; i++) {
Packit 022b05
	    fprintf(f, "%s%u", i ? "," : "", smiNode->oid[i]);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
	xfree(dName);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	cModuleName = translateLower(smiModule->name);
Packit 022b05
	fprintf(f,
Packit 022b05
		"\n"
Packit 022b05
		"extern GNetSnmpIdentity const %s_identities[];\n"
Packit 022b05
		"\n",
Packit 022b05
		cModuleName);
Packit 022b05
	xfree(cModuleName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(dModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderNotifications(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode      *smiNode;
Packit 022b05
    int          cnt = 0;
Packit 022b05
    unsigned int i;
Packit 022b05
    char         *dName, *dModuleName;
Packit 022b05
    char         *cModuleName;
Packit 022b05
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
Packit 022b05
	if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (! cnt) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "/*\n"
Packit 022b05
		    " * Tables to map notifications to strings and vice versa.\n"
Packit 022b05
		    " */\n"
Packit 022b05
		    "\n");
Packit 022b05
	}
Packit 022b05
	cnt++;
Packit 022b05
	dName = translateUpper(smiNode->name);
Packit 022b05
	fprintf(f, "#define %s_%s\t", dModuleName, dName);
Packit 022b05
	for (i = 0; i < smiNode->oidlen; i++) {
Packit 022b05
	    fprintf(f, "%s%u", i ? "," : "", smiNode->oid[i]);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
	xfree(dName);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	cModuleName = translateLower(smiModule->name);
Packit 022b05
	fprintf(f,
Packit 022b05
		"\n"
Packit 022b05
		"extern GNetSnmpIdentity const %s_notifications[];\n"
Packit 022b05
		"\n",
Packit 022b05
		cModuleName);
Packit 022b05
	xfree(cModuleName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(dModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printParam(FILE *f, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    char *cName, *dNodeName, *dModuleName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (! smiType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cName = translate(smiNode->name);
Packit 022b05
    dNodeName = translateUpper(smiNode->name);
Packit 022b05
    dModuleName = translateUpper(smiModule ? smiModule->name : "");
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	fprintf(f,
Packit 022b05
		", guint32 *%s", cName);
Packit 022b05
	if (maxSize != minSize) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    ", guint16 _%sLength", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	fprintf(f,
Packit 022b05
		", guchar *%s", cName);
Packit 022b05
	if (maxSize != minSize) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    ", guint16 _%sLength", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	fprintf(f,
Packit 022b05
		", gint32 %s", cName);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	fprintf(f,
Packit 022b05
		", guint32 %s", cName);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	fprintf(f,
Packit 022b05
		", gint64 %s", cName);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	fprintf(f,
Packit 022b05
		", guint64 %s", cName);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	fprintf(f,
Packit 022b05
		" /* ?? */ _%s", cName);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    xfree(cName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printCreateMethodPrototype(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
    char *cPrefix, *cNodeName;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(groupNode);
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cNodeName = translate(groupNode->name);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "extern void\n"
Packit 022b05
	    "%s_create_%s(GNetSnmp *s", cPrefix, cNodeName);
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    fprintf(f, ");\n\n");
Packit 022b05
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printDeleteMethodPrototype(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
    char *cPrefix, *cNodeName;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(groupNode);
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cNodeName = translate(groupNode->name);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "extern void\n"
Packit 022b05
	    "%s_delete_%s(GNetSnmp *s", cPrefix, cNodeName);
Packit 022b05
    
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    
Packit 022b05
    fprintf(f, ");\n\n");
Packit 022b05
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printSetMethodPrototype(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
    char *cPrefix, *cNodeName;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cNodeName = translate(smiNode->name);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "extern void\n"
Packit 022b05
	    "%s_set_%s(GNetSnmp *s",
Packit 022b05
	    cPrefix, cNodeName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    printParam(f, smiNode);
Packit 022b05
    
Packit 022b05
    fprintf(f, ");\n\n");
Packit 022b05
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printMethodPrototypes(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
Packit 022b05
	    if (smiNode->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
		smiType = smiGetNodeType(smiNode);
Packit 022b05
		if (smiType && smiType->name
Packit 022b05
		    && strcmp(smiType->name, "RowStatus") == 0) {
Packit 022b05
		    if (cflag) printCreateMethodPrototype(f, groupNode);
Packit 022b05
		    if (dflag) printDeleteMethodPrototype(f, groupNode);
Packit 022b05
		} else {
Packit 022b05
		    if (! isIndex(groupNode, smiNode)) {
Packit 022b05
			if (sflag) printSetMethodPrototype(f, groupNode, smiNode);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}	    
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderTypedefMemberComment(FILE *f, SmiNode *smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    char *s = NULL;
Packit 022b05
Packit 022b05
    switch (smiNode->access) {
Packit 022b05
    case SMI_ACCESS_READ_WRITE:
Packit 022b05
	s = "rw";
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_READ_ONLY:
Packit 022b05
	s = "ro";
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_NOT_ACCESSIBLE:
Packit 022b05
	s = "na";
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_NOTIFY:
Packit 022b05
	s = "no";
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    if (s) fprintf(f, "%s", s);
Packit 022b05
    s = smiRenderType(smiType, SMI_RENDER_NAME | SMI_RENDER_QUALIFIED);
Packit 022b05
    if (s) {
Packit 022b05
	fprintf(f, " %s", s);
Packit 022b05
	free(s);
Packit 022b05
    }
Packit 022b05
    if (smiNode->units) {
Packit 022b05
	fprintf(f, " [%s]", smiNode->units);
Packit 022b05
    } else if (smiType->units) {
Packit 022b05
	fprintf(f, " [%s]", smiNode->units);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderTypedefMember(FILE *f, SmiNode *smiNode,
Packit 022b05
			 SmiType *smiType, int isIndex, int maxlen, char *name)
Packit 022b05
{
Packit 022b05
    char *cName, *dNodeName, *dModuleName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
Packit 022b05
    cName = translate(name ? name : smiNode->name);
Packit 022b05
    dNodeName = translateUpper(name ? name : smiNode->name);
Packit 022b05
    dModuleName = translateUpper(smiModule ? smiModule->name : "");
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	if (isIndex && maxSize > 128 - smiNode->oidlen) {
Packit 022b05
	    maxSize = 128 - smiNode->oidlen;
Packit 022b05
	}
Packit 022b05
	if (isIndex) {
Packit 022b05
	    fprintf(f, "    guint32  %s[%u];", cName, maxSize);
Packit 022b05
	    fprintf(f, "%*s/* ", maxlen-strlen(cName)+2, "");
Packit 022b05
	    printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	    fprintf(f, " */\n");
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "    guint32  *%s;", cName);
Packit 022b05
	    fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
Packit 022b05
	    printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	    fprintf(f, " */\n");
Packit 022b05
	}
Packit 022b05
	if (maxSize == minSize) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, maxSize);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sMINLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, minSize);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sMAXLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, maxSize);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "    guint16  _%sLength;\n", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	if (isIndex && maxSize > 128 - smiNode->oidlen) {
Packit 022b05
	    maxSize = 128 - smiNode->oidlen;
Packit 022b05
	}
Packit 022b05
	if (isIndex) {
Packit 022b05
	    fprintf(f, "    guchar   %s[%u];", cName, maxSize);
Packit 022b05
	    fprintf(f, "%*s/* ", maxlen-strlen(cName)+2, "");
Packit 022b05
	    printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	    fprintf(f, " */\n");
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "    guchar   *%s;", cName);
Packit 022b05
	    fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
Packit 022b05
	    printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	    fprintf(f, " */\n");
Packit 022b05
	}
Packit 022b05
	if (maxSize == minSize) {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, maxSize);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sMINLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, minSize);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "#define %s_%sMAXLENGTH %u\n",
Packit 022b05
		    dModuleName, dNodeName, maxSize);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "    guint16  _%sLength;\n", cName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	fprintf(f, "    gint32   %s%s;", isIndex ? "" : "*", cName);
Packit 022b05
	fprintf(f, "%*s/* ", maxlen-strlen(cName)+5+isIndex, "");
Packit 022b05
	printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	fprintf(f, " */\n");
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	fprintf(f, "    guint32  %s%s;", isIndex ? "" : "*", cName);
Packit 022b05
	fprintf(f, "%*s/* ", maxlen-strlen(cName)+5+isIndex, "");
Packit 022b05
	printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	fprintf(f, " */\n");
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	fprintf(f, "    gint64   *%s;", cName);
Packit 022b05
	fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
Packit 022b05
	printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	fprintf(f, " */\n");
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	fprintf(f, "    guint64  *%s;", cName);
Packit 022b05
	fprintf(f, "%*s/* ", maxlen-strlen(cName)+5, "");
Packit 022b05
	printHeaderTypedefMemberComment(f, smiNode, smiType);
Packit 022b05
	fprintf(f, " */\n");
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	fprintf(f,
Packit 022b05
		"    /* ?? */  _%s; \n", cName);
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(dNodeName);
Packit 022b05
    xfree(cName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderTypedefMemberIndex(FILE *f, SmiNode *smiNode, SmiNode *iNode,
Packit 022b05
			      int flags, int maxlen, char *name)
Packit 022b05
{
Packit 022b05
    SmiType *iType;
Packit 022b05
Packit 022b05
    iType = smiGetNodeType(iNode);
Packit 022b05
    if (! iType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printHeaderTypedefMember(f, iNode, iType, 1, maxlen, name);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderTypedef(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char    *cPrefix, *dModuleName, *cGroupName, *dGroupName, *dNodeName;
Packit 022b05
    int     writable = 0, count = 0, len = 0;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    dGroupName = translateUpper(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * C type definitions for %s::%s.\n"
Packit 022b05
	    " */\n\n",
Packit 022b05
	    smiModule->name, groupNode->name);
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
Packit 022b05
	    if (len < strlen(smiNode->name)) {
Packit 022b05
		len = strlen(smiNode->name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
Packit 022b05
	    dNodeName = translateUpper(smiNode->name);
Packit 022b05
	    fprintf(f, "#define %s_%-*s (1 << %d) \n", dModuleName, len, dNodeName, count);
Packit 022b05
	    xfree(dNodeName);
Packit 022b05
	    count++;
Packit 022b05
	}	    
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (count) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "typedef struct {\n");
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printHeaderTypedefMemberIndex, 0, len);
Packit 022b05
	    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
Packit 022b05
	    if (isIndex(groupNode, smiNode)) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    if (smiNode->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
		writable++;
Packit 022b05
	    }
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (! smiType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    printHeaderTypedefMember(f, smiNode, smiType, 0, len, 0);
Packit 022b05
	}	    
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "} %s_%s_t;\n\n", cPrefix, cGroupName);
Packit 022b05
Packit 022b05
    if (groupNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	char *cTableName;
Packit 022b05
	SmiNode *tableNode;
Packit 022b05
Packit 022b05
	tableNode = smiGetParentNode(groupNode);
Packit 022b05
	if (tableNode) {
Packit 022b05
	    cTableName = translate(tableNode->name);
Packit 022b05
	    fprintf(f, "extern void\n"
Packit 022b05
		    "%s_get_%s(GNetSnmp *s, %s_%s_t ***%s, gint64 mask);\n\n",
Packit 022b05
		    cPrefix, cTableName,
Packit 022b05
		    cPrefix, cGroupName, cGroupName);
Packit 022b05
	    fprintf(f, "extern void\n"
Packit 022b05
		    "%s_free_%s(%s_%s_t **%s);\n\n",
Packit 022b05
		    cPrefix, cTableName,
Packit 022b05
		    cPrefix, cGroupName, cGroupName);
Packit 022b05
	    xfree(cTableName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    fprintf(f, "extern %s_%s_t *\n"
Packit 022b05
	    "%s_new_%s(void);\n\n",
Packit 022b05
	    cPrefix, cGroupName, cPrefix, cGroupName);
Packit 022b05
    fprintf(f, "extern void\n"
Packit 022b05
	    "%s_get_%s(GNetSnmp *s, %s_%s_t **%s",
Packit 022b05
	    cPrefix, cGroupName,
Packit 022b05
	    cPrefix, cGroupName,
Packit 022b05
	    cGroupName);
Packit 022b05
    if (groupNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    }
Packit 022b05
    fprintf(f, ", gint64 mask);\n\n");
Packit 022b05
    if (writable) {
Packit 022b05
	fprintf(f, "extern void\n"
Packit 022b05
		"%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask);\n\n",
Packit 022b05
		cPrefix, cGroupName,
Packit 022b05
		cPrefix, cGroupName, cGroupName);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "extern void\n"
Packit 022b05
	    "%s_free_%s(%s_%s_t *%s);\n\n",
Packit 022b05
	    cPrefix, cGroupName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    printMethodPrototypes(f, groupNode);
Packit 022b05
	    
Packit 022b05
    xfree(dGroupName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printHeaderTypedefs(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printHeaderTypedef(f, smiModule, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpHeader(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    char *pModuleName;
Packit 022b05
    FILE *f;
Packit 022b05
    
Packit 022b05
    pModuleName = translateUpper(smiModule->name);
Packit 022b05
Packit 022b05
    f = createFile(baseName, ".h");
Packit 022b05
    if (! f) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintTopComment(f, smiModule);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#ifndef _%s_H_\n"
Packit 022b05
	    "#define _%s_H_\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include \"gsnmp.h\"\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "G_BEGIN_DECLS\n"
Packit 022b05
	    "\n",
Packit 022b05
	    pModuleName, pModuleName);
Packit 022b05
Packit 022b05
    printHeaderEnumerations(f, smiModule);
Packit 022b05
    printHeaderIdentities(f, smiModule);
Packit 022b05
    printHeaderNotifications(f, smiModule);
Packit 022b05
    printHeaderTypedefs(f, smiModule);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "G_END_DECLS\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#endif /* _%s_H_ */\n",
Packit 022b05
	    pModuleName);
Packit 022b05
Packit 022b05
    if (fflush(f) || ferror(f)) {
Packit 022b05
	perror("smidump: write error");
Packit 022b05
	exit(1);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fclose(f);
Packit 022b05
    xfree(pModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubEnumeration(FILE *f, SmiModule *smiModule,
Packit 022b05
		     SmiNode *smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    char *cName, *cPrefix;
Packit 022b05
    char *dName, *dModuleName;
Packit 022b05
    char *name;
Packit 022b05
    int len;
Packit 022b05
Packit 022b05
    if (smiType && smiType->name) {
Packit 022b05
	name = smiType->name;
Packit 022b05
    } else if (smiNode && smiNode->name) {
Packit 022b05
	name = smiNode->name;
Packit 022b05
    } else {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cName = translate(name);
Packit 022b05
    dName = translateUpper(name);
Packit 022b05
    
Packit 022b05
    fprintf(f, "GNetSnmpEnum const %s_enums_%s[] = {\n",
Packit 022b05
	    cPrefix, cName);
Packit 022b05
    for (len = 0, nn = smiGetFirstNamedNumber(smiType); nn;
Packit 022b05
	 nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	if (len < strlen(nn->name)) {
Packit 022b05
	    len = strlen(nn->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    for (nn = smiGetFirstNamedNumber(smiType); nn;
Packit 022b05
	 nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	char *dEnum = translateUpper(nn->name);
Packit 022b05
	fprintf(f, "    { %s_%s_%s,%*s \"%s\" },\n",
Packit 022b05
		dModuleName, dName, dEnum,
Packit 022b05
		len - strlen(dEnum), "", nn->name);
Packit 022b05
	xfree(dEnum);
Packit 022b05
    }
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    { 0, NULL }\n"
Packit 022b05
	    "};\n"
Packit 022b05
	    "\n");
Packit 022b05
    
Packit 022b05
    xfree(dName);
Packit 022b05
    xfree(cName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubEnumerations(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode, *parentNode;
Packit 022b05
    SmiType   *smiType;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, groupkind);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, groupkind)) {
Packit 022b05
	parentNode = smiGetParentNode(smiNode);
Packit 022b05
	if (! parentNode || ! isGroup(parentNode, groupkind)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
	if (smiType && !smiType->name
Packit 022b05
	    && smiType->basetype == SMI_BASETYPE_ENUM
Packit 022b05
	    && smiGetTypeModule(smiType) == smiModule) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printStubEnumeration(f, smiModule, smiNode, smiType);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (smiType = smiGetFirstType(smiModule);
Packit 022b05
	 smiType;
Packit 022b05
	 smiType = smiGetNextType(smiType)) {
Packit 022b05
	if (smiType->basetype == SMI_BASETYPE_ENUM
Packit 022b05
	    && smiGetTypeModule(smiType) == smiModule) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printStubEnumeration(f, smiModule, NULL, smiType);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubIdentities(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode, *moduleIdentityNode, *parentNode;
Packit 022b05
    char      *cName, *cModuleName;
Packit 022b05
    char      *dName, *dModuleName;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    
Packit 022b05
    moduleIdentityNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
    
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	parentNode = smiGetParentNode(smiNode);
Packit 022b05
	if (! parentNode || ! isGroup(parentNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	if (smiNode == moduleIdentityNode) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	cnt++;
Packit 022b05
	cName = translate(smiNode->name);
Packit 022b05
	dName = translateUpper(smiNode->name);
Packit 022b05
	fprintf(f,
Packit 022b05
		"static guint32 const %s[]\n\t= { %s_%s };\n",
Packit 022b05
		cName, dModuleName, dName);
Packit 022b05
	xfree(dName);
Packit 022b05
	xfree(cName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"\n"
Packit 022b05
		"GNetSnmpIdentity const %s_identities[] = {\n",
Packit 022b05
		cModuleName);
Packit 022b05
    
Packit 022b05
	for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	    if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    if (smiNode == moduleIdentityNode) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
	    fprintf(f, "    { %s,\n"
Packit 022b05
		    "      G_N_ELEMENTS(%s),\n"
Packit 022b05
		    "      \"%s\" },\n",
Packit 022b05
		    cName, cName, smiNode->name);
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	fprintf(f,
Packit 022b05
		"    { 0, 0, NULL }\n"
Packit 022b05
		"};\n"
Packit 022b05
		"\n"
Packit 022b05
		"\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubNotifications(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    char      *cName, *cModuleName;
Packit 022b05
    char      *dName, *dModuleName;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
Packit 022b05
	if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	cnt++;
Packit 022b05
	cName = translate(smiNode->name);
Packit 022b05
	dName = translateUpper(smiNode->name);
Packit 022b05
	fprintf(f,
Packit 022b05
		"static guint32 const %s[]\n\t= { %s_%s };\n",
Packit 022b05
		cName, dModuleName, dName);
Packit 022b05
	xfree(dName);
Packit 022b05
	xfree(cName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"\n"
Packit 022b05
		"GNetSnmpIdentity const %s_notifications[] = {\n",
Packit 022b05
		cModuleName);
Packit 022b05
    
Packit 022b05
	for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
Packit 022b05
	    if (smiNode->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
	    fprintf(f, "    { %s,\n"
Packit 022b05
		    "      G_N_ELEMENTS(%s),\n"
Packit 022b05
		    "      \"%s\" },\n",
Packit 022b05
		    cName, cName, smiNode->name);
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	fprintf(f,
Packit 022b05
		"    { 0, 0, NULL }\n"
Packit 022b05
		"};\n"
Packit 022b05
		"\n"
Packit 022b05
		"\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printSizeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiRange *smiRange;
Packit 022b05
    unsigned int minSize, maxSize;
Packit 022b05
    int cnt;
Packit 022b05
    char *cName;
Packit 022b05
Packit 022b05
    cName = translate(smiNode->name);
Packit 022b05
Packit 022b05
    for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
Packit 022b05
	for (smiRange = smiGetFirstRange(smiType);
Packit 022b05
	     smiRange ; smiRange = smiGetNextRange(smiRange)) {
Packit 022b05
	    minSize = smiRange->minValue.value.unsigned32;
Packit 022b05
	    maxSize = smiRange->maxValue.value.unsigned32;
Packit 022b05
	    if (minSize == 0 && maxSize >= 65535) continue;
Packit 022b05
	    if (f) {
Packit 022b05
		if (cnt) {
Packit 022b05
		    fprintf(f, ", %u, %u", minSize, maxSize);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f, "static guint16 %s_constraints[] = {%uU, %uU",
Packit 022b05
			    cName, minSize, maxSize);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    cnt++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(cName);
Packit 022b05
    if (f && cnt) fprintf(f, ", 0, 0};\n");
Packit 022b05
    return (cnt > 0);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printInteger32RangeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiRange *smiRange;
Packit 022b05
    long minSize, maxSize;
Packit 022b05
    int cnt;
Packit 022b05
    char *cName;
Packit 022b05
Packit 022b05
    cName = translate(smiNode->name);
Packit 022b05
Packit 022b05
    for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
Packit 022b05
	for (smiRange = smiGetFirstRange(smiType);
Packit 022b05
	     smiRange ; smiRange = smiGetNextRange(smiRange)) {
Packit 022b05
	    minSize = smiRange->minValue.value.integer32;
Packit 022b05
	    maxSize = smiRange->maxValue.value.integer32;
Packit 022b05
	    if (minSize < -2147483647 && maxSize > 2147483646) continue;
Packit 022b05
	    if (f) {
Packit 022b05
		if (cnt) {
Packit 022b05
		    fprintf(f, ", %ldL, %ldL", minSize, maxSize);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f, "static gint32 %s_constraints[] = {%ldL, %ldL",
Packit 022b05
			    cName, minSize, maxSize);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    cnt++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(cName);
Packit 022b05
    if (f && cnt) fprintf(f, ", 0, 0};\n");
Packit 022b05
    return (cnt > 0);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printUnsigned32RangeConstraints(FILE *f, SmiNode *smiNode, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiRange *smiRange;
Packit 022b05
    unsigned long minSize, maxSize;
Packit 022b05
    int cnt;
Packit 022b05
    char *cName;
Packit 022b05
Packit 022b05
    cName = translate(smiNode->name);
Packit 022b05
Packit 022b05
    for (cnt = 0; !cnt && smiType; smiType = smiGetParentType(smiType)) {
Packit 022b05
	for (smiRange = smiGetFirstRange(smiType);
Packit 022b05
	     smiRange ; smiRange = smiGetNextRange(smiRange)) {
Packit 022b05
	    minSize = smiRange->minValue.value.unsigned32;
Packit 022b05
	    maxSize = smiRange->maxValue.value.unsigned32;
Packit 022b05
	    if (minSize == 0 && maxSize >= 4294967295UL) continue;
Packit 022b05
	    if (f) {
Packit 022b05
		if (cnt) {
Packit 022b05
		    fprintf(f, ", %luUL, %luUL", minSize, maxSize);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f, "static guint32 %s_constraints[] = {%luUL, %luUL",
Packit 022b05
			cName, minSize, maxSize);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    cnt++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(cName);
Packit 022b05
    if (f && cnt) fprintf(f, ", 0, 0};\n");
Packit 022b05
    return (cnt > 0);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printConstraints(FILE *f, SmiNode *smiNode, SmiNode *groupNode, int flags)
Packit 022b05
{
Packit 022b05
    SmiType *smiType;
Packit 022b05
    int cnt;
Packit 022b05
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (! smiType) {
Packit 022b05
	return 0;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * Generally suppress all INDEX objects (treat them as if they
Packit 022b05
     * were not-accessible). This is a cheap optimization for SMIv1
Packit 022b05
     * MIBs where these objects were generally read-only.
Packit 022b05
     */
Packit 022b05
Packit 022b05
    if (flags && isIndex(groupNode, smiNode)) {
Packit 022b05
	return 0;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE
Packit 022b05
	|| smiNode->access == SMI_ACCESS_NOTIFY) {
Packit 022b05
	return 0;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	cnt = printSizeConstraints(f, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	cnt = printInteger32RangeConstraints(f, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	cnt = printUnsigned32RangeConstraints(f, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	cnt = 0;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return cnt;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printScalarsAttributesContraints(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int      n = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	n += printConstraints(f, smiNode, groupNode, 0);
Packit 022b05
    }
Packit 022b05
    return n;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
printTableAttributesConstraints(FILE *f, SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int     idx, cnt, n = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(rowNode), idx = 0, cnt = 0;
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (isIndex(rowNode, smiNode)) idx++;
Packit 022b05
	cnt++;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(rowNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	n += printConstraints(f, smiNode, rowNode, cnt > idx);
Packit 022b05
    }
Packit 022b05
    return n;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubContraints(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int cnt = 0;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
Packit 022b05
	    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		cnt += printTableAttributesConstraints(f, smiNode);
Packit 022b05
	    } else {
Packit 022b05
		cnt += printScalarsAttributesContraints(f, smiNode);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printAttribute(FILE *f, SmiNode *smiNode, SmiNode *groupNode, int flags)
Packit 022b05
{
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char *snmpType;
Packit 022b05
    char *dModuleName, *dNodeName;
Packit 022b05
    char *cPrefix, *cGroupName, *cNodeName;
Packit 022b05
    unsigned maxSize = 0, minSize = 0;
Packit 022b05
    int cnt;
Packit 022b05
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (!smiType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    snmpType = getSnmpType(smiType);
Packit 022b05
    if (!snmpType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * Generally suppress all INDEX objects (treat them as if they
Packit 022b05
     * were not-accessible). This is a cheap optimization for SMIv1
Packit 022b05
     * MIBs where these objects were generally read-only.
Packit 022b05
     */
Packit 022b05
Packit 022b05
    if (flags && isIndex(groupNode, smiNode)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE
Packit 022b05
	|| smiNode->access == SMI_ACCESS_NOTIFY) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    dModuleName = translateUpper(smiGetNodeModule(smiNode)->name);
Packit 022b05
    dNodeName = translateUpper(smiNode->name);
Packit 022b05
    cNodeName = translate(smiNode->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiGetNodeModule(smiNode)->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    { %u, %s,\n"
Packit 022b05
	    "      %s_%s, \"%s\",\n",
Packit 022b05
	    smiNode->oid[smiNode->oidlen-1], snmpType,
Packit 022b05
	    dModuleName, dNodeName, smiNode->name);
Packit 022b05
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	cnt = printSizeConstraints(NULL, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	cnt = printInteger32RangeConstraints(NULL, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	cnt = printUnsigned32RangeConstraints(NULL, smiNode, smiType);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	cnt = 0;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "       %s_constraints,\n", cNodeName);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "       NULL,\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! flags && isIndex(groupNode, smiNode)) {
Packit 022b05
	fprintf(f, "      -1,\n");
Packit 022b05
    } else {
Packit 022b05
	fprintf(f,
Packit 022b05
		"      G_STRUCT_OFFSET(%s_%s_t, %s),\n",
Packit 022b05
		cPrefix, cGroupName, cNodeName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    if (minSize != maxSize) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"      G_STRUCT_OFFSET(%s_%s_t, _%sLength)",
Packit 022b05
		cPrefix, cGroupName, cNodeName);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f,
Packit 022b05
		"      0");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    ",\n"
Packit 022b05
	    "      %s },\n",
Packit 022b05
	    (smiNode->access > SMI_ACCESS_READ_ONLY) ? "GSNMP_ATTR_FLAG_WRITABLE" : "0");
Packit 022b05
Packit 022b05
    xfree(cPrefix);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(dNodeName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printScalarsAttributes(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	printAttribute(f, smiNode, groupNode, 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printTableAttributes(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int     idx, cnt;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(rowNode), idx = 0, cnt = 0;
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (isIndex(rowNode, smiNode)) idx++;
Packit 022b05
	cnt++;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(rowNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	printAttribute(f, smiNode, rowNode, cnt > idx);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubAttributes(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode      *smiNode;
Packit 022b05
    char         *cName;
Packit 022b05
    int          cnt = 0;
Packit 022b05
    unsigned int i;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
        
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
Packit 022b05
	    fprintf(f, "static guint32 const %s_oid[] = {", cName);
Packit 022b05
	    for (i = 0; i < smiNode->oidlen; i++) {
Packit 022b05
		fprintf(f, "%s%u", i ? ", " : "", smiNode->oid[i]);
Packit 022b05
	    }
Packit 022b05
	    fprintf(f, "};\n\n");
Packit 022b05
	    
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "static GNetSnmpAttribute %s_attr[] = {\n",
Packit 022b05
		    cName);
Packit 022b05
	    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		printTableAttributes(f, smiModule, smiNode);
Packit 022b05
	    } else {
Packit 022b05
		printScalarsAttributes(f, smiModule, smiNode);
Packit 022b05
	    }
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "    { 0, 0, 0, NULL }\n"
Packit 022b05
		    "};\n"
Packit 022b05
		    "\n");
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printInteger32RangeChecks(FILE *f, char *cGroupName, char *cName,
Packit 022b05
			  SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiRange *smiRange;
Packit 022b05
    long int minSize, maxSize;
Packit 022b05
    int c;
Packit 022b05
Packit 022b05
    for (c = 0; smiType; smiType = smiGetParentType(smiType)) {
Packit 022b05
	for (smiRange = smiGetFirstRange(smiType);
Packit 022b05
	     smiRange ; smiRange = smiGetNextRange(smiRange)) {
Packit 022b05
	    minSize = smiRange->minValue.value.integer32;
Packit 022b05
	    maxSize = smiRange->maxValue.value.integer32;
Packit 022b05
	    if (! c) {
Packit 022b05
		fprintf(f, "    if (");
Packit 022b05
	    } else {
Packit 022b05
		fprintf(f, "\n        && ");
Packit 022b05
	    }
Packit 022b05
	    if (minSize == -2147483647 - 1) {
Packit 022b05
		fprintf(f, "(%s->%s > %ld)", cGroupName, cName, maxSize);
Packit 022b05
	    } else if (maxSize == 2147483647) {
Packit 022b05
		fprintf(f, "(%s->%s < %ld)", cGroupName, cName, minSize);
Packit 022b05
	    } else if (minSize == maxSize) {
Packit 022b05
		fprintf(f, "(%s->%s != %ld)", cGroupName, cName, maxSize);
Packit 022b05
	    } else {
Packit 022b05
		fprintf(f, "(%s->%s < %ld || %s->%s > %ld)",
Packit 022b05
			cGroupName, cName, minSize,
Packit 022b05
			cGroupName, cName, maxSize);
Packit 022b05
	    }
Packit 022b05
	    c++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (c) {
Packit 022b05
	fprintf(f, ") {\n"
Packit 022b05
		"         return -1;\n"
Packit 022b05
		"    }\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printUnsigned32RangeChecks(FILE *f, char *cGroupName, char *cName,
Packit 022b05
			   SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiRange *smiRange;
Packit 022b05
    unsigned long minSize, maxSize;
Packit 022b05
    int c;
Packit 022b05
Packit 022b05
    for (c = 0; smiType; smiType = smiGetParentType(smiType)) {
Packit 022b05
	for (smiRange = smiGetFirstRange(smiType);
Packit 022b05
	     smiRange ; smiRange = smiGetNextRange(smiRange)) {
Packit 022b05
	    minSize = smiRange->minValue.value.unsigned32;
Packit 022b05
	    maxSize = smiRange->maxValue.value.unsigned32;
Packit 022b05
	    if (minSize == 0 && maxSize == 4294967295U) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    if (! c) {
Packit 022b05
		fprintf(f, "     if (");
Packit 022b05
	    } else {
Packit 022b05
		fprintf(f, "\n         && ");
Packit 022b05
	    }
Packit 022b05
	    if (minSize == 0) {
Packit 022b05
		fprintf(f, "(%s->%s > %lu)", cGroupName, cName, maxSize);
Packit 022b05
	    } else if (maxSize == 4294967295U) {
Packit 022b05
		fprintf(f, "(%s->%s < %lu)", cGroupName, cName, minSize);
Packit 022b05
	    } else if (minSize == maxSize) {
Packit 022b05
		fprintf(f, "(%s->%s != %lu)", cGroupName, cName, maxSize);
Packit 022b05
	    } else {
Packit 022b05
		fprintf(f, "(%s->%s < %lu || %s->%s > %lu)",
Packit 022b05
			cGroupName, cName, minSize,
Packit 022b05
			cGroupName, cName, maxSize);
Packit 022b05
	    }
Packit 022b05
	    c++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    if (c) {
Packit 022b05
	fprintf(f, ") {\n"
Packit 022b05
		"         return -1;\n"
Packit 022b05
		"    }\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printUnpackMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    SmiNode *indexNode = NULL;
Packit 022b05
    SmiNode *iNode;
Packit 022b05
    SmiType *iType;
Packit 022b05
    char    *cPrefix, *cGroupName, *cName, *name;
Packit 022b05
    unsigned maxSize, minSize;
Packit 022b05
    int last = 0;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    switch (groupNode->indexkind) {
Packit 022b05
    case SMI_INDEX_INDEX:
Packit 022b05
    case SMI_INDEX_REORDER:
Packit 022b05
	indexNode = groupNode;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_EXPAND:	/* TODO: we have to do more work here! */
Packit 022b05
	indexNode = NULL;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_AUGMENT:
Packit 022b05
    case SMI_INDEX_SPARSE:
Packit 022b05
	indexNode = smiGetRelatedNode(groupNode);
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_UNKNOWN:
Packit 022b05
	indexNode = NULL;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * First check if there are OID or string types so that we
Packit 022b05
     * know whether we need some additional variables.
Packit 022b05
     */
Packit 022b05
    
Packit 022b05
    for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
	 smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	iNode = smiGetElementNode(smiElement);
Packit 022b05
	if (iNode) {
Packit 022b05
	    iType = smiGetNodeType(iNode);
Packit 022b05
	    if (iType
Packit 022b05
		&& (iType->basetype == SMI_BASETYPE_OCTETSTRING
Packit 022b05
		    || iType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER)) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "static inline int\n"
Packit 022b05
	    "unpack_%s(GNetSnmpVarBind *vb, %s_%s_t *%s)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    guint8 idx = %u;\n"
Packit 022b05
	    "%s"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cPrefix, cGroupName, cGroupName,
Packit 022b05
	    groupNode->oidlen + 1,
Packit 022b05
	    smiElement ? "    guint16 i, len;\n" : "");
Packit 022b05
Packit 022b05
    for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
	 smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	iNode = smiGetElementNode(smiElement);
Packit 022b05
	last = (smiGetNextElement(smiElement) == NULL);
Packit 022b05
	if (iNode) {
Packit 022b05
	    iType = smiGetNodeType(iNode);
Packit 022b05
	    if (! iType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    name = getIndexName(indexNode, iNode, smiElement);
Packit 022b05
	    cName = translate(name ? name : iNode->name);
Packit 022b05
	    switch (iType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			"    %s->%s = vb->oid[idx++];\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		printInteger32RangeChecks(f, cGroupName, cName, iType);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			"    %s->%s = vb->oid[idx++];\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		printUnsigned32RangeChecks(f, cGroupName, cName, iType);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
		maxSize = smiGetMaxSize(iType);
Packit 022b05
		minSize = smiGetMinSize(iType);
Packit 022b05
		if (maxSize > 128 - iNode->oidlen) {
Packit 022b05
		    maxSize = 128 - iNode->oidlen;
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = %u;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else if (last && indexNode->implied) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			    "    len = vb->oid_len - idx;\n");
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			    "    len = vb->oid[idx++];\n");
Packit 022b05
		}
Packit 022b05
		if (minSize != maxSize) {
Packit 022b05
		    if (minSize > 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u || len > %u) return -1;\n",
Packit 022b05
				minSize, maxSize);
Packit 022b05
		    } else if (minSize > 0 && maxSize == 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u) return -1;\n", minSize);
Packit 022b05
		    } else if (minSize == 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len > %u) return -1;\n", maxSize);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fprintf(f,
Packit 022b05
			"    if (vb->oid_len < idx + len) return -1;\n"
Packit 022b05
			"    for (i = 0; i < len; i++) {\n"
Packit 022b05
			"        %s->%s[i] = vb->oid[idx++];\n"
Packit 022b05
			"    }\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		if (minSize != maxSize) {
Packit 022b05
		    fprintf(f, 
Packit 022b05
			    "    %s->_%sLength = len;\n", cGroupName, cName);
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		maxSize = smiGetMaxSize(iType);
Packit 022b05
		minSize = smiGetMinSize(iType);
Packit 022b05
		if (maxSize > 128 - iNode->oidlen) {
Packit 022b05
		    maxSize = 128 - iNode->oidlen;
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = %u;\n"
Packit 022b05
			    "    if (vb->oid_len < idx + len) return -1;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else if (last && indexNode->implied) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			    "    len = vb->oid_len - idx;\n");
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (vb->oid_len < idx) return -1;\n"
Packit 022b05
			    "    len = vb->oid[idx++];\n"
Packit 022b05
			    "    if (vb->oid_len < idx + len) return -1;\n");
Packit 022b05
		}
Packit 022b05
		if (minSize != maxSize) {
Packit 022b05
		    if (minSize > 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u || len > %u) return -1;\n",
Packit 022b05
				minSize, maxSize);
Packit 022b05
		    } else if (minSize > 0 && maxSize == 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u) return -1;\n", minSize);
Packit 022b05
		    } else if (minSize == 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len > %u) return -1;\n", maxSize);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fprintf(f,
Packit 022b05
			"    for (i = 0; i < len; i++) {\n"
Packit 022b05
			"        %s->%s[i] = vb->oid[idx++];\n"
Packit 022b05
			"    }\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		if (minSize != maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    %s->_%sLength = len;\n", cGroupName, cName);
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    /* XXX how to unpack %s->%s ? */\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    xfree(cName);
Packit 022b05
	    if (name) xfree(name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    if (vb->oid_len > idx) return -1;\n"
Packit 022b05
	    "    return 0;\n"
Packit 022b05
	    "}\n\n");
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printPackMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    SmiNode *indexNode = NULL;
Packit 022b05
    SmiNode *iNode;
Packit 022b05
    SmiType *iType;
Packit 022b05
    char    *cGroupName, *cName, *name;
Packit 022b05
    unsigned maxSize, minSize;
Packit 022b05
    int last = 0;
Packit 022b05
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    switch (groupNode->indexkind) {
Packit 022b05
    case SMI_INDEX_INDEX:
Packit 022b05
    case SMI_INDEX_REORDER:
Packit 022b05
	indexNode = groupNode;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_EXPAND:	/* TODO: we have to do more work here! */
Packit 022b05
	indexNode = NULL;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_AUGMENT:
Packit 022b05
    case SMI_INDEX_SPARSE:
Packit 022b05
	indexNode = smiGetRelatedNode(groupNode);
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_UNKNOWN:
Packit 022b05
	indexNode = NULL;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * First check if there are OID or string types so that we
Packit 022b05
     * know whether we need some additional variables.
Packit 022b05
     */
Packit 022b05
    
Packit 022b05
    for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
	 smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	iNode = smiGetElementNode(smiElement);
Packit 022b05
	if (iNode) {
Packit 022b05
	    iType = smiGetNodeType(iNode);
Packit 022b05
	    if (iType
Packit 022b05
		&& (iType->basetype == SMI_BASETYPE_OCTETSTRING
Packit 022b05
		    || iType->basetype == SMI_BASETYPE_OBJECTIDENTIFIER)) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "static inline gint8\n"
Packit 022b05
	    "pack_%s(guint32 *base",
Packit 022b05
	    cGroupName);
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    fprintf(f,
Packit 022b05
	    ")\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    guint8 idx = %u;\n"
Packit 022b05
	    "%s"
Packit 022b05
	    "\n",
Packit 022b05
	    groupNode->oidlen + 1,
Packit 022b05
	    smiElement ? "    guint16 i, len;\n" : "");
Packit 022b05
Packit 022b05
    for (smiElement = smiGetFirstElement(indexNode);
Packit 022b05
	 smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	iNode = smiGetElementNode(smiElement);
Packit 022b05
	last = (smiGetNextElement(smiElement) == NULL);
Packit 022b05
	if (iNode) {
Packit 022b05
	    iType = smiGetNodeType(iNode);
Packit 022b05
	    if (! iType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    name = getIndexName(indexNode, iNode, smiElement);
Packit 022b05
	    cName = translate(name ? name : iNode->name);
Packit 022b05
	    switch (iType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    base[idx++] = %s;\n",
Packit 022b05
			cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    base[idx++] = %s;\n",
Packit 022b05
			cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
		maxSize = smiGetMaxSize(iType);
Packit 022b05
		minSize = smiGetMinSize(iType);
Packit 022b05
		if (maxSize > 128 - iNode->oidlen) {
Packit 022b05
		    maxSize = 128 - iNode->oidlen;
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = %u;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else if (last && indexNode->implied) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = _%sLength;\n",
Packit 022b05
			    cName);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = _%sLength;\n"
Packit 022b05
			    "    base[idx++] = len;\n",
Packit 022b05
			    cName);
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (len != %u) return -1;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else {
Packit 022b05
		    if (minSize > 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u || len > %u) return -1;\n",
Packit 022b05
				minSize, maxSize);
Packit 022b05
		    } else if (minSize > 0 && maxSize == 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u) return -1;\n", minSize);
Packit 022b05
		    } else if (minSize == 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len > %u) return -1;\n", maxSize);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fprintf(f,
Packit 022b05
			"    for (i = 0; i < len; i++) {\n"
Packit 022b05
			"        base[idx++] = %s[i];\n"
Packit 022b05
			"        if (idx >= 128) return -1;\n"
Packit 022b05
			"    }\n",
Packit 022b05
			cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		maxSize = smiGetMaxSize(iType);
Packit 022b05
		minSize = smiGetMinSize(iType);
Packit 022b05
		if (maxSize > 128 - iNode->oidlen) {
Packit 022b05
		    maxSize = 128 - iNode->oidlen;
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = %u;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else if (last && indexNode->implied) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = _%sLength;\n",
Packit 022b05
			    cName);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    len = _%sLength;\n"
Packit 022b05
			    "    base[idx++] = len;\n",
Packit 022b05
			    cName);
Packit 022b05
		}
Packit 022b05
		if (minSize == maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    if (len != %u) return -1;\n",
Packit 022b05
			    minSize);
Packit 022b05
		} else {
Packit 022b05
		    if (minSize > 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u || len > %u) return -1;\n",
Packit 022b05
				minSize, maxSize);
Packit 022b05
		    } else if (minSize > 0 && maxSize == 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len < %u) return -1;\n", minSize);
Packit 022b05
		    } else if (minSize == 0 && maxSize < 65535) {
Packit 022b05
			fprintf(f,
Packit 022b05
				"    if (len > %u) return -1;\n", maxSize);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		fprintf(f,
Packit 022b05
			"    for (i = 0; i < len; i++) {\n"
Packit 022b05
			"        base[idx++] = %s[i];\n"
Packit 022b05
			"        if (idx >= 128) return -1;\n"
Packit 022b05
			"    }\n",
Packit 022b05
			cName);
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    /* XXX how to pack %s ? */\n", cGroupName);
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    xfree(cName);
Packit 022b05
	    if (name) xfree(name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    return idx;\n"
Packit 022b05
	    "}\n\n");
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printAssignMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    char *cPrefix, *cGroupName;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    if (groupNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	printUnpackMethod(f, smiModule, groupNode);
Packit 022b05
	printPackMethod(f, smiModule, groupNode);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "static inline %s_%s_t *\n"
Packit 022b05
	    "assign_%s(GList *vbl)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    %s_%s_t *%s;\n"
Packit 022b05
	    "    char *p;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s = %s_new_%s();\n"
Packit 022b05
	    "    p = (char *) %s + sizeof(%s_%s_t);\n"
Packit 022b05
	    "    * (GList **) p = vbl;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cPrefix, cGroupName,
Packit 022b05
	    cGroupName, cPrefix, cGroupName);
Packit 022b05
Packit 022b05
    if (groupNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"    if (unpack_%s((GNetSnmpVarBind *) vbl->data, %s) < 0) {\n"
Packit 022b05
		"        g_warning(\"%%s: invalid instance identifier\", \"%s\");\n"
Packit 022b05
		"        g_free(%s);\n"
Packit 022b05
		"        return NULL;\n"
Packit 022b05
		"    }\n\n",
Packit 022b05
		cGroupName, cGroupName, cGroupName, cGroupName);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_assign(vbl, %s_oid, G_N_ELEMENTS(%s_oid),\n"
Packit 022b05
	    "                      %s_attr, %s);\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    return %s;\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n", cGroupName, cGroupName, cGroupName, cGroupName, cGroupName);
Packit 022b05
	    
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
 
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printGetTableMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    SmiNode      *tableNode;
Packit 022b05
    char         *cPrefix, *cModuleName, *cRowName, *cTableName;
Packit 022b05
    unsigned int i;
Packit 022b05
Packit 022b05
    tableNode = smiGetParentNode(rowNode);
Packit 022b05
    if (! tableNode) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    cRowName = translate(rowNode->name);
Packit 022b05
    cTableName = translate(tableNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_get_%s(GNetSnmp *s, %s_%s_t ***%s, gint64 mask)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *in = NULL, *out = NULL;\n",
Packit 022b05
	    cPrefix, cTableName, cPrefix, cRowName, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    GList *row;\n"
Packit 022b05
	    "    int i;\n");
Packit 022b05
Packit 022b05
    fprintf(f, "    static guint32 const _base[] = {");
Packit 022b05
    for (i = 0; i < rowNode->oidlen; i++) {
Packit 022b05
	fprintf(f, "%u, ", rowNode->oid[i]);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "0};\n");
Packit 022b05
    fprintf(f, "    guint32 base[128];\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    *%s = NULL;\n"
Packit 022b05
	    "    memcpy(base, _base, sizeof(_base));\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_get(s, &in, base, %u, %u, %s_attr, mask);\n",
Packit 022b05
	    rowNode->oidlen+1, rowNode->oidlen, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    out = gnet_snmp_sync_table(s, in);\n"
Packit 022b05
	    "    /* gnet_snmp_varbind_list_free(in); */\n"
Packit 022b05
	    "\n");
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    if (out) {\n"
Packit 022b05
	    "        *%s = (%s_%s_t **) g_malloc0((g_list_length(out) + 1) * sizeof(%s_%s_t *));\n"
Packit 022b05
	    "        for (row = out, i = 0; row; row = g_list_next(row), i++) {\n"
Packit 022b05
	    "            (*%s)[i] = assign_%s(row->data);\n"
Packit 022b05
	    "        }\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cRowName, cPrefix, cRowName,
Packit 022b05
	    cPrefix, cRowName,
Packit 022b05
	    cRowName, cRowName);
Packit 022b05
    
Packit 022b05
    xfree(cTableName);
Packit 022b05
    xfree(cRowName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printGetRowMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    char       *cPrefix, *cRowName;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cRowName = translate(rowNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_get_%s(GNetSnmp *s, %s_%s_t **%s",
Packit 022b05
	    cPrefix, cRowName, cPrefix, cRowName, cRowName);
Packit 022b05
    foreachIndexDo(f, rowNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    fprintf(f,
Packit 022b05
	    ", gint64 mask)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *in = NULL, *out = NULL;\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    guint32 base[128];\n"
Packit 022b05
	    "    gint8 len;\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    memcpy(base, %s_oid, sizeof(%s_oid));\n",
Packit 022b05
	    cRowName, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    len = pack_%s(base",
Packit 022b05
	    cRowName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, rowNode, printIndexParamsFunc, 0, 0);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    ");\n"
Packit 022b05
	    "    if (len < 0) {\n"
Packit 022b05
	    "        g_warning(\"%%s: invalid index values\", \"%s\");\n"
Packit 022b05
	    "        s->error_status = GNET_SNMP_PDU_ERR_INTERNAL;\n"
Packit 022b05
	    "        return;\n"
Packit 022b05
	    "    }\n",
Packit 022b05
	    cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    *%s = NULL;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_get(s, &in, base, len, %u, %s_attr, mask);\n",
Packit 022b05
	    rowNode->oidlen, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    out = gnet_snmp_sync_get(s, in);\n"
Packit 022b05
	    "    g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "    g_list_free(in);\n"
Packit 022b05
	    "    if (out) {\n"
Packit 022b05
	    "        if (s->error_status != GNET_SNMP_PDU_ERR_NOERROR) {\n"
Packit 022b05
	    "            g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "            g_list_free(out);\n"
Packit 022b05
	    "            return;\n"
Packit 022b05
	    "        }\n"
Packit 022b05
	    "        *%s = assign_%s(out);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n", cRowName, cRowName);
Packit 022b05
    
Packit 022b05
    xfree(cRowName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printSetRowMethod(FILE *f, SmiModule *smiModule, SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    char         *cPrefix, *cRowName, *cTableName;
Packit 022b05
    SmiNode      *tableNode;
Packit 022b05
Packit 022b05
    tableNode = smiGetParentNode(rowNode);
Packit 022b05
    if (! tableNode) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cRowName = translate(rowNode->name);
Packit 022b05
    cTableName = translate(tableNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *in = NULL, *out = NULL;\n",
Packit 022b05
	    cPrefix, cRowName, cPrefix, cRowName, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    guint32 base[128];\n"
Packit 022b05
	    "    gint8 len;\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    memcpy(base, %s_oid, sizeof(%s_oid));\n",
Packit 022b05
	    cRowName, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    len = pack_%s(base", cRowName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, rowNode, printIndexParamsPassFunc, 0, 0);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    ");\n"
Packit 022b05
	    "    if (len < 0) {\n"
Packit 022b05
	    "        g_warning(\"%%s: invalid index values\", \"%s\");\n"
Packit 022b05
	    "        s->error_status = GNET_SNMP_PDU_ERR_INTERNAL;\n"
Packit 022b05
	    "        return;\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_set(s, &in, base, len, %u, %s_attr, mask, %s);\n",
Packit 022b05
	    rowNode->oidlen, cRowName, cRowName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    out = gnet_snmp_sync_set(s, in);\n"
Packit 022b05
	    "    g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "    g_list_free(in);\n"
Packit 022b05
	    "    if (out) {\n"
Packit 022b05
	    "        g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "        g_list_free(out);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(cTableName);
Packit 022b05
    xfree(cRowName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printCreateMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    char        *cPrefix, *cNodeName, *cGroupName;
Packit 022b05
    char	*dModuleName, *dNodeName;
Packit 022b05
    SmiModule   *smiModule;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    cNodeName = translate(smiNode->name);
Packit 022b05
    dNodeName = translateUpper(smiNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_create_%s(GNetSnmp *s",
Packit 022b05
	    cPrefix, cGroupName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    ")\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    %s_%s_t *%s;\n"
Packit 022b05
	    "    gint32 create = 4; /* SNMPv2-TC::RowStatus createAndGo */\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s = %s_new_%s();\n",
Packit 022b05
	    cGroupName, cPrefix, cGroupName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexAssignmentFunc, 0, 0);
Packit 022b05
Packit 022b05
    fprintf(f, "    %s->%s = &create;\n",
Packit 022b05
	    cGroupName, cNodeName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s_set_%s(s, %s, %s_%s);\n"
Packit 022b05
	    "    %s_free_%s(%s);\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName,
Packit 022b05
	    dModuleName, dNodeName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(dNodeName);
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printDeleteMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    char        *cPrefix, *cNodeName, *cGroupName;
Packit 022b05
    char	*dModuleName, *dNodeName;
Packit 022b05
    SmiModule   *smiModule;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    cNodeName = translate(smiNode->name);
Packit 022b05
    dNodeName = translateUpper(smiNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_delete_%s(GNetSnmp *s",
Packit 022b05
	    cPrefix, cGroupName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    ")\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    %s_%s_t *%s;\n"
Packit 022b05
	    "    gint32 destroy = 6; /* SNMPv2-TC::RowStatus destroy */\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s_get_%s(s, &%s",
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 0, 0);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    ", %s_%s);\n"
Packit 022b05
	    "    if (s->error_status || !%s) return;\n",
Packit 022b05
	    dModuleName, dNodeName,
Packit 022b05
	    cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f, "    %s->%s = &destroy;\n",
Packit 022b05
	    cGroupName, cNodeName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s_set_%s(s, %s, %s_%s);\n"
Packit 022b05
	    "    %s_free_%s(%s);\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName,
Packit 022b05
	    dModuleName, dNodeName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(dNodeName);
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printSetMethod(FILE *f, SmiNode *groupNode, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    char        *cPrefix, *cNodeName, *cGroupName;
Packit 022b05
    char	*dModuleName, *dNodeName;
Packit 022b05
    SmiType	*smiType;
Packit 022b05
    SmiModule   *smiModule;
Packit 022b05
    unsigned	minSize, maxSize;
Packit 022b05
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (! smiType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    dModuleName = translateUpper(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    cNodeName = translate(smiNode->name);
Packit 022b05
    dNodeName = translateUpper(smiNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_set_%s(GNetSnmp *s",
Packit 022b05
	    cPrefix, cNodeName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 1, 0);
Packit 022b05
    printParam(f, smiNode);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    ")\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    %s_%s_t *%s;\n"
Packit 022b05
	    "\n", cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s_get_%s(s, &%s",
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    foreachIndexDo(f, groupNode, printIndexParamsFunc, 0, 0);
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    ", %s_%s);\n"
Packit 022b05
	    "    if (s->error_status || !%s) return;\n",
Packit 022b05
	    dModuleName, dNodeName,
Packit 022b05
	    cGroupName);
Packit 022b05
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	maxSize = smiGetMaxSize(smiType);
Packit 022b05
	minSize = smiGetMinSize(smiType);
Packit 022b05
	fprintf(f, "    %s->%s = %s;\n",
Packit 022b05
		cGroupName, cNodeName, cNodeName);
Packit 022b05
	if (minSize != maxSize) {
Packit 022b05
	    fprintf(f, "    %s->_%sLength = _%sLength;\n",
Packit 022b05
		    cGroupName, cNodeName, cNodeName);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	fprintf(f, "    %s->%s = &%;;\n",
Packit 022b05
		cGroupName, cNodeName, cNodeName);
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	fprintf(f, "    /* ?? */\n");
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s_set_%s(s, %s, %s_%s);\n"
Packit 022b05
	    "    %s_free_%s(%s);\n",
Packit 022b05
	    cPrefix, cGroupName, cGroupName,
Packit 022b05
	    dModuleName, dNodeName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(dNodeName);
Packit 022b05
    xfree(cNodeName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(dModuleName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printGetScalarsMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    char         *cPrefix, *cGroupName;
Packit 022b05
    unsigned int i;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_get_%s(GNetSnmp *s, %s_%s_t **%s, gint64 mask)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *in = NULL, *out = NULL;\n",
Packit 022b05
	    cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f, "    static const guint32 _base[] = {");
Packit 022b05
    for (i = 0; i < groupNode->oidlen; i++) {
Packit 022b05
	fprintf(f, "%u, ", groupNode->oid[i]);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "0};\n");
Packit 022b05
    fprintf(f, "    guint32 base[128];\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    *%s = NULL;\n"
Packit 022b05
	    "    memcpy(base, _base, sizeof(_base));\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_get(s, &in, base, %u, %u, %s_attr, mask);\n",
Packit 022b05
	    groupNode->oidlen + 1, groupNode->oidlen, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    out = gnet_snmp_sync_getnext(s, in);\n"
Packit 022b05
	    "    g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "    g_list_free(in);\n"
Packit 022b05
	    "    if (out) {\n"
Packit 022b05
	    "        if (s->error_status != GNET_SNMP_PDU_ERR_NOERROR) {\n"
Packit 022b05
	    "            g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "            g_list_free(out);\n"
Packit 022b05
	    "            return;\n"
Packit 022b05
	    "        }\n"
Packit 022b05
	    "        *%s = assign_%s(out);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n", cGroupName, cGroupName);
Packit 022b05
    
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printSetScalarsMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    char         *cPrefix, *cGroupName;
Packit 022b05
    unsigned int i;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_set_%s(GNetSnmp *s, %s_%s_t *%s, gint64 mask)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *in = NULL, *out = NULL;\n",
Packit 022b05
	    cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f, "    static guint32 base[] = {");
Packit 022b05
    for (i = 0; i < groupNode->oidlen; i++) {
Packit 022b05
	fprintf(f, "%u, ", groupNode->oid[i]);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "0, 0};\n\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    gnet_snmp_attr_set(s, &in, base, %u, %u, %s_attr, mask, %s);\n",
Packit 022b05
	    groupNode->oidlen + 2, groupNode->oidlen, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    out = gnet_snmp_sync_set(s, in);\n"
Packit 022b05
	    "    g_list_foreach(in, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "    g_list_free(in);\n"
Packit 022b05
	    "    if (out) {\n"
Packit 022b05
	    "        g_list_foreach(out, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "        g_list_free(out);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printNewMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    char *cPrefix, *cGroupName;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "%s_%s_t *\n"
Packit 022b05
	    "%s_new_%s()\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    %s_%s_t *%s;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cGroupName,
Packit 022b05
	    cPrefix, cGroupName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    %s = (%s_%s_t *) g_malloc0(sizeof(%s_%s_t) + sizeof(gpointer));\n"
Packit 022b05
	    "    return %s;\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cPrefix, cGroupName,
Packit 022b05
	    cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printFreeTableMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *tableNode;
Packit 022b05
    char *cPrefix, *cGroupName, *cTableName;
Packit 022b05
Packit 022b05
    tableNode = smiGetParentNode(groupNode);
Packit 022b05
    if (! tableNode) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
    cTableName = translate(tableNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_free_%s(%s_%s_t **%s)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    int i;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cTableName, cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,	    
Packit 022b05
	    "    if (%s) {\n"
Packit 022b05
	    "        for (i = 0; %s[i]; i++) {\n"
Packit 022b05
	    "            %s_free_%s(%s[i]);\n"
Packit 022b05
	    "        }\n"
Packit 022b05
	    "        g_free(%s);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cGroupName, cPrefix,
Packit 022b05
	    cGroupName, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    xfree(cTableName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
 
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printFreeMethod(FILE *f, SmiModule *smiModule, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    char *cPrefix, *cGroupName;
Packit 022b05
Packit 022b05
    cPrefix = prefix ? xstrdup(prefix) : translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void\n"
Packit 022b05
	    "%s_free_%s(%s_%s_t *%s)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    GList *vbl;\n"
Packit 022b05
	    "    char *p;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cPrefix, cGroupName, cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,	    
Packit 022b05
	    "    if (%s) {\n"
Packit 022b05
	    "        p = (char *) %s + sizeof(%s_%s_t);\n"
Packit 022b05
	    "        vbl = * (GList **) p;\n"
Packit 022b05
	    "        g_list_foreach(vbl, (GFunc) gnet_snmp_varbind_delete, NULL);\n"
Packit 022b05
	    "        g_list_free(vbl);\n"
Packit 022b05
	    "        g_free(%s);\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cGroupName, cPrefix, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cPrefix);
Packit 022b05
}
Packit 022b05
 
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubMethod2(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access >= SMI_ACCESS_READ_ONLY)) {
Packit 022b05
	    if (smiNode->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
		smiType = smiGetNodeType(smiNode);
Packit 022b05
		if (smiType && smiType->name
Packit 022b05
		    && strcmp(smiType->name, "RowStatus") == 0) {
Packit 022b05
		    if (cflag) printCreateMethod(f, groupNode, smiNode);
Packit 022b05
		    if (dflag) printDeleteMethod(f, groupNode, smiNode);
Packit 022b05
		} else {
Packit 022b05
		    if (! isIndex(groupNode, smiNode)) {
Packit 022b05
			if (sflag) printSetMethod(f, groupNode, smiNode);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}	    
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
printStubMethods(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    const unsigned int groupkind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode, groupkind) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printNewMethod(f, smiModule, smiNode);
Packit 022b05
	    printAssignMethod(f, smiModule, smiNode);
Packit 022b05
	    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		printGetTableMethod(f, smiModule, smiNode);
Packit 022b05
		printGetRowMethod(f, smiModule, smiNode);
Packit 022b05
		if (isWritable(smiNode, SMI_NODEKIND_COLUMN)) {
Packit 022b05
		    printSetRowMethod(f, smiModule, smiNode);
Packit 022b05
		}
Packit 022b05
	    } else {
Packit 022b05
		printGetScalarsMethod(f, smiModule, smiNode);
Packit 022b05
		if (isWritable(smiNode, SMI_NODEKIND_SCALAR)) {
Packit 022b05
		    printSetScalarsMethod(f, smiModule, smiNode);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    printFreeMethod(f, smiModule, smiNode);
Packit 022b05
	    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		printFreeTableMethod(f, smiModule, smiNode);
Packit 022b05
	    }
Packit 022b05
	    printStubMethod2(f, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpStubs(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    FILE *f;
Packit 022b05
Packit 022b05
    f = createFile(baseName, ".c");
Packit 022b05
    if (! f) {
Packit 022b05
        return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintTopComment(f, smiModule);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#include \"%s.h\"\n"
Packit 022b05
	    "\n",
Packit 022b05
	    baseName);
Packit 022b05
Packit 022b05
    printStubEnumerations(f, smiModule);
Packit 022b05
    printStubIdentities(f, smiModule);
Packit 022b05
    printStubNotifications(f, smiModule);
Packit 022b05
Packit 022b05
    printStubContraints(f, smiModule);
Packit 022b05
    printStubAttributes(f, smiModule);
Packit 022b05
    printStubMethods(f, smiModule);
Packit 022b05
    
Packit 022b05
    if (fflush(f) || ferror(f)) {
Packit 022b05
	perror("smidump: write error");
Packit 022b05
	exit(1);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fclose(f);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpScli(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    char	*baseName;
Packit 022b05
    int		i, code;
Packit 022b05
Packit 022b05
    if (include) {
Packit 022b05
	incl_regex = &_incl_regex;
Packit 022b05
	code = regcomp(incl_regex, include, REG_EXTENDED|REG_NOSUB);
Packit 022b05
	if (code != 0) {
Packit 022b05
	    char buffer[256];
Packit 022b05
	    regerror(code, incl_regex, buffer, sizeof(buffer));
Packit 022b05
	    fprintf(stderr, "smidump: regular expression error: %s\n", buffer);
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (exclude) {
Packit 022b05
	excl_regex = &_excl_regex;
Packit 022b05
	code = regcomp(excl_regex, exclude, REG_EXTENDED|REG_NOSUB);
Packit 022b05
	if (code != 0) {
Packit 022b05
	    char buffer[256];
Packit 022b05
	    regerror(code, excl_regex, buffer, sizeof(buffer));
Packit 022b05
	    fprintf(stderr, "smidump: regular expression error: %s\n", buffer);
Packit 022b05
	    if (incl_regex) {
Packit 022b05
		regfree(incl_regex);
Packit 022b05
	    }
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	/* not implemented yet */
Packit 022b05
    } else {
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    baseName = output ? output : translateFileName(modv[i]->name);
Packit 022b05
	    dumpHeader(modv[i], baseName);
Packit 022b05
	    dumpStubs(modv[i], baseName);
Packit 022b05
	    if (! output) xfree(baseName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (incl_regex) {
Packit 022b05
	regfree(incl_regex);
Packit 022b05
	incl_regex = NULL;
Packit 022b05
    }
Packit 022b05
    if (excl_regex) {
Packit 022b05
	regfree(excl_regex);
Packit 022b05
	excl_regex = NULL;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
void initScli()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "prefix", OPT_STRING, &prefix, 0,
Packit 022b05
	  "use prefix instead of module name in stubs"},
Packit 022b05
	{ "include", OPT_STRING, &include, 0,
Packit 022b05
	  "include stubs for groups matching a regex"},
Packit 022b05
	{ "exclude", OPT_STRING, &exclude, 0,
Packit 022b05
	  "exclude stubs for groups matching a regex"},
Packit 022b05
	{ "set", OPT_FLAG, &sflag, 0,
Packit 022b05
	  "generate set stubs for writable objects"},
Packit 022b05
	{ "create", OPT_FLAG, &cflag, 0,
Packit 022b05
	  "generate create stubs for tables using RowStatus"},
Packit 022b05
	{ "delete", OPT_FLAG, &dflag, 0,
Packit 022b05
	  "generate delete stubs for tables using RowStatus"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"scli",
Packit 022b05
	dumpScli,
Packit 022b05
	0,
Packit 022b05
	SMIDUMP_DRIVER_CANT_UNITE,
Packit 022b05
	"ANSI C manager stubs for the gsnmp package",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}