source: git/src/validate.c @ a72ed95

RELEASE/1.2debug-cidebug-ci-sanitisersstereowalls-data
Last change on this file since a72ed95 was ecbc6c18, checked in by Olly Betts <olly@…>, 14 years ago

src/: Update FSF address in licence notices.

git-svn-id: file:///home/survex-svn/survex/branches/survex-1_1@3417 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/* validate.c
2 *
3 *   Checks that SURVEX's data structures are valid and consistent
4 *
5 *   NB The checks currently done aren't very comprehensive - more will be
6 *    added if bugs require them
7 *
8 *   Copyright (C) 1993,1994,1996,2000,2001 Olly Betts
9 *
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.
14 *
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.
19 *
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
23 */
24
25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
28
29#include "cavern.h"
30#include "filename.h"
31#include "message.h"
32#include "netbits.h"
33#include "validate.h"
34
35/* maximum absolute value allowed for a coordinate of a fixed station */
36#define MAX_POS 10000000.0
37
38static bool validate_prefix_tree(void);
39static bool validate_prefix_subtree(prefix *pfx);
40
41static bool validate_station_list(void);
42
43#if 0
44extern void
45check_fixed(void)
46{
47   /* not a requirement -- we allow hanging sections of survey
48    * which get spotted and removed */
49   node *stn;
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);
57      }
58   }
59}
60#endif
61
62#undef validate
63extern bool
64validate(void)
65{
66   bool fOk = fTrue;
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");
71   return fOk;
72}
73
74static bool
75validate_prefix_tree(void)
76{
77   bool fOk = fTrue;
78   if (root->up != NULL) {
79      printf("*** root->up == %p\n", root->up);
80      fOk = fFalse;
81   }
82   if (root->right != NULL) {
83      printf("*** root->right == %p\n", root->right);
84      fOk = fFalse;
85   }
86   if (root->stn != NULL) {
87      printf("*** root->stn == %p\n", root->stn);
88      fOk = fFalse;
89   }
90   if (root->pos != NULL) {
91      printf("*** root->pos == %p\n", root->pos);
92      fOk = fFalse;
93   }
94   fOk &= validate_prefix_subtree(root);
95   return fOk;
96}
97
98static bool
99validate_prefix_subtree(prefix *pfx)
100{
101   bool fOk = fTrue;
102   prefix *pfx2;
103   pfx2 = pfx->down;
104   /* this happens now, as nodes are freed after solving */
105#if 0
106   if (pfx2 == NULL) {
107      if (pfx->stn == NULL) {
108         printf("*** Leaf prefix '");
109         print_prefix(pfx);
110         printf("' has no station attached\n");
111         fOk = fFalse;
112      }
113      return fOk;
114   }
115#endif
116
117   while (pfx2 != NULL) {
118      if (pfx2->stn != NULL && pfx2->stn->name != pfx2) {
119         printf("*** Prefix '");
120         print_prefix(pfx2);
121         printf("' ->stn->name is '");
122         print_prefix(pfx2->stn->name);
123         printf("'\n");
124         fOk = fFalse;
125      }
126      if (pfx2->up != pfx) {
127         printf("*** Prefix '");
128         print_prefix(pfx2);
129         printf("' ->up is '");
130         print_prefix(pfx);
131         printf("'\n");
132         fOk = fFalse;
133      }
134      fOk &= validate_prefix_subtree(pfx2);
135      pfx2 = pfx2->right;
136   }
137   return fOk;
138}
139
140static bool
141validate_station_list(void)
142{
143   bool fOk = fTrue;
144   node *stn, *stn2;
145   int d, d2;
146
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) {
150      bool fGap = fFalse;
151#if 0
152      printf("V [%p]<-[%p]->[%p] ", stn->prev, stn, stn->next); print_prefix(stn->name); putnl();
153#endif
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++) {
157         if (!stn->leg[d]) {
158            fGap = fTrue;
159         } else {
160            if (fGap) {
161               printf("*** Station '");
162               print_prefix(stn->name);
163               printf("', leg %d is used, but an earlier leg isn't\n", d);
164               fOk = fFalse;
165            }
166            stn2 = stn->leg[d]->l.to;
167            SVX_ASSERT(stn2);
168#if 0
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);
175               fOk = fFalse;
176            }
177#endif
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 */
181               node *s;
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;
184               if (s) {
185                  printf("*** Station '");
186                  print_prefix(stn->name);
187                  printf("', leg %d doesn't reciprocate from station '", d);
188                  print_prefix(stn2->name);
189                  printf("'\n");
190                  fOk = fFalse;
191               }
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);
196               fOk = fFalse;
197            } else if (stn2->leg[d2]->l.to!=stn) {
198               /* fine iff stn is at the disconnected end of a fragment */
199               node *s;
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;
202               if (s) {
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);
209                  printf("'\n");
210                  fOk = fFalse;
211               }
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");
220               else
221                  printf("' - data on neither leg\n");
222               fOk = fFalse;
223            }
224            if (data_here(stn->leg[d])) {
225               int i;
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]));
232                     fOk = fFalse;
233                  }
234            }
235         }
236
237         if (fixed(stn)) {
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) );
245               fOk = fFalse;
246            }
247         }
248
249      }
250   }
251   return fOk;
252}
253
254#undef dump_node
255extern void
256dump_node(node *stn)
257{
258   int d;
259   if (stn->name)
260      print_prefix(stn->name);
261   else
262      printf("<null>");
263
264   printf(" stn [%p] name (%p) colour %ld %sfixed\n",
265          stn, stn->name, stn->colour, fixed(stn) ? "" : "un");
266
267   for (d = 0; d <= 2; d++) {
268      if (stn->leg[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);
272         putnl();
273      }
274   }
275}
276
277/* This doesn't cover removed stations - might be nice to have
278 * dump_entire_network() which iterates prefix tree */
279#undef dump_network
280extern void
281dump_network(void)
282{
283   node *stn;
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);
286}
Note: See TracBrowser for help on using the repository browser.