Blame tools/dump-types.c

Packit 022b05
/*
Packit 022b05
 * dump-types.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to dump the type hierarchy in a human readable format.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
Packit 022b05
 * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
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-types.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Decide how we want to name the implicitely defined types.
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <string.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
Packit 022b05
static int noimplicit = 0;
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct BaseTypeCount {
Packit 022b05
    SmiBasetype basetype;
Packit 022b05
    int         counter;
Packit 022b05
} BaseTypeCount;
Packit 022b05
Packit 022b05
Packit 022b05
static BaseTypeCount basetypes[] = {
Packit 022b05
    { SMI_BASETYPE_INTEGER32, 0 },
Packit 022b05
    { SMI_BASETYPE_OCTETSTRING, 0 },
Packit 022b05
    { SMI_BASETYPE_OBJECTIDENTIFIER, 0 },
Packit 022b05
    { SMI_BASETYPE_UNSIGNED32, 0 },
Packit 022b05
    { SMI_BASETYPE_INTEGER64, 0 },
Packit 022b05
    { SMI_BASETYPE_UNSIGNED64, 0 },
Packit 022b05
    { SMI_BASETYPE_FLOAT32, 0 },
Packit 022b05
    { SMI_BASETYPE_FLOAT64, 0 },
Packit 022b05
    { SMI_BASETYPE_FLOAT128, 0 },
Packit 022b05
    { SMI_BASETYPE_ENUM, 0 },
Packit 022b05
    { SMI_BASETYPE_BITS, 0 },
Packit 022b05
    { SMI_BASETYPE_UNKNOWN, 0 }
Packit 022b05
};
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct TypeNode {
Packit 022b05
    SmiType	*smiType;
Packit 022b05
    SmiModule	*smiModule;
Packit 022b05
    SmiBasetype smiBasetype;
Packit 022b05
    struct TypeNode *nextNodePtr;
Packit 022b05
    struct TypeNode *childNodePtr;
Packit 022b05
} TypeNode;
Packit 022b05
Packit 022b05
Packit 022b05
static TypeNode typeRoot = {
Packit 022b05
    NULL, NULL, SMI_BASETYPE_UNKNOWN, NULL, NULL
Packit 022b05
};
Packit 022b05
Packit 022b05
Packit 022b05
static int pmodc = 0;
Packit 022b05
static SmiModule **pmodv = NULL;
Packit 022b05
Packit 022b05
Packit 022b05
static char getStatusChar(SmiStatus status)
Packit 022b05
{
Packit 022b05
    switch (status) {
Packit 022b05
    case SMI_STATUS_UNKNOWN:
Packit 022b05
	return '+';
Packit 022b05
    case SMI_STATUS_CURRENT:
Packit 022b05
	return '+';
Packit 022b05
    case SMI_STATUS_DEPRECATED:
Packit 022b05
	return 'x';
Packit 022b05
    case SMI_STATUS_MANDATORY:
Packit 022b05
        return '+';
Packit 022b05
    case SMI_STATUS_OPTIONAL:
Packit 022b05
	return '+';
Packit 022b05
    case SMI_STATUS_OBSOLETE:
Packit 022b05
	return 'o';
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return ' ';
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getFlags(SmiModule *smiModule, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    static char flags[4];
Packit 022b05
    int		i;
Packit 022b05
    
Packit 022b05
    memset(flags, 0, sizeof(flags));
Packit 022b05
    strcpy(flags, "---");
Packit 022b05
Packit 022b05
    switch (smiType->decl) {
Packit 022b05
    case SMI_DECL_IMPLICIT_TYPE:
Packit 022b05
	flags[0] = 'i';
Packit 022b05
	break;
Packit 022b05
    case SMI_DECL_TYPEASSIGNMENT:
Packit 022b05
	flags[0] = 'a';
Packit 022b05
	break;
Packit 022b05
    case SMI_DECL_TEXTUALCONVENTION:
Packit 022b05
    case SMI_DECL_TYPEDEF:
Packit 022b05
	flags[0] = 't';
Packit 022b05
	break;
Packit 022b05
    default:
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (i = 0; i < pmodc; i++) {
Packit 022b05
	if (strcmp(pmodv[i]->name, smiModule->name) == 0) {
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if ((!smiModule) || (strlen(smiModule->name) == 0)) {
Packit 022b05
	flags[2] = 'b';
Packit 022b05
#if 0	/* xxx fixme */
Packit 022b05
    } else if (!moduleList) {
Packit 022b05
	flags[2] = '-';
Packit 022b05
    } else if (mPtr) {
Packit 022b05
	flags[2] = 'l';
Packit 022b05
#endif
Packit 022b05
    } else {
Packit 022b05
	flags[2] = 'i';
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return flags;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void initBaseTypeCount()
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    for (i = 0; i < sizeof(basetypes)/sizeof(BaseTypeCount); i++) {
Packit 022b05
	basetypes[i].counter = 0;
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void incrBaseTypeCount(SmiBasetype basetype)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    for (i = 0; i < sizeof(basetypes)/sizeof(BaseTypeCount); i++) {
Packit 022b05
	if (basetypes[i].basetype == basetype) {
Packit 022b05
	    basetypes[i].counter++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int getBaseTypeCount(SmiBasetype basetype)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    for (i = 0; i < sizeof(basetypes)/sizeof(BaseTypeCount); i++) {
Packit 022b05
	if (basetypes[i].basetype == basetype) {
Packit 022b05
	    return basetypes[i].counter;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return -1;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
Packit 022b05
{
Packit 022b05
    static char    s[1024];
Packit 022b05
    char           ss[9];
Packit 022b05
    int		   n;
Packit 022b05
    unsigned int   i;
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    SmiNode        *nodePtr;
Packit 022b05
    
Packit 022b05
    s[0] = 0;
Packit 022b05
    
Packit 022b05
    switch (valuePtr->basetype) {
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	sprintf(s, "%lu", valuePtr->value.unsigned32);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	sprintf(s, "%ld", valuePtr->value.integer32);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_FLOAT32:
Packit 022b05
    case SMI_BASETYPE_FLOAT64:
Packit 022b05
    case SMI_BASETYPE_FLOAT128:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
	for (nn = smiGetFirstNamedNumber(typePtr); nn;
Packit 022b05
	     nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	    if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
Packit 022b05
		break;
Packit 022b05
	}
Packit 022b05
	if (nn) {
Packit 022b05
	    sprintf(s, "%s", nn->name);
Packit 022b05
	} else {
Packit 022b05
	    sprintf(s, "%ld", valuePtr->value.integer32);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	for (i = 0; i < valuePtr->len; i++) {
Packit 022b05
	    if (!isprint((int)valuePtr->value.ptr[i])) break;
Packit 022b05
	}
Packit 022b05
	if (i == valuePtr->len) {
Packit 022b05
	    sprintf(s, "\"%s\"", valuePtr->value.ptr);
Packit 022b05
	} else {
Packit 022b05
            sprintf(s, "0x%*s", 2 * valuePtr->len, "");
Packit 022b05
            for (i=0; i < valuePtr->len; i++) {
Packit 022b05
                sprintf(ss, "%02x", valuePtr->value.ptr[i]);
Packit 022b05
                strncpy(&s[2+2*i], ss, 2);
Packit 022b05
            }
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	sprintf(s, "(");
Packit 022b05
	for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
Packit 022b05
	    if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
Packit 022b05
		if (n)
Packit 022b05
		    sprintf(&s[strlen(s)], ", ");
Packit 022b05
		n++;
Packit 022b05
		for (nn = smiGetFirstNamedNumber(typePtr); nn;
Packit 022b05
		     nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
		    if (nn->value.value.unsigned32 == i)
Packit 022b05
			break;
Packit 022b05
		}
Packit 022b05
		if (nn) {
Packit 022b05
		    sprintf(&s[strlen(s)], "%s", nn->name);
Packit 022b05
		} else {
Packit 022b05
		    sprintf(s, "%d", i);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	sprintf(&s[strlen(s)], ")");
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_POINTER:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	nodePtr = smiGetNodeByOID(valuePtr->len, valuePtr->value.oid);
Packit 022b05
	if (!nodePtr) {
Packit 022b05
	    sprintf(s, "%s", nodePtr->name);
Packit 022b05
	} else {
Packit 022b05
	    strcpy(s, "");
Packit 022b05
	    for (i=0; i < valuePtr->len; i++) {
Packit 022b05
		if (i) strcat(s, ".");
Packit 022b05
		sprintf(&s[strlen(s)], "%u", valuePtr->value.oid[i]);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void addToTypeTree(TypeNode *root,
Packit 022b05
			  SmiModule *smiModule, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    TypeNode  *newType, **typePtrPtr;
Packit 022b05
    SmiType   *smiParentType;
Packit 022b05
    SmiModule *smiParentModule;
Packit 022b05
Packit 022b05
    if (! root) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiParentType = smiGetParentType(smiType);
Packit 022b05
    smiParentModule = smiParentType ? smiGetTypeModule(smiParentType) : NULL;
Packit 022b05
Packit 022b05
    if ((root->smiModule == smiParentModule && root->smiType == smiParentType)
Packit 022b05
	|| (! root->smiModule && ! root->smiType
Packit 022b05
	    && root->smiBasetype == smiType->basetype)) {
Packit 022b05
Packit 022b05
	 newType = xmalloc(sizeof(TypeNode));
Packit 022b05
	 newType->smiModule = smiModule;
Packit 022b05
	 newType->smiType = smiType;
Packit 022b05
	 newType->smiBasetype = smiType->basetype;
Packit 022b05
	 newType->childNodePtr = NULL;
Packit 022b05
	 newType->nextNodePtr = NULL;
Packit 022b05
Packit 022b05
	 for (typePtrPtr = &(root->childNodePtr);
Packit 022b05
	      *typePtrPtr; typePtrPtr = &((*typePtrPtr)->nextNodePtr)) ;
Packit 022b05
	 *typePtrPtr = newType;
Packit 022b05
	 return;
Packit 022b05
     }
Packit 022b05
Packit 022b05
     if (root->nextNodePtr) {
Packit 022b05
	 addToTypeTree(root->nextNodePtr, smiModule, smiType);
Packit 022b05
     }
Packit 022b05
     
Packit 022b05
     if (root->childNodePtr) {
Packit 022b05
	 addToTypeTree(root->childNodePtr, smiModule, smiType);
Packit 022b05
     }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void freeTypeTree(TypeNode *root)
Packit 022b05
{
Packit 022b05
    if (root->childNodePtr) {
Packit 022b05
	if (root->childNodePtr->smiModule) {
Packit 022b05
	    freeTypeTree(root->childNodePtr);
Packit 022b05
	    root->childNodePtr = NULL;
Packit 022b05
	} else {
Packit 022b05
	    freeTypeTree(root->childNodePtr);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (root->nextNodePtr) {
Packit 022b05
	if (root->nextNodePtr->smiModule) {
Packit 022b05
	    freeTypeTree(root->nextNodePtr);
Packit 022b05
	    root->nextNodePtr = NULL;
Packit 022b05
	} else {
Packit 022b05
	    freeTypeTree(root->nextNodePtr);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (root->smiModule) {
Packit 022b05
	xfree(root);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static TypeNode *findInTypeTree(TypeNode *root,
Packit 022b05
				SmiModule *smiModule, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    TypeNode *result = NULL;
Packit 022b05
    
Packit 022b05
    if (root->smiModule && root->smiModule == smiModule
Packit 022b05
	&& smiType->name
Packit 022b05
	&& root->smiType && root->smiType == smiType) {
Packit 022b05
	result = root;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (!result && root->childNodePtr) {
Packit 022b05
	result = findInTypeTree(root->childNodePtr, smiModule, smiType);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (!result && root->nextNodePtr) {
Packit 022b05
	result = findInTypeTree(root->nextNodePtr, smiModule, smiType);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return result;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char* getTypeName(TypeNode *typeNode)
Packit 022b05
{
Packit 022b05
    SmiRefinement *smiRefinement;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char *name = "?";
Packit 022b05
Packit 022b05
    if (typeNode->smiType->name) {
Packit 022b05
#if 1
Packit 022b05
	return xstrdup(typeNode->smiType->name);
Packit 022b05
#else
Packit 022b05
	char *s;
Packit 022b05
	s = xmalloc(strlen(typeNode->smiType->name)+
Packit 022b05
		    strlen(typeNode->smiModule ? typeNode->smiModule->name : "") +3);
Packit 022b05
	sprintf(s, "%s::%s", typeNode->smiModule ? typeNode->smiModule->name : "",
Packit 022b05
		typeNode->smiType->name);
Packit 022b05
	return s;
Packit 022b05
#endif
Packit 022b05
	
Packit 022b05
    } else if (typeNode->smiModule) {
Packit 022b05
	SmiNode *smiNode;
Packit 022b05
Packit 022b05
	for (smiNode = smiGetFirstNode(typeNode->smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	    if (smiGetNodeType(smiNode) == typeNode->smiType) {
Packit 022b05
		name = xmalloc(strlen(smiNode->name) + 3);
Packit 022b05
		sprintf(name, "(%s)", smiNode->name);
Packit 022b05
		return name;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	for (smiNode = smiGetFirstNode(typeNode->smiModule,
Packit 022b05
				       SMI_NODEKIND_COMPLIANCE);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
Packit 022b05
	    for(smiRefinement = smiGetFirstRefinement(smiNode);
Packit 022b05
		smiRefinement;
Packit 022b05
		smiRefinement = smiGetNextRefinement(smiRefinement)) {
Packit 022b05
		smiType = smiGetRefinementType(smiRefinement);
Packit 022b05
		if (smiType == typeNode->smiType) {
Packit 022b05
		    smiNode = smiGetRefinementNode(smiRefinement);
Packit 022b05
		    name = xmalloc(strlen(smiNode->name) + 3);
Packit 022b05
		    sprintf(name, "(%s)", smiNode->name);
Packit 022b05
		    return name;
Packit 022b05
		}
Packit 022b05
		smiType = smiGetRefinementWriteType(smiRefinement);
Packit 022b05
		if (smiType == typeNode->smiType) {
Packit 022b05
		    smiNode = smiGetRefinementNode(smiRefinement);
Packit 022b05
		    name = xmalloc(strlen(smiNode->name) + 3);
Packit 022b05
		    sprintf(name, "(%s)", smiNode->name);
Packit 022b05
		    return name;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return xstrdup(name);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintRestrictions(FILE *f, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    SmiRange       *range;
Packit 022b05
    char           s1[40], s2[40];
Packit 022b05
    int            i;
Packit 022b05
    
Packit 022b05
    if ((smiType->basetype == SMI_BASETYPE_ENUM) ||
Packit 022b05
	(smiType->basetype == SMI_BASETYPE_BITS)) {
Packit 022b05
	for(i = 0, nn = smiGetFirstNamedNumber(smiType);
Packit 022b05
	    nn ; nn = smiGetNextNamedNumber(nn), i++) {
Packit 022b05
	    fprintf(f, "%s%s(%ld)", (i == 0) ? " {" : ", ",
Packit 022b05
		   nn->name, nn->value.value.integer32);
Packit 022b05
	}
Packit 022b05
	if (i) fprintf(f, "}");
Packit 022b05
    } else {
Packit 022b05
	for(i = 0, range = smiGetFirstRange(smiType);
Packit 022b05
	    range ; range = smiGetNextRange(range), i++) {
Packit 022b05
	    strcpy(s1, getValueString(&range->minValue, smiType));
Packit 022b05
	    strcpy(s2, getValueString(&range->maxValue, smiType));
Packit 022b05
	    fprintf(f, "%s%s", (i == 0) ? " [" : ", ", s1);
Packit 022b05
	    if (strcmp(s1, s2)) fprintf(f, "..%s", s2);
Packit 022b05
	}
Packit 022b05
	if (i) fprintf(f, "]");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintTypeTree(FILE *f, TypeNode *root, char *prefix)
Packit 022b05
{
Packit 022b05
    TypeNode *typeNode, *nextNode;
Packit 022b05
    char *name;
Packit 022b05
    int namelen = -1;
Packit 022b05
Packit 022b05
    if (root->smiModule) {
Packit 022b05
	fprintf(f, "%s  |\n", prefix);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (typeNode = root; typeNode; typeNode = typeNode->nextNodePtr) {
Packit 022b05
	if (typeNode->smiType) {
Packit 022b05
	    int len;
Packit 022b05
	    name = getTypeName(typeNode);
Packit 022b05
	    len = strlen(name);
Packit 022b05
	    if (len > namelen) namelen = len;
Packit 022b05
	    xfree(name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (typeNode = root; typeNode; typeNode = typeNode->nextNodePtr) {
Packit 022b05
 	if (typeNode != &typeRoot) {
Packit 022b05
	    char c = '+', *flags;
Packit 022b05
	    if (typeNode->smiType) {
Packit 022b05
		name = getTypeName(typeNode);
Packit 022b05
		c = getStatusChar(typeNode->smiType->status);
Packit 022b05
		if (getBaseTypeCount(typeNode->smiBasetype)) {
Packit 022b05
		    flags = getFlags(typeNode->smiModule, typeNode->smiType);
Packit 022b05
		    if (flags && *flags) {
Packit 022b05
			fprintf(f, "%s  %c-- %s %-*s", prefix, c, flags,
Packit 022b05
				namelen, name);
Packit 022b05
		    } else {
Packit 022b05
			fprintf(f, "%s  %c--%-*s", prefix, c,
Packit 022b05
				namelen, name);
Packit 022b05
		    }
Packit 022b05
		    fprintRestrictions(f, typeNode->smiType);
Packit 022b05
		    if (typeNode->smiType->format) {
Packit 022b05
			fprintf(f, "\t\"%s\"", typeNode->smiType->format);
Packit 022b05
		    }
Packit 022b05
		    fprintf(f, "\n");
Packit 022b05
		}
Packit 022b05
		xfree(name);
Packit 022b05
	    } else {
Packit 022b05
		fprintf(f, "xxxx\n");
Packit 022b05
	    }
Packit 022b05
 	}
Packit 022b05
 	if (typeNode->childNodePtr) {
Packit 022b05
 	    char *newprefix;
Packit 022b05
 	    newprefix = xmalloc(strlen(prefix)+10);
Packit 022b05
 	    strcpy(newprefix, prefix);
Packit 022b05
 	    if (typeNode != &typeRoot) {
Packit 022b05
		for (nextNode = typeNode->nextNodePtr;
Packit 022b05
		     nextNode; nextNode = nextNode->nextNodePtr) {
Packit 022b05
		    if (getBaseTypeCount(nextNode->smiBasetype)) {
Packit 022b05
			break;
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
 		if (nextNode) {
Packit 022b05
  		    strcat(newprefix, "  |");
Packit 022b05
 		} else {
Packit 022b05
 		    strcat(newprefix, "   ");
Packit 022b05
 		}
Packit 022b05
 	    }
Packit 022b05
 	    fprintTypeTree(f, typeNode->childNodePtr, newprefix);
Packit 022b05
 	    xfree(newprefix);
Packit 022b05
	    for (nextNode = typeNode->nextNodePtr;
Packit 022b05
		 nextNode; nextNode = nextNode->nextNodePtr) {
Packit 022b05
		if (getBaseTypeCount(nextNode->smiBasetype)) {
Packit 022b05
		    break;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if (nextNode) {
Packit 022b05
		fprintf(f, "%s  |\n", prefix);
Packit 022b05
	    }
Packit 022b05
 	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void addType(SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiModule *smiModule;
Packit 022b05
    SmiType   *smiParentType;
Packit 022b05
Packit 022b05
    smiModule = smiGetTypeModule(smiType);
Packit 022b05
    if (! smiModule) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (findInTypeTree(&typeRoot, smiModule, smiType)) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiParentType = smiGetParentType(smiType);
Packit 022b05
    if (smiParentType && smiParentType->name) {
Packit 022b05
 	if (smiParentType) {
Packit 022b05
 	    addType(smiParentType);
Packit 022b05
 	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    addToTypeTree(&typeRoot, smiModule, smiType);
Packit 022b05
    incrBaseTypeCount(smiType->basetype);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpTypes(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    SmiNode	  *smiNode;
Packit 022b05
    SmiType       *smiType;
Packit 022b05
    SmiRefinement *smiRefinement;
Packit 022b05
    int		  i;
Packit 022b05
    FILE          *f = stdout;
Packit 022b05
    const unsigned int nodekind = SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR;
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
    pmodc = modc;
Packit 022b05
    pmodv = modv;
Packit 022b05
    
Packit 022b05
    initBaseTypeCount();
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
Packit 022b05
	if (! (flags & SMIDUMP_FLAG_UNITE)) {
Packit 022b05
	    initBaseTypeCount();
Packit 022b05
	}
Packit 022b05
Packit 022b05
	for (smiType = smiGetFirstType(modv[i]);
Packit 022b05
	     smiType;
Packit 022b05
	     smiType = smiGetNextType(smiType)) {
Packit 022b05
	    addType(smiType);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	for (smiNode = smiGetFirstNode(modv[i], nodekind);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, nodekind)) {
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (smiType) {
Packit 022b05
		if (!noimplicit && smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit 022b05
		    addType(smiType);
Packit 022b05
		}
Packit 022b05
		incrBaseTypeCount(smiType->basetype);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	for (smiNode = smiGetFirstNode(modv[i], SMI_NODEKIND_COMPLIANCE);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
Packit 022b05
	    for (smiRefinement = smiGetFirstRefinement(smiNode);
Packit 022b05
		 smiRefinement;
Packit 022b05
		 smiRefinement = smiGetNextRefinement(smiRefinement)) {
Packit 022b05
		smiType = smiGetRefinementType(smiRefinement);
Packit 022b05
		if (smiType) {
Packit 022b05
		    if (!noimplicit
Packit 022b05
			&& smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit 022b05
			addType(smiType);
Packit 022b05
		    }
Packit 022b05
		    incrBaseTypeCount(smiType->basetype);
Packit 022b05
		}
Packit 022b05
		smiType = smiGetRefinementWriteType(smiRefinement);
Packit 022b05
		if (smiType) {
Packit 022b05
		    if (!noimplicit
Packit 022b05
			&& smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit 022b05
			addType(smiType);
Packit 022b05
		    }
Packit 022b05
		    incrBaseTypeCount(smiType->basetype);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! (flags & SMIDUMP_FLAG_UNITE)) {
Packit 022b05
	    if (! (flags & SMIDUMP_FLAG_SILENT)) {
Packit 022b05
		fprintf(f, "# %s type derivation tree (generated by smidump "
Packit 022b05
			SMI_VERSION_STRING ")\n\n", modv[i]->name);
Packit 022b05
	    }
Packit 022b05
	    if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
Packit 022b05
		fprintf(f, "# WARNING: this output may be incorrect due to "
Packit 022b05
			"significant parse errors\n\n");
Packit 022b05
	    }
Packit 022b05
	    fprintTypeTree(f, &typeRoot, "");
Packit 022b05
	    freeTypeTree(&typeRoot);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	if (! (flags & SMIDUMP_FLAG_SILENT)) {
Packit 022b05
	    fprintf(f, "# united type derivation tree (generated by smidump "
Packit 022b05
		   SMI_VERSION_STRING ")\n\n");
Packit 022b05
	}
Packit 022b05
	if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
Packit 022b05
	    fprintf(f, "# WARNING: this output may be incorrect due to "
Packit 022b05
		    "significant parse errors\n\n");
Packit 022b05
	}
Packit 022b05
	fprintTypeTree(f, &typeRoot, "");
Packit 022b05
	freeTypeTree(&typeRoot);
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 initTypes()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "no-implicit", OPT_FLAG, &noimplicit, 0,
Packit 022b05
	  "ignore implicit type definitions"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"types",
Packit 022b05
	dumpTypes,
Packit 022b05
	SMI_FLAG_NODESCR,
Packit 022b05
	0,
Packit 022b05
	"recursive list of all derived types",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}