Home | History | Annotate | Download | only in src
      1 /* VCG description handler for Bison.
      2 
      3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
      4    Foundation, Inc.
      5 
      6    This file is part of Bison, the GNU Compiler Compiler.
      7 
      8    Bison is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 2, or (at your option)
     11    any later version.
     12 
     13    Bison is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with Bison; see the file COPYING.  If not, write to
     20    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21    Boston, MA 02110-1301, USA.  */
     22 
     23 #include <config.h>
     24 #include "system.h"
     25 
     26 #include <quotearg.h>
     27 
     28 #include "vcg.h"
     29 #include "vcg_defaults.h"
     30 
     31 /* Return an unambiguous printable representated, for NAME, suitable
     32    for C strings.  Use slot 2 since the user may use slots 0 and 1.
     33    */
     34 
     35 static char const *
     36 quote (char const *name)
     37 {
     38   return quotearg_n_style (2, c_quoting_style, name);
     39 }
     40 
     41 
     42 /* Initialize a graph with the default values. */
     43 void
     44 new_graph (graph *g)
     45 {
     46   g->title = G_TITLE;
     47   g->label = G_LABEL;
     48 
     49   g->infos[0] = G_INFOS1;
     50   g->infos[1] = G_INFOS2;
     51   g->infos[2] = G_INFOS3;
     52 
     53   g->color = G_COLOR;
     54   g->textcolor = G_TEXTCOLOR;
     55   g->bordercolor = G_BORDERCOLOR;
     56 
     57   g->width = G_WIDTH;
     58   g->height = G_HEIGHT;
     59   g->borderwidth = G_BORDERWIDTH;
     60   g->x = G_X;
     61   g->y = G_Y;
     62   g->folding = G_FOLDING;
     63   g->shrink = G_SHRINK;
     64   g->stretch = G_STRETCH;
     65 
     66   g->textmode = G_TEXTMODE;
     67   g->shape = G_SHAPE;
     68 
     69   g->vertical_order = G_VERTICAL_ORDER;
     70   g->horizontal_order = G_HORIZONTAL_ORDER;
     71 
     72   g->xmax = G_XMAX; /* Not output. */
     73   g->ymax = G_YMAX; /* Not output. */
     74 
     75   g->xbase = G_XBASE;
     76   g->ybase = G_YBASE;
     77 
     78   g->xspace = G_XSPACE;
     79   g->yspace = G_YSPACE;
     80   g->xlspace = G_XLSPACE; /* Not output. */
     81 
     82   g->xraster = G_XRASTER;
     83   g->yraster = G_YRASTER;
     84   g->xlraster = G_XLRASTER;
     85 
     86   g->hidden = G_HIDDEN; /* No default value. */
     87 
     88   g->classname = G_CLASSNAME; /* No class name association. */
     89 
     90   g->layout_downfactor = G_LAYOUT_DOWNFACTOR;
     91   g->layout_upfactor = G_LAYOUT_UPFACTOR;
     92   g->layout_nearfactor = G_LAYOUT_NEARFACTOR;
     93   g->layout_splinefactor = G_LAYOUT_SPLINEFACTOR;
     94 
     95   g->late_edge_labels = G_LATE_EDGE_LABELS;
     96   g->display_edge_labels = G_DISPLAY_EDGE_LABELS;
     97   g->dirty_edge_labels = G_DIRTY_EDGE_LABELS;
     98   g->finetuning = G_FINETUNING;
     99   g->ignore_singles = G_IGNORE_SINGLES;
    100   g->priority_phase = G_PRIORITY_PHASE;
    101   g->manhattan_edges = G_MANHATTAN_EDGES;
    102   g->smanhattan_edges = G_SMANHATTAN_EDGES;
    103   g->near_edges = G_NEAR_EDGES;
    104 
    105   g->orientation = G_ORIENTATION;
    106   g->node_alignment = G_NODE_ALIGNMENT;
    107   g->port_sharing = G_PORT_SHARING;
    108   g->arrow_mode = G_ARROW_MODE;
    109   g->treefactor = G_TREEFACTOR;
    110   g->spreadlevel = G_SPREADLEVEL;
    111   g->crossing_weight = G_CROSSING_WEIGHT;
    112   g->crossing_phase2 = G_CROSSING_PHASE2;
    113   g->crossing_optimization = G_CROSSING_OPTIMIZATION;
    114   g->view = G_VIEW;
    115 
    116   g->edges = G_EDGES;
    117   g->nodes = G_NODES;
    118   g->splines = G_SPLINES;
    119 
    120   g->bmax = G_BMAX;
    121   g->cmin = G_CMIN;
    122   g->cmax = G_CMAX;
    123   g->pmin = G_PMIN;
    124   g->pmax = G_PMAX;
    125   g->rmin = G_RMIN;
    126   g->rmax = G_RMAX;
    127   g->smax = G_SMAX;
    128 
    129   g->node_list = G_NODE_LIST;
    130   g->edge_list = G_EDGE_LIST;
    131 
    132   new_edge (&g->edge);
    133   new_node (&g->node);
    134 }
    135 
    136 /* Initialize a node with the default values. */
    137 void
    138 new_node (node *n)
    139 {
    140   n->title = N_TITLE;
    141   n->label = N_LABEL;
    142 
    143   n->locx = N_LOCX; /* Default unspcified. */
    144   n->locy = N_LOCY; /* Default unspcified. */
    145 
    146   n->vertical_order = N_VERTICAL_ORDER;	/* Default unspcified. */
    147   n->horizontal_order = N_HORIZONTAL_ORDER;	/* Default unspcified. */
    148 
    149   n->width = N_WIDTH; /* We assume that we can't define it now. */
    150   n->height = N_HEIGHT; /* Also. */
    151 
    152   n->shrink = N_SHRINK;
    153   n->stretch = N_STRETCH;
    154 
    155   n->folding = N_FOLDING; /* No explicit default value. */
    156 
    157   n->shape = N_SHAPE;
    158   n->textmode = N_TEXTMODE;
    159   n->borderwidth = N_BORDERWIDTH;
    160 
    161   n->color = N_COLOR;
    162   n->textcolor = N_TEXTCOLOR;
    163   n->bordercolor = N_BORDERCOLOR;
    164 
    165   n->infos[0] = N_INFOS1;
    166   n->infos[1] = N_INFOS2;
    167   n->infos[2] = N_INFOS3;
    168 
    169   n->next = N_NEXT;
    170 }
    171 
    172 /* Initialize an edge with the default values. */
    173 void
    174 new_edge (edge *e)
    175 {
    176   e->type = E_EDGE_TYPE;
    177 
    178   e->sourcename = E_SOURCENAME;
    179   e->targetname = E_TARGETNAME;
    180   e->label = E_LABEL;
    181 
    182   e->linestyle = E_LINESTYLE;
    183   e->thickness = E_THICKNESS;
    184 
    185   e->class = E_CLASS;
    186 
    187   e->color = E_COLOR;
    188   e->textcolor = E_TEXTCOLOR;
    189   e->arrowcolor = E_ARROWCOLOR;
    190   e->backarrowcolor = E_BACKARROWCOLOR;
    191 
    192   e->arrowsize = E_ARROWSIZE;
    193   e->backarrowsize = E_BACKARROWSIZE;
    194   e->arrowstyle = E_ARROWSTYLE;
    195 
    196   e->backarrowstyle = E_BACKARROWSTYLE;
    197 
    198   e->priority = E_PRIORITY;
    199 
    200   e->anchor = E_ANCHOR;
    201 
    202   e->horizontal_order = E_HORIZONTAL_ORDER;
    203 
    204   e->next = E_NEXT;
    205 }
    206 
    207 /*----------------------------------------------.
    208 | Get functions.	                        |
    209 | Return string corresponding to an enum value. |
    210 `----------------------------------------------*/
    211 
    212 static const char *
    213 get_color_str (enum color color)
    214 {
    215   switch (color)
    216     {
    217     default:		abort ();
    218     case white:		return "white";
    219     case blue:		return "blue";
    220     case red:		return "red";
    221     case green:		return "green";
    222     case yellow:	return "yellow";
    223     case magenta:	return "magenta";
    224     case cyan:		return "cyan";
    225     case darkgrey:	return "darkgrey";
    226     case darkblue:	return "darkblue";
    227     case darkred:	return "darkred";
    228     case darkgreen:	return "darkgreen";
    229     case darkyellow:	return "darkyellow";
    230     case darkmagenta:	return "darkmagenta";
    231     case darkcyan:	return "darkcyan";
    232     case gold:		return "gold";
    233     case lightgrey:	return "lightgrey";
    234     case lightblue:	return "lightblue";
    235     case lightred:	return "lightred";
    236     case lightgreen:	return "lightgreen";
    237     case lightyellow:	return "lightyellow";
    238     case lightmagenta:	return "lightmagenta";
    239     case lightcyan:	return "lightcyan";
    240     case lilac:		return "lilac";
    241     case turquoise:	return "turquoise";
    242     case aquamarine:	return "aquamarine";
    243     case khaki:		return "khaki";
    244     case purple:	return "purple";
    245     case yellowgreen:	return "yellowgreen";
    246     case pink:		return "pink";
    247     case orange:	return "orange";
    248     case orchid:	return "orchid";
    249     case black:		return "black";
    250     }
    251 }
    252 
    253 static const char *
    254 get_textmode_str (enum textmode textmode)
    255 {
    256   switch (textmode)
    257     {
    258     default:		abort ();
    259     case centered:	return "center";
    260     case left_justify:	return "left_justify";
    261     case right_justify:	return "right_justify";
    262     }
    263 }
    264 
    265 static const char *
    266 get_shape_str (enum shape shape)
    267 {
    268   switch (shape)
    269     {
    270     default:		abort ();
    271     case box:		return "box";
    272     case rhomb:		return "rhomb";
    273     case ellipse:	return "ellipse";
    274     case triangle:	return "triangle";
    275     }
    276 }
    277 
    278 static const char *
    279 get_decision_str (enum decision decision)
    280 {
    281   switch (decision)
    282     {
    283     default:	abort ();
    284     case no:	return "no";
    285     case yes:	return "yes";
    286     }
    287 }
    288 
    289 static const char *
    290 get_orientation_str (enum orientation orientation)
    291 {
    292   switch (orientation)
    293     {
    294     default:		abort ();
    295     case top_to_bottom:	return "top_to_bottom";
    296     case bottom_to_top: return "bottom_to_top";
    297     case left_to_right: return "left_to_right";
    298     case right_to_left: return "right_to_left";
    299     }
    300 }
    301 
    302 static const char *
    303 get_node_alignment_str (enum alignment alignment)
    304 {
    305   switch (alignment)
    306     {
    307     default:		abort ();
    308     case center:	return "center";
    309     case top:		return "top";
    310     case bottom:	return "bottom";
    311     }
    312 }
    313 
    314 static const char *
    315 get_arrow_mode_str (enum arrow_mode arrow_mode)
    316 {
    317   switch (arrow_mode)
    318     {
    319     default:		abort ();
    320     case fixed:		return "fixed";
    321     case free_a:	return "free";
    322     }
    323 }
    324 
    325 static const char *
    326 get_crossing_type_str (enum crossing_type crossing_type)
    327 {
    328   switch (crossing_type)
    329     {
    330     default:		abort ();
    331     case bary:		return "bary";
    332     case median:	return "median";
    333     case barymedian:	return "barymedian";
    334     case medianbary:	return "medianbary";
    335     }
    336 }
    337 
    338 static const char *
    339 get_view_str (enum view view)
    340 {
    341   /* There is no way with vcg 1.30 to specify a normal view explicitly,
    342      so it is an error here if view == normal_view.  */
    343   switch (view)
    344     {
    345     default:		abort ();
    346     case cfish:		return "cfish";
    347     case pfish:		return "pfish";
    348     case fcfish:	return "fcfish";
    349     case fpfish:	return "fpfish";
    350     }
    351 }
    352 
    353 static const char *
    354 get_linestyle_str (enum linestyle linestyle)
    355 {
    356   switch (linestyle)
    357     {
    358     default:		abort ();
    359     case continuous:	return "continuous";
    360     case dashed:	return "dashed";
    361     case dotted:	return "dotted";
    362     case invisible:	return "invisible";
    363     }
    364 }
    365 
    366 static const char *
    367 get_arrowstyle_str (enum arrowstyle arrowstyle)
    368 {
    369   switch (arrowstyle)
    370     {
    371     default:	abort ();
    372     case solid:	return "solid";
    373     case line:	return "line";
    374     case none:	return "none";
    375     }
    376 }
    377 
    378 /*------------------------------.
    379 | Add functions.	        |
    380 | Edge and nodes into a graph.  |
    381 `------------------------------*/
    382 
    383 void
    384 add_node (graph *g, node *n)
    385 {
    386   n->next = g->node_list;
    387   g->node_list = n;
    388 }
    389 
    390 void
    391 add_edge (graph *g, edge *e)
    392 {
    393   e->next = g->edge_list;
    394   g->edge_list = e;
    395 }
    396 
    397 void
    398 add_classname (graph *g, int val, const char *name)
    399 {
    400   struct classname *classname = xmalloc (sizeof *classname);
    401   classname->no = val;
    402   classname->name = name;
    403   classname->next = g->classname;
    404   g->classname = classname;
    405 }
    406 
    407 void
    408 add_infoname (graph *g, int integer, const char *str)
    409 {
    410   struct infoname *infoname = xmalloc (sizeof *infoname);
    411   infoname->integer = integer;
    412   infoname->chars = str;
    413   infoname->next = g->infoname;
    414   g->infoname = infoname;
    415 }
    416 
    417 /* Build a colorentry struct and add it to the list.  */
    418 void
    419 add_colorentry (graph *g, int color_idx, int red_cp,
    420 		int green_cp, int blue_cp)
    421 {
    422   struct colorentry *ce = xmalloc (sizeof *ce);
    423   ce->color_index = color_idx;
    424   ce->red_cp = red_cp;
    425   ce->green_cp = green_cp;
    426   ce->blue_cp = blue_cp;
    427   ce->next = g->colorentry;
    428   g->colorentry = ce;
    429 }
    430 
    431 /*-------------------------------------.
    432 | Open and close functions (formatted) |
    433 `-------------------------------------*/
    434 
    435 void
    436 open_edge (edge *e, FILE *fout)
    437 {
    438   switch (e->type)
    439     {
    440     case normal_edge:
    441       fputs ("\tedge: {\n", fout);
    442       break;
    443     case back_edge:
    444       fputs ("\tbackedge: {\n", fout);
    445       break;
    446     case near_edge:
    447       fputs ("\tnearedge: {\n", fout);
    448       break;
    449     case bent_near_edge:
    450       fputs ("\tbentnearedge: {\n", fout);
    451       break;
    452     default:
    453       fputs ("\tedge: {\n", fout);
    454     }
    455 }
    456 
    457 void
    458 close_edge (FILE *fout)
    459 {
    460   fputs ("\t}\n", fout);
    461 }
    462 
    463 void
    464 open_node (FILE *fout)
    465 {
    466   fputs ("\tnode: {\n", fout);
    467 }
    468 
    469 void
    470 close_node (FILE *fout)
    471 {
    472   fputs ("\t}\n", fout);
    473 }
    474 
    475 void
    476 open_graph (FILE *fout)
    477 {
    478   fputs ("graph: {\n", fout);
    479 }
    480 
    481 void
    482 close_graph (graph *g, FILE *fout)
    483 {
    484   fputc ('\n', fout);
    485 
    486   /* FIXME: Unallocate nodes and edges if required.  */
    487   {
    488     node *n;
    489 
    490     for (n = g->node_list; n; n = n->next)
    491       {
    492 	open_node (fout);
    493 	output_node (n, fout);
    494 	close_node (fout);
    495       }
    496   }
    497 
    498   fputc ('\n', fout);
    499 
    500   {
    501     edge *e;
    502 
    503     for (e = g->edge_list; e; e = e->next)
    504       {
    505 	open_edge (e, fout);
    506 	output_edge (e, fout);
    507 	close_edge (fout);
    508       }
    509   }
    510 
    511   fputs ("}\n", fout);
    512 }
    513 
    514 /*-------------------------------------------.
    515 | Output functions (formatted) in file FOUT  |
    516 `-------------------------------------------*/
    517 
    518 void
    519 output_node (node *n, FILE *fout)
    520 {
    521   if (n->title != N_TITLE)
    522     fprintf (fout, "\t\ttitle:\t%s\n", quote (n->title));
    523   if (n->label != N_LABEL)
    524     fprintf (fout, "\t\tlabel:\t%s\n", quote (n->label));
    525 
    526   if ((n->locx != N_LOCX) && (n->locy != N_LOCY))
    527     fprintf (fout, "\t\tloc { x: %d  y: %d }\t\n", n->locx, n->locy);
    528 
    529   if (n->vertical_order != N_VERTICAL_ORDER)
    530     fprintf (fout, "\t\tvertical_order:\t%d\n", n->vertical_order);
    531   if (n->horizontal_order != N_HORIZONTAL_ORDER)
    532     fprintf (fout, "\t\thorizontal_order:\t%d\n", n->horizontal_order);
    533 
    534   if (n->width != N_WIDTH)
    535     fprintf (fout, "\t\twidth:\t%d\n", n->width);
    536   if (n->height != N_HEIGHT)
    537     fprintf (fout, "\t\theight:\t%d\n", n->height);
    538 
    539   if (n->shrink != N_SHRINK)
    540     fprintf (fout, "\t\tshrink:\t%d\n", n->shrink);
    541   if (n->stretch != N_STRETCH)
    542     fprintf (fout, "\t\tstretch:\t%d\n", n->stretch);
    543 
    544   if (n->folding != N_FOLDING)
    545     fprintf (fout, "\t\tfolding:\t%d\n", n->folding);
    546 
    547   if (n->textmode != N_TEXTMODE)
    548     fprintf (fout, "\t\ttextmode:\t%s\n",
    549 	     get_textmode_str (n->textmode));
    550 
    551   if (n->shape != N_SHAPE)
    552     fprintf (fout, "\t\tshape:\t%s\n", get_shape_str (n->shape));
    553 
    554   if (n->borderwidth != N_BORDERWIDTH)
    555     fprintf (fout, "\t\tborderwidth:\t%d\n", n->borderwidth);
    556 
    557   if (n->color != N_COLOR)
    558     fprintf (fout, "\t\tcolor:\t%s\n", get_color_str (n->color));
    559   if (n->textcolor != N_TEXTCOLOR)
    560     fprintf (fout, "\t\ttextcolor:\t%s\n",
    561 	     get_color_str (n->textcolor));
    562   if (n->bordercolor != N_BORDERCOLOR)
    563     fprintf (fout, "\t\tbordercolor:\t%s\n",
    564 	     get_color_str (n->bordercolor));
    565 
    566   {
    567     int i;
    568     for (i = 0; i < 3; ++i)
    569       if (n->infos[i])
    570 	fprintf (fout, "\t\tinfo%d:\t%s\n",
    571 		 i, quote (n->infos[i]));
    572   }
    573 }
    574 
    575 void
    576 output_edge (edge *e, FILE *fout)
    577 {
    578   /* FIXME: SOURCENAME and TARGETNAME are mandatory
    579      so it has to be fatal not to give these informations.  */
    580   if (e->sourcename != E_SOURCENAME)
    581     fprintf (fout, "\t\tsourcename:\t%s\n", quote (e->sourcename));
    582   if (e->targetname != E_TARGETNAME)
    583     fprintf (fout, "\t\ttargetname:\t%s\n", quote (e->targetname));
    584 
    585   if (e->label != E_LABEL)
    586     fprintf (fout, "\t\tlabel:\t%s\n", quote (e->label));
    587 
    588   if (e->linestyle != E_LINESTYLE)
    589     fprintf (fout, "\t\tlinestyle:\t%s\n", get_linestyle_str (e->linestyle));
    590 
    591   if (e->thickness != E_THICKNESS)
    592     fprintf (fout, "\t\tthickness:\t%d\n", e->thickness);
    593   if (e->class != E_CLASS)
    594     fprintf (fout, "\t\tclass:\t%d\n", e->class);
    595 
    596   if (e->color != E_COLOR)
    597     fprintf (fout, "\t\tcolor:\t%s\n", get_color_str (e->color));
    598   if (e->color != E_TEXTCOLOR)
    599     fprintf (fout, "\t\ttextcolor:\t%s\n",
    600 	     get_color_str (e->textcolor));
    601   if (e->arrowcolor != E_ARROWCOLOR)
    602     fprintf (fout, "\t\tarrowcolor:\t%s\n",
    603 	     get_color_str (e->arrowcolor));
    604   if (e->backarrowcolor != E_BACKARROWCOLOR)
    605     fprintf (fout, "\t\tbackarrowcolor:\t%s\n",
    606 	     get_color_str (e->backarrowcolor));
    607 
    608   if (e->arrowsize != E_ARROWSIZE)
    609     fprintf (fout, "\t\tarrowsize:\t%d\n", e->arrowsize);
    610   if (e->backarrowsize != E_BACKARROWSIZE)
    611     fprintf (fout, "\t\tbackarrowsize:\t%d\n", e->backarrowsize);
    612 
    613   if (e->arrowstyle != E_ARROWSTYLE)
    614     fprintf (fout, "\t\tarrowstyle:\t%s\n",
    615 	     get_arrowstyle_str (e->arrowstyle));
    616   if (e->backarrowstyle != E_BACKARROWSTYLE)
    617     fprintf (fout, "\t\tbackarrowstyle:\t%s\n",
    618 	     get_arrowstyle_str (e->backarrowstyle));
    619 
    620   if (e->priority != E_PRIORITY)
    621     fprintf (fout, "\t\tpriority:\t%d\n", e->priority);
    622   if (e->anchor != E_ANCHOR)
    623     fprintf (fout, "\t\tanchor:\t%d\n", e->anchor);
    624   if (e->horizontal_order != E_HORIZONTAL_ORDER)
    625     fprintf (fout, "\t\thorizontal_order:\t%d\n", e->horizontal_order);
    626 }
    627 
    628 void
    629 output_graph (graph *g, FILE *fout)
    630 {
    631   if (g->title)
    632     fprintf (fout, "\ttitle:\t%s\n", quote (g->title));
    633   if (g->label)
    634     fprintf (fout, "\tlabel:\t%s\n", quote (g->label));
    635 
    636   {
    637     int i;
    638     for (i = 0; i < 3; ++i)
    639       if (g->infos[i])
    640 	fprintf (fout, "\tinfo%d:\t%s\n", i, quote (g->infos[i]));
    641   }
    642 
    643   if (g->color != G_COLOR)
    644     fprintf (fout, "\tcolor:\t%s\n", get_color_str (g->color));
    645   if (g->textcolor != G_TEXTCOLOR)
    646     fprintf (fout, "\ttextcolor:\t%s\n", get_color_str (g->textcolor));
    647   if (g->bordercolor != G_BORDERCOLOR)
    648     fprintf (fout, "\tbordercolor:\t%s\n",
    649 	     get_color_str (g->bordercolor));
    650 
    651   if (g->width != G_WIDTH)
    652     fprintf (fout, "\twidth:\t%d\n", g->width);
    653   if (g->height != G_HEIGHT)
    654     fprintf (fout, "\theight:\t%d\n", g->height);
    655   if (g->borderwidth != G_BORDERWIDTH)
    656     fprintf (fout, "\tborderwidth:\t%d\n", g->borderwidth);
    657 
    658   if (g->x != G_X)
    659     fprintf (fout, "\tx:\t%d\n", g->x);
    660   if (g->y != G_Y)
    661     fprintf (fout, "\ty:\t%d\n", g->y);
    662 
    663   if (g->folding != G_FOLDING)
    664     fprintf (fout, "\tfolding:\t%d\n", g->folding);
    665 
    666   if (g->shrink != G_SHRINK)
    667     fprintf (fout, "\tshrink:\t%d\n", g->shrink);
    668   if (g->stretch != G_STRETCH)
    669     fprintf (fout, "\tstretch:\t%d\n", g->stretch);
    670 
    671   if (g->textmode != G_TEXTMODE)
    672     fprintf (fout, "\ttextmode:\t%s\n",
    673 	     get_textmode_str (g->textmode));
    674 
    675   if (g->shape != G_SHAPE)
    676     fprintf (fout, "\tshape:\t%s\n", get_shape_str (g->shape));
    677 
    678   if (g->vertical_order != G_VERTICAL_ORDER)
    679     fprintf (fout, "\tvertical_order:\t%d\n", g->vertical_order);
    680   if (g->horizontal_order != G_HORIZONTAL_ORDER)
    681     fprintf (fout, "\thorizontal_order:\t%d\n", g->horizontal_order);
    682 
    683   if (g->xmax != G_XMAX)
    684     fprintf (fout, "\txmax:\t%d\n", g->xmax);
    685   if (g->ymax != G_YMAX)
    686     fprintf (fout, "\tymax:\t%d\n", g->ymax);
    687 
    688   if (g->xbase != G_XBASE)
    689     fprintf (fout, "\txbase:\t%d\n", g->xbase);
    690   if (g->ybase != G_YBASE)
    691     fprintf (fout, "\tybase:\t%d\n", g->ybase);
    692 
    693   if (g->xspace != G_XSPACE)
    694     fprintf (fout, "\txspace:\t%d\n", g->xspace);
    695   if (g->yspace != G_YSPACE)
    696     fprintf (fout, "\tyspace:\t%d\n", g->yspace);
    697   if (g->xlspace != G_XLSPACE)
    698     fprintf (fout, "\txlspace:\t%d\n", g->xlspace);
    699 
    700   if (g->xraster != G_XRASTER)
    701     fprintf (fout, "\txraster:\t%d\n", g->xraster);
    702   if (g->yraster != G_YRASTER)
    703     fprintf (fout, "\tyraster:\t%d\n", g->yraster);
    704   if (g->xlraster != G_XLRASTER)
    705     fprintf (fout, "\txlraster:\t%d\n", g->xlraster);
    706 
    707   if (g->hidden != G_HIDDEN)
    708     fprintf (fout, "\thidden:\t%d\n", g->hidden);
    709 
    710   /* FIXME: Unallocate struct list if required.
    711      Maybe with a little function.  */
    712   if (g->classname != G_CLASSNAME)
    713     {
    714       struct classname *ite;
    715 
    716       for (ite = g->classname; ite; ite = ite->next)
    717 	fprintf (fout, "\tclassname %d :\t%s\n", ite->no, ite->name);
    718     }
    719 
    720   if (g->infoname != G_INFONAME)
    721     {
    722       struct infoname *ite;
    723 
    724       for (ite = g->infoname; ite; ite = ite->next)
    725 	fprintf (fout, "\tinfoname %d :\t%s\n", ite->integer, ite->chars);
    726     }
    727 
    728   if (g->colorentry != G_COLORENTRY)
    729     {
    730       struct colorentry *ite;
    731 
    732       for (ite = g->colorentry; ite; ite = ite->next)
    733 	{
    734 	  fprintf (fout, "\tcolorentry %d :\t%d %d %d\n",
    735 		   ite->color_index,
    736 		   ite->red_cp,
    737 		   ite->green_cp,
    738 		   ite->blue_cp);
    739 	}
    740     }
    741 
    742   if (g->layout_downfactor != G_LAYOUT_DOWNFACTOR)
    743     fprintf (fout, "\tlayout_downfactor:\t%d\n", g->layout_downfactor);
    744   if (g->layout_upfactor != G_LAYOUT_UPFACTOR)
    745     fprintf (fout, "\tlayout_upfactor:\t%d\n", g->layout_upfactor);
    746   if (g->layout_nearfactor != G_LAYOUT_NEARFACTOR)
    747     fprintf (fout, "\tlayout_nearfactor:\t%d\n", g->layout_nearfactor);
    748   if (g->layout_splinefactor != G_LAYOUT_SPLINEFACTOR)
    749     fprintf (fout, "\tlayout_splinefactor:\t%d\n",
    750 	     g->layout_splinefactor);
    751 
    752   if (g->late_edge_labels != G_LATE_EDGE_LABELS)
    753     fprintf (fout, "\tlate_edge_labels:\t%s\n",
    754 	     get_decision_str (g->late_edge_labels));
    755   if (g->display_edge_labels != G_DISPLAY_EDGE_LABELS)
    756     fprintf (fout, "\tdisplay_edge_labels:\t%s\n",
    757 	     get_decision_str (g->display_edge_labels));
    758   if (g->dirty_edge_labels != G_DIRTY_EDGE_LABELS)
    759     fprintf (fout, "\tdirty_edge_labels:\t%s\n",
    760 	     get_decision_str (g->dirty_edge_labels));
    761   if (g->finetuning != G_FINETUNING)
    762     fprintf (fout, "\tfinetuning:\t%s\n",
    763 	     get_decision_str (g->finetuning));
    764   if (g->ignore_singles != G_IGNORE_SINGLES)
    765     fprintf (fout, "\tignore_singles:\t%s\n",
    766 	     get_decision_str (g->ignore_singles));
    767   if (g->priority_phase != G_PRIORITY_PHASE)
    768     fprintf (fout, "\tpriority_phase:\t%s\n",
    769 	     get_decision_str (g->priority_phase));
    770   if (g->manhattan_edges != G_MANHATTAN_EDGES)
    771     fprintf (fout,
    772 	     "\tmanhattan_edges:\t%s\n",
    773 	     get_decision_str (g->manhattan_edges));
    774   if (g->smanhattan_edges != G_SMANHATTAN_EDGES)
    775     fprintf (fout,
    776 	     "\tsmanhattan_edges:\t%s\n",
    777 	     get_decision_str (g->smanhattan_edges));
    778   if (g->near_edges != G_NEAR_EDGES)
    779     fprintf (fout, "\tnear_edges:\t%s\n",
    780 	     get_decision_str (g->near_edges));
    781 
    782   if (g->orientation != G_ORIENTATION)
    783     fprintf (fout, "\torientation:\t%s\n",
    784 	     get_orientation_str (g->orientation));
    785 
    786   if (g->node_alignment != G_NODE_ALIGNMENT)
    787     fprintf (fout, "\tnode_alignment:\t%s\n",
    788 	     get_node_alignment_str (g->node_alignment));
    789 
    790   if (g->port_sharing != G_PORT_SHARING)
    791     fprintf (fout, "\tport_sharing:\t%s\n",
    792 	     get_decision_str (g->port_sharing));
    793 
    794   if (g->arrow_mode != G_ARROW_MODE)
    795     fprintf (fout, "\tarrow_mode:\t%s\n",
    796 	     get_arrow_mode_str (g->arrow_mode));
    797 
    798   if (g->treefactor != G_TREEFACTOR)
    799     fprintf (fout, "\ttreefactor:\t%f\n", g->treefactor);
    800   if (g->spreadlevel != G_SPREADLEVEL)
    801     fprintf (fout, "\tspreadlevel:\t%d\n", g->spreadlevel);
    802 
    803   if (g->crossing_weight != G_CROSSING_WEIGHT)
    804     fprintf (fout, "\tcrossing_weight:\t%s\n",
    805 	     get_crossing_type_str (g->crossing_weight));
    806   if (g->crossing_phase2 != G_CROSSING_PHASE2)
    807     fprintf (fout, "\tcrossing_phase2:\t%s\n",
    808 	     get_decision_str (g->crossing_phase2));
    809   if (g->crossing_optimization != G_CROSSING_OPTIMIZATION)
    810     fprintf (fout, "\tcrossing_optimization:\t%s\n",
    811 	     get_decision_str (g->crossing_optimization));
    812 
    813   if (g->view != normal_view)
    814     fprintf (fout, "\tview:\t%s\n", get_view_str (g->view));
    815 
    816   if (g->edges != G_EDGES)
    817     fprintf (fout, "\tedges:\t%s\n", get_decision_str (g->edges));
    818 
    819   if (g->nodes != G_NODES)
    820     fprintf (fout,"\tnodes:\t%s\n", get_decision_str (g->nodes));
    821 
    822   if (g->splines != G_SPLINES)
    823     fprintf (fout, "\tsplines:\t%s\n", get_decision_str (g->splines));
    824 
    825   if (g->bmax != G_BMAX)
    826     fprintf (fout, "\tbmax:\t%d\n", g->bmax);
    827   if (g->cmin != G_CMIN)
    828     fprintf (fout, "\tcmin:\t%d\n", g->cmin);
    829   if (g->cmax != G_CMAX)
    830     fprintf (fout, "\tcmax:\t%d\n", g->cmax);
    831   if (g->pmin != G_PMIN)
    832     fprintf (fout, "\tpmin:\t%d\n", g->pmin);
    833   if (g->pmax != G_PMAX)
    834     fprintf (fout, "\tpmax:\t%d\n", g->pmax);
    835   if (g->rmin != G_RMIN)
    836     fprintf (fout, "\trmin:\t%d\n", g->rmin);
    837   if (g->rmax != G_RMAX)
    838     fprintf (fout, "\trmax:\t%d\n", g->rmax);
    839   if (g->smax != G_SMAX)
    840     fprintf (fout, "\tsmax:\t%d\n", g->smax);
    841 }
    842