source: git/src/cavern.c @ 62781f4

RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereostereo-2025walls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since 62781f4 was ee05463, checked in by Olly Betts <olly@…>, 20 years ago

Added support for LRUD data in .svx files, in .3d files, and tweak aven to
load them. The ability to "fake" LRUD data in aven is gone for now...

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

  • Property mode set to 100644
File size: 10.8 KB
RevLine 
[0156ccfc]1/* cavern.c
[bb90203]2 * SURVEX Cave surveying software: data reduction main and related functions
[a4ae909]3 * Copyright (C) 1991-2003,2004,2005 Olly Betts
[846746e]4 *
[89231c4]5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
[846746e]9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[89231c4]12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
[846746e]14 *
[89231c4]15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
[bb90203]18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
[be97baf]24#include <limits.h>
[bb90203]25#include <time.h>
26
[5853657]27#include "cavern.h"
28#include "cmdline.h"
29#include "commands.h"
[bb90203]30#include "datain.h"
31#include "debug.h"
32#include "message.h"
33#include "filename.h"
34#include "filelist.h"
35#include "img.h"
36#include "listpos.h"
[5853657]37#include "netbits.h"
38#include "netskel.h"
39#include "osdepend.h"
[bb90203]40#include "out.h"
[8e8057c]41#include "str.h"
[5853657]42#include "validate.h"
[bb90203]43
44/* For funcs which want to be immune from messing around with different
45 * calling conventions */
46#ifndef CDECL
47# define CDECL
48#endif
49
50/* Globals */
51node *stnlist = NULL;
52settings *pcs;
53prefix *root;
54long cLegs, cStns;
55long cComponents;
[d1878c51]56bool fExportUsed = fFalse;
[bb90203]57
58FILE *fhErrStat = NULL;
[693388e]59img *pimg = NULL;
[bb90203]60#ifndef NO_PERCENTAGE
61bool fPercent = fFalse;
62#endif
[647407d]63bool fQuiet = fFalse; /* just show brief summary + errors */
[ed0f5b6]64bool fMute = fFalse; /* just show errors */
[647407d]65bool fSuppress = fFalse; /* only output 3d(3dx) file */
[2b6eca8]66static bool fLog = fFalse; /* stdout to .log file */
[421b7d2]67static bool f_warnings_are_errors = fFalse; /* turn warnings into errors */
[647407d]68
69nosurveylink *nosurveyhead;
[bb90203]70
71real totadj, total, totplan, totvert;
72real min[3], max[3];
73prefix *pfxHi[3], *pfxLo[3];
74
75char *survey_title = NULL;
76int survey_title_len;
77
78bool fExplicitTitle = fFalse;
79
[8e8057c]80char *fnm_output_base = NULL;
81int fnm_output_base_is_dir = 0;
82
[ee05463]83lrudlist * model = NULL;
84lrud ** next_lrud = NULL;
85
[06a871f]86static void do_stats(void);
[bb90203]87
88static const struct option long_opts[] = {
89   /* const char *name; int has_arg (0 no_argument, 1 required_*, 2 optional_*); int *flag; int val; */
90#ifdef NO_PERCENTAGE
91   {"percentage", no_argument, 0, 0},
92   {"no-percentage", no_argument, 0, 0},
93#else
94   {"percentage", no_argument, 0, 'p'},
[b4fe9fb]95   {"no-percentage", no_argument, 0, 3},
[bb90203]96#endif
[8e8057c]97   {"output", required_argument, 0, 'o'},
[647407d]98   {"quiet", no_argument, 0, 'q'},
99   {"no-auxiliary-files", no_argument, 0, 's'},
[bb9d869]100   {"warnings-are-errors", no_argument, 0, 'w'},
[0dab87a]101   {"log", no_argument, 0, 1},
[ce6ab688]102#if (OS==WIN32)
[0dab87a]103   {"pause", no_argument, 0, 2},
[647407d]104#endif
[bb90203]105   {"help", no_argument, 0, HLP_HELP},
106   {"version", no_argument, 0, HLP_VERSION},
107   {0, 0, 0, 0}
108};
109
[bb9d869]110#define short_opts "pao:qswz:"
[bb90203]111
[647407d]112/* TRANSLATE extract help messages to message file */
[bb90203]113static struct help_msg help[] = {
114/*                              <-- */
[a4ae909]115   {HLP_ENCODELONG(0),          "display percentage progress"},
116   {HLP_ENCODELONG(2),          "set location for output files"},
117   {HLP_ENCODELONG(3),          "only show brief summary (-qq for errors only)"},
118   {HLP_ENCODELONG(4),          "do not create .err file"},
119   {HLP_ENCODELONG(5),          "turn warnings into errors"},
120   {HLP_ENCODELONG(6),          "log output to .log file"},
121 /*{'z',                        "set optimizations for network reduction"},*/
[bb90203]122   {0, 0}
123};
124
[5b68ae1]125/* atexit functions */
[25ab06b]126static void
127delete_output_on_error(void)
128{
[bb9d869]129   if (msg_errors || (f_warnings_are_errors && msg_warnings))
130      filename_delete_output();
[25ab06b]131}
132
[5b68ae1]133#if (OS==WIN32)
134static void
135pause_on_exit(void)
136{
137   while (_kbhit()) _getch();
138   _getch();
139}
140#endif
141
[bb90203]142extern CDECL int
143main(int argc, char **argv)
144{
145   int d;
[be97baf]146   time_t tmUserStart = time(NULL);
147   clock_t tmCPUStart = clock();
[bb90203]148   init_screen();
149
[bdfe97f]150   msg_init(argv);
[bb90203]151
152   pcs = osnew(settings);
153   pcs->next = NULL;
154   pcs->Translate = ((short*) osmalloc(ossizeof(short) * 257)) + 1;
[b5a3219]155   pcs->meta = NULL;
[bb90203]156
157   /* Set up root of prefix hierarchy */
158   root = osnew(prefix);
159   root->up = root->right = root->down = NULL;
160   root->stn = NULL;
[421b7d2]161   root->pos = NULL;
[ff6cfe1]162   root->ident = NULL;
[932f7e9]163   root->min_export = root->max_export = 0;
[95c3272]164   root->sflags = BIT(SFLAGS_SURVEY);
[016068a]165   root->filename = NULL;
[647407d]166
167   nosurveyhead = NULL;
[bb90203]168
169   stnlist = NULL;
170   cLegs = cStns = cComponents = 0;
171   totadj = total = totplan = totvert = 0.0;
172
173   for (d = 0; d <= 2; d++) {
[fa42426]174      min[d] = HUGE_REAL;
175      max[d] = -HUGE_REAL;
[bb90203]176      pfxHi[d] = pfxLo[d] = NULL;
177   }
178
[d06141c]179   /* at least one argument must be given */
[b85e20f]180   cmdline_init(argc, argv, short_opts, long_opts, NULL, help, 1, -1);
[bb90203]181   while (1) {
[b85e20f]182      int opt = cmdline_getopt();
[bb90203]183      if (opt == EOF) break;
184      switch (opt) {
185       case 'p':
186#ifndef NO_PERCENTAGE
187         fPercent = 1;
188#endif
189         break;
[b4fe9fb]190#ifndef NO_PERCENTAGE
191       case 3:
192         fPercent = 0;
193         break;
194#endif
[8e8057c]195       case 'o': {
196         /* can be a directory (in which case use basename of leaf input)
197          * or a file (in which case just trim the extension off) */
198         if (fDirectory(optarg)) {
199            /* this is a little tricky - we need to note the path here,
200             * and then add the leaf later on (in datain.c) */
201            fnm_output_base = base_from_fnm(optarg);
202            fnm_output_base_is_dir = 1;
203         } else {
204            osfree(fnm_output_base); /* in case of multiple -o options */
205            fnm_output_base = base_from_fnm(optarg);
206         }
207         break;
208       }
[647407d]209       case 'q':
210         if (fQuiet) fMute = 1;
211         fQuiet = 1;
212         break;
213       case 's':
214         fSuppress = 1;
215         break;
[bb9d869]216       case 'w':
217         f_warnings_are_errors = 1;
218         break;
[8e8057c]219       case 'z': {
220         /* Control which network optimisations are used (development tool) */
221         static int first_opt_z = 1;
[eb18f4d]222         char c;
[8e8057c]223         if (first_opt_z) {
[bb90203]224            optimize = 0;
[8e8057c]225            first_opt_z = 0;
[bb90203]226         }
[c50391b8]227         /* Lollipops, Parallel legs, Iterate mx, Delta* */
[eb18f4d]228         while ((c = *optarg++) != '\0')
[0580c6a]229            if (islower((unsigned char)c)) optimize |= BITA(c);
[0dab87a]230         break;
231       case 1:
232         fLog = fTrue;
[bb90203]233         break;
[5b68ae1]234#if (OS==WIN32)
[0dab87a]235       case 2:
[5b68ae1]236         atexit(pause_on_exit);
237         break;
238#endif
[bb90203]239       }
240      }
241   }
242
[0dab87a]243   if (fLog) {
244      char *fnm;
[9887ea01]245      if (!fnm_output_base) {
246         char *p;
247         p = baseleaf_from_fnm(argv[optind]);
[0156ccfc]248         fnm = add_ext(p, EXT_LOG);
[421b7d2]249         osfree(p);
[9887ea01]250      } else if (fnm_output_base_is_dir) {
[09e8f4c]251         char *p;
252         fnm = baseleaf_from_fnm(argv[optind]);
253         p = use_path(fnm_output_base, fnm);
254         osfree(fnm);
[0156ccfc]255         fnm = add_ext(p, EXT_LOG);
[09e8f4c]256         osfree(p);
257      } else {
[0156ccfc]258         fnm = add_ext(fnm_output_base, EXT_LOG);
[09e8f4c]259      }
[421b7d2]260
[0dab87a]261      if (!freopen(fnm, "w", stdout))
262         fatalerror(/*Failed to open output file `%s'*/47, fnm);
263
264      osfree(fnm);
265   }
266
[90123e8]267   if (!fMute)
268      printf(PRETTYPACKAGE" "VERSION"\n"COPYRIGHT_MSG"\n", msg(/*&copy;*/0));
[bb90203]269
[25ab06b]270   atexit(delete_output_on_error);
271
[bb90203]272   /* end of options, now process data files */
273   while (argv[optind]) {
274      const char *fnm = argv[optind];
275
276      if (!fExplicitTitle) {
277         char *lf;
[8e8057c]278         lf = baseleaf_from_fnm(fnm);
[bb90203]279         if (survey_title) s_catchar(&survey_title, &survey_title_len, ' ');
280         s_cat(&survey_title, &survey_title_len, lf);
281         osfree(lf);
282      }
283
284      /* Select defaults settings */
285      default_all(pcs);
[f4b609d]286      data_file(NULL, fnm); /* first argument is current path */
[cb3d1e2]287
[bb90203]288      optind++;
289   }
[cb3d1e2]290
[bb90203]291   validate();
292
293   solve_network(/*stnlist*/); /* Find coordinates of all points */
294   validate();
[421b7d2]295
[a4ae909]296   /* close .3d file */
297   if (!img_close(pimg)) {
298      char *fnm = add_ext(fnm_output_base, EXT_SVX_3D);
299      fatalerror(img_error(), fnm);
[647407d]300   }
[7104f16]301   if (fhErrStat) safe_fclose(fhErrStat);
[bb90203]302
303   out_current_action(msg(/*Calculating statistics*/120));
[2b6eca8]304   if (!fMute) do_stats();
[647407d]305   if (!fQuiet) {
[f03053a7]306      /* clock() typically wraps after 72 minutes, but there doesn't seem
307       * to be a better way.  Still 72 minutes means some cave!
[be97baf]308       * We detect if clock() could have wrapped and suppress CPU time
309       * printing in this case.
[f03053a7]310       */
[be97baf]311      double tmUser = difftime(time(NULL), tmUserStart);
312      double tmCPU;
313      clock_t now = clock();
314#define CLOCK_T_WRAP \
315        (sizeof(clock_t)<sizeof(long)?(1ul << (CHAR_BIT * sizeof(clock_t))):0)
316      tmCPU = (now - (unsigned long)tmCPUStart)
317         / (double)CLOCKS_PER_SEC;
318      if (now < tmCPUStart)
319         tmCPU += CLOCK_T_WRAP / (double)CLOCKS_PER_SEC;
320      if (tmUser >= tmCPU + CLOCK_T_WRAP / (double)CLOCKS_PER_SEC)
321         tmCPU = 0;
[647407d]322
[27b8b59]323      /* tmUser is integer, tmCPU not - equivalent to (ceil(tmCPU) >= tmUser) */
[647407d]324      if (tmCPU + 1 > tmUser) {
[421b7d2]325         printf(msg(/*CPU time used %5.2fs*/140), tmCPU);
[647407d]326      } else if (tmCPU == 0) {
[27b8b59]327         if (tmUser != 0.0) {
[421b7d2]328            printf(msg(/*Time used %5.2fs*/141), tmUser);
[647407d]329         } else {
[421b7d2]330            fputs(msg(/*Time used unavailable*/142), stdout);
[647407d]331         }
[bb90203]332      } else {
[5b68ae1]333         printf(msg(/*Time used %5.2fs (%5.2fs CPU time)*/143), tmUser, tmCPU);
[bb90203]334      }
[5b68ae1]335      putnl();
[bb90203]336
[5b68ae1]337      puts(msg(/*Done.*/144));
[647407d]338   }
[25ab06b]339   if (msg_warnings || msg_errors) {
[7ebee5b]340      if (msg_errors || (f_warnings_are_errors && msg_warnings)) {
341         printf(msg(/*There were %d warning(s) and %d non-fatal error(s) - no output files produced.*/113),
342                msg_warnings, msg_errors);
343         putnl();
344         return EXIT_FAILURE;
345      }
346      printf(msg(/*There were %d warning(s).*/16), msg_warnings);
[25ab06b]347      putnl();
348   }
[bb9d869]349   return EXIT_SUCCESS;
[bb90203]350}
351
352static void
[2b6eca8]353do_range(int d, int msg1, int msg2, int msg3)
[bb90203]354{
[2b6eca8]355   printf(msg(msg1), max[d] - min[d]);
356   fprint_prefix(stdout, pfxHi[d]);
357   printf(msg(msg2), max[d]);
358   fprint_prefix(stdout, pfxLo[d]);
359   printf(msg(msg3), min[d]);
360   putnl();
[bb90203]361}
362
363static void
[06a871f]364do_stats(void)
[bb90203]365{
366   long cLoops = cComponents + cLegs - cStns;
367
[2b6eca8]368   putnl();
[bb90203]369
[a63fdd2a]370   if (cStns == 1) {
[2b6eca8]371      fputs(msg(/*Survey contains 1 survey station,*/172), stdout);
[a63fdd2a]372   } else {
[2b6eca8]373      printf(msg(/*Survey contains %ld survey stations,*/173), cStns);
[a63fdd2a]374   }
[bb90203]375
[a63fdd2a]376   if (cLegs == 1) {
[2b6eca8]377      fputs(msg(/* joined by 1 leg.*/174), stdout);
[a63fdd2a]378   } else {
[2b6eca8]379      printf(msg(/* joined by %ld legs.*/175), cLegs);
[a63fdd2a]380   }
[bb90203]381
[2b6eca8]382   putnl();
[bb90203]383
[a63fdd2a]384   if (cLoops == 1) {
[2b6eca8]385      fputs(msg(/*There is 1 loop.*/138), stdout);
[a63fdd2a]386   } else {
[2b6eca8]387      printf(msg(/*There are %ld loops.*/139), cLoops);
[a63fdd2a]388   }
[bb90203]389
[2b6eca8]390   putnl();
[bb90203]391
392   if (cComponents != 1) {
[2b6eca8]393      printf(msg(/*Survey has %ld connected components.*/178), cComponents);
[a63fdd2a]394      putnl();
395   }
[bb90203]396
[2b6eca8]397   printf(msg(/*Total length of survey legs = %7.2fm (%7.2fm adjusted)*/132),
398          total, totadj);
399   putnl();
400   printf(msg(/*Total plan length of survey legs = %7.2fm*/133),
401          totplan);
402   putnl();
403   printf(msg(/*Total vertical length of survey legs = %7.2fm*/134),
404          totvert);
405   putnl();
406
[4ae2ea4]407   /* If there's no underground survey, we've no ranges */
408   if (pfxHi[0]) {
409      do_range(2, /*Vertical range = %4.2fm (from */135,
410               /* at %4.2fm to */136, /* at %4.2fm)*/137);
411      do_range(1, /*North-South range = %4.2fm (from */148,
412               /* at %4.2fm to */196, /* at %4.2fm)*/197);
413      do_range(0, /*East-West range = %4.2fm (from */149,
414               /* at %4.2fm to */196, /* at %4.2fm)*/197);
415   }
[bb90203]416
[2b6eca8]417   print_node_stats();
[bb90203]418   /* Also, could give:
419    *  # nodes stations (ie have other than two references or are fixed)
420    *  # fixed stations (list of?)
421    */
422}
Note: See TracBrowser for help on using the repository browser.