コード例 #1
0
ファイル: cavern.c プロジェクト: aardgoose/survex
extern CDECL int
main(int argc, char **argv)
{
   int d;
   time_t tmUserStart = time(NULL);
   clock_t tmCPUStart = clock();
   {
       /* FIXME: localtime? */
       struct tm * t = localtime(&tmUserStart);
       int y = t->tm_year + 1900;
       current_days_since_1900 = days_since_1900(y, t->tm_mon + 1, t->tm_mday);
   }

   /* Always buffer by line for aven's benefit. */
   setvbuf(stdout, NULL, _IOLBF, 0);

   msg_init(argv);

#if OS_WIN32 || OS_UNIX_MACOSX
   pj_set_finder(msg_proj_finder);
#endif

   pcs = osnew(settings);
   pcs->next = NULL;
   pcs->Translate = ((short*) osmalloc(ossizeof(short) * 257)) + 1;
   pcs->meta = NULL;
   pcs->proj = NULL;
   pcs->declination = HUGE_REAL;
   pcs->convergence = 0.0;

   /* Set up root of prefix hierarchy */
   root = osnew(prefix);
   root->up = root->right = root->down = NULL;
   root->stn = NULL;
   root->pos = NULL;
   root->ident = NULL;
   root->min_export = root->max_export = 0;
   root->sflags = BIT(SFLAGS_SURVEY);
   root->filename = NULL;

   nosurveyhead = NULL;

   stnlist = NULL;
   cLegs = cStns = cComponents = 0;
   totadj = total = totplan = totvert = 0.0;

   for (d = 0; d <= 2; d++) {
      min[d] = HUGE_REAL;
      max[d] = -HUGE_REAL;
      pfxHi[d] = pfxLo[d] = NULL;
   }

   /* at least one argument must be given */
   cmdline_init(argc, argv, short_opts, long_opts, NULL, help, 1, -1);
   while (1) {
      int opt = cmdline_getopt();
      if (opt == EOF) break;
      switch (opt) {
       case 'p':
	 /* Ignore for compatibility with older versions. */
	 break;
       case 'o': {
	 osfree(fnm_output_base); /* in case of multiple -o options */
	 /* can be a directory (in which case use basename of leaf input)
	  * or a file (in which case just trim the extension off) */
	 if (fDirectory(optarg)) {
	    /* this is a little tricky - we need to note the path here,
	     * and then add the leaf later on (in datain.c) */
	    fnm_output_base = base_from_fnm(optarg);
	    fnm_output_base_is_dir = 1;
	 } else {
	    fnm_output_base = base_from_fnm(optarg);
	 }
	 break;
       }
       case 'q':
	 if (fQuiet) fMute = 1;
	 fQuiet = 1;
	 break;
       case 's':
	 fSuppress = 1;
	 break;
       case 'v': {
	 int v = atoi(optarg);
	 if (v < IMG_VERSION_MIN || v > IMG_VERSION_MAX)
	    fatalerror(/*3d file format versions %d to %d supported*/88,
		       IMG_VERSION_MIN, IMG_VERSION_MAX);
	 img_output_version = v;
	 break;
       }
       case 'w':
	 f_warnings_are_errors = 1;
	 break;
       case 'z': {
	 /* Control which network optimisations are used (development tool) */
	 static int first_opt_z = 1;
	 char c;
	 if (first_opt_z) {
	    optimize = 0;
	    first_opt_z = 0;
	 }
	 /* Lollipops, Parallel legs, Iterate mx, Delta* */
	 while ((c = *optarg++) != '\0')
	    if (islower((unsigned char)c)) optimize |= BITA(c);
	 break;
       case 1:
	 fLog = fTrue;
	 break;
#if OS_WIN32
       case 2:
	 atexit(pause_on_exit);
	 break;
#endif
       }
      }
   }

   if (fLog) {
      char *fnm;
      if (!fnm_output_base) {
	 char *p;
	 p = baseleaf_from_fnm(argv[optind]);
	 fnm = add_ext(p, EXT_LOG);
	 osfree(p);
      } else if (fnm_output_base_is_dir) {
	 char *p;
	 fnm = baseleaf_from_fnm(argv[optind]);
	 p = use_path(fnm_output_base, fnm);
	 osfree(fnm);
	 fnm = add_ext(p, EXT_LOG);
	 osfree(p);
      } else {
	 fnm = add_ext(fnm_output_base, EXT_LOG);
      }

      if (!freopen(fnm, "w", stdout))
	 fatalerror(/*Failed to open output file “%s”*/47, fnm);

      osfree(fnm);
   }

   if (!fMute) {
      const char *p = COPYRIGHT_MSG;
      puts(PRETTYPACKAGE" "VERSION);
      while (1) {
	  const char *q = p;
	  p = strstr(p, "(C)");
	  if (p == NULL) {
	      puts(q);
	      break;
	  }
	  fwrite(q, 1, p - q, stdout);
	  fputs(msg(/*©*/0), stdout);
	  p += 3;
      }
   }

   atexit(delete_output_on_error);

   /* end of options, now process data files */
   while (argv[optind]) {
      const char *fnm = argv[optind];

      if (!fExplicitTitle) {
	 char *lf;
	 lf = baseleaf_from_fnm(fnm);
	 if (survey_title) s_catchar(&survey_title, &survey_title_len, ' ');
	 s_cat(&survey_title, &survey_title_len, lf);
	 osfree(lf);
      }

      /* Select defaults settings */
      default_all(pcs);
      data_file(NULL, fnm); /* first argument is current path */

      optind++;
   }

   validate();

   solve_network(/*stnlist*/); /* Find coordinates of all points */
   validate();

   /* close .3d file */
   if (!img_close(pimg)) {
      char *fnm = add_ext(fnm_output_base, EXT_SVX_3D);
      fatalerror(img_error2msg(img_error()), fnm);
   }
   if (fhErrStat) safe_fclose(fhErrStat);

   out_current_action(msg(/*Calculating statistics*/120));
   if (!fMute) do_stats();
   if (!fQuiet) {
      /* clock() typically wraps after 72 minutes, but there doesn't seem
       * to be a better way.  Still 72 minutes means some cave!
       * We detect if clock() could have wrapped and suppress CPU time
       * printing in this case.
       */
      double tmUser = difftime(time(NULL), tmUserStart);
      double tmCPU;
      clock_t now = clock();
#define CLOCK_T_WRAP \
	(sizeof(clock_t)<sizeof(long)?(1ul << (CHAR_BIT * sizeof(clock_t))):0)
      tmCPU = (now - (unsigned long)tmCPUStart)
	 / (double)CLOCKS_PER_SEC;
      if (now < tmCPUStart)
	 tmCPU += CLOCK_T_WRAP / (double)CLOCKS_PER_SEC;
      if (tmUser >= tmCPU + CLOCK_T_WRAP / (double)CLOCKS_PER_SEC)
	 tmCPU = 0;

      /* tmUser is integer, tmCPU not - equivalent to (ceil(tmCPU) >= tmUser) */
      if (tmCPU + 1 > tmUser) {
	 printf(msg(/*CPU time used %5.2fs*/140), tmCPU);
      } else if (tmCPU == 0) {
	 if (tmUser != 0.0) {
	    printf(msg(/*Time used %5.2fs*/141), tmUser);
	 } else {
	    fputs(msg(/*Time used unavailable*/142), stdout);
	 }
      } else {
	 printf(msg(/*Time used %5.2fs (%5.2fs CPU time)*/143), tmUser, tmCPU);
      }
      putnl();
   }
   if (msg_warnings || msg_errors) {
      if (msg_errors || (f_warnings_are_errors && msg_warnings)) {
	 printf(msg(/*There were %d warning(s) and %d error(s) - no output files produced.*/113),
		msg_warnings, msg_errors);
	 putnl();
	 return EXIT_FAILURE;
      }
      printf(msg(/*There were %d warning(s).*/16), msg_warnings);
      putnl();
   }
   return EXIT_SUCCESS;
}
コード例 #2
0
ファイル: img.c プロジェクト: mdornseif/therion
img *
img_open_survey(const char *fnm, const char *survey)
{
   img *pimg;
   size_t len;
   char buf[LITLEN(FILEID) + 9];
   int ch;

   if (fDirectory(fnm)) {
      img_errno = IMG_DIRECTORY;
      return NULL;
   }

   pimg = (img *)xosmalloc(ossizeof(img));
   if (pimg == NULL) {
      img_errno = IMG_OUTOFMEMORY;
      return NULL;
   }

   pimg->buf_len = 257;
   pimg->label_buf = xosmalloc(pimg->buf_len);
   if (!pimg->label_buf) {
      osfree(pimg);
      img_errno = IMG_OUTOFMEMORY;
      return NULL;
   }

   pimg->fh = fopenWithPthAndExt("", fnm, EXT_SVX_3D, "rb", &(pimg->filename_opened));
   if (pimg->fh == NULL) {
      osfree(pimg->label_buf);
      osfree(pimg);
      img_errno = IMG_FILENOTFOUND;
      return NULL;
   }

   pimg->fRead = fTrue; /* reading from this file */
   img_errno = IMG_NONE;

   pimg->flags = 0;

   /* for version >= 3 we use label_buf to store the prefix for reuse */
   /* for VERSION_COMPASS_PLT, 0 value indicates we haven't
    * entered a survey yet */
   /* for VERSION_CMAP_SHOT, we store the last station here
    * to detect whether we MOVE or LINE */
   pimg->label_len = 0;
   pimg->label_buf[0] = '\0';

   pimg->survey = NULL;
   pimg->survey_len = 0;
   pimg->separator = '.';
   pimg->date1 = 0;
   pimg->date2 = 0;
   pimg->is_extended_elevation = 0;

   pimg->l = pimg->r = pimg->u = pimg->d = -1.0;

   pimg->title = pimg->datestamp = NULL;
   if (survey) {
      len = strlen(survey);
      if (len) {
	 if (survey[len - 1] == '.') len--;
	 if (len) {
	    char *p;
	    pimg->survey = xosmalloc(len + 2);
	    if (!pimg->survey) {
	       img_errno = IMG_OUTOFMEMORY;
	       goto error;
	    }
	    memcpy(pimg->survey, survey, len);
	    /* Set title to leaf survey name */
	    pimg->survey[len] = '\0';
	    p = strchr(pimg->survey, '.');
	    if (p) p++; else p = pimg->survey;
	    pimg->title = my_strdup(p);
	    if (!pimg->title) {
	       img_errno = IMG_OUTOFMEMORY;
	       goto error;
	    }
	    pimg->survey[len] = '.';
	    pimg->survey[len + 1] = '\0';
	 }
      }
      pimg->survey_len = len;
   }

   /* [VERSION_COMPASS_PLT, VERSION_CMAP_STATION, VERSION_CMAP_SHOT] pending
    * IMG_LINE or IMG_MOVE - both have 4 added.
    * [VERSION_SURVEX_POS] already skipped heading line, or there wasn't one
    * [version 0] not in the middle of a 'LINE' command
    * [version >= 3] not in the middle of turning a LINE into a MOVE
    */
   pimg->pending = 0;

   len = strlen(fnm);
   if (has_ext(fnm, len, EXT_SVX_POS)) {
pos_file:
      pimg->version = VERSION_SURVEX_POS;
      if (!pimg->survey) pimg->title = baseleaf_from_fnm(fnm);
      pimg->datestamp = my_strdup(TIMENA);
      if (!pimg->datestamp) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      pimg->start = 0;
      return pimg;
   }

   if (has_ext(fnm, len, EXT_PLT) || has_ext(fnm, len, EXT_PLF)) {
      long fpos;
plt_file:
      pimg->version = VERSION_COMPASS_PLT;
      /* Spaces aren't legal in Compass station names, but dots are, so
       * use space as the level separator */
      pimg->separator = ' ';
      pimg->start = 0;
      if (!pimg->survey) pimg->title = baseleaf_from_fnm(fnm);
      pimg->datestamp = my_strdup(TIMENA);
      if (!pimg->datestamp) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      while (1) {
	 ch = getc(pimg->fh);
	 switch (ch) {
	  case '\x1a':
	    fseek(pimg->fh, -1, SEEK_CUR);
	    /* FALL THRU */
	  case EOF:
	    pimg->start = ftell(pimg->fh);
	    return pimg;
	  case 'N': {
	    char *line, *q;
	    fpos = ftell(pimg->fh) - 1;
	    if (!pimg->survey) {
	       /* FIXME : if there's only one survey in the file, it'd be nice
		* to use its description as the title here...
		*/
	       ungetc('N', pimg->fh);
	       pimg->start = fpos;
	       return pimg;
	    }
	    line = getline_alloc(pimg->fh);
	    if (!line) {
	       img_errno = IMG_OUTOFMEMORY;
	       goto error;
	    }
	    len = 0;
	    while (line[len] > 32) ++len;
	    if (pimg->survey_len != len ||
		memcmp(line, pimg->survey, len) != 0) {
	       osfree(line);
	       continue;
	    }
	    q = strchr(line + len, 'C');
	    if (q && q[1]) {
		osfree(pimg->title);
		pimg->title = my_strdup(q + 1);
	    } else if (!pimg->title) {
		pimg->title = my_strdup(pimg->label);
	    }
	    osfree(line);
	    if (!pimg->title) {
		img_errno = IMG_OUTOFMEMORY;
		goto error;
	    }
	    if (!pimg->start) pimg->start = fpos;
	    fseek(pimg->fh, pimg->start, SEEK_SET);
	    return pimg;
	  }
	  case 'M': case 'D':
	    pimg->start = ftell(pimg->fh) - 1;
	    break;
	 }
	 while (ch != '\n' && ch != '\r') {
	    ch = getc(pimg->fh);
	 }
      }
   }

   if (has_ext(fnm, len, EXT_XYZ)) {
      char *line;
xyz_file:
      /* Spaces aren't legal in CMAP station names, but dots are, so
       * use space as the level separator. */
      pimg->separator = ' ';
      line = getline_alloc(pimg->fh);
      if (!line) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      /* FIXME: reparse date? */
      len = strlen(line);
      if (len > 59) line[59] = '\0';
      if (len > 45) {
	 pimg->datestamp = my_strdup(line + 45);
      } else {
	 pimg->datestamp = my_strdup(TIMENA);
      }
      if (strncmp(line, "  Cave Survey Data Processed by CMAP ",
		  LITLEN("  Cave Survey Data Processed by CMAP ")) == 0) {
	 len = 0;
      } else {
	 if (len > 45) {
	    line[45] = '\0';
	    len = 45;
	 }
	 while (len > 2 && line[len - 1] == ' ') --len;
	 if (len > 2) {
	    line[len] = '\0';
	    pimg->title = my_strdup(line + 2);
	 }
      }
      if (len <= 2) pimg->title = baseleaf_from_fnm(fnm);
      osfree(line);
      if (!pimg->datestamp || !pimg->title) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      line = getline_alloc(pimg->fh);
      if (!line) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      if (line[0] != ' ' || (line[1] != 'S' && line[1] != 'O')) {
	 img_errno = IMG_BADFORMAT;
	 goto error;
      }
      if (line[1] == 'S') {
	 pimg->version = VERSION_CMAP_STATION;
      } else {
	 pimg->version = VERSION_CMAP_SHOT;
      }
      osfree(line);
      line = getline_alloc(pimg->fh);
      if (!line) {
	 img_errno = IMG_OUTOFMEMORY;
	 goto error;
      }
      if (line[0] != ' ' || line[1] != '-') {
	 img_errno = IMG_BADFORMAT;
	 goto error;
      }
      osfree(line);
      pimg->start = ftell(pimg->fh);
      return pimg;
   }

   if (fread(buf, LITLEN(FILEID) + 1, 1, pimg->fh) != 1 ||
       memcmp(buf, FILEID"\n", LITLEN(FILEID) + 1) != 0) {
      if (fread(buf + LITLEN(FILEID) + 1, 8, 1, pimg->fh) == 1 &&
	  memcmp(buf, FILEID"\r\nv0.01\r\n", LITLEN(FILEID) + 9) == 0) {
	 /* v0 3d file with DOS EOLs */
	 pimg->version = 0;
	 goto v03d;
      }
      rewind(pimg->fh);
      if (buf[1] == ' ') {
	 if (buf[0] == ' ') {
	    /* Looks like a CMAP .xyz file ... */
	    goto xyz_file;
	 } else if (strchr("ZSNF", buf[0])) {
	    /* Looks like a Compass .plt file ... */
	    /* Almost certainly it'll start "Z " */
	    goto plt_file;
	 }
      }
      if (buf[0] == '(') {
	 /* Looks like a Survex .pos file ... */
	 goto pos_file;
      }
      img_errno = IMG_BADFORMAT;
      goto error;
   }

   /* check file format version */
   ch = getc(pimg->fh);
   pimg->version = 0;
   if (tolower(ch) == 'b') {
      /* binary file iff B/b prefix */
      pimg->version = 1;
      ch = getc(pimg->fh);
   }
   if (ch != 'v') {
      img_errno = IMG_BADFORMAT;
      goto error;
   }
   ch = getc(pimg->fh);
   if (ch == '0') {
      if (fread(buf, 4, 1, pimg->fh) != 1 || memcmp(buf, ".01\n", 4) != 0) {
	 img_errno = IMG_BADFORMAT;
	 goto error;
      }
      /* nothing special to do */
   } else if (pimg->version == 0) {
      if (ch < '2' || ch > '0' + LATEST_IMG_VERSION || getc(pimg->fh) != '\n') {
	 img_errno = IMG_TOONEW;
	 goto error;
      }
      pimg->version = ch - '0';
   } else {
      img_errno = IMG_BADFORMAT;
      goto error;
   }

v03d:
   if (!pimg->title)
       pimg->title = getline_alloc(pimg->fh);
   else
       osfree(getline_alloc(pimg->fh));
   pimg->datestamp = getline_alloc(pimg->fh);
   if (!pimg->title || !pimg->datestamp) {
      img_errno = IMG_OUTOFMEMORY;
      error:
      osfree(pimg->title);
      osfree(pimg->datestamp);
      fclose(pimg->fh);
      osfree(pimg);
      return NULL;
   }

   pimg->start = ftell(pimg->fh);

   len = strlen(pimg->title);
   if (len > 11 && strcmp(pimg->title + len - 11, " (extended)") == 0) {
       pimg->title[len - 11] = '\0';
       pimg->is_extended_elevation = 1;
   }

   return pimg;
}