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
35 /* maximum absolute value allowed for a coordinate of a fixed station */
36 #define MAX_POS 10000000.0
38 static bool validate_prefix_tree(void);
39 static bool validate_prefix_subtree(prefix
*pfx
);
41 static bool validate_station_list(void);
47 /* not a requirement -- we allow hanging sections of survey
48 * which get spotted and removed */
50 printf("*** Checking fixed-ness\n");
51 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
52 for (stn
= stnlist
; stn
; stn
= stn
->next
) {
53 if (stn
->status
&& !fixed(stn
)) {
54 printf("*** Station '");
55 print_prefix(stn
->name
);
56 printf("' has status %d but isn't fixed\n", stn
->status
);
67 if (!validate_prefix_tree()) fOk
= fFalse
;
68 if (!validate_station_list()) fOk
= fFalse
;
69 if (fOk
) puts("*** Data structures passed consistency checks");
70 else puts("*** Data structures FAILED consistency checks");
75 validate_prefix_tree(void)
78 if (root
->up
!= NULL
) {
79 printf("*** root->up == %p\n", root
->up
);
82 if (root
->right
!= NULL
) {
83 printf("*** root->right == %p\n", root
->right
);
86 if (root
->stn
!= NULL
) {
87 printf("*** root->stn == %p\n", root
->stn
);
90 if (root
->pos
!= NULL
) {
91 printf("*** root->pos == %p\n", root
->pos
);
94 fOk
&= validate_prefix_subtree(root
);
99 validate_prefix_subtree(prefix
*pfx
)
104 /* this happens now, as nodes are freed after solving */
107 if (pfx
->stn
== NULL
) {
108 printf("*** Leaf prefix '");
110 printf("' has no station attached\n");
117 while (pfx2
!= NULL
) {
118 if (pfx2
->stn
!= NULL
&& pfx2
->stn
->name
!= pfx2
) {
119 printf("*** Prefix '");
121 printf("' ->stn->name is '");
122 print_prefix(pfx2
->stn
->name
);
126 if (pfx2
->up
!= pfx
) {
127 printf("*** Prefix '");
129 printf("' ->up is '");
134 fOk
&= validate_prefix_subtree(pfx2
);
141 validate_station_list(void)
147 SVX_ASSERT(!stnlist
|| !stnlist
->prev
);
148 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
149 for (stn
= stnlist
; stn
; stn
= stn
->next
) {
152 printf("V [%p]<-[%p]->[%p] ", stn
->prev
, stn
, stn
->next
); print_prefix(stn
->name
); putnl();
154 SVX_ASSERT(stn
->prev
== NULL
|| stn
->prev
->next
== stn
);
155 SVX_ASSERT(stn
->next
== NULL
|| stn
->next
->prev
== stn
);
156 for (d
= 0; d
<= 2; d
++) {
161 printf("*** Station '");
162 print_prefix(stn
->name
);
163 printf("', leg %d is used, but an earlier leg isn't\n", d
);
166 stn2
= stn
->leg
[d
]->l
.to
;
169 if (stn
->status
&& !stn2
->status
) {
170 printf("*** Station '");
171 print_prefix(stn
->name
);
172 printf("' has status %d and connects to '", stn
->status
);
173 print_prefix(stn2
->name
);
174 printf("' which has status %d\n", stn2
->status
);
178 d2
= reverse_leg_dirn(stn
->leg
[d
]);
179 if (stn2
->leg
[d2
] == NULL
) {
180 /* fine iff stn is at the disconnected end of a fragment */
182 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
183 for (s
= stnlist
; s
; s
= s
->next
) if (s
== stn
) break;
185 printf("*** Station '");
186 print_prefix(stn
->name
);
187 printf("', leg %d doesn't reciprocate from station '", d
);
188 print_prefix(stn2
->name
);
192 } else if (stn2
->leg
[d2
]->l
.to
== NULL
) {
193 printf("*** Station '");
194 print_prefix(stn2
->name
);
195 printf("' [%p], leg %d points to NULL\n", stn2
, d2
);
197 } else if (stn2
->leg
[d2
]->l
.to
!=stn
) {
198 /* fine iff stn is at the disconnected end of a fragment */
200 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
201 for (s
= stnlist
; s
; s
= s
->next
) if (s
== stn
) break;
203 printf("*** Station '");
204 print_prefix(stn
->name
);
205 printf("' [%p], leg %d reciprocates via station '", stn
, d
);
206 print_prefix(stn2
->name
);
207 printf("' to station '");
208 print_prefix(stn2
->leg
[d2
]->l
.to
->name
);
212 } else if ((data_here(stn
->leg
[d
]) != 0) ^
213 (data_here(stn2
->leg
[d2
]) == 0)) {
214 printf("*** Station '");
215 print_prefix(stn
->name
);
216 printf("' [%p], leg %d reciprocates via station '", stn
, d
);
217 print_prefix(stn2
->name
);
218 if (data_here(stn
->leg
[d
]))
219 printf("' - data on both legs\n");
221 printf("' - data on neither leg\n");
224 if (data_here(stn
->leg
[d
])) {
226 for (i
= 0; i
< 3; i
++)
227 if (fabs(stn
->leg
[d
]->d
[i
]) > MAX_POS
) {
228 printf("*** Station '");
229 print_prefix(stn
->name
);
230 printf("', leg %d, d[%d] = %g\n",
231 d
, i
, (double)(stn
->leg
[d
]->d
[i
]));
238 if (fabs(POS(stn
, 0)) > MAX_POS
||
239 fabs(POS(stn
, 1)) > MAX_POS
||
240 fabs(POS(stn
, 2)) > MAX_POS
) {
241 printf("*** Station '");
242 print_prefix(stn
->name
);
243 printf("' fixed at coords (%f,%f,%f)\n",
244 POS(stn
, 0), POS(stn
, 1), POS(stn
, 2) );
260 print_prefix(stn
->name
);
264 printf(" stn [%p] name (%p) colour %ld %sfixed\n",
265 stn
, stn
->name
, stn
->colour
, fixed(stn
) ? "" : "un");
267 for (d
= 0; d
<= 2; d
++) {
269 printf(" leg %d -> stn [%p] rev %d ", d
, stn
->leg
[d
]->l
.to
,
270 reverse_leg_dirn(stn
->leg
[d
]));
271 print_prefix(stn
->leg
[d
]->l
.to
->name
);
277 /* This doesn't cover removed stations - might be nice to have
278 * dump_entire_network() which iterates prefix tree */
284 /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
285 for (stn
= stnlist
; stn
; stn
= stn
->next
) dump_node(stn
);