source: git/src/diffpos.c@ fb93f7e

RELEASE/1.0 RELEASE/1.1 RELEASE/1.2 debug-ci debug-ci-sanitisers faster-cavernlog log-select main stereo stereo-2025 walls-data walls-data-hanging-as-warning warn-only-for-hanging-survey
Last change on this file since fb93f7e was 3262009, checked in by Olly Betts <olly@…>, 25 years ago

diffpos: the arguments can now be .pos or .3d files, or one of each.

git-svn-id: file:///home/survex-svn/survex/trunk@1098 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/* > diffpos.c */
2/* Utility to compare two SURVEX .pos or .3d files */
3/* Copyright (C) 1994,1996,1998,1999,2001 Olly Betts
4 *
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.
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
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <math.h>
28
29#include "cavern.h" /* just for REAL_EPSILON */
30#include "cmdline.h"
31#include "debug.h"
32#include "filelist.h"
33#include "img.h"
34
35#ifndef sqrd
36# define sqrd(X) ((X)*(X))
37#endif
38
39/* macro to just convert argument to a string */
40#define STRING(X) _STRING(X)
41#define _STRING(X) #X
42
43/* very small value for comparing floating point numbers with */
44#define EPSILON (REAL_EPSILON * 1000)
45
46/* default threshold is 1cm */
47#define DFLT_MAX_THRESHOLD 0.01
48
49static double threshold = DFLT_MAX_THRESHOLD;
50
51static const struct option long_opts[] = {
52 /* const char *name; int has_arg (0 no_argument, 1 required_*, 2 optional_*); int *flag; int val; */
53 {"help", no_argument, 0, HLP_HELP},
54 {"version", no_argument, 0, HLP_VERSION},
55 {0, 0, 0, 0}
56};
57
58#define short_opts ""
59
60static struct help_msg help[] = {
61/* <-- */
62 {0, 0}
63};
64
65/* some (preferably prime) number for the hashing function */
66#define HASH_PRIME 29363
67
68typedef struct station {
69 struct station *next;
70 char *name;
71 img_point pt;
72} station;
73
74static int
75hash_string(const char *p)
76{
77 int hash;
78 ASSERT(p != NULL); /* can't hash NULL */
79/* printf("HASH `%s' to ",p); */
80 for (hash = 0; *p; p++)
81 hash = (hash * HASH_PRIME + tolower(*(unsigned char*)p)) & 0x7fff;
82/* printf("%d\n",hash); */
83 return hash;
84}
85
86static station **htab;
87static bool fChanged = fFalse;
88
89static void
90tree_init(void)
91{
92 size_t i;
93 htab = osmalloc(0x2000 * sizeof(int));
94 for (i = 0; i < 0x2000; i++) htab[i] = NULL;
95}
96
97static void
98tree_insert(const char *name, const img_point *pt)
99{
100 int v = hash_string(name) & 0x1fff;
101 station *stn;
102#if 1
103 /* need to allow for duplicate labels ... */
104 for (stn = htab[v]; stn; stn = stn->next) {
105 if (strcmp(stn->name, name) == 0) return; /* found dup */
106 }
107#endif
108 stn = osnew(station);
109 stn->name = osstrdup(name);
110 stn->pt = *pt;
111 stn->next = htab[v];
112 htab[v] = stn;
113}
114
115static void
116tree_remove(const char *name, const img_point *pt)
117{
118 int v = hash_string(name) & 0x1fff;
119 station **prev;
120 station *p;
121
122 for (prev = &htab[v]; *prev; prev = &((*prev)->next)) {
123 if (strcmp((*prev)->name, name) == 0) break;
124 }
125
126 if (!*prev) {
127 printf("Added: %s\n", name);
128 fChanged = fTrue;
129 return;
130 }
131
132 if (fabs(pt->x - (*prev)->pt.x) - threshold > EPSILON ||
133 fabs(pt->y - (*prev)->pt.y) - threshold > EPSILON ||
134 fabs(pt->z - (*prev)->pt.z) - threshold > EPSILON) {
135 printf("Moved by (%3.2f,%3.2f,%3.2f): %s\n",
136 pt->x - (*prev)->pt.x,
137 pt->y - (*prev)->pt.y,
138 pt->z - (*prev)->pt.z,
139 name);
140 fChanged = fTrue;
141 }
142
143 osfree((*prev)->name);
144 p = *prev;
145 *prev = p->next;
146 osfree(p);
147}
148
149static int
150tree_check(void)
151{
152 size_t i;
153 for (i = 0; i < 0x2000; i++) {
154 station *p;
155 for (p = htab[i]; p; p = p->next) {
156 printf("Deleted: %s\n", p->name);
157 fChanged = fTrue;
158 }
159 }
160 return fChanged;
161}
162
163int
164main(int argc, char **argv)
165{
166 char *fnm1, *fnm2;
167 char *buf;
168 size_t len, buf_len = 256;
169 const char ext3d[] = EXT_SVX_3D;
170
171 msg_init(argv[0]);
172
173 cmdline_set_syntax_message("FILE1 FILE2 [THRESHOLD]",
174 "FILE1 and FILE2 can be .pos or .3d files\n"
175 "THRESHOLD is the max. ignorable change along "
176 "any axis in metres (default "
177 STRING(DFLT_MAX_THRESHOLD)")");
178 cmdline_init(argc, argv, short_opts, long_opts, NULL, help, 2, 3);
179 while (cmdline_getopt() != EOF) {
180 /* do nothing */
181 }
182 fnm1 = argv[optind++];
183 fnm2 = argv[optind++];
184 if (argv[optind]) {
185 optarg = argv[optind];
186 threshold = cmdline_double_arg();
187 }
188
189 tree_init();
190
191 buf = osmalloc(buf_len);
192
193 len = strlen(fnm1);
194 if (len > sizeof(ext3d) && fnm1[len - sizeof(ext3d)] == FNM_SEP_EXT &&
195 strcmp(fnm1 + len - sizeof(ext3d) + 1, ext3d) == 0) {
196 img_point pt;
197 int result;
198 img *pimg = img_open(fnm1, NULL, NULL);
199 if (!pimg) fatalerror(img_error(), fnm1);
200
201 do {
202 result = img_read_item(pimg, &pt);
203 switch (result) {
204 case img_MOVE:
205 case img_LINE:
206 break;
207 case img_LABEL:
208 tree_insert(pimg->label, &pt);
209 break;
210 case img_BAD:
211 img_close(pimg);
212 exit(1);
213 }
214 } while (result != img_STOP);
215
216 img_close(pimg);
217 } else {
218 img_point pt;
219
220 FILE *fh = fopen(fnm1, "rb");
221 if (!fh) fatalerror(/*Couldn't open file `%s'*/93, fnm1);
222
223 while (1) {
224 size_t off = 0;
225 if (fscanf(fh, "(%lf,%lf,%lf ) ", &pt.x, &pt.y, &pt.z) != 3) {
226 int ch;
227 if (feof(fh)) break;
228 printf("Skipping first\n");
229 do {
230 ch = getc(fh);
231 } while (ch != EOF && ch != '\n');
232 /* FIXME */
233 continue;
234 }
235 buf[0] = '\0';
236 while (!feof(fh)) {
237 if (!fgets(buf + off, buf_len - off, fh)) {
238 /* FIXME */
239 break;
240 }
241 off += strlen(buf + off);
242 if (off && buf[off - 1] == '\n') {
243 buf[off - 1] = '\0';
244 break;
245 }
246 buf_len += buf_len;
247 buf = osrealloc(buf, buf_len);
248 }
249 tree_insert(buf, &pt);
250 }
251
252 fclose(fh);
253 }
254
255 len = strlen(fnm2);
256 if (len > sizeof(ext3d) && fnm2[len - sizeof(ext3d)] == FNM_SEP_EXT &&
257 strcmp(fnm2 + len - sizeof(ext3d) + 1, ext3d) == 0) {
258 img_point pt;
259 int result;
260 img *pimg = img_open(fnm2, NULL, NULL);
261 if (!pimg) fatalerror(img_error(), fnm2);
262 do {
263 result = img_read_item(pimg, &pt);
264 switch (result) {
265 case img_MOVE:
266 case img_LINE:
267 break;
268 case img_LABEL:
269 tree_remove(pimg->label, &pt);
270 break;
271 case img_BAD:
272 img_close(pimg);
273 exit(1);
274 }
275 } while (result != img_STOP);
276
277 img_close(pimg);
278 } else {
279 img_point pt;
280
281 FILE *fh = fopen(fnm2, "rb");
282 if (!fh) fatalerror(/*Couldn't open file `%s'*/93, fnm2);
283
284 while (1) {
285 size_t off = 0;
286 if (fscanf(fh, "(%lf,%lf,%lf ) ", &pt.x, &pt.y, &pt.z) != 3) {
287 int ch;
288 if (feof(fh)) break;
289 printf("Skipping second\n");
290 do {
291 ch = getc(fh);
292 } while (ch != EOF && ch != '\n');
293 /* FIXME */
294 continue;
295 }
296 buf[0] = '\0';
297 while (!feof(fh)) {
298 if (!fgets(buf + off, buf_len - off, fh)) {
299 /* FIXME */
300 break;
301 }
302 off += strlen(buf + off);
303 if (off && buf[off - 1] == '\n') {
304 buf[off - 1] = '\0';
305 break;
306 }
307 buf_len += buf_len;
308 buf = osrealloc(buf, buf_len);
309 }
310 tree_remove(buf, &pt);
311 }
312
313 fclose(fh);
314 }
315
316 return tree_check() ? EXIT_FAILURE : EXIT_SUCCESS;
317}
Note: See TracBrowser for help on using the repository browser.