]> granicus.if.org Git - graphviz/commitdiff
Really integrate and turn on aspect ratio code in dot.
authorerg <devnull@localhost>
Fri, 17 Oct 2008 20:31:01 +0000 (20:31 +0000)
committererg <devnull@localhost>
Fri, 17 Oct 2008 20:31:01 +0000 (20:31 +0000)
lib/dotgen/Makefile.am
lib/dotgen/aspect.c
lib/dotgen/dotinit.c
lib/dotgen/dotprocs.h
lib/dotgen/dotsplines.c
lib/dotgen/mincross.c
lib/dotgen/position.c
lib/dotgen/rank.c

index 3c9c2df1d96bc352bc5e39d4eebec7faa5617bda..20971a9d1bb22d956b3b42f0a7bc00d5f5f3262a 100644 (file)
@@ -5,10 +5,13 @@ AM_CPPFLAGS = \
        -I$(top_srcdir) \
         -I$(top_srcdir)/lib/common \
         -I$(top_srcdir)/lib/gvc \
+        -I$(top_srcdir)/lib/ortho \
        -I$(top_srcdir)/lib/graph \
        -I$(top_srcdir)/lib/cdt \
        -I$(top_srcdir)/lib/pathplan
 
+AM_CFLAGS = -DORTHO
+
 if WITH_CGRAPH
 else
 noinst_HEADERS = dot.h dotprocs.h
index f8052665739d768c661bed574020833722718b6d..ed3e2a3ac3aee8aa158367dc511b70c8741c3740 100644 (file)
 
 #include "dot.h"
 
-/********************************************************************************************
-*       CODES BY  MOHAMMAD T. IRFAN
-*********************************************************************************************/
-
-#define DPI 72
-
-/**************************** GLOBAL VARIABLES ***********************/
-double targetAR = 0;
-double currentAR  = 0;
-double combiAR = 0;
-int prevIterations = 0;
-int curIterations = 0;
-/**************************** END OF GLOBAL VARIABLES ****************/
+/*
+ * Author: Mohammad T. Irfan
+ *   Summer, 2008
+ */
 
+/* TODO:
+ *   - Support clusters
+ *   - Support disconnected graphs
+ *   - Provide algorithms for aspect rations < 1
+ */
 
+#define DPI 72
 
-/********************************************************************************************
+/*
  *       NODE GROUPS FOR SAME RANKING
  *       Node group data structure groups nodes together for
  *       MIN, MAX, SOURCE, SINK constraints.
  *       The grouping is based on the union-find data structure and
  *       provides sequential access to the nodes in the same group.
- *********************************************************************************************/
+ */
 
-//data structure for node groups
-typedef struct nodeGroup_t
-{
-  node_t **nodes; 
-  int nNodes;
-  double width, height;
+/* data structure for node groups */
+typedef struct nodeGroup_t {
+    node_t **nodes;
+    int nNodes;
+    double width, height;
 } nodeGroup_t;
 
-nodeGroup_t *nodeGroups;
-int nNodeGroups = 0;
+static nodeGroup_t *nodeGroups;
+static int nNodeGroups = 0;
 
-/***************************************************************************
+/* computeNodeGroups:
  * computeNodeGroups function does the groupings of nodes.   
  * The grouping is based on the union-find data structure.
- ***************************************************************************/
-static void
-computeNodeGroups(graph_t *g)
+ */
+static void computeNodeGroups(graph_t * g)
 {
-  int i;
-  node_t *n;
-
-  nodeGroups = (nodeGroup_t *) malloc(sizeof(nodeGroup_t)*agnnodes(g));
-
-  if (nodeGroups == NULL)
-  {
-      agerr(AGERR, "Memory allocation error in computeNodeGroups function.\n");
-      printf("Memory allocation error for nodeGroups\n");
-  }
-
-  nNodeGroups = 0;
-
-  //initialize node ids. Id of a node is used as an index to the group.
-  for (n = agfstnode(g); n; n = agnxtnode(g,n))
-  {
-    ND_id(n) = -1;
-  }
-
-  for (n = agfstnode(g); n; n = agnxtnode(g,n))
-  {
-    if (ND_UF_size(n) == 0) //no same ranking constraint
-    {
-      nodeGroups[nNodeGroups].nodes = (node_t **) malloc(sizeof(node_t *) * 1);
-      if (nodeGroups[nNodeGroups].nodes == NULL)
-      {
-       agerr(AGERR, "Memory allocation error in computeNodeGroups function.\n");
-       printf("Memory allocation error for nodeGroups[nNodeGroups].nodes\n");
-      }
-      nodeGroups[nNodeGroups].nodes[0] = n;
-      nodeGroups[nNodeGroups].nNodes = 1;
-      nodeGroups[nNodeGroups].width = ND_width(n);
-      nodeGroups[nNodeGroups].height = ND_height(n);
-      
-      ND_id(n) = nNodeGroups;
-      nNodeGroups++;
+    node_t *n;
+
+    nodeGroups = N_GNEW(agnnodes(g), nodeGroup_t);
+
+    nNodeGroups = 0;
+
+    /* initialize node ids. Id of a node is used as an index to the group. */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       ND_id(n) = -1;
     }
-    else //group same ranked nodes
-    {
-      node_t *l = UF_find(n);
-      if (ND_id(l) > -1) //leader is already grouped
-      {
-       int index = ND_id(l);
-       nodeGroups[index].nodes[nodeGroups[index].nNodes++] = n;
-       nodeGroups[index].width += ND_width(n);
-       nodeGroups[index].height = (nodeGroups[index].height < ND_height(n)) ? ND_height(n) : nodeGroups[index].height;
-
-       ND_id(n) = index;
-      }
-      else //create a new group
-      {
-       nodeGroups[nNodeGroups].nodes = (node_t **) malloc(sizeof(node_t *) * ND_UF_size(l));
-       if (nodeGroups[nNodeGroups].nodes == NULL)
-       {
-           agerr(AGERR, "Memory allocation error in computeNodeGroups function.\n");
-           printf("Memory allocation error for nodeGroups[nNodeGroups].nodes\n");
-       }
-       
-       if (l == n) //node n is the leader
-       {
-         nodeGroups[nNodeGroups].nodes[0] = l;
-         nodeGroups[nNodeGroups].nNodes = 1;
-         nodeGroups[nNodeGroups].width = ND_width(l);
-         nodeGroups[nNodeGroups].height = ND_height(l);
-       }
-       else
+
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       if (ND_UF_size(n) == 0) {       /* no same ranking constraint */
+           nodeGroups[nNodeGroups].nodes = NEW(node_t *);
+           nodeGroups[nNodeGroups].nodes[0] = n;
+           nodeGroups[nNodeGroups].nNodes = 1;
+           nodeGroups[nNodeGroups].width = ND_width(n);
+           nodeGroups[nNodeGroups].height = ND_height(n);
+
+           ND_id(n) = nNodeGroups;
+           nNodeGroups++;
+       } else                  /* group same ranked nodes */
        {
-         nodeGroups[nNodeGroups].nodes[0] = l;
-         nodeGroups[nNodeGroups].nodes[1] = n;
-         nodeGroups[nNodeGroups].nNodes = 2;
-         nodeGroups[nNodeGroups].width = ND_width(l) + ND_width(n);
-         nodeGroups[nNodeGroups].height = (ND_height(l) < ND_height(n)) ? ND_height(n) : ND_height(l);
-       }
+           node_t *l = UF_find(n);
+           if (ND_id(l) > -1)  /* leader is already grouped */
+           {
+               int index = ND_id(l);
+               nodeGroups[index].nodes[nodeGroups[index].nNodes++] = n;
+               nodeGroups[index].width += ND_width(n);
+               nodeGroups[index].height =
+                   (nodeGroups[index].height <
+                    ND_height(n)) ? ND_height(n) : nodeGroups[index].
+                   height;
+
+               ND_id(n) = index;
+           } else              /* create a new group */
+           {
+               nodeGroups[nNodeGroups].nodes =
+                   N_NEW(ND_UF_size(l), node_t *);
+
+               if (l == n)     /* node n is the leader */
+               {
+                   nodeGroups[nNodeGroups].nodes[0] = l;
+                   nodeGroups[nNodeGroups].nNodes = 1;
+                   nodeGroups[nNodeGroups].width = ND_width(l);
+                   nodeGroups[nNodeGroups].height = ND_height(l);
+               } else {
+                   nodeGroups[nNodeGroups].nodes[0] = l;
+                   nodeGroups[nNodeGroups].nodes[1] = n;
+                   nodeGroups[nNodeGroups].nNodes = 2;
+                   nodeGroups[nNodeGroups].width =
+                       ND_width(l) + ND_width(n);
+                   nodeGroups[nNodeGroups].height =
+                       (ND_height(l) <
+                        ND_height(n)) ? ND_height(n) : ND_height(l);
+               }
 
-       ND_id(l) = nNodeGroups;
-       ND_id(n) = nNodeGroups;
-       nNodeGroups++;
-      }
+               ND_id(l) = nNodeGroups;
+               ND_id(n) = nNodeGroups;
+               nNodeGroups++;
+           }
+       }
     }
-  }
 
 }
 
-/********************************************************************************************
-*       END OF CODES FOR NODE GROUPS 
-*********************************************************************************************/
-
-
-/********************************************************************************************
-*       Count the number of dummy nodes
-*********************************************************************************************/
+/*
+ *       END OF CODES FOR NODE GROUPS 
+ */
 
-int
-countDummyNodes(graph_t *g)
+/* countDummyNodes:
+ *  Count the number of dummy nodes
+ */
+int countDummyNodes(graph_t * g)
 {
-  int count = 0;
-  node_t *n;
-  edge_t *e;
-
-  //Count dummy nodes
-  for (n = agfstnode(g); n; n = agnxtnode(g, n))
-    for (e = agfstout(g, n); e; e = agnxtout(g, e))
-    {
-      int k;
-      //this loop can be avoided
-      /*for (k = ND_rank(e->tail)+1; k < ND_rank(e->head); k++)
-      {
-       count++;
-       }*/
+    int count = 0;
+    node_t *n;
+    edge_t *e;
 
-      if (ND_rank(e->head) != ND_rank(e->tail)) //flat edges do not have dummy nodes
-       count += abs(ND_rank(e->head) - ND_rank(e->tail)) - 1;   
+    /* Count dummy nodes */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+#ifdef UNUSED
+           /* this loop can be avoided */
+           for (k = ND_rank(e->tail)+1; k < ND_rank(e->head); k++) {
+              count++;
+           }
+#endif
+               /* flat edges do not have dummy nodes */
+           if (ND_rank(e->head) != ND_rank(e->tail))   
+               count += abs(ND_rank(e->head) - ND_rank(e->tail)) - 1;
+       }
     }
-
-  return count;
+    return count;
 }
 
-/********************************************************************************************
-*       FFDH PACKING ALGORITHM TO ACHIEVE TARGET ASPECT RATIO
-*********************************************************************************************/
-
-
-/********************************************************************************************
-*       layerWidthInfo_t: data structure for keeping layer width information
-*       Each layer consists of a number of node groups.
-*********************************************************************************************/
+/*
+ *       FFDH PACKING ALGORITHM TO ACHIEVE TARGET ASPECT RATIO
+ */
 
-typedef struct layerWidthInfo_t
-{
-  int layerNumber;
-  nodeGroup_t **nodeGroupsInLayer;
-  int *removed; // is the node group removed?
-  int nNodeGroupsInLayer;
-  int nDummyNodes;
-  double width;
-  double height;
+/*
+ *  layerWidthInfo_t: data structure for keeping layer width information
+ *  Each layer consists of a number of node groups.
+ */
+typedef struct layerWidthInfo_t {
+    int layerNumber;
+    nodeGroup_t **nodeGroupsInLayer;
+    int *removed;              /* is the node group removed? */
+    int nNodeGroupsInLayer;
+    int nDummyNodes;
+    double width;
+    double height;
 } layerWidthInfo_t;
 
-layerWidthInfo_t *layerWidthInfo = NULL;
-int *sortedLayerIndex;
-int nLayers = 0;
+static layerWidthInfo_t *layerWidthInfo = NULL;
+static int *sortedLayerIndex;
+static int nLayers = 0;
 
-void computeLayerWidths(graph_t *g)
+/* computeLayerWidths:
+ */
+static void computeLayerWidths(graph_t * g)
 {
-  int i;
-  node_t *v;
-  
-  nLayers = 0;
-
-
-  //free previously allocated memory
-
-  if (layerWidthInfo)
-  {
-      for (i=0; i<nNodeGroups; i++) 
-      {
-         if (layerWidthInfo[i].nodeGroupsInLayer)
-         {
-           int j;
-           for (j=0; j<layerWidthInfo[i].nNodeGroupsInLayer; j++)
-           {
-             //if (layerWidthInfo[i].nodeGroupsInLayer[j])
-             //free(layerWidthInfo[i].nodeGroupsInLayer[j]);
+    int i;
+    node_t *v;
+
+    nLayers = 0;
+
+    /* free previously allocated memory */
+    if (layerWidthInfo) {
+       for (i = 0; i < nNodeGroups; i++) {
+           if (layerWidthInfo[i].nodeGroupsInLayer) {
+               int j;
+               for (j = 0; j < layerWidthInfo[i].nNodeGroupsInLayer; j++) {
+                   //if (layerWidthInfo[i].nodeGroupsInLayer[j])
+                   //free(layerWidthInfo[i].nodeGroupsInLayer[j]);
+               }
+               free(layerWidthInfo[i].nodeGroupsInLayer);
            }
-           free(layerWidthInfo[i].nodeGroupsInLayer);
-         }
-         if (layerWidthInfo[i].removed)
-           free(layerWidthInfo[i].removed);
-      }    
-
-      free(layerWidthInfo);
-  }
-
-  //allocate memory
-  //the number of layers can go up to the number of node groups
-  layerWidthInfo = (layerWidthInfo_t *)malloc(sizeof(layerWidthInfo_t)*nNodeGroups);
-
-  if (layerWidthInfo == NULL)
-    {
-      agerr(AGERR, "Memory allocation error in computeLayerWidths function.\n");
-      printf("Memory allocation error for layerWidthInfo\n");
+           if (layerWidthInfo[i].removed)
+               free(layerWidthInfo[i].removed);
+       }
+
+       free(layerWidthInfo);
     }
-  
-  for (i=0; i<nNodeGroups; i++) 
-  {
-    layerWidthInfo[i].nodeGroupsInLayer = (nodeGroup_t **)malloc(sizeof(nodeGroup_t *)*nNodeGroups);
-    if (layerWidthInfo[i].nodeGroupsInLayer == NULL)
-    {
-       agerr(AGERR, "Memory allocation error in computeLayerWidths function.\n");
-       printf("Memory allocation error for layerWidthInfo[i].nodeGroupsInLayer\n");
+    /* allocate memory
+     * the number of layers can go up to the number of node groups
+     */
+    layerWidthInfo = N_NEW(nNodeGroups, layerWidthInfo_t);
+
+    for (i = 0; i < nNodeGroups; i++) {
+       layerWidthInfo[i].nodeGroupsInLayer =
+           N_NEW(nNodeGroups, nodeGroup_t *);
+
+       layerWidthInfo[i].removed = N_NEW(nNodeGroups, int);
+
+       layerWidthInfo[i].layerNumber = i;
+       layerWidthInfo[i].nNodeGroupsInLayer = 0;
+       layerWidthInfo[i].nDummyNodes = 0;
+       layerWidthInfo[i].width = 0.0;
+       layerWidthInfo[i].height = 0.0;
     }
 
-    layerWidthInfo[i].removed = (int *)malloc(sizeof(int)*nNodeGroups);
-    if (layerWidthInfo[i].removed == NULL)
-    {
-      agerr(AGERR, "Memory allocation error in computeLayerWidths function.\n");
-      printf("Memory allocation error for layerWidthInfo[i].removed\n");
-    }
 
-    memset(layerWidthInfo[i].removed, 0, sizeof(int)*nNodeGroups);
-    layerWidthInfo[i].layerNumber = i; 
-    layerWidthInfo[i].nNodeGroupsInLayer = 0;
-    layerWidthInfo[i].nDummyNodes = 0;
-    layerWidthInfo[i].width = 0.0;
-    layerWidthInfo[i].height = 0.0;
-  }
-
-
-  node_t *n;
-  edge_t *e;
-
-  //Count dummy nodes in the layer
-  for (n = agfstnode(g); n; n = agnxtnode(g, n))
-    for (e = agfstout(g, n); e; e = agnxtout(g, e))
-    {
-      int k;
-      
-      //This loop maybe unnecessary, but removing it and using the commented codes next,
-      //gives segmentation fault. I forgot the reason why.
-      for (k = ND_rank(e->tail)+1; k < ND_rank(e->head); k++)
-      {
-       layerWidthInfo[k].nDummyNodes++;
-      }
-       
-      /*if (ND_rank(e->head) != ND_rank(e->tail)) //flat edges do not have dummy nodes 
-       layerWidthInfo[k].nDummyNodes = abs(ND_rank(e->head) - ND_rank(e->tail)) - 1;*/
-    }
+    node_t *n;
+    edge_t *e;
+
+    /* Count dummy nodes in the layer */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n))
+       for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+           int k;
+
+           /* FIX: This loop maybe unnecessary, but removing it and using 
+             * the commented codes next, gives a segmentation fault. I 
+             * forgot the reason why.
+             */
+           for (k = ND_rank(e->tail) + 1; k < ND_rank(e->head); k++) {
+               layerWidthInfo[k].nDummyNodes++;
+           }
+
+#ifdef UNUSED
+           if (ND_rank(e->head) != ND_rank(e->tail))
+               /* flat edges do not have dummy nodes  */
+               layerWidthInfo[k].nDummyNodes = abs(ND_rank(e->head) - ND_rank(e->tail)) - 1;
+#endif
+       }
 
+#ifdef UNUSED
   /*****************************************************************
    * This code is removed. It considers dummy nodes in layer width,
    * which does not give good results in experiments.
    *****************************************************************/
-  
-  /*for (i = 0; i < nNodeGroups; i++)
-  {
-    v = nodeGroups[i].nodes[0];
-    layerWidthInfo[ND_rank(v)].width = (layerWidthInfo[ND_rank(v)].nDummyNodes - 1) * GD_nodesep(g); 
-    }*/
-  
-  //gather the layer information
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    v = nodeGroups[i].nodes[0];
-    if (ND_rank(v)+1 > nLayers) //update the number of layers
-      nLayers = ND_rank(v)+1;
-
-    layerWidthInfo[ND_rank(v)].width += nodeGroups[i].width*DPI + (layerWidthInfo[ND_rank(v)].width > 0) * GD_nodesep(g);
-    if (layerWidthInfo[ND_rank(v)].height < nodeGroups[i].height * DPI)
-      layerWidthInfo[ND_rank(v)].height = nodeGroups[i].height * DPI;
-    layerWidthInfo[ND_rank(v)].nodeGroupsInLayer[layerWidthInfo[ND_rank(v)].nNodeGroupsInLayer] = &nodeGroups[i];
-    layerWidthInfo[ND_rank(v)].nNodeGroupsInLayer++;
-  }  
 
-}
+    for (i = 0; i < nNodeGroups; i++) {
+       v = nodeGroups[i].nodes[0];
+       layerWidthInfo[ND_rank(v)].width = (layerWidthInfo[ND_rank(v)].nDummyNodes - 1) * GD_nodesep(g); 
+       }
+#endif
+
+    /* gather the layer information */
+    for (i = 0; i < nNodeGroups; i++) {
+       v = nodeGroups[i].nodes[0];
+       if (ND_rank(v) + 1 > nLayers)   /* update the number of layers */
+           nLayers = ND_rank(v) + 1;
+
+       layerWidthInfo[ND_rank(v)].width +=
+           nodeGroups[i].width * DPI + (layerWidthInfo[ND_rank(v)].width >
+                                        0) * GD_nodesep(g);
+       if (layerWidthInfo[ND_rank(v)].height < nodeGroups[i].height * DPI)
+           layerWidthInfo[ND_rank(v)].height = nodeGroups[i].height * DPI;
+       layerWidthInfo[ND_rank(v)].
+           nodeGroupsInLayer[layerWidthInfo[ND_rank(v)].
+                             nNodeGroupsInLayer] = &nodeGroups[i];
+       layerWidthInfo[ND_rank(v)].nNodeGroupsInLayer++;
+    }
 
+}
 
-/*****************************************************************
+/* compFunction:
  * Comparison function to be used in qsort.
  * For sorting the layers by nonincreasing width
- *****************************************************************/
-
-static int
-compFunction(const void *a, const void *b)
+ */
+static int compFunction(const void *a, const void *b)
 {
-  int *ind1 = (int *)a;
-  int *ind2 = (int *)b;
+    int *ind1 = (int *) a;
+    int *ind2 = (int *) b;
 
-  return (layerWidthInfo[*ind2].width > layerWidthInfo[*ind1].width) - (layerWidthInfo[*ind2].width < layerWidthInfo[*ind1].width);
+    return (layerWidthInfo[*ind2].width >
+           layerWidthInfo[*ind1].width) - (layerWidthInfo[*ind2].width <
+                                           layerWidthInfo[*ind1].width);
 }
 
-
-/********************************************************************
+/* sortLayers:
  * Sort the layers by width (nonincreasing order)
  * qsort should be replaced by insertion sort for better performance.
  * (layers are "almost" sorted during iterations)
- ********************************************************************/
-
-void sortLayers(graph_t *g)
+ */
+static void sortLayers(graph_t * g)
 {
-  qsort(sortedLayerIndex, agnnodes(g), sizeof(int), compFunction);
+    qsort(sortedLayerIndex, agnnodes(g), sizeof(int), compFunction);
 }
 
-//get the max # of dummy nodes on the incoming edges to a nodeGroup
-static int
-getMaxDummyNodes (nodeGroup_t *ng)
+#ifdef UNUSED
+/* getMaxDummyNodes:
+ * get the max # of dummy nodes on the incoming edges to a nodeGroup
+ */
+static int getMaxDummyNodes(nodeGroup_t * ng)
 {
-  int i, max = 0, cnt = 0;
-  for (i = 0; i < ng->nNodes; i++)
-  {
-    node_t *n = ng->nodes[i];
-    edge_t *e;
-    graph_t *g = n->graph;
-    for (e = agfstin(g,n); e; e = agnxtin(g,e))
-    {
-      cnt += ND_rank(e->head) - ND_rank(e->tail); // it's 1 more than the original count
-      if (ND_rank(e->head) - ND_rank(e->tail) > max)
-       max = ND_rank(e->head) - ND_rank(e->tail);
+    int i, max = 0, cnt = 0;
+    for (i = 0; i < ng->nNodes; i++) {
+       node_t *n = ng->nodes[i];
+       edge_t *e;
+       graph_t *g = n->graph;
+       for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
+           cnt += ND_rank(e->head) - ND_rank(e->tail); // it's 1 more than the original count
+           if (ND_rank(e->head) - ND_rank(e->tail) > max)
+               max = ND_rank(e->head) - ND_rank(e->tail);
+       }
     }
-  }
 
-  return max;
+    return max;
 }
+#endif
 
-//Return the sum of out degrees of the nodes in a node group.
-static int getOutDegree(nodeGroup_t *ng)
+/* getOutDegree:
+ * Return the sum of out degrees of the nodes in a node group.
+ */
+static int getOutDegree(nodeGroup_t * ng)
 {
-  int i, cnt = 0;
-  for (i = 0; i < ng->nNodes; i++)
-  {
-    node_t *n = ng->nodes[i];
-    edge_t *e;
-    graph_t *g = n->graph;
+    int i, cnt = 0;
+    for (i = 0; i < ng->nNodes; i++) {
+       node_t *n = ng->nodes[i];
+       edge_t *e;
+       graph_t *g = n->graph;
 
-    //count outdegree. This loop might be unnecessary.
-    for (e = agfstout(g,n); e; e=agnxtout(g,e))
-    {
-      cnt++;
+       /* count outdegree. This loop might be unnecessary. */
+       for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+           cnt++;
+       }
     }
 
-  }
-
-  return cnt;
+    return cnt;
 }
 
-
-/******************************************************************
+/* compFunction2:
  * Comparison function to be used in qsort.
  * For sorting the node groups by their out degrees (nondecreasing)
- ******************************************************************/
-static int
-compFunction2(const void *a, const void *b)
+ */
+static int compFunction2(const void *a, const void *b)
 {
-  nodeGroup_t **ind1 = (nodeGroup_t **)a, **ind2 = (nodeGroup_t **)b;
+    nodeGroup_t **ind1 = (nodeGroup_t **) a, **ind2 = (nodeGroup_t **) b;
 
-  int cnt1 = getOutDegree(*ind1);
-  int cnt2 = getOutDegree(*ind2);
+    int cnt1 = getOutDegree(*ind1);
+    int cnt2 = getOutDegree(*ind2);
 
-  return (cnt2 < cnt1) - (cnt2 > cnt1);
+    return (cnt2 < cnt1) - (cnt2 > cnt1);
 }
 
-
-/*****************************************************************
+#ifdef UNUSED
+/* compFunction3:
  * Comparison function to be used in qsort.
  * For sorting the node groups by their height & width
- *****************************************************************/
-static int
-compFunction3(const void *a, const void *b)
+ */
+static int compFunction3(const void *a, const void *b)
 {
-  nodeGroup_t **ind1 = (nodeGroup_t **)a, **ind2 = (nodeGroup_t **)b;
-  if ((*ind2)->height == (*ind1)->height)
-    return ((*ind2)->width < (*ind1)->width) - ((*ind2)->width > (*ind1)->width);
+    nodeGroup_t **ind1 = (nodeGroup_t **) a, **ind2 = (nodeGroup_t **) b;
+    if ((*ind2)->height == (*ind1)->height)
+       return ((*ind2)->width < (*ind1)->width) - ((*ind2)->width >
+                                                   (*ind1)->width);
 
-  return ((*ind2)->height < (*ind1)->height) - ((*ind2)->height > (*ind1)->height);
+    return ((*ind2)->height < (*ind1)->height) - ((*ind2)->height >
+                                                 (*ind1)->height);
 }
 
-
 /*****************************************************************
  * The following commented codes are no longer used
  * Originally used in the cocktail tool.
  *****************************************************************/
-/*
-//check if there is any node group in the layer that is not constrained by MIN/MAX/SOURCE/SINK-RANK constraints.
-
-static int
-checkLayerConstraints(layerWidthInfo_t lwi)
+/* checkLayerConstraints:
+ * check if there is any node group in the layer 
+ * that is not constrained by MIN/MAX/SOURCE/SINK-RANK constraints.
+ */
+static int checkLayerConstraints(layerWidthInfo_t lwi)
 {
-  int i;
-  for (i = 0; i < lwi.nNodeGroupsInLayer; i++)
-  {
-    if (lwi.nodeGroupsInLayer[i]->nNodes > 0)
-    {
-      int rtype = ND_ranktype(lwi.nodeGroupsInLayer[i]->nodes[0]);
-      if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK && rtype != SINKRANK)
-       return 1;
+    int i;
+    for (i = 0; i < lwi.nNodeGroupsInLayer; i++) {
+       if (lwi.nodeGroupsInLayer[i]->nNodes > 0) {
+           int rtype = ND_ranktype(lwi.nodeGroupsInLayer[i]->nodes[0]);
+           if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK
+               && rtype != SINKRANK)
+               return 1;
+       }
     }
-  }
 
-  return 0;
+    return 0;
 }
 
-//check if all the node groups in the layer are constrained by MIN/MAX/SOURCE/SINK-RANK constraints
-static int
-checkLayerConstraints(layerWidthInfo_t lwi)
+/* checkLayerConstraints:
+ * check if all the node groups in the layer are 
+ * constrained by MIN/MAX/SOURCE/SINK-RANK constraints
+ */
+static int checkLayerConstraints(layerWidthInfo_t lwi)
 {
-  int i;
-  for (i = 0; i < lwi.nNodeGroupsInLayer; i++)
-  {
-    if (lwi.nodeGroupsInLayer[i]->nNodes > 0)
-    {
-      int rtype = ND_ranktype(lwi.nodeGroupsInLayer[i]->nodes[0]);
-      if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK && rtype != SINKRANK)
-       return 0;
+    int i;
+    for (i = 0; i < lwi.nNodeGroupsInLayer; i++) {
+       if (lwi.nodeGroupsInLayer[i]->nNodes > 0) {
+           int rtype = ND_ranktype(lwi.nodeGroupsInLayer[i]->nodes[0]);
+           if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK
+               && rtype != SINKRANK)
+               return 0;
+       }
     }
-  }
 
-  return 1;
+    return 1;
 }
-*/
-
 
-
-/*****************************************************************
+/* checkNodeGroupConstraints:
  * check if the node group is not constrained by 
  * MIN/MAX/SOURCE/SINK-RANK constraints
  * Only used in the cocktail tool.
- *****************************************************************/
-
-static int
-checkNodeGroupConstraints(nodeGroup_t *ndg)
+ */
+static int checkNodeGroupConstraints(nodeGroup_t * ndg)
 {
-  int i;
-  int rtype = ND_ranktype(ndg->nodes[0]);
+    int i;
+    int rtype = ND_ranktype(ndg->nodes[0]);
 
-  if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK && rtype != SINKRANK)
-    return 1;
+    if (rtype != MINRANK && rtype != MAXRANK && rtype != SOURCERANK
+       && rtype != SINKRANK)
+       return 1;
 
-  return 0;
+    return 0;
 }
 
-
-/*****************************************************************
+/* checkHorizontalEdge:
  * check if there is an edge from ng to a node in 
  * layerWidthInfo[nextLayerIndex].
  * Only used in the cocktail tool.
- *****************************************************************/
-
+ */
 static int
-checkHorizontalEdge(graph_t *g, nodeGroup_t *ng, int nextLayerIndex)
+checkHorizontalEdge(graph_t * g, nodeGroup_t * ng, int nextLayerIndex)
 {
-  int i;
-  edge_t *e;
-  
-  for (i = 0; i < ng->nNodes; i++)
-  {
-    for (e = agfstout(g, ng->nodes[i]); e; e = agnxtout(g, e))
-    {
-      if (layerWidthInfo[nextLayerIndex].layerNumber == ND_rank(e->head))
-       {
-         return 1;
+    int i;
+    edge_t *e;
+
+    for (i = 0; i < ng->nNodes; i++) {
+       for (e = agfstout(g, ng->nodes[i]); e; e = agnxtout(g, e)) {
+           if (layerWidthInfo[nextLayerIndex].layerNumber ==
+               ND_rank(e->head)) {
+               return 1;
+           }
        }
     }
-  }
 
 
-  return 0;
+    return 0;
 }
 
-
-/*****************************************************************
+/* hasMaxOrSinkNodes:
  * check if the the layer lwi has MAX or SINK nodes
  * Only used in the cocktail tool.
- *****************************************************************/
-
-static int
-hasMaxOrSinkNodes(layerWidthInfo_t *lwi)
+ */
+static int hasMaxOrSinkNodes(layerWidthInfo_t * lwi)
 {
-  int i, j;
-
-  for (i = 0; i < lwi->nNodeGroupsInLayer; i++)
-  {
-    if (lwi->removed[i])
-      continue;
-    for (j = 0; j < lwi->nodeGroupsInLayer[i]->nNodes; j++)
-    {
-      if (ND_ranktype(lwi->nodeGroupsInLayer[i]->nodes[j]) == MAXRANK || ND_ranktype(lwi->nodeGroupsInLayer[i]->nodes[j]) == SINKRANK)
-         return 1;
+    int i, j;
+
+    for (i = 0; i < lwi->nNodeGroupsInLayer; i++) {
+       if (lwi->removed[i])
+           continue;
+       for (j = 0; j < lwi->nodeGroupsInLayer[i]->nNodes; j++) {
+           if (ND_ranktype(lwi->nodeGroupsInLayer[i]->nodes[j]) == MAXRANK
+               || ND_ranktype(lwi->nodeGroupsInLayer[i]->nodes[j]) ==
+               SINKRANK)
+               return 1;
+       }
     }
-  }
-  
-  return 0;
+
+    return 0;
 }
 
-/*****************************************************************
+/* reduceMaxWidth:
  * The following function is no longer used.
  * Originally used for FFDH packing heuristic
- *****************************************************************/
-
-//FFDH procedure
-void reduceMaxWidth(graph_t *g)
+ * FFDH procedure
+ */
+static void reduceMaxWidth(graph_t * g)
 {
-  int i;
-  int maxLayerIndex;  // = sortedLayerIndex[0];
-  double nextMaxWidth; // = (nLayers > 1) ? layerWidthInfo[sortedLayerIndex[1]].width : 0;
-  double w = 0;
-  Agnode_t *v;
-
-  for (i=0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1)// || !checkLayerConstraints(layerWidthInfo[sortedLayerIndex[i]]))
-      continue;
-    else
-    {
-      maxLayerIndex = sortedLayerIndex[i];
-      nextMaxWidth = (nLayers > i+1) ? layerWidthInfo[sortedLayerIndex[i+1]].width : 0;
-      break;
+    int i;
+    int maxLayerIndex;         // = sortedLayerIndex[0];
+    double nextMaxWidth;       // = (nLayers > 1) ? layerWidthInfo[sortedLayerIndex[1]].width : 0;
+    double w = 0;
+    Agnode_t *v;
+
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1)        // || !checkLayerConstraints(layerWidthInfo[sortedLayerIndex[i]]))
+           continue;
+       else {
+           maxLayerIndex = sortedLayerIndex[i];
+           nextMaxWidth =
+               (nLayers >
+                i + 1) ? layerWidthInfo[sortedLayerIndex[i +
+                                                         1]].width : 0;
+           break;
+       }
     }
-  }
-
-  if (i == nLayers)
-    return; //reduction of layerwidth is not possible.
-
-
-  //sort the node groups in maxLayerIndex layer by height and then width, nonincreasing
-  qsort(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer, layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer, sizeof(nodeGroup_t *), compFunction2);
-  //printf("ht0 = %lf, ht1 = %lf\n", ND_height(layerWidthInfo[maxLayerIndex].nodes[0]), ND_height(layerWidthInfo[maxLayerIndex].nodes[1]));
-
-
-  if (nextMaxWidth <= layerWidthInfo[maxLayerIndex].width/2 || nextMaxWidth == layerWidthInfo[maxLayerIndex].width)
-    nextMaxWidth = layerWidthInfo[maxLayerIndex].width/2;
-
-  double targetWidth = nextMaxWidth;//layerWidthInfo[maxLayerIndex].width/2;
-  
-  //printf("max = %lf, target = %lf\n", layerWidthInfo[maxLayerIndex].width, targetWidth);//,  w + (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width );
-  //getchar();
-
-  
-  //packing by node demotion
-  int nextLayerIndex = -1;
-  for (i = 0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[i].layerNumber == layerWidthInfo[maxLayerIndex].layerNumber + 1)
-      nextLayerIndex = i;
-  }
-
-  if (nextLayerIndex > -1)
-  {
-    //if (layerWidthInfo[nextLayerIndex].width <= 0.5*layerWidthInfo[maxLayerIndex].width)
-    //{
-      int changed = 0;
-      //demote nodes to the next layer
-      for (i=0; i<layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++)
-      {
-       if (layerWidthInfo[maxLayerIndex].removed[i])
-         continue;
 
-       if (!checkHorizontalEdge(g, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i], nextLayerIndex) && w + layerWidthInfo[nextLayerIndex].width + (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width <= targetWidth )
-       {
-         w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width;
-         changed++;
-
-         int j;
-         nodeGroup_t *ng = layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-
-         layerWidthInfo[maxLayerIndex].removed[i] = 1;
-         layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
-         layerWidthInfo[maxLayerIndex].width -= ng->width;
-         for (j = 0; j < ng->nNodes; j++)
-           ND_rank(ng->nodes[j])++;
-      
-         
-         layerWidthInfo[nextLayerIndex].nodeGroupsInLayer[layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer] = ng;
-         layerWidthInfo[nextLayerIndex].removed[layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer] = 0;
-         layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer++;
-         layerWidthInfo[nextLayerIndex].width += ng->width;
-
-         int jj;
-         for (jj=0; jj<layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer; jj++)
-           {
-             //printf("%s\n", layerWidthInfo[nextLayerIndex].nodeGroupsInLayer[jj]->nodes[0]->name);
-             }
+    if (i == nLayers)
+       return;                 //reduction of layerwidth is not possible.
+
+
+    //sort the node groups in maxLayerIndex layer by height and then width, nonincreasing
+    qsort(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer,
+         layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer,
+         sizeof(nodeGroup_t *), compFunction2);
+    //printf("ht0 = %lf, ht1 = %lf\n", ND_height(layerWidthInfo[maxLayerIndex].nodes[0]), ND_height(layerWidthInfo[maxLayerIndex].nodes[1]));
+
+
+    if (nextMaxWidth <= layerWidthInfo[maxLayerIndex].width / 2
+       || nextMaxWidth == layerWidthInfo[maxLayerIndex].width)
+       nextMaxWidth = layerWidthInfo[maxLayerIndex].width / 2;
+
+    double targetWidth = nextMaxWidth; //layerWidthInfo[maxLayerIndex].width/2;
+
+    //printf("max = %lf, target = %lf\n", layerWidthInfo[maxLayerIndex].width, targetWidth);//,  w + (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width );
+    //getchar();
+
+
+    //packing by node demotion
+    int nextLayerIndex = -1;
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[i].layerNumber ==
+           layerWidthInfo[maxLayerIndex].layerNumber + 1)
+           nextLayerIndex = i;
+    }
+
+    if (nextLayerIndex > -1) {
+       //if (layerWidthInfo[nextLayerIndex].width <= 0.5*layerWidthInfo[maxLayerIndex].width)
+       //{
+       int changed = 0;
+       //demote nodes to the next layer
+       for (i = 0; i < layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer;
+            i++) {
+           if (layerWidthInfo[maxLayerIndex].removed[i])
+               continue;
+
+           if (!checkHorizontalEdge
+               (g, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i],
+                nextLayerIndex)
+               && w + layerWidthInfo[nextLayerIndex].width +
+               (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
+               width <= targetWidth) {
+               w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
+                   width;
+               changed++;
+
+               int j;
+               nodeGroup_t *ng =
+                   layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
+
+               layerWidthInfo[maxLayerIndex].removed[i] = 1;
+               layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
+               layerWidthInfo[maxLayerIndex].width -= ng->width;
+               for (j = 0; j < ng->nNodes; j++)
+                   ND_rank(ng->nodes[j])++;
+
+
+               layerWidthInfo[nextLayerIndex].
+                   nodeGroupsInLayer[layerWidthInfo[nextLayerIndex].
+                                     nNodeGroupsInLayer] = ng;
+               layerWidthInfo[nextLayerIndex].
+                   removed[layerWidthInfo[nextLayerIndex].
+                           nNodeGroupsInLayer] = 0;
+               layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer++;
+               layerWidthInfo[nextLayerIndex].width += ng->width;
+
+               int jj;
+               for (jj = 0;
+                    jj <
+                    layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer;
+                    jj++) {
+                   //printf("%s\n", layerWidthInfo[nextLayerIndex].nodeGroupsInLayer[jj]->nodes[0]->name);
+               }
+           }
+
        }
 
-      }
+       if (changed) {
+           //printf("Demoted %d nodes\n", changed);
+           return;
+       }
+       //}
+    }
+    //packing by creating new layers. Must be commented out if packing by demotion is used
+
+    //going to create a new layer. increase the rank of all higher ranked nodes. (to be modified...)
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       if (ND_rank(v) > layerWidthInfo[maxLayerIndex].layerNumber)     ///////////********  +1
+           ND_rank(v)++;
+    }
+
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[i].layerNumber >
+           layerWidthInfo[maxLayerIndex].layerNumber)
+           layerWidthInfo[i].layerNumber++;
+    }
+
+    //now partition the current layer into two layers (to be modified to support general case of > 2 layers)
+    int flag = 0;              //is a new layer created?
+    int alt = 0;
+    for (i = 0; i < layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++) {
+       if (layerWidthInfo[maxLayerIndex].removed[i])
+           continue;
 
-      if (changed)
+       //nodesep-> only if there are > 1 nodes*******************************
+       if ((w +
+            (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width *
+            DPI + (w > 0) * GD_nodesep(g) <= targetWidth && alt == 0
+            && ND_ranktype(layerWidthInfo[maxLayerIndex].
+                           nodeGroupsInLayer[i]->nodes[0]) != SINKRANK
+            && ND_ranktype(layerWidthInfo[maxLayerIndex].
+                           nodeGroupsInLayer[i]->nodes[0]) != MAXRANK)
+           ||
+           (ND_ranktype
+            (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->
+             nodes[0]) != SINKRANK
+            && ND_ranktype(layerWidthInfo[maxLayerIndex].
+                           nodeGroupsInLayer[i]->nodes[0]) != MAXRANK
+            && hasMaxOrSinkNodes(&layerWidthInfo[maxLayerIndex]))
+           )
+           //&& ND_pinned(layerWidthInfo[maxLayerIndex].nodes[i]) == 0 ) 
        {
-         //printf("Demoted %d nodes\n", changed);
-         return;
+           w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
+               width * DPI + (w > 0) * GD_nodesep(g);
+           alt = 1;
+       } else {
+           int j;
+           nodeGroup_t *ng =
+               layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
+
+           flag = 1;
+
+           layerWidthInfo[maxLayerIndex].removed[i] = 1;
+           layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
+           layerWidthInfo[maxLayerIndex].nDummyNodes++;        /////************** SHOULD BE INCREASED BY THE SUM OF INDEG OF ALL NODES IN GROUP
+           layerWidthInfo[maxLayerIndex].width -=
+               (ng->width * DPI + GD_nodesep(g));
+           for (j = 0; j < ng->nNodes; j++)
+               ND_rank(ng->nodes[j])++;
+
+           //create new layer
+           layerWidthInfo[nLayers].
+               nodeGroupsInLayer[layerWidthInfo[nLayers].
+                                 nNodeGroupsInLayer] = ng;
+           layerWidthInfo[nLayers].nNodeGroupsInLayer++;
+           layerWidthInfo[nLayers].layerNumber = ND_rank(ng->nodes[0]);
+
+           layerWidthInfo[nLayers].width += (ng->width * DPI + (layerWidthInfo[nLayers].nNodeGroupsInLayer > 1) * GD_nodesep(g));      // just add the node widths now. 
+
+           alt = 0;
        }
-   //}
-  }
-  
-  //packing by creating new layers. Must be commented out if packing by demotion is used
-
-  //going to create a new layer. increase the rank of all higher ranked nodes. (to be modified...)
-  for (v = agfstnode(g); v; v = agnxtnode(g,v))
-  {
-    if (ND_rank(v) > layerWidthInfo[maxLayerIndex].layerNumber) ///////////********  +1
-       ND_rank(v)++;
-  }  
-
-  for (i = 0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[i].layerNumber > layerWidthInfo[maxLayerIndex].layerNumber)
-      layerWidthInfo[i].layerNumber++;
-  }
-
-  //now partition the current layer into two layers (to be modified to support general case of > 2 layers)
-  int flag = 0; //is a new layer created?
-  int alt = 0;
-  for (i=0; i<layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++)
-  {
-    if (layerWidthInfo[maxLayerIndex].removed[i])
-       continue;
-
-    //nodesep-> only if there are > 1 nodes*******************************
-    if ( (w + (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*DPI + (w>0)*GD_nodesep(g) <= targetWidth && alt == 0 && ND_ranktype(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->nodes[0]) != SINKRANK && ND_ranktype(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->nodes[0]) != MAXRANK)
-        ||
-        (ND_ranktype(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->nodes[0]) != SINKRANK && ND_ranktype(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->nodes[0]) != MAXRANK && hasMaxOrSinkNodes(&layerWidthInfo[maxLayerIndex]) )
-       )
-      //&& ND_pinned(layerWidthInfo[maxLayerIndex].nodes[i]) == 0 ) 
-    {
-      w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*DPI + (w > 0) * GD_nodesep(g);
-      alt = 1;
-    }
-    else
-    {
-      int j;
-      nodeGroup_t *ng = layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-
-      flag = 1;
-
-      layerWidthInfo[maxLayerIndex].removed[i] = 1;
-      layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
-      layerWidthInfo[maxLayerIndex].nDummyNodes++;     /////************** SHOULD BE INCREASED BY THE SUM OF INDEG OF ALL NODES IN GROUP
-      layerWidthInfo[maxLayerIndex].width -= (ng->width*DPI + GD_nodesep(g));
-      for (j = 0; j < ng->nNodes; j++)
-       ND_rank(ng->nodes[j])++;
-
-      //create new layer
-      layerWidthInfo[nLayers].nodeGroupsInLayer[layerWidthInfo[nLayers].nNodeGroupsInLayer] = ng;
-      layerWidthInfo[nLayers].nNodeGroupsInLayer++;
-      layerWidthInfo[nLayers].layerNumber = ND_rank(ng->nodes[0]);
-      
-      layerWidthInfo[nLayers].width += ( ng->width*DPI + (layerWidthInfo[nLayers].nNodeGroupsInLayer > 1) * GD_nodesep(g) ); // just add the node widths now. 
-
-      alt = 0;
     }
-  }
 
-  if (flag)
-  {
-    //calculate number of dummy nodes
-    node_t *n;
-    edge_t *e;
-    int nDummy = 0;
-    
-    for (n = agfstnode(g); n; n = agnxtnode(g, n))
-      for (e = agfstout(g, n); e; e = agnxtout(g, e))
-      {
-       if ( (ND_rank(e->head) > layerWidthInfo[nLayers].layerNumber && ND_rank(e->tail) < layerWidthInfo[nLayers].layerNumber)
-          ||
-          (ND_rank(e->head) < layerWidthInfo[nLayers].layerNumber && ND_rank(e->tail) > layerWidthInfo[nLayers].layerNumber)
-            )
-         nDummy++;
-      }
-
-    layerWidthInfo[nLayers].nDummyNodes = nDummy;
-    layerWidthInfo[nLayers].width += (layerWidthInfo[nLayers].nDummyNodes - 1) * GD_nodesep(g);
-    nLayers++;
-  }
-
-  else
-  {
-    //undo increment of ranks and layerNumbers.*****************
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-       if (ND_rank(v) > layerWidthInfo[maxLayerIndex].layerNumber+1)
-         ND_rank(v)--;
-    }  
-
-    for (i = 0; i < nLayers; i++)
-    {
-       if (layerWidthInfo[i].layerNumber > layerWidthInfo[maxLayerIndex].layerNumber+1)
-         layerWidthInfo[i].layerNumber--;
+    if (flag) {
+       //calculate number of dummy nodes
+       node_t *n;
+       edge_t *e;
+       int nDummy = 0;
+
+       for (n = agfstnode(g); n; n = agnxtnode(g, n))
+           for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+               if ((ND_rank(e->head) > layerWidthInfo[nLayers].layerNumber
+                    && ND_rank(e->tail) <
+                    layerWidthInfo[nLayers].layerNumber)
+                   || (ND_rank(e->head) <
+                       layerWidthInfo[nLayers].layerNumber
+                       && ND_rank(e->tail) >
+                       layerWidthInfo[nLayers].layerNumber)
+                   )
+                   nDummy++;
+           }
+
+       layerWidthInfo[nLayers].nDummyNodes = nDummy;
+       layerWidthInfo[nLayers].width +=
+           (layerWidthInfo[nLayers].nDummyNodes - 1) * GD_nodesep(g);
+       nLayers++;
     }
-  }
-}
 
+    else {
+       //undo increment of ranks and layerNumbers.*****************
+       for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+           if (ND_rank(v) > layerWidthInfo[maxLayerIndex].layerNumber + 1)
+               ND_rank(v)--;
+       }
 
+       for (i = 0; i < nLayers; i++) {
+           if (layerWidthInfo[i].layerNumber >
+               layerWidthInfo[maxLayerIndex].layerNumber + 1)
+               layerWidthInfo[i].layerNumber--;
+       }
+    }
+}
+#endif
 
-/*****************************************************************
+/* reduceMaxWidth2:
  * This is the main heuristic for partitioning the widest layer.
  * Partitioning is based on outdegrees of nodes.
  * Replace compFunction2 by compFunction3 if you want to partition
  * by node widths and heights.
- *****************************************************************/
-
-//FFDH procedure
-void reduceMaxWidth2(graph_t *g)
+ * FFDH procedure
+ */
+static void reduceMaxWidth2(graph_t * g)
 {
-  int i;
-  int maxLayerIndex;  
-  double nextMaxWidth; 
-  double w = 0;
-  Agnode_t *v, *n;
-  
-  //Find the widest layer. it must have at least 2 nodes.
-  for (i=0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1)
-      continue;
-    else
-    {
-      maxLayerIndex = sortedLayerIndex[i];
-      //get the width of the next widest layer
-      nextMaxWidth = (nLayers > i+1) ? layerWidthInfo[sortedLayerIndex[i+1]].width : 0; 
-      break;
+    int i;
+    int maxLayerIndex;
+    double nextMaxWidth;
+    double w = 0;
+    double targetWidth;
+    int fst;
+    nodeGroup_t *fstNdGrp;
+    int ndem;
+    int p, q;
+    int limit;
+    int rem;
+    int rem2;
+
+
+    /* Find the widest layer. it must have at least 2 nodes. */
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1)
+           continue;
+       else {
+           maxLayerIndex = sortedLayerIndex[i];
+           /* get the width of the next widest layer */
+           nextMaxWidth =
+               (nLayers >
+                i + 1) ? layerWidthInfo[sortedLayerIndex[i +
+                                                         1]].width : 0;
+           break;
+       }
     }
-  }
-
-  if (i == nLayers)
-    return; //reduction of layerwidth is not possible.
-
-  //sort the node groups in maxLayerIndex layer by height and then width, nonincreasing
-  qsort(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer, layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer, sizeof(nodeGroup_t *), compFunction2);
-
-  //printf("ht0 = %lf, ht1 = %lf\n", ND_height(layerWidthInfo[maxLayerIndex].nodes[0]), ND_height(layerWidthInfo[maxLayerIndex].nodes[1]));
-  /*
-  printf("\nSorted nodes in mx layer:\n---------------------------\n");
-  for (i=0; i<layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++)
-    {
-      printf("%s. width=%lf, height=%lf\n", layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->nodes[0]->name, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->width, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->height);
-    }*/
-  
-
-  if (nextMaxWidth <= layerWidthInfo[maxLayerIndex].width/4 || nextMaxWidth >= layerWidthInfo[maxLayerIndex].width*3/4)
-    nextMaxWidth = layerWidthInfo[maxLayerIndex].width/2;
-
-  double targetWidth = nextMaxWidth;//layerWidthInfo[maxLayerIndex].width/2;
-  
-  //now partition the current layer into two or more layers (determined by the ranking algorithm)
-  int flag = 0; //is a new layer created?
-  int alt = 0;
-  int fst = 0;
-  nodeGroup_t  *fstNdGrp;
-  int ndem = 0;
-
-  //initialize w, the width of the widest layer after partitioning
-  w = 0;
-
-  int limit = layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer;
-  int rem = 0;
-  int rem2 = 0;
-
-  for (i=0; i<limit+rem; i++)
-  {
-    if (layerWidthInfo[maxLayerIndex].removed[i])
-    {
-      rem++;
-      continue;
+
+    if (i == nLayers)
+       return;                 /* reduction of layerwidth is not possible. */
+
+    /* sort the node groups in maxLayerIndex layer by height and 
+     * then width, nonincreasing 
+     */
+    qsort(layerWidthInfo[maxLayerIndex].nodeGroupsInLayer,
+         layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer,
+         sizeof(nodeGroup_t *), compFunction2);
+
+#if 0
+    printf("\nSorted nodes in mx layer:\n---------------------------\n");
+    for (i = 0; i < layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++) {
+       printf("%s. width=%lf, height=%lf\n",
+              layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->
+              nodes[0]->name,
+              layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->width,
+              layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->height);
     }
+#endif
 
-    if ( (w + layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->width*DPI + (w>0)*GD_nodesep(g) <= targetWidth)
-        ||
-        !fst
-       )
-    {
-      w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*DPI + (w > 0) * GD_nodesep(g);
-      if (!fst)
-       {
-         fstNdGrp = layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-         fst = 1;
+    if (nextMaxWidth <= layerWidthInfo[maxLayerIndex].width / 4
+       || nextMaxWidth >= layerWidthInfo[maxLayerIndex].width * 3 / 4)
+       nextMaxWidth = layerWidthInfo[maxLayerIndex].width / 2;
+
+    targetWidth = nextMaxWidth;        /* layerWidthInfo[maxLayerIndex].width/2; */
+
+    /* now partition the current layer into two or more 
+     * layers (determined by the ranking algorithm)
+     */
+    fst = 0;
+    ndem = 0;
+    limit = layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer;
+    rem = 0;
+    rem2 = 0;
+
+    /* initialize w, the width of the widest layer after partitioning */
+    w = 0;
+
+    for (i = 0; i < limit + rem; i++) {
+       if (layerWidthInfo[maxLayerIndex].removed[i]) {
+           rem++;
+           continue;
        }
-    }
-    else
-    {
-      int j;
-      nodeGroup_t *ng = layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-
-
-      //The following code corrects w by adding dummy node spacing. It's no longer used
-      /*int l;
-      for (l = 0; l < ng->nNodes; l++)
-      {
-       w += (ND_in(ng->nodes[l]).size - 1) * GD_nodesep(g);
-       }*/
-
-      int p, q;
-      for (p = 0; p < fstNdGrp->nNodes; p++)
-       for (q = 0; q < ng->nNodes; q++)
-         {
-           //printf("Trying to add virtual edge: %s -> %s\n", fstNdGrp->nodes[p]->name, ng->nodes[q]->name);
-           edge_t *ev;
-           int s, cnt = 0;
-
-           //The following code is for deletion of long virtual edges.
-           //It's no longer used.
-
-           /*for (s = ND_in(ng->nodes[q]).size - 1; s >= 0; s--)
-           {
-             ev = ND_in(ng->nodes[q]).list[s];
-             
-             edge_t *et;
-             int fail = 0;
-             cnt =0;
-             
-             for (et = agfstin(g,ev->head); et; et = agnxtin(g,et))
-             {
-               if (et->head == ev->head && et->tail == ev->tail)
-               {
-                 fail = 1;
-                 break;
-               }               
-             }
 
-            if (fail)
-               {
-                 //printf("FAIL DETECTED\n");
-                 continue;
+       if ((w +
+            layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i]->width *
+            DPI + (w > 0) * GD_nodesep(g) <= targetWidth)
+           || !fst) {
+           w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
+               width * DPI + (w > 0) * GD_nodesep(g);
+           if (!fst) {
+               fstNdGrp =
+                   layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
+               fst = 1;
+           }
+       } else {
+           nodeGroup_t *ng =
+               layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
+
+
+#ifdef UNUSED
+           /* The following code corrects w by adding dummy node spacing. 
+            * It's no longer used
+            */
+           int l;
+           for (l = 0; l < ng->nNodes; l++) {
+               w += (ND_in(ng->nodes[l]).size - 1) * GD_nodesep(g);
+           }
+#endif
+
+           for (p = 0; p < fstNdGrp->nNodes; p++)
+               for (q = 0; q < ng->nNodes; q++) {
+                   //printf("Trying to add virtual edge: %s -> %s\n", fstNdGrp->nodes[p]->name, ng->nodes[q]->name);
+
+                   /* The following code is for deletion of long virtual edges.
+                    * It's no longer used.
+                    */
+#ifdef UNUSED
+                   for (s = ND_in(ng->nodes[q]).size - 1; s >= 0; s--) {
+                       ev = ND_in(ng->nodes[q]).list[s];
+
+                       edge_t *et;
+                       int fail = 0;
+                       cnt = 0;
+
+                       for (et = agfstin(g, ev->head); et;
+                            et = agnxtin(g, et)) {
+                           if (et->head == ev->head
+                               && et->tail == ev->tail) {
+                               fail = 1;
+                               break;
+                           }
+                       }
+
+                       if (fail) {
+                           //printf("FAIL DETECTED\n");
+                           continue;
+                       }
+
+
+                       if (ED_edge_type(ev) == VIRTUAL
+                           && ND_rank(ev->head) > ND_rank(ev->tail) + 1) {
+                           //printf("%d. inNode= %s.deleted: %s->%s\n", test++, ng->nodes[q]->name, ev->tail->name, ev->head->name);
+
+                           delete_fast_edge(ev);
+                           free(ev);
+                       }
+                   }
+#endif
+
+                   /* add a new virtual edge */
+                   edge_t *newVEdge =
+                       virtual_edge(fstNdGrp->nodes[p], ng->nodes[q],
+                                    NULL);
+                   ED_edge_type(newVEdge) = VIRTUAL;
+                   ndem++;     /* increase number of node demotions */
                }
-             
-
-            if (ED_edge_type(ev) == VIRTUAL && ND_rank(ev->head) > ND_rank(ev->tail)+1)
-            {
-              //printf("%d. inNode= %s.deleted: %s->%s\n", test++, ng->nodes[q]->name, ev->tail->name, ev->head->name);
-                 
-                 delete_fast_edge(ev);
-                 free(ev);
-            }
-            }*/
-
-           //add a new virtual edge
-           edge_t *newVEdge = virtual_edge(fstNdGrp->nodes[p], ng->nodes[q], NULL);
-           ED_edge_type(newVEdge) = VIRTUAL;
-           ndem++; //increase number of node demotions
-         }
-      
-      //the following code updates the layer width information. The update is not useful in the current version of the heuristic.
-
-      layerWidthInfo[maxLayerIndex].removed[i] = 1;
-      rem2++;
-      layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
-      layerWidthInfo[maxLayerIndex].nDummyNodes++;     /////************** SHOULD BE INCREASED BY THE SUM OF INDEG OF ALL NODES IN GROUP
-      layerWidthInfo[maxLayerIndex].width -= (ng->width*DPI + GD_nodesep(g));
+
+           /* the following code updates the layer width information. The 
+            * update is not useful in the current version of the heuristic.
+            */
+           layerWidthInfo[maxLayerIndex].removed[i] = 1;
+           rem2++;
+           layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
+           /* SHOULD BE INCREASED BY THE SUM OF INDEG OF ALL NODES IN GROUP */
+           layerWidthInfo[maxLayerIndex].nDummyNodes++;
+           layerWidthInfo[maxLayerIndex].width -=
+               (ng->width * DPI + GD_nodesep(g));
+       }
     }
-  }
 }
 
-
-/*****************************************************************
+#ifdef UNUSED
+/* balanceLayers:
  * The following is the layer balancing heuristic.
  * Balance the widths of the layers as much as possible.
  * It's no longer used.
- *****************************************************************/
-
-void balanceLayers(graph_t *g)
+ */
+static void balanceLayers(graph_t * g)
 {
-  int maxLayerIndex, nextLayerIndex, i;
-  double maxWidth, w;
-
-  //get the max width layer number
-
-  for (i=0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1
-       ||
-       layerWidthInfo[sortedLayerIndex[i]].layerNumber+1 == nLayers)
-      continue;
-    else
-    {
-      maxLayerIndex = sortedLayerIndex[i];
-      maxWidth = layerWidthInfo[maxLayerIndex].width;
-      printf("Balancing: maxLayerIndex = %d\n", maxLayerIndex);
-      break;
-    }
-  }
-
-  if (i == nLayers)
-    return; //reduction of layerwidth is not possible.
-
-  //balancing ~~ packing by node demotion
-  nextLayerIndex = -1;
-  for (i = 0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[i].layerNumber == layerWidthInfo[maxLayerIndex].layerNumber + 1)
-    {
-      nextLayerIndex = i;
+    int maxLayerIndex, nextLayerIndex, i;
+    double maxWidth, w;
+
+    //get the max width layer number
+
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[sortedLayerIndex[i]].nNodeGroupsInLayer <= 1
+           ||
+           layerWidthInfo[sortedLayerIndex[i]].layerNumber + 1 == nLayers)
+           continue;
+       else {
+           maxLayerIndex = sortedLayerIndex[i];
+           maxWidth = layerWidthInfo[maxLayerIndex].width;
+           printf("Balancing: maxLayerIndex = %d\n", maxLayerIndex);
+           break;
+       }
     }
-  }
-
-  if (nextLayerIndex > -1)
-  {
-    //if (layerWidthInfo[nextLayerIndex].width <= 0.5*layerWidthInfo[maxLayerIndex].width)
-    //{
-      int changed = 0;
-      w = 0;
-
-      //demote nodes to the next layer
-      for (i=0; i<layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer; i++)
-      {
-       if (layerWidthInfo[maxLayerIndex].removed[i])
-         continue;
 
-       if (!checkHorizontalEdge(g, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i], nextLayerIndex) && layerWidthInfo[nextLayerIndex].width /*+ (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*/ <= layerWidthInfo[maxLayerIndex].width /*- (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*/)
-       {
-         w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width;
-         changed++;
-
-         int j;
-         nodeGroup_t *ng = layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
-
-         layerWidthInfo[maxLayerIndex].removed[i] = 1;
-         layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
-         layerWidthInfo[maxLayerIndex].width -= (ng->width);
-         layerWidthInfo[maxLayerIndex].nDummyNodes++;
-         for (j = 0; j < ng->nNodes; j++)
-           ND_rank(ng->nodes[j])++;
-      
-         
-         layerWidthInfo[nextLayerIndex].nodeGroupsInLayer[layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer] = ng;
-         layerWidthInfo[nextLayerIndex].removed[layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer] = 0;
-         layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer++;
-         layerWidthInfo[nextLayerIndex].width += (ng->width + GD_nodesep(g));
+    if (i == nLayers)
+       return;                 //reduction of layerwidth is not possible.
+
+    //balancing ~~ packing by node demotion
+    nextLayerIndex = -1;
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[i].layerNumber ==
+           layerWidthInfo[maxLayerIndex].layerNumber + 1) {
+           nextLayerIndex = i;
        }
+    }
 
-      }
+    if (nextLayerIndex > -1) {
+       //if (layerWidthInfo[nextLayerIndex].width <= 0.5*layerWidthInfo[maxLayerIndex].width)
+       //{
+       int changed = 0;
+       w = 0;
+
+       //demote nodes to the next layer
+       for (i = 0; i < layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer;
+            i++) {
+           if (layerWidthInfo[maxLayerIndex].removed[i])
+               continue;
+
+           if (!checkHorizontalEdge
+               (g, layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i],
+                nextLayerIndex)
+               && layerWidthInfo[nextLayerIndex].width
+               /*+ (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width */
+               <= layerWidthInfo[maxLayerIndex].width
+               /*- (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->width*/
+               ) {
+               w += (layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i])->
+                   width;
+               changed++;
+
+               int j;
+               nodeGroup_t *ng =
+                   layerWidthInfo[maxLayerIndex].nodeGroupsInLayer[i];
+
+               layerWidthInfo[maxLayerIndex].removed[i] = 1;
+               layerWidthInfo[maxLayerIndex].nNodeGroupsInLayer--;
+               layerWidthInfo[maxLayerIndex].width -= (ng->width);
+               layerWidthInfo[maxLayerIndex].nDummyNodes++;
+               for (j = 0; j < ng->nNodes; j++)
+                   ND_rank(ng->nodes[j])++;
+
+
+               layerWidthInfo[nextLayerIndex].
+                   nodeGroupsInLayer[layerWidthInfo[nextLayerIndex].
+                                     nNodeGroupsInLayer] = ng;
+               layerWidthInfo[nextLayerIndex].
+                   removed[layerWidthInfo[nextLayerIndex].
+                           nNodeGroupsInLayer] = 0;
+               layerWidthInfo[nextLayerIndex].nNodeGroupsInLayer++;
+               layerWidthInfo[nextLayerIndex].width +=
+                   (ng->width + GD_nodesep(g));
+           }
 
-      if (changed)
-       {
-         //printf("Demoted %d nodes\n", changed);
-         return;
        }
-   //}
-  }   
-}
 
+       if (changed) {
+           //printf("Demoted %d nodes\n", changed);
+           return;
+       }
+       //}
+    }
+}
 
-/*****************************************************************
+/* applyPacking:
  * The following is the initial packing heuristic
  * It's no longer used.
- *****************************************************************/
-
-void applyPacking(graph_t *g, double targetAR)
+ */
+static void applyPacking(graph_t * g, double targetAR)
 {
-  int i;
+    int i;
 
-  sortedLayerIndex = (int *)malloc(sizeof(int)*agnnodes(g));
-  if (sortedLayerIndex == NULL)
-    agerr(AGERR, "Memory allocation error in applyPacking function.\n");
+    sortedLayerIndex = N_NEW(agnnodes(g), int);
 
-  for (i=0; i<agnnodes(g); i++)
-  {
-    sortedLayerIndex[i] = i;
-  }
+    for (i = 0; i < agnnodes(g); i++) {
+       sortedLayerIndex[i] = i;
+    }
 
 
-  node_t *v;
+    node_t *v;
 
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-      //printf("%s, rank = %d, ranktype = %d\n", v->name, ND_rank(v), ND_ranktype(v));
-      }
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       //printf("%s, rank = %d, ranktype = %d\n", v->name, ND_rank(v), ND_ranktype(v));
+    }
 
     //GD_nodesep(g) = 0.25;
     //GD_ranksep(g) = 0.25;
     ////////////////////
     //printf("Nodesep = %d, Ranksep = %d\n",GD_nodesep(g), GD_ranksep(g));
-    
-
-    for (i=0; i<1; i++)
-    {
-    //printf("iteration = %d\n----------------------\n", i);
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-       //printf("%s rank = %d\n", v->name, ND_rank(v));
-    }
 
-    computeLayerWidths(g);
-    sortLayers(g);
-    reduceMaxWidth(g);
 
-    //printf("====================\n");
+    for (i = 0; i < 1; i++) {
+       //printf("iteration = %d\n----------------------\n", i);
+       for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+           //printf("%s rank = %d\n", v->name, ND_rank(v));
+       }
+
+       computeLayerWidths(g);
+       sortLayers(g);
+       reduceMaxWidth(g);
+
+       //printf("====================\n");
     }
-   
-  
-  int k;
-
-  for (k = 0; k < nLayers-1; k++)
-  {
-    int cnt = 0, tg;
-    if (layerWidthInfo[k].nNodeGroupsInLayer > 7)
-    {
-    
-      cnt = 0;
-      tg = layerWidthInfo[k].nNodeGroupsInLayer - 7;
-
-      for (i = layerWidthInfo[k].nNodeGroupsInLayer-1; i >=0; i--)
-       {
 
-         if (layerWidthInfo[k].removed[i])
-           continue;
 
-      int j;
-      nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
+    int k;
+
+    for (k = 0; k < nLayers - 1; k++) {
+       int cnt = 0, tg;
+       if (layerWidthInfo[k].nNodeGroupsInLayer > 7) {
+
+           cnt = 0;
+           tg = layerWidthInfo[k].nNodeGroupsInLayer - 7;
+
+           for (i = layerWidthInfo[k].nNodeGroupsInLayer - 1; i >= 0; i--) {
+
+               if (layerWidthInfo[k].removed[i])
+                   continue;
+
+               int j;
+               nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
 
 
-      layerWidthInfo[k].removed[i] = 1;
-      layerWidthInfo[k].nNodeGroupsInLayer--;
-      layerWidthInfo[k].nDummyNodes++;     
-      layerWidthInfo[k].width -= (ng->width*DPI + GD_nodesep(g));
-      for (j = 0; j < ng->nNodes; j++)
-       ND_rank(ng->nodes[j])++;
+               layerWidthInfo[k].removed[i] = 1;
+               layerWidthInfo[k].nNodeGroupsInLayer--;
+               layerWidthInfo[k].nDummyNodes++;
+               layerWidthInfo[k].width -=
+                   (ng->width * DPI + GD_nodesep(g));
+               for (j = 0; j < ng->nNodes; j++)
+                   ND_rank(ng->nodes[j])++;
 
-      //create new layer
-      layerWidthInfo[k+1].nodeGroupsInLayer[layerWidthInfo[k+1].nNodeGroupsInLayer] = ng;
-      layerWidthInfo[k+1].nNodeGroupsInLayer++;
-      //layerWidthInfo[k+1].layerNumber = ND_rank(ng->nodes[0]);
-      
-      //layerWidthInfo[k+1].width += ( ng->width*DPI + (layerWidthInfo[nLayers].nNodeGroupsInLayer > 1) * GD_nodesep(g) ); // just add the node widths now. 
+               //create new layer
+               layerWidthInfo[k +
+                              1].nodeGroupsInLayer[layerWidthInfo[k +
+                                                                  1].
+                                                   nNodeGroupsInLayer] =
+                   ng;
+               layerWidthInfo[k + 1].nNodeGroupsInLayer++;
+               //layerWidthInfo[k+1].layerNumber = ND_rank(ng->nodes[0]);
 
-      cnt++;
-      
-      if (cnt == tg)
-       break;
+               //layerWidthInfo[k+1].width += ( ng->width*DPI + (layerWidthInfo[nLayers].nNodeGroupsInLayer > 1) * GD_nodesep(g) ); // just add the node widths now. 
 
+               cnt++;
+
+               if (cnt == tg)
+                   break;
+
+           }
        }
     }
-    }
-  
+
     //calcualte the max width
     int maxW = 0;
     int nNodeG = 0, l, nDummy = 0;
     int index;
 
-    for (k=0; k<nLayers; k++)
-      {
+    for (k = 0; k < nLayers; k++) {
        //printf("Layer#=%d, #dumNd=%d, width=%0.1lf, node=%s\n", layerWidthInfo[k].layerNumber, layerWidthInfo[k].nDummyNodes, layerWidthInfo[k].width,
        // layerWidthInfo[k].nodeGroupsInLayer[0]->nodes[0]->name);
-       if (layerWidthInfo[k].width > maxW)// && layerWidthInfo[k].nNodeGroupsInLayer > 0)
-         {
+       if (layerWidthInfo[k].width > maxW)     // && layerWidthInfo[k].nNodeGroupsInLayer > 0)
+       {
            maxW = layerWidthInfo[k].width;
            nNodeG = layerWidthInfo[k].nNodeGroupsInLayer;
            l = layerWidthInfo[k].layerNumber;
            nDummy = layerWidthInfo[k].nDummyNodes;
            index = k;
-         }
-      }
+       }
+    }
     //printf("Ht=%d, MxW=%d, #ndGr=%d, #dumNd=%d, lyr#=%d, 1stNd=%s\n", (nLayers-1)*DPI, maxW, nNodeG, nDummy, l, layerWidthInfo[index].nodeGroupsInLayer[0]->nodes[0]->name);
 
     // printf("Finally...\n------------------\n");
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-      //printf("%s, rank = %d, ranktype = %d\n", v->name, ND_rank(v), ND_ranktype(v));
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       //printf("%s, rank = %d, ranktype = %d\n", v->name, ND_rank(v), ND_ranktype(v));
     }
 
 }
+#endif
 
-
-
-
-/*****************************************************************
+/* applyPacking2:
  * The following is the packing heuristic for wide layout.
- *****************************************************************/
-
-void applyPacking2(graph_t *g)
+ */
+static void applyPacking2(graph_t * g)
 {
-  int i;
-
-  sortedLayerIndex = (int *)malloc(sizeof(int)*agnnodes(g));
-  if (sortedLayerIndex == NULL)
-    agerr(AGERR, "Memory allocation error in applyPacking function.\n");
-
-  for (i=0; i<agnnodes(g); i++)
-  {
-    sortedLayerIndex[i] = i;
-  }
+    int i;
 
+    sortedLayerIndex = N_NEW(agnnodes(g), int);
 
-  node_t *v;
+    for (i = 0; i < agnnodes(g); i++) {
+       sortedLayerIndex[i] = i;
+    }
 
-  computeLayerWidths(g);
-  sortLayers(g);
-  reduceMaxWidth2(g);
+    computeLayerWidths(g);
+    sortLayers(g);
+    reduceMaxWidth2(g);
 
 }
 
-/*****************************************************************
+#ifdef UNUSED
+/* applyPacking4:
  * The following is the packing heuristic for wide layout.
  * It's used with Nikolov-Healy healy heuristic.
- *****************************************************************/
-
-void applyPacking4(graph_t *g)
+ */
+void applyPacking4(graph_t * g)
 {
-  int i;
+    int i;
 
-  sortedLayerIndex = (int *)malloc(sizeof(int)*agnnodes(g));
-  if (sortedLayerIndex == NULL)
-    agerr(AGERR, "Memory allocation error in applyPacking function.\n");
+    sortedLayerIndex = N_NEW(agnnodes(g), int);
 
-  for (i=0; i<agnnodes(g); i++)
-  {
-    sortedLayerIndex[i] = i;
-  }
+    for (i = 0; i < agnnodes(g); i++) {
+       sortedLayerIndex[i] = i;
+    }
 
 
-  for (i=0; i<1; i++)
-  {
-    /*    printf("iteration = %d\n----------------------\n", i);
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-       printf("%s rank = %d\n", v->name, ND_rank(v));
-    }
-    */
+    for (i = 0; i < 1; i++) {
+       /*    printf("iteration = %d\n----------------------\n", i);
+          for (v = agfstnode(g); v; v = agnxtnode(g,v))
+          {
+          printf("%s rank = %d\n", v->name, ND_rank(v));
+          }
+        */
 
-    computeLayerWidths(g);
-    sortLayers(g);
-    reduceMaxWidth2(g);
-    //printf("====================\n");
-  }
+
+       computeLayerWidths(g);
+       sortLayers(g);
+       reduceMaxWidth2(g);
+       //printf("====================\n");
+    }
 }
 
-/********************************************************************************************
-*       NOCOLOV & HEALY'S NODE PROMOTION HEURISTIC
-*********************************************************************************************/
+/*
+ *       NOCOLOV & HEALY'S NODE PROMOTION HEURISTIC
+ */
 
 /****************************************************************
  * This data structure is needed for backing up node information
  * during node promotion
  ****************************************************************/
-typedef struct myNodeInfo_t
-{
-  int indegree;
-  int outdegree;
-  int rank;
-  Agnode_t *node;
+typedef struct myNodeInfo_t {
+    int indegree;
+    int outdegree;
+    int rank;
+    Agnode_t *node;
 } myNodeInfo_t;
 
 myNodeInfo_t *myNodeInfo;
 
 
-
-//return the maximum level number assigned
-int getMaxLevelNumber(graph_t *g)
+/* getMaxLevelNumber:
+ * return the maximum level number assigned
+ */
+int getMaxLevelNumber(graph_t * g)
 {
-  int max;
-  Agnode_t *n;
-    
-  max = ND_rank(agfstnode(g));
-
-  for (n = agfstnode(g); n; n = agnxtnode(g,n))
-  {
-    if (ND_rank(n) > max)
-      max = ND_rank(n);
-  }
-
-  return max;
+    int max;
+    Agnode_t *n;
+
+    max = ND_rank(agfstnode(g));
+
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       if (ND_rank(n) > max)
+           max = ND_rank(n);
+    }
+
+    return max;
 }
 
-/****************************************************************
+/* countDummyDiff:
  * return the difference in the count of dummy nodes before 
  * and after promoting the node v
- ****************************************************************/
-
-static int
-countDummyDiff(graph_t *g, Agnode_t *v, int max)
+ */
+static int countDummyDiff(graph_t * g, Agnode_t * v, int max)
 {
-  int dummydiff = 0;
-  Agedge_t *e;
-  Agnode_t *u;
-
-  int maxR = 0;
+    int dummydiff = 0;
+    Agedge_t *e;
+    Agnode_t *u;
+    int maxR = 0;
+    int j;
 
+    for (j = 0; j < ND_in(v).size; j++) {
+       e = ND_in(v).list[j];
+       u = e->tail;
 
-  int j;
+       if (myNodeInfo[ND_id(u)].rank == myNodeInfo[ND_id(v)].rank + 1) {
+           dummydiff += countDummyDiff(g, u, max);
+       }
+    }
 
-  //for (e = agfstin(g,v); e; e = agnxtin(g,e))
-  for (j = 0; j < ND_in(v).size; j++)
-  {
-    e = ND_in(v).list[j];
-    u = e->tail;
+    if (myNodeInfo[ND_id(v)].rank + 1 < max
+       || (ND_in(v).size == 0 && myNodeInfo[ND_id(v)].rank + 1 <= max))
+       myNodeInfo[ND_id(v)].rank += 1;
 
-    if (myNodeInfo[ND_id(u)].rank == myNodeInfo[ND_id(v)].rank+1)
-    {
-      dummydiff += countDummyDiff(g,u,max);
-    }
-  }
-  
-  if (myNodeInfo[ND_id(v)].rank+1 < max || (ND_in(v).size == 0 && myNodeInfo[ND_id(v)].rank+1 <= max))
-    myNodeInfo[ND_id(v)].rank += 1;
+    dummydiff = dummydiff - ND_in(v).size + ND_out(v).size;
 
-  dummydiff = dummydiff - ND_in(v).size + ND_out(v).size;
 
-    
-  return dummydiff;
+    return dummydiff;
 }
 
-/****************************************************************
+/* applyPromotionHeuristic:
  * Node Promotion Heuristic
  * by Nikolov and Healy
- ****************************************************************/
-
-static void 
-applyPromotionHeuristic(graph_t *g)
+ */
+static void applyPromotionHeuristic(graph_t * g)
 {
-  graph_t graphBkup = *g;
-  Agnode_t * v;
-  int promotions;
-
-  int max = getMaxLevelNumber(g);
-  int count = 0;
-  int nNodes = agnnodes(g);
-  int i, j;
-  
-  myNodeInfo = (myNodeInfo_t *) malloc(sizeof(myNodeInfo_t) * nNodes);
-  myNodeInfo_t *myNodeInfoBak = (myNodeInfo_t *) malloc(sizeof(myNodeInfo_t) * nNodes);
-
-  for (v = agfstnode(g), i = 0; v; v = agnxtnode(g,v), i++)
-  {
-    myNodeInfo[i].indegree = ND_in(v).size;
-    myNodeInfo[i].outdegree = ND_out(v).size;
-    myNodeInfo[i].rank = ND_rank(v);
-    myNodeInfo[i].node = v;
-    ND_id(v) = i;
-
-    myNodeInfoBak[i] = myNodeInfo[i];
-  }
-
-  do
-  {
-    promotions  = 0;
-    
-    for (v = agfstnode(g); v; v = agnxtnode(g,v))
-    {
-      if (ND_in(v).size > 0)
-      {
-       if (countDummyDiff(g,v,max) <= 0)
-       {
-         promotions++;
-         
-         for (j = 0; j < nNodes; j++)
-         {
-           myNodeInfoBak[j] = myNodeInfo[j];
-         }
-
-       }
-       else 
-       {
-         for (j = 0; j < nNodes; j++)
-         {
-           myNodeInfo[j] = myNodeInfoBak[j];
-         }
-       }
-      }
+    graph_t graphBkup = *g;
+    Agnode_t *v;
+    int promotions;
+
+    int max = getMaxLevelNumber(g);
+    int count = 0;
+    int nNodes = agnnodes(g);
+    int i, j;
+
+    myNodeInfo = N_NEW(nNodes, myNodeInfo_t);
+    myNodeInfo_t *myNodeInfoBak = N_NEW(nNodes, myNodeInfo_t);
+
+    for (v = agfstnode(g), i = 0; v; v = agnxtnode(g, v), i++) {
+       myNodeInfo[i].indegree = ND_in(v).size;
+       myNodeInfo[i].outdegree = ND_out(v).size;
+       myNodeInfo[i].rank = ND_rank(v);
+       myNodeInfo[i].node = v;
+       ND_id(v) = i;
+
+       myNodeInfoBak[i] = myNodeInfo[i];
     }
-    count++;
-  }  while (count < max);
 
-  for (v = agfstnode(g); v; v = agnxtnode(g,v))
-  {
-    ND_rank(v) = myNodeInfo[ND_id(v)].rank;
-  }
-}
+    do {
+       promotions = 0;
 
+       for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+           if (ND_in(v).size > 0) {
+               if (countDummyDiff(g, v, max) <= 0) {
+                   promotions++;
 
-/********************************************************************************************
-*       LONGEST PATH ALGORITHM
-*********************************************************************************************/
+                   for (j = 0; j < nNodes; j++) {
+                       myNodeInfoBak[j] = myNodeInfo[j];
+                   }
+
+               } else {
+                   for (j = 0; j < nNodes; j++) {
+                       myNodeInfo[j] = myNodeInfoBak[j];
+                   }
+               }
+           }
+       }
+       count++;
+    } while (count < max);
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       ND_rank(v) = myNodeInfo[ND_id(v)].rank;
+    }
+}
 
-/********************************************************************************************
-* Return 1 if all the neighbors of n already ranked, else 0
-*********************************************************************************************/
-int 
-allNeighborsAreBelow (Agnode_t *n) 
+/*
+ *       LONGEST PATH ALGORITHM
+ */
+
+/* allNeighborsAreBelow:
+ * Return 1 if all the neighbors of n already ranked, else 0
+ */
+static int allNeighborsAreBelow(Agnode_t * n)
 {
     Agedge_t *e;
     graph_t *g = n->graph;
     int i;
 
     //for (e = agfstout(g,n); e; e = agnxtout(g,e))
-    for (i = 0; i < ND_out(n).size; i++)
-    {
-      e = ND_out(n).list[i];
-      if (ED_edge_type(e) == VIRTUAL)
-      {
-       if (ED_to_orig(e) != NULL)
-         e = ED_to_orig(e);
-        else if (ND_node_type(e->head) == VIRTUAL)
-         continue;
-      }
-
-      if(ND_pinned(e->head) != 2) //neighbor of n is not below
-      {
-          return 0;
-      }
+    for (i = 0; i < ND_out(n).size; i++) {
+       e = ND_out(n).list[i];
+       if (ED_edge_type(e) == VIRTUAL) {
+           if (ED_to_orig(e) != NULL)
+               e = ED_to_orig(e);
+           else if (ND_node_type(e->head) == VIRTUAL)
+               continue;
+       }
+
+       if (ND_pinned(e->head) != 2)    //neighbor of n is not below
+       {
+           return 0;
+       }
     }
 
     return 1;
 }
 
-
-/****************************************************************
+/* reverseLevelNumbers:
  * In Nikolov and Healy ranking, bottom layer ranking is  0 and
  * top layer ranking is the maximum. 
  * Graphviz does the opposite.
  * This function does the reversing from Nikolov to Graphviz.
- ****************************************************************/
-
-static void 
-reverseLevelNumbers(graph_t *g)
+ */
+static void reverseLevelNumbers(graph_t * g)
 {
     Agnode_t *n;
     int max;
-    
+
     max = getMaxLevelNumber(g);
 
     //printf("max = %d\n", max);
 
     //return;
-    for (n = agfstnode(g); n; n = agnxtnode(g,n))
-    {
-      ND_rank(n) = max - ND_rank(n);
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       ND_rank(n) = max - ND_rank(n);
     }
 }
 
-
-/****************************************************************
+/* doSameRank:
  * Maintain the same ranking constraint.
  * Can only be used with the Nikolov and Healy algorithm
- ****************************************************************/
-
-static void
-doSameRank(graph_t *g)
+ */
+static void doSameRank(graph_t * g)
 {
-  int i;
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    int j;
+    int i;
+    for (i = 0; i < nNodeGroups; i++) {
+       int j;
 
-    for (j = 0; j < nodeGroups[i].nNodes; j++)
-    {
-      if ( ND_ranktype(nodeGroups[i].nodes[j]) == SAMERANK) //once we find a SAMERANK node in a group- make all the members of the group SAMERANK
-      {
-       int k;
-       int r = ND_rank(UF_find(nodeGroups[i].nodes[j])); 
-       for (k = 0; k < nodeGroups[i].nNodes; k++)
-       {
-         ND_rank(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = r;
+       for (j = 0; j < nodeGroups[i].nNodes; j++) {
+           if (ND_ranktype(nodeGroups[i].nodes[j]) == SAMERANK)        //once we find a SAMERANK node in a group- make all the members of the group SAMERANK
+           {
+               int k;
+               int r = ND_rank(UF_find(nodeGroups[i].nodes[j]));
+               for (k = 0; k < nodeGroups[i].nNodes; k++) {
+                   ND_rank(nodeGroups[i].
+                           nodes[(j + k) % nodeGroups[i].nNodes]) = r;
+               }
+
+               break;
+           }
        }
-       
-       break;
-      }
     }
-  }
-
 }
 
-
-/****************************************************************
+/* doMinRank:
  * Maintain the MIN ranking constraint.
  * Can only be used with the Nikolov and Healy algorithm
- ****************************************************************/
-
-void
-doMinRank(graph_t *g)
+ */
+void doMinRank(graph_t * g)
 {
-  int i;
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    int j;
+    int i;
+    for (i = 0; i < nNodeGroups; i++) {
+       int j;
 
-    for (j = 0; j < nodeGroups[i].nNodes; j++)
-    {
-      if ( ND_ranktype(nodeGroups[i].nodes[j]) == MINRANK) //once we find a MINRANK node in a group- make the rank of all the members of the group 0
-      {
-       int k;
-       for (k = 0; k < nodeGroups[i].nNodes; k++)
-       {
-         ND_rank(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = 0;
-         if (ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) != SOURCERANK)
-           ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = MINRANK;
+       for (j = 0; j < nodeGroups[i].nNodes; j++) {
+           if (ND_ranktype(nodeGroups[i].nodes[j]) == MINRANK) //once we find a MINRANK node in a group- make the rank of all the members of the group 0
+           {
+               int k;
+               for (k = 0; k < nodeGroups[i].nNodes; k++) {
+                   ND_rank(nodeGroups[i].
+                           nodes[(j + k) % nodeGroups[i].nNodes]) = 0;
+                   if (ND_ranktype
+                       (nodeGroups[i].
+                        nodes[(j + k) % nodeGroups[i].nNodes]) !=
+                       SOURCERANK)
+                       ND_ranktype(nodeGroups[i].
+                                   nodes[(j +
+                                          k) % nodeGroups[i].nNodes]) =
+                           MINRANK;
+               }
+
+               break;
+           }
        }
-       
-       break;
-      }
     }
-  }
 }
 
-
-/****************************************************************
+/* getMaxRank:
  * Return the maximum rank among all nodes.
- ****************************************************************/
-
-static int
-getMaxRank(graph_t *g)
+ */
+static int getMaxRank(graph_t * g)
 {
-  int i;
-  node_t *v;
-  int maxR = ND_rank(agfstnode(g));
-  for (v = agfstnode(g); v; v = agnxtnode(g,v))
-  {
-    if (ND_rank(v) > maxR)
-      maxR = ND_rank(v);
-  }
-
-  return maxR;
-}
+    int i;
+    node_t *v;
+    int maxR = ND_rank(agfstnode(g));
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       if (ND_rank(v) > maxR)
+           maxR = ND_rank(v);
+    }
 
+    return maxR;
+}
 
-/****************************************************************
+/* doMaxRank:
  * Maintain the MAX ranking constraint.
  * Can only be used with the Nikolov and Healy algorithm
- ****************************************************************/
-
-static void
-doMaxRank(graph_t *g)
+ */
+static void doMaxRank(graph_t * g)
 {
-  int i;
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    int j;
-    int maxR = getMaxRank(g);
-
-    for (j = 0; j < nodeGroups[i].nNodes; j++)
-    {
-      if ( ND_ranktype(nodeGroups[i].nodes[j]) == MAXRANK) //once we find a MAXRANK node in a group- make the rank of all the members of the group MAX
-      {
-       int k;
-       for (k = 0; k < nodeGroups[i].nNodes; k++)
-       {
-         ND_rank(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = maxR;
-         if (ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) != SINKRANK)
-           ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = MAXRANK;
+    int i;
+    for (i = 0; i < nNodeGroups; i++) {
+       int j;
+       int maxR = getMaxRank(g);
+
+       for (j = 0; j < nodeGroups[i].nNodes; j++) {
+           if (ND_ranktype(nodeGroups[i].nodes[j]) == MAXRANK) //once we find a MAXRANK node in a group- make the rank of all the members of the group MAX
+           {
+               int k;
+               for (k = 0; k < nodeGroups[i].nNodes; k++) {
+                   ND_rank(nodeGroups[i].
+                           nodes[(j + k) % nodeGroups[i].nNodes]) = maxR;
+                   if (ND_ranktype
+                       (nodeGroups[i].
+                        nodes[(j + k) % nodeGroups[i].nNodes]) !=
+                       SINKRANK)
+                       ND_ranktype(nodeGroups[i].
+                                   nodes[(j +
+                                          k) % nodeGroups[i].nNodes]) =
+                           MAXRANK;
+               }
+
+               break;
+           }
        }
-       
-       break;
-      }
     }
-  }
 }
 
-
-/****************************************************************
+/* doSourceRank:
  * Maintain the SOURCE ranking constraint.
  * Can only be used with the Nikolov and Healy algorithm
- ****************************************************************/
-
-static void
-doSourceRank(graph_t *g)
+ */
+static void doSourceRank(graph_t * g)
 {
-  int i;
-  int flag = 0;
-
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    int j;
+    int i;
+    int flag = 0;
+
+    for (i = 0; i < nNodeGroups; i++) {
+       int j;
+
+       for (j = 0; j < nodeGroups[i].nNodes; j++) {
+           //once we find a SOURCERANK node in a group- make the rank of all the members of the group 0
+           if (ND_ranktype(nodeGroups[i].nodes[j]) == SOURCERANK) {
+               int k;
+               for (k = 0; k < nodeGroups[i].nNodes; k++) {
+                   ND_rank(nodeGroups[i].
+                           nodes[(j + k) % nodeGroups[i].nNodes]) = 0;
+                   ND_ranktype(nodeGroups[i].
+                               nodes[(j + k) % nodeGroups[i].nNodes]) =
+                       SOURCERANK;
+               }
 
-    for (j = 0; j < nodeGroups[i].nNodes; j++)
-    {
-      //once we find a SOURCERANK node in a group- make the rank of all the members of the group 0
-      if ( ND_ranktype(nodeGroups[i].nodes[j]) == SOURCERANK) 
-      {
-       int k;
-       for (k = 0; k < nodeGroups[i].nNodes; k++)
-       {
-         ND_rank(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = 0;
-         ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = SOURCERANK;
+               flag = 1;
+               break;
+           }
        }
-       
-       flag = 1;       
-       break;
-      }
     }
-  }
 
-  if (!flag)
-    return;
+    if (!flag)
+       return;
 
-  flag = 0;
+    flag = 0;
 
-  //The SourceRank group might be the only group having rank 0. Check if increment of ranking of other nodes is necessary at all.
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    if (nodeGroups[i].nNodes > 0 && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK && ND_rank(nodeGroups[i].nodes[0]) == 0)
-    {
-      flag = 1;
-      break;
-    }
-  }
-
-  
-  if (!flag)
-    return;
-
-  //Now make all NON-SourceRank nodes' ranking nonzero (increment)
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    if (nodeGroups[i].nNodes > 0 && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK)
-    {
-      int j;
-
-      for (j = 0; j < nodeGroups[i].nNodes; j++)
-      {
-       ND_rank(nodeGroups[i].nodes[j])++;
-      } 
+    //The SourceRank group might be the only group having rank 0. Check if increment of ranking of other nodes is necessary at all.
+    for (i = 0; i < nNodeGroups; i++) {
+       if (nodeGroups[i].nNodes > 0
+           && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK
+           && ND_rank(nodeGroups[i].nodes[0]) == 0) {
+           flag = 1;
+           break;
+       }
     }
-  }
-}
 
 
+    if (!flag)
+       return;
 
-/****************************************************************
+    //Now make all NON-SourceRank nodes' ranking nonzero (increment)
+    for (i = 0; i < nNodeGroups; i++) {
+       if (nodeGroups[i].nNodes > 0
+           && ND_ranktype(nodeGroups[i].nodes[0]) != SOURCERANK) {
+           int j;
+
+           for (j = 0; j < nodeGroups[i].nNodes; j++) {
+               ND_rank(nodeGroups[i].nodes[j])++;
+           }
+       }
+    }
+}
+
+/* doSinkRank:
  * Maintain the SINK ranking constraint.
  * Can only be used with the Nikolov and Healy algorithm
- ****************************************************************/
-
-static void
-doSinkRank(graph_t *g)
+ */
+static void doSinkRank(graph_t * g)
 {
-  int i, max;
-  int flag = 0;
+    int i, max;
+    int flag = 0;
 
-  max = getMaxRank(g);
+    max = getMaxRank(g);
 
 
-  //Check if any non-sink node has rank = max
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    if (nodeGroups[i].nNodes > 0 && ND_ranktype(nodeGroups[i].nodes[0]) != SINKRANK && ND_rank(nodeGroups[i].nodes[0]) == max)
-    {
-      flag = 1;
-      break;
+    //Check if any non-sink node has rank = max
+    for (i = 0; i < nNodeGroups; i++) {
+       if (nodeGroups[i].nNodes > 0
+           && ND_ranktype(nodeGroups[i].nodes[0]) != SINKRANK
+           && ND_rank(nodeGroups[i].nodes[0]) == max) {
+           flag = 1;
+           break;
+       }
     }
-  }
 
-  if (!flag)
-    return;
+    if (!flag)
+       return;
 
-  for (i = 0; i < nNodeGroups; i++)
-  {
-    int j;
+    for (i = 0; i < nNodeGroups; i++) {
+       int j;
 
-    for (j = 0; j < nodeGroups[i].nNodes; j++)
-    {
-      if ( ND_ranktype(nodeGroups[i].nodes[j]) == SINKRANK) //once we find a SINKRANK node in a group- make the rank of all the members of the group: max+1
-      {
-       int k;
-       for (k = 0; k < nodeGroups[i].nNodes; k++)
-       {
-         ND_rank(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = max+1;
-         ND_ranktype(nodeGroups[i].nodes[(j+k)%nodeGroups[i].nNodes]) = SINKRANK;
+       for (j = 0; j < nodeGroups[i].nNodes; j++) {
+           if (ND_ranktype(nodeGroups[i].nodes[j]) == SINKRANK)        //once we find a SINKRANK node in a group- make the rank of all the members of the group: max+1
+           {
+               int k;
+               for (k = 0; k < nodeGroups[i].nNodes; k++) {
+                   ND_rank(nodeGroups[i].
+                           nodes[(j + k) % nodeGroups[i].nNodes]) =
+                       max + 1;
+                   ND_ranktype(nodeGroups[i].
+                               nodes[(j + k) % nodeGroups[i].nNodes]) =
+                       SINKRANK;
+               }
+
+               break;
+           }
        }
-       
-       break;
-      }
     }
-  }
 }
 
-
-/****************************************************************
- * rank2: Initial codes for ranking (Nikolov-Healy).
+/* rank2: 
+ * Initial codes for ranking (Nikolov-Healy).
  * It's no longer used.
- ****************************************************************/
-void
-rank2(graph_t * g)
+ */
+void rank2(graph_t * g)
 {
     int currentLayer = 1;
     int nNodes = agnnodes(g);
     int nEdges = agnedges(g);
     int nPinnedNodes = 0, nSelected = 0;
     Agnode_t *n, **UArray;
-    int USize = 0;    
+    int USize = 0;
     int i, prevSize = 0;
 
-    UArray = (Agnode_t **) malloc(sizeof(Agnode_t *) * nEdges * 2);
-    if (UArray == NULL) 
-        agerr(AGERR, "Memory allocation error for the graph \"%s\"\n", g->name);
+    UArray = N_NEW(nEdges * 2, Agnode_t *);
 
-    //make all pinning values 0
-    for (n = agfstnode(g); n; n = agnxtnode(g,n))
-    {
-        ND_pinned(n) = 0;
+    /* make all pinning values 0 */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       ND_pinned(n) = 0;
     }
 
-    while (nPinnedNodes != nNodes)
-    {
-        for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g,n)) 
-        {
-            if (ND_pinned(n) == 0)
-            {
-                if (allNeighborsAreBelow(n))
-                {
-                   ND_pinned(n) = 1;
-                   
-                   UArray[USize] = n;
-                   USize++;
-                   
-                   ND_rank(n) = currentLayer;
-                   nPinnedNodes++;
-                   nSelected++;
-                } 
-            }
-        }
-
-        if (nSelected == 0) //no node has been selected
-        {
-            currentLayer++;
-            for (i = prevSize; i < USize; i++)
-            {
-                ND_pinned(UArray[i]) = 2; //pinning value of 2 indicates this node is below the current node under consideration
-            }
-
-            prevSize = USize;
-        }
+    while (nPinnedNodes != nNodes) {
+       for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
+           if (ND_pinned(n) == 0) {
+               if (allNeighborsAreBelow(n)) {
+                   ND_pinned(n) = 1;
+
+                   UArray[USize] = n;
+                   USize++;
+
+                   ND_rank(n) = currentLayer;
+                   nPinnedNodes++;
+                   nSelected++;
+               }
+           }
+       }
+
+       if (nSelected == 0)     //no node has been selected
+       {
+           currentLayer++;
+           for (i = prevSize; i < USize; i++) {
+               ND_pinned(UArray[i]) = 2;       //pinning value of 2 indicates this node is below the current node under consideration
+           }
+
+           prevSize = USize;
+       }
     }
 
     //Apply Nikolov's node promotion heuristic
@@ -1664,11 +1572,11 @@ rank2(graph_t * g)
     //this is for the sake of graphViz layer numbering scheme
     reverseLevelNumbers(g);
 
-    computeNodeGroups(g); //groups of UF DS nodes
+    computeNodeGroups(g);      //groups of UF DS nodes
 
     //modify the ranking to respect the same ranking constraint
     doSameRank(g);
-    
+
     //satisfy min ranking constraints
     doMinRank(g);
     doMaxRank(g);
@@ -1678,223 +1586,199 @@ rank2(graph_t * g)
     doSinkRank(g);
 
     //Apply the FFDH algorithm to achieve better aspect ratio;
-    applyPacking(g,1); //achieve an aspect ratio of 1
+    applyPacking(g, 1);                //achieve an aspect ratio of 1
 }
-
+#endif
 
 /****************************************************************
  * Initialize all the edge types to NORMAL 
  ****************************************************************/
-
-void initEdgeTypes(g)
+void initEdgeTypes(graph_t * g)
 {
     edge_t *e;
     node_t *n;
-    int cnt = 0;
     int lc;
-    
-    for (n = agfstnode(g); n; n = agnxtnode(g, n))
-      for (lc = 0; lc < ND_in(n).size; lc++)
-      {
-       e = ND_in(n).list[lc];
-       ED_edge_type(e) = NORMAL;
-      }
-}
 
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       for (lc = 0; lc < ND_in(n).size; lc++) {
+           e = ND_in(n).list[lc];
+           ED_edge_type(e) = NORMAL;
+       }
+    }
+}
 
-/****************************************************************
+/* computeCombiAR:
  * Compute and return combinatorial aspect ratio 
  * =
  * Width of the widest layer / Height 
  * (in ranking phase)
- ****************************************************************/
-
-static double
-computeCombiAR(graph_t *g)
+ */
+static double computeCombiAR(graph_t * g)
 {
-  int i, maxLayerIndex;
-  double maxW = 0;
-  double maxH;
-  double ratio;
-
-  computeLayerWidths(g);
-  maxH = (nLayers - 1) * GD_ranksep(g);
-
-  for (i = 0; i < nLayers; i++)
-  {
-    if (maxW < layerWidthInfo[i].width + layerWidthInfo[i].nDummyNodes*GD_nodesep(g))
-    {
-      maxW = layerWidthInfo[i].width + layerWidthInfo[i].nDummyNodes*GD_nodesep(g);
-      maxLayerIndex = i;
+    int i, maxLayerIndex;
+    double maxW = 0;
+    double maxH;
+    double ratio;
+
+    computeLayerWidths(g);
+    maxH = (nLayers - 1) * GD_ranksep(g);
+
+    for (i = 0; i < nLayers; i++) {
+       if (maxW <
+           layerWidthInfo[i].width +
+           layerWidthInfo[i].nDummyNodes * GD_nodesep(g)) {
+           maxW =
+               layerWidthInfo[i].width +
+               layerWidthInfo[i].nDummyNodes * GD_nodesep(g);
+           maxLayerIndex = i;
+       }
+       maxH += layerWidthInfo[i].height;
     }
-    maxH += layerWidthInfo[i].height;
-  }
 
-  ratio = maxW/maxH;
+    ratio = maxW / maxH;
 
-  return ratio;
+    return ratio;
 }
 
-
-node_t *sink = NULL;
-
-
-/****************************************************************
+#ifdef UNUSED
+/* applyExpansion:
  * Heuristic for expanding very narrow graphs by edge reversal.
  * Needs improvement.
- ****************************************************************/
-
-void 
-applyExpansion(graph_t *g)
+ */
+void applyExpansion(graph_t * g)
 {
-  int i, k;
-  edge_t *e;
-
-  computeLayerWidths(g);
-  
-  for (i = 0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[i].layerNumber == nLayers/2)
-    {
-      k = i;
-      break;
-    }
-  }
-
-  //now reverse the edges, from the k-th layer nodes to their parents
-  for (i = 0; i < layerWidthInfo[k].nNodeGroupsInLayer; i++)
-  {
-    int p;
-    nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
-    for (p = 0; p < ng->nNodes; p++)
-    {
-      node_t *nd = ng->nodes[p];
-
-      while (e = ND_in(nd).list[0])
-      {
-       printf("Reversing edge: %s->%s\n", e->tail->name, e->head->name);
-       reverse_edge(e);
-      }
-
-      int j, l;
-      node_t *v3;
-      edge_t *e3;
-      for (v3 = agfstnode(g); v3; v3 = agnxtnode(g,v3))
-      {
-       for (e3 = agfstout(g,v3); e3; e3 = agnxtout(g,e3))
-       {
-         if (ND_rank(e3->head) > k && ND_rank(e3->tail) < k)
-         {
-           printf("Reversing long edge: %s->%s\n", e3->tail->name, e3->head->name);
-           reverse_edge(e3);
-         }
+    node_t *sink = NULL;
+    int i, k;
+    edge_t *e;
 
+    computeLayerWidths(g);
+
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[i].layerNumber == nLayers / 2) {
+           k = i;
+           break;
        }
-       }
+    }
 
-      /*for (l = 0; l < nLayers; l++)
-      {
-       if (layerWidthInfo[l].layerNumber <= k)
-         continue;
-       
-       for (j = 0; j < layerWidthInfo[l].nNodeGroupsInLayer; j++)
-       {
-         int q;
-         nodeGroup_t *ng2 = layerWidthInfo[l].nodeGroupsInLayer[j];
-         for (q = 0; q < ng2->nNodes; q++)
-         {
-           node_t *nd2 = ng2->nodes[q];
-           edge_t *e2;
-           int s = 0;
-           while (e2 = ND_in(nd2).list[s])
-           {
-             if (ND_rank(e2->tail) < k)
-             {
-               printf("Reversing edge: %s->%s\n", e2->tail->name, e2->head->name);
-               getchar();
-               //reverse_edge(e2);
-             }
-             else s++;
+    //now reverse the edges, from the k-th layer nodes to their parents
+    for (i = 0; i < layerWidthInfo[k].nNodeGroupsInLayer; i++) {
+       int p;
+       nodeGroup_t *ng = layerWidthInfo[k].nodeGroupsInLayer[i];
+       for (p = 0; p < ng->nNodes; p++) {
+           node_t *nd = ng->nodes[p];
+
+           while (e = ND_in(nd).list[0]) {
+               printf("Reversing edge: %s->%s\n", e->tail->name,
+                      e->head->name);
+               reverse_edge(e);
            }
-         }
-       }
-       }*/
-      
-      if (sink == NULL)
-      {
-       int brFlag = 1;
-      for (l = 0; l < nLayers && brFlag; l++)
-      {
-       for (j = 0; j < layerWidthInfo[l].nNodeGroupsInLayer && brFlag; j++)
-       {
-         int q;
-         nodeGroup_t *ng2 = layerWidthInfo[l].nodeGroupsInLayer[j];
-         for (q = 0; q < ng2->nNodes && brFlag; q++)
-         {
-           node_t *nd2 = ng2->nodes[q];
-           if (ND_in(nd2).size == 0)
-           {
-             sink = nd2;
-             brFlag = 0;
+
+           int j, l;
+           node_t *v3;
+           edge_t *e3;
+           for (v3 = agfstnode(g); v3; v3 = agnxtnode(g, v3)) {
+               for (e3 = agfstout(g, v3); e3; e3 = agnxtout(g, e3)) {
+                   if (ND_rank(e3->head) > k && ND_rank(e3->tail) < k) {
+                       printf("Reversing long edge: %s->%s\n",
+                              e3->tail->name, e3->head->name);
+                       reverse_edge(e3);
+                   }
+
+               }
            }
-         }
-       }
-      }
 
-      }
+           /*for (l = 0; l < nLayers; l++)
+              {
+              if (layerWidthInfo[l].layerNumber <= k)
+              continue;
+
+              for (j = 0; j < layerWidthInfo[l].nNodeGroupsInLayer; j++)
+              {
+              int q;
+              nodeGroup_t *ng2 = layerWidthInfo[l].nodeGroupsInLayer[j];
+              for (q = 0; q < ng2->nNodes; q++)
+              {
+              node_t *nd2 = ng2->nodes[q];
+              edge_t *e2;
+              int s = 0;
+              while (e2 = ND_in(nd2).list[s])
+              {
+              if (ND_rank(e2->tail) < k)
+              {
+              printf("Reversing edge: %s->%s\n", e2->tail->name, e2->head->name);
+              getchar();
+              //reverse_edge(e2);
+              }
+              else s++;
+              }
+              }
+              }
+              } */
+
+           if (sink == NULL) {
+               int brFlag = 1;
+               for (l = 0; l < nLayers && brFlag; l++) {
+                   for (j = 0;
+                        j < layerWidthInfo[l].nNodeGroupsInLayer
+                        && brFlag; j++) {
+                       int q;
+                       nodeGroup_t *ng2 =
+                           layerWidthInfo[l].nodeGroupsInLayer[j];
+                       for (q = 0; q < ng2->nNodes && brFlag; q++) {
+                           node_t *nd2 = ng2->nodes[q];
+                           if (ND_in(nd2).size == 0) {
+                               sink = nd2;
+                               brFlag = 0;
+                           }
+                       }
+                   }
+               }
+
+           }
 
-      virtual_edge(nd, /*sink*/ layerWidthInfo[0].nodeGroupsInLayer[0]->nodes[0], NULL);
+           virtual_edge(nd,    /*sink */
+                        layerWidthInfo[0].nodeGroupsInLayer[0]->nodes[0],
+                        NULL);
+       }
     }
-  }
 
-  //collapse_sets(g);
+    //collapse_sets(g);
 }
+#endif
 
-
-/****************************************************************
+/* zapLayers:
  * After applying the expansion heuristic, some layers are
  * found to be empty.
  * This function removes the empty layers.
- ****************************************************************/
-
-static void 
-zapLayers(graph_t *g)
+ */
+static void zapLayers(graph_t * g)
 {
-  int i, j;
-  int start = 0;
-  int count = 0;
-
-  //the layers are sorted by the layer number.
-  //now zap the empty layers
-
-  for (i = 0; i < nLayers; i++)
-  {
-    if (layerWidthInfo[i].nNodeGroupsInLayer == 0)
-    {
-      if (count == 0)
-       start = layerWidthInfo[i].layerNumber;
-      count ++;
-    }
-    else if (count && layerWidthInfo[i].layerNumber > start)
-    {
-       for (j = 0; j < layerWidthInfo[i].nNodeGroupsInLayer; j++)
-       {
-         int q;
-         nodeGroup_t *ng = layerWidthInfo[i].nodeGroupsInLayer[j];
-         for (q = 0; q < ng->nNodes; q++)
-         {
-           node_t *nd = ng->nodes[q];
-           ND_rank(nd) -= count;
-         }
+    int i, j;
+    int start = 0;
+    int count = 0;
+
+    /* the layers are sorted by the layer number.  now zap the empty layers */
+
+    for (i = 0; i < nLayers; i++) {
+       if (layerWidthInfo[i].nNodeGroupsInLayer == 0) {
+           if (count == 0)
+               start = layerWidthInfo[i].layerNumber;
+           count++;
+       } else if (count && layerWidthInfo[i].layerNumber > start) {
+           for (j = 0; j < layerWidthInfo[i].nNodeGroupsInLayer; j++) {
+               int q;
+               nodeGroup_t *ng = layerWidthInfo[i].nodeGroupsInLayer[j];
+               for (q = 0; q < ng->nNodes; q++) {
+                   node_t *nd = ng->nodes[q];
+                   ND_rank(nd) -= count;
+               }
+           }
        }
     }
-  }
-
 }
 
-
-/****************************************************************
- * rank3: ranking function for dealing with wide/narrow graphs,
+/* rank3: 
+ * ranking function for dealing with wide/narrow graphs,
  * or graphs with varying node widths and heights.
  * This function iteratively calls dot's rank1() function and 
  * applies packing (by calling the applyPacking2 function. 
@@ -1903,135 +1787,111 @@ zapLayers(graph_t *g)
  * Initially the iterations argument is -1, for which rank3
  * callse applyPacking2 function until the combinatorial aspect
  * ratio is <= the desired aspect ratio.
- ****************************************************************/
-
-void
-rank3(graph_t * g, int iterations)
+ */
+void rank3(graph_t * g, aspect_t * asp)
 {
-    int currentLayer = 1;
-    int nNodes = agnnodes(g);
-    int nEdges = agnedges(g);
-    int nPinnedNodes = 0, nSelected = 0;
-    Agnode_t *n, **UArray;
-    int USize = 0;    
-    int i, prevSize = 0;
+    Agnode_t *n;
+    int i;
+    int iterations = asp->nextIter;
 
+    computeNodeGroups(g);      /* groups of UF DS nodes */
 
-    computeNodeGroups(g); //groups of UF DS nodes
+    for (i = 0; i < iterations || iterations == -1; i++) {
+       /* initialize all ranks to be 0 */
+       for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+           ND_rank(n) = 0;
+       }
 
+       /* need to compute ranking first--- by Network flow */
 
-    edge_t *e;
-    int cnt = 0;
-    int lc;
-    
-
-    for (i=0; i<iterations || iterations == -1; i++)
-    {
-      //initialize all ranks to be 0
-      for (n = agfstnode(g); n; n = agnxtnode(g,n))
-      {
-       ND_rank(n) = 0;
-      }
-
-      //need to compute ranking first--- by Network flow
-
-      rank1(g);
-
-      combiAR = computeCombiAR(g);
-      printf("combiAR = %lf\n", combiAR);
-    
-
-      //Uncomment the following codes, for working with narrow graphs
-      /*if (combiAR < 0.8*targetAR)
-      {
-       char str[20];
-       printf("Apply expansion? (y/n):");
-       scanf("%s", str);
-       if (strcmp(str, "y") == 0)
-         applyExpansion(g);
-       break;
-      }
-      else*/
-       if (iterations == -1 && combiAR <= targetAR)
-       {
-         prevIterations = curIterations;
-         curIterations = i;
+       rank1(g);
+
+       asp->combiAR = computeCombiAR(g);
+       if (Verbose)
+           fprintf(stderr, "combiAR = %lf\n", asp->combiAR);
 
-         break;
-       }
 
-      //Apply the FFDH algorithm to reduce the aspect ratio;
-      applyPacking2(g);
-     }
+       /* Uncomment the following codes, for working with narrow graphs */
+#ifdef UNUSED
+       if (combiAR < 0.8 * targetAR) {
+           char str[20];
+           printf("Apply expansion? (y/n):");
+           scanf("%s", str);
+           if (strcmp(str, "y") == 0)
+               applyExpansion(g);
+           break;
+       } else
+#endif
+       if (iterations == -1 && asp->combiAR <= asp->targetAR) {
+           asp->prevIterations = asp->curIterations;
+           asp->curIterations = i;
 
-    //do network flow once again... incorporating the added edges
+           break;
+       }
+       /* Apply the FFDH algorithm to reduce the aspect ratio; */
+       applyPacking2(g);
+    }
+
+    /* do network flow once again... incorporating the added edges */
     rank1(g);
 
     computeLayerWidths(g);
     zapLayers(g);
-    combiAR = computeCombiAR(g);
+    asp->combiAR = computeCombiAR(g);
 }
 
-/****************************************************************
+#ifdef UNUSED
+/* NikolovHealy:
  * Nikolov-Healy approach to ranking.
  * First, use longest path algorithm.
  * Then use node promotion heuristic.
  * This function is called by rank4 function.
- ****************************************************************/
-
-void NikolovHealy(graph_t *g)
+ */
+static void NikolovHealy(graph_t * g)
 {
     int currentLayer = 1;
     int nNodes = agnnodes(g);
     int nEdges = agnedges(g);
     int nPinnedNodes = 0, nSelected = 0;
     Agnode_t *n, **UArray;
-    int USize = 0;    
+    int USize = 0;
     int i, prevSize = 0;
 
     /************************************************************************
      * longest path algorithm
      ************************************************************************/
-    UArray = (Agnode_t **) malloc(sizeof(Agnode_t *) * nEdges * 2);
-    if (UArray == NULL) 
-    agerr(AGERR, "Memory allocation error for the graph \"%s\"\n", g->name);
-
-    //make all pinning values 0
-    for (n = agfstnode(g); n; n = agnxtnode(g,n))
-    {
-        ND_pinned(n) = 0;
+    UArray = N_NEW(nEdges * 2, Agnode_t *);
+
+    /* make all pinning values 0 */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       ND_pinned(n) = 0;
     }
 
-    while (nPinnedNodes != nNodes)
-    {
-        for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g,n)) 
-        {
-            if (ND_pinned(n) == 0)
-            {
-                if (allNeighborsAreBelow(n))
-                {
-                   ND_pinned(n) = 1;
-                   
-                   UArray[USize] = n;
-                   USize++;
-                   
-                   ND_rank(n) = currentLayer;
-                   nPinnedNodes++;
-                   nSelected++;
-                } 
-            }
-        }
-
-        if (nSelected == 0) //no node has been selected
-        {
-            currentLayer++;
-            for (i = prevSize; i < USize; i++)
-            {
-                ND_pinned(UArray[i]) = 2; //pinning value of 2 indicates this node is below the current node under consideration
-            }
-
-            prevSize = USize;
-        }
+    while (nPinnedNodes != nNodes) {
+       for (nSelected = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
+           if (ND_pinned(n) == 0) {
+               if (allNeighborsAreBelow(n)) {
+                   ND_pinned(n) = 1;
+
+                   UArray[USize] = n;
+                   USize++;
+
+                   ND_rank(n) = currentLayer;
+                   nPinnedNodes++;
+                   nSelected++;
+               }
+           }
+       }
+
+       if (nSelected == 0)     //no node has been selected
+       {
+           currentLayer++;
+           for (i = prevSize; i < USize; i++) {
+               ND_pinned(UArray[i]) = 2;       //pinning value of 2 indicates this node is below the current node under consideration
+           }
+
+           prevSize = USize;
+       }
 
     }
 
@@ -2047,82 +1907,71 @@ void NikolovHealy(graph_t *g)
 
 }
 
-/****************************************************************
+
+/* rank4:
  * This function is calls the NikolovHealy function
  * for ranking in the Nikolov-Healy approach.
- ****************************************************************/
-
-void
-rank4(graph_t * g, int iterations)
+ */
+void rank4(graph_t * g, int iterations)
 {
     int currentLayer = 1;
     int nNodes = agnnodes(g);
     int nEdges = agnedges(g);
     int nPinnedNodes = 0, nSelected = 0;
     Agnode_t *n, **UArray;
-    int USize = 0;    
+    int USize = 0;
     int i, prevSize = 0;
-    
+
     int it;
     printf("# of interations of packing: ");
     scanf("%d", &it);
     printf("it=%d\n", it);
-    
-    computeNodeGroups(g); //groups of UF DS nodes
 
-    for (i=0; i<it; i++)
-    {
-       for (n = agfstnode(g); n; n = agnxtnode(g,n))
-       {
-         ND_rank(n) = 0;
-       }
+    computeNodeGroups(g);      //groups of UF DS nodes
 
+    for (i = 0; i < it; i++) {
+       for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+           ND_rank(n) = 0;
+       }
 
        NikolovHealy(g);
-               
+
        edge_t *e;
        int cnt = 0;
        int lc;
-    
+
 
        combiAR = computeCombiAR(g);
        printf("%d. combiAR = %lf\n", i, combiAR);
 
        /*
-       //modify the ranking to respect the same ranking constraint
-       doSameRank(g);
-    
-       //satisfy min ranking constraints
-       doMinRank(g);
-       doMaxRank(g);
-
-       //satisfy source ranking constraints
-       doSourceRank(g);
-       doSinkRank(g);
-       */
+          //modify the ranking to respect the same ranking constraint
+          doSameRank(g);
+
+          //satisfy min ranking constraints
+          doMinRank(g);
+          doMaxRank(g);
+
+          //satisfy source ranking constraints
+          doSourceRank(g);
+          doSinkRank(g);
+        */
 
        //Apply the FFDH algorithm to achieve better aspect ratio;
        applyPacking4(g);
 
-  }
+    }
 
 }
+#endif
 
-
-/****************************************************************
+/* init_UF_size:
  * Initialize the Union Find data structure
- ****************************************************************/
-
-void 
-init_UF_size(graph_t *g)
+ */
+void init_UF_size(graph_t * g)
 {
-  node_t *n;
+    node_t *n;
 
-  for (n=agfstnode(g); n; n=agnxtnode(g,n))
-    ND_UF_size(n) = 0;
+    for (n = agfstnode(g); n; n = agnxtnode(g, n))
+       ND_UF_size(n) = 0;
 }
-
-
-/********************************************************************************************
-*       END OF CODES BY MOHAMMAD T. IRFAN
-*********************************************************************************************/
index dc5bfc38a3a5027f1b5fd862d042917f4d6ccb6d..91281bdf49d671e85d848da18ceec834d7d93edf 100644 (file)
@@ -16,6 +16,7 @@
 
 
 #include    "dot.h"
+#include    "aspect.h"
 #include <time.h>
 
 static void 
@@ -96,27 +97,6 @@ dot_cleanup_node(node_t * n)
     memset(&(n->u), 0, sizeof(Agnodeinfo_t));
 }
 
-static void 
-dot_free_splines(edge_t * e)
-{
-    int i;
-    if (ED_spl(e)) {
-       for (i = 0; i < ED_spl(e)->size; i++)
-           free(ED_spl(e)->list[i].list);
-       free(ED_spl(e)->list);
-       free(ED_spl(e));
-    }
-    ED_spl(e) = NULL;
-}
-
-static void 
-dot_cleanup_edge(edge_t * e)
-{
-    dot_free_splines(e);
-    free_label(ED_label(e));
-    memset(&(e->u), 0, sizeof(Agedgeinfo_t));
-}
-
 static void free_virtual_edge_list(node_t * n)
 {
     edge_t *e;
@@ -221,94 +201,63 @@ dumpRanks (graph_t * g)
 }
 #endif
 
+#define MIN_AR 1.0
+#define MAX_AR 20.0
+#define DEF_PASSES 5
 
-/***********************************************************************
- * The codes in the dot_layout function has been changed.
- * It gets an estimation of next number of iterations for ranking
- * from the positioning step.
- * User can change the number of iterations or stop the iterations.
- ***********************************************************************/
-
-/**************************** EXTERNAL VARIABLES ***********************/
-extern double targetAR;
-extern double currentAR;
-extern double combiAR;
-extern int prevIterations;
-extern int curIterations;
-/**************************** EXTERNAL VARIABLES ***********************/
-
-int packiter = 0;
-
-void dot_layout(Agraph_t * g)
+static aspect_t*
+setAspect (Agraph_t * g, aspect_t* adata)
 {
-    int rvi, targetITR, iter, packiter = 0;
-    double rv, start, finish, totalCLK;
-    setEdgeType (g, ET_SPLINE);
-    attrsym_t *a;
+    double rv;
     char *p;
+    int r, passes = DEF_PASSES;
 
+    p = agget (g, "aspect");
 
-#define MIN_AR 1.0
-#define MAX_AR 20.0
-#define MIN_ITR 1
-#define DEF_ITR 5
-#define MAX_ITR 200
-
-    targetAR = MIN_AR; /* default target aspect-ratio and iterations */
-    targetITR = MIN_ITR;  /* if targetAR isn't given, the do just the minimum*/
-    if ((a = agfindattr(g, "aspect"))) {
-        p = agxget(g, a->index);
-       if (p[0]) {
-           if ((rv = atof(p)) > MIN_AR) targetAR = rv;
-           if (targetAR > MAX_AR) targetAR = MAX_AR;
-            targetITR = DEF_ITR;  /* if targetAR *is* given, the init default */
-           if ((p = strchr(p, ','))) {
-               p++;
-               if (p[0]) {
-                   if ((rvi = atoi(p)) > MIN_ITR) targetITR = rvi;
-                   if (targetITR > MAX_ITR) targetITR = MAX_ITR;
-               }
-           }
-       }
+    if (!p || ((r = sscanf (p, "%lf,%d", &rv, &passes)) <= 0)) {
+       adata->nextIter = 0;
+       adata->badGraph = 0;
+       return NULL;
     }
+    
+    if (rv < MIN_AR) rv = MIN_AR;
+    else if (rv > MAX_AR) rv = MAX_AR;
+    adata->targetAR = rv;
+    adata->nextIter = -1;
+    adata->nPasses = passes;
+    adata->badGraph = 0;
 
     if (Verbose) 
-        fprintf(stderr, "Target AR = %g\n", targetAR);
-
-    dot_init_node_edge(g);
-
-    iter = 0;
-    while (iter < targetITR) {
-       iter++;
+        fprintf(stderr, "Target AR = %g\n", adata->targetAR);
 
-        if (Verbose) 
-            fprintf(stderr, "Iteration = %d (of %d max) Current AR = %g\n",
-               iter, targetITR, currentAR);
+    return adata;
+}
 
-        start = clock();
-        dot_rank(g);
-        packiter += curIterations;
+void dot_layout(Agraph_t * g)
+{
+    aspect_t aspect;
+    aspect_t* asp;
 
-        dot_mincross(g);
-        /* dumpRanks (g); */
+    setEdgeType (g, ET_SPLINE);
+    asp = setAspect (g, &aspect);
 
-        dot_position(g);
+    dot_init_node_edge(g);
 
-        finish = clock();
-        totalCLK += finish - start;
-    }
+    do {
+        dot_rank(g, asp);
+       if (aspect.badGraph) {
+           agerr(AGWARN, "dot does not support the aspect attribute for disconnected graphs or graphs with clusters\n");
+           asp = NULL;
+           aspect.nextIter = 0;
+       }
+        dot_mincross(g,  (asp != NULL));
+        dot_position(g, asp);
+       aspect.nPasses--;
+    } while (aspect.nextIter && aspect.nPasses);
 
     dot_sameports(g);
-
     dot_splines(g);
-
     if (mapbool(agget(g, "compound")))
        dot_compoundEdges(g);
-
     dotneato_postprocess(g);
-
-    if (Verbose) {
-        fprintf(stderr, "Packing iterations=%d\n# of Passes=%d\n", packiter, iter);
-        fprintf(stderr, "Total time = %0.3lf sec\n\n", totalCLK/CLOCKS_PER_SEC);
-    }
 }
index ba313a0e3dd6335068349b8799ed6863f7f7ace3..c3f4aee1785a17e1c1feb5d3de7b9567e8b04370 100644 (file)
@@ -25,6 +25,8 @@ _BEGIN_EXTERNS_                       /* public data */
 extern "C" {
 #endif
 
+#include "aspect.h"
+
     extern void acyclic(Agraph_t *);
     extern void allocate_ranks(Agraph_t *);
     extern void build_ranks(Agraph_t *, int);
@@ -61,6 +63,7 @@ extern "C" {
     extern Agedge_t *new_virtual_edge(Agnode_t *, Agnode_t *, Agedge_t *);
     extern int nonconstraint_edge(Agedge_t *);
     extern void other_edge(Agedge_t *);
+    extern void rank1(graph_t * g);
     extern int portcmp(port p0, port p1);
     extern int ports_eq(edge_t *, edge_t *);
     extern void rec_reset_vlists(Agraph_t *);
@@ -79,9 +82,9 @@ extern "C" {
 #endif
     extern void dot_nodesize(Agnode_t *, boolean);
     extern void dot_concentrate(Agraph_t *);
-    extern void dot_mincross(Agraph_t *);
-    extern void dot_position(Agraph_t *);
-    extern void dot_rank(Agraph_t *);
+    extern void dot_mincross(Agraph_t *, int);
+    extern void dot_position(Agraph_t *, aspect_t*);
+    extern void dot_rank(Agraph_t *, aspect_t*);
     extern void dot_sameports(Agraph_t *);
     extern void dot_splines(Agraph_t *);
 #undef extern
index 7a6409f2dfc6b81a955b378fdeb91aab278d3151..361e1e95c78358faa24414255946a209598ab6ac 100644 (file)
@@ -801,9 +801,9 @@ make_flat_adj_edges(path* P, edge_t** edges, int ind, int cnt, edge_t* e0,
     setEdgeType (auxg, et);
     dot_init_node_edge(auxg);
 
-    dot_rank(auxg);
-    dot_mincross(auxg);
-    dot_position(auxg);
+    dot_rank(auxg, 0);
+    dot_mincross(auxg, 0);
+    dot_position(auxg, 0);
     
     /* reposition */
     midx = (ND_coord(tn).x - ND_rw(tn) + ND_coord(hn).x + ND_lw(hn))/2;
index c174472c76ba36d9ad474811a123d7ccc1955a63..8d6186f7625190b2d9e576e2f383bd033ec16809 100644 (file)
@@ -40,8 +40,8 @@ static void init_mincross(graph_t * g);
 static void merge2(graph_t * g);
 static void init_mccomp(graph_t * g, int c);
 static void cleanup2(graph_t * g, int nc);
-static int mincross_clust(graph_t * par, graph_t * g);
-static int mincross(graph_t * g, int startpass, int endpass);
+static int mincross_clust(graph_t * par, graph_t * g, int);
+static int mincross(graph_t * g, int startpass, int endpass, int);
 static void init_mincross(graph_t * g);
 static void mincross_step(graph_t * g, int pass);
 static void mincross_options(graph_t * g);
@@ -72,7 +72,7 @@ static boolean ReMincross;
  * Note that nodes are not placed into GD_rank(g) until mincross()
  * is called.
  */
-void dot_mincross(graph_t * g)
+void dot_mincross(graph_t * g, int doBalance)
 {
     int c, nc;
     char *s;
@@ -81,14 +81,14 @@ void dot_mincross(graph_t * g)
 
     for (nc = c = 0; c < GD_comp(g).size; c++) {
        init_mccomp(g, c);
-       nc += mincross(g, 0, 2);
+       nc += mincross(g, 0, 2, doBalance);
     }
 
     merge2(g);
 
     /* run mincross on contents of each cluster */
     for (c = 1; c <= GD_n_cluster(g); c++) {
-       nc += mincross_clust(g, GD_clust(g)[c]);
+       nc += mincross_clust(g, GD_clust(g)[c], doBalance);
 #ifdef DEBUG
        check_vlists(GD_clust(g)[c]);
        check_order();
@@ -99,7 +99,7 @@ void dot_mincross(graph_t * g)
        && (!(s = agget(g, "remincross")) || (mapbool(s)))) {
        mark_lowclusters(g);
        ReMincross = TRUE;
-       nc = mincross(g, 2, 2);
+       nc = mincross(g, 2, 2, doBalance);
 #ifdef DEBUG
        for (c = 1; c <= GD_n_cluster(g); c++)
            check_vlists(GD_clust(g)[c]);
@@ -224,7 +224,7 @@ static void ordered_edges(graph_t * g)
     }
 }
 
-static int mincross_clust(graph_t * par, graph_t * g)
+static int mincross_clust(graph_t * par, graph_t * g, int doBalance)
 {
     int c, nc;
 
@@ -232,10 +232,10 @@ static int mincross_clust(graph_t * par, graph_t * g)
     ordered_edges(g);
     flat_breakcycles(g);
     flat_reorder(g);
-    nc = mincross(g, 2, 2);
+    nc = mincross(g, 2, 2, doBalance);
 
     for (c = 1; c <= GD_n_cluster(g); c++)
-       nc += mincross_clust(g, GD_clust(g)[c]);
+       nc += mincross_clust(g, GD_clust(g)[c], doBalance);
 
     save_vlist(g);
     return nc;
@@ -331,167 +331,144 @@ static void exchange(node_t * v, node_t * w)
     GD_rank(Root)[r].v[vi] = w;
 }
 
-
-void
-balanceNodes(graph_t *g, int r, node_t *v, node_t* w)
+static void balanceNodes(graph_t * g, int r, node_t * v, node_t * w)
 {
-  node_t *s; //separator node
-  int sepIndex;
-  int nullType; //type of null nodes
-  int cntDummy = 0, cntOri = 0;
-  int k = 0, m = 0, k1 = 0, m1 = 0, i = 0;
-
-  //printf("Balancing nodes ... \n");
-  //printf("r = %d\n", r);
-
-  //we only consider v and w of different types
-  if (ND_node_type(v) == ND_node_type(w))
-    return;
-
-  //count the number of dummy and original nodes
-  for (i = 0; i < GD_rank(g)[r].n; i++) 
-  {
-    if (ND_node_type(GD_rank(g)[r].v[i]) == NORMAL )
-      cntOri++;
-    else
-      cntDummy++;
-  }
-
-  if (cntOri < cntDummy)
-  {
-    if (ND_node_type(v) == NORMAL)
-      s = v;
-    else s = w;
-  }
-  else
-  {
-    if (ND_node_type(v) == NORMAL)
-      s = w;
-    else s = v;
-  }
-
-  //get the separator node index
-  for (i = 0; i < GD_rank(g)[r].n; i++) 
-  {
-    if (GD_rank(g)[r].v[i] == s)
-      sepIndex = i;
-  }  
-
-  nullType = (ND_node_type(s) == NORMAL) ? VIRTUAL : NORMAL;
-  
-  //count the number of null nodes to the left and right of the separator node
-  for (i = sepIndex-1; i >= 0; i--)
-  {
-    if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
-      k++;
-    else break;
-  }
-
-  for (i = sepIndex+1; i < GD_rank(g)[r].n; i++)
-  {
-    if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
-      m++;
-    else break;
-
-  }
-
-  //now exchange v,w and calculate the same counts
-
-  exchange(v, w);
-  
-  //get the separator node index
-  for (i = 0; i < GD_rank(g)[r].n; i++) 
-  {
-    if (GD_rank(g)[r].v[i] == s)
-      sepIndex = i;
-  }  
-
-  //count the number of null nodes to the left and right of the separator node
-  for (i = sepIndex-1; i >= 0; i--)
-  {
-    if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
-      k1++;
-    else break;
-  }
-
-  for (i = sepIndex+1; i < GD_rank(g)[r].n; i++)
-  {
-    if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
-      m1++;
-    else break;
-  }
-
-  if (abs(k1-m1) > abs(k-m))
-  {
-    //printf("exchanging to revert to original ordering...\n");
-    exchange(v,w); //revert to the original ordering
-  }
-
-  //printf("v=%s, w=%s, k=%d, m=%d, k1=%d, m1=%d\n", v->name, w->name, k, m, k1, m1);
-}
+    node_t *s;                 /* separator node */
+    int sepIndex;
+    int nullType;              /* type of null nodes */
+    int cntDummy = 0, cntOri = 0;
+    int k = 0, m = 0, k1 = 0, m1 = 0, i = 0;
+
+    /* we only consider v and w of different types */
+    if (ND_node_type(v) == ND_node_type(w))
+       return;
 
+    /* count the number of dummy and original nodes */
+    for (i = 0; i < GD_rank(g)[r].n; i++) {
+       if (ND_node_type(GD_rank(g)[r].v[i]) == NORMAL)
+           cntOri++;
+       else
+           cntDummy++;
+    }
 
-static int 
-balance(graph_t * g)
-{
-    int i, c0, c1, rv;
-    node_t *v, *w;
-    int r;
+    if (cntOri < cntDummy) {
+       if (ND_node_type(v) == NORMAL)
+           s = v;
+       else
+           s = w;
+    } else {
+       if (ND_node_type(v) == NORMAL)
+           s = w;
+       else
+           s = v;
+    }
 
-    rv = 0;
+    /* get the separator node index */
+    for (i = 0; i < GD_rank(g)[r].n; i++) {
+       if (GD_rank(g)[r].v[i] == s)
+           sepIndex = i;
+    }
 
-    //printf("maxr = %d, minr = %d\n", GD_maxrank(g), GD_minrank(g));
+    nullType = (ND_node_type(s) == NORMAL) ? VIRTUAL : NORMAL;
 
-    for (r = GD_maxrank(g); r >= GD_minrank(g); r--)
-    {
+    /* count the number of null nodes to the left and 
+     * right of the separator node 
+     */
+    for (i = sepIndex - 1; i >= 0; i--) {
+       if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
+           k++;
+       else
+           break;
+    }
 
-      GD_rank(g)[r].candidate = FALSE;
-      for (i = 0; i < GD_rank(g)[r].n - 1; i++) 
-      //for (i = GD_rank(g)[r].n-2; i >= 0; i--) 
-      {
-       v = GD_rank(g)[r].v[i];
-       w = GD_rank(g)[r].v[i + 1];
-       assert(ND_order(v) < ND_order(w));
-       if (left2right(g, v, w))
-           continue;
-       c0 = c1 = 0;
-       if (r > 0) {
-           c0 += in_cross(v, w);
-           c1 += in_cross(w, v);
-       }
+    for (i = sepIndex + 1; i < GD_rank(g)[r].n; i++) {
+       if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
+           m++;
+       else
+           break;
+    }
 
-       //printf("before.... c0 = %d, c1 = %d\n", c0, c1);
+    /* now exchange v,w and calculate the same counts */
 
-       if (GD_rank(g)[r + 1].n > 0) {
-           c0 += out_cross(v, w);
-           c1 += out_cross(w, v);
-       }
+    exchange(v, w);
 
-       //printf("after.... c0 = %d, c1 = %d\n", c0, c1);
+    /* get the separator node index */
+    for (i = 0; i < GD_rank(g)[r].n; i++) {
+       if (GD_rank(g)[r].v[i] == s)
+           sepIndex = i;
+    }
 
-       //printf("r = %d, c0 = %d, c1 = %d\n",r, c0, c1);
+    /* count the number of null nodes to the left and 
+     * right of the separator node 
+     */
+    for (i = sepIndex - 1; i >= 0; i--) {
+       if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
+           k1++;
+       else
+           break;
+    }
 
-       /*if ((c1 < c0) || ((c0 > 0) && reverse && (c1 == c0))) {
-           exchange(v, w);
-           rv += (c0 - c1);
-           GD_rank(Root)[r].valid = FALSE;
-           GD_rank(g)[r].candidate = TRUE;
+    for (i = sepIndex + 1; i < GD_rank(g)[r].n; i++) {
+       if (ND_node_type(GD_rank(g)[r].v[i]) == nullType)
+           m1++;
+       else
+           break;
+    }
 
-           if (r > GD_minrank(g)) {
-               GD_rank(Root)[r - 1].valid = FALSE;
-               GD_rank(g)[r - 1].candidate = TRUE;
+    if (abs(k1 - m1) > abs(k - m)) {
+       exchange(v, w);         //revert to the original ordering
+    }
+}
+
+static int balance(graph_t * g)
+{
+    int i, c0, c1, rv;
+    node_t *v, *w;
+    int r;
+
+    rv = 0;
+
+    for (r = GD_maxrank(g); r >= GD_minrank(g); r--) {
+
+       GD_rank(g)[r].candidate = FALSE;
+       for (i = 0; i < GD_rank(g)[r].n - 1; i++) {
+           v = GD_rank(g)[r].v[i];
+           w = GD_rank(g)[r].v[i + 1];
+           assert(ND_order(v) < ND_order(w));
+           if (left2right(g, v, w))
+               continue;
+           c0 = c1 = 0;
+           if (r > 0) {
+               c0 += in_cross(v, w);
+               c1 += in_cross(w, v);
            }
-           if (r < GD_maxrank(g)) {
-               GD_rank(Root)[r + 1].valid = FALSE;
-               GD_rank(g)[r + 1].candidate = TRUE;
+
+           if (GD_rank(g)[r + 1].n > 0) {
+               c0 += out_cross(v, w);
+               c1 += out_cross(w, v);
+           }
+#if 0
+           if ((c1 < c0) || ((c0 > 0) && reverse && (c1 == c0))) {
+               exchange(v, w);
+               rv += (c0 - c1);
+               GD_rank(Root)[r].valid = FALSE;
+               GD_rank(g)[r].candidate = TRUE;
+
+               if (r > GD_minrank(g)) {
+                   GD_rank(Root)[r - 1].valid = FALSE;
+                   GD_rank(g)[r - 1].candidate = TRUE;
+               }
+               if (r < GD_maxrank(g)) {
+                   GD_rank(Root)[r + 1].valid = FALSE;
+                   GD_rank(g)[r + 1].candidate = TRUE;
+               }
+           }
+#endif
+
+           if (c1 <= c0) {
+               balanceNodes(g, r, v, w);
            }
-       }*/
-       
-       if (c1 <= c0)
-       {
-         balanceNodes(g, r, v, w);
        }
-      }
     }
     return rv;
 }
@@ -562,7 +539,7 @@ static void transpose(graph_t * g, int reverse)
     } while (delta >= 1);
 }
 
-static int mincross(graph_t * g, int startpass, int endpass)
+static int mincross(graph_t * g, int startpass, int endpass, int doBalance)
 {
     int maxthispass, iter, trying, pass;
     int cur_cross, best_cross;
@@ -619,6 +596,11 @@ static int mincross(graph_t * g, int startpass, int endpass)
        transpose(g, FALSE);
        best_cross = ncross(g);
     }
+    if (doBalance) {
+       for (iter = 0; iter < maxthispass; iter++)
+           balance(g);
+    }
+
     return best_cross;
 }
 
@@ -860,10 +842,12 @@ void flat_rev(Agraph_t * g, Agedge_t * e)
     int j;
     Agedge_t *rev;
 
-    if (!ND_flat_out(e->head).list) rev = NULL;
-    else for (j = 0; (rev = ND_flat_out(e->head).list[j]); j++)
-       if (rev->head == e->tail)
-           break;
+    if (!ND_flat_out(e->head).list)
+       rev = NULL;
+    else
+       for (j = 0; (rev = ND_flat_out(e->head).list[j]); j++)
+           if (rev->head == e->tail)
+               break;
     if (rev) {
        merge_oneway(e, rev);
        if (ED_to_virt(e) == 0)
index 42b2ffe3cd4d88c8698cccc956eb67642e19ef36..b03a6ca3c003f67487529a35a8074beb90f4c268 100644 (file)
  */
 
 #include "dot.h"
+#include "aspect.h"
 
 static int nsiter2(graph_t * g);
 static void create_aux_edges(graph_t * g);
 static void remove_aux_edges(graph_t * g);
 static void set_xcoords(graph_t * g);
 static void set_ycoords(graph_t * g);
-static void set_aspect(graph_t * g);
+static void set_aspect(graph_t * g, aspect_t* );
 static void expand_leaves(graph_t * g);
 static void make_lrvn(graph_t * g);
 static void contain_nodes(graph_t * g);
@@ -118,7 +119,7 @@ connectGraph (graph_t* g)
     }
 }
 
-void dot_position(graph_t * g)
+void dot_position(graph_t * g, aspect_t* asp)
 {
     if (GD_nlist(g) == NULL)
        return;                 /* ignore empty graph */
@@ -135,7 +136,7 @@ void dot_position(graph_t * g)
        assert(rank(g, 2, nsiter2(g)) == 0);
     }
     set_xcoords(g);
-    set_aspect(g);
+    set_aspect(g, asp);
     remove_aux_edges(g);       /* must come after set_aspect since we now
                                 * use GD_ln and GD_rn for bbox width.
                                 */
@@ -938,28 +939,36 @@ static void scale_bb(graph_t * g, graph_t * root, double xf, double yf)
     GD_bb(g).UR.y *= yf;
 }
 
-/**************************** EXTERNAL VARIABLES ***********************/
-extern double targetAR;
-extern double currentAR;
-extern double combiAR;
-extern int prevIterations;
-extern int curIterations;
-extern int nextiter;
-/**************************** EXTERNAL VARIABLES ***********************/
-
-
-/***********************************************************************
- *  Some additional codes have been added at the end of set_aspect
- *  function to estimate the next number of iterations for ranking phase
- ***********************************************************************/
-
+/* adjustAspectRatio:
+ */
+static void adjustAspectRatio (graph_t* g, aspect_t* asp)
+{
+    double AR = (GD_bb(g).UR.x - GD_bb(g).LL.x)/(GD_bb(g).UR.y - GD_bb(g).LL.y);
+    if (Verbose) {
+        fprintf(stderr, "AR=%0.4lf\t Area= %0.4lf\t", AR, (double)(GD_bb(g).UR.x - GD_bb(g).LL.x)*(GD_bb(g).UR.y - GD_bb(g).LL.y)/10000.0);
+        fprintf(stderr, "Dummy=%d\n", countDummyNodes(g));
+    }
+    if (AR > 1.1*asp->targetAR) {
+      asp->nextIter = (int)(asp->targetAR * (double)(asp->curIterations - asp->prevIterations)/(AR));
+    }
+    else if (AR <= 0.8 * asp->targetAR) {
+      asp->nextIter = -1;
+      if (Verbose)
+        fprintf(stderr, "Going to apply another expansion.\n");
+    }
+    else {
+       asp->nextIter = 0;
+    }
+    if (Verbose)
+        fprintf(stderr, "next#iter=%d\n", asp->nextIter);
+}
 
 /* set_aspect:
  * Set bounding boxes and, if ratio is set, rescale graph.
  * Note that if some dimension shrinks, there may be problems
  * with labels.
  */
-static void set_aspect(graph_t * g)
+static void set_aspect(graph_t * g, aspect_t* asp)
 {
     double xf = 0.0, yf = 0.0, actual, desired;
     node_t *n;
@@ -1037,28 +1046,7 @@ static void set_aspect(graph_t * g)
        }
     }
 
-#ifdef ASPECT
-    double AR = (GD_bb(g).UR.x - GD_bb(g).LL.x)/(GD_bb(g).UR.y - GD_bb(g).LL.y);
-    if (Verbose) {
-        fprintf(stderr, "AR=%0.4lf\t Area= %0.4lf\t", AR, (double)(GD_bb(g).UR.x - GD_bb(g).LL.x)*(GD_bb(g).UR.y - GD_bb(g).LL.y)/10000.0);
-        fprintf(stderr, "Dummy=%d\n", countDummyNodes(g));
-    }
-    if (AR > 1.1*targetAR)
-    {
-      nextiter = (int)(targetAR * (double)(curIterations - prevIterations)/(AR));
-    }
-    else if (AR <= 0.8 * targetAR)
-    {
-      nextiter = -1;
-      if (Verbose)
-        fprintf(stderr, "Going to apply another expansion.\n");
-    }
-    else {
-       nextiter = 0;
-    }
-    if (Verbose)
-        fprintf(stderr, "next#iter=%d\n", nextiter);
-#endif
+    if (asp) adjustAspectRatio (g, asp);
 }
 
 static point resize_leaf(node_t * leaf, point lbound)
index 695cfc44205e2fa9322cc3a9d6be0faa68085589..747a3df8461b860fb6903c591bdbe32f63e31c24 100644 (file)
 
 #include       "dot.h"
 
-void expand_ranksets(graph_t *);
-static void saveVirtualEdges(graph_t *);
-static void restoreVirtualEdges(graph_t *);
-
 static void 
 renewlist(elist * L)
 {
@@ -62,10 +58,11 @@ cleanup1(graph_t * g)
     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
        for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
            f = ED_to_virt(e);
+           /* Null out any other references to f to make sure we don't 
+            * handle it a second time. For example, parallel multiedges 
+            * share a virtual edge.
+            */
            if (f && (e == ED_to_orig(f))) {
-               /* Null out any other references to f to make sure we don't handle it
-                * a second time. For example, parallel multiedges share a virtual edge.
-                */
                edge_t *e1, *f1;
                for (e1 = agfstout(g, n); e1; e1 = agnxtout(g, e1)) {
                    if (e != e1) {
@@ -262,7 +259,7 @@ collapse_cluster(graph_t * g, graph_t * subg)
        return;
     make_new_cluster(g, subg);
     if (CL_type == LOCAL) {
-       dot_rank(subg);
+       dot_rank(subg, 0);
        cluster_leader(subg);
     } else
        dot_scan_ranks(subg);
@@ -405,7 +402,7 @@ void rank1(graph_t * g)
  * Leaf sets and clusters remain merged.
  * Sets minrank and maxrank appropriately.
  */
-void expand_ranksets(graph_t * g)
+static void expand_ranksets(graph_t * g, aspect_t* asp)
 {
     int c;
     node_t *n, *leader;
@@ -418,11 +415,8 @@ void expand_ranksets(graph_t * g)
            /* The following works because ND_rank(n) == 0 if n is not in a
             * cluster, and ND_rank(n) = the local rank offset if n is in
             * a cluster. */
-           if (leader != n)
-#ifdef ASPECT
-               if (ND_rank(n) == 0)
-#endif
-                   ND_rank(n) += ND_rank(leader);
+           if ((leader != n) && (!asp || (ND_rank(n) == 0)))
+               ND_rank(n) += ND_rank(leader);
 
            if (GD_maxrank(g) < ND_rank(n))
                GD_maxrank(g) = ND_rank(n);
@@ -465,96 +459,98 @@ setRanks (graph_t* g, attrsym_t* lsym)
 }
 #endif
 
-node_t **virtualEdgeHeadList = NULL;
-node_t **virtualEdgeTailList = NULL;
-
-int nVirtualEdges = 0;
+#ifdef UNUSED
+static node_t **virtualEdgeHeadList = NULL;
+static node_t **virtualEdgeTailList = NULL;
+static int nVirtualEdges = 0;
 
 static void
 saveVirtualEdges(graph_t *g)
 {
-  if (virtualEdgeHeadList != NULL)
-  {
-    free(virtualEdgeHeadList);
-  }
-  if (virtualEdgeTailList != NULL)
-  {
-    free(virtualEdgeTailList);
-  }
-
-  //allocate memory
     edge_t *e;
     node_t *n;
     int cnt = 0;
     int lc;
     
-    for (n = agfstnode(g); n; n = agnxtnode(g, n))
-      for (lc = 0; lc < ND_in(n).size; lc++)
-      {
-       e = ND_in(n).list[lc];
-       if (ED_edge_type(e) == VIRTUAL)
-         cnt++;
-      }
+    if (virtualEdgeHeadList != NULL) {
+       free(virtualEdgeHeadList);
+    }
+    if (virtualEdgeTailList != NULL) {
+       free(virtualEdgeTailList);
+    }
+
+  /* allocate memory */
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       for (lc = 0; lc < ND_in(n).size; lc++) {
+           e = ND_in(n).list[lc];
+           if (ED_edge_type(e) == VIRTUAL) cnt++;
+       }
+    }
 
     nVirtualEdges = cnt;
-    virtualEdgeHeadList = (node_t **)malloc(sizeof(node_t *) * cnt);
-    virtualEdgeTailList = (node_t **)malloc(sizeof(node_t *) * cnt);
-
-    for (n = agfstnode(g); n; n = agnxtnode(g, n))
-      for (lc = 0, cnt = 0; lc < ND_in(n).size; lc++)
-      {
-       e = ND_in(n).list[lc];
-       if (ED_edge_type(e) == VIRTUAL)
-         {
-           virtualEdgeHeadList[cnt] = e->head;
-           virtualEdgeTailList[cnt] = e->tail;
-           printf("saved virtual edge: %s->%s\n", virtualEdgeTailList[cnt]->name, virtualEdgeHeadList[cnt]->name);         
-           cnt++;
-         }
-      }
+    virtualEdgeHeadList = N_GNEW(cnt, node_t*);
+    virtualEdgeTailList = N_GNEW(cnt, node_t*);
+
+    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+       for (lc = 0, cnt = 0; lc < ND_in(n).size; lc++) {
+           e = ND_in(n).list[lc];
+           if (ED_edge_type(e) == VIRTUAL) {
+               virtualEdgeHeadList[cnt] = e->head;
+               virtualEdgeTailList[cnt] = e->tail;
+               if (Verbose)
+                   printf("saved virtual edge: %s->%s\n", 
+                       virtualEdgeTailList[cnt]->name, 
+                       virtualEdgeHeadList[cnt]->name);            
+               cnt++;
+           }
+       }
+    }
 }
 
 static void
 restoreVirtualEdges(graph_t *g)
 {
-  int i;
-  edge_t e;
-
-  for (i = 0; i < nVirtualEdges; i++)
-  {
-    if (virtualEdgeTailList[i] && virtualEdgeHeadList[i])
-      {
-       printf("restoring virtual edge: %s->%s\n", virtualEdgeTailList[i]->name, virtualEdgeHeadList[i]->name);
-       virtual_edge(virtualEdgeTailList[i], virtualEdgeHeadList[i], NULL);
-      }
-    else
-      {
-       printf("Deleted?\n");
-      }
-  }
-  printf("restored %d virt edges\n", nVirtualEdges);
-  getchar();
+    int i;
+    edge_t e;
+
+    for (i = 0; i < nVirtualEdges; i++) {
+       if (virtualEdgeTailList[i] && virtualEdgeHeadList[i]) {
+           if (Verbose)
+               printf("restoring virtual edge: %s->%s\n", 
+                   virtualEdgeTailList[i]->name, virtualEdgeHeadList[i]->name);
+           virtual_edge(virtualEdgeTailList[i], virtualEdgeHeadList[i], NULL);
+       }
+    }
+    if (Verbose)
+       printf("restored %d virt edges\n", nVirtualEdges);
 }
+#endif
 
-extern int nextiter;
-
-
-void dot_rank(graph_t * g)
+/* dot_rank:
+ * asp != NULL => g is root
+ */
+void dot_rank(graph_t * g, aspect_t* asp)
 {
     point p;
 #ifdef ALLOW_LEVELS
     attrsym_t* N_level;
 #endif
     edgelabel_ranks(g);
-#ifdef ASPECT
-    init_UF_size(g);
-    initEdgeTypes(g);
-#endif
+
+    if (asp) {
+       init_UF_size(g);
+       initEdgeTypes(g);
+    }
+
     collapse_sets(g,g);
     /*collapse_leaves(g); */
     class1(g);
     p = minmax_edges(g);
     decompose(g, 0);
+    if (asp && ((g->u.comp.size > 1)||(g->u.n_cluster > 0))) {
+       asp->badGraph = 1;
+       asp = NULL;
+    }
     acyclic(g);
     if (minmax_edges2(g, p))
        decompose(g, 0);
@@ -563,11 +559,13 @@ void dot_rank(graph_t * g)
        setRanks(g, N_level);
     else
 #endif
-#ifdef ASPECT
-#else
-    rank1(g);
-#endif
-    expand_ranksets(g);
+
+    if (asp)
+       rank3(g, asp);
+    else
+       rank1(g);
+
+    expand_ranksets(g, asp);
     cleanup1(g);
 }