| [ff6cfe1] | 1 | /* commands.c
|
|---|
| [d1b1380] | 2 | * Code for directives
|
|---|
| [82919e07] | 3 | * Copyright (C) 1991-2003,2004,2005,2006,2010,2011,2012,2013,2014,2015 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
|
|---|
| [d333899] | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|---|
| [d1b1380] | 18 | */
|
|---|
| 19 |
|
|---|
| [a420b49] | 20 | #ifdef HAVE_CONFIG_H
|
|---|
| 21 | #include <config.h>
|
|---|
| 22 | #endif
|
|---|
| [d1b1380] | 23 |
|
|---|
| 24 | #include <assert.h>
|
|---|
| [a420b49] | 25 | #include <limits.h>
|
|---|
| [be97baf] | 26 | #include <stddef.h> /* for offsetof */
|
|---|
| [a420b49] | 27 |
|
|---|
| [c092d72] | 28 | #include <proj_api.h>
|
|---|
| 29 |
|
|---|
| [a420b49] | 30 | #include "cavern.h"
|
|---|
| [d1b1380] | 31 | #include "commands.h"
|
|---|
| 32 | #include "datain.h"
|
|---|
| [1ee204e] | 33 | #include "date.h"
|
|---|
| [d1b1380] | 34 | #include "debug.h"
|
|---|
| [5853657] | 35 | #include "filename.h"
|
|---|
| 36 | #include "message.h"
|
|---|
| 37 | #include "netbits.h"
|
|---|
| 38 | #include "netskel.h"
|
|---|
| [5f1e194] | 39 | #include "out.h"
|
|---|
| [5853657] | 40 | #include "readval.h"
|
|---|
| [69c920d] | 41 | #include "str.h"
|
|---|
| [a420b49] | 42 |
|
|---|
| 43 | static void
|
|---|
| 44 | default_grade(settings *s)
|
|---|
| 45 | {
|
|---|
| [770157e] | 46 | /* Values correspond to those in bcra5.svx */
|
|---|
| 47 | s->Var[Q_POS] = (real)sqrd(0.05);
|
|---|
| 48 | s->Var[Q_LENGTH] = (real)sqrd(0.05);
|
|---|
| 49 | s->Var[Q_COUNT] = (real)sqrd(0.05);
|
|---|
| 50 | s->Var[Q_DX] = s->Var[Q_DY] = s->Var[Q_DZ] = (real)sqrd(0.05);
|
|---|
| 51 | s->Var[Q_BEARING] = (real)sqrd(rad(0.5));
|
|---|
| 52 | s->Var[Q_GRADIENT] = (real)sqrd(rad(0.5));
|
|---|
| 53 | s->Var[Q_BACKBEARING] = (real)sqrd(rad(0.5));
|
|---|
| 54 | s->Var[Q_BACKGRADIENT] = (real)sqrd(rad(0.5));
|
|---|
| [a420b49] | 55 | /* SD of plumbed legs (0.25 degrees?) */
|
|---|
| 56 | s->Var[Q_PLUMB] = (real)sqrd(rad(0.25));
|
|---|
| [6b7079f] | 57 | /* SD of level legs (0.25 degrees?) */
|
|---|
| 58 | s->Var[Q_LEVEL] = (real)sqrd(rad(0.25));
|
|---|
| [770157e] | 59 | s->Var[Q_DEPTH] = (real)sqrd(0.05);
|
|---|
| [a420b49] | 60 | }
|
|---|
| 61 |
|
|---|
| 62 | static void
|
|---|
| 63 | default_truncate(settings *s)
|
|---|
| 64 | {
|
|---|
| 65 | s->Truncate = INT_MAX;
|
|---|
| 66 | }
|
|---|
| 67 |
|
|---|
| 68 | static void
|
|---|
| 69 | default_case(settings *s)
|
|---|
| 70 | {
|
|---|
| 71 | s->Case = LOWER;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| [27b8b59] | 74 | static reading default_order[] = { Fr, To, Tape, Comp, Clino, End };
|
|---|
| [a420b49] | 75 |
|
|---|
| 76 | static void
|
|---|
| 77 | default_style(settings *s)
|
|---|
| 78 | {
|
|---|
| [107b8bd] | 79 | s->style = STYLE_NORMAL;
|
|---|
| [a420b49] | 80 | s->ordering = default_order;
|
|---|
| [dcbcae0] | 81 | s->dash_for_anon_wall_station = fFalse;
|
|---|
| [a420b49] | 82 | }
|
|---|
| 83 |
|
|---|
| 84 | static void
|
|---|
| 85 | default_prefix(settings *s)
|
|---|
| 86 | {
|
|---|
| 87 | s->Prefix = root;
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | static void
|
|---|
| 91 | default_translate(settings *s)
|
|---|
| 92 | {
|
|---|
| 93 | int i;
|
|---|
| 94 | short *t;
|
|---|
| 95 | if (s->next && s->next->Translate == s->Translate) {
|
|---|
| 96 | t = ((short*)osmalloc(ossizeof(short) * 257)) + 1;
|
|---|
| 97 | memcpy(t - 1, s->Translate - 1, sizeof(short) * 257);
|
|---|
| 98 | s->Translate = t;
|
|---|
| 99 | }
|
|---|
| [4c07c51] | 100 | /* SVX_ASSERT(EOF==-1);*/ /* important, since we rely on this */
|
|---|
| [a420b49] | 101 | t = s->Translate;
|
|---|
| [be97baf] | 102 | memset(t - 1, 0, sizeof(short) * 257);
|
|---|
| 103 | for (i = '0'; i <= '9'; i++) t[i] = SPECIAL_NAMES;
|
|---|
| 104 | for (i = 'A'; i <= 'Z'; i++) t[i] = SPECIAL_NAMES;
|
|---|
| 105 | for (i = 'a'; i <= 'z'; i++) t[i] = SPECIAL_NAMES;
|
|---|
| [a420b49] | 106 |
|
|---|
| 107 | t['\t'] |= SPECIAL_BLANK;
|
|---|
| 108 | t[' '] |= SPECIAL_BLANK;
|
|---|
| 109 | t[','] |= SPECIAL_BLANK;
|
|---|
| 110 | t[';'] |= SPECIAL_COMMENT;
|
|---|
| 111 | t['\032'] |= SPECIAL_EOL; /* Ctrl-Z, so olde DOS text files are handled ok */
|
|---|
| 112 | t[EOF] |= SPECIAL_EOL;
|
|---|
| 113 | t['\n'] |= SPECIAL_EOL;
|
|---|
| 114 | t['\r'] |= SPECIAL_EOL;
|
|---|
| 115 | t['*'] |= SPECIAL_KEYWORD;
|
|---|
| 116 | t['-'] |= SPECIAL_OMIT;
|
|---|
| 117 | t['\\'] |= SPECIAL_ROOT;
|
|---|
| 118 | t['.'] |= SPECIAL_SEPARATOR;
|
|---|
| 119 | t['_'] |= SPECIAL_NAMES;
|
|---|
| [f3ac7d4] | 120 | t['-'] |= SPECIAL_NAMES; /* Added in 0.97 prerelease 4 */
|
|---|
| [a420b49] | 121 | t['.'] |= SPECIAL_DECIMAL;
|
|---|
| 122 | t['-'] |= SPECIAL_MINUS;
|
|---|
| 123 | t['+'] |= SPECIAL_PLUS;
|
|---|
| [3593388] | 124 | #if 0 /* FIXME */
|
|---|
| [7d40549] | 125 | t['{'] |= SPECIAL_OPEN;
|
|---|
| 126 | t['}'] |= SPECIAL_CLOSE;
|
|---|
| [3593388] | 127 | #endif
|
|---|
| [a420b49] | 128 | }
|
|---|
| 129 |
|
|---|
| [be97baf] | 130 | void
|
|---|
| [a420b49] | 131 | default_units(settings *s)
|
|---|
| 132 | {
|
|---|
| 133 | int quantity;
|
|---|
| 134 | for (quantity = 0; quantity < Q_MAC; quantity++) {
|
|---|
| [7f08c83] | 135 | if (TSTBIT(ANG_QMASK, quantity))
|
|---|
| [bca0071] | 136 | s->units[quantity] = (real)(M_PI / 180.0); /* degrees */
|
|---|
| [a420b49] | 137 | else
|
|---|
| 138 | s->units[quantity] = (real)1.0; /* metres */
|
|---|
| 139 | }
|
|---|
| [fa42426] | 140 | s->f_clino_percent = s->f_backclino_percent = fFalse;
|
|---|
| [a420b49] | 141 | }
|
|---|
| 142 |
|
|---|
| [be97baf] | 143 | void
|
|---|
| [a420b49] | 144 | default_calib(settings *s)
|
|---|
| 145 | {
|
|---|
| 146 | int quantity;
|
|---|
| 147 | for (quantity = 0; quantity < Q_MAC; quantity++) {
|
|---|
| 148 | s->z[quantity] = (real)0.0;
|
|---|
| 149 | s->sc[quantity] = (real)1.0;
|
|---|
| 150 | }
|
|---|
| 151 | }
|
|---|
| 152 |
|
|---|
| [5c3c61a] | 153 | static void
|
|---|
| 154 | default_flags(settings *s)
|
|---|
| 155 | {
|
|---|
| 156 | s->flags = 0;
|
|---|
| 157 | }
|
|---|
| 158 |
|
|---|
| [a420b49] | 159 | extern void
|
|---|
| 160 | default_all(settings *s)
|
|---|
| 161 | {
|
|---|
| 162 | default_truncate(s);
|
|---|
| [27b8b59] | 163 | s->infer = 0;
|
|---|
| [a420b49] | 164 | default_case(s);
|
|---|
| 165 | default_style(s);
|
|---|
| 166 | default_prefix(s);
|
|---|
| 167 | default_translate(s);
|
|---|
| 168 | default_grade(s);
|
|---|
| 169 | default_units(s);
|
|---|
| 170 | default_calib(s);
|
|---|
| [5c3c61a] | 171 | default_flags(s);
|
|---|
| [a420b49] | 172 | }
|
|---|
| 173 |
|
|---|
| [ee1ec59] | 174 | char *buffer = NULL;
|
|---|
| [ee7bafa] | 175 | static int buf_len;
|
|---|
| [d1b1380] | 176 |
|
|---|
| [cfe093e] | 177 | static char *ucbuffer = NULL;
|
|---|
| [5f1e194] | 178 |
|
|---|
| [647407d] | 179 | /* read token */
|
|---|
| [a420b49] | 180 | extern void
|
|---|
| 181 | get_token(void)
|
|---|
| [f6bdb01] | 182 | {
|
|---|
| 183 | skipblanks();
|
|---|
| 184 | get_token_no_blanks();
|
|---|
| 185 | }
|
|---|
| 186 |
|
|---|
| 187 | extern void
|
|---|
| 188 | get_token_no_blanks(void)
|
|---|
| [a420b49] | 189 | {
|
|---|
| [be97baf] | 190 | int i = -1;
|
|---|
| 191 |
|
|---|
| [cfe093e] | 192 | s_zero(&buffer);
|
|---|
| 193 | osfree(ucbuffer);
|
|---|
| [5f1e194] | 194 | while (isalpha(ch)) {
|
|---|
| [63dc4eb] | 195 | s_catchar(&buffer, &buf_len, (char)ch);
|
|---|
| [5f1e194] | 196 | nextch();
|
|---|
| 197 | }
|
|---|
| [cfe093e] | 198 |
|
|---|
| [be97baf] | 199 | if (!buffer) s_catchar(&buffer, &buf_len, '\0');
|
|---|
| 200 |
|
|---|
| [cfe093e] | 201 | ucbuffer = osmalloc(buf_len);
|
|---|
| [be97baf] | 202 | do {
|
|---|
| 203 | i++;
|
|---|
| 204 | ucbuffer[i] = toupper(buffer[i]);
|
|---|
| 205 | } while (buffer[i]);
|
|---|
| [cfe093e] | 206 | #if 0
|
|---|
| [f6bdb01] | 207 | printf("get_token_no_blanks() got “%s”\n", buffer);
|
|---|
| [cfe093e] | 208 | #endif
|
|---|
| [d1b1380] | 209 | }
|
|---|
| 210 |
|
|---|
| [dcbcae0] | 211 | /* read word */
|
|---|
| 212 | static void
|
|---|
| 213 | get_word(void)
|
|---|
| 214 | {
|
|---|
| 215 | s_zero(&buffer);
|
|---|
| 216 | skipblanks();
|
|---|
| 217 | while (!isBlank(ch) && !isEol(ch)) {
|
|---|
| 218 | s_catchar(&buffer, &buf_len, (char)ch);
|
|---|
| 219 | nextch();
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | if (!buffer) s_catchar(&buffer, &buf_len, '\0');
|
|---|
| 223 | #if 0
|
|---|
| 224 | printf("get_word() got “%s”\n", buffer);
|
|---|
| 225 | #endif
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| [d1b1380] | 228 | /* match_tok() now uses binary chop
|
|---|
| 229 | * tab argument should be alphabetically sorted (ascending)
|
|---|
| 230 | */
|
|---|
| [a420b49] | 231 | extern int
|
|---|
| 232 | match_tok(const sztok *tab, int tab_size)
|
|---|
| 233 | {
|
|---|
| [5f1e194] | 234 | int a = 0, b = tab_size - 1, c;
|
|---|
| 235 | int r;
|
|---|
| 236 | assert(tab_size > 0); /* catch empty table */
|
|---|
| [d1b1380] | 237 | /* printf("[%d,%d]",a,b); */
|
|---|
| [5f1e194] | 238 | while (a <= b) {
|
|---|
| 239 | c = (unsigned)(a + b) / 2;
|
|---|
| [d1b1380] | 240 | /* printf(" %d",c); */
|
|---|
| [647407d] | 241 | r = strcmp(tab[c].sz, ucbuffer);
|
|---|
| [5f1e194] | 242 | if (r == 0) return tab[c].tok; /* match */
|
|---|
| 243 | if (r < 0)
|
|---|
| 244 | a = c + 1;
|
|---|
| 245 | else
|
|---|
| 246 | b = c - 1;
|
|---|
| 247 | }
|
|---|
| 248 | return tab[tab_size].tok; /* no match */
|
|---|
| [d1b1380] | 249 | }
|
|---|
| 250 |
|
|---|
| [fb2e93c] | 251 | typedef enum {
|
|---|
| [dcbcae0] | 252 | CMD_NULL = -1, CMD_ALIAS, CMD_BEGIN, CMD_CALIBRATE, CMD_CASE, CMD_COPYRIGHT,
|
|---|
| [abd0310] | 253 | CMD_CS, CMD_DATA, CMD_DATE, CMD_DEFAULT, CMD_END, CMD_ENTRANCE, CMD_EQUATE,
|
|---|
| [dfb4240] | 254 | CMD_EXPORT, CMD_FIX, CMD_FLAGS, CMD_INCLUDE, CMD_INFER, CMD_INSTRUMENT,
|
|---|
| [82be646] | 255 | CMD_PREFIX, CMD_REQUIRE, CMD_SD, CMD_SET, CMD_SOLVE,
|
|---|
| [13a48f6] | 256 | CMD_TEAM, CMD_TITLE, CMD_TRUNCATE, CMD_UNITS
|
|---|
| [5f1e194] | 257 | } cmds;
|
|---|
| [cb3d1e2] | 258 |
|
|---|
| [82919e07] | 259 | static const sztok cmd_tab[] = {
|
|---|
| [dcbcae0] | 260 | {"ALIAS", CMD_ALIAS},
|
|---|
| [5f1e194] | 261 | {"BEGIN", CMD_BEGIN},
|
|---|
| 262 | {"CALIBRATE", CMD_CALIBRATE},
|
|---|
| [a420b49] | 263 | {"CASE", CMD_CASE},
|
|---|
| [13a48f6] | 264 | {"COPYRIGHT", CMD_COPYRIGHT},
|
|---|
| [abd0310] | 265 | {"CS", CMD_CS},
|
|---|
| [5f1e194] | 266 | {"DATA", CMD_DATA},
|
|---|
| [13a48f6] | 267 | {"DATE", CMD_DATE},
|
|---|
| [a7d5f1c] | 268 | #ifndef NO_DEPRECATED
|
|---|
| [5f1e194] | 269 | {"DEFAULT", CMD_DEFAULT},
|
|---|
| [a7d5f1c] | 270 | #endif
|
|---|
| [5f1e194] | 271 | {"END", CMD_END},
|
|---|
| [dfb4240] | 272 | {"ENTRANCE", CMD_ENTRANCE},
|
|---|
| [5f1e194] | 273 | {"EQUATE", CMD_EQUATE},
|
|---|
| [fb2e93c] | 274 | {"EXPORT", CMD_EXPORT},
|
|---|
| [5f1e194] | 275 | {"FIX", CMD_FIX},
|
|---|
| [5c3c61a] | 276 | {"FLAGS", CMD_FLAGS},
|
|---|
| [5f1e194] | 277 | {"INCLUDE", CMD_INCLUDE},
|
|---|
| [a420b49] | 278 | {"INFER", CMD_INFER},
|
|---|
| [ec6a4b3] | 279 | {"INSTRUMENT",CMD_INSTRUMENT},
|
|---|
| [a7d5f1c] | 280 | #ifndef NO_DEPRECATED
|
|---|
| [5f1e194] | 281 | {"PREFIX", CMD_PREFIX},
|
|---|
| [a7d5f1c] | 282 | #endif
|
|---|
| [647407d] | 283 | {"REQUIRE", CMD_REQUIRE},
|
|---|
| [a4ae909] | 284 | {"SD", CMD_SD},
|
|---|
| [5f1e194] | 285 | {"SET", CMD_SET},
|
|---|
| 286 | {"SOLVE", CMD_SOLVE},
|
|---|
| [13a48f6] | 287 | {"TEAM", CMD_TEAM},
|
|---|
| [a420b49] | 288 | {"TITLE", CMD_TITLE},
|
|---|
| 289 | {"TRUNCATE", CMD_TRUNCATE},
|
|---|
| [5f1e194] | 290 | {"UNITS", CMD_UNITS},
|
|---|
| [a4ae909] | 291 | {NULL, CMD_NULL}
|
|---|
| [5f1e194] | 292 | };
|
|---|
| 293 |
|
|---|
| [fa42426] | 294 | /* masks for units which are length and angles respectively */
|
|---|
| 295 | #define LEN_UMASK (BIT(UNITS_METRES) | BIT(UNITS_FEET) | BIT(UNITS_YARDS))
|
|---|
| 296 | #define ANG_UMASK (BIT(UNITS_DEGS) | BIT(UNITS_GRADS) | BIT(UNITS_MINUTES))
|
|---|
| 297 |
|
|---|
| 298 | /* ordering must be the same as the units enum */
|
|---|
| [85c0078] | 299 | const real factor_tab[] = {
|
|---|
| [fa42426] | 300 | 1.0, METRES_PER_FOOT, (METRES_PER_FOOT*3.0),
|
|---|
| 301 | (M_PI/180.0), (M_PI/200.0), 0.01, (M_PI/180.0/60.0)
|
|---|
| 302 | };
|
|---|
| 303 |
|
|---|
| [85c0078] | 304 | const int units_to_msgno[] = {
|
|---|
| 305 | /*m*/424,
|
|---|
| 306 | /*ft*/428,
|
|---|
| 307 | -1, /* yards */
|
|---|
| 308 | /*°*/344,
|
|---|
| 309 | /*ᵍ*/76,
|
|---|
| 310 | /*%*/96,
|
|---|
| 311 | -1 /* minutes */
|
|---|
| 312 | };
|
|---|
| 313 |
|
|---|
| 314 | int get_length_units(int quantity) {
|
|---|
| 315 | double factor = pcs->units[quantity];
|
|---|
| 316 | if (fabs(factor - METRES_PER_FOOT) <= REAL_EPSILON ||
|
|---|
| 317 | fabs(factor - METRES_PER_FOOT * 3.0) <= REAL_EPSILON) {
|
|---|
| 318 | return UNITS_FEET;
|
|---|
| 319 | }
|
|---|
| 320 | return UNITS_METRES;
|
|---|
| 321 | }
|
|---|
| 322 |
|
|---|
| 323 | int get_angle_units(int quantity) {
|
|---|
| 324 | double factor = pcs->units[quantity];
|
|---|
| 325 | if (fabs(factor - M_PI / 200.0) <= REAL_EPSILON) {
|
|---|
| 326 | return UNITS_GRADS;
|
|---|
| 327 | }
|
|---|
| 328 | return UNITS_DEGS;
|
|---|
| 329 | }
|
|---|
| 330 |
|
|---|
| [a420b49] | 331 | static int
|
|---|
| [fa42426] | 332 | get_units(unsigned long qmask, bool percent_ok)
|
|---|
| [a420b49] | 333 | {
|
|---|
| [82919e07] | 334 | static const sztok utab[] = {
|
|---|
| [5f1e194] | 335 | {"DEGREES", UNITS_DEGS },
|
|---|
| [a4ae909] | 336 | {"DEGS", UNITS_DEGS },
|
|---|
| 337 | {"FEET", UNITS_FEET },
|
|---|
| 338 | {"GRADS", UNITS_GRADS },
|
|---|
| 339 | {"METERS", UNITS_METRES },
|
|---|
| 340 | {"METRES", UNITS_METRES },
|
|---|
| 341 | {"METRIC", UNITS_METRES },
|
|---|
| 342 | {"MILS", UNITS_GRADS },
|
|---|
| 343 | {"MINUTES", UNITS_MINUTES },
|
|---|
| 344 | {"PERCENT", UNITS_PERCENT },
|
|---|
| [5f1e194] | 345 | {"PERCENTAGE", UNITS_PERCENT },
|
|---|
| [a4ae909] | 346 | {"YARDS", UNITS_YARDS },
|
|---|
| 347 | {NULL, UNITS_NULL }
|
|---|
| [5f1e194] | 348 | };
|
|---|
| [3a33d12] | 349 | int units;
|
|---|
| 350 | get_token();
|
|---|
| 351 | units = match_tok(utab, TABSIZE(utab));
|
|---|
| [647407d] | 352 | if (units == UNITS_NULL) {
|
|---|
| [da96015] | 353 | file.lpos += strlen(buffer);
|
|---|
| 354 | compile_error_skip(-/*Unknown units “%s”*/35, buffer);
|
|---|
| [fa42426] | 355 | return UNITS_NULL;
|
|---|
| 356 | }
|
|---|
| 357 | if (units == UNITS_PERCENT && percent_ok &&
|
|---|
| 358 | !(qmask & ~(BIT(Q_GRADIENT)|BIT(Q_BACKGRADIENT)))) {
|
|---|
| 359 | return units;
|
|---|
| 360 | }
|
|---|
| 361 | if (((qmask & LEN_QMASK) && !TSTBIT(LEN_UMASK, units)) ||
|
|---|
| 362 | ((qmask & ANG_QMASK) && !TSTBIT(ANG_UMASK, units))) {
|
|---|
| [da96015] | 363 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 364 | /* TRANSLATORS: Note: In English you talk about the *units* of a single
|
|---|
| 365 | * measurement, but the correct term in other languages may be singular.
|
|---|
| 366 | */
|
|---|
| [da96015] | 367 | compile_error_skip(-/*Invalid units “%s” for quantity*/37, buffer);
|
|---|
| [fa42426] | 368 | return UNITS_NULL;
|
|---|
| [647407d] | 369 | }
|
|---|
| [5f1e194] | 370 | return units;
|
|---|
| [d1b1380] | 371 | }
|
|---|
| 372 |
|
|---|
| 373 | /* returns mask with bit x set to indicate quantity x specified */
|
|---|
| [67508f0] | 374 | static unsigned long
|
|---|
| [46cb98f] | 375 | get_qlist(unsigned long mask_bad)
|
|---|
| [a420b49] | 376 | {
|
|---|
| [82919e07] | 377 | static const sztok qtab[] = {
|
|---|
| [9b5d785] | 378 | {"ALTITUDE", Q_DZ },
|
|---|
| [b14f44f] | 379 | {"BACKBEARING", Q_BACKBEARING },
|
|---|
| 380 | {"BACKCLINO", Q_BACKGRADIENT }, /* alternative name */
|
|---|
| 381 | {"BACKCOMPASS", Q_BACKBEARING }, /* alternative name */
|
|---|
| 382 | {"BACKGRADIENT", Q_BACKGRADIENT },
|
|---|
| [5f1e194] | 383 | {"BEARING", Q_BEARING },
|
|---|
| [ee05463] | 384 | {"CEILING", Q_UP }, /* alternative name */
|
|---|
| [a4ae909] | 385 | {"CLINO", Q_GRADIENT }, /* alternative name */
|
|---|
| [5f1e194] | 386 | {"COMPASS", Q_BEARING }, /* alternative name */
|
|---|
| [a4ae909] | 387 | {"COUNT", Q_COUNT },
|
|---|
| [5f1e194] | 388 | {"COUNTER", Q_COUNT }, /* alternative name */
|
|---|
| 389 | {"DECLINATION", Q_DECLINATION },
|
|---|
| [a420b49] | 390 | {"DEFAULT", Q_DEFAULT }, /* not a real quantity... */
|
|---|
| [a4ae909] | 391 | {"DEPTH", Q_DEPTH },
|
|---|
| [ee05463] | 392 | {"DOWN", Q_DOWN },
|
|---|
| [a4ae909] | 393 | {"DX", Q_DX }, /* alternative name */
|
|---|
| 394 | {"DY", Q_DY }, /* alternative name */
|
|---|
| 395 | {"DZ", Q_DZ }, /* alternative name */
|
|---|
| 396 | {"EASTING", Q_DX },
|
|---|
| [ee05463] | 397 | {"FLOOR", Q_DOWN }, /* alternative name */
|
|---|
| [5f1e194] | 398 | {"GRADIENT", Q_GRADIENT },
|
|---|
| [ee05463] | 399 | {"LEFT", Q_LEFT },
|
|---|
| [5f1e194] | 400 | {"LENGTH", Q_LENGTH },
|
|---|
| [a4ae909] | 401 | {"LEVEL", Q_LEVEL},
|
|---|
| [9b5d785] | 402 | {"NORTHING", Q_DY },
|
|---|
| [a4ae909] | 403 | {"PLUMB", Q_PLUMB},
|
|---|
| [5f1e194] | 404 | {"POSITION", Q_POS },
|
|---|
| [ee05463] | 405 | {"RIGHT", Q_RIGHT },
|
|---|
| [a4ae909] | 406 | {"TAPE", Q_LENGTH }, /* alternative name */
|
|---|
| [ee05463] | 407 | {"UP", Q_UP },
|
|---|
| [a4ae909] | 408 | {NULL, Q_NULL }
|
|---|
| [5f1e194] | 409 | };
|
|---|
| [67508f0] | 410 | unsigned long qmask = 0;
|
|---|
| [5f1e194] | 411 | int tok;
|
|---|
| [3a33d12] | 412 | filepos fp;
|
|---|
| 413 |
|
|---|
| [a420b49] | 414 | while (1) {
|
|---|
| [3a33d12] | 415 | get_pos(&fp);
|
|---|
| [a420b49] | 416 | get_token();
|
|---|
| [5f1e194] | 417 | tok = match_tok(qtab, TABSIZE(qtab));
|
|---|
| [da96015] | 418 | if (tok == Q_DEFAULT && !(mask_bad & BIT(Q_DEFAULT))) {
|
|---|
| 419 | /* Only recognise DEFAULT if it is the first quantity, and then don't
|
|---|
| 420 | * look for any more. */
|
|---|
| 421 | if (qmask == 0)
|
|---|
| 422 | return BIT(Q_DEFAULT);
|
|---|
| 423 | break;
|
|---|
| 424 | }
|
|---|
| [5f1e194] | 425 | /* bail out if we reach the table end with no match */
|
|---|
| 426 | if (tok == Q_NULL) break;
|
|---|
| 427 | qmask |= BIT(tok);
|
|---|
| [da96015] | 428 | if (qmask & mask_bad) {
|
|---|
| 429 | file.lpos += strlen(buffer);
|
|---|
| 430 | compile_error_skip(-/*Unknown instrument “%s”*/39, buffer);
|
|---|
| [46cb98f] | 431 | return 0;
|
|---|
| 432 | }
|
|---|
| [5f1e194] | 433 | }
|
|---|
| [3a33d12] | 434 |
|
|---|
| [647407d] | 435 | if (qmask == 0) {
|
|---|
| [da96015] | 436 | file.lpos += strlen(buffer);
|
|---|
| [36efb03] | 437 | /* TRANSLATORS: A "quantity" is something measured like "LENGTH",
|
|---|
| 438 | * "BEARING", "ALTITUDE", etc. */
|
|---|
| [da96015] | 439 | compile_error_skip(-/*Unknown quantity “%s”*/34, buffer);
|
|---|
| [3a33d12] | 440 | } else {
|
|---|
| 441 | set_pos(&fp);
|
|---|
| [647407d] | 442 | }
|
|---|
| [3a33d12] | 443 |
|
|---|
| [5f1e194] | 444 | return qmask;
|
|---|
| [d1b1380] | 445 | }
|
|---|
| 446 |
|
|---|
| 447 | #define SPECIAL_UNKNOWN 0
|
|---|
| [a420b49] | 448 | static void
|
|---|
| [eb18f4d] | 449 | cmd_set(void)
|
|---|
| [a420b49] | 450 | {
|
|---|
| [82919e07] | 451 | static const sztok chartab[] = {
|
|---|
| [5f1e194] | 452 | {"BLANK", SPECIAL_BLANK },
|
|---|
| [3593388] | 453 | /*FIXME {"CLOSE", SPECIAL_CLOSE }, */
|
|---|
| [5f1e194] | 454 | {"COMMENT", SPECIAL_COMMENT },
|
|---|
| 455 | {"DECIMAL", SPECIAL_DECIMAL },
|
|---|
| 456 | {"EOL", SPECIAL_EOL }, /* EOL won't work well */
|
|---|
| 457 | {"KEYWORD", SPECIAL_KEYWORD },
|
|---|
| 458 | {"MINUS", SPECIAL_MINUS },
|
|---|
| 459 | {"NAMES", SPECIAL_NAMES },
|
|---|
| 460 | {"OMIT", SPECIAL_OMIT },
|
|---|
| [3593388] | 461 | /*FIXME {"OPEN", SPECIAL_OPEN }, */
|
|---|
| [5f1e194] | 462 | {"PLUS", SPECIAL_PLUS },
|
|---|
| [7f1ab95] | 463 | #ifndef NO_DEPRECATED
|
|---|
| [5f1e194] | 464 | {"ROOT", SPECIAL_ROOT },
|
|---|
| [7f1ab95] | 465 | #endif
|
|---|
| [5f1e194] | 466 | {"SEPARATOR", SPECIAL_SEPARATOR },
|
|---|
| [a4ae909] | 467 | {NULL, SPECIAL_UNKNOWN }
|
|---|
| [5f1e194] | 468 | };
|
|---|
| 469 | int mask;
|
|---|
| 470 | int i;
|
|---|
| [b15eeda] | 471 |
|
|---|
| [a420b49] | 472 | get_token();
|
|---|
| [5f1e194] | 473 | mask = match_tok(chartab, TABSIZE(chartab));
|
|---|
| [b15eeda] | 474 |
|
|---|
| [f74d0cb] | 475 | if (mask == SPECIAL_UNKNOWN) {
|
|---|
| [da96015] | 476 | file.lpos += strlen(buffer);
|
|---|
| 477 | compile_error_skip(-/*Unknown character class “%s”*/42, buffer);
|
|---|
| [5f1e194] | 478 | return;
|
|---|
| 479 | }
|
|---|
| [b15eeda] | 480 |
|
|---|
| [7f1ab95] | 481 | #ifndef NO_DEPRECATED
|
|---|
| [c86cc71] | 482 | if (mask == SPECIAL_ROOT) {
|
|---|
| 483 | if (root_depr_count < 5) {
|
|---|
| [da96015] | 484 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 485 | /* TRANSLATORS: Use of the ROOT character (which is "\" by default) is
|
|---|
| 486 | * deprecated, so this error would be generated by:
|
|---|
| 487 | *
|
|---|
| 488 | * *equate \foo.7 1
|
|---|
| 489 | *
|
|---|
| 490 | * If you're unsure what "deprecated" means, see:
|
|---|
| 491 | * http://en.wikipedia.org/wiki/Deprecation */
|
|---|
| [da96015] | 492 | compile_warning(-/*ROOT is deprecated*/25);
|
|---|
| [c86cc71] | 493 | if (++root_depr_count == 5)
|
|---|
| [736f7df] | 494 | /* TRANSLATORS: If you're unsure what "deprecated" means, see:
|
|---|
| 495 | * http://en.wikipedia.org/wiki/Deprecation */
|
|---|
| [c40038a] | 496 | compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
|
|---|
| [c86cc71] | 497 | }
|
|---|
| 498 | }
|
|---|
| [7f1ab95] | 499 | #endif
|
|---|
| [b15eeda] | 500 |
|
|---|
| [5f1e194] | 501 | /* if we're currently using an inherited translation table, allocate a new
|
|---|
| 502 | * table, and copy old one into it */
|
|---|
| 503 | if (pcs->next && pcs->next->Translate == pcs->Translate) {
|
|---|
| 504 | short *p;
|
|---|
| 505 | p = ((short*)osmalloc(ossizeof(short) * 257)) + 1;
|
|---|
| 506 | memcpy(p - 1, pcs->Translate - 1, sizeof(short) * 257);
|
|---|
| 507 | pcs->Translate = p;
|
|---|
| 508 | }
|
|---|
| [11f9067] | 509 |
|
|---|
| 510 | skipblanks();
|
|---|
| 511 |
|
|---|
| [5f1e194] | 512 | /* clear this flag for all non-alphanums */
|
|---|
| [a420b49] | 513 | for (i = 0; i < 256; i++)
|
|---|
| 514 | if (!isalnum(i)) pcs->Translate[i] &= ~mask;
|
|---|
| [11f9067] | 515 |
|
|---|
| [5f1e194] | 516 | /* now set this flag for all specified chars */
|
|---|
| 517 | while (!isEol(ch)) {
|
|---|
| [11f9067] | 518 | if (!isalnum(ch)) {
|
|---|
| 519 | pcs->Translate[ch] |= mask;
|
|---|
| 520 | } else if (tolower(ch) == 'x') {
|
|---|
| 521 | int hex;
|
|---|
| 522 | filepos fp;
|
|---|
| 523 | get_pos(&fp);
|
|---|
| 524 | nextch();
|
|---|
| 525 | if (!isxdigit(ch)) {
|
|---|
| 526 | set_pos(&fp);
|
|---|
| 527 | break;
|
|---|
| 528 | }
|
|---|
| 529 | hex = isdigit(ch) ? ch - '0' : tolower(ch) - 'a';
|
|---|
| 530 | nextch();
|
|---|
| 531 | if (!isxdigit(ch)) {
|
|---|
| 532 | set_pos(&fp);
|
|---|
| 533 | break;
|
|---|
| 534 | }
|
|---|
| 535 | hex = hex << 4 | (isdigit(ch) ? ch - '0' : tolower(ch) - 'a');
|
|---|
| 536 | pcs->Translate[hex] |= mask;
|
|---|
| 537 | } else {
|
|---|
| 538 | break;
|
|---|
| 539 | }
|
|---|
| [5f1e194] | 540 | nextch();
|
|---|
| 541 | }
|
|---|
| [d1b1380] | 542 | }
|
|---|
| 543 |
|
|---|
| [4d9eecd] | 544 | static void
|
|---|
| [613028c] | 545 | check_reentry(prefix *survey)
|
|---|
| [4d9eecd] | 546 | {
|
|---|
| [91912b4] | 547 | /* Don't try to check "*prefix \" or "*begin \" */
|
|---|
| [613028c] | 548 | if (!survey->up) return;
|
|---|
| 549 | if (TSTBIT(survey->sflags, SFLAGS_PREFIX_ENTERED)) {
|
|---|
| [15696f3] | 550 | static int reenter_depr_count = 0;
|
|---|
| [c86cc71] | 551 |
|
|---|
| [e1a66da] | 552 | if (reenter_depr_count >= 5)
|
|---|
| 553 | return;
|
|---|
| 554 |
|
|---|
| 555 | /* TRANSLATORS: e.g.
|
|---|
| 556 | *
|
|---|
| 557 | * *begin crawl
|
|---|
| 558 | * 1 2 9.45 234 -01
|
|---|
| 559 | * *end crawl
|
|---|
| 560 | * *begin crawl # <- warning here
|
|---|
| 561 | * 2 3 7.67 223 -03
|
|---|
| 562 | * *end crawl
|
|---|
| 563 | *
|
|---|
| 564 | * If you're unsure what "deprecated" means, see:
|
|---|
| 565 | * http://en.wikipedia.org/wiki/Deprecation */
|
|---|
| 566 | compile_warning(/*Reentering an existing survey is deprecated*/29);
|
|---|
| [93e3492] | 567 | compile_warning_pfx(survey, /*Originally entered here*/30);
|
|---|
| [e1a66da] | 568 | if (++reenter_depr_count == 5)
|
|---|
| 569 | compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
|
|---|
| [4d9eecd] | 570 | } else {
|
|---|
| [613028c] | 571 | survey->sflags |= BIT(SFLAGS_PREFIX_ENTERED);
|
|---|
| 572 | survey->filename = file.filename;
|
|---|
| 573 | survey->line = file.line;
|
|---|
| [4d9eecd] | 574 | }
|
|---|
| 575 | }
|
|---|
| 576 |
|
|---|
| [7f1ab95] | 577 | #ifndef NO_DEPRECATED
|
|---|
| [a420b49] | 578 | static void
|
|---|
| [eb18f4d] | 579 | cmd_prefix(void)
|
|---|
| [a420b49] | 580 | {
|
|---|
| [c86cc71] | 581 | static int prefix_depr_count = 0;
|
|---|
| [613028c] | 582 | prefix *survey;
|
|---|
| [91912b4] | 583 | /* Issue warning first, so "*prefix \" warns first that *prefix is
|
|---|
| 584 | * deprecated and then that ROOT is...
|
|---|
| 585 | */
|
|---|
| [c86cc71] | 586 | if (prefix_depr_count < 5) {
|
|---|
| [736f7df] | 587 | /* TRANSLATORS: If you're unsure what "deprecated" means, see:
|
|---|
| 588 | * http://en.wikipedia.org/wiki/Deprecation */
|
|---|
| [da96015] | 589 | compile_warning(-/**prefix is deprecated - use *begin and *end instead*/6);
|
|---|
| [c86cc71] | 590 | if (++prefix_depr_count == 5)
|
|---|
| [c40038a] | 591 | compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
|
|---|
| [c86cc71] | 592 | }
|
|---|
| [613028c] | 593 | survey = read_prefix(PFX_SURVEY|PFX_ALLOW_ROOT);
|
|---|
| 594 | pcs->Prefix = survey;
|
|---|
| 595 | check_reentry(survey);
|
|---|
| [d1b1380] | 596 | }
|
|---|
| [7f1ab95] | 597 | #endif
|
|---|
| [d1b1380] | 598 |
|
|---|
| [dcbcae0] | 599 | static void
|
|---|
| 600 | cmd_alias(void)
|
|---|
| 601 | {
|
|---|
| [45dcea2] | 602 | /* Currently only two forms are supported:
|
|---|
| [dcbcae0] | 603 | * *alias station - ..
|
|---|
| [45dcea2] | 604 | * *alias station -
|
|---|
| [dcbcae0] | 605 | */
|
|---|
| 606 | get_token();
|
|---|
| 607 | if (strcmp(ucbuffer, "STATION") != 0)
|
|---|
| 608 | goto bad;
|
|---|
| 609 | get_word();
|
|---|
| 610 | if (strcmp(buffer, "-") != 0)
|
|---|
| 611 | goto bad;
|
|---|
| 612 | get_word();
|
|---|
| 613 | if (*buffer && strcmp(buffer, "..") != 0)
|
|---|
| 614 | goto bad;
|
|---|
| 615 | pcs->dash_for_anon_wall_station = (*buffer != '\0');
|
|---|
| 616 | return;
|
|---|
| 617 | bad:
|
|---|
| 618 | compile_error_skip(/*Bad *alias command*/397);
|
|---|
| 619 | }
|
|---|
| 620 |
|
|---|
| [a420b49] | 621 | static void
|
|---|
| [eb18f4d] | 622 | cmd_begin(void)
|
|---|
| [a420b49] | 623 | {
|
|---|
| [613028c] | 624 | prefix *survey;
|
|---|
| [5f1e194] | 625 | settings *pcsNew;
|
|---|
| [4be360f] | 626 |
|
|---|
| [5f1e194] | 627 | pcsNew = osnew(settings);
|
|---|
| 628 | *pcsNew = *pcs; /* copy contents */
|
|---|
| [47c7a94] | 629 | pcsNew->begin_lineno = file.line;
|
|---|
| [5f1e194] | 630 | pcsNew->next = pcs;
|
|---|
| 631 | pcs = pcsNew;
|
|---|
| [4be360f] | 632 |
|
|---|
| [613028c] | 633 | survey = read_prefix(PFX_SURVEY|PFX_OPT|PFX_ALLOW_ROOT|PFX_WARN_SEPARATOR);
|
|---|
| 634 | pcs->begin_survey = survey;
|
|---|
| 635 | if (survey) {
|
|---|
| 636 | pcs->Prefix = survey;
|
|---|
| 637 | check_reentry(survey);
|
|---|
| [4dcd3af] | 638 | f_export_ok = fTrue;
|
|---|
| [d53b0f5] | 639 | }
|
|---|
| [647407d] | 640 | }
|
|---|
| 641 |
|
|---|
| 642 | extern void
|
|---|
| [eb18f4d] | 643 | free_settings(settings *p) {
|
|---|
| [647407d] | 644 | /* don't free default ordering or ordering used by parent */
|
|---|
| [0395657] | 645 | reading *order = p->ordering;
|
|---|
| [0580c6a] | 646 | if (order != default_order && (!p->next || order != p->next->ordering))
|
|---|
| 647 | osfree(order);
|
|---|
| [cb3d1e2] | 648 |
|
|---|
| [647407d] | 649 | /* free Translate if not used by parent */
|
|---|
| [0580c6a] | 650 | if (!p->next || p->Translate != p->next->Translate)
|
|---|
| 651 | osfree(p->Translate - 1);
|
|---|
| [647407d] | 652 |
|
|---|
| [aa6536a] | 653 | /* free meta if not used by parent, or in this block */
|
|---|
| [ef3d3cc] | 654 | if (p->meta && (!p->next || p->meta != p->next->meta) && p->meta->ref_count == 0)
|
|---|
| [b5a3219] | 655 | osfree(p->meta);
|
|---|
| 656 |
|
|---|
| [c092d72] | 657 | /* free proj if not used by parent, or as the output projection */
|
|---|
| 658 | if (p->proj && (!p->next || p->proj != p->next->proj) && p->proj != proj_out)
|
|---|
| 659 | pj_free(p->proj);
|
|---|
| 660 |
|
|---|
| [eb18f4d] | 661 | osfree(p);
|
|---|
| [d1b1380] | 662 | }
|
|---|
| 663 |
|
|---|
| [4be360f] | 664 | static void
|
|---|
| [eb18f4d] | 665 | cmd_end(void)
|
|---|
| [a420b49] | 666 | {
|
|---|
| [5f1e194] | 667 | settings *pcsParent;
|
|---|
| [613028c] | 668 | prefix *survey, *begin_survey;
|
|---|
| [4be360f] | 669 |
|
|---|
| [5f1e194] | 670 | pcsParent = pcs->next;
|
|---|
| [4be360f] | 671 |
|
|---|
| [47c7a94] | 672 | if (pcs->begin_lineno == 0) {
|
|---|
| [4be360f] | 673 | if (pcsParent == NULL) {
|
|---|
| 674 | /* more ENDs than BEGINs */
|
|---|
| [fa42426] | 675 | compile_error_skip(/*No matching BEGIN*/192);
|
|---|
| [4be360f] | 676 | } else {
|
|---|
| [fa42426] | 677 | compile_error_skip(/*END with no matching BEGIN in this file*/22);
|
|---|
| [4be360f] | 678 | }
|
|---|
| 679 | return;
|
|---|
| 680 | }
|
|---|
| 681 |
|
|---|
| [613028c] | 682 | begin_survey = pcs->begin_survey;
|
|---|
| [647407d] | 683 |
|
|---|
| [4c07c51] | 684 | SVX_ASSERT(pcsParent);
|
|---|
| [647407d] | 685 | free_settings(pcs);
|
|---|
| [5f1e194] | 686 | pcs = pcsParent;
|
|---|
| [d1b1380] | 687 |
|
|---|
| [84c60fc] | 688 | /* note need to read using root *before* BEGIN */
|
|---|
| [613028c] | 689 | survey = read_prefix(PFX_SURVEY|PFX_OPT|PFX_ALLOW_ROOT);
|
|---|
| 690 | if (survey != begin_survey) {
|
|---|
| 691 | if (survey) {
|
|---|
| 692 | if (!begin_survey) {
|
|---|
| 693 | /* TRANSLATORS: Used when a BEGIN command has no survey, but the
|
|---|
| 694 | * END command does, e.g.:
|
|---|
| [736f7df] | 695 | *
|
|---|
| 696 | * *begin
|
|---|
| 697 | * 1 2 10.00 178 -01
|
|---|
| 698 | * *end entrance <--[Message given here] */
|
|---|
| [613028c] | 699 | compile_error_skip(-/*Matching BEGIN command has no survey name*/36);
|
|---|
| [647407d] | 700 | } else {
|
|---|
| [613028c] | 701 | /* TRANSLATORS: *BEGIN <survey> and *END <survey> should have the
|
|---|
| 702 | * same <survey> if it’s given at all */
|
|---|
| 703 | compile_error_skip(-/*Survey name doesn’t match BEGIN*/193);
|
|---|
| [647407d] | 704 | }
|
|---|
| [a420b49] | 705 | } else {
|
|---|
| [613028c] | 706 | /* TRANSLATORS: Used when a BEGIN command has a survey name, but the
|
|---|
| 707 | * END command omits it, e.g.:
|
|---|
| 708 | *
|
|---|
| 709 | * *begin entrance
|
|---|
| 710 | * 1 2 10.00 178 -01
|
|---|
| 711 | * *end <--[Message given here] */
|
|---|
| 712 | compile_warning(-/*Survey name omitted from END*/194);
|
|---|
| [a420b49] | 713 | }
|
|---|
| [5f1e194] | 714 | }
|
|---|
| 715 | }
|
|---|
| [d1b1380] | 716 |
|
|---|
| [dfb4240] | 717 | static void
|
|---|
| 718 | cmd_entrance(void)
|
|---|
| 719 | {
|
|---|
| [c458cf7] | 720 | prefix *pfx = read_prefix(PFX_STATION);
|
|---|
| [dfb4240] | 721 | pfx->sflags |= BIT(SFLAGS_ENTRANCE);
|
|---|
| 722 | }
|
|---|
| 723 |
|
|---|
| [56db37f] | 724 | static const prefix * first_fix_name = NULL;
|
|---|
| 725 | static const char * first_fix_filename;
|
|---|
| 726 | static unsigned first_fix_line;
|
|---|
| [216ada0] | 727 |
|
|---|
| [a420b49] | 728 | static void
|
|---|
| [eb18f4d] | 729 | cmd_fix(void)
|
|---|
| [a420b49] | 730 | {
|
|---|
| [5f1e194] | 731 | prefix *fix_name;
|
|---|
| [153f951] | 732 | node *stn = NULL;
|
|---|
| [216ada0] | 733 | static prefix *name_omit_already = NULL;
|
|---|
| [31699b54] | 734 | static const char * name_omit_already_filename = NULL;
|
|---|
| 735 | static unsigned int name_omit_already_line;
|
|---|
| [a420b49] | 736 | real x, y, z;
|
|---|
| [21c226e] | 737 | int nx, ny, nz;
|
|---|
| [c80bd34] | 738 | filepos fp;
|
|---|
| [5f1e194] | 739 |
|
|---|
| [c458cf7] | 740 | fix_name = read_prefix(PFX_STATION|PFX_ALLOW_ROOT);
|
|---|
| [dfb4240] | 741 | fix_name->sflags |= BIT(SFLAGS_FIXED);
|
|---|
| [5f1e194] | 742 |
|
|---|
| [c80bd34] | 743 | get_pos(&fp);
|
|---|
| [647407d] | 744 | get_token();
|
|---|
| [c80bd34] | 745 | if (strcmp(ucbuffer, "REFERENCE") == 0) {
|
|---|
| [f15cde77] | 746 | /* suppress "unused fixed point" warnings for this station */
|
|---|
| 747 | fix_name->sflags |= BIT(SFLAGS_USED);
|
|---|
| [c80bd34] | 748 | } else {
|
|---|
| 749 | if (*ucbuffer) set_pos(&fp);
|
|---|
| [647407d] | 750 | }
|
|---|
| [c80bd34] | 751 |
|
|---|
| [21c226e] | 752 | x = read_numeric(fTrue, &nx);
|
|---|
| [2aa2f3f] | 753 | if (x == HUGE_REAL) {
|
|---|
| 754 | /* If the end of the line isn't blank, read a number after all to
|
|---|
| 755 | * get a more helpful error message */
|
|---|
| [21c226e] | 756 | if (!isEol(ch) && !isComm(ch)) x = read_numeric(fFalse, &nx);
|
|---|
| [2aa2f3f] | 757 | }
|
|---|
| [5f1e194] | 758 | if (x == HUGE_REAL) {
|
|---|
| [a4f1d96] | 759 | if (pcs->proj || proj_out) {
|
|---|
| 760 | compile_error_skip(/*Coordinates can't be omitted when coordinate system has been specified*/439);
|
|---|
| 761 | return;
|
|---|
| 762 | }
|
|---|
| 763 |
|
|---|
| [6727d64] | 764 | if (fix_name == name_omit_already) {
|
|---|
| 765 | compile_warning(/*Same station fixed twice with no coordinates*/61);
|
|---|
| [5f1e194] | 766 | return;
|
|---|
| 767 | }
|
|---|
| [6727d64] | 768 |
|
|---|
| [736f7df] | 769 | /* TRANSLATORS: " *fix a " gives this message: */
|
|---|
| [a420b49] | 770 | compile_warning(/*FIX command with no coordinates - fixing at (0,0,0)*/54);
|
|---|
| [6727d64] | 771 |
|
|---|
| 772 | if (name_omit_already) {
|
|---|
| 773 | /* TRANSLATORS: Emitted after second and subsequent "FIX command with
|
|---|
| 774 | * no coordinates - fixing at (0,0,0)" warnings.
|
|---|
| 775 | */
|
|---|
| 776 | compile_error_at(name_omit_already_filename,
|
|---|
| 777 | name_omit_already_line,
|
|---|
| 778 | /*Already had FIX command with no coordinates for station “%s”*/441,
|
|---|
| 779 | sprint_prefix(name_omit_already));
|
|---|
| 780 | } else {
|
|---|
| 781 | name_omit_already = fix_name;
|
|---|
| 782 | name_omit_already_filename = file.filename;
|
|---|
| 783 | name_omit_already_line = file.line;
|
|---|
| 784 | }
|
|---|
| 785 |
|
|---|
| [5f1e194] | 786 | x = y = z = (real)0.0;
|
|---|
| 787 | } else {
|
|---|
| [647407d] | 788 | real sdx;
|
|---|
| [21c226e] | 789 | y = read_numeric(fFalse, &ny);
|
|---|
| 790 | z = read_numeric(fFalse, &nz);
|
|---|
| 791 | sdx = read_numeric(fTrue, NULL);
|
|---|
| [647407d] | 792 | if (sdx != HUGE_REAL) {
|
|---|
| 793 | real sdy, sdz;
|
|---|
| [c80bd34] | 794 | real cxy = 0, cyz = 0, czx = 0;
|
|---|
| [21c226e] | 795 | sdy = read_numeric(fTrue, NULL);
|
|---|
| [647407d] | 796 | if (sdy == HUGE_REAL) {
|
|---|
| 797 | /* only one variance given */
|
|---|
| 798 | sdy = sdz = sdx;
|
|---|
| 799 | } else {
|
|---|
| [21c226e] | 800 | sdz = read_numeric(fTrue, NULL);
|
|---|
| [647407d] | 801 | if (sdz == HUGE_REAL) {
|
|---|
| 802 | /* two variances given - horizontal & vertical */
|
|---|
| 803 | sdz = sdy;
|
|---|
| 804 | sdy = sdx;
|
|---|
| [c80bd34] | 805 | } else {
|
|---|
| [21c226e] | 806 | cxy = read_numeric(fTrue, NULL);
|
|---|
| [c80bd34] | 807 | if (cxy != HUGE_REAL) {
|
|---|
| 808 | /* covariances given */
|
|---|
| [21c226e] | 809 | cyz = read_numeric(fFalse, NULL);
|
|---|
| 810 | czx = read_numeric(fFalse, NULL);
|
|---|
| [c2211a5] | 811 | } else {
|
|---|
| 812 | cxy = 0;
|
|---|
| [c80bd34] | 813 | }
|
|---|
| [647407d] | 814 | }
|
|---|
| 815 | }
|
|---|
| [153f951] | 816 | stn = StnFromPfx(fix_name);
|
|---|
| [647407d] | 817 | if (!fixed(stn)) {
|
|---|
| 818 | node *fixpt = osnew(node);
|
|---|
| [be97baf] | 819 | prefix *name;
|
|---|
| 820 | name = osnew(prefix);
|
|---|
| 821 | name->pos = osnew(pos);
|
|---|
| [ff6cfe1] | 822 | name->ident = NULL;
|
|---|
| [6adb88c] | 823 | name->shape = 0;
|
|---|
| [647407d] | 824 | fixpt->name = name;
|
|---|
| 825 | name->stn = fixpt;
|
|---|
| 826 | name->up = NULL;
|
|---|
| [27b8b59] | 827 | if (TSTBIT(pcs->infer, INFER_EXPORTS)) {
|
|---|
| [c00c74a9] | 828 | name->min_export = USHRT_MAX;
|
|---|
| 829 | } else {
|
|---|
| 830 | name->min_export = 0;
|
|---|
| 831 | }
|
|---|
| 832 | name->max_export = 0;
|
|---|
| [95c3272] | 833 | name->sflags = 0;
|
|---|
| [cb3d1e2] | 834 | add_stn_to_list(&stnlist, fixpt);
|
|---|
| [647407d] | 835 | POS(fixpt, 0) = x;
|
|---|
| 836 | POS(fixpt, 1) = y;
|
|---|
| 837 | POS(fixpt, 2) = z;
|
|---|
| 838 | fix(fixpt);
|
|---|
| [4c45ef1] | 839 | fixpt->leg[0] = fixpt->leg[1] = fixpt->leg[2] = NULL;
|
|---|
| [647407d] | 840 | addfakeleg(fixpt, stn, 0, 0, 0,
|
|---|
| 841 | sdx * sdx, sdy * sdy, sdz * sdz
|
|---|
| 842 | #ifndef NO_COVARIANCES
|
|---|
| [c80bd34] | 843 | , cxy, cyz, czx
|
|---|
| [647407d] | 844 | #endif
|
|---|
| 845 | );
|
|---|
| 846 | }
|
|---|
| [cb3d1e2] | 847 | return;
|
|---|
| [647407d] | 848 | }
|
|---|
| [c092d72] | 849 |
|
|---|
| 850 | if (pcs->proj && proj_out) {
|
|---|
| 851 | int r = pj_transform(pcs->proj, proj_out, 1, 1, &x, &y, &z);
|
|---|
| 852 | if (r != 0) {
|
|---|
| 853 | compile_error(/*Failed to convert coordinates*/436);
|
|---|
| 854 | /* FIXME: report pj_strerrno(r) */
|
|---|
| 855 | printf("[%s]\n", pj_strerrno(r));
|
|---|
| 856 | }
|
|---|
| 857 | } else if (pcs->proj) {
|
|---|
| [29d1883f] | 858 | compile_error(/*The input projection is set but the output projection isn't*/437);
|
|---|
| [c092d72] | 859 | } else if (proj_out) {
|
|---|
| [29d1883f] | 860 | compile_error(/*The output projection is set but the input projection isn't*/438);
|
|---|
| [c092d72] | 861 | }
|
|---|
| [5f1e194] | 862 | }
|
|---|
| 863 |
|
|---|
| [56db37f] | 864 | if (!first_fix_name) {
|
|---|
| 865 | /* We track if we've fixed a station yet, and if so what the name of the
|
|---|
| 866 | * first fix was, so that we can issue an error if the output coordinate
|
|---|
| 867 | * system is set after fixing a station. */
|
|---|
| 868 | first_fix_name = fix_name;
|
|---|
| 869 | first_fix_filename = file.filename;
|
|---|
| 870 | first_fix_line = file.line;
|
|---|
| 871 | }
|
|---|
| 872 |
|
|---|
| 873 | stn = StnFromPfx(fix_name);
|
|---|
| [5f1e194] | 874 | if (!fixed(stn)) {
|
|---|
| 875 | POS(stn, 0) = x;
|
|---|
| 876 | POS(stn, 1) = y;
|
|---|
| 877 | POS(stn, 2) = z;
|
|---|
| 878 | fix(stn);
|
|---|
| 879 | return;
|
|---|
| 880 | }
|
|---|
| [d1b1380] | 881 |
|
|---|
| [5f1e194] | 882 | if (x != POS(stn, 0) || y != POS(stn, 1) || z != POS(stn, 2)) {
|
|---|
| [a420b49] | 883 | compile_error(/*Station already fixed or equated to a fixed point*/46);
|
|---|
| [5f1e194] | 884 | return;
|
|---|
| 885 | }
|
|---|
| [736f7df] | 886 | /* TRANSLATORS: *fix a 1 2 3 / *fix a 1 2 3 */
|
|---|
| [a420b49] | 887 | compile_warning(/*Station already fixed at the same coordinates*/55);
|
|---|
| [d1b1380] | 888 | }
|
|---|
| 889 |
|
|---|
| [5c3c61a] | 890 | static void
|
|---|
| 891 | cmd_flags(void)
|
|---|
| 892 | {
|
|---|
| [82919e07] | 893 | static const sztok flagtab[] = {
|
|---|
| [5c3c61a] | 894 | {"DUPLICATE", FLAGS_DUPLICATE },
|
|---|
| 895 | {"NOT", FLAGS_NOT },
|
|---|
| [95c3272] | 896 | {"SPLAY", FLAGS_SPLAY },
|
|---|
| [5c3c61a] | 897 | {"SURFACE", FLAGS_SURFACE },
|
|---|
| [a4ae909] | 898 | {NULL, FLAGS_UNKNOWN }
|
|---|
| [5c3c61a] | 899 | };
|
|---|
| 900 | bool fNot = fFalse;
|
|---|
| [9881759] | 901 | bool fEmpty = fTrue;
|
|---|
| [5c3c61a] | 902 | while (1) {
|
|---|
| 903 | int flag;
|
|---|
| 904 | get_token();
|
|---|
| [62bb4d3] | 905 | /* If buffer is empty, it could mean end of line, or maybe
|
|---|
| 906 | * some non-letter junk which is better reported later */
|
|---|
| [9881759] | 907 | if (!buffer[0]) break;
|
|---|
| [62bb4d3] | 908 |
|
|---|
| [9881759] | 909 | fEmpty = fFalse;
|
|---|
| [5c3c61a] | 910 | flag = match_tok(flagtab, TABSIZE(flagtab));
|
|---|
| 911 | /* treat the second NOT in "NOT NOT" as an unknown flag */
|
|---|
| 912 | if (flag == FLAGS_UNKNOWN || (fNot && flag == FLAGS_NOT)) {
|
|---|
| [da96015] | 913 | file.lpos += strlen(buffer);
|
|---|
| 914 | compile_error(-/*FLAG “%s” unknown*/68, buffer);
|
|---|
| [0804fbe] | 915 | /* Recover from “*FLAGS NOT BOGUS SURFACE” by ignoring "NOT BOGUS" */
|
|---|
| [62bb4d3] | 916 | fNot = fFalse;
|
|---|
| 917 | } else if (flag == FLAGS_NOT) {
|
|---|
| [421b7d2] | 918 | fNot = fTrue;
|
|---|
| [5c3c61a] | 919 | } else if (fNot) {
|
|---|
| [421b7d2] | 920 | pcs->flags &= ~BIT(flag);
|
|---|
| 921 | fNot = fFalse;
|
|---|
| [5c3c61a] | 922 | } else {
|
|---|
| [421b7d2] | 923 | pcs->flags |= BIT(flag);
|
|---|
| [5c3c61a] | 924 | }
|
|---|
| 925 | }
|
|---|
| [9881759] | 926 |
|
|---|
| 927 | if (fNot) {
|
|---|
| [da96015] | 928 | file.lpos += strlen(buffer);
|
|---|
| 929 | compile_error(-/*Expecting “DUPLICATE”, “SPLAY”, or “SURFACE”*/188);
|
|---|
| [9881759] | 930 | } else if (fEmpty) {
|
|---|
| [da96015] | 931 | file.lpos += strlen(buffer);
|
|---|
| 932 | compile_error(-/*Expecting “NOT”, “DUPLICATE”, “SPLAY”, or “SURFACE”*/189);
|
|---|
| [9881759] | 933 | }
|
|---|
| [5c3c61a] | 934 | }
|
|---|
| 935 |
|
|---|
| [a420b49] | 936 | static void
|
|---|
| [eb18f4d] | 937 | cmd_equate(void)
|
|---|
| [a420b49] | 938 | {
|
|---|
| [5f1e194] | 939 | prefix *name1, *name2;
|
|---|
| 940 | bool fOnlyOneStn = fTrue; /* to trap eg *equate entrance.6 */
|
|---|
| 941 |
|
|---|
| [c458cf7] | 942 | name1 = read_prefix(PFX_STATION|PFX_ALLOW_ROOT|PFX_SUSPECT_TYPO);
|
|---|
| [5f1e194] | 943 | while (fTrue) {
|
|---|
| 944 | name2 = name1;
|
|---|
| [c458cf7] | 945 | name1 = read_prefix(PFX_STATION|PFX_ALLOW_ROOT|PFX_SUSPECT_TYPO|PFX_OPT);
|
|---|
| [5f1e194] | 946 | if (name1 == NULL) {
|
|---|
| [11f9067] | 947 | if (fOnlyOneStn) {
|
|---|
| [736f7df] | 948 | /* TRANSLATORS: EQUATE is a command name, so shouldn’t be
|
|---|
| [0b8c321] | 949 | * translated.
|
|---|
| 950 | *
|
|---|
| 951 | * Here "station" is a survey station, not a train station.
|
|---|
| 952 | */
|
|---|
| [da96015] | 953 | compile_error_skip(-/*Only one station in EQUATE command*/33);
|
|---|
| [11f9067] | 954 | }
|
|---|
| [5f1e194] | 955 | return;
|
|---|
| [d1b1380] | 956 | }
|
|---|
| [cb3d1e2] | 957 |
|
|---|
| [be374fc] | 958 | process_equate(name1, name2);
|
|---|
| [5f1e194] | 959 | fOnlyOneStn = fFalse;
|
|---|
| 960 | }
|
|---|
| [d1b1380] | 961 | }
|
|---|
| 962 |
|
|---|
| [84c60fc] | 963 | static void
|
|---|
| 964 | report_missing_export(prefix *pfx, int depth)
|
|---|
| 965 | {
|
|---|
| 966 | char *s;
|
|---|
| [93e3492] | 967 | const char *p;
|
|---|
| 968 | prefix *survey = pfx;
|
|---|
| [84c60fc] | 969 | int i;
|
|---|
| 970 | for (i = depth + 1; i; i--) {
|
|---|
| 971 | survey = survey->up;
|
|---|
| [4c07c51] | 972 | SVX_ASSERT(survey);
|
|---|
| [84c60fc] | 973 | }
|
|---|
| 974 | s = osstrdup(sprint_prefix(survey));
|
|---|
| [93e3492] | 975 | p = sprint_prefix(pfx);
|
|---|
| [84c60fc] | 976 | if (survey->filename) {
|
|---|
| [93e3492] | 977 | /* TRANSLATORS: A station must be exported out of each level it is in, so
|
|---|
| 978 | * this would give "Station “\outer.inner.1” not exported from survey
|
|---|
| 979 | * “\outer”)":
|
|---|
| 980 | *
|
|---|
| 981 | * *equate entrance outer.inner.1
|
|---|
| 982 | * *begin outer
|
|---|
| 983 | * *begin inner
|
|---|
| 984 | * *export 1
|
|---|
| 985 | * 1 2 1.23 045 -6
|
|---|
| 986 | * *end inner
|
|---|
| [0b8c321] | 987 | * *end outer
|
|---|
| 988 | *
|
|---|
| 989 | * Here "survey" is a "cave map" rather than list of questions - it should be
|
|---|
| 990 | * translated to the terminology that cavers using the language would use.
|
|---|
| 991 | */
|
|---|
| [93e3492] | 992 | compile_error_pfx(survey,
|
|---|
| 993 | /*Station “%s” not exported from survey “%s”*/26, p, s);
|
|---|
| 994 | } else {
|
|---|
| 995 | compile_error(/*Station “%s” not exported from survey “%s”*/26, p, s);
|
|---|
| [84c60fc] | 996 | }
|
|---|
| 997 | osfree(s);
|
|---|
| 998 | }
|
|---|
| 999 |
|
|---|
| [fb2e93c] | 1000 | static void
|
|---|
| [d1878c51] | 1001 | cmd_export(void)
|
|---|
| [fb2e93c] | 1002 | {
|
|---|
| [d1878c51] | 1003 | prefix *pfx;
|
|---|
| 1004 |
|
|---|
| 1005 | fExportUsed = fTrue;
|
|---|
| [c458cf7] | 1006 | pfx = read_prefix(PFX_STATION);
|
|---|
| [932f7e9] | 1007 | do {
|
|---|
| [fb2e93c] | 1008 | int depth = 0;
|
|---|
| 1009 | {
|
|---|
| [421b7d2] | 1010 | prefix *p = pfx;
|
|---|
| [fb2e93c] | 1011 | while (p != NULL && p != pcs->Prefix) {
|
|---|
| 1012 | depth++;
|
|---|
| 1013 | p = p->up;
|
|---|
| 1014 | }
|
|---|
| [84c60fc] | 1015 | /* Something like: *export \foo, but we've excluded use of root */
|
|---|
| [4c07c51] | 1016 | SVX_ASSERT(p);
|
|---|
| [fb2e93c] | 1017 | }
|
|---|
| [84c60fc] | 1018 | /* *export \ or similar bogus stuff */
|
|---|
| [4c07c51] | 1019 | SVX_ASSERT(depth);
|
|---|
| [932f7e9] | 1020 | #if 0
|
|---|
| 1021 | printf("C min %d max %d depth %d pfx %s\n",
|
|---|
| 1022 | pfx->min_export, pfx->max_export, depth, sprint_prefix(pfx));
|
|---|
| 1023 | #endif
|
|---|
| 1024 | if (pfx->min_export == 0) {
|
|---|
| [421b7d2] | 1025 | /* not encountered *export for this name before */
|
|---|
| 1026 | if (pfx->max_export > depth) report_missing_export(pfx, depth);
|
|---|
| 1027 | pfx->min_export = pfx->max_export = depth;
|
|---|
| [c00c74a9] | 1028 | } else if (pfx->min_export != USHRT_MAX) {
|
|---|
| 1029 | /* FIXME: what to do if a station is marked for inferred exports
|
|---|
| 1030 | * but is then explicitly exported? Currently we just ignore the
|
|---|
| 1031 | * explicit export... */
|
|---|
| [421b7d2] | 1032 | if (pfx->min_export - 1 > depth) {
|
|---|
| [84c60fc] | 1033 | report_missing_export(pfx, depth);
|
|---|
| [421b7d2] | 1034 | } else if (pfx->min_export - 1 < depth) {
|
|---|
| [736f7df] | 1035 | /* TRANSLATORS: Here "station" is a survey station, not a train station.
|
|---|
| 1036 | *
|
|---|
| 1037 | * Exporting a station twice gives this error:
|
|---|
| 1038 | *
|
|---|
| 1039 | * *begin example
|
|---|
| 1040 | * *export 1
|
|---|
| 1041 | * *export 1
|
|---|
| 1042 | * 1 2 1.24 045 -6
|
|---|
| 1043 | * *end example */
|
|---|
| [0804fbe] | 1044 | compile_error(/*Station “%s” already exported*/66,
|
|---|
| [932f7e9] | 1045 | sprint_prefix(pfx));
|
|---|
| [421b7d2] | 1046 | }
|
|---|
| 1047 | pfx->min_export = depth;
|
|---|
| [fb2e93c] | 1048 | }
|
|---|
| [c458cf7] | 1049 | pfx = read_prefix(PFX_STATION|PFX_OPT);
|
|---|
| [932f7e9] | 1050 | } while (pfx);
|
|---|
| [fb2e93c] | 1051 | }
|
|---|
| 1052 |
|
|---|
| [a420b49] | 1053 | static void
|
|---|
| [eb18f4d] | 1054 | cmd_data(void)
|
|---|
| [a420b49] | 1055 | {
|
|---|
| [82919e07] | 1056 | static const sztok dtab[] = {
|
|---|
| [9b5d785] | 1057 | {"ALTITUDE", Dz },
|
|---|
| [5b7c1b7] | 1058 | {"BACKBEARING", BackComp },
|
|---|
| 1059 | {"BACKCLINO", BackClino }, /* alternative name */
|
|---|
| 1060 | {"BACKCOMPASS", BackComp }, /* alternative name */
|
|---|
| 1061 | {"BACKGRADIENT", BackClino },
|
|---|
| [5f1e194] | 1062 | {"BEARING", Comp },
|
|---|
| [ee05463] | 1063 | {"CEILING", Up }, /* alternative name */
|
|---|
| [a4ae909] | 1064 | {"CLINO", Clino }, /* alternative name */
|
|---|
| [a420b49] | 1065 | {"COMPASS", Comp }, /* alternative name */
|
|---|
| [a4ae909] | 1066 | {"COUNT", Count }, /* FrCount&ToCount in multiline */
|
|---|
| 1067 | {"DEPTH", Depth }, /* FrDepth&ToDepth in multiline */
|
|---|
| [6114207] | 1068 | {"DEPTHCHANGE", DepthChange },
|
|---|
| [421b7d2] | 1069 | {"DIRECTION", Dir },
|
|---|
| [ee05463] | 1070 | {"DOWN", Down },
|
|---|
| [647407d] | 1071 | {"DX", Dx },
|
|---|
| 1072 | {"DY", Dy },
|
|---|
| 1073 | {"DZ", Dz },
|
|---|
| [9b5d785] | 1074 | {"EASTING", Dx },
|
|---|
| [ee05463] | 1075 | {"FLOOR", Down }, /* alternative name */
|
|---|
| [a4ae909] | 1076 | {"FROM", Fr },
|
|---|
| [647407d] | 1077 | {"FROMCOUNT", FrCount },
|
|---|
| [5f1e194] | 1078 | {"FROMDEPTH", FrDepth },
|
|---|
| 1079 | {"GRADIENT", Clino },
|
|---|
| 1080 | {"IGNORE", Ignore },
|
|---|
| 1081 | {"IGNOREALL", IgnoreAll },
|
|---|
| [ee05463] | 1082 | {"LEFT", Left },
|
|---|
| [5f1e194] | 1083 | {"LENGTH", Tape },
|
|---|
| [a0027a2] | 1084 | {"NEWLINE", Newline },
|
|---|
| [9b5d785] | 1085 | {"NORTHING", Dy },
|
|---|
| [ee05463] | 1086 | {"RIGHT", Right },
|
|---|
| [421b7d2] | 1087 | {"STATION", Station }, /* Fr&To in multiline */
|
|---|
| [a4ae909] | 1088 | {"TAPE", Tape }, /* alternative name */
|
|---|
| 1089 | {"TO", To },
|
|---|
| [647407d] | 1090 | {"TOCOUNT", ToCount },
|
|---|
| [5f1e194] | 1091 | {"TODEPTH", ToDepth },
|
|---|
| [ee05463] | 1092 | {"UP", Up },
|
|---|
| [a4ae909] | 1093 | {NULL, End }
|
|---|
| [5f1e194] | 1094 | };
|
|---|
| 1095 |
|
|---|
| [107b8bd] | 1096 | #define MASK_stns BIT(Fr) | BIT(To) | BIT(Station)
|
|---|
| 1097 | #define MASK_tape BIT(Tape) | BIT(FrCount) | BIT(ToCount) | BIT(Count)
|
|---|
| 1098 | #define MASK_dpth BIT(FrDepth) | BIT(ToDepth) | BIT(Depth) | BIT(DepthChange)
|
|---|
| [5b7c1b7] | 1099 | #define MASK_comp BIT(Comp) | BIT(BackComp)
|
|---|
| 1100 | #define MASK_clin BIT(Clino) | BIT(BackClino)
|
|---|
| [5f1e194] | 1101 |
|
|---|
| [5b7c1b7] | 1102 | #define MASK_NORMAL MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_clin
|
|---|
| 1103 | #define MASK_DIVING MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth
|
|---|
| [107b8bd] | 1104 | #define MASK_CARTESIAN MASK_stns | BIT(Dx) | BIT(Dy) | BIT(Dz)
|
|---|
| [5b7c1b7] | 1105 | #define MASK_CYLPOLAR MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth
|
|---|
| [ee05463] | 1106 | #define MASK_PASSAGE BIT(Station) | BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down)
|
|---|
| [107b8bd] | 1107 | #define MASK_NOSURVEY MASK_stns
|
|---|
| [421b7d2] | 1108 |
|
|---|
| [5f1e194] | 1109 | /* readings which may be given for each style */
|
|---|
| [6114207] | 1110 | static const unsigned long mask[] = {
|
|---|
| [200a12c] | 1111 | MASK_NORMAL, MASK_DIVING, MASK_CARTESIAN, MASK_CYLPOLAR, MASK_NOSURVEY,
|
|---|
| 1112 | MASK_PASSAGE
|
|---|
| [5f1e194] | 1113 | };
|
|---|
| 1114 |
|
|---|
| 1115 | /* readings which may be omitted for each style */
|
|---|
| [6114207] | 1116 | static const unsigned long mask_optional[] = {
|
|---|
| [5b7c1b7] | 1117 | BIT(Dir) | BIT(Clino) | BIT(BackClino),
|
|---|
| [276286d] | 1118 | BIT(Dir),
|
|---|
| [86f26e2] | 1119 | 0,
|
|---|
| [54c4612] | 1120 | BIT(Dir),
|
|---|
| [200a12c] | 1121 | 0,
|
|---|
| 1122 | 0 /* BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down), */
|
|---|
| [5f1e194] | 1123 | };
|
|---|
| 1124 |
|
|---|
| [6114207] | 1125 | /* all valid readings */
|
|---|
| 1126 | static const unsigned long mask_all[] = {
|
|---|
| 1127 | MASK_NORMAL | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
|
|---|
| 1128 | MASK_DIVING | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
|
|---|
| 1129 | MASK_CARTESIAN | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
|
|---|
| 1130 | MASK_CYLPOLAR | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
|
|---|
| [200a12c] | 1131 | MASK_NOSURVEY | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
|
|---|
| 1132 | MASK_PASSAGE | BIT(Ignore) | BIT(IgnoreAll) | BIT(End)
|
|---|
| [6114207] | 1133 | };
|
|---|
| [54c4612] | 1134 | #define STYLE_DEFAULT -2
|
|---|
| 1135 | #define STYLE_UNKNOWN -1
|
|---|
| 1136 |
|
|---|
| [82919e07] | 1137 | static const sztok styletab[] = {
|
|---|
| [647407d] | 1138 | {"CARTESIAN", STYLE_CARTESIAN },
|
|---|
| [54c4612] | 1139 | {"CYLPOLAR", STYLE_CYLPOLAR },
|
|---|
| [a420b49] | 1140 | {"DEFAULT", STYLE_DEFAULT },
|
|---|
| [5f1e194] | 1141 | {"DIVING", STYLE_DIVING },
|
|---|
| 1142 | {"NORMAL", STYLE_NORMAL },
|
|---|
| [647407d] | 1143 | {"NOSURVEY", STYLE_NOSURVEY },
|
|---|
| [ee05463] | 1144 | {"PASSAGE", STYLE_PASSAGE },
|
|---|
| [107b8bd] | 1145 | {"TOPOFIL", STYLE_NORMAL },
|
|---|
| [a4ae909] | 1146 | {NULL, STYLE_UNKNOWN }
|
|---|
| [5f1e194] | 1147 | };
|
|---|
| 1148 |
|
|---|
| [ee3a4ed] | 1149 | #define m_multi (BIT(Station) | BIT(Count) | BIT(Depth))
|
|---|
| 1150 |
|
|---|
| [5f1e194] | 1151 | int style, k = 0, kMac;
|
|---|
| [0395657] | 1152 | reading *new_order, d;
|
|---|
| [6114207] | 1153 | unsigned long mUsed = 0;
|
|---|
| [1b34062] | 1154 | char *style_name;
|
|---|
| [5f1e194] | 1155 |
|
|---|
| [50f6901] | 1156 | /* after a bad *data command ignore survey data until the next
|
|---|
| 1157 | * *data command to avoid an avalanche of errors */
|
|---|
| [107b8bd] | 1158 | pcs->style = STYLE_IGNORE;
|
|---|
| [289b7a8] | 1159 |
|
|---|
| [5f1e194] | 1160 | kMac = 6; /* minimum for NORMAL style */
|
|---|
| [0395657] | 1161 | new_order = osmalloc(kMac * sizeof(reading));
|
|---|
| [5f1e194] | 1162 |
|
|---|
| [a420b49] | 1163 | get_token();
|
|---|
| [5f1e194] | 1164 | style = match_tok(styletab, TABSIZE(styletab));
|
|---|
| 1165 |
|
|---|
| [a420b49] | 1166 | if (style == STYLE_DEFAULT) {
|
|---|
| 1167 | default_style(pcs);
|
|---|
| 1168 | return;
|
|---|
| 1169 | }
|
|---|
| 1170 |
|
|---|
| [5f1e194] | 1171 | if (style == STYLE_UNKNOWN) {
|
|---|
| [da96015] | 1172 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1173 | /* TRANSLATORS: e.g. trying to refer to an invalid FNORD data style */
|
|---|
| [da96015] | 1174 | compile_error_skip(-/*Data style “%s” unknown*/65, buffer);
|
|---|
| [5f1e194] | 1175 | return;
|
|---|
| 1176 | }
|
|---|
| [a420b49] | 1177 |
|
|---|
| [5f1e194] | 1178 | skipblanks();
|
|---|
| [d6d3576] | 1179 | #ifndef NO_DEPRECATED
|
|---|
| 1180 | /* Olde syntax had optional field for survey grade, so allow an omit
|
|---|
| 1181 | * but issue a warning about it */
|
|---|
| 1182 | if (isOmit(ch)) {
|
|---|
| 1183 | static int data_depr_count = 0;
|
|---|
| 1184 | if (data_depr_count < 5) {
|
|---|
| [da96015] | 1185 | file.lpos += strlen(buffer);
|
|---|
| 1186 | compile_warning(-/*“*data %s %c …” is deprecated - use “*data %s …” instead*/104,
|
|---|
| [d6d3576] | 1187 | buffer, ch, buffer);
|
|---|
| 1188 | if (++data_depr_count == 5)
|
|---|
| [c40038a] | 1189 | compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
|
|---|
| [d6d3576] | 1190 | }
|
|---|
| 1191 | nextch();
|
|---|
| 1192 | }
|
|---|
| 1193 | #endif
|
|---|
| [d1b1380] | 1194 |
|
|---|
| [1b34062] | 1195 | style_name = osstrdup(buffer);
|
|---|
| [421b7d2] | 1196 | do {
|
|---|
| [c80bd34] | 1197 | filepos fp;
|
|---|
| 1198 | get_pos(&fp);
|
|---|
| [a420b49] | 1199 | get_token();
|
|---|
| [5f1e194] | 1200 | d = match_tok(dtab, TABSIZE(dtab));
|
|---|
| [90bb053f] | 1201 | /* only token allowed after IGNOREALL is NEWLINE */
|
|---|
| 1202 | if (k && new_order[k - 1] == IgnoreAll && d != Newline) {
|
|---|
| [c80bd34] | 1203 | set_pos(&fp);
|
|---|
| [90bb053f] | 1204 | break;
|
|---|
| 1205 | }
|
|---|
| [0395657] | 1206 | /* Note: an unknown token is reported as trailing garbage */
|
|---|
| [6114207] | 1207 | if (!TSTBIT(mask_all[style], d)) {
|
|---|
| [da96015] | 1208 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1209 | /* TRANSLATORS: a data "style" is something like NORMAL, DIVING, etc.
|
|---|
| 1210 | * a "reading" is one of FROM, TO, TAPE, COMPASS, CLINO for NORMAL
|
|---|
| 1211 | * neither style nor reading is a keyword in the program This error
|
|---|
| 1212 | * complains about a depth gauge reading in normal style, for example
|
|---|
| 1213 | */
|
|---|
| [da96015] | 1214 | compile_error_skip(-/*Reading “%s” not allowed in data style “%s”*/63,
|
|---|
| [1b34062] | 1215 | buffer, style_name);
|
|---|
| 1216 | osfree(style_name);
|
|---|
| [a6d094f] | 1217 | osfree(new_order);
|
|---|
| [ee3a4ed] | 1218 | return;
|
|---|
| 1219 | }
|
|---|
| [6114207] | 1220 | if (TSTBIT(mUsed, Newline) && TSTBIT(m_multi, d)) {
|
|---|
| [da96015] | 1221 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1222 | /* TRANSLATORS: caused by e.g.
|
|---|
| 1223 | *
|
|---|
| 1224 | * *data diving station newline depth tape compass
|
|---|
| 1225 | *
|
|---|
| 1226 | * ("depth" needs to occur before "newline"). */
|
|---|
| [da96015] | 1227 | compile_error_skip(-/*Reading “%s” must occur before NEWLINE*/225, buffer);
|
|---|
| [ee3a4ed] | 1228 | osfree(style_name);
|
|---|
| [a6d094f] | 1229 | osfree(new_order);
|
|---|
| [5f1e194] | 1230 | return;
|
|---|
| 1231 | }
|
|---|
| [0395657] | 1232 | /* Check for duplicates unless it's a special reading:
|
|---|
| [ee3a4ed] | 1233 | * IGNOREALL,IGNORE (duplicates allowed) ; END (not possible)
|
|---|
| [5f1e194] | 1234 | */
|
|---|
| [ee3a4ed] | 1235 | if (!((BIT(Ignore) | BIT(End) | BIT(IgnoreAll)) & BIT(d))) {
|
|---|
| [95c3272] | 1236 | if (TSTBIT(mUsed, d)) {
|
|---|
| [da96015] | 1237 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1238 | /* TRANSLATORS: complains about a situation like trying to define
|
|---|
| 1239 | * two from stations per leg */
|
|---|
| [da96015] | 1240 | compile_error_skip(-/*Duplicate reading “%s”*/67, buffer);
|
|---|
| [90bb053f] | 1241 | osfree(style_name);
|
|---|
| [a6d094f] | 1242 | osfree(new_order);
|
|---|
| [90bb053f] | 1243 | return;
|
|---|
| [62bb4d3] | 1244 | } else {
|
|---|
| [5b7c1b7] | 1245 | /* Check for previously listed readings which are incompatible
|
|---|
| 1246 | * with this one - e.g. Count vs FrCount */
|
|---|
| [90bb053f] | 1247 | bool fBad = fFalse;
|
|---|
| 1248 | switch (d) {
|
|---|
| 1249 | case Station:
|
|---|
| 1250 | if (mUsed & (BIT(Fr) | BIT(To))) fBad = fTrue;
|
|---|
| 1251 | break;
|
|---|
| 1252 | case Fr: case To:
|
|---|
| 1253 | if (TSTBIT(mUsed, Station)) fBad = fTrue;
|
|---|
| 1254 | break;
|
|---|
| 1255 | case Count:
|
|---|
| [107b8bd] | 1256 | if (mUsed & (BIT(FrCount) | BIT(ToCount) | BIT(Tape)))
|
|---|
| 1257 | fBad = fTrue;
|
|---|
| [90bb053f] | 1258 | break;
|
|---|
| 1259 | case FrCount: case ToCount:
|
|---|
| [107b8bd] | 1260 | if (mUsed & (BIT(Count) | BIT(Tape)))
|
|---|
| 1261 | fBad = fTrue;
|
|---|
| [90bb053f] | 1262 | break;
|
|---|
| 1263 | case Depth:
|
|---|
| [6114207] | 1264 | if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange)))
|
|---|
| [a186573] | 1265 | fBad = fTrue;
|
|---|
| [90bb053f] | 1266 | break;
|
|---|
| 1267 | case FrDepth: case ToDepth:
|
|---|
| [6114207] | 1268 | if (mUsed & (BIT(Depth) | BIT(DepthChange))) fBad = fTrue;
|
|---|
| [a186573] | 1269 | break;
|
|---|
| [6114207] | 1270 | case DepthChange:
|
|---|
| [a186573] | 1271 | if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(Depth)))
|
|---|
| 1272 | fBad = fTrue;
|
|---|
| [90bb053f] | 1273 | break;
|
|---|
| [ee3a4ed] | 1274 | case Newline:
|
|---|
| 1275 | if (mUsed & ~m_multi) {
|
|---|
| [da96015] | 1276 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1277 | /* TRANSLATORS: e.g.
|
|---|
| 1278 | *
|
|---|
| 1279 | * *data normal from to tape newline compass clino */
|
|---|
| [da96015] | 1280 | compile_error_skip(-/*NEWLINE can only be preceded by STATION, DEPTH, and COUNT*/226);
|
|---|
| [ee3a4ed] | 1281 | osfree(style_name);
|
|---|
| [a6d094f] | 1282 | osfree(new_order);
|
|---|
| [ee3a4ed] | 1283 | return;
|
|---|
| 1284 | }
|
|---|
| [6114207] | 1285 | if (k == 0) {
|
|---|
| [da96015] | 1286 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1287 | /* TRANSLATORS: error from:
|
|---|
| 1288 | *
|
|---|
| 1289 | * *data normal newline from to tape compass clino */
|
|---|
| [da96015] | 1290 | compile_error_skip(-/*NEWLINE can’t be the first reading*/222);
|
|---|
| [6114207] | 1291 | osfree(style_name);
|
|---|
| 1292 | osfree(new_order);
|
|---|
| 1293 | return;
|
|---|
| 1294 | }
|
|---|
| [ee3a4ed] | 1295 | break;
|
|---|
| [90bb053f] | 1296 | default: /* avoid compiler warnings about unhandled enums */
|
|---|
| 1297 | break;
|
|---|
| [421b7d2] | 1298 | }
|
|---|
| [90bb053f] | 1299 | if (fBad) {
|
|---|
| [46cb98f] | 1300 | /* Not entirely happy with phrasing this... */
|
|---|
| [da96015] | 1301 | file.lpos += strlen(buffer);
|
|---|
| [36efb03] | 1302 | /* TRANSLATORS: This is an error from the *DATA command. It
|
|---|
| 1303 | * means that a reading (which will appear where %s is isn't
|
|---|
| 1304 | * valid as the list of readings has already included the same
|
|---|
| 1305 | * reading, or an equivalent one (e.g. you can't have both
|
|---|
| 1306 | * DEPTH and DEPTHCHANGE together). */
|
|---|
| [da96015] | 1307 | compile_error_skip(-/*Reading “%s” duplicates previous reading(s)*/77,
|
|---|
| [46cb98f] | 1308 | buffer);
|
|---|
| [90bb053f] | 1309 | osfree(style_name);
|
|---|
| [a6d094f] | 1310 | osfree(new_order);
|
|---|
| [90bb053f] | 1311 | return;
|
|---|
| 1312 | }
|
|---|
| [62bb4d3] | 1313 | mUsed |= BIT(d); /* used to catch duplicates */
|
|---|
| [a420b49] | 1314 | }
|
|---|
| [d1b1380] | 1315 | }
|
|---|
| [90bb053f] | 1316 | if (k && new_order[k - 1] == IgnoreAll) {
|
|---|
| [4c07c51] | 1317 | SVX_ASSERT(d == Newline);
|
|---|
| [90bb053f] | 1318 | k--;
|
|---|
| 1319 | d = IgnoreAllAndNewLine;
|
|---|
| 1320 | }
|
|---|
| [a420b49] | 1321 | if (k >= kMac) {
|
|---|
| 1322 | kMac = kMac * 2;
|
|---|
| [0395657] | 1323 | new_order = osrealloc(new_order, kMac * sizeof(reading));
|
|---|
| [a420b49] | 1324 | }
|
|---|
| 1325 | new_order[k++] = d;
|
|---|
| [90bb053f] | 1326 | } while (d != End);
|
|---|
| 1327 |
|
|---|
| [6114207] | 1328 | if (k >= 2 && new_order[k - 2] == Newline) {
|
|---|
| [da96015] | 1329 | file.lpos += strlen(buffer);
|
|---|
| [736f7df] | 1330 | /* TRANSLATORS: error from:
|
|---|
| 1331 | *
|
|---|
| 1332 | * *data normal from to tape compass clino newline */
|
|---|
| [da96015] | 1333 | compile_error_skip(-/*NEWLINE can’t be the last reading*/223);
|
|---|
| [6114207] | 1334 | osfree(style_name);
|
|---|
| 1335 | osfree(new_order);
|
|---|
| 1336 | return;
|
|---|
| 1337 | }
|
|---|
| [421b7d2] | 1338 |
|
|---|
| [6114207] | 1339 | if (style == STYLE_NOSURVEY) {
|
|---|
| 1340 | if (TSTBIT(mUsed, Station)) {
|
|---|
| 1341 | if (k >= kMac) {
|
|---|
| 1342 | kMac = kMac * 2;
|
|---|
| 1343 | new_order = osrealloc(new_order, kMac * sizeof(reading));
|
|---|
| 1344 | }
|
|---|
| 1345 | new_order[k - 1] = Newline;
|
|---|
| 1346 | new_order[k++] = End;
|
|---|
| 1347 | }
|
|---|
| [ee05463] | 1348 | } else if (style == STYLE_PASSAGE) {
|
|---|
| 1349 | /* Station doesn't mean "multiline" for STYLE_PASSAGE. */
|
|---|
| [6114207] | 1350 | } else if (!TSTBIT(mUsed, Newline) && (m_multi & mUsed)) {
|
|---|
| [736f7df] | 1351 | /* TRANSLATORS: Error given by something like:
|
|---|
| 1352 | *
|
|---|
| [6114207] | 1353 | * *data normal station tape compass clino
|
|---|
| [736f7df] | 1354 | *
|
|---|
| 1355 | * ("station" signifies interleaved data). */
|
|---|
| [fa42426] | 1356 | compile_error_skip(/*Interleaved readings, but no NEWLINE*/224);
|
|---|
| [6114207] | 1357 | osfree(style_name);
|
|---|
| 1358 | osfree(new_order);
|
|---|
| 1359 | return;
|
|---|
| 1360 | }
|
|---|
| 1361 |
|
|---|
| [a6d094f] | 1362 | #if 0
|
|---|
| 1363 | printf("mUsed = 0x%x\n", mUsed);
|
|---|
| 1364 | #endif
|
|---|
| [90bb053f] | 1365 |
|
|---|
| [5b7c1b7] | 1366 | /* Check the supplied readings form a sufficient set. */
|
|---|
| [ee05463] | 1367 | if (style != STYLE_PASSAGE) {
|
|---|
| 1368 | if (mUsed & (BIT(Fr) | BIT(To)))
|
|---|
| 1369 | mUsed |= BIT(Station);
|
|---|
| 1370 | else if (TSTBIT(mUsed, Station))
|
|---|
| 1371 | mUsed |= BIT(Fr) | BIT(To);
|
|---|
| 1372 | }
|
|---|
| [a186573] | 1373 |
|
|---|
| [5b7c1b7] | 1374 | if (mUsed & (BIT(Comp) | BIT(BackComp)))
|
|---|
| 1375 | mUsed |= BIT(Comp) | BIT(BackComp);
|
|---|
| 1376 |
|
|---|
| 1377 | if (mUsed & (BIT(Clino) | BIT(BackClino)))
|
|---|
| 1378 | mUsed |= BIT(Clino) | BIT(BackClino);
|
|---|
| 1379 |
|
|---|
| [a186573] | 1380 | if (mUsed & (BIT(FrDepth) | BIT(ToDepth)))
|
|---|
| [6114207] | 1381 | mUsed |= BIT(Depth) | BIT(DepthChange);
|
|---|
| [a186573] | 1382 | else if (TSTBIT(mUsed, Depth))
|
|---|
| [6114207] | 1383 | mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange);
|
|---|
| 1384 | else if (TSTBIT(mUsed, DepthChange))
|
|---|
| [a186573] | 1385 | mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(Depth);
|
|---|
| 1386 |
|
|---|
| 1387 | if (mUsed & (BIT(FrCount) | BIT(ToCount)))
|
|---|
| [107b8bd] | 1388 | mUsed |= BIT(Count) | BIT(Tape);
|
|---|
| [a186573] | 1389 | else if (TSTBIT(mUsed, Count))
|
|---|
| [107b8bd] | 1390 | mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Tape);
|
|---|
| 1391 | else if (TSTBIT(mUsed, Tape))
|
|---|
| 1392 | mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Count);
|
|---|
| [90bb053f] | 1393 |
|
|---|
| [a6d094f] | 1394 | #if 0
|
|---|
| 1395 | printf("mUsed = 0x%x, opt = 0x%x, mask = 0x%x\n", mUsed,
|
|---|
| 1396 | mask_optional[style], mask[style]);
|
|---|
| 1397 | #endif
|
|---|
| [cb3d1e2] | 1398 |
|
|---|
| [6114207] | 1399 | if (((mUsed &~ BIT(Newline)) | mask_optional[style]) != mask[style]) {
|
|---|
| 1400 | /* Test should only fail with too few bits set, not too many */
|
|---|
| [4c07c51] | 1401 | SVX_ASSERT((((mUsed &~ BIT(Newline)) | mask_optional[style])
|
|---|
| [6114207] | 1402 | &~ mask[style]) == 0);
|
|---|
| [736f7df] | 1403 | /* TRANSLATORS: i.e. not enough readings for the style. */
|
|---|
| [0804fbe] | 1404 | compile_error_skip(/*Too few readings for data style “%s”*/64, style_name);
|
|---|
| [1b34062] | 1405 | osfree(style_name);
|
|---|
| [a6d094f] | 1406 | osfree(new_order);
|
|---|
| [a420b49] | 1407 | return;
|
|---|
| 1408 | }
|
|---|
| [d1b1380] | 1409 |
|
|---|
| [a420b49] | 1410 | /* don't free default ordering or ordering used by parent */
|
|---|
| 1411 | if (pcs->ordering != default_order &&
|
|---|
| 1412 | !(pcs->next && pcs->next->ordering == pcs->ordering))
|
|---|
| 1413 | osfree(pcs->ordering);
|
|---|
| [cb3d1e2] | 1414 |
|
|---|
| [107b8bd] | 1415 | pcs->style = style;
|
|---|
| [a420b49] | 1416 | pcs->ordering = new_order;
|
|---|
| [1b34062] | 1417 |
|
|---|
| [421b7d2] | 1418 | osfree(style_name);
|
|---|
| [ee05463] | 1419 |
|
|---|
| 1420 | if (style == STYLE_PASSAGE) {
|
|---|
| 1421 | lrudlist * new_psg = osnew(lrudlist);
|
|---|
| 1422 | new_psg->tube = NULL;
|
|---|
| 1423 | new_psg->next = model;
|
|---|
| 1424 | model = new_psg;
|
|---|
| 1425 | next_lrud = &(new_psg->tube);
|
|---|
| 1426 | }
|
|---|
| [d1b1380] | 1427 | }
|
|---|
| 1428 |
|
|---|
| [a420b49] | 1429 | static void
|
|---|
| [eb18f4d] | 1430 | cmd_units(void)
|
|---|
| [a420b49] | 1431 | {
|
|---|
| [5f1e194] | 1432 | int units, quantity;
|
|---|
| [6114207] | 1433 | unsigned long qmask;
|
|---|
| 1434 | unsigned long m; /* mask with bit x set to indicate quantity x specified */
|
|---|
| [5f1e194] | 1435 | real factor;
|
|---|
| [a420b49] | 1436 |
|
|---|
| [699bf50] | 1437 | qmask = get_qlist(BIT(Q_POS)|BIT(Q_PLUMB)|BIT(Q_LEVEL));
|
|---|
| 1438 |
|
|---|
| [647407d] | 1439 | if (!qmask) return;
|
|---|
| [a420b49] | 1440 | if (qmask == BIT(Q_DEFAULT)) {
|
|---|
| 1441 | default_units(pcs);
|
|---|
| [5f1e194] | 1442 | return;
|
|---|
| 1443 | }
|
|---|
| [a420b49] | 1444 |
|
|---|
| [21c226e] | 1445 | factor = read_numeric(fTrue, NULL);
|
|---|
| [fa42426] | 1446 | if (factor == 0.0) {
|
|---|
| [736f7df] | 1447 | /* TRANSLATORS: error message given by "*units tape 0 feet" - it’s
|
|---|
| 1448 | * meaningless to say your tape is marked in "0 feet" (but you might
|
|---|
| 1449 | * measure distance by counting knots on a diving line, and tie them
|
|---|
| 1450 | * every "2 feet"). */
|
|---|
| [da96015] | 1451 | compile_error_skip(-/**UNITS factor must be non-zero*/200);
|
|---|
| [fa42426] | 1452 | return;
|
|---|
| 1453 | }
|
|---|
| [a420b49] | 1454 |
|
|---|
| [fa42426] | 1455 | units = get_units(qmask, fTrue);
|
|---|
| [647407d] | 1456 | if (units == UNITS_NULL) return;
|
|---|
| [fa42426] | 1457 | if (TSTBIT(qmask, Q_GRADIENT))
|
|---|
| 1458 | pcs->f_clino_percent = (units == UNITS_PERCENT);
|
|---|
| 1459 | if (TSTBIT(qmask, Q_BACKGRADIENT))
|
|---|
| 1460 | pcs->f_backclino_percent = (units == UNITS_PERCENT);
|
|---|
| 1461 |
|
|---|
| [6eb50ab] | 1462 | if (factor == HUGE_REAL) {
|
|---|
| 1463 | factor = factor_tab[units];
|
|---|
| 1464 | } else {
|
|---|
| 1465 | factor *= factor_tab[units];
|
|---|
| 1466 | }
|
|---|
| [5f1e194] | 1467 |
|
|---|
| 1468 | for (quantity = 0, m = BIT(quantity); m <= qmask; quantity++, m <<= 1)
|
|---|
| 1469 | if (qmask & m) pcs->units[quantity] = factor;
|
|---|
| [d1b1380] | 1470 | }
|
|---|
| 1471 |
|
|---|
| [a420b49] | 1472 | static void
|
|---|
| [eb18f4d] | 1473 | cmd_calibrate(void)
|
|---|
| [a420b49] | 1474 | {
|
|---|
| [d6d3576] | 1475 | real sc, z;
|
|---|
| [67508f0] | 1476 | unsigned long qmask, m;
|
|---|
| [a420b49] | 1477 | int quantity;
|
|---|
| [46cb98f] | 1478 |
|
|---|
| [da96015] | 1479 | qmask = get_qlist(BIT(Q_POS)|BIT(Q_PLUMB)|BIT(Q_LEVEL));
|
|---|
| [46cb98f] | 1480 | if (!qmask) return; /* error already reported */
|
|---|
| 1481 |
|
|---|
| [a420b49] | 1482 | if (qmask == BIT(Q_DEFAULT)) {
|
|---|
| 1483 | default_calib(pcs);
|
|---|
| 1484 | return;
|
|---|
| 1485 | }
|
|---|
| [46cb98f] | 1486 |
|
|---|
| [a420b49] | 1487 | if (((qmask & LEN_QMASK)) && ((qmask & ANG_QMASK))) {
|
|---|
| [0b8c321] | 1488 | /* TRANSLATORS: e.g.
|
|---|
| 1489 | *
|
|---|
| 1490 | * *calibrate tape compass 1 1
|
|---|
| 1491 | */
|
|---|
| [ee7511a] | 1492 | compile_error_skip(/*Can’t calibrate angular and length quantities together*/227);
|
|---|
| [647407d] | 1493 | return;
|
|---|
| [a420b49] | 1494 | }
|
|---|
| [46cb98f] | 1495 |
|
|---|
| [21c226e] | 1496 | z = read_numeric(fFalse, NULL);
|
|---|
| 1497 | sc = read_numeric(fTrue, NULL);
|
|---|
| [a420b49] | 1498 | if (sc == HUGE_REAL) sc = (real)1.0;
|
|---|
| [647407d] | 1499 | /* check for declination scale */
|
|---|
| [3a33d12] | 1500 | /* perhaps "*calibrate declination XXX" should be "*declination XXX" ? */
|
|---|
| [95c3272] | 1501 | if (TSTBIT(qmask, Q_DECLINATION) && sc != 1.0) {
|
|---|
| [736f7df] | 1502 | /* TRANSLATORS: DECLINATION is a built-in keyword, so best not to
|
|---|
| 1503 | * translate */
|
|---|
| [da96015] | 1504 | compile_error_skip(-/*Scale factor must be 1.0 for DECLINATION*/40);
|
|---|
| [647407d] | 1505 | return;
|
|---|
| 1506 | }
|
|---|
| [4b14118] | 1507 | if (sc == 0.0) {
|
|---|
| [736f7df] | 1508 | /* TRANSLATORS: If the scale factor for an instrument is zero, then any
|
|---|
| 1509 | * reading would be mapped to zero, which doesn't make sense. */
|
|---|
| [da96015] | 1510 | compile_error_skip(-/*Scale factor must be non-zero*/391);
|
|---|
| [4b14118] | 1511 | return;
|
|---|
| 1512 | }
|
|---|
| [647407d] | 1513 | for (quantity = 0, m = BIT(quantity); m <= qmask; quantity++, m <<= 1) {
|
|---|
| [a420b49] | 1514 | if (qmask & m) {
|
|---|
| [647407d] | 1515 | pcs->z[quantity] = pcs->units[quantity] * z;
|
|---|
| [a420b49] | 1516 | pcs->sc[quantity] = sc;
|
|---|
| 1517 | }
|
|---|
| [647407d] | 1518 | }
|
|---|
| [d1b1380] | 1519 | }
|
|---|
| 1520 |
|
|---|
| [7f1ab95] | 1521 | #ifndef NO_DEPRECATED
|
|---|
| [a420b49] | 1522 | static void
|
|---|
| [eb18f4d] | 1523 | cmd_default(void)
|
|---|
| [a420b49] | 1524 | {
|
|---|
| [82919e07] | 1525 | static const sztok defaulttab[] = {
|
|---|
| [c0563da] | 1526 | { "CALIBRATE", CMD_CALIBRATE },
|
|---|
| 1527 | { "DATA", CMD_DATA },
|
|---|
| 1528 | { "UNITS", CMD_UNITS },
|
|---|
| [a4ae909] | 1529 | { NULL, CMD_NULL }
|
|---|
| [c0563da] | 1530 | };
|
|---|
| [c86cc71] | 1531 | static int default_depr_count = 0;
|
|---|
| 1532 |
|
|---|
| 1533 | if (default_depr_count < 5) {
|
|---|
| [736f7df] | 1534 | /* TRANSLATORS: If you're unsure what "deprecated" means, see:
|
|---|
| 1535 | * http://en.wikipedia.org/wiki/Deprecation */
|
|---|
| [da96015] | 1536 | compile_warning(-/**DEFAULT is deprecated - use *CALIBRATE/DATA/SD/UNITS with argument DEFAULT instead*/20);
|
|---|
| [c86cc71] | 1537 | if (++default_depr_count == 5)
|
|---|
| [c40038a] | 1538 | compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
|
|---|
| [c86cc71] | 1539 | }
|
|---|
| 1540 |
|
|---|
| [cb3d1e2] | 1541 | get_token();
|
|---|
| [c0563da] | 1542 | switch (match_tok(defaulttab, TABSIZE(defaulttab))) {
|
|---|
| 1543 | case CMD_CALIBRATE:
|
|---|
| [5f1e194] | 1544 | default_calib(pcs);
|
|---|
| [c0563da] | 1545 | break;
|
|---|
| 1546 | case CMD_DATA:
|
|---|
| [5f1e194] | 1547 | default_style(pcs);
|
|---|
| 1548 | default_grade(pcs);
|
|---|
| [c0563da] | 1549 | break;
|
|---|
| 1550 | case CMD_UNITS:
|
|---|
| [5f1e194] | 1551 | default_units(pcs);
|
|---|
| [c0563da] | 1552 | break;
|
|---|
| 1553 | default:
|
|---|
| [da96015] | 1554 | file.lpos += strlen(buffer);
|
|---|
| 1555 | compile_error_skip(-/*Unknown setting “%s”*/41, buffer);
|
|---|
| [5f1e194] | 1556 | }
|
|---|
| [d1b1380] | 1557 | }
|
|---|
| [7f1ab95] | 1558 | #endif
|
|---|
| [d1b1380] | 1559 |
|
|---|
| [a420b49] | 1560 | static void
|
|---|
| [eb18f4d] | 1561 | cmd_include(void)
|
|---|
| [a420b49] | 1562 | {
|
|---|
| [f97076a] | 1563 | char *pth, *fnm = NULL;
|
|---|
| [a420b49] | 1564 | int fnm_len;
|
|---|
| [a882316] | 1565 | #ifndef NO_DEPRECATED
|
|---|
| [5f1e194] | 1566 | prefix *root_store;
|
|---|
| [a882316] | 1567 | #endif
|
|---|
| [5f1e194] | 1568 | int ch_store;
|
|---|
| 1569 |
|
|---|
| [f97076a] | 1570 | pth = path_from_fnm(file.filename);
|
|---|
| 1571 |
|
|---|
| [a420b49] | 1572 | read_string(&fnm, &fnm_len);
|
|---|
| [d1b1380] | 1573 |
|
|---|
| [a882316] | 1574 | #ifndef NO_DEPRECATED
|
|---|
| 1575 | /* Since *begin / *end nesting cannot cross file boundaries we only
|
|---|
| 1576 | * need to preserve the prefix if the deprecated *prefix command
|
|---|
| 1577 | * can be used */
|
|---|
| [5f1e194] | 1578 | root_store = root;
|
|---|
| 1579 | root = pcs->Prefix; /* Root for include file is current prefix */
|
|---|
| [a882316] | 1580 | #endif
|
|---|
| [5f1e194] | 1581 | ch_store = ch;
|
|---|
| [cb3d1e2] | 1582 |
|
|---|
| [5f1e194] | 1583 | data_file(pth, fnm);
|
|---|
| [a420b49] | 1584 |
|
|---|
| [a882316] | 1585 | #ifndef NO_DEPRECATED
|
|---|
| [5f1e194] | 1586 | root = root_store; /* and restore root */
|
|---|
| [647407d] | 1587 | #endif
|
|---|
| [5f1e194] | 1588 | ch = ch_store;
|
|---|
| [d1b1380] | 1589 |
|
|---|
| [a420b49] | 1590 | s_free(&fnm);
|
|---|
| [f97076a] | 1591 | osfree(pth);
|
|---|
| [d1b1380] | 1592 | }
|
|---|
| 1593 |
|
|---|
| [a420b49] | 1594 | static void
|
|---|
| [eb18f4d] | 1595 | cmd_sd(void)
|
|---|
| [a420b49] | 1596 | {
|
|---|
| [5f1e194] | 1597 | real sd, variance;
|
|---|
| 1598 | int units;
|
|---|
| [67508f0] | 1599 | unsigned long qmask, m;
|
|---|
| [5f1e194] | 1600 | int quantity;
|
|---|
| [b14f44f] | 1601 | qmask = get_qlist(BIT(Q_DECLINATION));
|
|---|
| [46cb98f] | 1602 | if (!qmask) return; /* no quantities found - error already reported */
|
|---|
| 1603 |
|
|---|
| [a420b49] | 1604 | if (qmask == BIT(Q_DEFAULT)) {
|
|---|
| 1605 | default_grade(pcs);
|
|---|
| [5f1e194] | 1606 | return;
|
|---|
| 1607 | }
|
|---|
| [21c226e] | 1608 | sd = read_numeric(fFalse, NULL);
|
|---|
| [d6d3576] | 1609 | if (sd <= (real)0.0) {
|
|---|
| [da96015] | 1610 | compile_error_skip(-/*Standard deviation must be positive*/48);
|
|---|
| [d6d3576] | 1611 | return;
|
|---|
| [5f1e194] | 1612 | }
|
|---|
| [fa42426] | 1613 | units = get_units(qmask, fFalse);
|
|---|
| [647407d] | 1614 | if (units == UNITS_NULL) return;
|
|---|
| [5f1e194] | 1615 |
|
|---|
| 1616 | sd *= factor_tab[units];
|
|---|
| 1617 | variance = sqrd(sd);
|
|---|
| 1618 |
|
|---|
| 1619 | for (quantity = 0, m = BIT(quantity); m <= qmask; quantity++, m <<= 1)
|
|---|
| 1620 | if (qmask & m) pcs->Var[quantity] = variance;
|
|---|
| [d1b1380] | 1621 | }
|
|---|
| [5f1e194] | 1622 |
|
|---|
| [a420b49] | 1623 | static void
|
|---|
| [eb18f4d] | 1624 | cmd_title(void)
|
|---|
| [a420b49] | 1625 | {
|
|---|
| [1925d66] | 1626 | if (!fExplicitTitle && pcs->Prefix == root) {
|
|---|
| 1627 | /* If we don't have an explicit title yet, and we're currently in the
|
|---|
| 1628 | * root prefix, use this title explicitly. */
|
|---|
| [a420b49] | 1629 | fExplicitTitle = fTrue;
|
|---|
| 1630 | read_string(&survey_title, &survey_title_len);
|
|---|
| 1631 | } else {
|
|---|
| 1632 | /* parse and throw away this title (but still check rest of line) */
|
|---|
| 1633 | char *s = NULL;
|
|---|
| 1634 | int len;
|
|---|
| 1635 | read_string(&s, &len);
|
|---|
| 1636 | s_free(&s);
|
|---|
| 1637 | }
|
|---|
| 1638 | }
|
|---|
| 1639 |
|
|---|
| [82919e07] | 1640 | static const sztok case_tab[] = {
|
|---|
| [a420b49] | 1641 | {"PRESERVE", OFF},
|
|---|
| [c57e9da] | 1642 | {"TOLOWER", LOWER},
|
|---|
| 1643 | {"TOUPPER", UPPER},
|
|---|
| [a420b49] | 1644 | {NULL, -1}
|
|---|
| 1645 | };
|
|---|
| [cb3d1e2] | 1646 |
|
|---|
| [a420b49] | 1647 | static void
|
|---|
| [eb18f4d] | 1648 | cmd_case(void)
|
|---|
| [a420b49] | 1649 | {
|
|---|
| 1650 | int setting;
|
|---|
| 1651 | get_token();
|
|---|
| 1652 | setting = match_tok(case_tab, TABSIZE(case_tab));
|
|---|
| 1653 | if (setting != -1) {
|
|---|
| 1654 | pcs->Case = setting;
|
|---|
| 1655 | } else {
|
|---|
| [da96015] | 1656 | file.lpos += strlen(buffer);
|
|---|
| 1657 | compile_error_skip(-/*Found “%s”, expecting “PRESERVE”, “TOUPPER”, or “TOLOWER”*/10,
|
|---|
| 1658 | buffer);
|
|---|
| [a420b49] | 1659 | }
|
|---|
| 1660 | }
|
|---|
| 1661 |
|
|---|
| [abd0310] | 1662 | typedef enum {
|
|---|
| 1663 | CS_NONE = -1,
|
|---|
| 1664 | CS_CUSTOM,
|
|---|
| 1665 | CS_EPSG,
|
|---|
| 1666 | CS_ESRI,
|
|---|
| 1667 | CS_EUR,
|
|---|
| 1668 | CS_IJTSK,
|
|---|
| 1669 | CS_JTSK,
|
|---|
| 1670 | CS_LAT,
|
|---|
| 1671 | CS_LOCAL,
|
|---|
| 1672 | CS_LONG,
|
|---|
| 1673 | CS_OSGB,
|
|---|
| 1674 | CS_S_MERC,
|
|---|
| 1675 | CS_UTM
|
|---|
| 1676 | } cs_class;
|
|---|
| 1677 |
|
|---|
| [82919e07] | 1678 | static const sztok cs_tab[] = {
|
|---|
| [abd0310] | 1679 | {"CUSTOM", CS_CUSTOM},
|
|---|
| 1680 | {"EPSG", CS_EPSG}, /* EPSG:<number> */
|
|---|
| 1681 | {"ESRI", CS_ESRI}, /* ESRI:<number> */
|
|---|
| 1682 | {"EUR", CS_EUR}, /* EUR79Z30 */
|
|---|
| 1683 | {"IJTSK", CS_IJTSK}, /* IJTSK or IJTSK03 */
|
|---|
| 1684 | {"JTSK", CS_JTSK}, /* JTSK or JTSK03 */
|
|---|
| 1685 | {"LAT", CS_LAT}, /* LAT-LONG */
|
|---|
| 1686 | {"LOCAL", CS_LOCAL},
|
|---|
| 1687 | {"LONG", CS_LONG}, /* LONG-LAT */
|
|---|
| 1688 | {"OSGB", CS_OSGB}, /* OSGB:<H, N, O, S or T><A-Z except I> */
|
|---|
| 1689 | {"S", CS_S_MERC}, /* S-MERC */
|
|---|
| 1690 | {"UTM", CS_UTM}, /* UTM<zone><N or S or nothing> */
|
|---|
| 1691 | {NULL, CS_NONE}
|
|---|
| 1692 | };
|
|---|
| 1693 |
|
|---|
| 1694 | static void
|
|---|
| 1695 | cmd_cs(void)
|
|---|
| 1696 | {
|
|---|
| [e755560] | 1697 | char * proj_str = NULL;
|
|---|
| [abd0310] | 1698 | int proj_str_len;
|
|---|
| 1699 | cs_class cs;
|
|---|
| 1700 | int cs_sub = INT_MIN;
|
|---|
| 1701 | filepos fp;
|
|---|
| [c092d72] | 1702 | bool output = fFalse;
|
|---|
| 1703 | enum { YES, NO, MAYBE } ok_for_output = YES;
|
|---|
| [56db37f] | 1704 | static bool had_cs = fFalse;
|
|---|
| 1705 |
|
|---|
| 1706 | if (!had_cs) {
|
|---|
| 1707 | had_cs = fTrue;
|
|---|
| 1708 | if (first_fix_name) {
|
|---|
| 1709 | compile_error_at(first_fix_filename, first_fix_line,
|
|---|
| 1710 | /*Station “%s” fixed before CS command first used*/442,
|
|---|
| 1711 | sprint_prefix(first_fix_name));
|
|---|
| 1712 | }
|
|---|
| 1713 | }
|
|---|
| [abd0310] | 1714 |
|
|---|
| 1715 | get_pos(&fp);
|
|---|
| [acf82004] | 1716 | /* Note get_token() only accepts letters - it'll stop at digits so "UTM12"
|
|---|
| [abd0310] | 1717 | * will give token "UTM". */
|
|---|
| 1718 | get_token();
|
|---|
| [c092d72] | 1719 | if (strcmp(ucbuffer, "OUT") == 0) {
|
|---|
| 1720 | output = fTrue;
|
|---|
| 1721 | get_token();
|
|---|
| 1722 | }
|
|---|
| [abd0310] | 1723 | cs = match_tok(cs_tab, TABSIZE(cs_tab));
|
|---|
| 1724 | switch (cs) {
|
|---|
| 1725 | case CS_NONE:
|
|---|
| 1726 | break;
|
|---|
| 1727 | case CS_CUSTOM:
|
|---|
| [c092d72] | 1728 | ok_for_output = MAYBE;
|
|---|
| [abd0310] | 1729 | read_string(&proj_str, &proj_str_len);
|
|---|
| [c092d72] | 1730 | cs_sub = 0;
|
|---|
| [abd0310] | 1731 | break;
|
|---|
| 1732 | case CS_EPSG: case CS_ESRI:
|
|---|
| [c092d72] | 1733 | ok_for_output = MAYBE;
|
|---|
| [abd0310] | 1734 | if (ch == ':' && isdigit(nextch())) {
|
|---|
| 1735 | unsigned n = read_uint();
|
|---|
| [ddd24f28] | 1736 | if (n < 1000000) {
|
|---|
| [abd0310] | 1737 | cs_sub = (int)n;
|
|---|
| 1738 | }
|
|---|
| 1739 | }
|
|---|
| 1740 | break;
|
|---|
| 1741 | case CS_EUR:
|
|---|
| 1742 | if (isdigit(ch) &&
|
|---|
| 1743 | read_uint() == 79 &&
|
|---|
| 1744 | (ch == 'Z' || ch == 'z') &&
|
|---|
| 1745 | isdigit(nextch()) &&
|
|---|
| 1746 | read_uint() == 30) {
|
|---|
| 1747 | cs_sub = 7930;
|
|---|
| 1748 | }
|
|---|
| 1749 | break;
|
|---|
| [c092d72] | 1750 | case CS_JTSK:
|
|---|
| 1751 | ok_for_output = NO;
|
|---|
| 1752 | /* FALLTHRU */
|
|---|
| 1753 | case CS_IJTSK:
|
|---|
| [abd0310] | 1754 | if (ch == '0') {
|
|---|
| 1755 | if (nextch() == '3') {
|
|---|
| 1756 | nextch();
|
|---|
| 1757 | cs_sub = 3;
|
|---|
| 1758 | }
|
|---|
| 1759 | } else {
|
|---|
| 1760 | cs_sub = 0;
|
|---|
| 1761 | }
|
|---|
| 1762 | break;
|
|---|
| 1763 | case CS_LAT: case CS_LONG:
|
|---|
| [c092d72] | 1764 | ok_for_output = NO;
|
|---|
| [abd0310] | 1765 | if (ch == '-') {
|
|---|
| 1766 | nextch();
|
|---|
| 1767 | get_token_no_blanks();
|
|---|
| 1768 | cs_class cs2 = match_tok(cs_tab, TABSIZE(cs_tab));
|
|---|
| [f21d797] | 1769 | if ((cs ^ cs2) == (CS_LAT ^ CS_LONG)) {
|
|---|
| [abd0310] | 1770 | cs_sub = 0;
|
|---|
| 1771 | }
|
|---|
| 1772 | }
|
|---|
| 1773 | break;
|
|---|
| 1774 | case CS_LOCAL:
|
|---|
| 1775 | cs_sub = 0;
|
|---|
| 1776 | break;
|
|---|
| 1777 | case CS_OSGB:
|
|---|
| 1778 | if (ch == ':') {
|
|---|
| 1779 | int uch1 = toupper(nextch());
|
|---|
| 1780 | if (strchr("HNOST", uch1)) {
|
|---|
| 1781 | int uch2 = toupper(nextch());
|
|---|
| 1782 | if (uch2 >= 'A' && uch2 <= 'Z' && uch2 != 'I') {
|
|---|
| [a4cd4eea] | 1783 | int x, y;
|
|---|
| [abd0310] | 1784 | nextch();
|
|---|
| [a4cd4eea] | 1785 | if (uch1 > 'I') --uch1;
|
|---|
| 1786 | uch1 -= 'A';
|
|---|
| [abd0310] | 1787 | if (uch2 > 'I') --uch2;
|
|---|
| [a4cd4eea] | 1788 | uch2 -= 'A';
|
|---|
| 1789 | x = uch1 % 5;
|
|---|
| 1790 | y = uch1 / 5;
|
|---|
| 1791 | x = (x * 5) + uch2 % 5;
|
|---|
| 1792 | y = (y * 5) + uch2 / 5;
|
|---|
| 1793 | cs_sub = y * 25 + x;
|
|---|
| [abd0310] | 1794 | }
|
|---|
| 1795 | }
|
|---|
| 1796 | }
|
|---|
| 1797 | break;
|
|---|
| 1798 | case CS_S_MERC:
|
|---|
| 1799 | if (ch == '-') {
|
|---|
| [2076d59] | 1800 | nextch();
|
|---|
| [abd0310] | 1801 | get_token_no_blanks();
|
|---|
| 1802 | if (strcmp(ucbuffer, "MERC") == 0) {
|
|---|
| 1803 | cs_sub = 0;
|
|---|
| 1804 | }
|
|---|
| 1805 | }
|
|---|
| 1806 | break;
|
|---|
| 1807 | case CS_UTM:
|
|---|
| 1808 | if (isdigit(ch)) {
|
|---|
| 1809 | unsigned n = read_uint();
|
|---|
| 1810 | if (n >= 1 && n <= 60) {
|
|---|
| 1811 | int uch = toupper(ch);
|
|---|
| 1812 | cs_sub = (int)n;
|
|---|
| 1813 | if (uch == 'S') {
|
|---|
| 1814 | nextch();
|
|---|
| 1815 | cs_sub = -cs_sub;
|
|---|
| 1816 | } else if (uch == 'N') {
|
|---|
| 1817 | nextch();
|
|---|
| 1818 | }
|
|---|
| 1819 | }
|
|---|
| 1820 | }
|
|---|
| 1821 | break;
|
|---|
| 1822 | }
|
|---|
| 1823 | if (cs_sub == INT_MIN || isalnum(ch)) {
|
|---|
| 1824 | set_pos(&fp);
|
|---|
| 1825 | compile_error_skip(-/*Unknown coordinate system*/434);
|
|---|
| [c092d72] | 1826 | return;
|
|---|
| [abd0310] | 1827 | }
|
|---|
| 1828 | /* Actually handle the cs */
|
|---|
| [c092d72] | 1829 | switch (cs) {
|
|---|
| [5d36f97] | 1830 | case CS_NONE:
|
|---|
| 1831 | break;
|
|---|
| 1832 | case CS_CUSTOM:
|
|---|
| 1833 | /* proj_str already set */
|
|---|
| 1834 | break;
|
|---|
| [ddd24f28] | 1835 | case CS_EPSG:
|
|---|
| 1836 | proj_str = osmalloc(32);
|
|---|
| 1837 | sprintf(proj_str, "+init=epsg:%d +no_defs", cs_sub);
|
|---|
| 1838 | break;
|
|---|
| 1839 | case CS_ESRI:
|
|---|
| 1840 | proj_str = osmalloc(32);
|
|---|
| 1841 | sprintf(proj_str, "+init=esri:%d +no_defs", cs_sub);
|
|---|
| 1842 | break;
|
|---|
| 1843 | case CS_EUR:
|
|---|
| 1844 | proj_str = osstrdup("+proj=utm +zone=30 +ellps=intl +towgs84=-86,-98,-119,0,0,0,0 +no_defs");
|
|---|
| 1845 | break;
|
|---|
| [5598e2c] | 1846 | case CS_IJTSK:
|
|---|
| 1847 | if (cs_sub == 0)
|
|---|
| 1848 | proj_str = osstrdup("+proj=krovak +ellps=bessel +towgs84=570.8285,85.6769,462.842,4.9984,1.5867,5.2611,3.5623 +no_defs");
|
|---|
| 1849 | else
|
|---|
| 1850 | proj_str = osstrdup("+proj=krovak +ellps=bessel +towgs84=485.021,169.465,483.839,7.786342,4.397554,4.102655,0 +no_defs");
|
|---|
| 1851 | break;
|
|---|
| [10af28e] | 1852 | case CS_JTSK:
|
|---|
| 1853 | if (cs_sub == 0)
|
|---|
| 1854 | proj_str = osstrdup("+proj=krovak +czech +ellps=bessel +towgs84=570.8285,85.6769,462.842,4.9984,1.5867,5.2611,3.5623 +no_defs");
|
|---|
| 1855 | else
|
|---|
| 1856 | proj_str = osstrdup("+proj=krovak +czech +ellps=bessel +towgs84=485.021,169.465,483.839,7.786342,4.397554,4.102655,0 +no_defs");
|
|---|
| 1857 | break;
|
|---|
| [16734b2] | 1858 | case CS_LAT:
|
|---|
| 1859 | /* FIXME: Requires PROJ >= 4.8.0 for +axis, and the SDs will be
|
|---|
| [10af28e] | 1860 | * misapplied, so we may want to swap ourselves. Also, while
|
|---|
| 1861 | * therion supports lat-long, I'm not totally convinced that it is
|
|---|
| 1862 | * sensible to do so - people often say "lat-long", but probably
|
|---|
| 1863 | * don't think that that's actually "Northing, Easting". This
|
|---|
| 1864 | * seems like it'll result in people accidentally getting X and Y
|
|---|
| 1865 | * swapped in their fixed points...
|
|---|
| 1866 | */
|
|---|
| [5d36f97] | 1867 | #if 0
|
|---|
| [cb0a137] | 1868 | proj_str = osstrdup("+proj=longlat +ellps=WGS84 +datum=WGS84 +axis=neu +no_defs");
|
|---|
| [5d36f97] | 1869 | #endif
|
|---|
| [16734b2] | 1870 | break;
|
|---|
| [10af28e] | 1871 | case CS_LOCAL:
|
|---|
| 1872 | /* FIXME: Is it useful to be able to explicitly specify this? */
|
|---|
| 1873 | break;
|
|---|
| [16734b2] | 1874 | case CS_LONG:
|
|---|
| [cb0a137] | 1875 | proj_str = osstrdup("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
|
|---|
| [16734b2] | 1876 | break;
|
|---|
| [a4cd4eea] | 1877 | case CS_OSGB: {
|
|---|
| 1878 | int x = 14 - (cs_sub % 25);
|
|---|
| 1879 | int y = (cs_sub / 25) - 20;
|
|---|
| 1880 | proj_str = osmalloc(160);
|
|---|
| 1881 | sprintf(proj_str, "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=%d +y_0=%d +ellps=airy +datum=OSGB36 +units=m +no_defs", x * 100000, y * 100000);
|
|---|
| 1882 | break;
|
|---|
| 1883 | }
|
|---|
| [2076d59] | 1884 | case CS_S_MERC:
|
|---|
| [7ed1380] | 1885 | proj_str = osstrdup("+proj=merc +lat_ts=0 +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +units=m +nadgrids=@null +no_defs");
|
|---|
| [2076d59] | 1886 | break;
|
|---|
| [c092d72] | 1887 | case CS_UTM:
|
|---|
| [cb0a137] | 1888 | proj_str = osmalloc(74);
|
|---|
| [c092d72] | 1889 | if (cs_sub > 0) {
|
|---|
| [cb0a137] | 1890 | sprintf(proj_str, "+proj=utm +ellps=WGS84 +datum=WGS84 +units=m +zone=%d +no_defs", cs_sub);
|
|---|
| [c092d72] | 1891 | } else {
|
|---|
| [cb0a137] | 1892 | sprintf(proj_str, "+proj=utm +ellps=WGS84 +datum=WGS84 +units=m +zone=%d +south +no_defs", -cs_sub);
|
|---|
| [c092d72] | 1893 | }
|
|---|
| 1894 | break;
|
|---|
| 1895 | }
|
|---|
| 1896 |
|
|---|
| [10af28e] | 1897 | if (!proj_str) {
|
|---|
| 1898 | /* printf("CS %d:%d\n", (int)cs, cs_sub); */
|
|---|
| 1899 | set_pos(&fp);
|
|---|
| 1900 | compile_error_skip(-/*Unknown coordinate system*/434);
|
|---|
| 1901 | return;
|
|---|
| 1902 | }
|
|---|
| 1903 |
|
|---|
| [c092d72] | 1904 | if (output) {
|
|---|
| 1905 | if (ok_for_output == NO) {
|
|---|
| 1906 | set_pos(&fp);
|
|---|
| 1907 | compile_error_skip(-/*Coordinate system unsuitable for output*/435);
|
|---|
| 1908 | return;
|
|---|
| 1909 | }
|
|---|
| 1910 |
|
|---|
| 1911 | /* If the output projection is already set, we still need to create the
|
|---|
| 1912 | * projection object for a custom projection, so we can report errors.
|
|---|
| 1913 | * But if the string is identical, we know it's valid.
|
|---|
| 1914 | */
|
|---|
| 1915 | if (!proj_out ||
|
|---|
| 1916 | (ok_for_output == MAYBE && strcmp(proj_str, proj_str_out) != 0)) {
|
|---|
| 1917 | projPJ pj = pj_init_plus(proj_str);
|
|---|
| 1918 | if (!pj) {
|
|---|
| 1919 | set_pos(&fp);
|
|---|
| [5b107ee] | 1920 | compile_error_skip(-/*Invalid coordinate system: %s*/443,
|
|---|
| 1921 | pj_strerrno(pj_errno));
|
|---|
| [c092d72] | 1922 | return;
|
|---|
| 1923 | }
|
|---|
| 1924 | if (ok_for_output == MAYBE && pj_is_latlong(pj)) {
|
|---|
| 1925 | compile_error_skip(-/*Coordinate system unsuitable for output*/435);
|
|---|
| 1926 | return;
|
|---|
| 1927 | }
|
|---|
| 1928 | if (proj_out) {
|
|---|
| 1929 | pj_free(pj);
|
|---|
| 1930 | osfree(proj_str);
|
|---|
| 1931 | } else {
|
|---|
| 1932 | proj_out = pj;
|
|---|
| 1933 | proj_str_out = proj_str;
|
|---|
| 1934 | }
|
|---|
| 1935 | }
|
|---|
| 1936 | } else {
|
|---|
| 1937 | projPJ pj;
|
|---|
| 1938 | if (proj_str_out && strcmp(proj_str, proj_str_out) == 0) {
|
|---|
| 1939 | /* Same as the current output projection. */
|
|---|
| 1940 | pj = proj_out;
|
|---|
| 1941 | } else {
|
|---|
| 1942 | pj = pj_init_plus(proj_str);
|
|---|
| 1943 | if (!pj) {
|
|---|
| 1944 | set_pos(&fp);
|
|---|
| [5b107ee] | 1945 | compile_error_skip(-/*Invalid coordinate system: %s*/443,
|
|---|
| 1946 | pj_strerrno(pj_errno));
|
|---|
| [c092d72] | 1947 | return;
|
|---|
| 1948 | }
|
|---|
| 1949 | }
|
|---|
| 1950 |
|
|---|
| 1951 | /* Free proj if not used by parent, or as the output projection. */
|
|---|
| 1952 | settings * p = pcs;
|
|---|
| 1953 | if (p->proj && (!p->next || p->proj != p->next->proj))
|
|---|
| 1954 | if (p->proj != proj_out)
|
|---|
| 1955 | pj_free(p->proj);
|
|---|
| 1956 | p->proj = pj;
|
|---|
| 1957 | }
|
|---|
| [abd0310] | 1958 | }
|
|---|
| 1959 |
|
|---|
| [82919e07] | 1960 | static const sztok infer_tab[] = {
|
|---|
| [27b8b59] | 1961 | { "EQUATES", INFER_EQUATES },
|
|---|
| 1962 | { "EXPORTS", INFER_EXPORTS },
|
|---|
| 1963 | { "PLUMBS", INFER_PLUMBS },
|
|---|
| 1964 | #if 0 /* FIXME */
|
|---|
| 1965 | { "SUBSURVEYS", INFER_SUBSURVEYS },
|
|---|
| 1966 | #endif
|
|---|
| 1967 | { NULL, INFER_NULL }
|
|---|
| [a420b49] | 1968 | };
|
|---|
| [cb3d1e2] | 1969 |
|
|---|
| [82919e07] | 1970 | static const sztok onoff_tab[] = {
|
|---|
| [27b8b59] | 1971 | { "OFF", 0 },
|
|---|
| 1972 | { "ON", 1 },
|
|---|
| 1973 | { NULL, -1 }
|
|---|
| [a420b49] | 1974 | };
|
|---|
| [cb3d1e2] | 1975 |
|
|---|
| [a420b49] | 1976 | static void
|
|---|
| [eb18f4d] | 1977 | cmd_infer(void)
|
|---|
| [a420b49] | 1978 | {
|
|---|
| [27b8b59] | 1979 | infer_what setting;
|
|---|
| [a420b49] | 1980 | int on;
|
|---|
| 1981 | get_token();
|
|---|
| 1982 | setting = match_tok(infer_tab, TABSIZE(infer_tab));
|
|---|
| [27b8b59] | 1983 | if (setting == INFER_NULL) {
|
|---|
| [da96015] | 1984 | file.lpos += strlen(buffer);
|
|---|
| 1985 | compile_error_skip(-/*Found “%s”, expecting “EQUATES”, “EXPORTS”, or “PLUMBS”*/31, buffer);
|
|---|
| [647407d] | 1986 | return;
|
|---|
| [a420b49] | 1987 | }
|
|---|
| 1988 | get_token();
|
|---|
| 1989 | on = match_tok(onoff_tab, TABSIZE(onoff_tab));
|
|---|
| 1990 | if (on == -1) {
|
|---|
| [da96015] | 1991 | file.lpos += strlen(buffer);
|
|---|
| 1992 | compile_error_skip(-/*Found “%s”, expecting “ON” or “OFF”*/32, buffer);
|
|---|
| [647407d] | 1993 | return;
|
|---|
| [a420b49] | 1994 | }
|
|---|
| [cb3d1e2] | 1995 |
|
|---|
| [27b8b59] | 1996 | if (on) {
|
|---|
| 1997 | pcs->infer |= BIT(setting);
|
|---|
| 1998 | if (setting == INFER_EXPORTS) fExportUsed = fTrue;
|
|---|
| 1999 | } else {
|
|---|
| 2000 | pcs->infer &= ~BIT(setting);
|
|---|
| [a420b49] | 2001 | }
|
|---|
| 2002 | }
|
|---|
| 2003 |
|
|---|
| 2004 | static void
|
|---|
| [eb18f4d] | 2005 | cmd_truncate(void)
|
|---|
| [a420b49] | 2006 | {
|
|---|
| [647407d] | 2007 | unsigned int truncate_at = 0; /* default is no truncation */
|
|---|
| [c80bd34] | 2008 | filepos fp;
|
|---|
| 2009 |
|
|---|
| 2010 | get_pos(&fp);
|
|---|
| 2011 |
|
|---|
| [647407d] | 2012 | get_token();
|
|---|
| 2013 | if (strcmp(ucbuffer, "OFF") != 0) {
|
|---|
| [c80bd34] | 2014 | if (*ucbuffer) set_pos(&fp);
|
|---|
| [647407d] | 2015 | truncate_at = read_uint();
|
|---|
| 2016 | }
|
|---|
| 2017 | /* for backward compatibility, "*truncate 0" means "*truncate off" */
|
|---|
| 2018 | pcs->Truncate = (truncate_at == 0) ? INT_MAX : truncate_at;
|
|---|
| 2019 | }
|
|---|
| 2020 |
|
|---|
| 2021 | static void
|
|---|
| [eb18f4d] | 2022 | cmd_require(void)
|
|---|
| [647407d] | 2023 | {
|
|---|
| [e2546c0] | 2024 | const unsigned int version[] = {COMMAVERSION};
|
|---|
| 2025 | const unsigned int *ver = version;
|
|---|
| [c80bd34] | 2026 | filepos fp;
|
|---|
| 2027 |
|
|---|
| [69c920d] | 2028 | skipblanks();
|
|---|
| [c80bd34] | 2029 | get_pos(&fp);
|
|---|
| [647407d] | 2030 | while (1) {
|
|---|
| [e2546c0] | 2031 | int diff = *ver++ - read_uint();
|
|---|
| 2032 | if (diff > 0) break;
|
|---|
| 2033 | if (diff < 0) {
|
|---|
| [647407d] | 2034 | size_t i, len;
|
|---|
| 2035 | char *v;
|
|---|
| [c80bd34] | 2036 | filepos fp_tmp;
|
|---|
| 2037 |
|
|---|
| [647407d] | 2038 | /* find end of version number */
|
|---|
| 2039 | while (isdigit(ch) || ch == '.') nextch();
|
|---|
| [c80bd34] | 2040 | get_pos(&fp_tmp);
|
|---|
| 2041 | len = (size_t)(fp_tmp.offset - fp.offset);
|
|---|
| [647407d] | 2042 | v = osmalloc(len + 1);
|
|---|
| [c80bd34] | 2043 | set_pos(&fp);
|
|---|
| [647407d] | 2044 | for (i = 0; i < len; i++) {
|
|---|
| 2045 | v[i] = ch;
|
|---|
| [69c920d] | 2046 | nextch();
|
|---|
| 2047 | }
|
|---|
| [647407d] | 2048 | v[i] = '\0';
|
|---|
| [736f7df] | 2049 | /* TRANSLATORS: Feel free to translate as "or newer" instead of "or
|
|---|
| 2050 | * greater" if that gives a more natural translation. It's
|
|---|
| 2051 | * technically not quite right when there are parallel active release
|
|---|
| 2052 | * series (e.g. Survex 1.0.40 was released *after* 1.2.0), but this
|
|---|
| [0b8c321] | 2053 | * seems unlikely to confuse users. "Survex" is the name of the
|
|---|
| 2054 | * software, so should not be translated.
|
|---|
| 2055 | *
|
|---|
| 2056 | * Here "survey" is a "cave map" rather than list of questions - it should be
|
|---|
| 2057 | * translated to the terminology that cavers using the language would use.
|
|---|
| 2058 | */
|
|---|
| [647407d] | 2059 | fatalerror_in_file(file.filename, file.line, /*Survex version %s or greater required to process this survey data.*/2, v);
|
|---|
| 2060 | }
|
|---|
| 2061 | if (ch != '.') break;
|
|---|
| 2062 | nextch();
|
|---|
| [e2546c0] | 2063 | if (!isdigit(ch) || ver == version + sizeof(version)) break;
|
|---|
| [69c920d] | 2064 | }
|
|---|
| [647407d] | 2065 | /* skip rest of version number */
|
|---|
| 2066 | while (isdigit(ch) || ch == '.') nextch();
|
|---|
| [a420b49] | 2067 | }
|
|---|
| 2068 |
|
|---|
| [b5a3219] | 2069 | /* allocate new meta_data if need be */
|
|---|
| 2070 | void
|
|---|
| 2071 | copy_on_write_meta(settings *s)
|
|---|
| 2072 | {
|
|---|
| 2073 | if (!s->meta || s->meta->ref_count != 0) {
|
|---|
| 2074 | meta_data * meta_new = osnew(meta_data);
|
|---|
| 2075 | if (!s->meta) {
|
|---|
| [1ee204e] | 2076 | meta_new->days1 = meta_new->days2 = -1;
|
|---|
| [b5a3219] | 2077 | } else {
|
|---|
| 2078 | *meta_new = *(s->meta);
|
|---|
| 2079 | }
|
|---|
| 2080 | meta_new->ref_count = 0;
|
|---|
| 2081 | s->meta = meta_new;
|
|---|
| 2082 | }
|
|---|
| 2083 | }
|
|---|
| 2084 |
|
|---|
| [950a829] | 2085 | static void
|
|---|
| 2086 | cmd_date(void)
|
|---|
| [421b7d2] | 2087 | {
|
|---|
| [e0c7cd1] | 2088 | int year, month, day;
|
|---|
| [1ee204e] | 2089 | int days1, days2;
|
|---|
| 2090 | bool implicit_range = fFalse;
|
|---|
| [e0c7cd1] | 2091 |
|
|---|
| 2092 | read_date(&year, &month, &day);
|
|---|
| [1ee204e] | 2093 | days1 = days_since_1900(year, month ? month : 1, day ? day : 1);
|
|---|
| 2094 |
|
|---|
| 2095 | if (days1 > current_days_since_1900) {
|
|---|
| [da96015] | 2096 | compile_warning(-/*Date is in the future!*/80);
|
|---|
| [e0c7cd1] | 2097 | }
|
|---|
| 2098 |
|
|---|
| 2099 | skipblanks();
|
|---|
| 2100 | if (ch == '-') {
|
|---|
| 2101 | nextch();
|
|---|
| 2102 | read_date(&year, &month, &day);
|
|---|
| 2103 | } else {
|
|---|
| [1ee204e] | 2104 | if (month && day) {
|
|---|
| 2105 | days2 = days1;
|
|---|
| 2106 | goto read;
|
|---|
| 2107 | }
|
|---|
| 2108 | implicit_range = fTrue;
|
|---|
| 2109 | }
|
|---|
| 2110 |
|
|---|
| 2111 | if (month == 0) month = 12;
|
|---|
| 2112 | if (day == 0) day = last_day(year, month);
|
|---|
| 2113 | days2 = days_since_1900(year, month, day);
|
|---|
| 2114 |
|
|---|
| 2115 | if (!implicit_range && days2 > current_days_since_1900) {
|
|---|
| [da96015] | 2116 | compile_warning(-/*Date is in the future!*/80);
|
|---|
| [e0c7cd1] | 2117 | }
|
|---|
| [1ee204e] | 2118 |
|
|---|
| 2119 | if (days2 < days1) {
|
|---|
| [da96015] | 2120 | compile_error(-/*End of date range is before the start*/81);
|
|---|
| [1ee204e] | 2121 | }
|
|---|
| [e0c7cd1] | 2122 |
|
|---|
| [1ee204e] | 2123 | read:
|
|---|
| [e0c7cd1] | 2124 | copy_on_write_meta(pcs);
|
|---|
| [1ee204e] | 2125 | pcs->meta->days1 = days1;
|
|---|
| 2126 | pcs->meta->days2 = days2;
|
|---|
| [950a829] | 2127 | }
|
|---|
| 2128 |
|
|---|
| [3aafcee] | 2129 | typedef void (*cmd_fn)(void);
|
|---|
| 2130 |
|
|---|
| [82919e07] | 2131 | static const cmd_fn cmd_funcs[] = {
|
|---|
| [dcbcae0] | 2132 | cmd_alias,
|
|---|
| [3aafcee] | 2133 | cmd_begin,
|
|---|
| 2134 | cmd_calibrate,
|
|---|
| 2135 | cmd_case,
|
|---|
| 2136 | skipline, /*cmd_copyright,*/
|
|---|
| [abd0310] | 2137 | cmd_cs,
|
|---|
| [3aafcee] | 2138 | cmd_data,
|
|---|
| [950a829] | 2139 | cmd_date,
|
|---|
| [7f1ab95] | 2140 | #ifndef NO_DEPRECATED
|
|---|
| [3aafcee] | 2141 | cmd_default,
|
|---|
| [7f1ab95] | 2142 | #endif
|
|---|
| [3aafcee] | 2143 | cmd_end,
|
|---|
| 2144 | cmd_entrance,
|
|---|
| 2145 | cmd_equate,
|
|---|
| 2146 | cmd_export,
|
|---|
| 2147 | cmd_fix,
|
|---|
| 2148 | cmd_flags,
|
|---|
| 2149 | cmd_include,
|
|---|
| 2150 | cmd_infer,
|
|---|
| 2151 | skipline, /*cmd_instrument,*/
|
|---|
| [7f1ab95] | 2152 | #ifndef NO_DEPRECATED
|
|---|
| [3aafcee] | 2153 | cmd_prefix,
|
|---|
| [7f1ab95] | 2154 | #endif
|
|---|
| [3aafcee] | 2155 | cmd_require,
|
|---|
| 2156 | cmd_sd,
|
|---|
| 2157 | cmd_set,
|
|---|
| 2158 | solve_network,
|
|---|
| 2159 | skipline, /*cmd_team,*/
|
|---|
| 2160 | cmd_title,
|
|---|
| 2161 | cmd_truncate,
|
|---|
| 2162 | cmd_units
|
|---|
| 2163 | };
|
|---|
| 2164 |
|
|---|
| [a420b49] | 2165 | extern void
|
|---|
| 2166 | handle_command(void)
|
|---|
| 2167 | {
|
|---|
| [932f7e9] | 2168 | int cmdtok;
|
|---|
| [a420b49] | 2169 | get_token();
|
|---|
| [932f7e9] | 2170 | cmdtok = match_tok(cmd_tab, TABSIZE(cmd_tab));
|
|---|
| 2171 |
|
|---|
| [3aafcee] | 2172 | if (cmdtok < 0 || cmdtok >= (int)(sizeof(cmd_funcs) / sizeof(cmd_fn))) {
|
|---|
| [da96015] | 2173 | file.lpos += strlen(buffer);
|
|---|
| 2174 | compile_error_skip(-/*Unknown command “%s”*/12, buffer);
|
|---|
| [3aafcee] | 2175 | return;
|
|---|
| [932f7e9] | 2176 | }
|
|---|
| 2177 |
|
|---|
| 2178 | switch (cmdtok) {
|
|---|
| [3aafcee] | 2179 | case CMD_EXPORT:
|
|---|
| 2180 | if (!f_export_ok)
|
|---|
| [736f7df] | 2181 | /* TRANSLATORS: The *EXPORT command is only valid just after *BEGIN
|
|---|
| 2182 | * <SURVEY>, so this would generate this error:
|
|---|
| 2183 | *
|
|---|
| 2184 | * *begin fred
|
|---|
| 2185 | * 1 2 1.23 045 -6
|
|---|
| 2186 | * *export 2
|
|---|
| 2187 | * *end fred */
|
|---|
| [0804fbe] | 2188 | compile_error(/**EXPORT must immediately follow “*BEGIN <SURVEY>”*/57);
|
|---|
| [3aafcee] | 2189 | break;
|
|---|
| 2190 | case CMD_COPYRIGHT:
|
|---|
| 2191 | case CMD_DATE:
|
|---|
| 2192 | case CMD_INSTRUMENT:
|
|---|
| 2193 | case CMD_TEAM:
|
|---|
| 2194 | case CMD_TITLE:
|
|---|
| [4dcd3af] | 2195 | /* These can occur between *begin and *export */
|
|---|
| [421b7d2] | 2196 | break;
|
|---|
| [a420b49] | 2197 | default:
|
|---|
| [4dcd3af] | 2198 | /* NB: additional handling for "*begin <survey>" in cmd_begin */
|
|---|
| [3aafcee] | 2199 | f_export_ok = fFalse;
|
|---|
| 2200 | break;
|
|---|
| [647407d] | 2201 | }
|
|---|
| [421b7d2] | 2202 |
|
|---|
| [3aafcee] | 2203 | cmd_funcs[cmdtok]();
|
|---|
| [5f1e194] | 2204 | }
|
|---|