source: git/src/datain.c @ ce04943

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 ce04943 was b4fe9fb, checked in by Olly Betts <olly@…>, 22 years ago

Merged changes with 1.0 branch.

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

  • Property mode set to 100644
File size: 45.8 KB
RevLine 
[b0d908e]1/* datain.c
[d1b1380]2 * Reads in survey files, dealing with special characters, keywords & data
[b5a3219]3 * Copyright (C) 1991-2003 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
[d1b1380]18 */
19
[a420b49]20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
[d1b1380]23
24#include <limits.h>
[a420b49]25#include <stdarg.h>
[b5a3219]26#include <time.h>
[d1b1380]27
28#include "debug.h"
[a420b49]29#include "cavern.h"
[07025e3]30#include "filename.h"
31#include "message.h"
[d1b1380]32#include "filelist.h"
33#include "netbits.h"
[5853657]34#include "netskel.h"
[d1b1380]35#include "readval.h"
36#include "datain.h"
37#include "commands.h"
38#include "out.h"
[39fba51]39#include "str.h"
[d1b1380]40
[2b078c4]41#define EPSILON (REAL_EPSILON * 1000)
[d1b1380]42
[58cc1fb]43#define var(I) (pcs->Var[(I)])
[d1b1380]44
[58cc1fb]45int ch;
[d1b1380]46
[be97baf]47typedef enum {
48    CTYPE_OMIT, CTYPE_READING, CTYPE_PLUMB, CTYPE_INFERPLUMB, CTYPE_HORIZ
49} clino_type;
[5b7c1b7]50
[eb18f4d]51/* Don't explicitly initialise as we can't set the jmp_buf - this has
52 * static scope so will be initialised like this anyway */
[b0d908e]53parse file /* = { NULL, NULL, 0, fFalse, NULL } */ ;
[a420b49]54
[932f7e9]55bool f_export_ok;
56
[21c226e]57static real value[Fr - 1];
58#define VAL(N) value[(N)-1]
59static real variance[Fr - 1];
60#define VAR(N) variance[(N)-1]
61
[c7451a9]62void
[c80bd34]63get_pos(filepos *fp)
[c7451a9]64{
[c80bd34]65   fp->ch = ch;
66   fp->offset = ftell(file.fh);
67   if (fp->offset == -1)
[c7451a9]68      fatalerror_in_file(file.filename, 0, /*Error reading file*/18);
69}
70
[c80bd34]71void
72set_pos(const filepos *fp)
[c7451a9]73{
[c80bd34]74   ch = fp->ch;
75   if (fseek(file.fh, fp->offset, SEEK_SET) == -1)
[c7451a9]76      fatalerror_in_file(file.filename, 0, /*Error reading file*/18);
77}
78
[44bf1d9]79static void
[993454b]80push_back(int c)
81{
82   if (c != EOF && ungetc(c, file.fh) == EOF)
83      fatalerror_in_file(file.filename, 0, /*Error reading file*/18);
84}
85
[a420b49]86static void
87error_list_parent_files(void)
88{
[b0d908e]89   if (!file.reported_where && file.parent) {
[421b7d2]90      parse *p = file.parent;
[46cb98f]91      const char *m = msg(/*In file included from*/5);
[84c60fc]92      size_t len = strlen(m);
[b0d908e]93
[84c60fc]94      fprintf(STDERR, m);
[46cb98f]95      m = msg(/*from*/3);
[b0d908e]96
97      /* Suppress reporting of full include tree for further errors
98       * in this file */
99      file.reported_where = fTrue;
100
[a420b49]101      while (p) {
[b0d908e]102         /* Force re-report of include tree for further errors in
103          * parent files */
104         p->reported_where = fFalse;
[46cb98f]105         fprintf(STDERR, " %s:%d", p->filename, p->line);
[a420b49]106         p = p->parent;
[84f3ed6]107         if (p) fprintf(STDERR, ",\n%*s", (int)len, m);
[a420b49]108      }
109      fprintf(STDERR, ":\n");
110   }
111}
112
113void
114compile_error(int en, ...)
115{
116   va_list ap;
117   va_start(ap, en);
118   error_list_parent_files();
119   v_report(1, file.filename, file.line, en, ap);
120   va_end(ap);
121}
122
[fa42426]123void
124compile_error_skip(int en, ...)
125{
126   va_list ap;
127   va_start(ap, en);
128   error_list_parent_files();
129   v_report(1, file.filename, file.line, en, ap);
130   va_end(ap);
131   skipline();
132}
133
[39fba51]134void
135compile_error_token(int en)
136{
137   char *p = NULL;
138   static int len;
139   s_zero(&p);
140   skipblanks();
141   while (!isBlank(ch) && !isEol(ch)) {
142      s_catchar(&p, &len, ch);
143      nextch();
144   }
[fa42426]145   compile_error_skip(en, p ? p : "");
[39fba51]146   osfree(p);
147}
148
[a420b49]149void
150compile_warning(int en, ...)
151{
152   va_list ap;
153   va_start(ap, en);
154   error_list_parent_files();
155   v_report(0, file.filename, file.line, en, ap);
156   va_end(ap);
157}
158
159/* This function makes a note where to put output files */
160static void
161using_data_file(const char *fnm)
162{
163   if (!fnm_output_base) {
[4bab027]164      /* was: fnm_output_base = base_from_fnm(fnm); */
165      fnm_output_base = baseleaf_from_fnm(fnm);
166   } else if (fnm_output_base_is_dir) {
167      /* --output pointed to directory so use the leaf basename in that dir */
168      char *lf, *p;
169      lf = baseleaf_from_fnm(fnm);
170      p = use_path(fnm_output_base, lf);
171      osfree(lf);
172      osfree(fnm_output_base);
173      fnm_output_base = p;
174      fnm_output_base_is_dir = 0;
[58cc1fb]175   }
176}
177
[a420b49]178static void
179skipword(void)
180{
[58cc1fb]181   while (!isBlank(ch) && !isEol(ch)) nextch();
[d1b1380]182}
183
[a420b49]184extern void
185skipblanks(void)
186{
[58cc1fb]187   while (isBlank(ch)) nextch();
[d1b1380]188}
189
[a420b49]190extern void
191skipline(void)
192{
[58cc1fb]193   while (!isEol(ch)) nextch();
[d1b1380]194}
195
[90bb053f]196#ifndef NO_PERCENTAGE
197static long int filelen;
198#endif
199
200static void
201process_bol(void)
202{
203#ifndef NO_PERCENTAGE
204   /* print %age of file done */
[be97baf]205   if (filelen > 0) {
206      filepos fp;
207      get_pos(&fp);
208      printf("%d%%\r", (int)(100 * fp.offset / filelen));
209   }
[90bb053f]210#endif
211
212   nextch();
213   skipblanks();
214}
215
216static void
217process_eol(void)
218{
219   int eolchar;
220
221   skipblanks();
222
223   if (!isEol(ch)) {
[44bf1d9]224      if (!isComm(ch)) compile_error(/*End of line not blank*/15);
[90bb053f]225      skipline();
226   }
227
228   eolchar = ch;
229   file.line++;
230   /* skip any different eol characters so we get line counts correct on
231    * DOS text files and similar, but don't count several adjacent blank
232    * lines as one */
233   while (ch != EOF) {
234      nextch();
235      if (ch == eolchar || !isEol(ch)) {
[993454b]236         push_back(ch);
[90bb053f]237         break;
238      }
239   }
240}
241
242static bool
243process_non_data_line(void)
244{
245   process_bol();
246
247   if (isData(ch)) return fFalse;
248
249   if (isKeywd(ch)) {
250      nextch();
251      handle_command();
252   }
253
254   process_eol();
255
256   return fTrue;
257}
258
[21c226e]259static void
260read_reading(reading r, bool f_optional)
261{
262   int n_readings;
263   q_quantity q;
264   VAL(r) = read_numeric(f_optional, &n_readings);
265   switch (r) {
266      case Tape: q = Q_LENGTH; break;
267      case Comp: q = Q_BEARING; break;
268      case BackComp: q = Q_BACKBEARING; break;
269      case Clino: q = Q_GRADIENT; break;
270      case BackClino: q = Q_BACKGRADIENT; break;
271      case FrDepth: case ToDepth: q = Q_DEPTH; break;
272      case Dx: q = Q_DX; break;
273      case Dy: q = Q_DY; break;
274      case Dz: q = Q_DZ; break;
275      case FrCount: case ToCount: q = Q_COUNT; break;
276      default: BUG("Unexpected case");
277   }
278   VAR(r) = var(q);
279   if (n_readings > 1) VAR(r) /= sqrt(n_readings);
280}
281
282static void
283read_bearing_or_omit(reading r)
284{
285   int n_readings;
286   q_quantity q;
287   VAL(r) = read_numeric_or_omit(&n_readings);
288   switch (r) {
289      case Comp: q = Q_BEARING; break;
290      case BackComp: q = Q_BACKBEARING; break;
291      default: BUG("Unexpected case");
292   }
293   VAR(r) = var(q);
294   if (n_readings > 1) VAR(r) /= sqrt(n_readings);
295}
296
[be97baf]297/* For reading Compass MAK files which have a freeform syntax */
298static void
299nextch_handling_eol(void)
300{
301   nextch();
302   while (ch != EOF && isEol(ch)) {
303      process_eol();
304      nextch();
305   }
306}
307
308#define LITLEN(S) (sizeof(S"") - 1)
309#define has_ext(F,L,E) ((L) > LITLEN(E) + 1 &&\
310                        (F)[(L) - LITLEN(E) - 1] == FNM_SEP_EXT &&\
311                        strcasecmp((F) + (L) - LITLEN(E), E) == 0)
[a420b49]312extern void
313data_file(const char *pth, const char *fnm)
314{
[47c7a94]315   int begin_lineno_store;
[7f08c83]316   parse file_store;
[b4fe9fb]317   volatile enum {FMT_SVX, FMT_DAT, FMT_MAK} fmt = FMT_SVX;
[d1b1380]318
[7f08c83]319   {
320      char *filename;
[f4b609d]321      FILE *fh;
[be97baf]322      size_t len;
323
[f4b609d]324      if (!pth) {
325         /* file specified on command line - don't do special translation */
326         fh = fopenWithPthAndExt(pth, fnm, EXT_SVX_DATA, "rb", &filename);
327      } else {
328         fh = fopen_portable(pth, fnm, EXT_SVX_DATA, "rb", &filename);
329      }
[bd1913f]330
[7f08c83]331      if (fh == NULL) {
[759fb47]332         compile_error(/*Couldn't open data file `%s'*/24, fnm);
[7f08c83]333         return;
334      }
335
[be97baf]336      len = strlen(filename);
337      if (has_ext(filename, len, "dat")) {
338         fmt = FMT_DAT;
339      } else if (has_ext(filename, len, "mak")) {
340         fmt = FMT_MAK;
341      }
342
[7f08c83]343      file_store = file;
344      if (file.fh) file.parent = &file_store;
345      file.fh = fh;
346      file.filename = filename;
347      file.line = 1;
[b0d908e]348      file.reported_where = fFalse;
[a420b49]349   }
[cb3d1e2]350
[5b68ae1]351   if (fPercent) printf("%s:\n", fnm);
[d1b1380]352
[a420b49]353   using_data_file(file.filename);
[d1b1380]354
[47c7a94]355   begin_lineno_store = pcs->begin_lineno;
356   pcs->begin_lineno = 0;
[cb3d1e2]357
[d1b1380]358#ifndef NO_PERCENTAGE
[58cc1fb]359   /* Try to find how long the file is...
360    * However, under ANSI fseek( ..., SEEK_END) may not be supported */
361   filelen = 0;
362   if (fPercent) {
[c80bd34]363      if (fseek(file.fh, 0l, SEEK_END) == 0) {
364         filepos fp;
365         get_pos(&fp);
366         filelen = fp.offset;
367      }
[58cc1fb]368      rewind(file.fh); /* reset file ptr to start & clear any error state */
369   }
[d1b1380]370#endif
371
[be97baf]372   if (fmt == FMT_DAT) {
373      short *t;
374      int i;
375      settings *pcsNew;
376
377      pcsNew = osnew(settings);
378      *pcsNew = *pcs; /* copy contents */
379      pcsNew->begin_lineno = 0;
380      pcsNew->next = pcs;
381      pcs = pcsNew;
382      default_units(pcs);
383      default_calib(pcs);
384
385      pcs->style = STYLE_NORMAL;
386      pcs->units[Q_LENGTH] = METRES_PER_FOOT;
387      t = ((short*)osmalloc(ossizeof(short) * 257)) + 1;
388
389      t[EOF] = SPECIAL_EOL;
390      memset(t, 0, sizeof(short) * 33);
391      for (i = 33; i < 127; i++) t[i] = SPECIAL_NAMES;
392      t[127] = 0;
393      for (i = 128; i < 256; i++) t[i] = SPECIAL_NAMES;
394      t['\t'] |= SPECIAL_BLANK;
395      t[' '] |= SPECIAL_BLANK;
396      t['\032'] |= SPECIAL_EOL; /* Ctrl-Z, so olde DOS text files are handled ok */
397      t['\n'] |= SPECIAL_EOL;
398      t['\r'] |= SPECIAL_EOL;
399      t['.'] |= SPECIAL_DECIMAL;
400      t['-'] |= SPECIAL_MINUS;
401      t['+'] |= SPECIAL_PLUS;
402      pcs->Translate = t;
403      pcs->Case = OFF;
404      pcs->Truncate = INT_MAX;
405      pcs->infer = 7; /* FIXME: BIT(EQUATES)|BIT(EXPORTS)|BIT(PLUMBS); */
406   } else if (fmt == FMT_MAK) {
407      short *t;
408      int i;
409      settings *pcsNew;
410
411      pcsNew = osnew(settings);
412      *pcsNew = *pcs; /* copy contents */
413      pcsNew->begin_lineno = 0;
414      pcsNew->next = pcs;
415      pcs = pcsNew;
416
417      t = ((short*)osmalloc(ossizeof(short) * 257)) + 1;
418     
419      t[EOF] = SPECIAL_EOL;
420      memset(t, 0, sizeof(short) * 33);
421      for (i = 33; i < 127; i++) t[i] = SPECIAL_NAMES;
422      t[127] = 0;
423      for (i = 128; i < 256; i++) t[i] = SPECIAL_NAMES;
424      t['['] = t[','] = t[';'] = 0;
425      t['\t'] |= SPECIAL_BLANK;
426      t[' '] |= SPECIAL_BLANK;
427      t['\032'] |= SPECIAL_EOL; /* Ctrl-Z, so olde DOS text files are handled ok */
428      t['\n'] |= SPECIAL_EOL;
429      t['\r'] |= SPECIAL_EOL;
430      t['.'] |= SPECIAL_DECIMAL;
431      t['-'] |= SPECIAL_MINUS;
432      t['+'] |= SPECIAL_PLUS;
433      pcs->Translate = t;
434      pcs->Case = OFF;
435      pcs->Truncate = INT_MAX;
436   }
437
[7d5f3c0]438#ifdef HAVE_SETJMP_H
[a420b49]439   /* errors in nested functions can longjmp here */
440   if (setjmp(file.jbSkipLine)) {
[076d33d]441      process_eol();
[a420b49]442   }
[d1b1380]443#endif
[cb3d1e2]444
[be97baf]445   if (fmt == FMT_DAT) {
446      while (!feof(file.fh) && !ferror(file.fh)) {
447         static reading compass_order[] = {
448            Fr, To, Tape, Comp, Clino, Ignore, Ignore, Ignore, Ignore,
449            CompassDATFlags, IgnoreAll
450         };
451         static reading compass_order_backsights[] = {
452            Fr, To, Tape, Comp, Clino, Ignore, Ignore, Ignore, Ignore,
453            BackComp, BackClino,
454            CompassDATFlags, IgnoreAll
455         };
456         /* <Cave name> */
457         process_bol();
458         skipline();
459         process_eol();
460         /* SURVEY NAME: <Short name> */
461         get_token();
462         get_token();
463         /* if (ch != ':') ... */
464         nextch();
465         skipblanks();
466         get_token();
467         skipline();
468         process_eol();
469         /* SURVEY DATE: 7 10 79  COMMENT:<Long name> */
[b5a3219]470         /* NB order is *month* *day* year */
[be97baf]471         get_token();
472         get_token();
[b5a3219]473         if (ch == ':') {
474             struct tm t;
475
476             copy_on_write_meta(pcs);
477
478             nextch();
479             /* struct tm month uses 0 for Jan */
480             t.tm_mon = read_uint() - 1;
481             t.tm_mday = read_uint();
482             /* struct tm uses year - 1900 */
483             t.tm_year = read_uint();
484             /* Note: Larry says a 2 digit year is always 19XX */
485             if (t.tm_year >= 100) t.tm_year -= 1900;
486
487             pcs->meta->date1 = mktime(&t);
488             pcs->meta->date2 = pcs->meta->date1;
489         }
[be97baf]490         skipline();
491         process_eol();
492         /* SURVEY TEAM: */
493         get_token();
494         get_token();
495         skipline();
496         process_eol();
497         /* <Survey team> */
498         nextch();
499         skipline();
500         process_eol();
501         /* DECLINATION: 1.00  FORMAT: DDDDLUDRADLN  CORRECTIONS: 2.00 3.00 4.00 */
502         get_token();
503         nextch(); /* : */
504         skipblanks();
505         pcs->z[Q_DECLINATION] = -read_numeric(fFalse, NULL);
506         pcs->z[Q_DECLINATION] *= pcs->units[Q_DECLINATION];
507         get_token();
508         pcs->ordering = compass_order;
509         if (strcmp(buffer, "FORMAT") == 0) {
510            nextch(); /* : */
511            get_token();
512            if (strlen(buffer) >= 12 && buffer[11] == 'B') {
513               /* We have backsights for compass and clino */
514               pcs->ordering = compass_order_backsights;
515            }
516            get_token();
[107b8bd]517         }
[be97baf]518         if (strcmp(buffer, "CORRECTIONS") == 0) {
519            nextch(); /* : */
520            pcs->z[Q_BEARING] = -rad(read_numeric(fFalse, NULL));
521            pcs->z[Q_GRADIENT] = -rad(read_numeric(fFalse, NULL));
522            pcs->z[Q_LENGTH] = -read_numeric(fFalse, NULL);
523         } else {
524            pcs->z[Q_BEARING] = 0;
525            pcs->z[Q_GRADIENT] = 0;
526            pcs->z[Q_LENGTH] = 0;
[a420b49]527         }
[be97baf]528         skipline();
529         process_eol();
530         /* BLANK LINE */
531         process_bol();
532         skipline();
533         process_eol();
534         /* heading line */
535         process_bol();
536         skipline();
537         process_eol();
538         /* BLANK LINE */
539         process_bol();
540         skipline();
541         process_eol();
542         while (!feof(file.fh)) {
543            process_bol();
544            if (ch == '\x0c') {
545               nextch();
546               process_eol();
547               break;
548            }
549            (void)data_normal();
550         }
551      }
552      {
553         settings *pcsParent = pcs->next;
554         SVX_ASSERT(pcsParent);
555         pcs->ordering = NULL;
556         free_settings(pcs);
557         pcs = pcsParent;
558      }                                   
559   } else if (fmt == FMT_MAK) {
560      nextch_handling_eol();
561      while (!feof(file.fh) && !ferror(file.fh)) {
562         if (ch == '#') {
563            /* include a file */
564            int ch_store;
[b4fe9fb]565            char *dat_pth = path_from_fnm(file.filename);
566            char *dat_fnm = NULL;
567            int dat_fnm_len;
[be97baf]568            nextch_handling_eol();
569            while (ch != ',' && ch != ';' && ch != EOF) {
570               while (isEol(ch)) process_eol();
[b4fe9fb]571               s_catchar(&dat_fnm, &dat_fnm_len, ch);
[be97baf]572               nextch_handling_eol();
573            }
574            while (ch != ';' && ch != EOF) {
575               prefix *name;
576               nextch_handling_eol();
577               name = read_prefix_stn(fTrue, fFalse);
578               if (name) {
579                  skipblanks();
580                  if (ch == '[') {
581                     /* fixed pt */
582                     node *stn;
583                     real x, y, z;
584                     name->sflags |= BIT(SFLAGS_FIXED);
585                     nextch_handling_eol();
586                     while (!isdigit(ch) && ch != '+' && ch != '-' &&
587                            ch != '.' && ch != ']' && ch != EOF) {
588                        nextch_handling_eol();
589                     }
590                     x = read_numeric(fFalse, NULL);
591                     while (!isdigit(ch) && ch != '+' && ch != '-' &&
592                            ch != '.' && ch != ']' && ch != EOF) {
593                        nextch_handling_eol();
594                     }
595                     y = read_numeric(fFalse, NULL);
596                     while (!isdigit(ch) && ch != '+' && ch != '-' &&
597                            ch != '.' && ch != ']' && ch != EOF) {
598                        nextch_handling_eol();
599                     }
600                     z = read_numeric(fFalse, NULL);
601                     stn = StnFromPfx(name);
602                     if (!fixed(stn)) {
603                        POS(stn, 0) = x;
604                        POS(stn, 1) = y;
605                        POS(stn, 2) = z;
606                        fix(stn);
607                     } else {
608                        if (x != POS(stn, 0) || y != POS(stn, 1) ||
609                            z != POS(stn, 2)) {
610                           compile_error(/*Station already fixed or equated to a fixed point*/46);
611                        } else {
612                           compile_warning(/*Station already fixed at the same coordinates*/55);
613                        }
614                     }
615                     while (ch != ']' && ch != EOF) nextch_handling_eol();
616                     if (ch == ']') {
617                        nextch_handling_eol();
618                        skipblanks();
619                     }
620                  } else {
621                     /* FIXME: link station - ignore for now */
622                     /* FIXME: perhaps issue warning? */
623                  }
624                  while (ch != ',' && ch != ';' && ch != EOF)
625                     nextch_handling_eol();
626               }
627            }
[b4fe9fb]628            if (dat_fnm) {
[be97baf]629               ch_store = ch;
[b4fe9fb]630               data_file(dat_pth, dat_fnm);
[be97baf]631               ch = ch_store;
[b4fe9fb]632               osfree(dat_fnm);
[be97baf]633            }
634         } else {
635            /* FIXME: also check for % and $ later */
636            nextch_handling_eol();
637         }
638      }
639      {
640         settings *pcsParent = pcs->next;
641         SVX_ASSERT(pcsParent);
642         free_settings(pcs);
643         pcs = pcsParent;
644      }                                   
645   } else {
646      while (!feof(file.fh) && !ferror(file.fh)) {
647         if (!process_non_data_line()) {
[b4fe9fb]648            volatile int r;
[be97baf]649#ifdef CHASM3DX
650            twig *temp = limb;
[21c226e]651#endif
[be97baf]652            f_export_ok = fFalse;
653            switch (pcs->style) {
654             case STYLE_NORMAL:
655             case STYLE_DIVING:
656             case STYLE_CYLPOLAR:
657               r = data_normal();
658               break;
659             case STYLE_CARTESIAN:
660               r = data_cartesian();
661               break;
662             case STYLE_NOSURVEY:
663               r = data_nosurvey();
664               break;
665             case STYLE_IGNORE:
666               r = data_ignore();
667               break;
668             default:
669               BUG("bad style");
670            }
671            /* style function returns 0 => error */
672#ifdef CHASM3DX
673            if (!r && fUseNewFormat) {
674               /* we have just created a very naughty twiglet, and it must be
675                * punished */
676               osfree(limb);
677               limb = temp;
678            }
679#endif
680         }
[647407d]681      }
[a420b49]682   }
683
[932f7e9]684   /* don't allow *BEGIN at the end of a file, then *EXPORT in the
685    * including file */
686   f_export_ok = fFalse;
687
[a420b49]688#ifndef NO_PERCENTAGE
689   if (fPercent) putnl();
[4f8285d]690#endif
[d1b1380]691
[47c7a94]692   if (pcs->begin_lineno) {
[0e867ba6]693      error_in_file(file.filename, pcs->begin_lineno,
694                    /*BEGIN with no matching END in this file*/23);
[47c7a94]695      /* Implicitly close any unclosed BEGINs from this file */
696      do {
697         settings *pcsParent = pcs->next;
[4c07c51]698         SVX_ASSERT(pcsParent);
[647407d]699         free_settings(pcs);
[47c7a94]700         pcs = pcsParent;
701      } while (pcs->begin_lineno);
702   }
703
704   pcs->begin_lineno = begin_lineno_store;
[cb3d1e2]705
[22c9877]706   if (ferror(file.fh))
[bfe1242]707      fatalerror_in_file(file.filename, 0, /*Error reading file*/18);
[cb3d1e2]708
[22c9877]709   (void)fclose(file.fh);
[7f08c83]710
[22c9877]711   file = file_store;
[4d9eecd]712
713   /* don't free this - it may be pointed to by prefix.file */
714   /* osfree(file.filename); */
[a420b49]715}
[d1b1380]716
[b6de07d]717static real
718mod2pi(real a)
719{
720   return a - floor(a / (2 * M_PI)) * (2 * M_PI);
721}
722
[dcec245]723static real
[5b7c1b7]724handle_plumb(clino_type *p_ctype)
[dcec245]725{
726   typedef enum {
727      CLINO_NULL=-1, CLINO_UP, CLINO_DOWN, CLINO_LEVEL
728   } clino_tok;
729   static sztok clino_tab[] = {
730      {"D",     CLINO_DOWN},
731      {"DOWN",  CLINO_DOWN},
732      {"H",     CLINO_LEVEL},
733      {"LEVEL", CLINO_LEVEL},
734      {"U",     CLINO_UP},
735      {"UP",    CLINO_UP},
736      {NULL,    CLINO_NULL}
737   };
[5b7c1b7]738   static real clinos[] = {(real)M_PI_2, (real)(-M_PI_2), (real)0.0};
[dcec245]739   clino_tok tok;
740
741   skipblanks();
742   if (isalpha(ch)) {
[c80bd34]743      filepos fp;
744      get_pos(&fp);
[dcec245]745      get_token();
746      tok = match_tok(clino_tab, TABSIZE(clino_tab));
747      if (tok != CLINO_NULL) {
[be97baf]748         *p_ctype = (tok == CLINO_LEVEL ? CTYPE_HORIZ : CTYPE_PLUMB);
[dcec245]749         return clinos[tok];
750      }
[c80bd34]751      set_pos(&fp);
[dcec245]752   } else if (isSign(ch)) {
753      int chOld = ch;
754      nextch();
755      if (toupper(ch) == 'V') {
756         nextch();
[fa42426]757         *p_ctype = CTYPE_PLUMB;
[bceebf4]758         return (!isMinus(chOld) ? M_PI_2 : -M_PI_2);
[dcec245]759      }
760
[bd1913f]761      if (isOmit(chOld)) {
[fa42426]762         *p_ctype = CTYPE_OMIT;
[dcec245]763         /* no clino reading, so assume 0 with large sd */
764         return (real)0.0;
765      }
[5b7c1b7]766   } else if (isOmit(ch)) {
767      /* OMIT char may not be a SIGN char too so we need to check here as
768       * well as above... */
769      nextch();
[fa42426]770      *p_ctype = CTYPE_OMIT;
[5b7c1b7]771      /* no clino reading, so assume 0 with large sd */
772      return (real)0.0;
[dcec245]773   }
774   return HUGE_REAL;
775}
776
[b6de07d]777static void
[b4fe9fb]778warn_readings_differ(int msgno, real diff)
[b6de07d]779{
780   char buf[64];
781   char *p;
782   sprintf(buf, "%.2f", deg(fabs(diff)));
783   p = strchr(buf, '.');
784   if (p) {
785      char *z = p;
786      while (*++p) {
787         if (*p != '0') z = p + 1;
788      }
789      if (*z) *z = '\0';
790   }
[b4fe9fb]791   compile_warning(msgno, buf);
[b6de07d]792}
793
794static bool
[21c226e]795handle_comp_units(void)
[b6de07d]796{
797   bool fNoComp = fTrue;
[21c226e]798   if (VAL(Comp) != HUGE_REAL) {
[b6de07d]799      fNoComp = fFalse;
[21c226e]800      VAL(Comp) *= pcs->units[Q_BEARING];
801      if (VAL(Comp) < (real)0.0 || VAL(Comp) - M_PI * 2.0 > EPSILON) {
[b6de07d]802         compile_warning(/*Suspicious compass reading*/59);
[21c226e]803         VAL(Comp) = mod2pi(VAL(Comp));
[b6de07d]804      }
805   }
[21c226e]806   if (VAL(BackComp) != HUGE_REAL) {
[b6de07d]807      fNoComp = fFalse;
[21c226e]808      VAL(BackComp) *= pcs->units[Q_BACKBEARING];
809      if (VAL(BackComp) < (real)0.0 || VAL(BackComp) - M_PI * 2.0 > EPSILON) {
[b6de07d]810         /* FIXME: different message for BackComp? */
811         compile_warning(/*Suspicious compass reading*/59);
[21c226e]812         VAL(BackComp) = mod2pi(VAL(BackComp));
[b6de07d]813      }
814   }
815   return fNoComp;
816}
817
818static real
[21c226e]819handle_compass(real *p_var)
[b6de07d]820{
[b4fe9fb]821   real compvar = VAR(Comp);
[21c226e]822   real comp = VAL(Comp);
823   real backcomp = VAL(BackComp);
[b6de07d]824   if (comp != HUGE_REAL) {
825      comp = (comp - pcs->z[Q_BEARING]) * pcs->sc[Q_BEARING];
826      comp -= pcs->z[Q_DECLINATION];
827   }
828   if (backcomp != HUGE_REAL) {
829      backcomp = (backcomp - pcs->z[Q_BACKBEARING])
830              * pcs->sc[Q_BACKBEARING];
831      backcomp -= pcs->z[Q_DECLINATION];
832      backcomp -= M_PI;
833      if (comp != HUGE_REAL) {
834         real diff = comp - backcomp;
835         real adj = fabs(diff) > M_PI ? M_PI : 0;
836         diff -= floor((diff + M_PI) / (2 * M_PI)) * 2 * M_PI;
[b4fe9fb]837         if (sqrd(diff / 2.0) > compvar + VAR(Q_BACKBEARING)) {
[770157e]838            /* fore and back readings differ by more than 2 sds */
[fa42426]839            warn_readings_differ(/*Compass reading and back compass reading disagree by %s degrees*/98, diff);
[b6de07d]840         }
[b4fe9fb]841         comp = (comp / compvar + backcomp / VAR(BackComp));
842         compvar = (compvar + VAR(BackComp)) / 4;
843         comp *= compvar;
[b6de07d]844         comp += adj;
845      } else {
846         comp = backcomp;
[b4fe9fb]847         compvar = VAR(BackComp);
[b6de07d]848      }
849   }
[b4fe9fb]850   *p_var = compvar;
[b6de07d]851   return comp;
852}
853
[90bb053f]854static int
[21c226e]855process_normal(prefix *fr, prefix *to, bool fToFirst,
856               clino_type ctype, clino_type backctype)
[a420b49]857{
[21c226e]858   real tape = VAL(Tape);
859   real clin = VAL(Clino);
860   real backclin = VAL(BackClino);
861
[a420b49]862   real dx, dy, dz;
863   real vx, vy, vz;
864#ifndef NO_COVARIANCES
[cb3d1e2]865   real cxy, cyz, czx;
[a420b49]866#endif
[d1b1380]867
[90bb053f]868   bool fNoComp;
[a420b49]869
[107b8bd]870   /* adjusted tape is negative -- probably the calibration is wrong */
871   if (tape < (real)0.0) {
872      /* TRANSLATE different message for topofil? */
873      compile_warning(/*Negative adjusted tape reading*/79);
[647407d]874   }
[d1b1380]875
[21c226e]876   fNoComp = handle_comp_units();
[d1b1380]877
[fa42426]878   if (ctype == CTYPE_READING) {
[0b71cfc]879      real diff_from_abs90;
[a420b49]880      clin *= pcs->units[Q_GRADIENT];
[fa42426]881      /* percentage scale */
882      if (pcs->f_clino_percent) clin = atan(clin);
[0b71cfc]883      diff_from_abs90 = fabs(clin) - M_PI_2;
884      if (diff_from_abs90 > EPSILON) {
[a420b49]885         compile_warning(/*Clino reading over 90 degrees (absolute value)*/51);
[27b8b59]886      } else if (TSTBIT(pcs->infer, INFER_PLUMBS) &&
[be97baf]887                 diff_from_abs90 >= -EPSILON) {
888         ctype = CTYPE_INFERPLUMB;
[a420b49]889      }
890   }
[cb3d1e2]891
[fa42426]892   if (backctype == CTYPE_READING) {
[b14f44f]893      backclin *= pcs->units[Q_BACKGRADIENT];
[fa42426]894      /* percentage scale */
895      if (pcs->f_backclino_percent) backclin = atan(backclin);
[be97baf]896      if (ctype != CTYPE_READING) {
897         real diff_from_abs90 = fabs(backclin) - M_PI_2;
898         if (diff_from_abs90 > EPSILON) {
899            /* FIXME: different message for BackClino? */
900            compile_warning(/*Clino reading over 90 degrees (absolute value)*/51);
901         } else if (TSTBIT(pcs->infer, INFER_PLUMBS) &&
902                    diff_from_abs90 >= -EPSILON) {
903            backctype = CTYPE_INFERPLUMB;
904         }
[0b71cfc]905      }
906   }
907
[be97baf]908   /* un-infer the plumb if the backsight was just a reading */
909   if (ctype == CTYPE_INFERPLUMB && backctype == CTYPE_READING) {
910       ctype = CTYPE_READING;
911   }
912
[fa42426]913   if (ctype != CTYPE_OMIT && backctype != CTYPE_OMIT && ctype != backctype) {
914      compile_error_skip(/*Clino and BackClino readings must be of the same type*/84);
[b14f44f]915      return 0;
[0b71cfc]916   }
917
[be97baf]918   if (ctype == CTYPE_PLUMB || ctype == CTYPE_INFERPLUMB ||
919       backctype == CTYPE_PLUMB || backctype == CTYPE_INFERPLUMB) {
[a420b49]920      /* plumbed */
921      if (!fNoComp) {
[be97baf]922         if (ctype == CTYPE_PLUMB ||
923             (ctype == CTYPE_INFERPLUMB && VAL(Comp) != 0.0) ||
924             backctype == CTYPE_PLUMB ||
925             (backctype == CTYPE_INFERPLUMB && VAL(BackComp) != 0.0)) {
926            /* FIXME: Different message for BackComp? */
927            compile_warning(/*Compass reading given on plumbed leg*/21);
928         }
[a420b49]929      }
930
931      dx = dy = (real)0.0;
[fa42426]932      if (ctype != CTYPE_OMIT) {
933         if (backctype != CTYPE_OMIT && (clin > 0) == (backclin > 0)) {
[b14f44f]934            /* We've got two UPs or two DOWNs - FIXME: not ideal message */
[fa42426]935            compile_error_skip(/*Clino and BackClino readings must be of the same type*/84);
[b14f44f]936            return 0;
[0b71cfc]937         }
938         dz = (clin > (real)0.0) ? tape : -tape;
939      } else {
940         dz = (backclin < (real)0.0) ? tape : -tape;
941      }
[a420b49]942      vx = vy = var(Q_POS) / 3.0 + dz * dz * var(Q_PLUMB);
[21c226e]943      vz = var(Q_POS) / 3.0 + VAR(Tape);
[4f8285d]944#ifndef NO_COVARIANCES
[26a805f]945      /* Correct values - no covariances in this case! */
946      cxy = cyz = czx = (real)0.0;
[4f8285d]947#endif
[a420b49]948   } else {
[fa42426]949      /* Each of ctype and backctype are either CTYPE_READING/CTYPE_HORIZ
950       * or CTYPE_OMIT */
[a420b49]951      /* clino */
952      real L2, cosG, LcosG, cosG2, sinB, cosB, dx2, dy2, dz2, v, V;
[421b7d2]953      if (fNoComp) {
[fa42426]954         compile_error_skip(/*Compass reading may not be omitted except on plumbed legs*/14);
[a420b49]955         return 0;
956      }
957      if (tape == (real)0.0) {
958         dx = dy = dz = (real)0.0;
959         vx = vy = vz = (real)(var(Q_POS) / 3.0); /* Position error only */
[4f8285d]960#ifndef NO_COVARIANCES
[a420b49]961         cxy = cyz = czx = (real)0.0;
[4f8285d]962#endif
[d1b1380]963#if DEBUG_DATAIN_1
[a420b49]964         printf("Zero length leg: vx = %f, vy = %f, vz = %f\n", vx, vy, vz);
[d1b1380]965#endif
[a420b49]966      } else {
[dbb4e19]967         real sinGcosG;
[0b71cfc]968         /* take into account variance in LEVEL case */
969         real var_clin = var(Q_LEVEL);
[b6de07d]970         real var_comp;
[21c226e]971         real comp = handle_compass(&var_comp);
[fa42426]972         /* ctype != CTYPE_READING is LEVEL case */
973         if (ctype == CTYPE_READING) {
[a420b49]974            clin = (clin - pcs->z[Q_GRADIENT]) * pcs->sc[Q_GRADIENT];
[21c226e]975            var_clin = VAR(Clino);
[0b71cfc]976         }
[fa42426]977         if (backctype == CTYPE_READING) {
[b14f44f]978            backclin = (backclin - pcs->z[Q_BACKGRADIENT])
979               * pcs->sc[Q_BACKGRADIENT];
[fa42426]980            if (ctype == CTYPE_READING) {
[be97baf]981               if (sqrd((clin + backclin) / 3.0) > var_clin + VAR(BackClino)) {
[b14f44f]982                  /* fore and back readings differ by more than 3 sds */
[fa42426]983                  warn_readings_differ(/*Clino reading and back clino reading disagree by %s degrees*/99, clin + backclin);
[b14f44f]984               }
[21c226e]985               clin = (clin / var_clin - backclin / VAR(BackClino));
986               var_clin = (var_clin + VAR(BackClino)) / 4;
[b14f44f]987               clin *= var_clin;
[0b71cfc]988            } else {
989               clin = -backclin;
[21c226e]990               var_clin = VAR(BackClino);
[0b71cfc]991            }
992         }
[d1b1380]993
994#if DEBUG_DATAIN
[a420b49]995         printf("    %4.2f %4.2f %4.2f\n", tape, comp, clin);
[d1b1380]996#endif
[a420b49]997         cosG = cos(clin);
998         LcosG = tape * cosG;
999         sinB = sin(comp);
1000         cosB = cos(comp);
[d1b1380]1001#if DEBUG_DATAIN_1
[a420b49]1002         printf("sinB = %f, cosG = %f, LcosG = %f\n", sinB, cosG, LcosG);
[d1b1380]1003#endif
[a420b49]1004         dx = LcosG * sinB;
1005         dy = LcosG * cosB;
1006         dz = tape * sin(clin);
[d1b1380]1007/*      printf("%.2f\n",clin); */
1008#if DEBUG_DATAIN_1
[a420b49]1009         printf("dx = %f\ndy = %f\ndz = %f\n", dx, dy, dz);
[d1b1380]1010#endif
[a420b49]1011         dx2 = dx * dx;
1012         L2 = tape * tape;
[21c226e]1013         V = VAR(Tape) / L2;
[a420b49]1014         dy2 = dy * dy;
1015         cosG2 = cosG * cosG;
[dbb4e19]1016         sinGcosG = sin(clin) * cosG;
[a420b49]1017         dz2 = dz * dz;
[0b71cfc]1018         v = dz2 * var_clin;
[5b7c1b7]1019#ifdef NO_COVARIANCES
[0b71cfc]1020         vx = (var(Q_POS) / 3.0 + dx2 * V + dy2 * var_comp +
[a420b49]1021               (.5 + sinB * sinB * cosG2) * v);
[0b71cfc]1022         vy = (var(Q_POS) / 3.0 + dy2 * V + dx2 * var_comp +
[a420b49]1023               (.5 + cosB * cosB * cosG2) * v);
[fa42426]1024         if (ctype == CTYPE_OMIT && backctype == CTYPE_OMIT) {
[5b7c1b7]1025            /* if no clino, assume sd=tape/sqrt(10) so 3sds = .95*tape */
[0b71cfc]1026            vz = var(Q_POS) / 3.0 + L2 * (real)0.1;
[5b7c1b7]1027         } else {
[0b71cfc]1028            vz = var(Q_POS) / 3.0 + dz2 * V + L2 * cosG2 * var_clin;
[5b7c1b7]1029         }
[a420b49]1030         /* for Surveyor87 errors: vx=vy=vz=var(Q_POS)/3.0; */
[dbb4e19]1031#else
[0b71cfc]1032         vx = var(Q_POS) / 3.0 + dx2 * V + dy2 * var_comp +
[dbb4e19]1033            (sinB * sinB * v);
[0b71cfc]1034         vy = var(Q_POS) / 3.0 + dy2 * V + dx2 * var_comp +
[dbb4e19]1035            (cosB * cosB * v);
[fa42426]1036         if (ctype == CTYPE_OMIT && backctype == CTYPE_OMIT) {
[5b7c1b7]1037            /* if no clino, assume sd=tape/sqrt(10) so 3sds = .95*tape */
[0b71cfc]1038            vz = var(Q_POS) / 3.0 + L2 * (real)0.1;
[5b7c1b7]1039         } else {
[0b71cfc]1040            vz = var(Q_POS) / 3.0 + dz2 * V + L2 * cosG2 * var_clin;
[5b7c1b7]1041         }
[647407d]1042         /* usual covariance formulae are fine in no clino case since
[0b71cfc]1043          * dz = 0 so value of var_clin is ignored */
[21c226e]1044         cxy = sinB * cosB * (VAR(Tape) * cosG2 + var_clin * dz2)
[0b71cfc]1045               - var_comp * dx * dy;
[21c226e]1046         czx = VAR(Tape) * sinB * sinGcosG - var_clin * dx * dz;
1047         cyz = VAR(Tape) * cosB * sinGcosG - var_clin * dy * dz;
[dbb4e19]1048#if 0
1049         printf("vx = %6.3f, vy = %6.3f, vz = %6.3f\n", vx, vy, vz);
1050         printf("cxy = %6.3f, cyz = %6.3f, czx = %6.3f\n", cxy, cyz, czx);
1051#endif
[4f8285d]1052#endif
[d1b1380]1053#if DEBUG_DATAIN_1
[a420b49]1054         printf("In DATAIN.C, vx = %f, vy = %f, vz = %f\n", vx, vy, vz);
[d1b1380]1055#endif
[a420b49]1056      }
1057   }
[d1b1380]1058#if DEBUG_DATAIN_1
[a420b49]1059   printf("Just before addleg, vx = %f\n", vx);
[d1b1380]1060#endif
[a420b49]1061   /*printf("dx,dy,dz = %.2f %.2f %.2f\n\n", dx, dy, dz);*/
[90bb053f]1062   addlegbyname(fr, to, fToFirst, dx, dy, dz, vx, vy, vz
[4f8285d]1063#ifndef NO_COVARIANCES
[2140502]1064                , cyz, czx, cxy
[4f8285d]1065#endif
[2140502]1066                );
[647407d]1067
[be97baf]1068#ifdef CHASM3DX
[647407d]1069   if (fUseNewFormat) {
[407084d]1070      /* new twiglet and insert into twig tree */
1071      twig *twiglet = osnew(twig);
[90bb053f]1072      twiglet->from = fr;
1073      twiglet->to = to;
[407084d]1074      twiglet->down = twiglet->right = NULL;
1075      twiglet->source = twiglet->drawings
1076        = twiglet->date = twiglet->instruments = twiglet->tape = NULL;
1077      twiglet->up = limb->up;
1078      limb->right = twiglet;
1079      limb = twiglet;
1080
1081      /* record pre-fettling deltas */
[647407d]1082      twiglet->delta[0] = dx;
1083      twiglet->delta[1] = dy;
1084      twiglet->delta[2] = dz;
1085   }
1086#endif
[a420b49]1087   return 1;
[d1b1380]1088}
1089
[5a38209]1090static int
[21c226e]1091process_diving(prefix *fr, prefix *to, bool fToFirst, bool fDepthChange)
[a420b49]1092{
[21c226e]1093   real tape = VAL(Tape);
1094
[a420b49]1095   real dx, dy, dz;
1096   real vx, vy, vz;
[f795df0]1097#ifndef NO_COVARIANCES
1098   real cxy = 0, cyz = 0, czx = 0;
1099#endif
[a420b49]1100
[21c226e]1101   handle_comp_units();
[a420b49]1102
[a6d094f]1103   /* depth gauge readings increase upwards with default calibration */
[6114207]1104   if (fDepthChange) {
[21c226e]1105      SVX_ASSERT(VAL(FrDepth) == 0.0);
1106      dz = VAL(ToDepth) * pcs->units[Q_DEPTH] - pcs->z[Q_DEPTH];
1107      dz *= pcs->sc[Q_DEPTH];
[a6d094f]1108   } else {
[21c226e]1109      dz = VAL(ToDepth) - VAL(FrDepth);
1110      dz *= pcs->units[Q_DEPTH] * pcs->sc[Q_DEPTH];
[a6d094f]1111   }
[a420b49]1112
1113   /* adjusted tape is negative -- probably the calibration is wrong */
1114   if (tape < (real)0.0) {
1115      compile_warning(/*Negative adjusted tape reading*/79);
1116   }
1117
1118   /* check if tape is less than depth change */
1119   if (tape < fabs(dz)) {
[bd1913f]1120      /* FIXME: allow margin of error based on variances? */
[a420b49]1121      compile_warning(/*Tape reading is less than change in depth*/62);
1122   }
1123
[0a208f9]1124   if (tape == (real)0.0 && dz == 0.0) {
[a420b49]1125      dx = dy = dz = (real)0.0;
1126      vx = vy = vz = (real)(var(Q_POS) / 3.0); /* Position error only */
[21c226e]1127   } else if (VAL(Comp) == HUGE_REAL &&
1128              VAL(BackComp) == HUGE_REAL) {
[385b703]1129      /* plumb */
1130      dx = dy = (real)0.0;
1131      if (dz < 0) tape = -tape;
[21c226e]1132      /* FIXME: Should use FrDepth sometimes... */
1133      dz = (dz * VAR(Tape) + tape * 2 * VAR(ToDepth))
1134         / (VAR(Tape) * 2 * VAR(ToDepth));
[385b703]1135      vx = vy = var(Q_POS) / 3.0 + dz * dz * var(Q_PLUMB);
[21c226e]1136      /* FIXME: Should use FrDepth sometimes... */
1137      vz = var(Q_POS) / 3.0 + VAR(Tape) * 2 * VAR(ToDepth)
1138                              / (VAR(Tape) + VAR(ToDepth));
[a420b49]1139   } else {
[f795df0]1140      real L2, sinB, cosB, dz2, D2;
[b6de07d]1141      real var_comp;
[21c226e]1142      real comp = handle_compass(&var_comp);
[a420b49]1143      sinB = sin(comp);
1144      cosB = cos(comp);
1145      L2 = tape * tape;
1146      dz2 = dz * dz;
1147      D2 = L2 - dz2;
1148      if (D2 <= (real)0.0) {
[21c226e]1149         /* FIXME: Should use FrDepth sometimes... */
1150         real vsum = VAR(Tape) + 2 * VAR(ToDepth);
[a420b49]1151         dx = dy = (real)0.0;
[f795df0]1152         vx = vy = var(Q_POS) / 3.0;
[21c226e]1153         /* FIXME: Should use FrDepth sometimes... */
1154         vz = var(Q_POS) / 3.0 + VAR(Tape) * 2 * VAR(ToDepth) / vsum;
[f795df0]1155         if (dz > 0) {
[21c226e]1156            /* FIXME: Should use FrDepth sometimes... */
1157            dz = (dz * VAR(Tape) + tape * 2 * VAR(ToDepth)) / vsum;
[f795df0]1158         } else {
[21c226e]1159            dz = (dz * VAR(Tape) - tape * 2 * VAR(ToDepth)) / vsum;
[f795df0]1160         }
[a420b49]1161      } else {
1162         real D = sqrt(D2);
[21c226e]1163         /* FIXME: Should use FrDepth sometimes... */
1164         real F = VAR(Tape) * L2 + 2 * VAR(ToDepth) * D2;
[a420b49]1165         dx = D * sinB;
1166         dy = D * cosB;
[f795df0]1167
1168         vx = var(Q_POS) / 3.0 +
[72095d3]1169            sinB * sinB * F / D2 + var_comp * dy * dy;
[f795df0]1170         vy = var(Q_POS) / 3.0 +
[72095d3]1171            cosB * cosB * F / D2 + var_comp * dx * dx;
[21c226e]1172         /* FIXME: Should use FrDepth sometimes... */
1173         vz = var(Q_POS) / 3.0 + 2 * VAR(ToDepth);
[f795df0]1174
1175#ifndef NO_COVARIANCES
[72095d3]1176         cxy = sinB * cosB * (F / D2 + var_comp * D2);
[21c226e]1177         /* FIXME: Should use FrDepth sometimes... */
1178         cyz = -2 * VAR(ToDepth) * dy / D;
1179         czx = -2 * VAR(ToDepth) * dx / D;
[f795df0]1180#endif
[a420b49]1181      }
1182   }
[5a38209]1183   addlegbyname(fr, to, fToFirst, dx, dy, dz, vx, vy, vz
[2140502]1184#ifndef NO_COVARIANCES
[f795df0]1185                , cxy, cyz, czx
[647407d]1186#endif
[2140502]1187                );
[be97baf]1188#ifdef CHASM3DX
[647407d]1189   if (fUseNewFormat) {
[be97baf]1190      /* new twiglet and insert into twig tree */
[407084d]1191      twig *twiglet = osnew(twig);
[90bb053f]1192      twiglet->from = fr;
1193      twiglet->to = to;
[407084d]1194      twiglet->down = twiglet->right = NULL;
1195      twiglet->source = twiglet->drawings
1196        = twiglet->date = twiglet->instruments = twiglet->tape = NULL;
1197      twiglet->up = limb->up;
1198      limb->right = twiglet;
1199      limb = twiglet;
1200
1201      /* record pre-fettling deltas */
[647407d]1202      twiglet->delta[0] = dx;
1203      twiglet->delta[1] = dy;
1204      twiglet->delta[2] = dz;
1205   }
1206#endif
1207
1208   return 1;
1209}
1210
[5a38209]1211static int
[21c226e]1212process_cartesian(prefix *fr, prefix *to, bool fToFirst)
[5a38209]1213{
[21c226e]1214   real dx = (VAL(Dx) * pcs->units[Q_DX] - pcs->z[Q_DX]) * pcs->sc[Q_DX];
1215   real dy = (VAL(Dy) * pcs->units[Q_DY] - pcs->z[Q_DY]) * pcs->sc[Q_DY];
1216   real dz = (VAL(Dz) * pcs->units[Q_DZ] - pcs->z[Q_DZ]) * pcs->sc[Q_DZ];
[647407d]1217
[21c226e]1218   addlegbyname(fr, to, fToFirst, dx, dy, dz, VAR(Dx), VAR(Dy), VAR(Dz)
[647407d]1219#ifndef NO_COVARIANCES
[c80bd34]1220                , 0, 0, 0
[647407d]1221#endif
[2140502]1222                );
[647407d]1223
[be97baf]1224#ifdef CHASM3DX
[647407d]1225   if (fUseNewFormat) {
[407084d]1226      /* new twiglet and insert into twig tree */
1227      twig *twiglet = osnew(twig);
[90bb053f]1228      twiglet->from = fr;
1229      twiglet->to = to;
[407084d]1230      twiglet->down = twiglet->right = NULL;
1231      twiglet->source = twiglet->drawings
1232        = twiglet->date = twiglet->instruments = twiglet->tape = NULL;
1233      twiglet->up = limb->up;
1234      limb->right = twiglet;
1235      limb = twiglet;
1236
1237      /* record pre-fettling deltas */
[647407d]1238      twiglet->delta[0] = dx;
1239      twiglet->delta[1] = dy;
1240      twiglet->delta[2] = dz;
1241   }
[4f8285d]1242#endif
[647407d]1243
1244   return 1;
1245}
1246
1247extern int
[5a38209]1248data_cartesian(void)
[647407d]1249{
[90bb053f]1250   prefix *fr = NULL, *to = NULL;
[5a38209]1251
1252   bool fMulti = fFalse;
[647407d]1253
[0395657]1254   reading first_stn = End;
1255
1256   reading *ordering;
[647407d]1257
[5a38209]1258   again:
1259
[647407d]1260   for (ordering = pcs->ordering ; ; ordering++) {
1261      skipblanks();
1262      switch (*ordering) {
[4a6a094]1263       case Fr:
[21c226e]1264         fr = read_prefix_stn(fFalse, fTrue);
1265         if (first_stn == End) first_stn = Fr;
1266         break;
[4a6a094]1267       case To:
[21c226e]1268         to = read_prefix_stn(fFalse, fTrue);
1269         if (first_stn == End) first_stn = To;
1270         break;
[5a38209]1271       case Station:
[21c226e]1272         fr = to;
1273         to = read_prefix_stn(fFalse, fFalse);
1274         first_stn = To;
1275         break;
1276       case Dx: case Dy: case Dz:
1277         read_reading(*ordering, fFalse);
1278         break;
[647407d]1279       case Ignore:
1280         skipword(); break;
[5a38209]1281       case IgnoreAllAndNewLine:
1282         skipline();
1283         /* fall through */
1284       case Newline:
1285         if (fr != NULL) {
1286            int r;
[21c226e]1287            r = process_cartesian(fr, to, first_stn == To);
[5a38209]1288            if (!r) skipline();
1289         }
1290         fMulti = fTrue;
1291         while (1) {
1292            process_eol();
1293            process_bol();
1294            if (isData(ch)) break;
[ee6a621]1295            if (!isComm(ch)) {
[993454b]1296               push_back(ch);
[ee6a621]1297               return 1;
1298            }
[5a38209]1299         }
1300         break;
[647407d]1301       case IgnoreAll:
1302         skipline();
1303         /* fall through */
1304       case End:
[5a38209]1305         if (!fMulti) {
[21c226e]1306            int r = process_cartesian(fr, to, first_stn == To);
[5a38209]1307            process_eol();
1308            return r;
1309         }
[eef4d8c]1310         do {
[5a38209]1311            process_eol();
1312            process_bol();
[eef4d8c]1313         } while (isComm(ch));
[5a38209]1314         goto again;
[0395657]1315       default: BUG("Unknown reading in ordering");
[647407d]1316      }
1317   }
[5a38209]1318}
[cb3d1e2]1319
[98a2eec]1320static int
[21c226e]1321process_cylpolar(prefix *fr, prefix *to, bool fToFirst, bool fDepthChange)
[98a2eec]1322{
[21c226e]1323   real tape = VAL(Tape);
1324
[98a2eec]1325   real dx, dy, dz;
1326   real vx, vy, vz;
1327#ifndef NO_COVARIANCES
1328   real cxy = 0;
1329#endif
1330
[21c226e]1331   handle_comp_units();
[98a2eec]1332
[a6d094f]1333   /* depth gauge readings increase upwards with default calibration */
[6114207]1334   if (fDepthChange) {
[21c226e]1335      SVX_ASSERT(VAL(FrDepth) == 0.0);
1336      dz = VAL(ToDepth) * pcs->units[Q_DEPTH] - pcs->z[Q_DEPTH];
1337      dz *= pcs->sc[Q_DEPTH];
[a6d094f]1338   } else {
[21c226e]1339      dz = VAL(ToDepth) - VAL(FrDepth);
1340      dz *= pcs->units[Q_DEPTH] * pcs->sc[Q_DEPTH];
[a6d094f]1341   }
[98a2eec]1342
1343   /* adjusted tape is negative -- probably the calibration is wrong */
1344   if (tape < (real)0.0) {
1345      compile_warning(/*Negative adjusted tape reading*/79);
1346   }
1347
[21c226e]1348   if (VAL(Comp) == HUGE_REAL && VAL(BackComp) == HUGE_REAL) {
[98a2eec]1349      /* plumb */
1350      dx = dy = (real)0.0;
1351      vx = vy = var(Q_POS) / 3.0 + dz * dz * var(Q_PLUMB);
[21c226e]1352      /* FIXME: Should use FrDepth sometimes... */
1353      vz = var(Q_POS) / 3.0 + 2 * VAR(ToDepth);
[98a2eec]1354   } else {
1355      real sinB, cosB;
[b6de07d]1356      real var_comp;
[21c226e]1357      real comp = handle_compass(&var_comp);
[98a2eec]1358      sinB = sin(comp);
1359      cosB = cos(comp);
1360
1361      dx = tape * sinB;
1362      dy = tape * cosB;
1363
1364      vx = var(Q_POS) / 3.0 +
[21c226e]1365         VAR(Tape) * sinB * sinB + var_comp * dy * dy;
[98a2eec]1366      vy = var(Q_POS) / 3.0 +
[21c226e]1367         VAR(Tape) * cosB * cosB + var_comp * dx * dx;
1368      /* FIXME: Should use FrDepth sometimes... */
1369      vz = var(Q_POS) / 3.0 + 2 * VAR(ToDepth);
[98a2eec]1370
1371#ifndef NO_COVARIANCES
[21c226e]1372      cxy = (VAR(Tape) - var_comp * tape * tape) * sinB * cosB;
[98a2eec]1373#endif
1374   }
1375   addlegbyname(fr, to, fToFirst, dx, dy, dz, vx, vy, vz
1376#ifndef NO_COVARIANCES
1377                , cxy, 0, 0
1378#endif
1379                );
[be97baf]1380#ifdef CHASM3DX
[98a2eec]1381   if (fUseNewFormat) {
[be97baf]1382      /* new twiglet and insert into twig tree */
[98a2eec]1383      twig *twiglet = osnew(twig);
1384      twiglet->from = fr;
1385      twiglet->to = to;
1386      twiglet->down = twiglet->right = NULL;
1387      twiglet->source = twiglet->drawings
1388        = twiglet->date = twiglet->instruments = twiglet->tape = NULL;
1389      twiglet->up = limb->up;
1390      limb->right = twiglet;
1391      limb = twiglet;
1392
1393      /* record pre-fettling deltas */
1394      twiglet->delta[0] = dx;
1395      twiglet->delta[1] = dy;
1396      twiglet->delta[2] = dz;
1397   }
1398#endif
1399
1400   return 1;
1401}
1402
[107b8bd]1403/* Process tape/compass/clino, diving, and cylpolar styles of survey data
1404 * Also handles topofil (fromcount/tocount or count) in place of tape */
[54c4612]1405extern int
[107b8bd]1406data_normal(void)
[54c4612]1407{
1408   prefix *fr = NULL, *to = NULL;
[107b8bd]1409   reading first_stn = End;
[54c4612]1410
[107b8bd]1411   bool fTopofil = fFalse, fMulti = fFalse;
1412   bool fRev;
[e217d67]1413   clino_type ctype, backctype;
[107b8bd]1414   bool fDepthChange;
[be97baf]1415   unsigned long compass_dat_flags = 0;
[54c4612]1416
1417   reading *ordering;
1418
[21c226e]1419   VAL(Tape) = 0;
1420   VAL(Comp) = VAL(BackComp) = HUGE_VAL;
1421   VAL(FrCount) = VAL(ToCount) = 0;
1422   VAL(FrDepth) = VAL(ToDepth) = 0;
[54c4612]1423
1424   fRev = fFalse;
[fa42426]1425   ctype = backctype = CTYPE_OMIT;
[6114207]1426   fDepthChange = fFalse;
[54c4612]1427
[107b8bd]1428   /* ordering may omit clino reading, so set up default here */
1429   /* this is also used if clino reading is the omit character */
[21c226e]1430   VAL(Clino) = VAL(BackClino) = 0;
1431
1432   again:
[107b8bd]1433
[54c4612]1434   for (ordering = pcs->ordering; ; ordering++) {
1435      skipblanks();
1436      switch (*ordering) {
1437       case Fr:
[107b8bd]1438          fr = read_prefix_stn(fFalse, fTrue);
1439          if (first_stn == End) first_stn = Fr;
1440          break;
[54c4612]1441       case To:
[107b8bd]1442          to = read_prefix_stn(fFalse, fTrue);
1443          if (first_stn == End) first_stn = To;
1444          break;
[54c4612]1445       case Station:
[107b8bd]1446          fr = to;
1447          to = read_prefix_stn(fFalse, fFalse);
1448          first_stn = To;
1449          break;
[ee1ec59]1450       case Dir: {
1451          typedef enum {
1452             DIR_NULL=-1, DIR_FORE, DIR_BACK
1453          } dir_tok;
1454          static sztok dir_tab[] = {
1455             {"B",     DIR_BACK},
1456             {"F",     DIR_FORE},
1457          };
1458          dir_tok tok;
1459          get_token();
1460          tok = match_tok(dir_tab, TABSIZE(dir_tab));
1461          switch (tok) {
1462           case DIR_FORE:
[54c4612]1463             break;
[ee1ec59]1464           case DIR_BACK:
[54c4612]1465             fRev = fTrue;
1466             break;
1467           default:
[ee1ec59]1468             compile_error_skip(/*Found `%s', expecting `F' or `B'*/131,
1469                                buffer);
[54c4612]1470             process_eol();
1471             return 0;
1472          }
1473          break;
[ee1ec59]1474       }
[107b8bd]1475       case Tape:
[21c226e]1476          read_reading(Tape, fFalse);
1477          if (VAL(Tape) < (real)0.0)
1478             compile_warning(/*Negative tape reading*/60);
[107b8bd]1479          break;
1480       case Count:
[21c226e]1481          VAL(FrCount) = VAL(ToCount);
1482          read_reading(ToCount, fFalse);
[b4fe9fb]1483          fTopofil = fTrue;
[107b8bd]1484          break;
1485       case FrCount:
[21c226e]1486          read_reading(FrCount, fFalse);
[107b8bd]1487          break;
1488       case ToCount:
[21c226e]1489          read_reading(ToCount, fFalse);
[107b8bd]1490          fTopofil = fTrue;
1491          break;
1492       case Comp:
[21c226e]1493          read_bearing_or_omit(Comp);
[107b8bd]1494          break;
[5b7c1b7]1495       case BackComp:
[21c226e]1496          read_bearing_or_omit(BackComp);
[5b7c1b7]1497          break;
[5757725]1498       case Clino:
[21c226e]1499          read_reading(Clino, fTrue);
1500          if (VAL(Clino) == HUGE_REAL) {
1501             VAL(Clino) = handle_plumb(&ctype);
1502             if (VAL(Clino) != HUGE_REAL) break;
[107b8bd]1503             compile_error_token(/*Expecting numeric field, found `%s'*/9);
1504             process_eol();
1505             return 0;
1506          }
[fa42426]1507          ctype = CTYPE_READING;
[5b7c1b7]1508          break;
1509       case BackClino:
[21c226e]1510          read_reading(BackClino, fTrue);
1511          if (VAL(BackClino) == HUGE_REAL) {
1512             VAL(BackClino) = handle_plumb(&backctype);
1513             if (VAL(BackClino) != HUGE_REAL) break;
[5b7c1b7]1514             compile_error_token(/*Expecting numeric field, found `%s'*/9);
1515             process_eol();
1516             return 0;
1517          }
[fa42426]1518          backctype = CTYPE_READING;
[107b8bd]1519          break;
1520       case FrDepth:
[21c226e]1521          read_reading(FrDepth, fFalse);
[107b8bd]1522          break;
1523       case ToDepth:
[21c226e]1524          read_reading(ToDepth, fFalse);
[107b8bd]1525          break;
[54c4612]1526       case Depth:
[21c226e]1527          VAL(FrDepth) = VAL(ToDepth);
1528          read_reading(ToDepth, fFalse);
[54c4612]1529          break;
[6114207]1530       case DepthChange:
1531          fDepthChange = fTrue;
[21c226e]1532          VAL(FrDepth) = 0;
1533          read_reading(ToDepth, fFalse);
[a186573]1534          break;
[be97baf]1535       case CompassDATFlags:
1536          if (ch == '#') {
1537             nextch();
1538             if (ch == '|') {
1539                filepos fp;
1540                get_pos(&fp);
1541                nextch();
1542                while (ch >= 'A' && ch <= 'Z') {
1543                   compass_dat_flags |= BIT(ch - 'A');
1544                   nextch();
1545                }
1546                if (ch == '#') {
1547                   nextch();
1548                } else {
1549                   compass_dat_flags = 0;
1550                   set_pos(&fp);
1551                   push_back('|');
1552                   ch = '#';
1553                }
1554             } else {
1555                push_back(ch);
1556                ch = '#';
1557             }
1558          }
[107b8bd]1559          break;
[be97baf]1560       case Ignore:
1561          skipword(); break;
[54c4612]1562       case IgnoreAllAndNewLine:
[107b8bd]1563          skipline();
1564          /* fall through */
[54c4612]1565       case Newline:
[107b8bd]1566          if (fr != NULL) {
1567             int r;
[21c226e]1568             if (fTopofil)
1569                VAL(Tape) = VAL(ToCount) - VAL(FrCount);
[107b8bd]1570             /* Note: frdepth == todepth test works regardless of fDepthChange
1571              * (frdepth always zero, todepth is change of depth) and also
1572              * works for STYLE_NORMAL (both remain 0) */
[27b8b59]1573             if (TSTBIT(pcs->infer, INFER_EQUATES) &&
1574                 VAL(Tape) == (real)0.0 && VAL(FrDepth) == VAL(ToDepth)) {
[107b8bd]1575                process_equate(fr, to);
1576                goto inferred_equate;
1577             }
[e7576f6]1578             if (fRev) {
1579                prefix *t = fr;
1580                fr = to;
1581                to = t;
1582             }
[107b8bd]1583             if (fTopofil) {
[21c226e]1584                VAL(Tape) *= pcs->units[Q_COUNT] * pcs->sc[Q_COUNT];
[107b8bd]1585             } else {
[21c226e]1586                VAL(Tape) *= pcs->units[Q_LENGTH];
1587                VAL(Tape) -= pcs->z[Q_LENGTH];
1588                VAL(Tape) *= pcs->sc[Q_LENGTH];
[107b8bd]1589             }
1590             switch (pcs->style) {
1591              case STYLE_NORMAL:
[21c226e]1592                r = process_normal(fr, to, (first_stn == To) ^ fRev,
1593                                   ctype, backctype);
[107b8bd]1594                break;
1595              case STYLE_DIVING:
[21c226e]1596                r = process_diving(fr, to, (first_stn == To) ^ fRev,
1597                                   fDepthChange);
[107b8bd]1598                break;
1599              case STYLE_CYLPOLAR:
[21c226e]1600                r = process_cylpolar(fr, to, (first_stn == To) ^ fRev,
1601                                     fDepthChange);
[107b8bd]1602                break;
1603              default:
1604                BUG("bad style");
1605             }
1606             if (!r) skipline();
[e7576f6]1607             
1608             /* Swap fr and to back to how they were for next line */
1609             if (fRev) {
1610                prefix *t = fr;
1611                fr = to;
1612                to = t;
1613             }
[107b8bd]1614          }
[21c226e]1615
1616          fRev = fFalse;
1617          ctype = backctype = CTYPE_OMIT;
1618          fDepthChange = fFalse;
1619
1620          /* ordering may omit clino reading, so set up default here */
1621          /* this is also used if clino reading is the omit character */
1622          VAL(Clino) = VAL(BackClino) = 0;
1623
[107b8bd]1624          inferred_equate:
[e7576f6]1625
[107b8bd]1626          fMulti = fTrue;
1627          while (1) {
1628              process_eol();
1629              process_bol();
1630              if (isData(ch)) break;
1631              if (!isComm(ch)) {
1632                 push_back(ch);
1633                 return 1;
1634              }
1635          }
1636          break;
[54c4612]1637       case IgnoreAll:
[107b8bd]1638          skipline();
1639          /* fall through */
[54c4612]1640       case End:
[107b8bd]1641          if (!fMulti) {
1642             int r;
[be97baf]1643             /* Compass ignore flag is 'X' */
1644             if ((compass_dat_flags & BIT('X' - 'A'))) {
1645                process_eol();
1646                return 1;
1647             }
[107b8bd]1648             if (fRev) {
1649                prefix *t = fr;
1650                fr = to;
1651                to = t;
1652             }
[21c226e]1653             if (fTopofil) VAL(Tape) = VAL(ToCount) - VAL(FrCount);
[107b8bd]1654             /* Note: frdepth == todepth test works regardless of fDepthChange
1655              * (frdepth always zero, todepth is change of depth) and also
1656              * works for STYLE_NORMAL (both remain 0) */
[27b8b59]1657             if (TSTBIT(pcs->infer, INFER_EQUATES) &&
1658                 VAL(Tape) == (real)0.0 && VAL(FrDepth) == VAL(ToDepth)) {
[107b8bd]1659                process_equate(fr, to);
1660                process_eol();
1661                return 1;
1662             }
1663             if (fTopofil) {
[21c226e]1664                VAL(Tape) *= pcs->units[Q_COUNT] * pcs->sc[Q_COUNT];
[107b8bd]1665             } else {
[21c226e]1666                VAL(Tape) *= pcs->units[Q_LENGTH];
1667                VAL(Tape) -= pcs->z[Q_LENGTH];
1668                VAL(Tape) *= pcs->sc[Q_LENGTH];
[107b8bd]1669             }
1670             switch (pcs->style) {
1671              case STYLE_NORMAL:
[21c226e]1672                r = process_normal(fr, to, (first_stn == To) ^ fRev,
1673                                   ctype, backctype);
[107b8bd]1674                break;
1675              case STYLE_DIVING:
[21c226e]1676                r = process_diving(fr, to, (first_stn == To) ^ fRev,
1677                                   fDepthChange);
[107b8bd]1678                break;
1679              case STYLE_CYLPOLAR:
[21c226e]1680                r = process_cylpolar(fr, to, (first_stn == To) ^ fRev,
1681                                     fDepthChange);
[107b8bd]1682                break;
1683              default:
1684                BUG("bad style");
1685             }
1686             process_eol();
1687             return r;
1688          }
1689          do {
1690             process_eol();
1691             process_bol();
1692          } while (isComm(ch));
1693          goto again;
1694       default:
1695          BUG("Unknown reading in ordering");
[54c4612]1696      }
1697   }
1698}
1699
[5a38209]1700static int
1701process_nosurvey(prefix *fr, prefix *to, bool fToFirst)
1702{
1703   nosurveylink *link;
[838a602a]1704   int shape;
[647407d]1705
[be97baf]1706#ifdef CHASM3DX
[647407d]1707   if (fUseNewFormat) {
[407084d]1708      /* new twiglet and insert into twig tree */
1709      twig *twiglet = osnew(twig);
[90bb053f]1710      twiglet->from = fr;
1711      twiglet->to = to;
[647407d]1712      twiglet->down = twiglet->right = NULL;
1713      twiglet->source = twiglet->drawings
1714        = twiglet->date = twiglet->instruments = twiglet->tape = NULL;
1715      twiglet->up = limb->up;
1716      limb->right = twiglet;
1717      limb = twiglet;
[3bcbcb2]1718      /* delta is only used to calculate error - pass zero and cope
1719       * elsewhere */
[647407d]1720      twiglet->delta[0] = twiglet->delta[1] = twiglet->delta[2] = 0;
1721   }
1722#endif
1723
[838a602a]1724   /* Suppress "unused fixed point" warnings for these stations
1725    * We do this if it's a 0 or 1 node - 1 node might be an sdfix
1726    */
1727   shape = fr->shape;
1728   if (shape == 0 || shape == 1) fr->shape = -1 - shape;
1729   shape = to->shape;
1730   if (shape == 0 || shape == 1) to->shape = -1 - shape;
1731
[647407d]1732   /* add to linked list which is dealt with after network is solved */
1733   link = osnew(nosurveylink);
[5a38209]1734   if (fToFirst) {
[90bb053f]1735      link->to = StnFromPfx(to);
1736      link->fr = StnFromPfx(fr);
[0395657]1737   } else {
[90bb053f]1738      link->fr = StnFromPfx(fr);
1739      link->to = StnFromPfx(to);
[0395657]1740   }
[b3bef47]1741   link->flags = pcs->flags;
[647407d]1742   link->next = nosurveyhead;
1743   nosurveyhead = link;
[a420b49]1744   return 1;
[d1b1380]1745}
[50f6901]1746
[5a38209]1747extern int
1748data_nosurvey(void)
1749{
1750   prefix *fr = NULL, *to = NULL;
1751
1752   bool fMulti = fFalse;
1753
1754   reading first_stn = End;
1755
1756   reading *ordering;
1757
1758   again:
1759
1760   for (ordering = pcs->ordering ; ; ordering++) {
1761      skipblanks();
1762      switch (*ordering) {
1763       case Fr:
[84c60fc]1764          fr = read_prefix_stn(fFalse, fTrue);
[5a38209]1765          if (first_stn == End) first_stn = Fr;
1766          break;
1767       case To:
[84c60fc]1768          to = read_prefix_stn(fFalse, fTrue);
[5a38209]1769          if (first_stn == End) first_stn = To;
1770          break;
1771       case Station:
1772          fr = to;
[84c60fc]1773          to = read_prefix_stn(fFalse, fFalse);
[5a38209]1774          first_stn = To;
1775          break;
1776       case Ignore:
1777         skipword(); break;
1778       case IgnoreAllAndNewLine:
1779         skipline();
1780         /* fall through */
1781       case Newline:
1782         if (fr != NULL) {
1783            int r;
1784            r = process_nosurvey(fr, to, first_stn == To);
1785            if (!r) skipline();
1786         }
[838a602a]1787         if (ordering[1] == End) {
1788            do {
1789               process_eol();
1790               process_bol();
1791            } while (isComm(ch));
[ee6a621]1792            if (!isData(ch)) {
[993454b]1793               push_back(ch);
[ee6a621]1794               return 1;
1795            }
[838a602a]1796            goto again;
1797         }
[5a38209]1798         fMulti = fTrue;
1799         while (1) {
1800            process_eol();
1801            process_bol();
1802            if (isData(ch)) break;
[ee6a621]1803            if (!isComm(ch)) {
[993454b]1804               push_back(ch);
[ee6a621]1805               return 1;
1806            }
[5a38209]1807         }
1808         break;
1809       case IgnoreAll:
1810         skipline();
1811         /* fall through */
1812       case End:
1813         if (!fMulti) {
[ee6a621]1814            int r = process_nosurvey(fr, to, first_stn == To);
[5a38209]1815            process_eol();
1816            return r;
1817         }
[eef4d8c]1818         do {
[5a38209]1819            process_eol();
1820            process_bol();
[eef4d8c]1821         } while (isComm(ch));
[5a38209]1822         goto again;
1823       default: BUG("Unknown reading in ordering");
1824      }
1825   }
1826}
1827
[50f6901]1828/* totally ignore a line of survey data */
1829extern int
1830data_ignore(void)
1831{
1832   skipline();
[ee6a621]1833   process_eol();
[570f4bf]1834   return 1;
[50f6901]1835}
Note: See TracBrowser for help on using the repository browser.