* src/vcg.c: You do the output, so you are responsible of the

handling of VCG syntax, in particular: use quotearg.
* src/print_graph.c: Don't.
(print_actions): Don't output the actions as part of the nodes,
since that's the job of the edges.
(print_state): Don't output by hand: fill the node description,
and ask for its output.
This commit is contained in:
Akim Demaille
2001-11-19 09:13:40 +00:00
parent c555896775
commit dc3b81cd67
3 changed files with 96 additions and 86 deletions

View File

@@ -1,3 +1,13 @@
2001-11-19 Akim Demaille <akim@epita.fr>
* src/vcg.c: You do the output, so you are responsible of the
handling of VCG syntax, in particular: use quotearg.
* src/print_graph.c: Don't.
(print_actions): Don't output the actions as part of the nodes,
since that's the job of the edges.
(print_state): Don't output by hand: fill the node description,
and ask for its output.
2001-11-19 Akim Demaille <akim@epita.fr> 2001-11-19 Akim Demaille <akim@epita.fr>
* src/bison.simple (yyparse): When reporting verbosely an error, * src/bison.simple (yyparse): When reporting verbosely an error,

View File

@@ -31,21 +31,10 @@
#include "obstack.h" #include "obstack.h"
#include "print_graph.h" #include "print_graph.h"
#include "vcg.h" #include "vcg.h"
#include "quotearg.h"
static graph_t graph; static graph_t graph;
static FILE *fgraph = NULL; static FILE *fgraph = NULL;
static size_t node_output_size = 0;
/* Return an unambiguous printable representated, allocated in slot 0,
for NAME, suitable for C strings. */
static char const *
quote (char const *name)
{
return quotearg_n_style (0, escape_quoting_style, name);
}
/* This part will construct the label of nodes. */ /* This part will construct the label of nodes. */
static void static void
print_core (int state, struct obstack *node_obstack) print_core (int state, struct obstack *node_obstack)
@@ -66,7 +55,7 @@ print_core (int state, struct obstack *node_obstack)
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
{ {
if (i) if (i)
obstack_sgrow (node_obstack, "\\n"); obstack_1grow (node_obstack, '\n');
sp1 = sp = ritem + statep->items[i]; sp1 = sp = ritem + statep->items[i];
@@ -77,22 +66,26 @@ print_core (int state, struct obstack *node_obstack)
obstack_fgrow1 (node_obstack, "%d: ", rule); obstack_fgrow1 (node_obstack, "%d: ", rule);
obstack_fgrow1 (node_obstack, " %s -> ", obstack_fgrow1 (node_obstack, " %s -> ",
quote (tags[rule_table[rule].lhs])); tags[rule_table[rule].lhs]);
for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++) for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++)
obstack_fgrow1 (node_obstack, "%s ", quote (tags[*sp])); obstack_fgrow1 (node_obstack, "%s ", tags[*sp]);
obstack_1grow (node_obstack, '.'); obstack_1grow (node_obstack, '.');
while (*sp > 0) while (*sp > 0)
obstack_fgrow1 (node_obstack, " %s", quote (tags[*sp++])); obstack_fgrow1 (node_obstack, " %s", tags[*sp++]);
} }
} }
/* Output in graph_obstack edges specifications in incidence with current
node. */ /*---------------------------------------------------------------.
| Output in graph_obstack edges specifications in incidence with |
| current node. |
`---------------------------------------------------------------*/
static void static void
print_actions (int state, const char *node_name, struct obstack *node_obstack) print_actions (int state, const char *node_name)
{ {
int i; int i;
int k; int k;
@@ -111,10 +104,12 @@ print_actions (int state, const char *node_name, struct obstack *node_obstack)
if (!shiftp && !redp) if (!shiftp && !redp)
{ {
#if 0
if (final_state == state) if (final_state == state)
obstack_sgrow (node_obstack, "$default: accept"); obstack_sgrow (node_obstack, "$default: accept");
else else
obstack_sgrow (node_obstack, "NO ACTIONS"); obstack_sgrow (node_obstack, "NO ACTIONS");
#endif
return; return;
} }
@@ -143,9 +138,7 @@ print_actions (int state, const char *node_name, struct obstack *node_obstack)
sprintf (buff, "%d", state1); sprintf (buff, "%d", state1);
edge.targetname = buff; edge.targetname = buff;
edge.color = (symbol == 0) ? red : blue; edge.color = (symbol == 0) ? red : blue;
/* FIXME: Be aware that quote uses static memory. The string edge.label = tags[symbol];
must be output immediately (which is the case here). */
edge.label = tags[symbol] ? quote (tags[symbol]) : NULL;
output_edge (&edge, fgraph); output_edge (&edge, fgraph);
close_edge (fgraph); close_edge (fgraph);
} }
@@ -157,6 +150,7 @@ print_actions (int state, const char *node_name, struct obstack *node_obstack)
k = 0; k = 0;
} }
#if 0
if (errp) if (errp)
{ {
int j, nerrs; int j, nerrs;
@@ -169,25 +163,29 @@ print_actions (int state, const char *node_name, struct obstack *node_obstack)
continue; continue;
symbol = errp->errs[j]; symbol = errp->errs[j];
/* If something has been added in the NODE_OBSTACK after /* If something has been added in the NODE_OBSTACK after
the declaration of the label, then we need a `\n'. */ the declaration of the label, then we need a `\n'.
if (obstack_object_size (node_obstack) > node_output_size) if (obstack_object_size (node_obstack) > node_output_size)
obstack_sgrow (node_obstack, "\\n"); obstack_sgrow (node_obstack, "\n");
*/
obstack_fgrow1 (node_obstack, _("%-4s\terror (nonassociative)"), obstack_fgrow1 (node_obstack, _("%-4s\terror (nonassociative)"),
tags[symbol]); tags[symbol]);
} }
if (j > 0) if (j > 0)
obstack_sgrow (node_obstack, "\\n"); obstack_1grow (node_obstack, '\n');
} }
if (state_table[state].consistent && redp) if (state_table[state].consistent && redp)
{ {
rule = redp->rules[0]; rule = redp->rules[0];
symbol = rule_table[rule].lhs; symbol = rule_table[rule].lhs;
/*
if (obstack_object_size (node_obstack) > node_output_size) if (obstack_object_size (node_obstack) > node_output_size)
obstack_sgrow (node_obstack, "\\n"); obstack_sgrow (node_obstack, "\n");
*/
obstack_fgrow2 (node_obstack, _("$default\treduce using rule %d (%s)"), obstack_fgrow2 (node_obstack, _("$default\treduce using rule %d (%s)"),
rule, tags[symbol]); rule, tags[symbol]);
} }
#endif
if (i < k) if (i < k)
{ {
@@ -204,15 +202,19 @@ print_actions (int state, const char *node_name, struct obstack *node_obstack)
sprintf (buff, "%d", state1); sprintf (buff, "%d", state1);
edge.targetname = buff; edge.targetname = buff;
edge.color = red; edge.color = red;
edge.label = tags[symbol] ? quote (tags[symbol]) : NULL; edge.label = tags[symbol];
output_edge (&edge, fgraph); output_edge (&edge, fgraph);
close_edge (fgraph); close_edge (fgraph);
} }
} }
} }
/* Output in GRAPH_OBSTACK the current node specifications and edges
which go out from that node. */ /*-------------------------------------------------------------.
| Output in FGRAPH the current node specifications and exiting |
| edges. |
`-------------------------------------------------------------*/
static void static void
print_state (int state) print_state (int state)
{ {
@@ -220,35 +222,22 @@ print_state (int state)
struct obstack node_obstack; struct obstack node_obstack;
node_t node; node_t node;
/* The labels of the nodes are their the items. */
obstack_init (&node_obstack); obstack_init (&node_obstack);
new_node (&node); /* Set node attributs default value. */ new_node (&node);
sprintf (name, "%d", state); sprintf (name, "%d", state);
node.title = name; /* Give a name to the node. */ node.title = name;
print_core (state, &node_obstack);
{ obstack_1grow (&node_obstack, '\0');
/* Here we begin to compute the node label. */ node.label = obstack_finish (&node_obstack);
obstack_sgrow (&node_obstack, "\t\tlabel:\t\""); /* Open Label */
/* Keep the size of NODE_OBSTACK before computing the label. It is
useful to format the label. */
node_output_size = obstack_object_size (&node_obstack);
/* Compute the labels of nodes on the fly. */
print_core (state, &node_obstack);
/* Compute edges and additionnal parts of node label. */
print_actions (state, node.title, &node_obstack);
obstack_sgrow (&node_obstack, "\"\n"); /* Close Label. */
}
open_node (fgraph); open_node (fgraph);
/* Output a VCG formatted attributs list. */
output_node (&node, fgraph); output_node (&node, fgraph);
/* Save the node label. */
fwrite (obstack_base (&node_obstack),
obstack_object_size (&node_obstack), 1, fgraph);
close_node (fgraph); close_node (fgraph);
/* Output the edges. */
print_actions (state, name);
obstack_free (&node_obstack, 0); obstack_free (&node_obstack, 0);
} }
@@ -286,8 +275,8 @@ print_graph (void)
open_graph (fgraph); open_graph (fgraph);
output_graph (&graph, fgraph); output_graph (&graph, fgraph);
/* Output nodes and edges. */
for (i = 0; i < nstates; i++) for (i = 0; i < nstates; i++)
/* Output nodes & edges. */
print_state (i); print_state (i);
/* Close graph. */ /* Close graph. */

View File

@@ -21,6 +21,16 @@
#include "system.h" #include "system.h"
#include "vcg.h" #include "vcg.h"
#include "vcg_defaults.h" #include "vcg_defaults.h"
#include "quotearg.h"
/* Return an unambiguous printable representated, allocated in slot 0,
for NAME, suitable for C strings. */
static char const *
quote (char const *name)
{
return quotearg_n_style (0, c_quoting_style, name);
}
/* Initialize a graph with the default values. */ /* Initialize a graph with the default values. */
void void
@@ -429,7 +439,7 @@ void
add_classname (graph_t *g, int val, const char *name) add_classname (graph_t *g, int val, const char *name)
{ {
struct classname_s *classname; struct classname_s *classname;
classname = XMALLOC (struct classname_s, 1); classname = XMALLOC (struct classname_s, 1);
classname->no = val; classname->no = val;
classname->name = name; classname->name = name;
@@ -441,7 +451,7 @@ void
add_infoname (graph_t *g, int integer, const char *string) add_infoname (graph_t *g, int integer, const char *string)
{ {
struct infoname_s *infoname; struct infoname_s *infoname;
infoname = XMALLOC (struct infoname_s, 1); infoname = XMALLOC (struct infoname_s, 1);
infoname->integer = integer; infoname->integer = integer;
infoname->string = string; infoname->string = string;
@@ -451,11 +461,11 @@ add_infoname (graph_t *g, int integer, const char *string)
/* Build a colorentry struct and add it to the list. */ /* Build a colorentry struct and add it to the list. */
void void
add_colorentry (graph_t *g, int color_idx, int red_cp, add_colorentry (graph_t *g, int color_idx, int red_cp,
int green_cp, int blue_cp) int green_cp, int blue_cp)
{ {
struct colorentry_s *ce; struct colorentry_s *ce;
ce = XMALLOC (struct colorentry_s, 1); ce = XMALLOC (struct colorentry_s, 1);
ce->color_index = color_idx; ce->color_index = color_idx;
ce->red_cp = red_cp; ce->red_cp = red_cp;
@@ -556,9 +566,9 @@ void
output_node (node_t *node, FILE *fout) output_node (node_t *node, FILE *fout)
{ {
if (node->title != N_TITLE) if (node->title != N_TITLE)
fprintf (fout, "\t\ttitle:\t\"%s\"\n", node->title); fprintf (fout, "\t\ttitle:\t%s\n", quote (node->title));
if (node->label != N_LABEL) if (node->label != N_LABEL)
fprintf (fout, "\t\tlabel:\t\"%s\"\n", node->label); fprintf (fout, "\t\tlabel:\t%s\n", quote (node->label));
if ((node->locx != N_LOCX) && (node->locy != N_LOCY)) if ((node->locx != N_LOCX) && (node->locy != N_LOCY))
fprintf (fout, "\t\tloc { x: %d y: %d }\t\n", node->locx, node->locy); fprintf (fout, "\t\tloc { x: %d y: %d }\t\n", node->locx, node->locy);
@@ -600,12 +610,13 @@ output_node (node_t *node, FILE *fout)
fprintf (fout, "\t\tbordercolor:\t%s\n", fprintf (fout, "\t\tbordercolor:\t%s\n",
get_color_str (node->bordercolor)); get_color_str (node->bordercolor));
if (node->infos[0]) {
fprintf (fout, "\t\tinfo1:\t\"%s\"\n", node->infos[0]); int i;
if (node->infos[1]) for (i = 0; i < 3; ++i)
fprintf (fout, "\t\tinfo2:\t\"%s\"\n", node->infos[1]); if (node->infos[i])
if (node->infos[2]) fprintf (fout, "\t\tinfo%d:\t%s\n",
fprintf (fout, "\t\tinfo3:\t\"%s\"\n", node->infos[2]); i, quote (node->infos[i]));
}
} }
void void
@@ -614,16 +625,16 @@ output_edge (edge_t *edge, FILE *fout)
/* FIXME: SOURCENAME and TARGETNAME are mandatory /* FIXME: SOURCENAME and TARGETNAME are mandatory
so it has to be fatal not to give these informations. */ so it has to be fatal not to give these informations. */
if (edge->sourcename != E_SOURCENAME) if (edge->sourcename != E_SOURCENAME)
fprintf (fout, "\t\tsourcename:\t\"%s\"\n", edge->sourcename); fprintf (fout, "\t\tsourcename:\t%s\n", quote (edge->sourcename));
if (edge->targetname != E_TARGETNAME) if (edge->targetname != E_TARGETNAME)
fprintf (fout, "\t\ttargetname:\t\"%s\"\n", edge->targetname); fprintf (fout, "\t\ttargetname:\t%s\n", quote (edge->targetname));
if (edge->label != E_LABEL) if (edge->label != E_LABEL)
fprintf (fout, "\t\tlabel:\t\"%s\"\n", edge->label); fprintf (fout, "\t\tlabel:\t%s\n", quote (edge->label));
if (edge->linestyle != E_LINESTYLE) if (edge->linestyle != E_LINESTYLE)
fprintf (fout, "\t\tlinestyle:\t\"%s\"\n", fprintf (fout, "\t\tlinestyle:\t%s\n",
get_linestyle_str(edge->linestyle)); quote (get_linestyle_str(edge->linestyle)));
if (edge->thickness != E_THICKNESS) if (edge->thickness != E_THICKNESS)
fprintf (fout, "\t\tthickness:\t%d\n", edge->thickness); fprintf (fout, "\t\tthickness:\t%d\n", edge->thickness);
@@ -666,16 +677,16 @@ void
output_graph (graph_t *graph, FILE *fout) output_graph (graph_t *graph, FILE *fout)
{ {
if (graph->title) if (graph->title)
fprintf (fout, "\ttitle:\t\"%s\"\n", graph->title); fprintf (fout, "\ttitle:\t%s\n", quote (graph->title));
if (graph->label) if (graph->label)
fprintf (fout, "\tlabel:\t\"%s\"\n", graph->label); fprintf (fout, "\tlabel:\t%s\n", quote (graph->label));
if (graph->infos[0]) {
fprintf (fout, "\tinfo1:\t\"%s\"\n", graph->infos[0]); int i;
if (graph->infos[1]) for (i = 0; i < 3; ++i)
fprintf (fout, "\tinfo2:\t\"%s\"\n", graph->infos[1]); if (graph->infos[i])
if (graph->infos[2]) fprintf (fout, "\tinfo%d:\t%s\n", i, quote (graph->infos[i]));
fprintf (fout, "\tinfo3:\t\"%s\"\n", graph->infos[2]); }
if (graph->color != G_COLOR) if (graph->color != G_COLOR)
fprintf (fout, "\tcolor:\t%s\n", get_color_str (graph->color)); fprintf (fout, "\tcolor:\t%s\n", get_color_str (graph->color));
@@ -711,11 +722,11 @@ output_graph (graph_t *graph, FILE *fout)
if (graph->shape != G_SHAPE) if (graph->shape != G_SHAPE)
fprintf (fout, "\tshape:\t%s\n", get_shape_str (graph->shape)); fprintf (fout, "\tshape:\t%s\n", get_shape_str (graph->shape));
if (graph->vertical_order != G_VERTICAL_ORDER) if (graph->vertical_order != G_VERTICAL_ORDER)
fprintf (fout, "\tvertical_order:\t%d\n", graph->vertical_order); fprintf (fout, "\tvertical_order:\t%d\n", graph->vertical_order);
if (graph->horizontal_order != G_HORIZONTAL_ORDER) if (graph->horizontal_order != G_HORIZONTAL_ORDER)
fprintf (fout, "\thorizontal_order:\t%d\n", graph->horizontal_order); fprintf (fout, "\thorizontal_order:\t%d\n", graph->horizontal_order);
if (graph->xmax != G_XMAX) if (graph->xmax != G_XMAX)
fprintf (fout, "\txmax:\t%d\n", graph->xmax); fprintf (fout, "\txmax:\t%d\n", graph->xmax);
@@ -743,8 +754,8 @@ output_graph (graph_t *graph, FILE *fout)
if (graph->hidden != G_HIDDEN) if (graph->hidden != G_HIDDEN)
fprintf (fout, "\thidden:\t%d\n", graph->hidden); fprintf (fout, "\thidden:\t%d\n", graph->hidden);
/* FIXME: Unallocate struct list if required. /* FIXME: Unallocate struct list if required.
Maybe with a little function. */ Maybe with a little function. */
if (graph->classname != G_CLASSNAME) if (graph->classname != G_CLASSNAME)
{ {
@@ -765,15 +776,15 @@ output_graph (graph_t *graph, FILE *fout)
if (graph->colorentry != G_COLORENTRY) if (graph->colorentry != G_COLORENTRY)
{ {
struct colorentry_s *ite; struct colorentry_s *ite;
for (ite = graph->colorentry; ite; ite = ite->next) for (ite = graph->colorentry; ite; ite = ite->next)
{ {
fprintf (fout, "\tcolorentry %d :\t%d %d %d\n", fprintf (fout, "\tcolorentry %d :\t%d %d %d\n",
ite->color_index, ite->color_index,
ite->red_cp, ite->red_cp,
ite->green_cp, ite->green_cp,
ite->blue_cp); ite->blue_cp);
} }
} }
if (graph->layoutalgorithm != G_LAYOUTALGORITHM) if (graph->layoutalgorithm != G_LAYOUTALGORITHM)