source: git/src/diffpos.c @ fb93f7e

RELEASE/1.0RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereowalls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since fb93f7e was 3262009, checked in by Olly Betts <olly@…>, 23 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
RevLine 
[d1b1380]1/* > diffpos.c */
[3262009]2/* Utility to compare two SURVEX .pos or .3d files */
[759fb47]3/* Copyright (C) 1994,1996,1998,1999,2001 Olly Betts
[846746e]4 *
[89231c4]5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
[846746e]9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[89231c4]12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
[846746e]14 *
[89231c4]15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
[846746e]18 */
[d1b1380]19
[a420b49]20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
[d1b1380]23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <math.h>
28
[2b078c4]29#include "cavern.h" /* just for REAL_EPSILON */
[acc20b1]30#include "cmdline.h"
[3262009]31#include "debug.h"
32#include "filelist.h"
33#include "img.h"
[acc20b1]34
[8b0fcbc]35#ifndef sqrd
36# define sqrd(X) ((X)*(X))
37#endif
[d1b1380]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 */
[2b078c4]44#define EPSILON (REAL_EPSILON * 1000)
[d1b1380]45
46/* default threshold is 1cm */
47#define DFLT_MAX_THRESHOLD 0.01
48
[3262009]49static double threshold = DFLT_MAX_THRESHOLD;
[d1b1380]50
[acc20b1]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
[3262009]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
[a420b49]163int
[acc20b1]164main(int argc, char **argv)
[a420b49]165{
[73a8a94]166   char *fnm1, *fnm2;
[3262009]167   char *buf;
168   size_t len, buf_len = 256;
169   const char ext3d[] = EXT_SVX_3D;
[acc20b1]170
[d06141c]171   msg_init(argv[0]);
172
[3262009]173   cmdline_set_syntax_message("FILE1 FILE2 [THRESHOLD]",
174                              "FILE1 and FILE2 can be .pos or .3d files\n"
[acc20b1]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();
[73a8a94]187   }
[bfe1242]188
[3262009]189   tree_init();
[bfe1242]190
[3262009]191   buf = osmalloc(buf_len);
[d1b1380]192
[3262009]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);
[cb3d1e2]200
[3262009]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;
[cb3d1e2]219
[3262009]220      FILE *fh = fopen(fnm1, "rb");
221      if (!fh) fatalerror(/*Couldn't open file `%s'*/93, fnm1);
[cb3d1e2]222
[3262009]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);
[73a8a94]250      }
[cb3d1e2]251
[3262009]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);
[cb3d1e2]283
[3262009]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;
[3f93024]301            }
[3262009]302            off += strlen(buf + off);
303            if (off && buf[off - 1] == '\n') {
304               buf[off - 1] = '\0';
305               break;
[3f93024]306            }
[3262009]307            buf_len += buf_len;
308            buf = osrealloc(buf, buf_len);
[3f93024]309         }
[3262009]310         tree_remove(buf, &pt);
[73a8a94]311      }
[d1b1380]312
[3262009]313      fclose(fh);
[73a8a94]314   }
[3262009]315
316   return tree_check() ? EXIT_FAILURE : EXIT_SUCCESS;
[d1b1380]317}
Note: See TracBrowser for help on using the repository browser.