Blame tools/dump-cm.c

Packit 022b05
/*
Packit 022b05
 * dump-cm.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to dump conceptual models for MIB modules.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 2000 A. Mueller, 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-cm.c 2718 2005-08-24 06:59:15Z sperner $
Packit 022b05
 */
Packit 022b05
Packit 022b05
Packit 022b05
/* 
Packit 022b05
 * -- TO DO --
Packit 022b05
 *
Packit 022b05
 * Berechnungen der UML Diagramme debuggen
Packit 022b05
 *
Packit 022b05
 */
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <stdlib.h>
Packit 022b05
#include <string.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
#ifdef HAVE_WIN_H
Packit 022b05
#include "win.h"
Packit 022b05
#endif
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
#include "rea.h"
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Definitions used by the dia output driver (node layout).
Packit 022b05
 */
Packit 022b05
Packit 022b05
static const float HEADFONTSIZETABLE   = (float)0.51;
Packit 022b05
static const float HEADSPACESIZETABLE  = (float)0.6;
Packit 022b05
static const float ATTRFONTSIZE        = (float)0.48;
Packit 022b05
static const float ATTRSPACESIZE       = (float)2.4;
Packit 022b05
static const float RECTCORRECTION      = (float)0.85;
Packit 022b05
static const float EDGEYSPACING        = (float)2.0;
Packit 022b05
static const float TABLEHEIGHT         = (float)2.6;   /* headline of the table */
Packit 022b05
static const float TABLEELEMHEIGHT     = (float)0.675; /* height of one attribute */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * global dia graph layout
Packit 022b05
 */
Packit 022b05
static const float YSPACING            = (float)3.0;  /* y space between nodes */
Packit 022b05
static const float XSPACING            = (float)4.0;  /* x space between nodes */ 
Packit 022b05
static const float NEWLINEDISTANCE     = (float)40.0; /* length of one line */
Packit 022b05
static const float XOFFSET             = (float)2.0;  /* left upper start of graph */
Packit 022b05
static const float YOFFSET             = (float)5.0;  /* left upper start of graph */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * position of the dia info note 
Packit 022b05
 */
Packit 022b05
static const float XNOTE               = (float)1.0;  /* left upper corner of note */
Packit 022b05
static const float YNOTE               = (float)1.0;  /* left upper corner of note */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Stereotype Name
Packit 022b05
 */
Packit 022b05
static const char* STEREOTYPE          = "smi mib class";
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Property String for index objects
Packit 022b05
 */
Packit 022b05
static const char* INDEXPROPERTY       = " {index}";
Packit 022b05
Packit 022b05
Packit 022b05
/* -------------- main functions ------------------------------------------- */
Packit 022b05
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Creates the graph nodes of the given module
Packit 022b05
 */
Packit 022b05
static void algCreateNodes(SmiModule *module)
Packit 022b05
{
Packit 022b05
    SmiNode *node;
Packit 022b05
    
Packit 022b05
    /* get tables and scalars from the MIB module */
Packit 022b05
    for (node = smiGetFirstNode(module, SMI_NODEKIND_TABLE);
Packit 022b05
	 node;
Packit 022b05
	 node = smiGetNextNode(node, SMI_NODEKIND_TABLE)) {
Packit 022b05
	if (node->status != SMI_STATUS_OBSOLETE) {
Packit 022b05
	    if (!SUPPRESS_DEPRECATED || node->status != SMI_STATUS_DEPRECATED)
Packit 022b05
		graphInsertNode(graph, node);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    for (node = smiGetFirstNode(module, SMI_NODEKIND_SCALAR);
Packit 022b05
	 node;
Packit 022b05
	 node = smiGetNextNode(node, SMI_NODEKIND_SCALAR)) {
Packit 022b05
	if (node->status != SMI_STATUS_OBSOLETE) {
Packit 022b05
	    if (!SUPPRESS_DEPRECATED || node->status != SMI_STATUS_DEPRECATED)
Packit 022b05
		graphInsertNode(graph, node);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/* ------ XML primitives ------                                              */
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void diaPrintXMLHeader()
Packit 022b05
{
Packit 022b05
    printf("\n");
Packit 022b05
    printf("<diagram xmlns:dia=\"http://www.lysator.liu.se/~alla/dia/\">\n");
Packit 022b05
    printf("  <diagramdata>\n");
Packit 022b05
    printf("    <attribute name=\"background\">\n");
Packit 022b05
    printf("      <color val=\"#ffffff\"/>\n");
Packit 022b05
    printf("    </attribute>\n");
Packit 022b05
    printf("    <attribute name=\"paper\">\n");
Packit 022b05
    printf("      <composite type=\"paper\">\n");
Packit 022b05
    printf("        <attribute name=\"name\">\n");
Packit 022b05
    printf("          <string>#A4#</string>\n");
Packit 022b05
    printf("        </attribute>\n");
Packit 022b05
    printf("        <attribute name=\"tmargin\">\n");
Packit 022b05
    printf("         <real val=\"2.82\"/>\n");
Packit 022b05
    printf("       </attribute>\n");
Packit 022b05
    printf("       <attribute name=\"bmargin\">\n");
Packit 022b05
    printf("         <real val=\"2.82\"/>\n");
Packit 022b05
    printf("        </attribute>\n");
Packit 022b05
    printf("       <attribute name=\"lmargin\">\n");
Packit 022b05
    printf("         <real val=\"2.82\"/>\n");
Packit 022b05
    printf("       </attribute>\n");
Packit 022b05
    printf("       <attribute name=\"rmargin\">\n");
Packit 022b05
    printf("         <real val=\"2.82\"/>\n");
Packit 022b05
    printf("       </attribute>\n");
Packit 022b05
    printf("       <attribute name=\"is_portrait\">\n");
Packit 022b05
    printf("         <boolean val=\"true\"/>\n");
Packit 022b05
    printf("       </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"scaling\">\n");
Packit 022b05
    printf("         <real val=\"1\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"fitto\">\n");
Packit 022b05
    printf("        <boolean val=\"false\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("    </composite>\n");
Packit 022b05
    printf("   </attribute>\n");
Packit 022b05
    printf("  </diagramdata>\n");
Packit 022b05
    printf("  <layer name=\"Background\" visible=\"true\">\n");   
Packit 022b05
}
Packit 022b05
Packit 022b05
static void diaPrintXMLClose()
Packit 022b05
{
Packit 022b05
    printf("  </layer>\n");
Packit 022b05
    printf("</diagram>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * prints the type of a given node
Packit 022b05
 */  
Packit 022b05
static void diaPrintXMLType(SmiNode *smiNode, int index)
Packit 022b05
{
Packit 022b05
    printf("          <attribute name=\"type\">\n");
Packit 022b05
    if (index) {
Packit 022b05
	printf("            <string>#%s%s#</string>\n",
Packit 022b05
	       algGetTypeName(smiNode), INDEXPROPERTY);
Packit 022b05
    } else {
Packit 022b05
	printf("            <string>#%s#</string>\n", algGetTypeName(smiNode));
Packit 022b05
    }
Packit 022b05
    printf("          </attribute>\n");    
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * index = 0 -> no index element
Packit 022b05
 * index = 1 -> index element -> printed with "+"
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLAttribute(SmiNode *node, int index)
Packit 022b05
{
Packit 022b05
    printf("        <composite type=\"umlattribute\">\n");
Packit 022b05
    printf("          <attribute name=\"name\">\n");
Packit 022b05
    printf("            <string>#%s#</string>\n", node->name);
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    
Packit 022b05
    diaPrintXMLType(node,index);
Packit 022b05
    
Packit 022b05
    printf("          <attribute name=\"value\">\n");
Packit 022b05
    printf("            <string/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"visibility\">\n");
Packit 022b05
Packit 022b05
    if (node->access == SMI_ACCESS_NOT_ACCESSIBLE) {
Packit 022b05
	printf("            <enum val=\"1\"/>\n");
Packit 022b05
    } else {
Packit 022b05
	printf("            <enum val=\"0\"/>\n");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"abstract\">\n");
Packit 022b05
    printf("            <boolean val=\"false\"/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"class_scope\">\n");
Packit 022b05
    
Packit 022b05
    if (node->nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	printf("            <boolean val=\"true\"/>\n");
Packit 022b05
    } else {
Packit 022b05
	printf("            <boolean val=\"false\"/>\n");	
Packit 022b05
    }
Packit 022b05
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("        </composite>\n");	   
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * prints the related scalars for a given table
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLRelatedScalars(GraphNode *node)
Packit 022b05
{
Packit 022b05
    GraphEdge *tEdge;
Packit 022b05
    
Packit 022b05
    for (tEdge = graphGetFirstEdgeByNode(graph, node);
Packit 022b05
	 tEdge;
Packit 022b05
	 tEdge = graphGetNextEdgeByNode(graph, tEdge, node)) {
Packit 022b05
	if (tEdge->startNode == node  &&
Packit 022b05
	    tEdge->endNode->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	    tEdge->dia.flags |= DIA_PRINT_FLAG;
Packit 022b05
	    tEdge->endNode->dia.flags |= DIA_PRINT_FLAG;
Packit 022b05
Packit 022b05
	    diaPrintXMLAttribute(tEdge->endNode->smiNode,0);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * prints all columns objects of the given node
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLAllColumns(GraphNode *node)
Packit 022b05
{
Packit 022b05
    SmiModule *module  = NULL;
Packit 022b05
    SmiNode   *smiNode = NULL;
Packit 022b05
    SmiNode   *ppNode;
Packit 022b05
Packit 022b05
    module  = smiGetNodeModule(node->smiNode);
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(module, SMI_NODEKIND_COLUMN);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COLUMN)) {
Packit 022b05
	ppNode = smiGetParentNode(smiNode);
Packit 022b05
	ppNode = smiGetParentNode(ppNode);
Packit 022b05
	
Packit 022b05
	if (!algIsIndexElement(node->smiNode, smiNode) &&
Packit 022b05
	    cmpSmiNodes(node->smiNode, ppNode))
Packit 022b05
	    diaPrintXMLAttribute(smiNode, 0);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * adds the index to an augmenting table (row-element)
Packit 022b05
 */
Packit 022b05
static void diaPrintAugmentIndex(GraphNode *tNode)
Packit 022b05
{
Packit 022b05
    GraphEdge  *tEdge;
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
Packit 022b05
    for (tEdge = graphGetFirstEdgeByNode(graph, tNode);
Packit 022b05
	 tEdge;
Packit 022b05
	 tEdge = graphGetNextEdgeByNode(graph, tEdge, tNode)) {
Packit 022b05
	if (tEdge->indexkind == SMI_INDEX_AUGMENT) {
Packit 022b05
	    for (smiElement = smiGetFirstElement(
Packit 022b05
		smiGetFirstChildNode(tEdge->startNode->smiNode));
Packit 022b05
		 smiElement;
Packit 022b05
		 smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
		if (!cmpSmiNodes(tNode->smiNode, tEdge->startNode->smiNode)) {
Packit 022b05
		    diaPrintXMLAttribute(smiGetElementNode(smiElement),1);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
static void diaPrintXMLObject(GraphNode *node, float x, float y)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    
Packit 022b05
    if (!node) return;
Packit 022b05
    if (node->dia.flags & DIA_PRINT_FLAG) return;
Packit 022b05
Packit 022b05
    node->dia.x = x;
Packit 022b05
    node->dia.y = y;
Packit 022b05
    node->dia.flags |= DIA_PRINT_FLAG; /* object is now printed */
Packit 022b05
    
Packit 022b05
    printf("    <object type=\"UML - Class\" version=\"0\" id=\"%s\">\n",
Packit 022b05
	   node->smiNode->name);
Packit 022b05
    printf("      <attribute name=\"obj_pos\">\n");
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n",x,y);
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"obj_bb\">\n");
Packit 022b05
    printf("       <rectangle val=\"0.0,0.0;0.0,0.0\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_corner\">\n");
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n",x,y);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_width\">\n");
Packit 022b05
    printf("       <real val=\"%.2f\"/>\n",node->dia.w);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_height\">\n");
Packit 022b05
    printf("       <real val=\"%.2f\"/>\n",node->dia.h);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"name\">\n");
Packit 022b05
    printf("       <string>#%s#</string>\n",
Packit 022b05
	   smiGetFirstChildNode(node->smiNode)->name);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"stereotype\">\n");
Packit 022b05
    printf("        <string>#%s#</string>\n", STEREOTYPE);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"abstract\">\n");
Packit 022b05
    printf("       <boolean val=\"false\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"suppress_attributes\">\n");
Packit 022b05
    printf("        <boolean val=\"false\"/>\n");    
Packit 022b05
    printf("      </attribute>\n");   
Packit 022b05
    printf("      <attribute name=\"suppress_operations\">\n");
Packit 022b05
    printf("        <boolean val=\"true\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"visible_attributes\">\n");
Packit 022b05
    printf("       <boolean val=\"true\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"visible_operations\">\n");
Packit 022b05
    printf("        <boolean val=\"false\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
Packit 022b05
    printf("     <attribute name=\"attributes\">\n");
Packit 022b05
Packit 022b05
    if (node->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit 022b05
Packit 022b05
	diaPrintXMLRelatedScalars(node);
Packit 022b05
Packit 022b05
	diaPrintAugmentIndex(node);
Packit 022b05
	
Packit 022b05
	for (smiElement = smiGetFirstElement(
Packit 022b05
	    smiGetFirstChildNode(node->smiNode));
Packit 022b05
	     smiElement;
Packit 022b05
	     smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	    diaPrintXMLAttribute(smiGetElementNode(smiElement),1);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (PRINT_DETAILED_ATTR) {
Packit 022b05
	    diaPrintXMLAllColumns(node);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    
Packit 022b05
    printf("     <attribute name=\"operations\"/>\n");
Packit 022b05
    printf("    <attribute name=\"template\">\n");
Packit 022b05
    printf("      <boolean val=\"false\"/>\n");
Packit 022b05
    printf("    </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"templates\"/>\n");
Packit 022b05
    printf("   </object>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * prints a group of scalars denoted by group
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLGroup(int group, float x, float y)
Packit 022b05
{
Packit 022b05
    GraphNode *tNode;
Packit 022b05
Packit 022b05
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit 022b05
	if (tNode->group == group) break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (!tNode) return;
Packit 022b05
    
Packit 022b05
    printf("    <object type=\"UML - Class\" version=\"0\" id=\"%s\">\n",
Packit 022b05
	   smiGetParentNode(tNode->smiNode)->name);
Packit 022b05
    printf("      <attribute name=\"obj_pos\">\n");
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n",x,y);
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"obj_bb\">\n");
Packit 022b05
    printf("       <rectangle val=\"0.0,0.0;0.0,0.0\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_corner\">\n");
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n",x,y);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_width\">\n");
Packit 022b05
    printf("       <real val=\"%.2f\"/>\n",0.0);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"elem_height\">\n");
Packit 022b05
    printf("       <real val=\"%.2f\"/>\n",0.0);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"name\">\n");
Packit 022b05
    printf("       <string>#%s#</string>\n",
Packit 022b05
	   smiGetParentNode(tNode->smiNode)->name);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"stereotype\">\n");
Packit 022b05
    printf("         <string>#%s#</string>\n", STEREOTYPE);
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"abstract\">\n");
Packit 022b05
    printf("       <boolean val=\"false\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"suppress_attributes\">\n");
Packit 022b05
    printf("        <boolean val=\"false\"/>\n");    
Packit 022b05
    printf("      </attribute>\n");   
Packit 022b05
    printf("      <attribute name=\"suppress_operations\">\n");
Packit 022b05
    printf("        <boolean val=\"true\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"visible_attributes\">\n");
Packit 022b05
    printf("       <boolean val=\"true\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"visible_operations\">\n");
Packit 022b05
    printf("        <boolean val=\"false\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
Packit 022b05
    printf("     <attribute name=\"attributes\">\n");
Packit 022b05
Packit 022b05
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit 022b05
	if (tNode->group == group) {
Packit 022b05
	    diaPrintXMLAttribute(tNode->smiNode,0);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    
Packit 022b05
    printf("     <attribute name=\"operations\"/>\n");
Packit 022b05
    printf("    <attribute name=\"template\">\n");
Packit 022b05
    printf("      <boolean val=\"false\"/>\n");
Packit 022b05
    printf("    </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"templates\"/>\n");
Packit 022b05
    printf("   </object>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getRectSX(GraphNode *tNode)
Packit 022b05
{
Packit 022b05
    return (float) (tNode->dia.w / 2.0 + tNode->dia.x - RECTCORRECTION);
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getRectEX(GraphNode *tNode)
Packit 022b05
{
Packit 022b05
    return (float) (tNode->dia.w / 2.0 + tNode->dia.x + RECTCORRECTION);
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getRectSY(GraphNode *tNode)
Packit 022b05
{
Packit 022b05
    return (float) (tNode->dia.y - 2.0 - RECTCORRECTION);
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getRectEY(GraphNode *tNode)
Packit 022b05
{
Packit 022b05
    return (float) (tNode->dia.y - 2.0 + RECTCORRECTION);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static int getConPoint(GraphNode *snode, GraphNode *enode)
Packit 022b05
{
Packit 022b05
    float x1,y1,x2,y2;
Packit 022b05
    int   con = 1;
Packit 022b05
    
Packit 022b05
    x1 = snode->dia.x;
Packit 022b05
    y1 = snode->dia.y;
Packit 022b05
    x2 = enode->dia.x;
Packit 022b05
    y2 = enode->dia.y;    
Packit 022b05
Packit 022b05
    if (x1 == x2 && y1 < y2) con = 6;
Packit 022b05
    if (x1 == x2 && y1 > y1) con = 1;
Packit 022b05
    if (x1 > x2 && y1 == y2) con = 3;
Packit 022b05
    if (x1 < x2 && y1 == y2) con = 4;
Packit 022b05
    if (x1 > x2 && y1 > y2)  con = 0;
Packit 022b05
    if (x1 > x2 && y1 < y2)  con = 5;
Packit 022b05
    if (x1 < x2 && y1 > y2)  con = 2;
Packit 022b05
    if (x1 < x2 && y1 < y2)  con = 7;
Packit 022b05
Packit 022b05
    return con;
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getObjX(GraphNode *node, int con)
Packit 022b05
{
Packit 022b05
    switch (con) {
Packit 022b05
    case 0 :
Packit 022b05
	return node->dia.x;
Packit 022b05
	break;
Packit 022b05
    case 1 :
Packit 022b05
	return (float) (node->dia.w / 2.0 + node->dia.x);
Packit 022b05
	break;
Packit 022b05
    case 2 :
Packit 022b05
	return node->dia.x + node->dia.w;
Packit 022b05
	break;
Packit 022b05
    case 3 :
Packit 022b05
	return node->dia.x;
Packit 022b05
	break;	
Packit 022b05
    case 4 :
Packit 022b05
	return node->dia.x + node->dia.w;
Packit 022b05
	break;
Packit 022b05
    case 5 :
Packit 022b05
	return node->dia.x;
Packit 022b05
	break;	
Packit 022b05
    case 6 :
Packit 022b05
	return (float) (node->dia.w / 2.0 + node->dia.x);
Packit 022b05
	break;
Packit 022b05
    case 7 :
Packit 022b05
	return node->dia.x + node->dia.w;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return 0.0;
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getObjY(GraphNode *node, int con)
Packit 022b05
{
Packit 022b05
    switch (con) {
Packit 022b05
    case 0 :
Packit 022b05
	return node->dia.y;
Packit 022b05
	break;
Packit 022b05
    case 1 :
Packit 022b05
	return node->dia.y;
Packit 022b05
	break;
Packit 022b05
    case 2 :
Packit 022b05
	return node->dia.y;
Packit 022b05
	break;
Packit 022b05
    case 3 :
Packit 022b05
	return (float) (node->dia.y + TABLEHEIGHT / 2.0);
Packit 022b05
	break;	
Packit 022b05
    case 4 :
Packit 022b05
	return (float) (node->dia.y + TABLEHEIGHT / 2.0);
Packit 022b05
	break;
Packit 022b05
    case 5 :
Packit 022b05
	return node->dia.y + node->dia.h;
Packit 022b05
	break;	
Packit 022b05
    case 6 :
Packit 022b05
	return node->dia.y + node->dia.h;
Packit 022b05
	break;
Packit 022b05
    case 7 :
Packit 022b05
	return node->dia.y + node->dia.h;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return 0.0;
Packit 022b05
}
Packit 022b05
Packit 022b05
static float getObjYRel(GraphEdge *edge, int con)
Packit 022b05
{
Packit 022b05
    GraphNode *node, *node2;
Packit 022b05
    float     dist;
Packit 022b05
    
Packit 022b05
    node = edge->startNode;
Packit 022b05
    node2 = edge->endNode;
Packit 022b05
    if (node->dia.y < node2->dia.y) {
Packit 022b05
	dist = ABS(((node->dia.y + node->dia.h) - node2->dia.y ) / 2.0);
Packit 022b05
    } else {
Packit 022b05
	dist = ABS((node->dia.y - (node2->dia.y + node2->dia.h)) / 2.0);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    switch (con) {
Packit 022b05
    case 0 :
Packit 022b05
	return node->dia.y - dist;
Packit 022b05
	break;
Packit 022b05
    case 1 :
Packit 022b05
	return node->dia.y - dist;
Packit 022b05
	break;
Packit 022b05
    case 2 :
Packit 022b05
	return node->dia.y - dist;
Packit 022b05
	break;
Packit 022b05
    case 3 :
Packit 022b05
	return (float) (node->dia.y + TABLEHEIGHT / 2.0);
Packit 022b05
	break;	
Packit 022b05
    case 4 :
Packit 022b05
	return (float) (node->dia.y + TABLEHEIGHT / 2.0);
Packit 022b05
	break;
Packit 022b05
    case 5 :
Packit 022b05
	return node->dia.y + node->dia.h + dist;
Packit 022b05
	break;	
Packit 022b05
    case 6 :
Packit 022b05
	return node->dia.y + node->dia.h + dist;
Packit 022b05
	break;
Packit 022b05
    case 7 :
Packit 022b05
	return node->dia.y + node->dia.h + dist;
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    return 0.0;
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * diaPrintXMLCoordinates
Packit 022b05
 *
Packit 022b05
 * prints and calculates the coordinates of a given edge
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLCoordinates(GraphEdge *tEdge)
Packit 022b05
{
Packit 022b05
    int scon, econ;
Packit 022b05
Packit 022b05
    scon = getConPoint(tEdge->startNode, tEdge->endNode);
Packit 022b05
    econ = getConPoint(tEdge->endNode, tEdge->startNode);
Packit 022b05
    
Packit 022b05
    printf("      <attribute name=\"obj_pos\">\n");
Packit 022b05
    printf("        <point val=\"%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getObjX(tEdge->startNode,scon)
Packit 022b05
	   ,getObjY(tEdge->startNode,scon));	   
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"obj_bb\">\n");
Packit 022b05
    printf("       <rectangle val=\"%.2f,%.2f;%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getRectSX(tEdge->startNode)
Packit 022b05
	   ,getRectSY(tEdge->startNode)
Packit 022b05
	   ,getRectEX(tEdge->startNode)
Packit 022b05
	   ,getRectEY(tEdge->startNode));
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"orth_points\">\n");
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getObjX(tEdge->startNode,scon)
Packit 022b05
	   ,getObjY(tEdge->startNode,scon));	
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getObjX(tEdge->startNode,scon)
Packit 022b05
	   ,getObjYRel(tEdge,scon));
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getObjX(tEdge->endNode,econ)
Packit 022b05
	   ,getObjYRel(tEdge,scon));
Packit 022b05
    printf("       <point val=\"%.2f,%.2f\"/>\n"
Packit 022b05
	   ,getObjX(tEdge->endNode,econ)
Packit 022b05
	   ,getObjY(tEdge->endNode,econ));	
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * diaPrintXMLConPoints
Packit 022b05
 *
Packit 022b05
 * prints the connection points of an edge
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLConPoints(GraphEdge *tEdge)
Packit 022b05
{
Packit 022b05
    int scon, econ;
Packit 022b05
Packit 022b05
    scon = getConPoint(tEdge->startNode, tEdge->endNode);
Packit 022b05
    econ = getConPoint(tEdge->endNode, tEdge->startNode);
Packit 022b05
    
Packit 022b05
    printf("    <connections>\n");
Packit 022b05
    printf("      <connection handle=\"0\" to=\"%s\" connection=\"%d\"/>\n",
Packit 022b05
	   tEdge->startNode->smiNode->name,scon);
Packit 022b05
    printf("      <connection handle=\"1\" to=\"%s\" connection=\"%d\"/>\n",
Packit 022b05
	   tEdge->endNode->smiNode->name, econ);
Packit 022b05
    printf("    </connections>\n");    
Packit 022b05
}
Packit 022b05
Packit 022b05
static void diaPrintXMLDependency(GraphEdge *tEdge)
Packit 022b05
{
Packit 022b05
    if (tEdge->dia.flags & DIA_PRINT_FLAG) return;
Packit 022b05
    tEdge->dia.flags |= DIA_PRINT_FLAG;
Packit 022b05
Packit 022b05
    printf("    
Packit 022b05
	   "version=\"0\" id=\"Depend:%s:%s\">\n",
Packit 022b05
	   tEdge->startNode->smiNode->name,
Packit 022b05
	   tEdge->endNode->smiNode->name);    
Packit 022b05
Packit 022b05
    diaPrintXMLCoordinates(tEdge);
Packit 022b05
    
Packit 022b05
    printf("     <attribute name=\"orth_orient\">\n");
Packit 022b05
    printf("       <enum val=\"1\"/>\n");
Packit 022b05
    printf("       <enum val=\"0\"/>\n");
Packit 022b05
    printf("       <enum val=\"1\"/>\n");
Packit 022b05
    printf("     </attribute>\n");
Packit 022b05
    printf("    <attribute name=\"draw_arrow\">\n");
Packit 022b05
    printf("       <boolean val=\"true\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"name\">\n");
Packit 022b05
    printf("        <string/>\n");
Packit 022b05
    printf("   </attribute>\n");
Packit 022b05
    printf("     <attribute name=\"stereotype\">\n");
Packit 022b05
    printf("      <string/>\n");
Packit 022b05
    printf("    </attribute>\n");
Packit 022b05
Packit 022b05
    diaPrintXMLConPoints(tEdge);
Packit 022b05
    
Packit 022b05
    printf("    </object>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * Aggregation is a special case of the association.
Packit 022b05
 * If aggregate = 1 it is an aggregation if 0 it is an association.
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLAssociation(GraphEdge *tEdge, int aggregate)
Packit 022b05
{
Packit 022b05
    if (tEdge->dia.flags & DIA_PRINT_FLAG) return;
Packit 022b05
    tEdge->dia.flags |= DIA_PRINT_FLAG;
Packit 022b05
    if (aggregate > 1) aggregate = 1;
Packit 022b05
    if (aggregate < 0) aggregate = 0;
Packit 022b05
    
Packit 022b05
    printf("    
Packit 022b05
	   "version=\"0\" id=\"Assoc:%s:%s\">\n",
Packit 022b05
	   tEdge->startNode->smiNode->name,
Packit 022b05
	   tEdge->endNode->smiNode->name);
Packit 022b05
    
Packit 022b05
    diaPrintXMLCoordinates(tEdge);
Packit 022b05
    
Packit 022b05
    printf("      <attribute name=\"orth_orient\">\n");
Packit 022b05
    printf("        <enum val=\"1\"/>\n");
Packit 022b05
    printf("        <enum val=\"0\"/>\n");
Packit 022b05
    printf("        <enum val=\"1\"/>\n");   
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"name\">\n");
Packit 022b05
Packit 022b05
    switch(tEdge->indexkind) {
Packit 022b05
    case SMI_INDEX_UNKNOWN :
Packit 022b05
	switch (tEdge->enhancedindex) {
Packit 022b05
	case GRAPH_ENHINDEX_UNKNOWN :
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_TYPES :
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_NAMES :
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_NOTIFICATION :
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_INDEX :
Packit 022b05
	    /* should not occur - is handled below */
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_REROUTE :
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;
Packit 022b05
	case GRAPH_ENHINDEX_POINTER :
Packit 022b05
	    printf("       <string>#%s#</string>\n","");
Packit 022b05
	    break;	    
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_INDEX :
Packit 022b05
	printf("       <string>#%s#</string>\n","");
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_AUGMENT :
Packit 022b05
	printf("       <string>#%s#</string>\n","augments");
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_SPARSE :
Packit 022b05
	printf("       <string>#%s#</string>\n","sparses");
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_REORDER :
Packit 022b05
	printf("       <string>#%s#</string>\n","reorders");
Packit 022b05
	break;
Packit 022b05
    case SMI_INDEX_EXPAND :
Packit 022b05
	printf("       <string>#%s#</string>\n","expands");
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"direction\">\n");
Packit 022b05
    printf("        <enum val=\"0\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"ends\">\n");
Packit 022b05
    printf("        <composite>\n");
Packit 022b05
    printf("          <attribute name=\"role\">\n");
Packit 022b05
    printf("            <string/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"multiplicity\">\n");
Packit 022b05
    
Packit 022b05
    switch (tEdge->cardinality) {
Packit 022b05
    case GRAPH_CARD_UNKNOWN :
Packit 022b05
	printf("       <string># #</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_ONE :
Packit 022b05
	printf("       <string>#1#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_MANY :
Packit 022b05
	printf("       <string>#1#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ZERO_TO_ONE :
Packit 022b05
	printf("       <string>#0#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ZERO_TO_MANY :
Packit 022b05
	printf("       <string>#0#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_ZERO_OR_ONE :
Packit 022b05
	printf("       <string>#1#</string>\n");
Packit 022b05
	break;		
Packit 022b05
    }
Packit 022b05
   
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"arrow\">\n");
Packit 022b05
    printf("            <boolean val=\"false\"/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"aggregate\">\n");
Packit 022b05
    printf("            <enum val=\"0\"/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("        </composite>\n");
Packit 022b05
    printf("        <composite>\n");
Packit 022b05
    printf("          <attribute name=\"role\">\n");
Packit 022b05
    printf("            <string/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
Packit 022b05
    printf("          <attribute name=\"multiplicity\">\n");
Packit 022b05
Packit 022b05
    switch (tEdge->cardinality) {
Packit 022b05
    case GRAPH_CARD_UNKNOWN :
Packit 022b05
	printf("       <string># #</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_ONE :
Packit 022b05
	printf("       <string>#1#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_MANY :
Packit 022b05
	printf("       <string>#*#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ZERO_TO_ONE :
Packit 022b05
	printf("       <string>#1#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ZERO_TO_MANY :
Packit 022b05
	printf("       <string>#*#</string>\n");
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CARD_ONE_TO_ZERO_OR_ONE :
Packit 022b05
	printf("       <string>#0..1#</string>\n");
Packit 022b05
	break;	
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"arrow\">\n");
Packit 022b05
    printf("            <boolean val=\"false\"/>\n");
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("          <attribute name=\"aggregate\">\n");
Packit 022b05
    printf("            <enum val=\"%d\"/>\n",aggregate);
Packit 022b05
    printf("          </attribute>\n");
Packit 022b05
    printf("        </composite>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
Packit 022b05
    diaPrintXMLConPoints(tEdge);
Packit 022b05
    
Packit 022b05
    printf("    </object>\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
static void diaPrintXMLConnection(GraphEdge *tEdge)
Packit 022b05
{
Packit 022b05
    switch (tEdge->connection) {
Packit 022b05
    case GRAPH_CON_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CON_AGGREGATION :
Packit 022b05
	diaPrintXMLAssociation(tEdge,1);
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CON_DEPENDENCY :
Packit 022b05
	diaPrintXMLDependency(tEdge);
Packit 022b05
	break;
Packit 022b05
    case GRAPH_CON_ASSOCIATION :
Packit 022b05
	diaPrintXMLAssociation(tEdge,0);
Packit 022b05
	break;	    
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * diaPrintXMLInfoNote
Packit 022b05
 *
Packit 022b05
 * Prints an UML note with a short information on it (Modulename and
Packit 022b05
 * smidump version).
Packit 022b05
 */
Packit 022b05
static void diaPrintXMLInfoNote(int modc, SmiModule **modv)
Packit 022b05
{
Packit 022b05
    size_t  length;
Packit 022b05
    float   width;
Packit 022b05
    char   *note;
Packit 022b05
    int	    i;
Packit 022b05
Packit 022b05
    const char *s1 = "Conceptual model of ";
Packit 022b05
    const char *s2 = "- generated by smidump " SMI_VERSION_STRING;
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * Calculate the length of the string...
Packit 022b05
     */
Packit 022b05
    
Packit 022b05
    length = strlen(s1) + strlen(s2) + 1;
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	length += strlen(modv[i]->name) + 1;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /*
Packit 022b05
     * ... before allocating a buffer and putting the string together.
Packit 022b05
     */
Packit 022b05
Packit 022b05
    note = xmalloc(length);
Packit 022b05
    strcpy(note, s1);
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	strcat(note, modv[i]->name);
Packit 022b05
	strcat(note, " ");
Packit 022b05
    }
Packit 022b05
    strcat(note, s2);
Packit 022b05
Packit 022b05
    width = (float)strlen(note) * (float)0.76;	/* don't ask */
Packit 022b05
Packit 022b05
    printf("<object type=\"UML - Note\" version=\"0\" id=\"O0\">\n");
Packit 022b05
    printf("  <attribute name=\"obj_pos\">\n");
Packit 022b05
    printf("    <point val=\"%.2f,%.2f\"/>\n",XNOTE, YNOTE);
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("  <attribute name=\"obj_bb\">\n");
Packit 022b05
    printf("    <rectangle val=\"%.2f,%.2f;%.2f,%.2f\"/>\n",
Packit 022b05
	   XNOTE-0.5, YNOTE-0.5, XNOTE-0.5 + width, YNOTE - 0.5 + 1.7);
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("  <attribute name=\"elem_corner\">\n");
Packit 022b05
    printf("    <point val=\"%.2f,%.2f\"/>\n",XNOTE, YNOTE);
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("  <attribute name=\"elem_width\">\n");
Packit 022b05
    printf("    <real val=\"%.2f\"/>\n", width);
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("  <attribute name=\"elem_height\">\n");
Packit 022b05
    printf("    <real val=\"1.7\"/>\n");
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("  <attribute name=\"text\">\n");
Packit 022b05
    printf("    <composite type=\"text\">\n");
Packit 022b05
    printf("      <attribute name=\"string\">\n");
Packit 022b05
    printf("        <string>#%s#</string>\n", note);
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"font\">\n");
Packit 022b05
    printf("        <font name=\"Courier\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"height\">\n");
Packit 022b05
    printf("        <real val=\"0.8\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"pos\">\n");
Packit 022b05
    printf("        <point val=\"%.2f,%.2f\"/>\n", XNOTE + 0.35, YNOTE + 1.28);
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"color\">\n");
Packit 022b05
    printf("        <color val=\"#000000\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("      <attribute name=\"alignment\">\n");
Packit 022b05
    printf("        <enum val=\"0\"/>\n");
Packit 022b05
    printf("      </attribute>\n");
Packit 022b05
    printf("    </composite>\n");
Packit 022b05
    printf("  </attribute>\n");
Packit 022b05
    printf("</object>\n");
Packit 022b05
Packit 022b05
    xfree(note);
Packit 022b05
}
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * diaCalcSize
Packit 022b05
 *
Packit 022b05
 * Calculates the size of a given node for the UML representation.
Packit 022b05
 */
Packit 022b05
static GraphNode *diaCalcSize(GraphNode *node)
Packit 022b05
{
Packit 022b05
    GraphEdge  *tEdge;
Packit 022b05
    SmiNode    *tNode,*ppNode;
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    SmiModule  *module;
Packit 022b05
Packit 022b05
    if (node->smiNode->nodekind == SMI_NODEKIND_SCALAR) return node;
Packit 022b05
    
Packit 022b05
    node->dia.w = (strlen(node->smiNode->name)+4) * HEADFONTSIZETABLE
Packit 022b05
	+ HEADSPACESIZETABLE;
Packit 022b05
    
Packit 022b05
    node->dia.h = TABLEHEIGHT;
Packit 022b05
    for (smiElement = smiGetFirstElement(
Packit 022b05
	smiGetFirstChildNode(node->smiNode));
Packit 022b05
	 smiElement;
Packit 022b05
	 smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	
Packit 022b05
	tNode = smiGetElementNode(smiElement);
Packit 022b05
	
Packit 022b05
	node->dia.w = max(node->dia.w, (strlen(tNode->name) +
Packit 022b05
					strlen(algGetTypeName(tNode)) +
Packit 022b05
					strlen(INDEXPROPERTY))
Packit 022b05
		      * ATTRFONTSIZE
Packit 022b05
		      + ATTRSPACESIZE);
Packit 022b05
	node->dia.h += TABLEELEMHEIGHT;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (tEdge = graphGetFirstEdgeByNode(graph,node);
Packit 022b05
	 tEdge;
Packit 022b05
	 tEdge = graphGetNextEdgeByNode(graph, tEdge, node)) {
Packit 022b05
	if (tEdge->startNode == node &&
Packit 022b05
	    tEdge->endNode->smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	    node->dia.h += TABLEELEMHEIGHT;
Packit 022b05
	    tNode = tEdge->endNode->smiNode;
Packit 022b05
	    
Packit 022b05
	    node->dia.w = max(node->dia.w, (strlen(tNode->name) +
Packit 022b05
				    strlen(algGetTypeName(tNode)))
Packit 022b05
			  * ATTRFONTSIZE
Packit 022b05
			  + ATTRSPACESIZE);		
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (PRINT_DETAILED_ATTR && node->smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit 022b05
	module  = smiGetNodeModule(node->smiNode);
Packit 022b05
Packit 022b05
	for (tNode = smiGetFirstNode(module, SMI_NODEKIND_COLUMN);
Packit 022b05
	     tNode;
Packit 022b05
	     tNode = smiGetNextNode(tNode, SMI_NODEKIND_COLUMN)) {
Packit 022b05
	    ppNode = smiGetParentNode(tNode);
Packit 022b05
	    ppNode = smiGetParentNode(ppNode);
Packit 022b05
Packit 022b05
	    if (cmpSmiNodes(node->smiNode, ppNode)) {
Packit 022b05
		int len;
Packit 022b05
		char *typeName;
Packit 022b05
Packit 022b05
		typeName = algGetTypeName(tNode);
Packit 022b05
		len = strlen(tNode->name) + (typeName ? strlen(typeName) : 0);
Packit 022b05
		node->dia.h += TABLEELEMHEIGHT;
Packit 022b05
		node->dia.w = max(node->dia.w, len)
Packit 022b05
		    * ATTRFONTSIZE
Packit 022b05
		    + ATTRSPACESIZE;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    return node;
Packit 022b05
}
Packit 022b05
Packit 022b05
static float diaPrintNode(GraphNode *node, float x, float y)
Packit 022b05
{
Packit 022b05
    GraphEdge *tEdge;
Packit 022b05
Packit 022b05
    for (tEdge = graphGetFirstEdgeByNode(graph, node);
Packit 022b05
	 tEdge;
Packit 022b05
	 tEdge = graphGetNextEdgeByNode(graph, tEdge, node)) {
Packit 022b05
	if (! (tEdge->dia.flags & DIA_PRINT_FLAG)) {
Packit 022b05
	    if (node == tEdge->startNode) {
Packit 022b05
		y += tEdge->endNode->dia.h + YSPACING;    
Packit 022b05
		diaPrintXMLObject(tEdge->endNode, x, y);
Packit 022b05
		diaPrintXMLConnection(tEdge);
Packit 022b05
		y = diaPrintNode(tEdge->startNode, x, y);
Packit 022b05
			      /* (x+tEdge->startNode->dia.w+XSPACING),y); */
Packit 022b05
		
Packit 022b05
		y = diaPrintNode(tEdge->endNode,
Packit 022b05
		  (x+tEdge->startNode->dia.w+XSPACING), y);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return y;
Packit 022b05
}
Packit 022b05
Packit 022b05
static void diaPrintXML(int modc, SmiModule **modv)
Packit 022b05
{
Packit 022b05
    GraphNode *tNode;
Packit 022b05
    GraphEdge *tEdge;
Packit 022b05
    float     x,y,ydiff;
Packit 022b05
    int       group;
Packit 022b05
    
Packit 022b05
    diaPrintXMLHeader();
Packit 022b05
Packit 022b05
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {	
Packit 022b05
	tNode = diaCalcSize(tNode);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    diaPrintXMLInfoNote(modc, modv);
Packit 022b05
    
Packit 022b05
    x = XOFFSET;
Packit 022b05
    y = YOFFSET;
Packit 022b05
    ydiff = 0;
Packit 022b05
Packit 022b05
    for (tEdge = graph->edges; tEdge; tEdge = tEdge->nextPtr) {
Packit 022b05
	if (! (tEdge->dia.flags & DIA_PRINT_FLAG)) {
Packit 022b05
	    diaPrintXMLObject(tEdge->startNode, x, y);
Packit 022b05
	    x = x + tEdge->startNode->dia.w + XSPACING;
Packit 022b05
Packit 022b05
	    diaPrintXMLObject(tEdge->endNode, x, y);
Packit 022b05
	    diaPrintXMLConnection(tEdge);
Packit 022b05
	    
Packit 022b05
	    ydiff = tEdge->startNode->dia.h;
Packit 022b05
Packit 022b05
      	    y = diaPrintNode(tEdge->startNode,x,y);
Packit 022b05
	    y = diaPrintNode(tEdge->endNode,x,y);    
Packit 022b05
Packit 022b05
	    y = y + ydiff + YSPACING;
Packit 022b05
	    x = XOFFSET;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    x = XOFFSET;
Packit 022b05
    y += ydiff;
Packit 022b05
    ydiff = 0;
Packit 022b05
    
Packit 022b05
    /* printing singular tables */
Packit 022b05
    for (tNode = graph->nodes; tNode; tNode = tNode->nextPtr) {
Packit 022b05
	if (!graphGetFirstEdgeByNode(graph,tNode) &&
Packit 022b05
	    tNode->smiNode->nodekind != SMI_NODEKIND_SCALAR) {
Packit 022b05
	    diaPrintXMLObject(tNode,x,y);
Packit 022b05
	    
Packit 022b05
	    x += tNode->dia.w + XSPACING;
Packit 022b05
	    ydiff = max(ydiff, tNode->dia.h);
Packit 022b05
	    if (x >= NEWLINEDISTANCE) {
Packit 022b05
		x = XOFFSET;
Packit 022b05
		y += ydiff + YSPACING;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* printing scalar groups */
Packit 022b05
    x = XOFFSET;
Packit 022b05
    y += ydiff + YSPACING;
Packit 022b05
    for (group = 1;
Packit 022b05
	 group <= algGetNumberOfGroups();
Packit 022b05
	 group++) {
Packit 022b05
	diaPrintXMLGroup(group,x,y);
Packit 022b05
	x += 2.0;
Packit 022b05
	y += 2.0;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    diaPrintXMLClose();
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
/* ------------------------------------------------------------------------- */
Packit 022b05
Packit 022b05
static void printModuleNames(int modc, SmiModule **modv)
Packit 022b05
{
Packit 022b05
    int i;
Packit 022b05
    
Packit 022b05
    printf("Conceptual model of: ");
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	printf("%s ", modv[i]->name);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    printf("(generated by smidump " SMI_VERSION_STRING ")\n\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpCm(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    int       i;
Packit 022b05
Packit 022b05
    if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	if (! graph) {
Packit 022b05
	    graph = xmalloc(sizeof(Graph));
Packit 022b05
	    graph->nodes = NULL;
Packit 022b05
	    graph->edges = NULL;
Packit 022b05
	    graph->components = NULL;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    algCreateNodes(modv[i]);
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if (XPLAIN) {
Packit 022b05
	    printModuleNames(modc, modv);
Packit 022b05
	    printf("\n--- First Phase - loading tables and scalars\n\n");
Packit 022b05
	    graphShowNodes(graph);
Packit 022b05
	    printf("\n");
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	algLinkTables();
Packit 022b05
	algCheckLinksByName();
Packit 022b05
	algConnectLonelyNodes();
Packit 022b05
	algCheckForDependency();
Packit 022b05
	algCheckForPointerRels();
Packit 022b05
	
Packit 022b05
	if (!XPLAIN) {
Packit 022b05
	    diaPrintXML(modc, modv);
Packit 022b05
	}
Packit 022b05
	graphExit(graph);
Packit 022b05
	graph = NULL;
Packit 022b05
    } else {
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    if (! graph) {
Packit 022b05
		graph = xmalloc(sizeof(Graph));
Packit 022b05
		graph->nodes = NULL;
Packit 022b05
		graph->edges = NULL;
Packit 022b05
		graph->components = NULL;
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    algCreateNodes(modv[i]);
Packit 022b05
	    
Packit 022b05
	    if (XPLAIN) {
Packit 022b05
		printModuleNames(1, &(modv[i]));
Packit 022b05
		printf("\n--- First Phase - loading tables and scalars\n\n");
Packit 022b05
		graphShowNodes(graph);
Packit 022b05
		printf("\n");
Packit 022b05
	    }
Packit 022b05
	
Packit 022b05
	    algLinkTables();
Packit 022b05
	    algCheckLinksByName();
Packit 022b05
	    algConnectLonelyNodes();
Packit 022b05
	    algCheckForDependency();
Packit 022b05
	    algCheckForPointerRels();
Packit 022b05
	    
Packit 022b05
	    if (!XPLAIN) {
Packit 022b05
		diaPrintXML(1, &(modv[i]));
Packit 022b05
	    }
Packit 022b05
	
Packit 022b05
	    graphExit(graph);
Packit 022b05
	    graph = NULL;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (fflush(stdout) || ferror(stdout)) {
Packit 022b05
	perror("smidump: write error");
Packit 022b05
	exit(1);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
void initCm()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "explain", OPT_FLAG, &XPLAIN, 0,
Packit 022b05
	  "explain what the algorithm does"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"cm",
Packit 022b05
	dumpCm,
Packit 022b05
	SMI_FLAG_NODESCR,
Packit 022b05
	SMIDUMP_DRIVER_CANT_OUTPUT,
Packit 022b05
	"reverse engineered conceptual model",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}