source: git/src/validate.c @ 76cf7f1

RELEASE/1.2debug-cidebug-ci-sanitiserswalls-datawalls-data-hanging-as-warning
Last change on this file since 76cf7f1 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
RevLine 
[421b7d2]1/* validate.c
[d1b1380]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 *
[b6e9e7e]8 *   Copyright (C) 1993,1994,1996,2000,2001 Olly Betts
[846746e]9 *
[89231c4]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.
[846746e]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
[89231c4]17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
[846746e]19 *
[89231c4]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
[ecbc6c18]22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
[d1b1380]23 */
24
[a420b49]25#ifdef HAVE_CONFIG_H
26# include <config.h>
27#endif
[d1b1380]28
[a420b49]29#include "cavern.h"
[c082b69]30#include "filename.h"
31#include "message.h"
[d1b1380]32#include "netbits.h"
33#include "validate.h"
34
35/* maximum absolute value allowed for a coordinate of a fixed station */
[577d6c1]36#define MAX_POS 10000000.0
[d1b1380]37
[a420b49]38static bool validate_prefix_tree(void);
39static bool validate_prefix_subtree(prefix *pfx);
[d1b1380]40
[a420b49]41static bool validate_station_list(void);
[d1b1380]42
43#if 0
[a420b49]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");
[6d3f931]51   /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
52   for (stn = stnlist; stn; stn = stn->next) {
[a420b49]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   }
[d1b1380]59}
60#endif
61
[a420b49]62#undef validate
63extern bool
64validate(void)
65{
66   bool fOk = fTrue;
[6d3f931]67   if (!validate_prefix_tree()) fOk = fFalse;
68   if (!validate_station_list()) fOk = fFalse;
[a420b49]69   if (fOk) puts("*** Data structures passed consistency checks");
[6d3f931]70   else puts("*** Data structures FAILED consistency checks");
[a420b49]71   return fOk;
72}
[d1b1380]73
[a420b49]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}
[d1b1380]97
[a420b49]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 */
[d1b1380]105#if 0
[a420b49]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;
[d1b1380]114   }
115#endif
116
[a420b49]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;
[d1b1380]136   }
[a420b49]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
[4c07c51]147   SVX_ASSERT(!stnlist || !stnlist->prev);
[6d3f931]148   /* NB: don't use FOR_EACH_STN as it isn't reentrant at present */
149   for (stn = stnlist; stn; stn = stn->next) {
[577d6c1]150      bool fGap = fFalse;
[095ef764]151#if 0
152      printf("V [%p]<-[%p]->[%p] ", stn->prev, stn, stn->next); print_prefix(stn->name); putnl();
153#endif
[4c07c51]154      SVX_ASSERT(stn->prev == NULL || stn->prev->next == stn);
155      SVX_ASSERT(stn->next == NULL || stn->next->prev == stn);
[a420b49]156      for (d = 0; d <= 2; d++) {
[577d6c1]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            }
[a420b49]166            stn2 = stn->leg[d]->l.to;
[4c07c51]167            SVX_ASSERT(stn2);
[564f471]168#if 0
[a420b49]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            }
[564f471]177#endif
[a420b49]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 */
[564f471]181               node *s;
[6d3f931]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;
[564f471]184               if (s) {
[a420b49]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               }
[6d3f931]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;
[a420b49]197            } else if (stn2->leg[d2]->l.to!=stn) {
198               /* fine iff stn is at the disconnected end of a fragment */
[564f471]199               node *s;
[6d3f931]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;
[564f471]202               if (s) {
[a420b49]203                  printf("*** Station '");
204                  print_prefix(stn->name);
[6d3f931]205                  printf("' [%p], leg %d reciprocates via station '", stn, d);
[a420b49]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);
[6d3f931]216               printf("' [%p], leg %d reciprocates via station '", stn, d);
[a420b49]217               print_prefix(stn2->name);
[cb3d1e2]218               if (data_here(stn->leg[d]))
[a420b49]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         }
[d1b1380]248
249      }
[a420b49]250   }
251   return fOk;
252}
253
254#undef dump_node
255extern void
256dump_node(node *stn)
257{
258   int d;
259   if (stn->name)
[d1b1380]260      print_prefix(stn->name);
[a420b49]261   else
262      printf("<null>");
[d1b1380]263
[564f471]264   printf(" stn [%p] name (%p) colour %ld %sfixed\n",
265          stn, stn->name, stn->colour, fixed(stn) ? "" : "un");
[d1b1380]266
[a420b49]267   for (d = 0; d <= 2; d++) {
[05312022]268      if (stn->leg[d]) {
[6d3f931]269         printf("  leg %d -> stn [%p] rev %d ", d, stn->leg[d]->l.to,
270                reverse_leg_dirn(stn->leg[d]));
[05312022]271         print_prefix(stn->leg[d]->l.to->name);
[5b68ae1]272         putnl();
[05312022]273      }
[d1b1380]274   }
[a420b49]275}
[d1b1380]276
[b6e9e7e]277/* This doesn't cover removed stations - might be nice to have
278 * dump_entire_network() which iterates prefix tree */
[cb3d1e2]279#undef dump_network
[a420b49]280extern void
281dump_network(void)
282{
283   node *stn;
[6d3f931]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);
[a420b49]286}
Note: See TracBrowser for help on using the repository browser.