Blame tools/dump-metrics.c

Packit 022b05
/*
Packit 022b05
 * dump-metrics.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to compute and dump some MIB metrics.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2000 Frank Strauss, Technical University of Braunschweig.
Packit 022b05
 * Copyright (c) 2000 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-metrics.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
/*
Packit 022b05
  # revisions
Packit 022b05
  # imports
Packit 022b05
  # row creations:
Packit 022b05
  # count node references in notification definitions
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <string.h>
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
Packit 022b05
static int raw = 0;
Packit 022b05
Packit 022b05
static int silent = 0;
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct BasetypeCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long unknown;
Packit 022b05
    unsigned long integer32;
Packit 022b05
    unsigned long octetstring;
Packit 022b05
    unsigned long objectidentifier;
Packit 022b05
    unsigned long unsigned32;
Packit 022b05
    unsigned long integer64;
Packit 022b05
    unsigned long unsigned64;
Packit 022b05
    unsigned long float32;
Packit 022b05
    unsigned long float64;
Packit 022b05
    unsigned long float128;
Packit 022b05
    unsigned long enums;
Packit 022b05
    unsigned long bits;
Packit 022b05
    unsigned long pointer;
Packit 022b05
} BasetypeCounter;
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct StatusCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long current;
Packit 022b05
    unsigned long deprecated;
Packit 022b05
    unsigned long obsolete;
Packit 022b05
} StatusCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct AccessCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long noaccess;
Packit 022b05
    unsigned long notify;
Packit 022b05
    unsigned long readonly;
Packit 022b05
    unsigned long readwrite;
Packit 022b05
} AccessCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct IndexCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long index;
Packit 022b05
    unsigned long augment;
Packit 022b05
    unsigned long reorder;
Packit 022b05
    unsigned long sparse;
Packit 022b05
    unsigned long expand;
Packit 022b05
} IndexCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct IndexLenCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long length[11];
Packit 022b05
} IndexLenCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct TableLenCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long length[81];
Packit 022b05
} TableLenCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct ScalarLenCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long length[81];
Packit 022b05
} ScalarLenCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct IndexComplexityCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long complexity[100];
Packit 022b05
} IndexComplexityCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct LengthCounter {
Packit 022b05
    unsigned long total;
Packit 022b05
    unsigned long descr;
Packit 022b05
    unsigned long descr_len;
Packit 022b05
    unsigned long reference;
Packit 022b05
    unsigned long reference_len;
Packit 022b05
    unsigned long units;
Packit 022b05
    unsigned long units_len;
Packit 022b05
    unsigned long format;
Packit 022b05
    unsigned long format_len;
Packit 022b05
} LengthCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct RowStatusCounter {
Packit 022b05
    unsigned long basetables;
Packit 022b05
    unsigned long rowstatus;
Packit 022b05
    unsigned long storagetype;
Packit 022b05
} RowStatusCounter;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct Metrics {
Packit 022b05
    BasetypeCounter basetypesColumns;
Packit 022b05
    BasetypeCounter basetypesScalars;
Packit 022b05
    BasetypeCounter basetypesAll;
Packit 022b05
    StatusCounter   statusTypes;
Packit 022b05
    StatusCounter   statusTables;
Packit 022b05
    StatusCounter   statusColumns;
Packit 022b05
    StatusCounter   statusScalars;
Packit 022b05
    StatusCounter   statusNotifications;
Packit 022b05
    StatusCounter   statusGroups;
Packit 022b05
    StatusCounter   statusCompliances;
Packit 022b05
    StatusCounter   statusAll;
Packit 022b05
    AccessCounter   accessColumns;
Packit 022b05
    AccessCounter   accessScalars;
Packit 022b05
    AccessCounter   accessAll;
Packit 022b05
    IndexCounter    indexTables;
Packit 022b05
    IndexLenCounter indexLenTables;
Packit 022b05
    IndexComplexityCounter indexComplexity;
Packit 022b05
    TableLenCounter tableLength;
Packit 022b05
    ScalarLenCounter scalarLength;
Packit 022b05
    LengthCounter   lengthTypes;
Packit 022b05
    LengthCounter   lengthTables;
Packit 022b05
    LengthCounter   lengthRows;
Packit 022b05
    LengthCounter   lengthColumns;
Packit 022b05
    LengthCounter   lengthScalars;
Packit 022b05
    LengthCounter   lengthNotifications;
Packit 022b05
    LengthCounter   lengthAll;
Packit 022b05
} Metrics;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct UsageCounter {
Packit 022b05
    char     *module;
Packit 022b05
    char     *name;
Packit 022b05
    unsigned count;
Packit 022b05
    struct UsageCounter *nextPtr;
Packit 022b05
} UsageCounter;
Packit 022b05
Packit 022b05
Packit 022b05
static UsageCounter *typeList = NULL;
Packit 022b05
static UsageCounter *extTypeList = NULL;
Packit 022b05
static UsageCounter *extNodeList = NULL;
Packit 022b05
static UsageCounter *extModuleList = NULL;
Packit 022b05
static UsageCounter *indexComplexityList = NULL;
Packit 022b05
Packit 022b05
#define INCR_NODE 0x01
Packit 022b05
#define INCR_TYPE 0x02
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
getDateString(time_t t)
Packit 022b05
{
Packit 022b05
    static char   *s = NULL;
Packit 022b05
    struct tm	  *tm;
Packit 022b05
Packit 022b05
    if (s) xfree(s);
Packit 022b05
    
Packit 022b05
    tm = gmtime(&t);
Packit 022b05
    smiAsprintf(&s, "%04d-%02d-%02d",
Packit 022b05
		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char*
Packit 022b05
language(SmiLanguage language)
Packit 022b05
{
Packit 022b05
    return
Packit 022b05
	(language == SMI_LANGUAGE_UNKNOWN)    ? "-" :
Packit 022b05
	(language == SMI_LANGUAGE_SMIV1)      ? "SMIv1" :
Packit 022b05
	(language == SMI_LANGUAGE_SMIV2)      ? "SMIv2" :
Packit 022b05
	(language == SMI_LANGUAGE_SMING)      ? "SMIng" :
Packit 022b05
						"-";
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
calcSize(SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    int size = 0;
Packit 022b05
    
Packit 022b05
    for (smiType = smiGetFirstType(smiModule);
Packit 022b05
	 smiType;
Packit 022b05
	 smiType = smiGetNextType(smiType)) {
Packit 022b05
	if (smiType->name) {
Packit 022b05
	    size++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
Packit 022b05
	switch (smiNode->nodekind) {
Packit 022b05
	case SMI_NODEKIND_SCALAR:
Packit 022b05
	case SMI_NODEKIND_COLUMN:
Packit 022b05
	case SMI_NODEKIND_NOTIFICATION:
Packit 022b05
	    size++;
Packit 022b05
	    break;
Packit 022b05
	default:
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return size;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
typedef void	(*ForEachIndexFunc)	(FILE *f, SmiNode *groupNode, SmiNode *smiNode, void *data);
Packit 022b05
Packit 022b05
static void
Packit 022b05
foreachIndexDo(FILE *f, SmiNode *smiNode, ForEachIndexFunc func, void *data)
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
		(func) (f, smiNode, iNode, data);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static UsageCounter*
Packit 022b05
incrUsageCounter(UsageCounter *uCntList, char *module, char *name, int incr)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
Packit 022b05
    for (uCnt = uCntList; uCnt; uCnt = uCnt->nextPtr) {
Packit 022b05
	if (strcmp(uCnt->module, module) == 0
Packit 022b05
	    && (! name || strcmp(uCnt->name, name) == 0)) {
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! uCnt) {
Packit 022b05
	uCnt = (UsageCounter *) xmalloc(sizeof(UsageCounter));
Packit 022b05
	uCnt->module = xstrdup(module);
Packit 022b05
	uCnt->name = name ? xstrdup(name) : NULL;
Packit 022b05
	uCnt->count = 0;
Packit 022b05
	uCnt->nextPtr = uCntList;
Packit 022b05
	uCntList = uCnt;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    uCnt->count += incr;
Packit 022b05
    return uCntList;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrTypeAndNodeUsageCounter(SmiModule *smiModule, SmiNode *smiNode, int flags)
Packit 022b05
{
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char *extModule;
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * First check whether the node is external. If yes, increment the
Packit 022b05
     * external node counter and we are done.
Packit 022b05
     */
Packit 022b05
Packit 022b05
    extModule = smiGetNodeModule(smiNode)->name;
Packit 022b05
    if (extModule
Packit 022b05
	&& strcmp(extModule, smiModule->name) != 0) {
Packit 022b05
	if (flags & INCR_NODE) {
Packit 022b05
	    extNodeList = incrUsageCounter(extNodeList,
Packit 022b05
					   extModule, smiNode->name, 1);
Packit 022b05
	    extModuleList = incrUsageCounter(extModuleList, extModule, NULL, 1);
Packit 022b05
	}
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    /*
Packit 022b05
     * Next, check whether the type of the node is external. If yes,
Packit 022b05
     * increment the external type counter and we are done. Do not
Packit 022b05
     * count base types (that is types that have no parent type).
Packit 022b05
     */
Packit 022b05
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (! smiType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (smiType->name && smiGetParentType(smiType)) {
Packit 022b05
	char *extModule = smiGetTypeModule(smiType)->name;
Packit 022b05
	if (extModule /* && *extModule */
Packit 022b05
	    && strcmp(extModule, smiModule->name) != 0) {
Packit 022b05
	    if (flags & INCR_TYPE) {
Packit 022b05
		extTypeList = incrUsageCounter(extTypeList,
Packit 022b05
					       extModule, smiType->name, 1);
Packit 022b05
		extModuleList = incrUsageCounter(extModuleList, extModule, NULL, 1);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * Finally, count the type name (whether external or not does not
Packit 022b05
     * matter here nor does it matter whether it is a base type or
Packit 022b05
     * not).
Packit 022b05
     */
Packit 022b05
Packit 022b05
    if (! smiType->name && smiGetParentType(smiType)) {
Packit 022b05
	smiType = smiGetParentType(smiType);
Packit 022b05
    }
Packit 022b05
    typeList = incrUsageCounter(typeList, smiGetTypeModule(smiType)->name,
Packit 022b05
				smiType->name, 1);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrIndexComplexityCounter(SmiModule *smiModule, SmiNode *smiNode, int complexity)
Packit 022b05
{
Packit 022b05
    indexComplexityList = incrUsageCounter(indexComplexityList,
Packit 022b05
					   smiModule->name, smiNode->name, complexity);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
cmp(const void *va, const void *vb)
Packit 022b05
{
Packit 022b05
    UsageCounter **a = (UsageCounter **) va;
Packit 022b05
    UsageCounter **b = (UsageCounter **) vb;
Packit 022b05
Packit 022b05
    if ((*a)->count > (*b)->count) return -1;
Packit 022b05
    if ((*a)->count < (*b)->count) return 1;
Packit 022b05
Packit 022b05
    if ((*a)->module && (*b)->module) {
Packit 022b05
	int x = strcmp((*a)->module,  (*b)->module);
Packit 022b05
	if (x) return x;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if ((*a)->name && (*b)->name) {
Packit 022b05
	int x = strcmp((*a)->name,  (*b)->name);
Packit 022b05
	if (x) return x;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int
Packit 022b05
fprintRevisions(FILE *f, int modLen, SmiRevision *smiRevision,
Packit 022b05
		SmiModule *smiModule, int size)
Packit 022b05
{
Packit 022b05
    int n = 0;
Packit 022b05
    
Packit 022b05
    if (smiRevision) {
Packit 022b05
	n = fprintRevisions(f, modLen,
Packit 022b05
			    smiGetNextRevision(smiRevision), smiModule, -1);
Packit 022b05
	fprintf(f, "%-*s %7s  ", modLen, smiModule->name,
Packit 022b05
		(size >= 0) ? language(smiModule->language) : "-");
Packit 022b05
 	if (size >= 0) {
Packit 022b05
	    fprintf(f, "%4d", size);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "   -");
Packit 022b05
	}
Packit 022b05
	fprintf(f, "   %3d    %s\n", n, getDateString(smiRevision->date));
Packit 022b05
	n++;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (!smiRevision && size >= 0) {
Packit 022b05
	fprintf(f, "%-*s %7s  ", modLen, smiModule->name,
Packit 022b05
		language(smiModule->language));
Packit 022b05
	fprintf(f, "%4d", size);
Packit 022b05
	fprintf(f, "     -    ----------\n");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return n;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintRevision(FILE *f, int modc, SmiModule **modv)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
    int modLen = 8;
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	if (modLen < strlen(modv[i]->name)) {
Packit 022b05
	    modLen = strlen(modv[i]->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "%-*s LANGUAGE SIZE REVISION DATE\n", modLen, "MODULE");
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	fprintRevisions(f, modLen, smiGetFirstRevision(modv[i]),
Packit 022b05
			modv[i], calcSize(modv[i]));
Packit 022b05
    }
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
 
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintTypeUsage(FILE *f, UsageCounter *typeUsageList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
    int modLen = 8, nameLen = 8;
Packit 022b05
    unsigned total = 0;
Packit 022b05
    int i, cnt = 0;
Packit 022b05
    UsageCounter **sortCnt;
Packit 022b05
Packit 022b05
    /* should be sorted */
Packit 022b05
Packit 022b05
    for (uCnt = typeUsageList, cnt = 0; uCnt; uCnt = uCnt->nextPtr, cnt++) {
Packit 022b05
	if (modLen < strlen(uCnt->module)) {
Packit 022b05
	    modLen = strlen(uCnt->module);
Packit 022b05
	}
Packit 022b05
	if (nameLen < strlen(uCnt->name)) {
Packit 022b05
	    nameLen = strlen(uCnt->name);
Packit 022b05
	}
Packit 022b05
	total += uCnt->count;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* create an array for a quick qsort */
Packit 022b05
Packit 022b05
    sortCnt = (UsageCounter **) xmalloc(cnt * sizeof(UsageCounter *));
Packit 022b05
    memset(sortCnt, 0, cnt * sizeof(UsageCounter *));
Packit 022b05
    for (uCnt = typeUsageList, i = 0; uCnt; uCnt = uCnt->nextPtr, i++) {
Packit 022b05
	sortCnt[i] = uCnt;
Packit 022b05
    }
Packit 022b05
    qsort(sortCnt, cnt, sizeof(UsageCounter *), cmp);
Packit 022b05
    
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the distribution of the number of references\n"
Packit 022b05
"# to defined types (including base types) in the set of loaded MIB\n"
Packit 022b05
"# modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-*s %-*s   USAGE\n", modLen, "MODULE", nameLen, "TYPE");
Packit 022b05
Packit 022b05
    for (i = 0; i < cnt; i++) {
Packit 022b05
	fprintf(f, "%-*s %-*s ",
Packit 022b05
		modLen, sortCnt[i]->module, nameLen, sortCnt[i]->name);
Packit 022b05
	if (raw) {
Packit 022b05
	    fprintf(f, "%8u\n", sortCnt[i]->count);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "%6.1f%%\n", (double) sortCnt[i]->count * 100 / total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(sortCnt);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintExtTypeUsage(FILE *f, UsageCounter *typeUsageList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
    int modLen = 8, nameLen = 8;
Packit 022b05
    unsigned total = 0;
Packit 022b05
    int i, cnt = 0;
Packit 022b05
    UsageCounter **sortCnt;
Packit 022b05
Packit 022b05
    /* should be sorted */
Packit 022b05
Packit 022b05
    for (uCnt = typeUsageList, cnt = 0; uCnt; uCnt = uCnt->nextPtr, cnt++) {
Packit 022b05
	if (modLen < strlen(uCnt->module)) {
Packit 022b05
	    modLen = strlen(uCnt->module);
Packit 022b05
	}
Packit 022b05
	if (nameLen < strlen(uCnt->name)) {
Packit 022b05
	    nameLen = strlen(uCnt->name);
Packit 022b05
	}
Packit 022b05
	total += uCnt->count;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* create an array for a quick qsort */
Packit 022b05
Packit 022b05
    sortCnt = (UsageCounter **) xmalloc(cnt * sizeof(UsageCounter *));
Packit 022b05
    memset(sortCnt, 0, cnt * sizeof(UsageCounter *));
Packit 022b05
    for (uCnt = typeUsageList, i = 0; uCnt; uCnt = uCnt->nextPtr, i++) {
Packit 022b05
	sortCnt[i] = uCnt;
Packit 022b05
    }
Packit 022b05
    qsort(sortCnt, cnt, sizeof(UsageCounter *), cmp);
Packit 022b05
    
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the distribution of the number of references\n"
Packit 022b05
"# to externally defined types (excluding base types) in the set of loaded\n"
Packit 022b05
"# MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-*s %-*s EXT-USAGE\n", modLen, "MODULE", nameLen, "TYPE");
Packit 022b05
Packit 022b05
    for (i = 0; i < cnt; i++) {
Packit 022b05
	fprintf(f, "%-*s %-*s ",
Packit 022b05
		modLen, sortCnt[i]->module, nameLen, sortCnt[i]->name);
Packit 022b05
	if (raw) {
Packit 022b05
	    fprintf(f, "%8u\n", sortCnt[i]->count);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "%6.1f%%\n", (double) sortCnt[i]->count * 100 / total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(sortCnt);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintExtNodeUsage(FILE *f, UsageCounter *typeUsageList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
    int modLen = 8, nameLen = 8;
Packit 022b05
    unsigned total = 0;
Packit 022b05
    int i, cnt = 0;
Packit 022b05
    UsageCounter **sortCnt;
Packit 022b05
Packit 022b05
    /* should be sorted */
Packit 022b05
Packit 022b05
    for (uCnt = typeUsageList, cnt = 0; uCnt; uCnt = uCnt->nextPtr, cnt++) {
Packit 022b05
	if (modLen < strlen(uCnt->module)) {
Packit 022b05
	    modLen = strlen(uCnt->module);
Packit 022b05
	}
Packit 022b05
	if (nameLen < strlen(uCnt->name)) {
Packit 022b05
	    nameLen = strlen(uCnt->name);
Packit 022b05
	}
Packit 022b05
	total += uCnt->count;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* create an array for a quick qsort */
Packit 022b05
Packit 022b05
    sortCnt = (UsageCounter **) xmalloc(cnt * sizeof(UsageCounter *));
Packit 022b05
    memset(sortCnt, 0, cnt * sizeof(UsageCounter *));
Packit 022b05
    for (uCnt = typeUsageList, i = 0; uCnt; uCnt = uCnt->nextPtr, i++) {
Packit 022b05
	sortCnt[i] = uCnt;
Packit 022b05
    }
Packit 022b05
    qsort(sortCnt, cnt, sizeof(UsageCounter *), cmp);
Packit 022b05
    
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the distribution of the number of references\n"
Packit 022b05
"# to externally defined nodes in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-*s %-*s EXT-USAGE\n", modLen, "MODULE", nameLen, "NODE");
Packit 022b05
Packit 022b05
    for (i = 0; i < cnt; i++) {
Packit 022b05
	fprintf(f, "%-*s %-*s ",
Packit 022b05
		modLen, sortCnt[i]->module, nameLen, sortCnt[i]->name);
Packit 022b05
	if (raw) {
Packit 022b05
	    fprintf(f, "%8u\n", sortCnt[i]->count);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "%6.1f%%\n", (double) sortCnt[i]->count * 100 / total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(sortCnt);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintModuleUsage(FILE *f, UsageCounter *modUsageList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
    int modLen = 8;
Packit 022b05
    unsigned total = 0;
Packit 022b05
    int i, cnt = 0;
Packit 022b05
    UsageCounter **sortCnt;
Packit 022b05
Packit 022b05
    /* should be sorted */
Packit 022b05
Packit 022b05
    for (uCnt = modUsageList, cnt = 0; uCnt; uCnt = uCnt->nextPtr, cnt++) {
Packit 022b05
	if (modLen < strlen(uCnt->module)) {
Packit 022b05
	    modLen = strlen(uCnt->module);
Packit 022b05
	}
Packit 022b05
	total += uCnt->count;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* create an array for a quick qsort */
Packit 022b05
Packit 022b05
    sortCnt = (UsageCounter **) xmalloc(cnt * sizeof(UsageCounter *));
Packit 022b05
    memset(sortCnt, 0, cnt * sizeof(UsageCounter *));
Packit 022b05
    for (uCnt = modUsageList, i = 0; uCnt; uCnt = uCnt->nextPtr, i++) {
Packit 022b05
	sortCnt[i] = uCnt;
Packit 022b05
    }
Packit 022b05
    qsort(sortCnt, cnt, sizeof(UsageCounter *), cmp);
Packit 022b05
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the distribution of the number of references\n"
Packit 022b05
"# to externally defined items (such as types or objects) accumulated by\n"
Packit 022b05
"# the defining MIB module in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-*s EXT-USAGE\n", modLen, "MODULE");
Packit 022b05
Packit 022b05
    for (i = 0; i < cnt; i++) {
Packit 022b05
	fprintf(f, "%-*s ", modLen, sortCnt[i]->module);
Packit 022b05
	if (raw) {
Packit 022b05
	    fprintf(f, "%8u\n", sortCnt[i]->count);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "%6.1f%%\n", (double) sortCnt[i]->count * 100 / total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(sortCnt);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintIndexComplexity(FILE *f, UsageCounter *modUsageList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt;
Packit 022b05
    int modLen = 8;
Packit 022b05
    int nameLen = 8;
Packit 022b05
    unsigned total = 0;
Packit 022b05
    int i, cnt = 0;
Packit 022b05
    UsageCounter **sortCnt;
Packit 022b05
Packit 022b05
    /* should be sorted */
Packit 022b05
Packit 022b05
    for (uCnt = modUsageList, cnt = 0; uCnt; uCnt = uCnt->nextPtr, cnt++) {
Packit 022b05
	if (modLen < strlen(uCnt->module)) {
Packit 022b05
	    modLen = strlen(uCnt->module);
Packit 022b05
	}
Packit 022b05
	if (nameLen < strlen(uCnt->name)) {
Packit 022b05
	    nameLen = strlen(uCnt->name);
Packit 022b05
	}
Packit 022b05
	total += uCnt->count;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt == 0) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* create an array for a quick qsort */
Packit 022b05
Packit 022b05
    sortCnt = (UsageCounter **) xmalloc(cnt * sizeof(UsageCounter *));
Packit 022b05
    memset(sortCnt, 0, cnt * sizeof(UsageCounter *));
Packit 022b05
    for (uCnt = modUsageList, i = 0; uCnt; uCnt = uCnt->nextPtr, i++) {
Packit 022b05
	sortCnt[i] = uCnt;
Packit 022b05
    }
Packit 022b05
    qsort(sortCnt, cnt, sizeof(UsageCounter *), cmp);
Packit 022b05
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the distribution of the index complexity\n"
Packit 022b05
"# in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-*s %-*s COMPLEXITY\n", modLen, "MODULE", nameLen, "TABLE");
Packit 022b05
Packit 022b05
    for (i = 0; i < cnt; i++) {
Packit 022b05
	fprintf(f, "%-*s %-*s ", modLen, sortCnt[i]->module, nameLen, sortCnt[i]->name);
Packit 022b05
	if (raw) {
Packit 022b05
	    fprintf(f, "%8u\n", sortCnt[i]->count);
Packit 022b05
	} else {
Packit 022b05
	    fprintf(f, "%6.1f%%\n", (double) sortCnt[i]->count);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(sortCnt);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
freeUsageCounter(UsageCounter *usageCounterList)
Packit 022b05
{
Packit 022b05
    UsageCounter *uCnt, *p;
Packit 022b05
    
Packit 022b05
    for (uCnt = usageCounterList; uCnt; ) {
Packit 022b05
	p = uCnt, uCnt = uCnt->nextPtr;
Packit 022b05
	xfree(p->module);
Packit 022b05
	xfree(p->name);
Packit 022b05
	xfree(p);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrBasetypeCounter(BasetypeCounter *basetypeCounter, SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    SmiType *smiType;
Packit 022b05
Packit 022b05
    smiType = smiGetNodeType(smiNode);
Packit 022b05
    if (smiType) {
Packit 022b05
	basetypeCounter->total++;
Packit 022b05
	switch (smiType->basetype) {
Packit 022b05
	case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	    basetypeCounter->unknown++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_INTEGER32:
Packit 022b05
	    basetypeCounter->integer32++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    basetypeCounter->octetstring++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	    basetypeCounter->objectidentifier++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	    basetypeCounter->unsigned32++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_INTEGER64:
Packit 022b05
	    basetypeCounter->integer64++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	    basetypeCounter->unsigned64++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_FLOAT32:
Packit 022b05
	    basetypeCounter->float32++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_FLOAT64:
Packit 022b05
	    basetypeCounter->float64++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_FLOAT128:
Packit 022b05
	    basetypeCounter->float128++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_ENUM:
Packit 022b05
	    basetypeCounter->enums++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_BITS:
Packit 022b05
	    basetypeCounter->bits++;
Packit 022b05
	    break;
Packit 022b05
	case SMI_BASETYPE_POINTER:
Packit 022b05
	    basetypeCounter->pointer++;
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrStatusCounter(StatusCounter *cnt, SmiStatus smiStatus)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    switch (smiStatus) {
Packit 022b05
    case SMI_STATUS_CURRENT:
Packit 022b05
    case SMI_STATUS_MANDATORY:
Packit 022b05
    case SMI_STATUS_OPTIONAL:
Packit 022b05
	cnt->current++;
Packit 022b05
	break;
Packit 022b05
    case SMI_STATUS_DEPRECATED:
Packit 022b05
	cnt->deprecated++;
Packit 022b05
	break;
Packit 022b05
    case SMI_STATUS_OBSOLETE:
Packit 022b05
	cnt->obsolete++;
Packit 022b05
	break;
Packit 022b05
    case SMI_STATUS_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrAccessCounter(AccessCounter *cnt, SmiAccess smiAccess)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    switch (smiAccess) {
Packit 022b05
    case SMI_ACCESS_NOT_ACCESSIBLE:
Packit 022b05
	cnt->noaccess++;
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_NOTIFY:
Packit 022b05
	cnt->notify++;
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_READ_ONLY:
Packit 022b05
	cnt->readonly++;
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_READ_WRITE:
Packit 022b05
	cnt->readwrite++;
Packit 022b05
	break;
Packit 022b05
    case SMI_ACCESS_INSTALL:
Packit 022b05
    case SMI_ACCESS_INSTALL_NOTIFY:
Packit 022b05
    case SMI_ACCESS_REPORT_ONLY:
Packit 022b05
    case SMI_ACCESS_UNKNOWN:
Packit 022b05
    case SMI_ACCESS_NOT_IMPLEMENTED:
Packit 022b05
    case SMI_ACCESS_EVENT_ONLY:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrIndexCounter(IndexCounter *cnt, SmiIndexkind indexkind)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    switch (indexkind) {
Packit 022b05
    case SMI_INDEX_INDEX:
Packit 022b05
	cnt->index++;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_AUGMENT:
Packit 022b05
	cnt->augment++;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_REORDER:
Packit 022b05
	cnt->reorder++;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_SPARSE:
Packit 022b05
	cnt->sparse++;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_EXPAND:
Packit 022b05
	cnt->expand++;
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrIndexLenCounter(IndexLenCounter *cnt, int len)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    if (len < sizeof(cnt->length)/sizeof(cnt->length[0])) {
Packit 022b05
	cnt->length[len]++;
Packit 022b05
    } else {
Packit 022b05
	fprintf(stderr, "smidump: index len overflow: %d\n", len);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrTableLenCounter(TableLenCounter *cnt, int len)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    if (len < sizeof(cnt->length)/sizeof(cnt->length[0])) {
Packit 022b05
	cnt->length[len]++;
Packit 022b05
    } else {
Packit 022b05
	fprintf(stderr, "smidump: table len overflow: %d\n", len);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrIndexComplexityMetric(IndexComplexityCounter *cnt, int cmplx)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    if (cmplx < sizeof(cnt->complexity)/sizeof(cnt->complexity[0])) {
Packit 022b05
	cnt->complexity[cmplx]++;
Packit 022b05
    } else {
Packit 022b05
	fprintf(stderr, "smidump: index complexity overflow: %d\n", cmplx);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrLengthCounter(LengthCounter *cnt, char *description, char *reference,
Packit 022b05
		  char *units, char *format)
Packit 022b05
{
Packit 022b05
    cnt->total++;
Packit 022b05
    if (description) {
Packit 022b05
	cnt->descr++;
Packit 022b05
	cnt->descr_len += strlen(description);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (reference) {
Packit 022b05
	cnt->reference++;
Packit 022b05
	cnt->reference_len += strlen(reference);
Packit 022b05
    }
Packit 022b05
    if (units) {
Packit 022b05
	cnt->units++;
Packit 022b05
	cnt->units_len += strlen(units);
Packit 022b05
    }
Packit 022b05
    if (format) {
Packit 022b05
	cnt->format++;
Packit 022b05
	cnt->format_len += strlen(format);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
incrRowStatusCounter(SmiNode *rowNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(rowNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
	if (smiType && smiType->name) {
Packit 022b05
	    smiModule = smiGetTypeModule(smiType);
Packit 022b05
	    if (smiModule && smiModule->name
Packit 022b05
		&& strcmp(smiType->name, "RowStatus") == 0
Packit 022b05
		&& strcmp(smiModule->name, "SNMPv2-TC") == 0) {
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (smiNode) {
Packit 022b05
#if 0
Packit 022b05
	fprintf(stderr, "** %s\t%s\t%s\n", rowNode->name,
Packit 022b05
		smiNode->name, smiType->name);
Packit 022b05
	/* xxx count rows indexed by ifIndex, InterfaceIndex, InterfaceIndexOrZero, ... */
Packit 022b05
#endif
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
count(FILE *f, SmiNode *row, SmiNode *col, void *data)
Packit 022b05
{
Packit 022b05
    int *cnt = (int *) data;
Packit 022b05
Packit 022b05
    (*cnt)++;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
complexity(FILE *f, SmiNode *row, SmiNode *col, void *data)
Packit 022b05
{
Packit 022b05
    int *cmplx = (int *) data;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    unsigned long min, max;
Packit 022b05
Packit 022b05
    smiType = smiGetNodeType(col);
Packit 022b05
    if (! smiType) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    switch (smiType->basetype) {
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
	*cmplx += 1;
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	*cmplx += 2;
Packit 022b05
	min = smiGetMinSize(smiType);
Packit 022b05
	max = smiGetMaxSize(smiType);
Packit 022b05
	if (min != max) {
Packit 022b05
	    *cmplx += 1;
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    default:				/* ignore everything else */
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
yadayada(FILE *f, SmiNode *row, SmiNode *col, void *data)
Packit 022b05
{
Packit 022b05
    SmiModule *smiModule = (SmiModule *) data;
Packit 022b05
    int flags = 0;
Packit 022b05
Packit 022b05
    if (col->access == SMI_ACCESS_NOT_ACCESSIBLE) {
Packit 022b05
	flags |= INCR_TYPE;
Packit 022b05
    }
Packit 022b05
    flags |= INCR_NODE;
Packit 022b05
Packit 022b05
    incrTypeAndNodeUsageCounter(smiModule, col, flags);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
addMetrics(Metrics *metrics, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    size_t len;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	len = smiNode->description ? strlen(smiNode->description) : 0;
Packit 022b05
	switch (smiNode->nodekind) {
Packit 022b05
	case SMI_NODEKIND_TABLE:
Packit 022b05
	    incrStatusCounter(&metrics->statusTables, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    incrLengthCounter(&metrics->lengthTables,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_ROW:
Packit 022b05
	    incrIndexCounter(&metrics->indexTables, smiNode->indexkind);
Packit 022b05
	    incrLengthCounter(&metrics->lengthRows,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrRowStatusCounter(smiNode);
Packit 022b05
	    {
Packit 022b05
		int cnt = 0;
Packit 022b05
		foreachIndexDo(NULL, smiNode, count, &cnt);
Packit 022b05
		incrIndexLenCounter(&metrics->indexLenTables, cnt);
Packit 022b05
		foreachIndexDo(NULL, smiNode, yadayada, smiModule);
Packit 022b05
	    }
Packit 022b05
	    {
Packit 022b05
		int cmplx = 0;
Packit 022b05
		foreachIndexDo(NULL, smiNode, complexity, &cmplx);
Packit 022b05
		incrIndexComplexityCounter(smiModule, smiNode, cmplx);
Packit 022b05
		incrIndexComplexityMetric(&metrics->indexComplexity, cmplx);
Packit 022b05
	    }
Packit 022b05
	    /* count the childs ... */
Packit 022b05
	    {
Packit 022b05
		    SmiModule *smiModule = smiGetModule("SNMPv2-TC");
Packit 022b05
		    SmiNode *childNode;
Packit 022b05
		    SmiType *rowStatus = smiGetType(smiModule, "RowStatus");
Packit 022b05
		    SmiType *storageType = smiGetType(smiModule, "StorageType");
Packit 022b05
		    /* include index elements not in table */
Packit 022b05
		    int n = 0;
Packit 022b05
		    for (childNode = smiGetFirstChildNode(smiNode);
Packit 022b05
			 childNode;
Packit 022b05
			 childNode = smiGetNextChildNode(childNode)) {
Packit 022b05
			    n++;
Packit 022b05
			    if (rowStatus == smiGetNodeType(childNode)) {
Packit 022b05
				    fprintf(stderr, "**** GEEEEEE - ROWSTATUS\n");
Packit 022b05
			    }
Packit 022b05
			    if (storageType == smiGetNodeType(childNode)) {
Packit 022b05
				    fprintf(stderr, "**** GEEEEEE - STORAGETYPE\n");
Packit 022b05
			    }
Packit 022b05
		    }
Packit 022b05
		    incrTableLenCounter(&metrics->tableLength, n);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_COLUMN:
Packit 022b05
	    incrBasetypeCounter(&metrics->basetypesColumns, smiNode);
Packit 022b05
	    incrBasetypeCounter(&metrics->basetypesAll, smiNode);
Packit 022b05
	    incrStatusCounter(&metrics->statusColumns, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    incrAccessCounter(&metrics->accessColumns, smiNode->access);
Packit 022b05
	    incrAccessCounter(&metrics->accessAll, smiNode->access);
Packit 022b05
	    incrLengthCounter(&metrics->lengthColumns,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrTypeAndNodeUsageCounter(smiModule, smiNode, INCR_TYPE);
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_SCALAR:
Packit 022b05
	    incrBasetypeCounter(&metrics->basetypesScalars, smiNode);
Packit 022b05
	    incrBasetypeCounter(&metrics->basetypesAll, smiNode);
Packit 022b05
	    incrStatusCounter(&metrics->statusScalars, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    incrAccessCounter(&metrics->accessScalars, smiNode->access);
Packit 022b05
	    incrAccessCounter(&metrics->accessAll, smiNode->access);
Packit 022b05
	    incrLengthCounter(&metrics->lengthScalars,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrTypeAndNodeUsageCounter(smiModule, smiNode, INCR_TYPE);
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_NOTIFICATION:
Packit 022b05
	    incrStatusCounter(&metrics->statusNotifications, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    incrLengthCounter(&metrics->lengthNotifications,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			      smiNode->description, smiNode->reference,
Packit 022b05
			      smiNode->units, smiNode->format);
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_GROUP:
Packit 022b05
	    incrStatusCounter(&metrics->statusGroups, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    break;
Packit 022b05
	case SMI_NODEKIND_COMPLIANCE:
Packit 022b05
	    incrStatusCounter(&metrics->statusCompliances, smiNode->status);
Packit 022b05
	    incrStatusCounter(&metrics->statusAll, smiNode->status);
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (smiType = smiGetFirstType(smiModule);
Packit 022b05
	 smiType;
Packit 022b05
	 smiType = smiGetNextType(smiType)) {
Packit 022b05
Packit 022b05
	/*
Packit 022b05
	 * Ignore all types with empty descriptions coming from the
Packit 022b05
	 * "SNMPv2-SMI" module since they are not really defined
Packit 022b05
	 * types but part of the language itself.
Packit 022b05
	 */
Packit 022b05
Packit 022b05
	if (! smiType->description) {
Packit 022b05
	    SmiModule *m = smiGetTypeModule(smiType);
Packit 022b05
	    if (m && strcmp(m->name, "SNMPv2-SMI") == 0) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    
Packit 022b05
	incrStatusCounter(&metrics->statusTypes, smiType->status);
Packit 022b05
	incrStatusCounter(&metrics->statusAll, smiType->status);
Packit 022b05
	incrLengthCounter(&metrics->lengthTypes,
Packit 022b05
			  smiType->description, smiType->reference,
Packit 022b05
			  smiType->units, smiType->format);
Packit 022b05
	incrLengthCounter(&metrics->lengthAll,
Packit 022b05
			  smiType->description, smiType->reference,
Packit 022b05
			  smiType->units, smiType->format);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintBasetypeCounter(FILE *f, BasetypeCounter *cnt, const char *s)
Packit 022b05
{
Packit 022b05
    if (!s && ! cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the basetype usage distribution in the\n"
Packit 022b05
"# set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-10s Int32 Uns32 Int64 Uns64 OctSt ObjId Enums  Bits Flo32 Flo64 Flo128\n",
Packit 022b05
		"CATEGORY");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-10s %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n", s,
Packit 022b05
		cnt->integer32, cnt->unsigned32,
Packit 022b05
		cnt->integer64, cnt->unsigned64,
Packit 022b05
		cnt->octetstring, cnt->objectidentifier,
Packit 022b05
		cnt->enums, cnt->bits,
Packit 022b05
		cnt->float32, cnt->float64, cnt->float128);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-10s %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%%\n", s,
Packit 022b05
		cnt->total ? (double) cnt->integer32 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->unsigned32 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->integer64 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->unsigned64 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->octetstring * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->objectidentifier * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->enums * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->bits * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->float32 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->float64 * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->float128 * 100 / cnt->total : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintStatusCounter(FILE *f, StatusCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    if (!s || !cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the status distribution of various\n"
Packit 022b05
"# definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-14s %8s %8s %11s %9s\n", "CATEGORY",
Packit 022b05
		"TOTAL", "CURRENT", "DEPRECATED", "OBSOLETE");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-14s %8lu %8lu %11lu %9lu\n", s,
Packit 022b05
		cnt->total, cnt->current, cnt->deprecated, cnt->obsolete);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-14s %8lu %7.1f%% %10.1f%% %8.1f%%\n", s,
Packit 022b05
		cnt->total,
Packit 022b05
		cnt->total ? (double) cnt->current * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->deprecated * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->obsolete * 100 / cnt->total : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintAccessCounter(FILE *f, AccessCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    if (!s || !cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the access mode distribution of all scalar\n"
Packit 022b05
"# or column definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-14s %8s %10s %9s %7s %8s\n", "CATEGORY",
Packit 022b05
		"TOTAL", "READWRITE", "READONLY", "NOTIFY", "NOACCES");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-14s %8lu %10lu %9lu %7lu %8lu\n", s,
Packit 022b05
		cnt->total, cnt->readwrite, cnt->readonly,
Packit 022b05
		cnt->notify, cnt->noaccess);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-14s %8lu %9.1f%% %8.1f%% %6.1f%% %7.1f%%\n", s,
Packit 022b05
		cnt->total,
Packit 022b05
		cnt->total ? (double) cnt->readwrite * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->readonly * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->notify * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->noaccess * 100 / cnt->total : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintIndexCounter(FILE *f, IndexCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    if (! s || ! cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the table index kind distribution of\n"
Packit 022b05
"# table definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	fprintf(f, "%-14s %8s %8s %8s %8s %8s %8s\n", "CATEGORY",
Packit 022b05
		"TOTAL", "INDEX", "AUGMENT", "REORDER", "SPARSE", "EXPAND");
Packit 022b05
	}
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-14s %8lu %8lu %8lu %8lu %8lu %8lu\n", s,
Packit 022b05
		cnt->total, cnt->index, cnt->augment,
Packit 022b05
		cnt->reorder, cnt->sparse, cnt->expand);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-14s %8lu %7.1f%% %7.1f%% %7.1f%% %7.1f%% %7.1f%%\n", s,
Packit 022b05
		cnt->total,
Packit 022b05
		cnt->total ? (double) cnt->index * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->augment * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->reorder * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->sparse * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->expand * 100 / cnt->total : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintIndexLenCounter(FILE *f, IndexLenCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
    int n = sizeof(cnt->length)/sizeof(cnt->length[0]);
Packit 022b05
    char buf[42];
Packit 022b05
    
Packit 022b05
    if (! s || ! cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the table index length distribution of\n"
Packit 022b05
"# table definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-10s %6s ", "CATEGORY", "TOTAL");
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    sprintf(buf, "[%d]", i);
Packit 022b05
	    fprintf(f, " %5s", buf);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "%-10s %6lu ", s, cnt->total);
Packit 022b05
    if (raw) {
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    fprintf(f, " %5lu", cnt->length[i]);
Packit 022b05
	}
Packit 022b05
    } else {
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    fprintf(f, " %4.1f%%", (double) cnt->length[i] * 100 / cnt->total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintTableLenCounter(FILE *f, TableLenCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
    int n = sizeof(cnt->length)/sizeof(cnt->length[0]);
Packit 022b05
    char buf[42];
Packit 022b05
    
Packit 022b05
    if (! s || ! cnt) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the table length distribution of\n"
Packit 022b05
"# table definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-10s %6s ", "CATEGORY", "TOTAL");
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    sprintf(buf, "[%d]", i);
Packit 022b05
	    fprintf(f, " %5s", buf);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "%-10s %6lu ", s, cnt->total);
Packit 022b05
    if (raw) {
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    fprintf(f, " %5lu", cnt->length[i]);
Packit 022b05
	}
Packit 022b05
    } else {
Packit 022b05
	for (i = 1; i < n; i++) {
Packit 022b05
	    fprintf(f, " %4.1f%%", (double) cnt->length[i] * 100 / cnt->total);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintLengthCounter(FILE *f, LengthCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    if (! s) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fputs(
Packit 022b05
"# The following table shows the text clause usage distribution of all\n"
Packit 022b05
"# definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-14s %8s %12s %10s %8s %8s\n", "CATEGORY",
Packit 022b05
		"TOTAL", "DESCRIPTION", "REFERENCE", "UNIT", "FORMAT");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-14s %8lu %12lu %10lu %8lu %8lu\n", s,
Packit 022b05
		cnt->total, cnt->descr, cnt->reference,
Packit 022b05
		cnt->units, cnt->format);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-14s %8lu %11.1f%% %9.1f%% %7.1f%% %7.1f%%\n", s,
Packit 022b05
		cnt->total,
Packit 022b05
		cnt->total ? (double) cnt->descr * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->reference * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->units * 100 / cnt->total : 0,
Packit 022b05
		cnt->total ? (double) cnt->format * 100 / cnt->total : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintLengthCounter2(FILE *f, LengthCounter *cnt, char *s)
Packit 022b05
{
Packit 022b05
    if (! s) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    fprintf(f,
Packit 022b05
"# The following table shows the %s text length distribution (in\n"
Packit 022b05
"# bytes) of all definitions contained in the set of loaded MIB modules.\n"
Packit 022b05
"\n", raw ? "total" : "average");
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-14s %8s %12s %10s %8s %8s\n", "CATEGORY",
Packit 022b05
		"TOTAL", "DESCRIPTION", "REFERENCE", "UNIT", "FORMAT");
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (raw) {
Packit 022b05
	fprintf(f, "%-14s %8lu %12lu %10lu %8lu %8lu\n", s,
Packit 022b05
		cnt->total, cnt->descr_len, cnt->reference_len,
Packit 022b05
		cnt->units_len, cnt->format_len);
Packit 022b05
    } else {
Packit 022b05
	fprintf(f, "%-14s %8lu %12.1f %10.1f %8.1f %8.1f\n", s,
Packit 022b05
		cnt->total,
Packit 022b05
		cnt->descr ? (double) cnt->descr_len / cnt->descr : 0,
Packit 022b05
		cnt->reference ? (double) cnt->reference_len / cnt->reference : 0,
Packit 022b05
		cnt->units ? (double) cnt->units_len / cnt->units : 0,
Packit 022b05
		cnt->format ? (double) cnt->format_len / cnt->format : 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintfComplexity(FILE *f, Metrics *metrics)
Packit 022b05
{
Packit 022b05
    unsigned long cmplx = 0, fctrs = 0;
Packit 022b05
    unsigned long total_cmplx = 0, total_fctrs = 0;
Packit 022b05
Packit 022b05
    if (! silent) {
Packit 022b05
	fputs(
Packit 022b05
"# The following table shows the complexity metrics of the set of loaded\n"
Packit 022b05
"# MIB modules.\n"
Packit 022b05
"\n", f);
Packit 022b05
    }
Packit 022b05
    fprintf(f, "%-14s %8s %8s %8s %8s\n", "CATEGORY", "TOTAL",
Packit 022b05
	    "RAW", "WEIGHT", "COMPLEXITY");
Packit 022b05
    
Packit 022b05
    cmplx = metrics->accessScalars.readonly  * 1;
Packit 022b05
    fctrs = metrics->accessScalars.readonly;
Packit 022b05
    fprintf(f, "%-14s %8lu %8lu\n", "Scalars (ro):", fctrs, cmplx);
Packit 022b05
    total_cmplx += cmplx;
Packit 022b05
    total_fctrs += fctrs;
Packit 022b05
	    
Packit 022b05
    cmplx = metrics->accessScalars.readwrite * 2;
Packit 022b05
    fctrs = metrics->accessScalars.readwrite;
Packit 022b05
    fprintf(f, "%-14s %8lu %8lu\n", "Scalars (rw):", fctrs, cmplx);
Packit 022b05
    total_cmplx += cmplx;
Packit 022b05
    total_fctrs += fctrs;
Packit 022b05
Packit 022b05
    cmplx = metrics->accessColumns.readonly * 2;
Packit 022b05
    fctrs = metrics->accessColumns.readonly;
Packit 022b05
    fprintf(f, "%-14s %8lu %8lu\n", "Columns (ro):", fctrs, cmplx);
Packit 022b05
    total_cmplx += cmplx;
Packit 022b05
    total_fctrs += fctrs;
Packit 022b05
Packit 022b05
    cmplx = metrics->accessColumns.readwrite * 3;
Packit 022b05
    fctrs = metrics->accessColumns.readwrite;
Packit 022b05
    fprintf(f, "%-14s %8lu %8lu\n", "Columns (rw):", fctrs, cmplx);
Packit 022b05
    total_cmplx += cmplx;
Packit 022b05
    total_fctrs += fctrs;
Packit 022b05
Packit 022b05
    /* readcreate tables ? */
Packit 022b05
Packit 022b05
    /* table index complexity ? */
Packit 022b05
Packit 022b05
    {
Packit 022b05
	int i;
Packit 022b05
	cmplx = 0;
Packit 022b05
	for (i = 0; i < 100; i++) {
Packit 022b05
	    cmplx += 3 * i * metrics->indexComplexity.complexity[i];
Packit 022b05
	}
Packit 022b05
	fprintf(f, "%-14s %8lu %8lu\n", "Indexes:", metrics->indexComplexity.total, cmplx);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "%-14s %8lu %8lu\n", "Summary:", total_fctrs, total_cmplx);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
fprintMetrics(FILE *f, Metrics *metrics)
Packit 022b05
{
Packit 022b05
    fprintStatusCounter(f, NULL, NULL);
Packit 022b05
    fprintStatusCounter(f, &metrics->statusTypes, "Types:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusTables, "Tables:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusColumns, "Columns:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusScalars, "Scalars:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusNotifications, "Notifications:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusGroups, "Groups:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusCompliances, "Compliances:");
Packit 022b05
    fprintStatusCounter(f, &metrics->statusAll, "Summary:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintAccessCounter(f, NULL, NULL);
Packit 022b05
    fprintAccessCounter(f, &metrics->accessColumns, "Columns:");
Packit 022b05
    fprintAccessCounter(f, &metrics->accessScalars, "Scalars:");
Packit 022b05
    fprintAccessCounter(f, &metrics->accessAll, "Summary:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintIndexCounter(f, NULL, NULL);
Packit 022b05
    fprintIndexCounter(f, &metrics->indexTables, "Tables:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintIndexLenCounter(f, NULL, NULL);
Packit 022b05
    fprintIndexLenCounter(f, &metrics->indexLenTables, "Tables:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintTableLenCounter(f, NULL, NULL);
Packit 022b05
    fprintTableLenCounter(f, &metrics->tableLength, "Tables:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintLengthCounter(f, NULL, NULL);
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthTypes, "Types:");
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthTables, "Tables:");
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthColumns, "Columns:");
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthScalars, "Scalars:");
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthNotifications, "Notifications:");
Packit 022b05
    fprintLengthCounter(f, &metrics->lengthAll, "Summary:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintLengthCounter2(f, NULL, NULL);
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthTypes, "Types:");
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthTables, "Tables:");
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthColumns, "Columns:");
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthScalars, "Scalars:");
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthNotifications, "Notifications:");
Packit 022b05
    fprintLengthCounter2(f, &metrics->lengthAll, "Summary:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintBasetypeCounter(f, NULL, NULL);
Packit 022b05
    fprintBasetypeCounter(f, &metrics->basetypesColumns, "Columns:");
Packit 022b05
    fprintBasetypeCounter(f, &metrics->basetypesScalars, "Scalars:");
Packit 022b05
    fprintBasetypeCounter(f, &metrics->basetypesAll, "Summary:");
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintfComplexity(f, metrics);
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintTypeUsage(f, typeList);
Packit 022b05
    freeUsageCounter(typeList), typeList = NULL;
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintExtTypeUsage(f, extTypeList);
Packit 022b05
    freeUsageCounter(extTypeList), extTypeList = NULL;
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintExtNodeUsage(f, extNodeList);
Packit 022b05
    freeUsageCounter(extNodeList), extNodeList = NULL;
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintModuleUsage(f, extModuleList);
Packit 022b05
    freeUsageCounter(extModuleList), extModuleList = NULL;
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
    fprintIndexComplexity(f, indexComplexityList);
Packit 022b05
    freeUsageCounter(indexComplexityList), indexComplexityList = NULL;
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void
Packit 022b05
dumpMetrics(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    Metrics   metrics;
Packit 022b05
    int       i;
Packit 022b05
    FILE      *f = stdout;
Packit 022b05
Packit 022b05
    silent = (flags & SMIDUMP_FLAG_SILENT);
Packit 022b05
Packit 022b05
    if (output) {
Packit 022b05
	f = fopen(output, "w");
Packit 022b05
	if (!f) {
Packit 022b05
	    fprintf(stderr, "smidump: cannot open %s for writing: ", output);
Packit 022b05
	    perror(NULL);
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	if (! silent) {
Packit 022b05
	    int pos = 8888;
Packit 022b05
	    fprintf(f, "# united module metrics [%d modules] "
Packit 022b05
		    "(generated by smidump " SMI_VERSION_STRING ")\n", modc);
Packit 022b05
	    fprintf(f, "#\n# smidump -u -f metrics");
Packit 022b05
	    if (raw) fprintf(f, " --metrics-raw");
Packit 022b05
	    for (i = 0; i < modc; i++) {
Packit 022b05
		int len = strlen(modv[i]->name);
Packit 022b05
		if (pos + len > 70) {
Packit 022b05
		    fprintf(f, " \\\n#\t"), pos = 8;
Packit 022b05
		}
Packit 022b05
		fprintf(f, "%s ", modv[i]->name);
Packit 022b05
		pos += len + 1;
Packit 022b05
	    }
Packit 022b05
	    fprintf(f, "%s\n", (pos == 8) ? "" : "\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprintRevision(f, modc, modv);
Packit 022b05
	    
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    memset(&metrics, 0, sizeof(Metrics));
Packit 022b05
	}
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    addMetrics(&metrics, modv[i]);
Packit 022b05
	}
Packit 022b05
	fprintMetrics(f, &metrics);
Packit 022b05
    } else {
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    if (! silent) {
Packit 022b05
		fprintf(f, "# %s module metrics (generated by smidump "
Packit 022b05
			SMI_VERSION_STRING ")\n\n", modv[i]->name);
Packit 022b05
	    }
Packit 022b05
Packit 022b05
	    fprintRevision(f, 1, modv+i);
Packit 022b05
    
Packit 022b05
	    memset(&metrics, 0, sizeof(Metrics));
Packit 022b05
	    addMetrics(&metrics, modv[i]);
Packit 022b05
	    fprintMetrics(f, &metrics);
Packit 022b05
	}
Packit 022b05
    }
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
    if (output) {
Packit 022b05
	fclose(f);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
void
Packit 022b05
initMetrics()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "raw", OPT_FLAG, &raw, 0,
Packit 022b05
	  "generate raw statistics (no percentages)"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"metrics",
Packit 022b05
	dumpMetrics,
Packit 022b05
	0,
Packit 022b05
	0,
Packit 022b05
	"metrics characterizing MIB modules",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}