]> git.saurik.com Git - bison.git/blame - src/relation.c
portability: fix several issues with M4 subprocess.
[bison.git] / src / relation.c
CommitLineData
0e4d5753 1/* Binary relations.
1462fcee
JD
2 Copyright (C) 2002, 2004-2005, 2009-2010 Free Software Foundation,
3 Inc.
0e4d5753
AD
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
f16b0819 7 This program is free software: you can redistribute it and/or modify
0e4d5753 8 it under the terms of the GNU General Public License as published by
f16b0819
PE
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
0e4d5753 11
f16b0819 12 This program is distributed in the hope that it will be useful,
0e4d5753
AD
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0e4d5753 19
2cec9080 20#include <config.h>
0e4d5753 21#include "system.h"
17ee7397
PE
22
23#include <bitsetv.h>
24
0e4d5753 25#include "getargs.h"
17ee7397 26#include "relation.h"
0e4d5753
AD
27
28void
7b21ee09 29relation_print (relation r, relation_node size, FILE *out)
0e4d5753 30{
7b21ee09
PE
31 relation_node i;
32 relation_node j;
0e4d5753
AD
33
34 for (i = 0; i < size; ++i)
35 {
7b21ee09 36 fprintf (out, "%3lu: ", (unsigned long int) i);
17ee7397 37 if (r[i])
0859e438 38 for (j = 0; r[i][j] != END_NODE; ++j)
7b21ee09 39 fprintf (out, "%3lu ", (unsigned long int) r[i][j]);
0e4d5753
AD
40 fputc ('\n', out);
41 }
42 fputc ('\n', out);
43}
44
45
46/*---------------------------------------------------------------.
47| digraph & traverse. |
48| |
49| The following variables are used as common storage between the |
50| two. |
51`---------------------------------------------------------------*/
52
17ee7397
PE
53static relation R;
54static relation_nodes INDEX;
55static relation_nodes VERTICES;
7b21ee09
PE
56static relation_node top;
57static relation_node infinity;
0e4d5753
AD
58static bitsetv F;
59
60static void
7b21ee09 61traverse (relation_node i)
0e4d5753 62{
7b21ee09
PE
63 relation_node j;
64 relation_node height;
0e4d5753
AD
65
66 VERTICES[++top] = i;
67 INDEX[i] = height = top;
68
69 if (R[i])
0859e438 70 for (j = 0; R[i][j] != END_NODE; ++j)
0e4d5753
AD
71 {
72 if (INDEX[R[i][j]] == 0)
73 traverse (R[i][j]);
74
75 if (INDEX[i] > INDEX[R[i][j]])
76 INDEX[i] = INDEX[R[i][j]];
77
78 bitset_or (F[i], F[i], F[R[i][j]]);
79 }
80
81 if (INDEX[i] == height)
82 for (;;)
83 {
84 j = VERTICES[top--];
85 INDEX[j] = infinity;
86
87 if (i == j)
88 break;
89
90 bitset_copy (F[j], F[i]);
91 }
92}
93
94
95void
7b21ee09 96relation_digraph (relation r, relation_node size, bitsetv *function)
0e4d5753 97{
7b21ee09 98 relation_node i;
0e4d5753
AD
99
100 infinity = size + 2;
da2a7671
PE
101 INDEX = xcalloc (size + 1, sizeof *INDEX);
102 VERTICES = xnmalloc (size + 1, sizeof *VERTICES);
0e4d5753
AD
103 top = 0;
104
17ee7397 105 R = r;
0e4d5753
AD
106 F = *function;
107
0e4d5753
AD
108 for (i = 0; i < size; i++)
109 if (INDEX[i] == 0 && R[i])
110 traverse (i);
111
afbb696d
PE
112 free (INDEX);
113 free (VERTICES);
0e4d5753
AD
114
115 *function = F;
116}
117
118
119/*-------------------------------------------.
120| Destructively transpose R_ARG, of size N. |
121`-------------------------------------------*/
122
123void
7b21ee09 124relation_transpose (relation *R_arg, relation_node n)
0e4d5753 125{
26a69b31 126 relation r = *R_arg;
0e4d5753 127 /* The result. */
da2a7671 128 relation new_R = xnmalloc (n, sizeof *new_R);
0e4d5753 129 /* END_R[I] -- next entry of NEW_R[I]. */
da2a7671 130 relation end_R = xnmalloc (n, sizeof *end_R);
0e4d5753 131 /* NEDGES[I] -- total size of NEW_R[I]. */
7b21ee09
PE
132 size_t *nedges = xcalloc (n, sizeof *nedges);
133 relation_node i;
134 relation_node j;
0e4d5753 135
273a74fa 136 if (trace_flag & trace_sets)
0e4d5753 137 {
427c0dda 138 fputs ("relation_transpose: input\n", stderr);
26a69b31 139 relation_print (r, n, stderr);
0e4d5753
AD
140 }
141
142 /* Count. */
143 for (i = 0; i < n; i++)
26a69b31
PE
144 if (r[i])
145 for (j = 0; r[i][j] != END_NODE; ++j)
146 ++nedges[r[i][j]];
0e4d5753
AD
147
148 /* Allocate. */
149 for (i = 0; i < n; i++)
da2a7671
PE
150 {
151 relation_node *sp = NULL;
152 if (nedges[i] > 0)
153 {
154 sp = xnmalloc (nedges[i] + 1, sizeof *sp);
155 sp[nedges[i]] = END_NODE;
156 }
157 new_R[i] = sp;
158 end_R[i] = sp;
159 }
0e4d5753
AD
160
161 /* Store. */
162 for (i = 0; i < n; i++)
26a69b31
PE
163 if (r[i])
164 for (j = 0; r[i][j] != END_NODE; ++j)
165 *end_R[r[i][j]]++ = i;
0e4d5753
AD
166
167 free (nedges);
168 free (end_R);
169
170 /* Free the input: it is replaced with the result. */
171 for (i = 0; i < n; i++)
26a69b31
PE
172 free (r[i]);
173 free (r);
0e4d5753 174
273a74fa 175 if (trace_flag & trace_sets)
0e4d5753 176 {
427c0dda 177 fputs ("relation_transpose: output\n", stderr);
0e4d5753
AD
178 relation_print (new_R, n, stderr);
179 }
180
181 *R_arg = new_R;
182}