3 * Checks that SURVEX's data structures are valid and consistent
5 * NB The checks currently done aren't very comprehensive - more will be
6 * added if bugs require them
8 * Copyright (C) 1993,1994,1996,2000,2001 Olly Betts
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 /* maximum absolute value allowed for a coordinate of a fixed station */
34 #define MAX_POS 10000000.0
36 static bool validate_prefix_tree(void);
37 static bool validate_prefix_subtree(prefix
*pfx
);
39 static bool validate_station_list(void);
45 /* not a requirement -- we allow hanging sections of survey
46 * which get spotted and removed */
48 printf("*** Checking fixed-ness\n");
49 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
50 for (stn
= stnlist
; stn
; stn
= stn
->next
) {
51 if (stn
->status
&& !fixed(stn
)) {
52 printf("*** Station '");
53 print_prefix(stn
->name
);
54 printf("' has status %d but isn't fixed\n", stn
->status
);
65 if (!validate_prefix_tree()) fOk
= false;
66 if (!validate_station_list()) fOk
= false;
67 if (fOk
) puts("*** Data structures passed consistency checks");
68 else puts("*** Data structures FAILED consistency checks");
73 validate_prefix_tree(void)
76 if (root
->up
!= NULL
) {
77 printf("*** root->up == %p\n", root
->up
);
80 if (root
->right
!= NULL
) {
81 printf("*** root->right == %p\n", root
->right
);
84 if (root
->stn
!= NULL
) {
85 printf("*** root->stn == %p\n", root
->stn
);
88 if (root
->pos
!= NULL
) {
89 printf("*** root->pos == %p\n", root
->pos
);
92 fOk
&= validate_prefix_subtree(root
);
97 validate_prefix_subtree(prefix
*pfx
)
102 /* this happens now, as nodes are freed after solving */
105 if (pfx
->stn
== NULL
) {
106 printf("*** Leaf prefix '");
108 printf("' has no station attached\n");
115 while (pfx2
!= NULL
) {
116 if (pfx2
->stn
!= NULL
&& pfx2
->stn
->name
!= pfx2
) {
117 printf("*** Prefix '");
119 printf("' ->stn->name is '");
120 print_prefix(pfx2
->stn
->name
);
124 if (pfx2
->up
!= pfx
) {
125 printf("*** Prefix '");
127 printf("' ->up is '");
132 fOk
&= validate_prefix_subtree(pfx2
);
139 validate_station_list(void)
145 SVX_ASSERT(!stnlist
|| !stnlist
->prev
);
146 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
147 for (stn
= stnlist
; stn
; stn
= stn
->next
) {
150 printf("V [%p]<-[%p]->[%p] ", stn
->prev
, stn
, stn
->next
); print_prefix(stn
->name
); putnl();
152 SVX_ASSERT(stn
->prev
== NULL
|| stn
->prev
->next
== stn
);
153 SVX_ASSERT(stn
->next
== NULL
|| stn
->next
->prev
== stn
);
154 for (d
= 0; d
<= 2; d
++) {
159 printf("*** Station '");
160 print_prefix(stn
->name
);
161 printf("', leg %d is used, but an earlier leg isn't\n", d
);
164 stn2
= stn
->leg
[d
]->l
.to
;
167 if (stn
->status
&& !stn2
->status
) {
168 printf("*** Station '");
169 print_prefix(stn
->name
);
170 printf("' has status %d and connects to '", stn
->status
);
171 print_prefix(stn2
->name
);
172 printf("' which has status %d\n", stn2
->status
);
176 d2
= reverse_leg_dirn(stn
->leg
[d
]);
177 if (stn2
->leg
[d2
] == NULL
) {
178 /* fine iff stn is at the disconnected end of a fragment */
180 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
181 for (s
= stnlist
; s
; s
= s
->next
) if (s
== stn
) break;
183 printf("*** Station '");
184 print_prefix(stn
->name
);
185 printf("', leg %d doesn't reciprocate from station '", d
);
186 print_prefix(stn2
->name
);
190 } else if (stn2
->leg
[d2
]->l
.to
== NULL
) {
191 printf("*** Station '");
192 print_prefix(stn2
->name
);
193 printf("' [%p], leg %d points to NULL\n", stn2
, d2
);
195 } else if (stn2
->leg
[d2
]->l
.to
!=stn
) {
196 /* fine iff stn is at the disconnected end of a fragment */
198 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
199 for (s
= stnlist
; s
; s
= s
->next
) if (s
== stn
) break;
201 printf("*** Station '");
202 print_prefix(stn
->name
);
203 printf("' [%p], leg %d reciprocates via station '", stn
, d
);
204 print_prefix(stn2
->name
);
205 printf("' to station '");
206 print_prefix(stn2
->leg
[d2
]->l
.to
->name
);
210 } else if ((data_here(stn
->leg
[d
]) != 0) ^
211 (data_here(stn2
->leg
[d2
]) == 0)) {
212 printf("*** Station '");
213 print_prefix(stn
->name
);
214 printf("' [%p], leg %d reciprocates via station '", stn
, d
);
215 print_prefix(stn2
->name
);
216 if (data_here(stn
->leg
[d
]))
217 printf("' - data on both legs\n");
219 printf("' - data on neither leg\n");
222 if (data_here(stn
->leg
[d
])) {
224 for (i
= 0; i
< 3; i
++)
225 if (fabs(stn
->leg
[d
]->d
[i
]) > MAX_POS
) {
226 printf("*** Station '");
227 print_prefix(stn
->name
);
228 printf("', leg %d, d[%d] = %g\n",
229 d
, i
, (double)(stn
->leg
[d
]->d
[i
]));
236 if (fabs(POS(stn
, 0)) > MAX_POS
||
237 fabs(POS(stn
, 1)) > MAX_POS
||
238 fabs(POS(stn
, 2)) > MAX_POS
) {
239 printf("*** Station '");
240 print_prefix(stn
->name
);
241 printf("' fixed at coords (%f,%f,%f)\n",
242 POS(stn
, 0), POS(stn
, 1), POS(stn
, 2) );
258 print_prefix(stn
->name
);
262 printf(" stn [%p] name (%p) colour %ld %sfixed\n",
263 stn
, stn
->name
, stn
->colour
, fixed(stn
) ? "" : "un");
265 for (d
= 0; d
<= 2; d
++) {
267 printf(" leg %d -> stn [%p] rev %d ", d
, stn
->leg
[d
]->l
.to
,
268 reverse_leg_dirn(stn
->leg
[d
]));
269 print_prefix(stn
->leg
[d
]->l
.to
->name
);
275 /* This doesn't cover removed stations - might be nice to have
276 * dump_entire_network() which iterates prefix tree */
282 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
283 for (stn
= stnlist
; stn
; stn
= stn
->next
) dump_node(stn
);