source: git/src/cavern.h @ c4a84dd

stereo-2025
Last change on this file since c4a84dd was cfef352, checked in by Olly Betts <olly@…>, 12 months ago

Only warn about hanging surveys

This has been an error previously, but at least for Walls data it seems
having hanging surveys is the norm, and Walls itself only warns about
them.

It seems we might as well support this for native Survex data too as
it allows viewing the connected parts of a survey with missing
connections without having to comment out the unconnected parts (and
then remember to fully uncomment once connections are surveyed).

If there are hanging surveys we may need to adjust the component
count, but don't currently so these statistics may be wrong so
for now we just suppress reporting them if there are hanging surveys.

  • Property mode set to 100644
File size: 15.9 KB
Line 
1/* cavern.h
2 * SURVEX Cave surveying software - header file
3 * Copyright (C) 1991-2024 Olly Betts
4 * Copyright (C) 2004 Simeon Warner
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19 */
20
21#ifndef CAVERN_H
22#define CAVERN_H
23
24/* Using covariances increases the memory required somewhat - may be
25 * desirable to disable this for small memory machines */
26
27/* #define NO_COVARIANCES 1 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <ctype.h>
33#include <math.h>
34#include <float.h>
35
36#include <proj.h>
37
38#include "img_hosted.h"
39#include "str.h"
40#include "useful.h"
41
42/* Set EXPLICIT_FIXED_FLAG to 1 to force an explicit fixed flag to be used
43 * in each pos struct, rather than using p[0]==UNFIXED_VAL to indicate
44 * unfixed-ness.  This may be slightly faster, but uses more memory.
45 */
46#ifndef EXPLICIT_FIXED_FLAG
47# define EXPLICIT_FIXED_FLAG 0
48#endif
49
50typedef double real; /* so we can change the precision used easily */
51#define HUGE_REAL HUGE_VAL
52#define REAL_EPSILON DBL_EPSILON
53
54#if (!EXPLICIT_FIXED_FLAG)
55# define UNFIXED_VAL HUGE_VAL /* if p[0]==UNFIXED_VAL, station is unfixed */
56#endif
57
58#define SPECIAL_EOL             0x0001
59#define SPECIAL_BLANK           0x0002
60#define SPECIAL_KEYWORD         0x0004
61#define SPECIAL_COMMENT         0x0008
62#define SPECIAL_OMIT            0x0010
63#ifndef NO_DEPRECATED
64#define SPECIAL_ROOT            0x0020
65#endif
66#define SPECIAL_SEPARATOR       0x0040
67#define SPECIAL_NAMES           0x0080
68#define SPECIAL_DECIMAL         0x0100
69#define SPECIAL_MINUS           0x0200
70#define SPECIAL_PLUS            0x0400
71#define SPECIAL_OPEN            0x0800
72#define SPECIAL_CLOSE           0x1000
73
74extern char *fnm_output_base;
75extern int fnm_output_base_is_dir;
76
77extern bool fExportUsed;
78
79extern int current_days_since_1900;
80
81/* Types */
82
83typedef enum {
84   Q_NULL = -1, Q_DEFAULT, Q_POS, Q_PLUMB, Q_LEVEL,
85   Q_GRADIENT, Q_BACKGRADIENT, Q_BEARING, Q_BACKBEARING,
86   Q_LENGTH, Q_BACKLENGTH, Q_DEPTH, Q_DX, Q_DY, Q_DZ, Q_COUNT, Q_DECLINATION,
87   Q_LEFT, Q_RIGHT, Q_UP, Q_DOWN,
88   Q_MAC
89} q_quantity;
90
91typedef enum {
92   INFER_NULL = -1,
93   INFER_EQUATES,
94   INFER_EXPORTS,
95   INFER_PLUMBS,
96   INFER_SUBSURVEYS,
97   /* In Compass DAT files a dummy zero-length leg from a station to itself is
98    * used to provide a place to specify LRUD for the start or end of a
99    * traverse (depending if dimensions are measured at the from or to
100    * station), so we shouldn't warn about equating a station to itself.
101    * This should be set *as well as* INFER_EQUATES.
102    */
103   INFER_EQUATES_SELF_OK
104} infer_what;
105
106/* unsigned long to cope with 16-bit int-s */
107#define BIT(N) (1UL << (N))
108#define BITA(N) (1UL << ((N) - 'a'))
109
110#define TSTBIT(W, N) (((W)>>(N))&1)
111
112/* masks for quantities which are length and angles respectively */
113#define LEN_QMASK (BIT(Q_LENGTH) | BIT(Q_BACKLENGTH) | BIT(Q_DEPTH) |\
114   BIT(Q_DX) | BIT(Q_DY) | BIT(Q_DZ) | BIT(Q_POS) | BIT(Q_COUNT) |\
115   BIT(Q_LEFT) | BIT(Q_RIGHT) | BIT(Q_UP) | BIT(Q_DOWN))
116#define ANG_QMASK (BIT(Q_BEARING) | BIT(Q_BACKBEARING) |\
117   BIT(Q_GRADIENT) | BIT(Q_BACKGRADIENT) | BIT(Q_PLUMB) | BIT(Q_LEVEL) |\
118   BIT(Q_DECLINATION))
119
120/* if you add/change the order, check factor_tab in commands.c */
121typedef enum {
122   UNITS_NULL = -1, UNITS_METRES, UNITS_FEET, UNITS_YARDS,
123   UNITS_DEGS, UNITS_QUADRANTS, UNITS_GRADS, UNITS_PERCENT, UNITS_MINUTES,
124   UNITS_MAC, UNITS_DEPRECATED_ALIAS_FOR_GRADS
125} u_units;
126
127/* don't reorder these values!  They need to match with img.h too */
128typedef enum {
129   FLAGS_NOT = -2, FLAGS_UNKNOWN = -1, FLAGS_SURFACE, FLAGS_DUPLICATE,
130   FLAGS_SPLAY,
131#if 0
132   /* underground, but through rock (e.g. radiolocation).  Want to hide from
133    * plots by default (so not cave) but don't want to include in surface
134    * triangulation nets (so not surface) */
135   FLAGS_SKELETAL, /* FIXME */
136#endif
137   /* Don't need to match img.h: */
138   FLAGS_ANON_ONE_END,
139   FLAGS_IMPLICIT_SPLAY,
140   FLAGS_STYLE_BIT0, FLAGS_STYLE_BIT1, FLAGS_STYLE_BIT2
141} flags;
142
143/* flags are currently stored in an unsigned char */
144typedef int compiletimeassert_flags0[FLAGS_STYLE_BIT2 <= 7 ? 1 : -1];
145
146/* Mask to AND with to get bits to pass to img library. */
147#define FLAGS_MASK \
148    (BIT(FLAGS_SURFACE) | BIT(FLAGS_DUPLICATE) | BIT(FLAGS_SPLAY))
149
150typedef int compiletimeassert_flags1[BIT(FLAGS_SURFACE) == img_FLAG_SURFACE ? 1 : -1];
151typedef int compiletimeassert_flags2[BIT(FLAGS_DUPLICATE) == img_FLAG_DUPLICATE ? 1 : -1];
152typedef int compiletimeassert_flags3[BIT(FLAGS_SPLAY) == img_FLAG_SPLAY ? 1 : -1];
153
154typedef enum {
155   /* Don't reorder these values!  They need to match with img.h too. */
156   SFLAGS_SURFACE = 0, SFLAGS_UNDERGROUND, SFLAGS_ENTRANCE, SFLAGS_EXPORTED,
157   SFLAGS_FIXED, SFLAGS_ANON, SFLAGS_WALL,
158   /* These values don't need to match img.h, but mustn't clash. */
159   SFLAGS_HANGING = 10,
160   SFLAGS_USED = 11,
161   SFLAGS_SOLVED = 12, SFLAGS_SUSPECTTYPO = 13, SFLAGS_SURVEY = 14, SFLAGS_PREFIX_ENTERED = 15
162} sflags;
163
164/* Mask to AND with to get bits to pass to img library. */
165#define SFLAGS_MASK (BIT(SFLAGS_SURFACE) | BIT(SFLAGS_UNDERGROUND) |\
166        BIT(SFLAGS_ENTRANCE) | BIT(SFLAGS_EXPORTED) | BIT(SFLAGS_FIXED) |\
167        BIT(SFLAGS_ANON) | BIT(SFLAGS_WALL))
168
169typedef int compiletimeassert_sflags1[BIT(SFLAGS_SURFACE) == img_SFLAG_SURFACE ? 1 : -1];
170typedef int compiletimeassert_sflags2[BIT(SFLAGS_UNDERGROUND) == img_SFLAG_UNDERGROUND ? 1 : -1];
171typedef int compiletimeassert_sflags3[BIT(SFLAGS_ENTRANCE) == img_SFLAG_ENTRANCE ? 1 : -1];
172typedef int compiletimeassert_sflags4[BIT(SFLAGS_EXPORTED) == img_SFLAG_EXPORTED ? 1 : -1];
173typedef int compiletimeassert_sflags5[BIT(SFLAGS_FIXED) == img_SFLAG_FIXED ? 1 : -1];
174typedef int compiletimeassert_sflags6[BIT(SFLAGS_ANON) == img_SFLAG_ANON ? 1 : -1];
175typedef int compiletimeassert_sflags7[BIT(SFLAGS_WALL) == img_SFLAG_WALL ? 1 : -1];
176
177/* enumeration of field types */
178typedef enum {
179   End = 0, Tape, Comp, Clino, BackTape, BackComp, BackClino,
180   Left, Right, Up, Down,
181   FrDepth, ToDepth, Dx, Dy, Dz, FrCount, ToCount,
182   /* Up to here are readings are allowed multiple values
183    * and have slot in the value[] array in datain.c.
184    * (Depth, DepthChange, and Count can have multiple
185    * readings, but are actually handled using tokens
186    * above rather than as themselves).
187    *
188    * Fr must be the first reading after this comment!
189    */
190   Fr, To, Station, Depth, DepthChange, Count, Dir,
191   Newline, IgnoreAllAndNewLine, Ignore, IgnoreAll,
192   /* IgnoreAll must be the last reading before this comment!
193    *
194    * Readings after this comment are only used in datain.c
195    * so can have enum values >= 32 because we only use a
196    * bitmask for those readings used in commands.c.
197    */
198   CompassDATFr, CompassDATTo,
199   CompassDATComp, CompassDATClino, CompassDATBackComp, CompassDATBackClino,
200   CompassDATLeft, CompassDATRight, CompassDATUp, CompassDATDown,
201   CompassDATFlags,
202
203   WallsSRVFr, WallsSRVTo, WallsSRVTape, WallsSRVComp, WallsSRVClino
204} reading;
205
206/* if IgnoreAll is >= 32, the compiler will choke on this */
207typedef char compiletimeassert_reading[IgnoreAll < 32 ? 1 : -1];
208
209/* position or length vector */
210typedef real delta[3];
211
212/* variance */
213#ifdef NO_COVARIANCES
214typedef real var[3];
215typedef var svar;
216#else
217typedef real var[3][3];
218typedef real svar[6];
219#endif
220
221/* station name */
222typedef struct Prefix {
223   struct Prefix *up, *down, *right;
224   struct Node *stn;
225   struct Pos *pos;
226   const char *ident;
227   // A filename:line where this name was used.  If it's a station used in *fix
228   // then this will be the location of such a *fix, otherwise if it's a
229   // station used in *equate then it's the location of such a *equate.
230   // Otherwise it's the first place it was used.
231   const char *filename;
232   unsigned int line;
233   /* If (min_export == 0) then max_export is max # levels above is this
234    * prefix is used (and so needs to be exported) (0 == parent only).
235    * If (min_export > 0) then max_export is max # levels above this
236    * prefix has been exported, and min_export is how far down the exports
237    * have got (if min_export > 1 after a run, this prefix hasn't been
238    * exported from below enough).
239    * If INFER_EXPORTS is active when a station is encountered, we
240    * set min_export = USHRT_MAX and max_export gets set as usual.  Then at
241    * the end of the run, we also mark stations with min_export == USHRT_MAX
242    * and max_export > 0 as exported. */
243   unsigned short max_export, min_export;
244   /* stn flags - e.g. surface, underground, entrance
245    * also suspecttypo and survey */
246   unsigned short sflags;
247   short shape;
248} prefix;
249
250/* survey metadata */
251typedef struct Meta_data {
252    size_t ref_count;
253    /* Days since 1900 for start and end date of survey, or -1 if undated. */
254    int days1, days2;
255} meta_data;
256
257/* stuff stored for both forward & reverse legs */
258typedef struct {
259   struct Node *to;
260   /* bits 0..1 = reverse leg number; bit7 is fFullLeg */
261   /* bit6 = fReplacementLeg (by reduction rules) */
262   /* bit5 = articulation leg (i.e. carries no error) */
263   unsigned char reverse;
264   /* flags - e.g. surface, duplicate survey
265    * only used if (FLAG_DATAHERE & !(FLAG_REPLACEMENTLEG|FLAG_FAKE))
266    * This could be only in linkfor, but this is actually more space
267    * efficient.
268    */
269   unsigned char flags;
270} linkcommon;
271
272#define FLAG_DATAHERE 0x80
273#define FLAG_REPLACEMENTLEG 0x40
274#define FLAG_ARTICULATION 0x20
275#define FLAG_FAKE 0x10 /* an equate or leg inside an sdfix */
276#define MASK_REVERSEDIRN 0x03
277
278/* reverse leg - deltas & vars stored on other dirn */
279typedef struct LinkRev {
280   linkcommon l;
281} linkrev;
282
283/* forward leg - deltas & vars stored here */
284typedef struct Link {
285   linkcommon l;
286   delta d; /* Delta */
287   svar v; /* Variances */
288   meta_data *meta;
289} linkfor;
290
291/* node - like a station, except several nodes are used to represent a
292 * station with more than 3 legs connected to it
293 */
294typedef struct Node {
295   struct Prefix *name;
296   struct Link *leg[3];
297   struct Node *prev, *next;
298   long colour;
299} node;
300
301/* station position */
302typedef struct Pos {
303   delta p; /* Position */
304#if EXPLICIT_FIXED_FLAG
305   unsigned char fFixed; /* flag indicating if station is a fixed point */
306#endif
307} pos;
308
309/*
310typedef struct Inst {
311   real zero, scale, units;
312} inst;
313*/
314
315/* Survey data styles */
316#define STYLE_NORMAL     0
317#define STYLE_DIVING     1
318#define STYLE_CARTESIAN  2
319#define STYLE_CYLPOLAR   3
320#define STYLE_NOSURVEY   4
321#define STYLE_PASSAGE    5
322#define STYLE_IGNORE     6
323
324typedef int compiletimeassert_style1[STYLE_NORMAL == img_STYLE_NORMAL ? 1 : -1];
325typedef int compiletimeassert_style2[STYLE_DIVING == img_STYLE_DIVING ? 1 : -1];
326typedef int compiletimeassert_style3[STYLE_CARTESIAN == img_STYLE_CARTESIAN ? 1 : -1];
327typedef int compiletimeassert_style4[STYLE_CYLPOLAR == img_STYLE_CYLPOLAR ? 1 : -1];
328typedef int compiletimeassert_style5[STYLE_NOSURVEY == img_STYLE_NOSURVEY ? 1 : -1];
329
330/* various settings preserved by *BEGIN and *END */
331typedef struct Settings {
332   struct Settings *next;
333   unsigned int Truncate;
334   bool f_clino_percent;
335   bool f_backclino_percent;
336   bool f_bearing_quadrants;
337   bool f_backbearing_quadrants;
338   bool dash_for_anon_wall_station;
339   unsigned char infer;
340   enum {OFF, LOWER, UPPER} Case;
341   /* STYLE_xxx value to process data as. */
342   int style;
343   /* STYLE_xxx value to put in 3d file (different for Compass DAT diving
344    * data, as the data in the DAT file is always presented in the format
345    * tape,compass,clino even if that isn't how it was really measured).
346    */
347   int recorded_style;
348   prefix *Prefix;
349   prefix *begin_survey; /* used to check BEGIN and END match */
350   short *Translate; /* if short is >= 16 bits, which ANSI requires */
351   real Var[Q_MAC];
352   real z[Q_MAC];
353   real sc[Q_MAC];
354   real units[Q_MAC];
355   const reading *ordering;
356   int begin_lineno; /* 0 means no block started in this file */
357   int flags;
358   char* proj_str;
359   /* Location at which we calculate the declination if
360    * z[Q_DECLINATION] == HUGE_REAL.
361    *
362    * Latitude and longitude are in radians; altitude is in metres above the
363    * ellipsoid.
364    */
365   real dec_lat, dec_lon, dec_alt;
366   /* Cached auto-declination in radians, or HUGE_REAL for no cached value.
367    * Only meaningful if date1 != -1.
368    */
369   real declination;
370   double min_declination, max_declination;
371   int min_declination_days, max_declination_days;
372   const char* dec_filename;
373   int dec_line;
374   /* Copy of the text of the `*declination auto ...` line (malloced). */
375   char* dec_context;
376   /* Grid convergence in radians. */
377   real convergence;
378   /* Input grid convergence in radians. */
379   real input_convergence;
380   /* Rotation from North for `*data cartesian`. */
381   real cartesian_rotation;
382   /* Which North to use for `*data cartesian`. */
383   enum { TRUE_NORTH, GRID_NORTH, MAGNETIC_NORTH } cartesian_north;
384   meta_data * meta;
385} settings;
386
387/* global variables */
388extern settings *pcs;
389extern prefix *root;
390extern prefix *anon_list;
391extern node *stnlist;
392extern unsigned long optimize;
393extern char * proj_str_out;
394extern PJ * pj_cached;
395
396extern string survey_title;
397
398extern bool fExplicitTitle;
399extern long cLegs, cStns, cComponents;
400extern bool hanging_surveys;
401extern FILE *fhErrStat;
402extern img *pimg;
403extern real totadj, total, totplan, totvert;
404extern real min[6], max[6];
405extern prefix *pfxHi[6], *pfxLo[6];
406extern bool fQuiet; /* just show brief summary + errors */
407extern bool fMute; /* just show errors */
408extern bool fSuppress; /* only output 3d file */
409
410/* macros */
411
412#define POS(S, D) ((S)->name->pos->p[(D)])
413#define POSD(S) ((S)->name->pos->p)
414
415#define data_here(L) ((L)->l.reverse & FLAG_DATAHERE)
416#define reverse_leg_dirn(L) ((L)->l.reverse & MASK_REVERSEDIRN)
417#define reverse_leg(L) ((L)->l.to->leg[reverse_leg_dirn(L)])
418
419#if EXPLICIT_FIXED_FLAG
420# define pfx_fixed(N) ((N)->pos->fFixed)
421# define pos_fixed(P) ((P)->fFixed)
422# define fix(S) (S)->name->pos->fFixed = (char)true
423# define fixpos(P) (P)->fFixed = (char)true
424# define unfix(S) (S)->name->pos->fFixed = (char)false
425#else
426# define pfx_fixed(N) ((N)->pos->p[0] != UNFIXED_VAL)
427# define pos_fixed(P) ((P)->p[0] != UNFIXED_VAL)
428# define fix(S) NOP
429# define fixpos(P) NOP
430# define unfix(S) POS((S), 0) = UNFIXED_VAL
431#endif
432#define fixed(S) pfx_fixed((S)->name)
433
434/* macros for special chars */
435
436#define isEol(c)    (pcs->Translate[(c)] & SPECIAL_EOL)
437#define isBlank(c)  (pcs->Translate[(c)] & SPECIAL_BLANK)
438#define isKeywd(c)  (pcs->Translate[(c)] & SPECIAL_KEYWORD)
439#define isComm(c)   (pcs->Translate[(c)] & SPECIAL_COMMENT)
440#define isOmit(c)   (pcs->Translate[(c)] & SPECIAL_OMIT)
441#ifndef NO_DEPRECATED
442#define isRoot(c)   (pcs->Translate[(c)] & SPECIAL_ROOT)
443#endif
444#define isSep(c)    (pcs->Translate[(c)] & SPECIAL_SEPARATOR)
445#define isNames(c)  (pcs->Translate[(c)] & SPECIAL_NAMES)
446#define isDecimal(c) (pcs->Translate[(c)] & SPECIAL_DECIMAL)
447#define isMinus(c)  (pcs->Translate[(c)] & SPECIAL_MINUS)
448#define isPlus(c)   (pcs->Translate[(c)] & SPECIAL_PLUS)
449#define isOpen(c)   (pcs->Translate[(c)] & SPECIAL_OPEN)
450#define isClose(c)  (pcs->Translate[(c)] & SPECIAL_CLOSE)
451
452#define isSign(c)   (pcs->Translate[(c)] & (SPECIAL_PLUS | SPECIAL_MINUS))
453#define isData(c)   (pcs->Translate[(c)] & (SPECIAL_OMIT | SPECIAL_ROOT|\
454   SPECIAL_SEPARATOR | SPECIAL_NAMES | SPECIAL_DECIMAL | SPECIAL_PLUS |\
455   SPECIAL_MINUS))
456
457typedef struct nosurveylink {
458   node *fr, *to;
459   int flags;
460   meta_data *meta;
461   struct nosurveylink *next;
462} nosurveylink;
463
464extern nosurveylink *nosurveyhead;
465
466typedef struct lrud {
467    struct lrud * next;
468    prefix *stn;
469    meta_data *meta;
470    real l, r, u, d;
471} lrud;
472
473typedef struct lrudlist {
474    lrud * tube;
475    struct lrudlist * next;
476} lrudlist;
477
478extern lrudlist * model;
479
480extern lrud ** next_lrud;
481
482extern char output_separator;
483
484#endif /* CAVERN_H */
Note: See TracBrowser for help on using the repository browser.