Blame tools/rea.c

Packit Service 9ccfef
/*
Packit Service 9ccfef
 * rea.c --
Packit Service 9ccfef
 *
Packit Service 9ccfef
 *      This file holds the reverse engineering algorithm common for
Packit Service 9ccfef
 *      dump-cm.c and dump-svg.c.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Copyright (c) 2000 A. Mueller, Technical University of Braunschweig.
Packit Service 9ccfef
 * Copyright (c) 2005 K. Sperner, Technical University of Braunschweig.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * See the file "COPYING" for information on usage and redistribution
Packit Service 9ccfef
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * @(#) $Id: rea.c 7823 2008-03-01 13:53:12Z schoenw $
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
#include <config.h>
Packit Service 9ccfef
Packit Service 9ccfef
#include <stdio.h>
Packit Service 9ccfef
#include <stdlib.h>
Packit Service 9ccfef
#include <string.h>
Packit Service 9ccfef
#include <ctype.h>
Packit Service 9ccfef
#ifdef HAVE_WIN_H
Packit Service 9ccfef
#include "win.h"
Packit Service 9ccfef
#endif
Packit Service 9ccfef
Packit Service 9ccfef
#include "smi.h"
Packit Service 9ccfef
#include "smidump.h"
Packit Service 9ccfef
#include "rea.h"
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * Constants used by the reverse engineering algorithm.
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
static char *pointer[] = {
Packit Service 9ccfef
    "Index", NULL
Packit Service 9ccfef
};
Packit Service 9ccfef
Packit Service 9ccfef
static char *suffix[] = {
Packit Service 9ccfef
    "OrZero", NULL
Packit Service 9ccfef
};
Packit Service 9ccfef
Packit Service 9ccfef
static char *supportObjs[] = {
Packit Service 9ccfef
    "RowStatus", "StorageType", NULL
Packit Service 9ccfef
};
Packit Service 9ccfef
Packit Service 9ccfef
static char *baseTypes[] = {
Packit Service 9ccfef
    "Integer32", "OctetString", "Unsigned32", "Integer64",
Packit Service 9ccfef
    "Unsigned64", "Float32", "Float64", "Float128",
Packit Service 9ccfef
    "Enumeration", "Counter32", "Counter64","Bits",
Packit Service 9ccfef
    "Gauge", "Gauge32", "Integer", "TimeTicks",
Packit Service 9ccfef
    "IpAddress", "Opaque", "ObjectIdentifier",
Packit Service 9ccfef
    NULL
Packit Service 9ccfef
};
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * driver output control
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * variables for svg-output
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * When you change CANVASHEIGHT, CANVASWIDTH values here, you should
Packit Service 9ccfef
 * also change them in initSvg() and the cgi-script.
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
int       CANVASHEIGHT          = 700; /* height of the svg */
Packit Service 9ccfef
int       CANVASWIDTH           = 1100; /* width of the svg */
Packit Service 9ccfef
int       SHOW_DEPRECATED       = 0; /* false, show deprecated objects */
Packit Service 9ccfef
int       SHOW_DEPR_OBSOLETE    = 0; /* false, show deprecated and
Packit Service 9ccfef
					obsolete objects */
Packit Service 9ccfef
int       STATIC_OUTPUT         = 0; /* false, enable interactivity */
Packit Service 9ccfef
/* variables for cm-driver */
Packit Service 9ccfef
int       XPLAIN                = 0; /* false, generates ASCII output */
Packit Service 9ccfef
int       XPLAIN_DEBUG          = 0; /* false, generates additional
Packit Service 9ccfef
					       output in xplain-mode */
Packit Service 9ccfef
int       SUPPRESS_DEPRECATED   = 1; /* true, suppresses deprecated
Packit Service 9ccfef
					       objects */
Packit Service 9ccfef
/* common variables */
Packit Service 9ccfef
int       PRINT_DETAILED_ATTR   = 1; /* true, prints all column
Packit Service 9ccfef
					       objects */
Packit Service 9ccfef
int       IGNORE_IMPORTED_NODES = 1; /* true, ignores nodes which are
Packit Service 9ccfef
					       imported from other MIBs*/
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * global variables
Packit Service 9ccfef
 */
Packit Service 9ccfef
Graph     *graph  = NULL;            /* the graph */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/* ------ Misc. -----------------                                            */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * cmpSmiNodes
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Compares two SmiNode and returns 1 if they are equal and 0 otherwise.
Packit Service 9ccfef
 */
Packit Service 9ccfef
int cmpSmiNodes(SmiNode *node1, SmiNode *node2)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiModule *module1, *module2;
Packit Service 9ccfef
Packit Service 9ccfef
    module1 = smiGetNodeModule(node1);
Packit Service 9ccfef
    module2 = smiGetNodeModule(node2);
Packit Service 9ccfef
    
Packit Service 9ccfef
    if (!node1 || !node2 || !module1 || !module2) return 0;
Packit Service 9ccfef
    
Packit Service 9ccfef
    return (strcmp(node1->name, node2->name) == 0 &&
Packit Service 9ccfef
	    strcmp(module1->name, module2->name) == 0);
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * strpfxlen
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the number of identical characters at the beginning of s1 and s2.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int strpfxlen(const char *s1, const char *s2)
Packit Service 9ccfef
{
Packit Service 9ccfef
    int i;
Packit Service 9ccfef
Packit Service 9ccfef
    for (i = 0; s1[i] && s2[i]; i++) {
Packit Service 9ccfef
	if (s1[i] != s2[i]) {
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    return i;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/* ------ Graph primitives ------                                            */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphInsertNode
Packit Service 9ccfef
 *
Packit Service 9ccfef
 *          Inserts a new node into an existing graph.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Result : pointer to the new node
Packit Service 9ccfef
 */
Packit Service 9ccfef
GraphNode *graphInsertNode(Graph *graph, SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *newNode;
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    GraphNode *lastNode;
Packit Service 9ccfef
Packit Service 9ccfef
    newNode = xmalloc(sizeof(GraphNode));
Packit Service 9ccfef
    memset(newNode, 0, sizeof(GraphNode));
Packit Service 9ccfef
    newNode->smiNode = smiNode;
Packit Service 9ccfef
Packit Service 9ccfef
    if (graph->nodes == NULL) {
Packit Service 9ccfef
	graph->nodes = newNode;
Packit Service 9ccfef
	return newNode;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastNode = NULL; 
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	lastNode = tNode;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastNode->nextPtr = newNode;
Packit Service 9ccfef
Packit Service 9ccfef
    return newNode;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphInsertComponent
Packit Service 9ccfef
 *
Packit Service 9ccfef
 *          Inserts a new component into an existing graph.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Result : pointer to the new component
Packit Service 9ccfef
 */
Packit Service 9ccfef
GraphComponent *graphInsertComponent(Graph *graph)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphComponent *newComponent;
Packit Service 9ccfef
    GraphComponent *tComponent;
Packit Service 9ccfef
    GraphComponent *lastComponent;
Packit Service 9ccfef
Packit Service 9ccfef
    newComponent = xmalloc(sizeof(GraphComponent));
Packit Service 9ccfef
    memset(newComponent, 0, sizeof(GraphComponent));
Packit Service 9ccfef
Packit Service 9ccfef
    if (graph->components == NULL) {
Packit Service 9ccfef
	graph->components = newComponent;
Packit Service 9ccfef
	return newComponent;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastComponent = NULL;
Packit Service 9ccfef
    for (tComponent = graph->components; tComponent;
Packit Service 9ccfef
					    tComponent = tComponent->nextPtr) {
Packit Service 9ccfef
	lastComponent = tComponent;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastComponent->nextPtr = newComponent;
Packit Service 9ccfef
Packit Service 9ccfef
    return newComponent;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphInsertEdge
Packit Service 9ccfef
 *
Packit Service 9ccfef
 *          Inserts a new edge into an existing list of edges.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Input  : graph     = pointer to an edge structure
Packit Service 9ccfef
 *          startNode = pointer to the starting node of the edge
Packit Service 9ccfef
 *          endNode   = pointer to the ending node of the edge
Packit Service 9ccfef
 *          indexkind = type of relationship between the two nodes
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Result : pointer to the new edge
Packit Service 9ccfef
 */
Packit Service 9ccfef
static GraphEdge *graphInsertEdge(Graph *graph, GraphNode *startNode,
Packit Service 9ccfef
			      GraphNode *endNode,
Packit Service 9ccfef
			      SmiIndexkind indexkind,
Packit Service 9ccfef
			      GraphEnhIndex enhancedindex)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *newEdge;
Packit Service 9ccfef
    GraphEdge *tEdge;
Packit Service 9ccfef
    GraphEdge *lastEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    newEdge = xmalloc(sizeof(GraphEdge));
Packit Service 9ccfef
    memset(newEdge, 0, sizeof(GraphEdge));
Packit Service 9ccfef
    newEdge->startNode = startNode;
Packit Service 9ccfef
    newEdge->endNode = endNode;
Packit Service 9ccfef
    newEdge->indexkind = indexkind;
Packit Service 9ccfef
    newEdge->connection = GRAPH_CON_ASSOCIATION;
Packit Service 9ccfef
    newEdge->enhancedindex = enhancedindex;
Packit Service 9ccfef
Packit Service 9ccfef
    switch (newEdge->indexkind) {
Packit Service 9ccfef
    case SMI_INDEX_AUGMENT : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_ONE_TO_ONE; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    case SMI_INDEX_SPARSE  : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_ONE_TO_ZERO_OR_ONE; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    case SMI_INDEX_EXPAND  : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_UNKNOWN; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    case SMI_INDEX_REORDER : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_ONE_TO_ONE; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    case SMI_INDEX_INDEX   : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_UNKNOWN; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    case SMI_INDEX_UNKNOWN : 
Packit Service 9ccfef
	newEdge->cardinality = GRAPH_CARD_UNKNOWN; 
Packit Service 9ccfef
	break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (graph->edges == NULL) {
Packit Service 9ccfef
	graph->edges = newEdge;
Packit Service 9ccfef
	return newEdge;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastEdge = NULL; 
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	lastEdge = tEdge;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    lastEdge->nextPtr = newEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    return newEdge;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphExit
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Frees all memory allocated by the graph.
Packit Service 9ccfef
 */
Packit Service 9ccfef
void graphExit(Graph *graph)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge, *dummyEdge;
Packit Service 9ccfef
    GraphNode *tNode, *dummyNode;
Packit Service 9ccfef
    GraphComponent *tComponent, *dummyComponent;
Packit Service 9ccfef
Packit Service 9ccfef
    if (graph) {
Packit Service 9ccfef
Packit Service 9ccfef
	dummyNode = NULL;
Packit Service 9ccfef
	tNode = graph->nodes;
Packit Service 9ccfef
	while (tNode != NULL) {
Packit Service 9ccfef
	    dummyNode = tNode;
Packit Service 9ccfef
	    tNode = tNode->nextPtr;
Packit Service 9ccfef
      
Packit Service 9ccfef
	    xfree(dummyNode);
Packit Service 9ccfef
	}
Packit Service 9ccfef
    
Packit Service 9ccfef
	dummyEdge = NULL;
Packit Service 9ccfef
	tEdge = graph->edges;
Packit Service 9ccfef
	while (tEdge != NULL) {
Packit Service 9ccfef
	    dummyEdge = tEdge;
Packit Service 9ccfef
	    tEdge = tEdge->nextPtr;
Packit Service 9ccfef
      
Packit Service 9ccfef
	    xfree(dummyEdge);
Packit Service 9ccfef
	}
Packit Service 9ccfef
    
Packit Service 9ccfef
	dummyComponent = NULL;
Packit Service 9ccfef
	tComponent = graph->components;
Packit Service 9ccfef
	while (tComponent != NULL) {
Packit Service 9ccfef
	    dummyComponent = tComponent;
Packit Service 9ccfef
	    tComponent = tComponent->nextPtr;
Packit Service 9ccfef
      
Packit Service 9ccfef
	    xfree(dummyComponent);
Packit Service 9ccfef
	}
Packit Service 9ccfef
    
Packit Service 9ccfef
	xfree(graph);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphGetFirstEdgeByNode
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the first edge adjacent to the given node (as startNode or EndNode).
Packit Service 9ccfef
 */
Packit Service 9ccfef
GraphEdge *graphGetFirstEdgeByNode(Graph *graph, GraphNode *node)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!graph || !node) {
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	/*if (tEdge->startNode->smiNode->name == node->smiNode->name ||
Packit Service 9ccfef
	  tEdge->endNode->smiNode->name == node->smiNode->name) break;*/
Packit Service 9ccfef
	if (cmpSmiNodes(tEdge->startNode->smiNode, node->smiNode) ||
Packit Service 9ccfef
	    cmpSmiNodes(tEdge->endNode->smiNode, node->smiNode)) break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return tEdge;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphGetNextEdgeByNode
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the next edge adjacent to the given node (as startNode or EndNode)
Packit Service 9ccfef
 * after the given edge.
Packit Service 9ccfef
 */
Packit Service 9ccfef
GraphEdge *graphGetNextEdgeByNode(Graph *graph, 
Packit Service 9ccfef
					 GraphEdge *edge,
Packit Service 9ccfef
					 GraphNode *node) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!graph || !node) {
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	/*if (tEdge->startNode->smiNode->name ==
Packit Service 9ccfef
	    edge->startNode->smiNode->name &&
Packit Service 9ccfef
	    tEdge->endNode->smiNode->name ==
Packit Service 9ccfef
	    edge->endNode->smiNode->name) break;*/
Packit Service 9ccfef
	if (cmpSmiNodes(tEdge->startNode->smiNode,edge->startNode->smiNode) &&
Packit Service 9ccfef
	    cmpSmiNodes(tEdge->endNode->smiNode,edge->endNode->smiNode))
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
  
Packit Service 9ccfef
    for (tEdge = tEdge->nextPtr; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	/*if (tEdge->startNode->smiNode->name == node->smiNode->name ||
Packit Service 9ccfef
	  tEdge->endNode->smiNode->name == node->smiNode->name) break;*/
Packit Service 9ccfef
	if (cmpSmiNodes(tEdge->startNode->smiNode, node->smiNode) ||
Packit Service 9ccfef
	    cmpSmiNodes(tEdge->endNode->smiNode, node->smiNode)) break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return tEdge;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphCheckForRedundantEdge
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Finds redundant edges and returns 1 if one is found and 0 otherwise.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int graphCheckForRedundantEdge(Graph *graph,
Packit Service 9ccfef
			       GraphNode *startNode,
Packit Service 9ccfef
			       GraphNode *endNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!graph || !startNode || !endNode) {
Packit Service 9ccfef
	return 0;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	/*if (tEdge->startNode->smiNode->name == startNode->smiNode->name &&
Packit Service 9ccfef
	  tEdge->endNode->smiNode->name == endNode->smiNode->name) {*/
Packit Service 9ccfef
	if (cmpSmiNodes(tEdge->startNode->smiNode, startNode->smiNode) &&
Packit Service 9ccfef
	    cmpSmiNodes(tEdge->endNode->smiNode, endNode->smiNode)) {
Packit Service 9ccfef
	    
Packit Service 9ccfef
	    return 1;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    return 0;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphGetNode
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the graph node containing smiNode.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static GraphNode *graphGetNode(Graph *graph, SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!smiNode || !graph) {
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->name == smiNode->name) {
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return tNode;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphShowNodes
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Prints the nodes of the graph.
Packit Service 9ccfef
 */
Packit Service 9ccfef
void graphShowNodes(Graph *graph) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (!graph->nodes) {
Packit Service 9ccfef
	printf("No nodes!\n");
Packit Service 9ccfef
	return;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->nodekind == SMI_NODEKIND_TABLE)
Packit Service 9ccfef
	    printf(" [TABLE]");
Packit Service 9ccfef
	else printf("[SCALAR]");
Packit Service 9ccfef
	printf("%40s [%s]\n", tNode->smiNode->name,
Packit Service 9ccfef
	       smiGetNodeModule(tNode->smiNode)->name);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * graphShowEdges
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Prints the edges with their attributes in the following order :
Packit Service 9ccfef
 *    - start node
Packit Service 9ccfef
 *    - reason for the link
Packit Service 9ccfef
 *    - connection type in UML
Packit Service 9ccfef
 *    - cardinality
Packit Service 9ccfef
 *    - index relationship derived from the row-objects of the tables
Packit Service 9ccfef
 *
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void graphShowEdges(Graph *graph) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge  *tEdge;
Packit Service 9ccfef
    
Packit Service 9ccfef
    if (!graph->edges) {
Packit Service 9ccfef
	printf("No edges!\n");
Packit Service 9ccfef
	return;
Packit Service 9ccfef
    }
Packit Service 9ccfef
  
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
Packit Service 9ccfef
	if (XPLAIN_DEBUG) {
Packit Service 9ccfef
	    switch (tEdge->enhancedindex) {
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_UNKNOWN :
Packit Service 9ccfef
		printf("[UNKNOWN] ");
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_NOTIFICATION :
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_NAMES :
Packit Service 9ccfef
		printf("  [NAMES] ");
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_TYPES :
Packit Service 9ccfef
		printf("  [TYPES] ");
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_INDEX :
Packit Service 9ccfef
		printf("  [INDEX] ");
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_REROUTE :
Packit Service 9ccfef
		printf("[REROUTE] ");
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    case GRAPH_ENHINDEX_POINTER :
Packit Service 9ccfef
		printf("[POINTER] ");
Packit Service 9ccfef
		break;	    
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
	
Packit Service 9ccfef
	switch (tEdge->connection) {
Packit Service 9ccfef
	case GRAPH_CON_AGGREGATION:
Packit Service 9ccfef
	    printf("AG.");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CON_DEPENDENCY:
Packit Service 9ccfef
	    printf("D. ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CON_ASSOCIATION:
Packit Service 9ccfef
	    printf("A. ");
Packit Service 9ccfef
	    break;    
Packit Service 9ccfef
	case GRAPH_CON_UNKNOWN:
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
Packit Service 9ccfef
	switch (tEdge->cardinality) {
Packit Service 9ccfef
	case GRAPH_CARD_UNKNOWN      :
Packit Service 9ccfef
	    printf("  (-:-)  ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CARD_ONE_TO_ONE   :
Packit Service 9ccfef
	    printf("  (1:1)  ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CARD_ONE_TO_MANY  :
Packit Service 9ccfef
	    printf("  (1:n)  ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CARD_ZERO_TO_ONE  :
Packit Service 9ccfef
	    printf("  (0:1)  ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CARD_ZERO_TO_MANY :
Packit Service 9ccfef
	    printf("  (0:n)  ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case GRAPH_CARD_ONE_TO_ZERO_OR_ONE :
Packit Service 9ccfef
	    printf("(1:0..1) ");
Packit Service 9ccfef
	    break;	    
Packit Service 9ccfef
	}
Packit Service 9ccfef
Packit Service 9ccfef
	switch (tEdge->indexkind) {
Packit Service 9ccfef
	case SMI_INDEX_UNKNOWN  :
Packit Service 9ccfef
	    printf("GENERIC ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case SMI_INDEX_INDEX    :
Packit Service 9ccfef
	    printf("  INDEX ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case SMI_INDEX_AUGMENT  :
Packit Service 9ccfef
	    printf("AUGMENT ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case SMI_INDEX_SPARSE   :
Packit Service 9ccfef
	    printf(" SPARSE ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case SMI_INDEX_EXPAND   :
Packit Service 9ccfef
	    printf(" EXPAND ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	case SMI_INDEX_REORDER  :
Packit Service 9ccfef
	    printf("REORDER ");
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
	printf("%29s - ",tEdge->startNode->smiNode->name);
Packit Service 9ccfef
	printf("%s\n",tEdge->endNode->smiNode->name);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/* ------ algorithm primitives ------                                        */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCountIndexElements
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the number of index elements in a given row entry.
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
static int algCountIndexElements(SmiNode *smiNode) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    int          count;
Packit Service 9ccfef
    SmiElement   *smiElement;
Packit Service 9ccfef
Packit Service 9ccfef
    if (smiNode->nodekind != SMI_NODEKIND_ROW) {
Packit Service 9ccfef
	return 0;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    count = 0;
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(smiNode);
Packit Service 9ccfef
	 smiElement;
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
	count++;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return count;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algInsertEdge
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Inserts an edge in a given graph. The edge is adjacent to snode 
Packit Service 9ccfef
 * and enode.
Packit Service 9ccfef
 * The type of edge is given in indexkind and the enhanced index as
Packit Service 9ccfef
 * an additional information in enhancedindex.
Packit Service 9ccfef
 * Nodes which are not loaded yet into the node list of the graph
Packit Service 9ccfef
 * are added (nodes from imported MIBs).
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algInsertEdge(SmiNode *snode, SmiNode *enode, 
Packit Service 9ccfef
			  SmiIndexkind indexkind,
Packit Service 9ccfef
			  GraphEnhIndex enhancedindex) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *startNode;
Packit Service 9ccfef
    GraphNode *endNode;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!graph) return;
Packit Service 9ccfef
Packit Service 9ccfef
    startNode = graphGetNode(graph, snode);
Packit Service 9ccfef
    endNode   = graphGetNode(graph, enode);
Packit Service 9ccfef
Packit Service 9ccfef
    /* insert imported nodes into graph if needed */
Packit Service 9ccfef
    if (startNode == NULL) {
Packit Service 9ccfef
	if (IGNORE_IMPORTED_NODES) return;
Packit Service 9ccfef
	
Packit Service 9ccfef
	startNode = graphInsertNode(graph, snode);
Packit Service 9ccfef
    }
Packit Service 9ccfef
    if (endNode == NULL) {
Packit Service 9ccfef
	if (IGNORE_IMPORTED_NODES) return;
Packit Service 9ccfef
	
Packit Service 9ccfef
	endNode = graphInsertNode(graph, enode);
Packit Service 9ccfef
    }  
Packit Service 9ccfef
Packit Service 9ccfef
    if (graphCheckForRedundantEdge(graph, startNode, endNode) == 0 &&
Packit Service 9ccfef
	graphCheckForRedundantEdge(graph, endNode, startNode) == 0) {
Packit Service 9ccfef
	graphInsertEdge(graph, startNode, endNode, indexkind, enhancedindex); 
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetGroupByFatherNode
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the group number associated with the father node of the
Packit Service 9ccfef
 * given node. If there is no group the result is 0 for no
Packit Service 9ccfef
 * grouping.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int algGetGroupByFatherNode(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR &&
Packit Service 9ccfef
	    !graphGetFirstEdgeByNode(graph, tNode)) {
Packit Service 9ccfef
	    if (cmpSmiNodes(smiGetParentNode(smiNode),
Packit Service 9ccfef
			    smiGetParentNode(tNode->smiNode))) {
Packit Service 9ccfef
		return tNode->group;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return 0;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetNumberOfGroups
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the number of groups.
Packit Service 9ccfef
 */
Packit Service 9ccfef
int algGetNumberOfGroups()
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    int       maxGroup;
Packit Service 9ccfef
Packit Service 9ccfef
    maxGroup = 0;
Packit Service 9ccfef
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	maxGroup = max(maxGroup, tNode->group); 
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return maxGroup;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algPrintGroup
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Prints the group with the number group.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algPrintGroup(int group)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->group == group) {
Packit Service 9ccfef
	    printf("%2d - %35s\n", group, tNode->smiNode->name);
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetTypeDescription
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the description of the data type used in smiNode.
Packit Service 9ccfef
 */
Packit Service 9ccfef
char *algGetTypeDescription(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiType *smiType, *parentType;
Packit Service 9ccfef
  
Packit Service 9ccfef
    smiType = smiGetNodeType(smiNode);
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (!smiType || smiNode->nodekind == SMI_NODEKIND_TABLE)
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit Service 9ccfef
	parentType = smiGetParentType(smiType);
Packit Service 9ccfef
	smiType = parentType;
Packit Service 9ccfef
    }
Packit Service 9ccfef
  
Packit Service 9ccfef
    return smiType->description;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetTypeName
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the name of the data type used in smiNode.
Packit Service 9ccfef
 */
Packit Service 9ccfef
char *algGetTypeName(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiType *smiType, *parentType;
Packit Service 9ccfef
  
Packit Service 9ccfef
    smiType = smiGetNodeType(smiNode);
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (!smiType || smiNode->nodekind == SMI_NODEKIND_TABLE)
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit Service 9ccfef
	parentType = smiGetParentType(smiType);
Packit Service 9ccfef
	smiType = parentType;
Packit Service 9ccfef
    }
Packit Service 9ccfef
  
Packit Service 9ccfef
    return smiType->name;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetTypeModule
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the module which defines the data type used in smiNode.
Packit Service 9ccfef
 */
Packit Service 9ccfef
SmiModule *algGetTypeModule(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiType *smiType, *parentType;
Packit Service 9ccfef
    SmiModule *smiModule;
Packit Service 9ccfef
  
Packit Service 9ccfef
    smiType = smiGetNodeType(smiNode);
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (!smiType || smiNode->nodekind == SMI_NODEKIND_TABLE)
Packit Service 9ccfef
	return NULL;
Packit Service 9ccfef
  
Packit Service 9ccfef
    if (smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit Service 9ccfef
	parentType = smiGetParentType(smiType);
Packit Service 9ccfef
	smiType = parentType;
Packit Service 9ccfef
    }
Packit Service 9ccfef
  
Packit Service 9ccfef
    smiModule = smiGetTypeModule(smiType);
Packit Service 9ccfef
Packit Service 9ccfef
    return smiModule;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCountElementsFromOtherTables
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the number of index objects derived from other tables than
Packit Service 9ccfef
 * the given one.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int algCountElementsFromOtherTables(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiElement *smiElement;
Packit Service 9ccfef
    SmiNode    *tNode;
Packit Service 9ccfef
    int        elems = 0;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(smiNode);
Packit Service 9ccfef
	 smiElement;
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
Packit Service 9ccfef
	tNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
	
Packit Service 9ccfef
	if (cmpSmiNodes(smiGetParentNode(smiGetParentNode(tNode)),
Packit Service 9ccfef
			smiGetParentNode(smiNode)) != 1) {
Packit Service 9ccfef
	    elems++;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return elems;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetNumberOfRows
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Returns the number of rows =
Packit Service 9ccfef
 *   number of elements in smiNode - number of rows 
Packit Service 9ccfef
 *   + RowStatus-Objects + StorageType-Objects
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * If the number is > 0 it is only a supporting table (like entLPMappingTable) 
Packit Service 9ccfef
 * and if the number is < 0 it is a "full" table (like ifTable).
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Subroutine for algCheckForDependency.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int algGetNumberOfRows(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiNode *tSmiNode;
Packit Service 9ccfef
    SmiNode *table;
Packit Service 9ccfef
    int     i, elemCount;
Packit Service 9ccfef
Packit Service 9ccfef
    elemCount = 0;
Packit Service 9ccfef
    table = smiNode;
Packit Service 9ccfef
    tSmiNode = smiGetFirstChildNode(table);
Packit Service 9ccfef
Packit Service 9ccfef
    elemCount = algCountIndexElements(tSmiNode) -
Packit Service 9ccfef
	algCountElementsFromOtherTables(tSmiNode);
Packit Service 9ccfef
Packit Service 9ccfef
    for (tSmiNode = smiGetNextNode(tSmiNode, SMI_NODEKIND_COLUMN);
Packit Service 9ccfef
	 tSmiNode;
Packit Service 9ccfef
	 tSmiNode = smiGetNextNode(tSmiNode, SMI_NODEKIND_COLUMN)) {
Packit Service 9ccfef
Packit Service 9ccfef
	if (cmpSmiNodes(table, smiGetParentNode(smiGetParentNode(tSmiNode)))
Packit Service 9ccfef
	    != 1) {
Packit Service 9ccfef
	    break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
	
Packit Service 9ccfef
	for (i = 0; supportObjs[i]; i++) {
Packit Service 9ccfef
	    char *typeName = algGetTypeName(tSmiNode);
Packit Service 9ccfef
	    if (typeName && (strcasecmp(typeName, supportObjs[i]) == 0)) {
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
Packit Service 9ccfef
	if (!supportObjs[i]) elemCount--;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return elemCount;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * isBaseType
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * returns 1 if smiElement is a basetype used in SMIv2/SMIng. Otherwise
Packit Service 9ccfef
 * the result is 0.
Packit Service 9ccfef
 */
Packit Service 9ccfef
int isBaseType(SmiNode *node)
Packit Service 9ccfef
{
Packit Service 9ccfef
    int i;
Packit Service 9ccfef
Packit Service 9ccfef
    for (i = 0; baseTypes[i]; i++) {
Packit Service 9ccfef
	if (strcasecmp(algGetTypeName(node), baseTypes[i]) == 0) {
Packit Service 9ccfef
	    return 1;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return 0;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algFindEqualType
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Looks in all tables indices for an equal type to the type used in typeNode.
Packit Service 9ccfef
 * It returns the first table found which is different to startTable.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Subroutine for algCheckForDependency. 
Packit Service 9ccfef
 */
Packit Service 9ccfef
static SmiNode *algFindEqualType(SmiNode *startTable, SmiNode *typeNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiElement *smiElement;
Packit Service 9ccfef
    SmiNode    *tSmiNode;
Packit Service 9ccfef
    char       *typeName;
Packit Service 9ccfef
    GraphNode  *tNode;
Packit Service 9ccfef
    
Packit Service 9ccfef
    typeName = algGetTypeName(typeNode);
Packit Service 9ccfef
    /* if (isBaseType(typeNode)) return NULL; */
Packit Service 9ccfef
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
Packit Service 9ccfef
	    tSmiNode = tNode->smiNode;
Packit Service 9ccfef
	    if (cmpSmiNodes(tSmiNode, startTable) == 1) break;
Packit Service 9ccfef
	    
Packit Service 9ccfef
	    for (smiElement = smiGetFirstElement(
Packit Service 9ccfef
		smiGetFirstChildNode(tSmiNode));
Packit Service 9ccfef
		 smiElement;
Packit Service 9ccfef
		 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
		/* found type matching ? */
Packit Service 9ccfef
		if (strcmp(typeName,
Packit Service 9ccfef
			       algGetTypeName(smiGetElementNode
Packit Service 9ccfef
					      (smiElement))) == 0) {
Packit Service 9ccfef
		    return tSmiNode;
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	    
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    return NULL;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * 0 = totaly equal (order and objects)
Packit Service 9ccfef
 * 1 = equal objects but different order
Packit Service 9ccfef
 * 2 = inequal
Packit Service 9ccfef
 * 3 = error;
Packit Service 9ccfef
 */
Packit Service 9ccfef
 static int equalElements(SmiNode *firstRow, SmiNode *secondRow)
Packit Service 9ccfef
{
Packit Service 9ccfef
    int i,j,number1, number2;
Packit Service 9ccfef
    SmiElement *elemFirst, *elemSecond;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!firstRow->nodekind == SMI_NODEKIND_ROW ||
Packit Service 9ccfef
	!secondRow->nodekind == SMI_NODEKIND_ROW) {
Packit Service 9ccfef
	/* printf("no row entries\n"); */
Packit Service 9ccfef
	return 3;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (cmpSmiNodes(firstRow, secondRow) == 1) {
Packit Service 9ccfef
	/* printf("same objects\n"); */
Packit Service 9ccfef
	return 3;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    number1 = algCountIndexElements(firstRow);
Packit Service 9ccfef
    number2 = algCountIndexElements(secondRow);
Packit Service 9ccfef
Packit Service 9ccfef
    if (number1 != number2) {
Packit Service 9ccfef
	/* printf("Different number of elements\n"); */
Packit Service 9ccfef
	return 2;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    i = 0;
Packit Service 9ccfef
    for (elemFirst = smiGetFirstElement(firstRow);
Packit Service 9ccfef
	 elemFirst;
Packit Service 9ccfef
	 elemFirst = smiGetNextElement(elemFirst)) {
Packit Service 9ccfef
	i++;
Packit Service 9ccfef
Packit Service 9ccfef
	j = 0;
Packit Service 9ccfef
	for (elemSecond = smiGetFirstElement(secondRow);
Packit Service 9ccfef
	     elemSecond;
Packit Service 9ccfef
	     elemSecond = smiGetNextElement(elemSecond)) {
Packit Service 9ccfef
	    j++;
Packit Service 9ccfef
	    if (i == j && cmpSmiNodes(smiGetElementNode(elemFirst),
Packit Service 9ccfef
				      smiGetElementNode(elemSecond)) == 1) {
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
Packit Service 9ccfef
	/* maybe same elements but in different order */
Packit Service 9ccfef
	if (!elemSecond) break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    if (!elemFirst) {
Packit Service 9ccfef
	/* printf("totaly equal\n"); */
Packit Service 9ccfef
	return 0;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    for (elemFirst = smiGetFirstElement(firstRow);
Packit Service 9ccfef
	 elemFirst;
Packit Service 9ccfef
	 elemFirst = smiGetNextElement(elemFirst)) {
Packit Service 9ccfef
Packit Service 9ccfef
	for (elemSecond = smiGetFirstElement(secondRow);
Packit Service 9ccfef
	     elemSecond;
Packit Service 9ccfef
	     elemSecond = smiGetNextElement(elemSecond)) {
Packit Service 9ccfef
Packit Service 9ccfef
	    if (cmpSmiNodes(smiGetElementNode(elemFirst),
Packit Service 9ccfef
			    smiGetElementNode(elemSecond)) == 1) {
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
Packit Service 9ccfef
	/* maybe same elements but in different order */
Packit Service 9ccfef
	if (!elemSecond) break;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (!elemFirst) {
Packit Service 9ccfef
	/* printf("Equal\n"); */
Packit Service 9ccfef
	return 1;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    else {
Packit Service 9ccfef
	/* printf("inequal"); */
Packit Service 9ccfef
	return 2;
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algIsIndexElement
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Tests whether a given node is part of the index of a particular
Packit Service 9ccfef
 * table. Returns 1 if the node is an index node and 0 otherwise.
Packit Service 9ccfef
 */
Packit Service 9ccfef
Packit Service 9ccfef
int algIsIndexElement(SmiNode *table, SmiNode *node)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiElement *smiElement;
Packit Service 9ccfef
    SmiNode    *row;
Packit Service 9ccfef
Packit Service 9ccfef
    if (node->nodekind != SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
	return 0;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    row = smiGetFirstChildNode(table);
Packit Service 9ccfef
    if (!row || row->nodekind != SMI_NODEKIND_ROW) {
Packit Service 9ccfef
	return 0;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(row);
Packit Service 9ccfef
	 smiElement;
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
	SmiNode *indexNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
	if (cmpSmiNodes(indexNode, node)) {
Packit Service 9ccfef
	    return 1;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return 0;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/* -------------- main functions ------------------------------------------- */
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCheckForExpandRel
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Checks the given table for an expand relationship to an other table.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * 1. gets the expanded table (father node of smiNode)
Packit Service 9ccfef
 * 2. gets the base table by walking through the elements of the smiNode
Packit Service 9ccfef
 *    starting at the end. The first table found which is different from the
Packit Service 9ccfef
 *    expanded table is the first candidate for the base table.
Packit Service 9ccfef
 * 3. comparing the number of elements in both tables
Packit Service 9ccfef
 *    if the number in the expanded table is greater -> 5.
Packit Service 9ccfef
 *    if the number in the base table is greater     -> 4.
Packit Service 9ccfef
 * 4. getting a second base table candidate :
Packit Service 9ccfef
 *    It is possible that a table expands an other table which is expanded
Packit Service 9ccfef
 *    by this.
Packit Service 9ccfef
 *    Therefore it is hard to track the base table.
Packit Service 9ccfef
 *    - scanning all tables which are different from the expanded table
Packit Service 9ccfef
 *    - the base table must have :
Packit Service 9ccfef
 *         - least elements
Packit Service 9ccfef
 *         - the same elementes must occur as in the expanded table
Packit Service 9ccfef
 * 5. the elements in both tables are checked for equality 
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algCheckForExpandRel(SmiNode *smiNode) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiNode      *tNode;
Packit Service 9ccfef
    SmiNode      *baseTable;
Packit Service 9ccfef
    SmiNode      *expTable;
Packit Service 9ccfef
    SmiElement   *smiElement;
Packit Service 9ccfef
    SmiElement   *findElement;
Packit Service 9ccfef
    unsigned int refcounter;
Packit Service 9ccfef
    unsigned int basecounter;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!smiNode) return;
Packit Service 9ccfef
Packit Service 9ccfef
    expTable = smiGetParentNode(smiNode);  
Packit Service 9ccfef
Packit Service 9ccfef
    /* count the elements in the given table <- father of smiNode */
Packit Service 9ccfef
    refcounter = algCountIndexElements(smiNode);
Packit Service 9ccfef
Packit Service 9ccfef
    /* find the base table <- via the last element which does not refer to 
Packit Service 9ccfef
       the expTable */
Packit Service 9ccfef
    baseTable = NULL;
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(smiNode); 
Packit Service 9ccfef
	 smiElement; 
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {  
Packit Service 9ccfef
	tNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
	tNode = smiGetParentNode(tNode);
Packit Service 9ccfef
	tNode = smiGetParentNode(tNode);
Packit Service 9ccfef
Packit Service 9ccfef
	if (cmpSmiNodes(tNode, expTable) == 1) break;
Packit Service 9ccfef
	
Packit Service 9ccfef
	baseTable = tNode;
Packit Service 9ccfef
    }  
Packit Service 9ccfef
Packit Service 9ccfef
    if (!baseTable) return;
Packit Service 9ccfef
Packit Service 9ccfef
    /* count the elements in the basetable */
Packit Service 9ccfef
    basecounter = algCountIndexElements(smiGetFirstChildNode(baseTable));
Packit Service 9ccfef
Packit Service 9ccfef
    /* are baseTable and expTable identical ? */
Packit Service 9ccfef
    if (basecounter >= refcounter) {
Packit Service 9ccfef
Packit Service 9ccfef
	/* searching for new base table candidate in order to handle multiple
Packit Service 9ccfef
	   indices */
Packit Service 9ccfef
	for (baseTable = smiGetNextNode(baseTable, SMI_NODEKIND_TABLE);
Packit Service 9ccfef
	     baseTable;
Packit Service 9ccfef
	     baseTable = smiGetNextNode(baseTable, SMI_NODEKIND_TABLE)) {
Packit Service 9ccfef
      
Packit Service 9ccfef
	    basecounter = algCountIndexElements(smiGetFirstChildNode(baseTable));
Packit Service 9ccfef
      
Packit Service 9ccfef
	    if (basecounter < refcounter) {
Packit Service 9ccfef
Packit Service 9ccfef
		for (smiElement = smiGetFirstElement(
Packit Service 9ccfef
		    smiGetFirstChildNode(expTable)); 
Packit Service 9ccfef
		     smiElement; 
Packit Service 9ccfef
		     smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
		    tNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
Packit Service 9ccfef
		    /*if (smiGetParentNode(smiGetParentNode(tNode))->name == 
Packit Service 9ccfef
		      expTable->name) break; */
Packit Service 9ccfef
		    if (cmpSmiNodes(smiGetParentNode(smiGetParentNode(tNode)),
Packit Service 9ccfef
				    expTable) == 1) break;
Packit Service 9ccfef
	  
Packit Service 9ccfef
		    for (findElement = smiGetFirstElement(
Packit Service 9ccfef
			smiGetFirstChildNode(baseTable)); 
Packit Service 9ccfef
			 findElement; 
Packit Service 9ccfef
			 findElement = smiGetNextElement(findElement)) {
Packit Service 9ccfef
			if (cmpSmiNodes(tNode, smiGetElementNode(findElement))
Packit Service 9ccfef
			    == 1) break;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
	  
Packit Service 9ccfef
		    if (!findElement) {
Packit Service 9ccfef
			return;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		}	
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    
Packit Service 9ccfef
	if (!baseTable) {
Packit Service 9ccfef
	    return;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(smiGetFirstChildNode(baseTable)); 
Packit Service 9ccfef
	 smiElement; 
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
	tNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
Packit Service 9ccfef
	for (findElement = smiGetFirstElement(smiGetFirstChildNode(expTable)); 
Packit Service 9ccfef
	     findElement; 
Packit Service 9ccfef
	     findElement = smiGetNextElement(findElement)) {
Packit Service 9ccfef
	    if (cmpSmiNodes(tNode, smiGetElementNode(findElement)) == 1)
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    
Packit Service 9ccfef
	if (!findElement) {
Packit Service 9ccfef
	    return;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    algInsertEdge(baseTable, expTable, SMI_INDEX_EXPAND,
Packit Service 9ccfef
		  GRAPH_ENHINDEX_INDEX);  
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCheckForSparseRel
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Checks the given table for a sparse relationship to an other table. 
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Criterias for a sparse relationship :
Packit Service 9ccfef
 *    - same number of index elements in both tables
Packit Service 9ccfef
 *    - the same order of this elements
Packit Service 9ccfef
 * 1. Getting the basetable via the last element in the index of smiNode.
Packit Service 9ccfef
 * 2. comparing the number of elements
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algCheckForSparseRel(SmiNode *smiNode) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiNode      *tNode = NULL;
Packit Service 9ccfef
    SmiNode      *table;
Packit Service 9ccfef
    SmiElement   *smiElement;
Packit Service 9ccfef
    unsigned int basecounter;
Packit Service 9ccfef
Packit Service 9ccfef
    if (!smiNode) return;
Packit Service 9ccfef
Packit Service 9ccfef
    table = smiGetParentNode(smiNode);
Packit Service 9ccfef
Packit Service 9ccfef
    basecounter = algCountIndexElements(smiNode);
Packit Service 9ccfef
Packit Service 9ccfef
    /* getting the basetable via the father node of the last element
Packit Service 9ccfef
       to handle multiple instanceing */
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(smiNode);
Packit Service 9ccfef
	 smiElement; 
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
	tNode = smiGetElementNode(smiElement);    
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (! tNode) {
Packit Service 9ccfef
	return;
Packit Service 9ccfef
    }
Packit Service 9ccfef
    
Packit Service 9ccfef
    tNode = smiGetParentNode(tNode);
Packit Service 9ccfef
    if (equalElements(smiNode, tNode) == 0) {
Packit Service 9ccfef
	algInsertEdge(smiGetParentNode(tNode), smiGetParentNode(smiNode), 
Packit Service 9ccfef
		      SMI_INDEX_SPARSE, GRAPH_ENHINDEX_INDEX);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCheckForReOrderRel
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Checks the given table for a reorder relationship to an other table.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Criterias for reoder relationships :
Packit Service 9ccfef
 *    - same number of elements
Packit Service 9ccfef
 *    - same elements must occur in a different order
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algCheckForReorderRel(SmiNode *smiNode)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiNode   *tNode;
Packit Service 9ccfef
    GraphNode *graphNode;
Packit Service 9ccfef
    
Packit Service 9ccfef
    if (!smiNode) {
Packit Service 9ccfef
	return;
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    for (graphNode = graph->nodes;
Packit Service 9ccfef
	 graphNode;
Packit Service 9ccfef
	 graphNode = graphNode->nextPtr) {	
Packit Service 9ccfef
	tNode = graphNode->smiNode;
Packit Service 9ccfef
	if (tNode->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
	    if (equalElements(smiNode, smiGetFirstChildNode(tNode)) == 1) {
Packit Service 9ccfef
		algInsertEdge(smiGetParentNode(smiNode), tNode,
Packit Service 9ccfef
			      SMI_INDEX_REORDER, GRAPH_ENHINDEX_INDEX);
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGetIndexkind
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Gets the indexkind of the given table. The row object of the table is
Packit Service 9ccfef
 * passed to this function.
Packit Service 9ccfef
 * Therefore three subfunctions are called to get the indexkind. 
Packit Service 9ccfef
 *   - algChechForExpandRel
Packit Service 9ccfef
 *   - algCheckForSparseRel
Packit Service 9ccfef
 *   - algCheckForReOrderRel
Packit Service 9ccfef
 * Look there for further information.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algGetIndexkind(SmiNode *row) 
Packit Service 9ccfef
{
Packit Service 9ccfef
    algCheckForExpandRel(row);
Packit Service 9ccfef
    algCheckForSparseRel(row);
Packit Service 9ccfef
    algCheckForReorderRel(row);
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algLinkTables
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Links the tables of the given module.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 *  1. Getting the tables and the scalars from the given module.
Packit Service 9ccfef
 *  2. Linking the tables :
Packit Service 9ccfef
 *     - AUGMENT no work to do just adding the corresponding edge
Packit Service 9ccfef
 *     - for other relationships the subfunction algGetIndexkind is called
Packit Service 9ccfef
 *       look there for further information  
Packit Service 9ccfef
 */
Packit Service 9ccfef
void algLinkTables() 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode  *tGraphNode;
Packit Service 9ccfef
    SmiNode    *node; 
Packit Service 9ccfef
    SmiNode    *tSmiNode;
Packit Service 9ccfef
Packit Service 9ccfef
    /* linking the tables */
Packit Service 9ccfef
    for (tGraphNode = graph->nodes;
Packit Service 9ccfef
	 tGraphNode;
Packit Service 9ccfef
	 tGraphNode = tGraphNode->nextPtr) {
Packit Service 9ccfef
	node = tGraphNode->smiNode;
Packit Service 9ccfef
Packit Service 9ccfef
	if (node->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
	    node = smiGetFirstChildNode(node);
Packit Service 9ccfef
Packit Service 9ccfef
	    if (node->nodekind == SMI_NODEKIND_ROW) {
Packit Service 9ccfef
Packit Service 9ccfef
		/* get the relationship between the tables and insert
Packit Service 9ccfef
		   the edges */
Packit Service 9ccfef
		if (node->indexkind == SMI_INDEX_INDEX) {
Packit Service 9ccfef
		    algGetIndexkind(node);
Packit Service 9ccfef
		} else {
Packit Service 9ccfef
		    tSmiNode = node;
Packit Service 9ccfef
		    node = smiGetRelatedNode(node);
Packit Service 9ccfef
		    node = smiGetParentNode(node);
Packit Service 9ccfef
		    algInsertEdge(node,
Packit Service 9ccfef
				  smiGetParentNode(tSmiNode), 
Packit Service 9ccfef
				  tSmiNode->indexkind,
Packit Service 9ccfef
				  GRAPH_ENHINDEX_INDEX);	    
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
   if (XPLAIN) {
Packit Service 9ccfef
       printf("--- Second Phase - linking the tables\n\n");
Packit Service 9ccfef
       graphShowEdges(graph);
Packit Service 9ccfef
   } 
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCheckLinksByName
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Reordering the connections by looking at the names.
Packit Service 9ccfef
 * Related objects are linked (if their names are related).
Packit Service 9ccfef
 * Every expand relationship is examined. Therefore number of
Packit Service 9ccfef
 * identical characters at the beginning of the both table names is
Packit Service 9ccfef
 * counted.
Packit Service 9ccfef
 * Then every sparse relationship (only the ending node) is checked if 
Packit Service 9ccfef
 * there is better connection with more identical characters at the beginning.
Packit Service 9ccfef
 * The starting node must be same as in the expand relationship to make sure
Packit Service 9ccfef
 * that there are no unrelated tables are linked.
Packit Service 9ccfef
 * Only legal overlappings lead to a new edge. A illegal overlap is :
Packit Service 9ccfef
 * - when the next character in both strings is a lower case character
Packit Service 9ccfef
 *   because if something like this is detected the two strings are
Packit Service 9ccfef
 *   corresponding in the middle of their names and not at defined points
Packit Service 9ccfef
 *   like suffix or prefix (-> the next character must be upper case or NULL)
Packit Service 9ccfef
 */
Packit Service 9ccfef
void algCheckLinksByName() 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge, *tEdge2, *newEdge;
Packit Service 9ccfef
    char      *start, *end, *end2;
Packit Service 9ccfef
    int       overlap, longestOverlap, i;
Packit Service 9ccfef
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
Packit Service 9ccfef
	if (tEdge->indexkind == SMI_INDEX_EXPAND) {
Packit Service 9ccfef
Packit Service 9ccfef
	    start = tEdge->startNode->smiNode->name;
Packit Service 9ccfef
	    end = tEdge->endNode->smiNode->name;
Packit Service 9ccfef
Packit Service 9ccfef
	    overlap = strpfxlen(start,end);
Packit Service 9ccfef
      
Packit Service 9ccfef
	    /*
Packit Service 9ccfef
	     * looking for better connection with longer overlap
Packit Service 9ccfef
	     * maybe better to traverse the edges with graphGetNextEdgeByNode
Packit Service 9ccfef
	     * using tEdge->startNode
Packit Service 9ccfef
	     */  
Packit Service 9ccfef
	    newEdge = NULL;
Packit Service 9ccfef
	    longestOverlap = overlap;
Packit Service 9ccfef
	    for (tEdge2 = graphGetFirstEdgeByNode(graph,tEdge->startNode);
Packit Service 9ccfef
		 tEdge2;
Packit Service 9ccfef
		 tEdge2 = graphGetNextEdgeByNode(graph, tEdge2,
Packit Service 9ccfef
						 tEdge->startNode)) {
Packit Service 9ccfef
	
Packit Service 9ccfef
		/*
Packit Service 9ccfef
		 * must be a sparse relationship to get a correct new edge
Packit Service 9ccfef
		 */
Packit Service 9ccfef
		if (tEdge2->indexkind == SMI_INDEX_SPARSE) {
Packit Service 9ccfef
		    end2 = tEdge2->endNode->smiNode->name;
Packit Service 9ccfef
	  
Packit Service 9ccfef
		    /*
Packit Service 9ccfef
		     * new overlap longer and different tables ? 
Packit Service 9ccfef
		     */
Packit Service 9ccfef
		    i = strpfxlen(end,end2);
Packit Service 9ccfef
		    if (overlap < i &&
Packit Service 9ccfef
			!cmpSmiNodes(tEdge->endNode->smiNode,
Packit Service 9ccfef
				     tEdge2->endNode->smiNode)) {
Packit Service 9ccfef
			/*
Packit Service 9ccfef
			 * legal overlap ?
Packit Service 9ccfef
			 */
Packit Service 9ccfef
			if (islower((int)end[i]) && islower((int)end2[i])) {
Packit Service 9ccfef
			    break;
Packit Service 9ccfef
			}
Packit Service 9ccfef
Packit Service 9ccfef
			longestOverlap=i;
Packit Service 9ccfef
			newEdge = tEdge2;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
      
Packit Service 9ccfef
	    /* better connection found -> changing the edge */
Packit Service 9ccfef
	    if (newEdge) {
Packit Service 9ccfef
		tEdge->startNode = newEdge->endNode;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	printf("\n--- Third Phase - reordering the connections\n\n");
Packit Service 9ccfef
	graphShowEdges(graph);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algLinkObjectsByNames
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Links Scalars to Tables using the prefix
Packit Service 9ccfef
 * Links Tables to Tables using the prefix
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algLinkObjectsByNames()
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode, *tNode2;
Packit Service 9ccfef
    int       overlap,minoverlap,new;
Packit Service 9ccfef
Packit Service 9ccfef
    /* getting the minimum overlap for all nodes */
Packit Service 9ccfef
    minoverlap = 10000;
Packit Service 9ccfef
    tNode2 = graph->nodes;
Packit Service 9ccfef
    if (tNode2) {
Packit Service 9ccfef
	for (tNode = tNode2->nextPtr; tNode; tNode = tNode->nextPtr) {	
Packit Service 9ccfef
	    minoverlap = min(minoverlap, strpfxlen(tNode->smiNode->name,
Packit Service 9ccfef
						   tNode2->smiNode->name));
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    /*
Packit Service 9ccfef
     * prefix overlap of one is too short to create any usefull edges
Packit Service 9ccfef
     */
Packit Service 9ccfef
    if (minoverlap == 1) return;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {    
Packit Service 9ccfef
	if (!graphGetFirstEdgeByNode(graph, tNode)) {
Packit Service 9ccfef
	    overlap = minoverlap;
Packit Service 9ccfef
Packit Service 9ccfef
	    for (tNode2 = graph->nodes; tNode2; tNode2 = tNode2->nextPtr) {
Packit Service 9ccfef
		if (cmpSmiNodes(tNode->smiNode, tNode2->smiNode)) continue;
Packit Service 9ccfef
		
Packit Service 9ccfef
		new = strpfxlen(tNode->smiNode->name, tNode2->smiNode->name);
Packit Service 9ccfef
		
Packit Service 9ccfef
		if (new >= overlap) {
Packit Service 9ccfef
Packit Service 9ccfef
		    /*
Packit Service 9ccfef
		     * no scalar - scalar edges
Packit Service 9ccfef
		     */
Packit Service 9ccfef
		    if (tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR &&
Packit Service 9ccfef
			tNode2->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit Service 9ccfef
			continue;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
Packit Service 9ccfef
		    /*
Packit Service 9ccfef
		     * is it a legal prefix
Packit Service 9ccfef
		     * (if the next char is NULL || uppercase)
Packit Service 9ccfef
		     */
Packit Service 9ccfef
		    if (tNode->smiNode->name[new] &&
Packit Service 9ccfef
			tNode2->smiNode->name[new]) {
Packit Service 9ccfef
			if (!isupper((int)tNode->smiNode->name[new]) ||
Packit Service 9ccfef
			    !isupper((int)tNode2->smiNode->name[new])) continue;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		    
Packit Service 9ccfef
		    overlap = new;
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
Packit Service 9ccfef
	    if (overlap == minoverlap) continue;
Packit Service 9ccfef
	    
Packit Service 9ccfef
	    new = 0;
Packit Service 9ccfef
	    for (tNode2 = graph->nodes; tNode2; tNode2 = tNode2->nextPtr) {
Packit Service 9ccfef
		if (cmpSmiNodes(tNode->smiNode, tNode2->smiNode)) continue;
Packit Service 9ccfef
Packit Service 9ccfef
		new = strpfxlen(tNode->smiNode->name, tNode2->smiNode->name);
Packit Service 9ccfef
		
Packit Service 9ccfef
		if (new == overlap && new > minoverlap) {
Packit Service 9ccfef
Packit Service 9ccfef
		    /*
Packit Service 9ccfef
		     * a scalar should only be adjacent to one node
Packit Service 9ccfef
		     */
Packit Service 9ccfef
		    if (tNode2->smiNode->nodekind == SMI_NODEKIND_SCALAR &&
Packit Service 9ccfef
			graphGetFirstEdgeByNode(graph,tNode2)) continue;
Packit Service 9ccfef
		    if (tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR &&
Packit Service 9ccfef
			graphGetFirstEdgeByNode(graph,tNode)) continue;    
Packit Service 9ccfef
Packit Service 9ccfef
		    /*
Packit Service 9ccfef
		     * adding only table -> scalar edges
Packit Service 9ccfef
		     */
Packit Service 9ccfef
		    if (tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR &&
Packit Service 9ccfef
			tNode2->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit Service 9ccfef
			continue;
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		    
Packit Service 9ccfef
		    if (tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit Service 9ccfef
			algInsertEdge(tNode2->smiNode, tNode->smiNode,
Packit Service 9ccfef
				      SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
				      GRAPH_ENHINDEX_NAMES);
Packit Service 9ccfef
		    } else {
Packit Service 9ccfef
			algInsertEdge(tNode->smiNode, tNode2->smiNode,
Packit Service 9ccfef
				      SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
				      GRAPH_ENHINDEX_NAMES);
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algGroupScalars
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Grouping the scalars using a common fathernode.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algGroupScalars()
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    int       actGroup, fGroup;
Packit Service 9ccfef
    
Packit Service 9ccfef
    actGroup = 0;
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {	
Packit Service 9ccfef
	if (!graphGetFirstEdgeByNode(graph, tNode) &&
Packit Service 9ccfef
	    tNode->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit Service 9ccfef
	    fGroup = algGetGroupByFatherNode(tNode->smiNode);
Packit Service 9ccfef
	    if (fGroup == 0) {
Packit Service 9ccfef
		tNode->group = ++actGroup;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	    else {
Packit Service 9ccfef
		tNode->group = fGroup; 
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	printf("Scalar Groups : \n");
Packit Service 9ccfef
Packit Service 9ccfef
	if (algGetNumberOfGroups() != 0) {
Packit Service 9ccfef
	    for (actGroup = 1;
Packit Service 9ccfef
		 actGroup <= algGetNumberOfGroups();
Packit Service 9ccfef
		 actGroup++) {
Packit Service 9ccfef
		algPrintGroup(actGroup);
Packit Service 9ccfef
		printf("\n");
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	} else printf("No groups!\n");
Packit Service 9ccfef
	printf("\n");
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algLinkLonelyTables
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Links isolated tables with other tables via the types of the
Packit Service 9ccfef
 * index objects.
Packit Service 9ccfef
 * If no type is found the types are checked via the suffix if they differ
Packit Service 9ccfef
 * only in the range (-OrZero). Therefore the suffix-vector is checked.
Packit Service 9ccfef
 * Basetypes used in SMIv1/v2/ng are sorted out.
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void algLinkLonelyTables()
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiElement *smiElement, *smiElement2 = NULL;
Packit Service 9ccfef
    GraphNode  *tNode, *tNode2;
Packit Service 9ccfef
    int        i;
Packit Service 9ccfef
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (!graphGetFirstEdgeByNode(graph, tNode) &&
Packit Service 9ccfef
	    tNode->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
Packit Service 9ccfef
	    for (smiElement = smiGetFirstElement(
Packit Service 9ccfef
		smiGetFirstChildNode(tNode->smiNode));
Packit Service 9ccfef
		 smiElement;
Packit Service 9ccfef
		 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
Packit Service 9ccfef
		for (tNode2 = graph->nodes;
Packit Service 9ccfef
		     tNode2;
Packit Service 9ccfef
		     tNode2 = tNode2->nextPtr) {
Packit Service 9ccfef
		    if (tNode->smiNode->nodekind == SMI_NODEKIND_TABLE &&
Packit Service 9ccfef
			tNode != tNode2) {
Packit Service 9ccfef
Packit Service 9ccfef
			for (smiElement2 = smiGetFirstElement(
Packit Service 9ccfef
			    smiGetFirstChildNode(tNode2->smiNode));
Packit Service 9ccfef
			     smiElement2;
Packit Service 9ccfef
			     smiElement2 = smiGetNextElement(smiElement2)) {
Packit Service 9ccfef
Packit Service 9ccfef
			    if (strcasecmp(algGetTypeName(
Packit Service 9ccfef
				           smiGetElementNode(smiElement2)),
Packit Service 9ccfef
				       algGetTypeName(
Packit Service 9ccfef
					   smiGetElementNode(smiElement)))
Packit Service 9ccfef
				== 0) {
Packit Service 9ccfef
Packit Service 9ccfef
				if (isBaseType(smiGetElementNode(smiElement))
Packit Service 9ccfef
				    == 1){
Packit Service 9ccfef
				    continue;
Packit Service 9ccfef
				}
Packit Service 9ccfef
				
Packit Service 9ccfef
				graphInsertEdge(graph,tNode2, tNode,
Packit Service 9ccfef
						SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
						GRAPH_ENHINDEX_TYPES);
Packit Service 9ccfef
				break;
Packit Service 9ccfef
			    }
Packit Service 9ccfef
			    else {
Packit Service 9ccfef
				for (i = 0; suffix[i]; i++) {
Packit Service 9ccfef
				    if (strstr(
Packit Service 9ccfef
					algGetTypeName(
Packit Service 9ccfef
					    smiGetElementNode(smiElement)),
Packit Service 9ccfef
					suffix[i])) {
Packit Service 9ccfef
					graphInsertEdge(graph,tNode2,
Packit Service 9ccfef
							tNode,
Packit Service 9ccfef
							SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
							GRAPH_ENHINDEX_TYPES);
Packit Service 9ccfef
					break;
Packit Service 9ccfef
				    }
Packit Service 9ccfef
				}
Packit Service 9ccfef
				
Packit Service 9ccfef
				if (suffix[i]) break;
Packit Service 9ccfef
			    }
Packit Service 9ccfef
			}
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		    if (smiElement2) break;
Packit Service 9ccfef
		}
Packit Service 9ccfef
		if (tNode2) break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
		
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algConnectLonelyNodes
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Connect the isolated nodes (scalars and tables)
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * 1. Trying to link tables via the type of the index objects
Packit Service 9ccfef
 * 2. Trying to link scalars to tables using the names
Packit Service 9ccfef
 * 3. Trying to group scalars which have not been adjacent to any edge.
Packit Service 9ccfef
 */
Packit Service 9ccfef
void algConnectLonelyNodes() 
Packit Service 9ccfef
{
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	printf("\n--- Fourth Phase -  connecting isolated nodes\n\n");
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    algLinkLonelyTables();
Packit Service 9ccfef
Packit Service 9ccfef
    algLinkObjectsByNames();
Packit Service 9ccfef
Packit Service 9ccfef
    algGroupScalars();
Packit Service 9ccfef
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	graphShowEdges(graph);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * Subfunction of algCheckForDependencies
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * change UML-edges to dependecy if possible
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void createDependencies()
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *tEdge;
Packit Service 9ccfef
    int       elemCount;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
	
Packit Service 9ccfef
	if (tEdge->indexkind == SMI_INDEX_UNKNOWN) {
Packit Service 9ccfef
Packit Service 9ccfef
	    if (tEdge->startNode->smiNode->nodekind == SMI_NODEKIND_TABLE &&
Packit Service 9ccfef
		tEdge->endNode->smiNode->nodekind   == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
		
Packit Service 9ccfef
		elemCount = algGetNumberOfRows(tEdge->startNode->smiNode);
Packit Service 9ccfef
		if (elemCount >= 0) tEdge->connection = GRAPH_CON_DEPENDENCY;
Packit Service 9ccfef
		
Packit Service 9ccfef
		elemCount = algGetNumberOfRows(tEdge->endNode->smiNode);
Packit Service 9ccfef
		if (elemCount >= 0) tEdge->connection = GRAPH_CON_DEPENDENCY;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * returns 1 if a new rerouting edge creates a loop and 0 otherwise
Packit Service 9ccfef
 */
Packit Service 9ccfef
static int isloop(GraphEdge *tEdge, SmiNode *depTable)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge *loopEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    for (loopEdge = graphGetFirstEdgeByNode(graph, tEdge->endNode);
Packit Service 9ccfef
	 loopEdge;
Packit Service 9ccfef
	 loopEdge = graphGetNextEdgeByNode(graph,loopEdge,tEdge->endNode)) {
Packit Service 9ccfef
Packit Service 9ccfef
	if ((cmpSmiNodes(loopEdge->startNode->smiNode, depTable)) ||
Packit Service 9ccfef
	    (cmpSmiNodes(loopEdge->endNode->smiNode, depTable) &&
Packit Service 9ccfef
	     (loopEdge != tEdge))) {
Packit Service 9ccfef
	    return 1;
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    return 0;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * subfunction of algCheckForDependency
Packit Service 9ccfef
 */
Packit Service 9ccfef
static void rerouteDependencyEdge(GraphEdge *tEdge)
Packit Service 9ccfef
{
Packit Service 9ccfef
    SmiNode    *startTable, *endTable, *depTable;
Packit Service 9ccfef
    SmiElement *smiElement;
Packit Service 9ccfef
    
Packit Service 9ccfef
    startTable = tEdge->startNode->smiNode;
Packit Service 9ccfef
    endTable = tEdge->endNode->smiNode;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (smiElement = smiGetFirstElement(
Packit Service 9ccfef
	smiGetFirstChildNode(endTable));
Packit Service 9ccfef
	 smiElement;
Packit Service 9ccfef
	 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
	
Packit Service 9ccfef
	/* look only at expanded indices (only present in endTable) */
Packit Service 9ccfef
	if (cmpSmiNodes(endTable, smiGetParentNode(
Packit Service 9ccfef
	    smiGetParentNode(smiGetElementNode(smiElement)))) == 1) {
Packit Service 9ccfef
	    depTable = algFindEqualType(startTable,
Packit Service 9ccfef
					smiGetElementNode(smiElement));
Packit Service 9ccfef
	    
Packit Service 9ccfef
	    /* depTable different to endTable? */
Packit Service 9ccfef
	    if (depTable && !cmpSmiNodes(depTable, endTable)) {
Packit Service 9ccfef
Packit Service 9ccfef
		/* prevent loops */
Packit Service 9ccfef
		if (isloop(tEdge, depTable)) continue;
Packit Service 9ccfef
		
Packit Service 9ccfef
		algInsertEdge(depTable,
Packit Service 9ccfef
			      startTable, SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
			      GRAPH_ENHINDEX_REROUTE);
Packit Service 9ccfef
		break;
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * algCheckForDependency
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * Tries to change connection types from association to dependency by
Packit Service 9ccfef
 * looking at the types.
Packit Service 9ccfef
 *
Packit Service 9ccfef
 * 1. Supporting tables are revealed. Supporting tables consist only
Packit Service 9ccfef
 *    index objects and RowStatus-Objects and/or Storage-Type/Objects.
Packit Service 9ccfef
 * 2. If a supporting table is found the connection type is changed to
Packit Service 9ccfef
 *    dependency.
Packit Service 9ccfef
 * 3. Now the types of the index objects are checked (only in the end-table).
Packit Service 9ccfef
 *    If the same type is found in an other table the start-table is going to
Packit Service 9ccfef
 *    be connected with it (inserting a new edge). 
Packit Service 9ccfef
 *    The end-table is still connected to the start-table.
Packit Service 9ccfef
 */
Packit Service 9ccfef
void algCheckForDependency() 
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphEdge  *tEdge;
Packit Service 9ccfef
Packit Service 9ccfef
    createDependencies();
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit Service 9ccfef
Packit Service 9ccfef
	if (tEdge->connection == GRAPH_CON_DEPENDENCY) {
Packit Service 9ccfef
Packit Service 9ccfef
	    rerouteDependencyEdge(tEdge);
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	printf("\n--- Fifth Phase - checking for dependency relationships\n\n");
Packit Service 9ccfef
	graphShowEdges(graph);
Packit Service 9ccfef
    }
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 *
Packit Service 9ccfef
 */
Packit Service 9ccfef
static SmiNode *algFindTable(SmiNode *node)
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode  *tNode;
Packit Service 9ccfef
    SmiNode    *smiNode;
Packit Service 9ccfef
    SmiElement *smiElement;
Packit Service 9ccfef
    char       *toFind;
Packit Service 9ccfef
    
Packit Service 9ccfef
    if (!node) return NULL;
Packit Service 9ccfef
Packit Service 9ccfef
    toFind = xstrdup(node->name
Packit Service 9ccfef
		     + strpfxlen(node->name, smiGetParentNode(node)->name));
Packit Service 9ccfef
		     
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
	    if (cmpSmiNodes(node, tNode->smiNode)) continue;
Packit Service 9ccfef
	    smiNode = smiGetFirstChildNode(tNode->smiNode);
Packit Service 9ccfef
	    
Packit Service 9ccfef
	    for (smiElement = smiGetFirstElement(smiNode);
Packit Service 9ccfef
		 smiElement;
Packit Service 9ccfef
		 smiElement = smiGetNextElement(smiElement)) {
Packit Service 9ccfef
		smiNode = smiGetElementNode(smiElement);
Packit Service 9ccfef
		if (strstr(smiNode->name, toFind)) {
Packit Service 9ccfef
		    xfree(toFind);
Packit Service 9ccfef
		    return smiGetParentNode(smiGetParentNode(smiNode));
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    xfree(toFind);
Packit Service 9ccfef
    
Packit Service 9ccfef
    return NULL;
Packit Service 9ccfef
}
Packit Service 9ccfef
Packit Service 9ccfef
/*
Packit Service 9ccfef
 * Creates edges based on column-objects pointing to other tables.
Packit Service 9ccfef
 * Column-objects with a substring "Index" are examined.
Packit Service 9ccfef
 */
Packit Service 9ccfef
void algCheckForPointerRels()
Packit Service 9ccfef
{
Packit Service 9ccfef
    GraphNode *tNode;
Packit Service 9ccfef
    SmiModule *module;
Packit Service 9ccfef
    SmiNode   *smiNode = NULL;
Packit Service 9ccfef
    SmiNode   *ppNode, *table;
Packit Service 9ccfef
    int       i;
Packit Service 9ccfef
    
Packit Service 9ccfef
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit Service 9ccfef
	if (tNode->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit Service 9ccfef
Packit Service 9ccfef
	    module  = smiGetNodeModule(tNode->smiNode);
Packit Service 9ccfef
Packit Service 9ccfef
	    for (smiNode = smiGetFirstNode(module, SMI_NODEKIND_COLUMN);
Packit Service 9ccfef
		 smiNode;
Packit Service 9ccfef
		 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COLUMN)) {
Packit Service 9ccfef
		ppNode = smiGetParentNode(smiNode);
Packit Service 9ccfef
		ppNode = smiGetParentNode(ppNode);
Packit Service 9ccfef
	
Packit Service 9ccfef
		if (!algIsIndexElement(tNode->smiNode, smiNode) &&
Packit Service 9ccfef
		    cmpSmiNodes(tNode->smiNode, ppNode)) {
Packit Service 9ccfef
Packit Service 9ccfef
		    for (i = 0; pointer[i]; i++) {
Packit Service 9ccfef
			if (strstr(smiNode->name, pointer[i])) {
Packit Service 9ccfef
			    /* printf("%s \n",smiNode->name); */
Packit Service 9ccfef
			    table = algFindTable(smiNode);
Packit Service 9ccfef
			    if (table) {
Packit Service 9ccfef
				algInsertEdge(table, tNode->smiNode,
Packit Service 9ccfef
					      SMI_INDEX_UNKNOWN,
Packit Service 9ccfef
					      GRAPH_ENHINDEX_POINTER);
Packit Service 9ccfef
			    }
Packit Service 9ccfef
			}
Packit Service 9ccfef
		    }
Packit Service 9ccfef
		}
Packit Service 9ccfef
	    }
Packit Service 9ccfef
	}
Packit Service 9ccfef
    }
Packit Service 9ccfef
Packit Service 9ccfef
    if (XPLAIN) {
Packit Service 9ccfef
	printf("\n--- Sixth Phase - checking for pointer relationships\n\n");
Packit Service 9ccfef
	graphShowEdges(graph);	
Packit Service 9ccfef
    }
Packit Service 9ccfef
}