コード例 #1
0
ファイル: diffpos.c プロジェクト: RobDeBagel/survex
static void
tree_remove(const char *name, const img_point *pt)
{
   /* We need to handle duplicate labels - normal .3d files shouldn't have them
    * (though some older ones do due to a couple of bugs in earlier versions of
    * Survex) but extended .3d files repeat the label where a loop is broken,
    * and data read from foreign formats might repeat labels.
    */
   int v = hash_string(name) & (TREE_SIZE - 1);
   station **prev;
   station *p;
   station **found = NULL;
   bool was_close_enough = fFalse;

   for (prev = &htab[v]; *prev; prev = &((*prev)->next)) {
      if (strcmp((*prev)->name, name) == 0) {
	 /* Handle stations with the same name.  Stations are inserted at the
	  * start of the linked list, so pick the *last* matching station in
	  * the list as then we match the first stations with the same name in
	  * each file.
	  */
	 if (close_enough(pt, &((*prev)->pt))) {
	    found = prev;
	    was_close_enough = fTrue;
	 } else if (!was_close_enough) {
	    found = prev;
	 }
      }
   }

   if (!found) {
      added *add = osnew(added);
      add->name = osstrdup(name);
      add->next = added_list;
      added_list = add;
      c_added++;
      fChanged = fTrue;
      return;
   }

   if (!was_close_enough) {
      printf(msg(/*Moved by (%3.2f,%3.2f,%3.2f): %s*/500),
	     pt->x - (*found)->pt.x,
	     pt->y - (*found)->pt.y,
	     pt->z - (*found)->pt.z,
	     name);
      putnl();
      fChanged = fTrue;
   }

   osfree((*found)->name);
   p = *found;
   *found = p->next;
   osfree(p);
}
コード例 #2
0
ファイル: filename.c プロジェクト: Cavewhere/survex
void
filename_delete_output(void)
{
   while (flhead) {
      filelist *p = flhead;
      flhead = flhead->next;
      if (p->fnm) {
	 (void)remove(p->fnm);
	 osfree(p->fnm);
      }
      osfree(p);
   }
}
コード例 #3
0
ファイル: diffpos.c プロジェクト: RobDeBagel/survex
static int
tree_check(void)
{
   size_t c = 0;
   char **names;
   size_t i;

   if (c_added) {
      names = osmalloc(c_added * ossizeof(char *));
      for (i = 0; i < c_added; i++) {
	 added *old;
	 SVX_ASSERT(added_list);
	 names[i] = added_list->name;
	 old = added_list;
	 added_list = old->next;
	 osfree(old);
      }
      SVX_ASSERT(added_list == NULL);
      sort_separator = new_separator;
      qsort(names, c_added, sizeof(char *), cmp_pname);
      for (i = 0; i < c_added; i++) {
	 printf(msg(/*Added: %s*/501), names[i]);
	 putnl();
	 osfree(names[i]);
      }
      osfree(names);
   }

   for (i = 0; i < TREE_SIZE; i++) {
      station *p;
      for (p = htab[i]; p; p = p->next) c++;
   }
   if (c == 0) return fChanged;

   names = osmalloc(c * ossizeof(char *));
   c = 0;
   for (i = 0; i < TREE_SIZE; i++) {
      station *p;
      for (p = htab[i]; p; p = p->next) names[c++] = p->name;
   }
   sort_separator = old_separator;
   qsort(names, c, sizeof(char *), cmp_pname);
   for (i = 0; i < c; i++) {
      printf(msg(/*Deleted: %s*/502), names[i]);
      putnl();
   }
   return fTrue;
}
コード例 #4
0
ファイル: img.c プロジェクト: mdornseif/therion
static char *
getline_alloc(FILE *fh)
{
   int ch;
   size_t i = 0;
   size_t len = 16;
   char *buf = xosmalloc(len);
   if (!buf) return NULL;

   ch = getc(fh);
   while (ch != '\n' && ch != '\r' && ch != EOF) {
      buf[i++] = ch;
      if (i == len - 1) {
	 char *p;
	 len += len;
	 p = xosrealloc(buf, len);
	 if (!p) {
	    osfree(buf);
	    return NULL;
	 }
	 buf = p;
      }
      ch = getc(fh);
   }
   if (ch == '\n' || ch == '\r') {
      int otherone = ch ^ ('\n' ^ '\r');
      ch = getc(fh);
      /* if it's not the other eol character, put it back */
      if (ch != otherone) ungetc(ch, fh);
   }
   buf[i++] = '\0';
   return buf;
}
コード例 #5
0
ファイル: commands.c プロジェクト: RobDeBagel/survex
static void
cmd_include(void)
{
   char *pth, *fnm = NULL;
   int fnm_len;
#ifndef NO_DEPRECATED
   prefix *root_store;
#endif
   int ch_store;

   pth = path_from_fnm(file.filename);

   read_string(&fnm, &fnm_len);

#ifndef NO_DEPRECATED
   /* Since *begin / *end nesting cannot cross file boundaries we only
    * need to preserve the prefix if the deprecated *prefix command
    * can be used */
   root_store = root;
   root = pcs->Prefix; /* Root for include file is current prefix */
#endif
   ch_store = ch;

   data_file(pth, fnm);

#ifndef NO_DEPRECATED
   root = root_store; /* and restore root */
#endif
   ch = ch_store;

   s_free(&fnm);
   osfree(pth);
}
コード例 #6
0
ファイル: commands.c プロジェクト: RobDeBagel/survex
static void
report_missing_export(prefix *pfx, int depth)
{
   const char *filename_store = file.filename;
   unsigned int line_store = file.line;
   prefix *survey = pfx;
   char *s;
   int i;
   for (i = depth + 1; i; i--) {
      survey = survey->up;
      SVX_ASSERT(survey);
   }
   s = osstrdup(sprint_prefix(survey));
   if (survey->filename) {
      file.filename = survey->filename;
      file.line = survey->line;
   }
   compile_error(/*Station “%s” not exported from survey “%s”*/26,
		 sprint_prefix(pfx), s);
   if (survey->filename) {
      file.filename = filename_store;
      file.line = line_store;
   }
   osfree(s);
}
コード例 #7
0
ファイル: commands.c プロジェクト: RobDeBagel/survex
extern void
free_settings(settings *p) {
   /* don't free default ordering or ordering used by parent */
   reading *order = p->ordering;
   if (order != default_order && (!p->next || order != p->next->ordering))
      osfree(order);

   /* free Translate if not used by parent */
   if (!p->next || p->Translate != p->next->Translate)
      osfree(p->Translate - 1);

   /* free meta is not used by parent, or in this block */
   if (p->meta && p->meta != p->next->meta && p->meta->ref_count == 0)
       osfree(p->meta);

   osfree(p);
}
コード例 #8
0
ファイル: filename.c プロジェクト: Cavewhere/survex
/* fopen file, found using pth and fnm
 * fnmUsed is used to return filename used to open file (ignored if NULL)
 * or NULL if file didn't open
 */
extern FILE *
fopenWithPthAndExt(const char *pth, const char *fnm, const char *ext,
		   const char *mode, char **fnmUsed)
{
   char *fnmFull = NULL;
   FILE *fh = NULL;
   bool fAbs;

   /* if no pth treat fnm as absolute */
   fAbs = (pth == NULL || *pth == '\0' || fAbsoluteFnm(fnm));

   /* if appropriate, try it without pth */
   if (fAbs) {
      fh = fopen_not_dir(fnm, mode);
      if (fh) {
	 if (fnmUsed) fnmFull = osstrdup(fnm);
      } else {
	 if (ext && *ext) {
	    /* we've been given an extension so try using it */
	    fnmFull = add_ext(fnm, ext);
	    fh = fopen_not_dir(fnmFull, mode);
	 }
      }
   } else {
      /* try using path given - first of all without the extension */
      fnmFull = use_path(pth, fnm);
      fh = fopen_not_dir(fnmFull, mode);
      if (!fh) {
	 if (ext && *ext) {
	    /* we've been given an extension so try using it */
	    char *fnmTmp;
	    fnmTmp = fnmFull;
	    fnmFull = add_ext(fnmFull, ext);
	    osfree(fnmTmp);
	    fh = fopen_not_dir(fnmFull, mode);
	 }
      }
   }

   /* either it opened or didn't. If not, fh == NULL from fopen_not_dir() */

   /* free name if it didn't open or name isn't wanted */
   if (fh == NULL || fnmUsed == NULL) osfree(fnmFull);
   if (fnmUsed) *fnmUsed = (fh ? fnmFull : NULL);
   return fh;
}
コード例 #9
0
ファイル: gameinfo.cpp プロジェクト: 0branch/qtads
/*
 *   Delete 
 */
CTadsGameInfo::~CTadsGameInfo()
{
    /* if we have a buffer, delete it */
    if (buf_ != 0)
        osfree(buf_);

    /* free the name/value pair list */
    free_value_list();
}
コード例 #10
0
ファイル: listpos.c プロジェクト: Cavewhere/survex
static void
check_node(prefix *p)
{
   if (!p->pos) {
      if (!TSTBIT(p->sflags, SFLAGS_SURVEY)) {
	 /* Could do away with the SFLAGS_SURVEY check and check
	  * p->min_export instead of p->max_export I think ... */
	 if (TSTBIT(p->sflags, SFLAGS_ENTRANCE) || p->max_export) {
	     /* p is a station which was referred to in "*entrance" and/or
	      * "*export" but not elsewhere (otherwise it'd have a position).
	      * p could also be a survey (SFLAGS_SURVEY) or be mentioned as
	      * a station, but only in a line of data which was rejected
	      * because of an error.
	      */
	     warning_in_file(p->filename, p->line,
		     /*Station “%s” referred to by *entrance or *export but never used*/190,
		     sprint_prefix(p));
	 }
      }
   } else {
      /* Do we need to worry about export violations in hanging surveys? */
      if (fExportUsed) {
#if 0
	 printf("L min %d max %d pfx %s\n",
		p->min_export, p->max_export, sprint_prefix(p));
#endif
	 if ((p->min_export > 1 && p->min_export != USHRT_MAX) ||
	     (p->min_export == 0 && p->max_export)) {
	    char *s;
	    prefix *where = p->up;
	    int msgno;
	    SVX_ASSERT(where);
	    s = osstrdup(sprint_prefix(where));
	    /* Report better when station called 2.1 for example */
	    while (!where->filename && where->up) where = where->up;

	    if (TSTBIT(where->sflags, SFLAGS_PREFIX_ENTERED)) {
	       msgno = /*Station “%s” not exported from survey “%s”*/26;
	    } else {
		/* TRANSLATORS: This error occurs if there's an attempt to
		 * export a station from a survey which doesn't actually exist.
		 */
	       msgno = /*Reference to station “%s” from non-existent survey “%s”*/286;
	    }
	    compile_error_pfx(where, msgno, sprint_prefix(p), s);
	    osfree(s);
	 }
      }

      if (TSTBIT(p->sflags, SFLAGS_SUSPECTTYPO)) {
	 /* TRANSLATORS: Here "station" is a survey station, not a train station. */
	 warning_in_file(p->filename, p->line,
		 /*Station “%s” referred to just once, with an explicit survey name - typo?*/70,
		 sprint_prefix(p));
      }
   }
}
コード例 #11
0
ファイル: filename.c プロジェクト: Cavewhere/survex
extern FILE *
safe_fopen_with_ext(const char *fnm, const char *ext, const char *mode)
{
   FILE *f;
   char *p;
   p = add_ext(fnm, ext);
   f = safe_fopen(p, mode);
   osfree(p);
   return f;
}
コード例 #12
0
ファイル: cavern.c プロジェクト: RobDeBagel/survex
static void
do_range(int d, int msgno)
{
   /* sprint_prefix uses a single buffer, so to report two stations in one
    * message we need to make a temporary copy of the string for one of them.
    */
   char * pfx_hi = osstrdup(sprint_prefix(pfxHi[d]));
   char * pfx_lo = sprint_prefix(pfxLo[d]);
   printf(msg(msgno), max[d] - min[d], pfx_hi, max[d], pfx_lo, min[d]);
   osfree(pfx_hi);
   putnl();
}
コード例 #13
0
ファイル: cavern.c プロジェクト: aardgoose/survex
static void
do_range(int d, int msgno, real length_factor, const char * units)
{
   /* sprint_prefix uses a single buffer, so to report two stations in one
    * message we need to make a temporary copy of the string for one of them.
    */
   char * pfx_hi = osstrdup(sprint_prefix(pfxHi[d]));
   char * pfx_lo = sprint_prefix(pfxLo[d]);
   real hi = max[d] * length_factor;
   real lo = min[d] * length_factor;
   printf(msg(msgno), hi - lo, units, pfx_hi, hi, units, pfx_lo, lo, units);
   osfree(pfx_hi);
   putnl();
}
コード例 #14
0
ファイル: gameinfo.cpp プロジェクト: 0branch/qtads
/*
 *   Delete the list.  If a subclass overrides free_value(), it should call
 *   this routine from its overridden destructor, to ensure that the vtable
 *   still has a reference to the subclass version of free_value() when this
 *   is called.
 *   
 *   Since this routine deletes each entry and leaves us with an empty list,
 *   it's harmless to call this more than once; each subclass can thus
 *   safely call this from its own destructor, even if it thinks its own
 *   superclass or subclasses might call it as well.  
 */
void CTadsGameInfo::free_value_list()
{
    while (first_val_ != 0)
    {
        /* remember the next one */
        tads_valinfo *nxt = first_val_->nxt;

        /* 
         *   delete this one - delete its value string and then the
         *   structure itself 
         */
        free_value(first_val_->val);
        osfree(first_val_);

        /* move on to the next */
        first_val_ = nxt;
    }
}
コード例 #15
0
ファイル: filename.c プロジェクト: Cavewhere/survex
/* Like fopenWithPthAndExt except that "foreign" paths are translated to
 * native ones (e.g. on Unix dir\file.ext -> dir/file.ext) */
FILE *
fopen_portable(const char *pth, const char *fnm, const char *ext,
	       const char *mode, char **fnmUsed)
{
   FILE *fh = fopenWithPthAndExt(pth, fnm, ext, mode, fnmUsed);
   if (fh == NULL) {
#if OS_UNIX
      int f_changed = 0;
      char *fnm_trans, *p;
      fnm_trans = osstrdup(fnm);
      for (p = fnm_trans; *p; p++) {
	 switch (*p) {
	 case '\\': /* swap a backslash to a forward slash */
	    *p = '/';
	    f_changed = 1;
	    break;
	 }
      }
      if (f_changed)
	 fh = fopenWithPthAndExt(pth, fnm_trans, ext, mode, fnmUsed);

      /* as a last ditch measure, try lowercasing the filename */
      if (fh == NULL) {
	 f_changed = 0;
	 for (p = fnm_trans; *p ; p++) {
	    unsigned char ch = *p;
	    if (isupper(ch)) {
	       *p = tolower(ch);
	       f_changed = 1;
	    }
	 }
	 if (f_changed)
	    fh = fopenWithPthAndExt(pth, fnm_trans, ext, mode, fnmUsed);
      }
      osfree(fnm_trans);
#endif
   }
   return fh;
}
コード例 #16
0
ファイル: commands.c プロジェクト: RobDeBagel/survex
/* read token */
extern void
get_token(void)
{
   int i = -1;

   s_zero(&buffer);
   osfree(ucbuffer);
   skipblanks();
   while (isalpha(ch)) {
      s_catchar(&buffer, &buf_len, (char)ch);
      nextch();
   }

   if (!buffer) s_catchar(&buffer, &buf_len, '\0');

   ucbuffer = osmalloc(buf_len);
   do {
      i++;
      ucbuffer[i] = toupper(buffer[i]);
   } while (buffer[i]);
#if 0
   printf("get_token() got “%s”\n", buffer);
#endif
}
コード例 #17
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;
}
コード例 #18
0
static void
parse_msg_file(int charset_code)
{
   FILE *fh;
   unsigned char header[20];
   int i;
   unsigned len;
   unsigned char *p;
   char *fnm, *s;
   int n;

#ifdef DEBUG
   fprintf(stderr, "parse_msg_file(%d)\n", charset_code);
#endif

   /* sort out messages we need to print if we can't open the message file */
   dontextract = parse_msgs(N_DONTEXTRACTMSGS, dontextractmsgs, charset_code);

   fnm = osstrdup(msg_lang);
   /* trim off charset from stuff like "de_DE.iso8859_1" */
   s = strchr(fnm, '.');
   if (s) *s = '\0';
   /* trim off any "@<something>" modifier. */
   s = strchr(fnm, '@');
   if (s) *s = '\0';

   fh = fopenWithPthAndExt(pth_cfg_files, fnm, EXT_SVX_MSG, "rb", NULL);

   if (!fh && strlen(fnm) > 3 && fnm[2] == '_') {
      /* e.g. if 'en_GB' is unknown, see if we know 'en' */
      fnm[2] = '\0';
      fh = fopenWithPthAndExt(pth_cfg_files, fnm, EXT_SVX_MSG, "rb", NULL);
      if (!fh) fnm[2] = '_'; /* for error reporting */
   }

   if (!fh && !msg_lang_explicit) {
      /* If msg_lang wasn't specified using environment variable SURVEXLANG,
       * then default to 'en' if we don't find messages for language msg_lang.
       */
      if (fnm[0] && fnm[1]) {
	 strcpy(fnm, "en");
      } else {
	 osfree(fnm);
	 fnm = osstrdup("en");
      }
      fh = fopenWithPthAndExt(pth_cfg_files, fnm, EXT_SVX_MSG, "rb", NULL);
   }

   if (!fh) {
      fatalerror(/*Can't open message file “%s” using path “%s”*/1000,
		 fnm, pth_cfg_files);
   }

   if (fread(header, 1, 20, fh) < 20 ||
       memcmp(header, "Svx\nMsg\r\n\xfe\xff", 12) != 0) {
      fatalerror(/*Problem with message file “%s”*/1001, fnm);
   }

   if (header[12] != 0)
      fatalerror(/*I don't understand this message file version*/1002);

   n = (header[14] << 8) | header[15];

   len = 0;
   for (i = 16; i < 20; i++) len = (len << 8) | header[i];

   p = osmalloc(len);
   if (fread(p, 1, len, fh) < len)
      fatalerror(/*Message file truncated?*/1003);

   fclose(fh);

#ifdef DEBUG
   fprintf(stderr, "fnm = “%s”, n = %d, len = %d\n", fnm, n, len);
#endif
   osfree(fnm);

   msg_array = parse_msgs(n, p, charset_code);
   num_msgs = n;
}
コード例 #19
0
ファイル: commands.c プロジェクト: RobDeBagel/survex
static void
cmd_data(void)
{
   static sztok dtab[] = {
	{"ALTITUDE",	 Dz },
	{"BACKBEARING",  BackComp },
	{"BACKCLINO",    BackClino }, /* alternative name */
	{"BACKCOMPASS",  BackComp }, /* alternative name */
	{"BACKGRADIENT", BackClino },
	{"BEARING",      Comp },
	{"CEILING",      Up }, /* alternative name */
	{"CLINO",	 Clino }, /* alternative name */
	{"COMPASS",      Comp }, /* alternative name */
	{"COUNT",	 Count }, /* FrCount&ToCount in multiline */
	{"DEPTH",	 Depth }, /* FrDepth&ToDepth in multiline */
	{"DEPTHCHANGE",  DepthChange },
	{"DIRECTION",    Dir },
	{"DOWN",         Down },
	{"DX",		 Dx },
	{"DY",		 Dy },
	{"DZ",		 Dz },
	{"EASTING",      Dx },
	{"FLOOR",        Down }, /* alternative name */
	{"FROM",	 Fr },
	{"FROMCOUNT",    FrCount },
	{"FROMDEPTH",    FrDepth },
	{"GRADIENT",     Clino },
	{"IGNORE",       Ignore },
	{"IGNOREALL",    IgnoreAll },
	{"LEFT",         Left },
	{"LENGTH",       Tape },
	{"NEWLINE",      Newline },
	{"NORTHING",     Dy },
	{"RIGHT",        Right },
	{"STATION",      Station }, /* Fr&To in multiline */
	{"TAPE",	 Tape }, /* alternative name */
	{"TO",		 To },
	{"TOCOUNT",      ToCount },
	{"TODEPTH",      ToDepth },
	{"UP",           Up },
	{NULL,		 End }
   };

#define MASK_stns BIT(Fr) | BIT(To) | BIT(Station)
#define MASK_tape BIT(Tape) | BIT(FrCount) | BIT(ToCount) | BIT(Count)
#define MASK_dpth BIT(FrDepth) | BIT(ToDepth) | BIT(Depth) | BIT(DepthChange)
#define MASK_comp BIT(Comp) | BIT(BackComp)
#define MASK_clin BIT(Clino) | BIT(BackClino)

#define MASK_NORMAL MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_clin
#define MASK_DIVING MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth
#define MASK_CARTESIAN MASK_stns | BIT(Dx) | BIT(Dy) | BIT(Dz)
#define MASK_CYLPOLAR  MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth
#define MASK_PASSAGE BIT(Station) | BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down)
#define MASK_NOSURVEY MASK_stns

   /* readings which may be given for each style */
   static const unsigned long mask[] = {
      MASK_NORMAL, MASK_DIVING, MASK_CARTESIAN, MASK_CYLPOLAR, MASK_NOSURVEY,
      MASK_PASSAGE
   };

   /* readings which may be omitted for each style */
   static const unsigned long mask_optional[] = {
      BIT(Dir) | BIT(Clino) | BIT(BackClino),
      BIT(Dir),
      0,
      BIT(Dir),
      0,
      0 /* BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down), */
   };

   /* all valid readings */
   static const unsigned long mask_all[] = {
      MASK_NORMAL | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
      MASK_DIVING | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
      MASK_CARTESIAN | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
      MASK_CYLPOLAR | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
      MASK_NOSURVEY | BIT(Ignore) | BIT(IgnoreAll) | BIT(End),
      MASK_PASSAGE | BIT(Ignore) | BIT(IgnoreAll) | BIT(End)
   };
#define STYLE_DEFAULT   -2
#define STYLE_UNKNOWN   -1

   static sztok styletab[] = {
	{"CARTESIAN",    STYLE_CARTESIAN },
	{"CYLPOLAR",     STYLE_CYLPOLAR },
	{"DEFAULT",      STYLE_DEFAULT },
	{"DIVING",       STYLE_DIVING },
	{"NORMAL",       STYLE_NORMAL },
	{"NOSURVEY",     STYLE_NOSURVEY },
	{"PASSAGE",      STYLE_PASSAGE },
	{"TOPOFIL",      STYLE_NORMAL },
	{NULL,		 STYLE_UNKNOWN }
   };

#define m_multi (BIT(Station) | BIT(Count) | BIT(Depth))

   int style, k = 0, kMac;
   reading *new_order, d;
   unsigned long mUsed = 0;
   char *style_name;

   /* after a bad *data command ignore survey data until the next
    * *data command to avoid an avalanche of errors */
   pcs->style = STYLE_IGNORE;

   kMac = 6; /* minimum for NORMAL style */
   new_order = osmalloc(kMac * sizeof(reading));

   get_token();
   style = match_tok(styletab, TABSIZE(styletab));

   if (style == STYLE_DEFAULT) {
      default_style(pcs);
      return;
   }

   if (style == STYLE_UNKNOWN) {
      file.lpos += strlen(buffer);
      compile_error_skip(-/*Data style “%s” unknown*/65, buffer);
      return;
   }

   skipblanks();
#ifndef NO_DEPRECATED
   /* Olde syntax had optional field for survey grade, so allow an omit
    * but issue a warning about it */
   if (isOmit(ch)) {
      static int data_depr_count = 0;
      if (data_depr_count < 5) {
	 file.lpos += strlen(buffer);
	 compile_warning(-/*“*data %s %c …” is deprecated - use “*data %s …” instead*/104,
			 buffer, ch, buffer);
	 if (++data_depr_count == 5)
	    compile_warning(/*Further uses of this deprecated feature will not be reported*/95);
      }
      nextch();
   }
#endif

   style_name = osstrdup(buffer);
   do {
      filepos fp;
      get_pos(&fp);
      get_token();
      d = match_tok(dtab, TABSIZE(dtab));
      /* only token allowed after IGNOREALL is NEWLINE */
      if (k && new_order[k - 1] == IgnoreAll && d != Newline) {
	 set_pos(&fp);
	 break;
      }
      /* Note: an unknown token is reported as trailing garbage */
      if (!TSTBIT(mask_all[style], d)) {
	 file.lpos += strlen(buffer);
	 compile_error_skip(-/*Reading “%s” not allowed in data style “%s”*/63,
		       buffer, style_name);
	 osfree(style_name);
	 osfree(new_order);
	 return;
      }
      if (TSTBIT(mUsed, Newline) && TSTBIT(m_multi, d)) {
	 /* e.g. "*data diving station newline tape depth compass" */
	 file.lpos += strlen(buffer);
	 compile_error_skip(-/*Reading “%s” must occur before NEWLINE*/225, buffer);
	 osfree(style_name);
	 osfree(new_order);
	 return;
      }
      /* Check for duplicates unless it's a special reading:
       *   IGNOREALL,IGNORE (duplicates allowed) ; END (not possible)
       */
      if (!((BIT(Ignore) | BIT(End) | BIT(IgnoreAll)) & BIT(d))) {
	 if (TSTBIT(mUsed, d)) {
	    file.lpos += strlen(buffer);
	    compile_error_skip(-/*Duplicate reading “%s”*/67, buffer);
	    osfree(style_name);
	    osfree(new_order);
	    return;
	 } else {
	    /* Check for previously listed readings which are incompatible
	     * with this one - e.g. Count vs FrCount */
	    bool fBad = fFalse;
	    switch (d) {
	     case Station:
	       if (mUsed & (BIT(Fr) | BIT(To))) fBad = fTrue;
	       break;
	     case Fr: case To:
	       if (TSTBIT(mUsed, Station)) fBad = fTrue;
	       break;
	     case Count:
	       if (mUsed & (BIT(FrCount) | BIT(ToCount) | BIT(Tape)))
		  fBad = fTrue;
	       break;
	     case FrCount: case ToCount:
	       if (mUsed & (BIT(Count) | BIT(Tape)))
		  fBad = fTrue;
	       break;
	     case Depth:
	       if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange)))
		  fBad = fTrue;
	       break;
	     case FrDepth: case ToDepth:
	       if (mUsed & (BIT(Depth) | BIT(DepthChange))) fBad = fTrue;
	       break;
	     case DepthChange:
	       if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(Depth)))
		  fBad = fTrue;
	       break;
	     case Newline:
	       if (mUsed & ~m_multi) {
		  /* e.g. "*data normal from to tape newline compass clino" */
		  file.lpos += strlen(buffer);
		  compile_error_skip(-/*NEWLINE can only be preceded by STATION, DEPTH, and COUNT*/226);
		  osfree(style_name);
		  osfree(new_order);
		  return;
	       }
	       if (k == 0) {
		  file.lpos += strlen(buffer);
		  compile_error_skip(-/*NEWLINE can’t be the first reading*/222);
		  osfree(style_name);
		  osfree(new_order);
		  return;
	       }
	       break;
	     default: /* avoid compiler warnings about unhandled enums */
	       break;
	    }
	    if (fBad) {
	       /* Not entirely happy with phrasing this... */
	       file.lpos += strlen(buffer);
	       compile_error_skip(-/*Reading “%s” duplicates previous reading(s)*/77,
			     buffer);
	       osfree(style_name);
	       osfree(new_order);
	       return;
	    }
	    mUsed |= BIT(d); /* used to catch duplicates */
	 }
      }
      if (k && new_order[k - 1] == IgnoreAll) {
	 SVX_ASSERT(d == Newline);
	 k--;
	 d = IgnoreAllAndNewLine;
      }
      if (k >= kMac) {
	 kMac = kMac * 2;
	 new_order = osrealloc(new_order, kMac * sizeof(reading));
      }
      new_order[k++] = d;
   } while (d != End);

   if (k >= 2 && new_order[k - 2] == Newline) {
      file.lpos += strlen(buffer);
      compile_error_skip(-/*NEWLINE can’t be the last reading*/223);
      osfree(style_name);
      osfree(new_order);
      return;
   }

   if (style == STYLE_NOSURVEY) {
      if (TSTBIT(mUsed, Station)) {
	 if (k >= kMac) {
	    kMac = kMac * 2;
	    new_order = osrealloc(new_order, kMac * sizeof(reading));
	 }
	 new_order[k - 1] = Newline;
	 new_order[k++] = End;
      }
   } else if (style == STYLE_PASSAGE) {
      /* Station doesn't mean "multiline" for STYLE_PASSAGE. */
   } else if (!TSTBIT(mUsed, Newline) && (m_multi & mUsed)) {
      /* This is for when they write
       * *data normal station tape compass clino
       * (i.e. no newline, but interleaved readings)
       */
      compile_error_skip(/*Interleaved readings, but no NEWLINE*/224);
      osfree(style_name);
      osfree(new_order);
      return;
   }

#if 0
   printf("mUsed = 0x%x\n", mUsed);
#endif

   /* Check the supplied readings form a sufficient set. */
   if (style != STYLE_PASSAGE) {
       if (mUsed & (BIT(Fr) | BIT(To)))
	   mUsed |= BIT(Station);
       else if (TSTBIT(mUsed, Station))
	   mUsed |= BIT(Fr) | BIT(To);
   }

   if (mUsed & (BIT(Comp) | BIT(BackComp)))
      mUsed |= BIT(Comp) | BIT(BackComp);

   if (mUsed & (BIT(Clino) | BIT(BackClino)))
      mUsed |= BIT(Clino) | BIT(BackClino);

   if (mUsed & (BIT(FrDepth) | BIT(ToDepth)))
      mUsed |= BIT(Depth) | BIT(DepthChange);
   else if (TSTBIT(mUsed, Depth))
      mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange);
   else if (TSTBIT(mUsed, DepthChange))
      mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(Depth);

   if (mUsed & (BIT(FrCount) | BIT(ToCount)))
      mUsed |= BIT(Count) | BIT(Tape);
   else if (TSTBIT(mUsed, Count))
      mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Tape);
   else if (TSTBIT(mUsed, Tape))
      mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Count);

#if 0
   printf("mUsed = 0x%x, opt = 0x%x, mask = 0x%x\n", mUsed,
	  mask_optional[style], mask[style]);
#endif

   if (((mUsed &~ BIT(Newline)) | mask_optional[style]) != mask[style]) {
      /* Test should only fail with too few bits set, not too many */
      SVX_ASSERT((((mUsed &~ BIT(Newline)) | mask_optional[style])
	      &~ mask[style]) == 0);
      compile_error_skip(/*Too few readings for data style “%s”*/64, style_name);
      osfree(style_name);
      osfree(new_order);
      return;
   }

   /* don't free default ordering or ordering used by parent */
   if (pcs->ordering != default_order &&
       !(pcs->next && pcs->next->ordering == pcs->ordering))
      osfree(pcs->ordering);

   pcs->style = style;
   pcs->ordering = new_order;

   osfree(style_name);

   if (style == STYLE_PASSAGE) {
      lrudlist * new_psg = osnew(lrudlist);
      new_psg->tube = NULL;
      new_psg->next = model;
      model = new_psg;
      next_lrud = &(new_psg->tube);
   }
}
コード例 #20
0
void
msg_init(char * const *argv)
{
   char *p;
   SVX_ASSERT(argv);

   /* Point to argv[0] itself so we report a more helpful error if the
    * code to work out the clean appname generates a signal */
   appname_copy = argv[0];
#if OS_UNIX
   /* use name as-is on Unix - programs run from path get name as supplied */
   appname_copy = osstrdup(argv[0]);
#else
   /* use the lower-cased leafname on other platforms */
   p = leaf_from_fnm(argv[0]);
   appname_copy = p;
   while (*p) {
      *p = tolower(*p);
      ++p;
   }
#endif

   /* shortcut --version so you can check the version number even when the
    * correct message file can't be found... */
   if (argv[1] && strcmp(argv[1], "--version") == 0) {
      cmdline_version();
      exit(0);
   }
   if (argv[0]) {
      exe_pth = path_from_fnm(argv[0]);
#ifdef MACOSX_BUNDLE
      /* If we're being built into a bundle, always look relative to
       * the path to the binary. */
#ifdef AVEN
      /* Aven is packaged as an application, so we must look inside there. */
      pth_cfg_files = use_path(exe_pth, "../Resources");
#else
      pth_cfg_files = use_path(exe_pth, "share/survex");
#endif
#elif OS_UNIX && defined DATADIR && defined PACKAGE
      bool free_pth = fFalse;
      char *pth = getenv("srcdir");
      if (!pth || !pth[0]) {
	 pth = path_from_fnm(argv[0]);
	 free_pth = fTrue;
      }
      if (pth[0]) {
	 struct stat buf;
#if OS_UNIX_MACOSX
	 /* On MacOS X the programs may be installed anywhere, with the
	  * share directory and the binaries in the same directory. */
	 p = use_path(pth, "share/survex/en.msg");
	 if (lstat(p, &buf) == 0 && S_ISREG(buf.st_mode)) {
	    pth_cfg_files = use_path(pth, "share/survex");
	    goto macosx_got_msg;
	 }
	 osfree(p);
	 /* The cavern which aven runs is a hardlinked copy alongside
	  * the aven binary.
	  */
	 p = use_path(pth, "../Resources/en.msg");
	 if (lstat(p, &buf) == 0 && S_ISREG(buf.st_mode)) {
	    pth_cfg_files = use_path(pth, "../Resources");
	    goto macosx_got_msg;
	 }
	 osfree(p);
#endif
	 /* If we're run with an explicit path, check if "../lib/en.msg"
	  * from the program's path exists, and if so look there for
	  * support files - this allows us to test binaries in the build
	  * tree easily. */
	 p = use_path(pth, "../lib/en.msg");
	 if (lstat(p, &buf) == 0) {
#ifdef S_ISREG
	    /* POSIX way */
	    if (S_ISREG(buf.st_mode)) {
	       pth_cfg_files = use_path(pth, "../lib");
	    }
#else
	    /* BSD way */
	    if ((buf.st_mode & S_IFMT) == S_IFREG) {
	       pth_cfg_files = use_path(pth, "../lib");
	    }
#endif
	 }
#if defined(__GNUC__) && defined(__APPLE_CC__)
macosx_got_msg:
#endif
	 osfree(p);
      }

      if (free_pth) osfree(pth);
#elif OS_WIN32
      DWORD len = 256;
      char *buf = NULL, *modname;
      while (1) {
	  DWORD got;
	  buf = osrealloc(buf, len);
	  got = GetModuleFileName(NULL, buf, len);
	  if (got < len) break;
	  len += len;
      }
      modname = buf;
      /* Strange Win32 nastiness - strip prefix "\\?\" if present */
      if (strncmp(modname, "\\\\?\\", 4) == 0) modname += 4;
      pth_cfg_files = path_from_fnm(modname);
      osfree(buf);
#else
      /* Get the path to the support files from argv[0] */
      pth_cfg_files = path_from_fnm(argv[0]);
#endif
   }

   msg_lang = getenv("SURVEXLANG");
#ifdef DEBUG
   fprintf(stderr, "msg_lang = %p (= \"%s\")\n", msg_lang, msg_lang?msg_lang:"(null)");
#endif

   msg_lang_explicit = fTrue;
   if (!msg_lang || !*msg_lang) {
      msg_lang_explicit = fFalse;
      msg_lang = getenv("LC_ALL");
   }
   if (!msg_lang || !*msg_lang) {
      msg_lang = getenv("LC_MESSAGES");
      if (!msg_lang || !*msg_lang) {
	 msg_lang = getenv("LANG");
	 /* Something (AutoCAD?) on Microsoft Windows sets LANG to a number. */
	 if (msg_lang && !isalpha(msg_lang[0])) msg_lang = NULL;
      }
      if (!msg_lang || !*msg_lang) {
#if OS_WIN32
	 LCID locid;
#endif
#ifdef DEFAULTLANG
	 msg_lang = STRING(DEFAULTLANG);
#else
	 msg_lang = "en";
#endif
#if OS_WIN32
	 /* GetUserDefaultUILanguage() requires Microsoft Windows 2000 or
	  * newer.  For older versions, we use GetUserDefaultLCID().
	  */
	 {
	    HMODULE win32 = GetModuleHandle(TEXT("kernel32.dll"));
	    FARPROC f = GetProcAddress(win32, "GetUserDefaultUILanguage");
	    if (f) {
	       typedef LANGID (WINAPI *func_GetUserDefaultUILanguage)(void);
	       func_GetUserDefaultUILanguage g;
	       g = (func_GetUserDefaultUILanguage)f;
	       locid = g();
	    } else {
	       locid = GetUserDefaultLCID();
	    }
	 }
	 if (locid) {
	    WORD langid = LANGIDFROMLCID(locid);
	    switch (PRIMARYLANGID(langid)) {
	     case LANG_BULGARIAN:
	       msg_lang = "bg";
	       break;
/* older mingw compilers don't seem to supply this value */
#ifndef LANG_CATALAN
# define LANG_CATALAN 0x03
#endif
	     case LANG_CATALAN:
	       msg_lang = "ca";
	       break;
	     case LANG_CHINESE:
	       msg_lang = "zh_CN";
	       break;
	     case LANG_ENGLISH:
	       if (SUBLANGID(langid) == SUBLANG_ENGLISH_US)
		  msg_lang = "en_US";
	       else
		  msg_lang = "en";
	       break;
	     case LANG_FRENCH:
	       msg_lang = "fr";
	       break;
	     case LANG_GERMAN:
	       switch (SUBLANGID(langid)) {
		case SUBLANG_GERMAN_SWISS:
		  msg_lang = "de_CH";
		  break;
		default:
		  msg_lang = "de";
	       }
	       break;
	     case LANG_GREEK:
	       msg_lang = "el";
	       break;
	     case LANG_HUNGARIAN:
	       msg_lang = "hu";
	       break;
	     case LANG_INDONESIAN:
	       msg_lang = "id";
	       break;
	     case LANG_ITALIAN:
	       msg_lang = "it";
	       break;
	     case LANG_POLISH:
	       msg_lang = "pl";
	       break;
	     case LANG_PORTUGUESE:
	       if (SUBLANGID(langid) == SUBLANG_PORTUGUESE_BRAZILIAN)
		  msg_lang = "pt_BR";
	       else
		  msg_lang = "pt";
	       break;
	     case LANG_ROMANIAN:
	       msg_lang = "ro";
	       break;
	     case LANG_RUSSIAN:
	       msg_lang = "ru";
	       break;
	     case LANG_SLOVAK:
	       msg_lang = "sk";
	       break;
	     case LANG_SPANISH:
	       msg_lang = "es";
	       break;
	    }
	 }
#endif
      }
   }
#ifdef DEBUG
   fprintf(stderr, "msg_lang = %p (= \"%s\")\n", msg_lang, msg_lang?msg_lang:"(null)");
#endif

   /* On Mandrake LANG defaults to C */
   if (strcmp(msg_lang, "C") == 0) msg_lang = "en";

   { /* If msg_lang has a country code, snip it out to give msg_lang2. */
      size_t b = 0;
      while (isalpha((unsigned char)msg_lang[b])) {
	 ++b;
      }
      if (msg_lang[b] == '_') {
	 char * tmp;
	 size_t e = b + 1;
	 while (isalpha((unsigned char)msg_lang[e])) {
	    ++e;
	 }
	 tmp = osstrdup(msg_lang);
	 memmove(tmp + b, tmp + e, strlen(tmp + e) + 1);
	 msg_lang2 = tmp;
      }
   }

#ifdef LC_MESSAGES
   /* try to setlocale() appropriately too */
   if (!setlocale(LC_MESSAGES, msg_lang)) {
      if (msg_lang2) {
	 (void)setlocale(LC_MESSAGES, msg_lang2);
      }
   }
#endif

   select_charset(default_charset());
}
コード例 #21
0
ファイル: extend.c プロジェクト: Cavewhere/survex
int
main(int argc, char **argv)
{
   const char *fnm_in, *fnm_out;
   char *desc;
   img_point pt;
   int result;
   point *fr = NULL, *to;
   double zMax = -DBL_MAX;
   point *p;
   const char *survey = NULL;
   const char *specfile = NULL;
   img *pimg;
   int have_xsect = 0;

   msg_init(argv);

   /* TRANSLATORS: Part of extend --help */
   cmdline_set_syntax_message(/*INPUT_3D_FILE [OUTPUT_3D_FILE]*/267, 0, NULL);
   cmdline_init(argc, argv, short_opts, long_opts, NULL, help, 1, 2);
   while (1) {
      int opt = cmdline_getopt();
      if (opt == EOF) break;
      if (opt == 's') survey = optarg;
      if (opt == 'p') specfile = optarg;
   }
   fnm_in = argv[optind++];
   if (argv[optind]) {
      fnm_out = argv[optind];
   } else {
      char * base_in = base_from_fnm(fnm_in);
      char * base_out = osmalloc(strlen(base_in) + 8);
      strcpy(base_out, base_in);
      strcat(base_out, "_extend");
      fnm_out = add_ext(base_out, EXT_SVX_3D);
      osfree(base_in);
      osfree(base_out);
   }

   /* try to open image file, and check it has correct header */
   pimg = img_open_survey(fnm_in, survey);
   if (pimg == NULL) fatalerror(img_error2msg(img_error()), fnm_in);

   putnl();
   puts(msg(/*Reading in data - please wait…*/105));

   htab = osmalloc(ossizeof(pfx*) * HTAB_SIZE);
   {
       int i;
       for (i = 0; i < HTAB_SIZE; ++i) htab[i] = NULL;
   }

   do {
      result = img_read_item(pimg, &pt);
      switch (result) {
      case img_MOVE:
	 fr = find_point(&pt);
	 break;
      case img_LINE:
	 if (!fr) {
	    result = img_BAD;
	    break;
	 }
	 to = find_point(&pt);
	 if (!(pimg->flags & (img_FLAG_SURFACE|img_FLAG_SPLAY)))
	    add_leg(fr, to, pimg->label, pimg->flags);
	 fr = to;
	 break;
      case img_LABEL:
	 to = find_point(&pt);
	 add_label(to, pimg->label, pimg->flags);
	 break;
      case img_BAD:
	 (void)img_close(pimg);
	 fatalerror(img_error2msg(img_error()), fnm_in);
	 break;
      case img_XSECT:
         have_xsect = 1;
         break;
      }
   } while (result != img_STOP);

   desc = osstrdup(pimg->title);

   if (specfile) {
      FILE *fs = NULL;
      char *fnm_used;
      /* TRANSLATORS: for extend: */
      printf(msg(/*Applying specfile: “%s”*/521), specfile);
      putnl();
      fs = fopenWithPthAndExt("", specfile, NULL, "r", &fnm_used);
      if (fs == NULL) fatalerror(/*Couldn’t open file “%s”*/93, specfile);
      while (!feof(fs)) {
	 char *lbuf = getline_alloc(fs, 32);
	 lineno++;
	 if (!lbuf)
	    fatalerror_in_file(fnm_used, lineno, /*Error reading file*/18);
	 parseconfigline(fnm_used, lbuf);
	 osfree(lbuf);
      }
      osfree(fnm_used);
   }

   if (start == NULL) { /* i.e. start wasn't specified in specfile */

      /* start at the highest entrance with some legs attached */
      for (p = headpoint.next; p != NULL; p = p->next) {
	 if (p->order > 0 && p->p.z > zMax) {
	    const stn *s;
	    for (s = p->stns; s; s = s->next) {
	       if (s->flags & img_SFLAG_ENTRANCE) {
		  start = p;
		  zMax = p->p.z;
		  break;
	       }
	    }
	 }
      }
      if (start == NULL) {
	 /* if no entrances with legs, start at the highest 1-node */
	 for (p = headpoint.next; p != NULL; p = p->next) {
	    if (p->order == 1 && p->p.z > zMax) {
	       start = p;
	       zMax = p->p.z;
	    }
	 }
	 /* of course we may have no 1-nodes... */
	 if (start == NULL) {
	    for (p = headpoint.next; p != NULL; p = p->next) {
	       if (p->order != 0 && p->p.z > zMax) {
		  start = p;
		  zMax = p->p.z;
	       }
	    }
	    if (start == NULL) {
	       /* There are no legs - just pick the highest station... */
	       for (p = headpoint.next; p != NULL; p = p->next) {
		  if (p->p.z > zMax) {
		     start = p;
		     zMax = p->p.z;
		  }
	       }
	       if (!start) fatalerror(/*No survey data*/43);
	    }
	 }
      }
   }

   /* TRANSLATORS: for extend:
    * Used to tell the user that a file is being written - %s is the filename
    */
   printf(msg(/*Writing %s…*/522), fnm_out);
   putnl();
   pimg_out = img_open_write(fnm_out, desc, img_FFLAG_EXTENDED);

   /* Only does single connected component currently. */
   do_stn(start, 0.0, NULL, ERIGHT, 0);

   if (have_xsect) {
      img_rewind(pimg);
      /* Read ahead on pimg before writing pimg_out so we find out if an
       * img_XSECT_END comes next. */
      char * label = NULL;
      int flags = 0;
      do {
	 result = img_read_item(pimg, &pt);
	 if (result == img_XSECT || result == img_XSECT_END) {
	    if (label) {
	       if (result == img_XSECT_END)
		  flags |= img_XFLAG_END;
	       img_write_item(pimg_out, img_XSECT, flags, label, 0, 0, 0);
	       osfree(label);
	       label = NULL;
	    }
	 }
	 if (result == img_XSECT) {
	    label = osstrdup(pimg->label);
	    flags = pimg->flags;
	    pimg_out->l = pimg->l;
	    pimg_out->r = pimg->r;
	    pimg_out->u = pimg->u;
	    pimg_out->d = pimg->d;
	 }
      } while (result != img_STOP);
   }

   (void)img_close(pimg);

   if (!img_close(pimg_out)) {
      (void)remove(fnm_out);
      fatalerror(img_error2msg(img_error()), fnm_out);
   }

   return EXIT_SUCCESS;
}
コード例 #22
0
/* if prefix is omitted: if PFX_OPT set return NULL, otherwise use longjmp */
extern prefix *
read_prefix(unsigned pfx_flags)
{
   bool f_optional = !!(pfx_flags & PFX_OPT);
   bool fSurvey = !!(pfx_flags & PFX_SURVEY);
   bool fSuspectTypo = !!(pfx_flags & PFX_SUSPECT_TYPO);
   prefix *back_ptr, *ptr;
   char *name;
   size_t name_len = 32;
   size_t i;
   bool fNew;
   bool fImplicitPrefix = fTrue;
   int depth = -1;
   filepos fp_firstsep;

   skipblanks();
#ifndef NO_DEPRECATED
   if (isRoot(ch)) {
      if (!(pfx_flags & PFX_ALLOW_ROOT)) {
	 compile_diagnostic(DIAG_ERR|DIAG_COL, /*ROOT is deprecated*/25);
	 LONGJMP(file.jbSkipLine);
      }
      if (root_depr_count < 5) {
	 compile_diagnostic(DIAG_WARN|DIAG_COL, /*ROOT is deprecated*/25);
	 if (++root_depr_count == 5)
	    compile_diagnostic(DIAG_WARN, /*Further uses of this deprecated feature will not be reported*/95);
      }
      nextch();
      ptr = root;
      if (!isNames(ch)) {
	 if (!isSep(ch)) return ptr;
	 /* Allow optional SEPARATOR after ROOT */
	 get_pos(&fp_firstsep);
	 nextch();
      }
      fImplicitPrefix = fFalse;
#else
   if (0) {
#endif
   } else {
      if ((pfx_flags & PFX_ANON) &&
	  (isSep(ch) || (pcs->dash_for_anon_wall_station && ch == '-'))) {
	 int first_ch = ch;
	 filepos here;
	 get_pos(&here);
	 nextch();
	 if (isBlank(ch) || isEol(ch)) {
	    if (!isSep(first_ch))
	       goto anon_wall_station;
	    /* A single separator alone ('.' by default) is an anonymous
	     * station which is on a point inside the passage and implies
	     * the leg to it is a splay.
	     */
	    if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) {
	       set_pos(&here);
	       compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3);
	       LONGJMP(file.jbSkipLine);
	    }
	    pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY);
	    return new_anon_station();
	 }
	 if (isSep(first_ch) && ch == first_ch) {
	    nextch();
	    if (isBlank(ch) || isEol(ch)) {
	       /* A double separator ('..' by default) is an anonymous station
		* which is on the wall and implies the leg to it is a splay.
		*/
	       prefix * pfx;
anon_wall_station:
	       if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) {
		  set_pos(&here);
		  compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3);
		  LONGJMP(file.jbSkipLine);
	       }
	       pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY);
	       pfx = new_anon_station();
	       pfx->sflags |= BIT(SFLAGS_WALL);
	       return pfx;
	    }
	    if (ch == first_ch) {
	       nextch();
	       if (isBlank(ch) || isEol(ch)) {
		  /* A triple separator ('...' by default) is an anonymous
		   * station, but otherwise not handled specially (e.g. for
		   * a single leg down an unexplored side passage to a station
		   * which isn't refindable).
		   */
		  if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) {
		     set_pos(&here);
		     compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3);
		     LONGJMP(file.jbSkipLine);
		  }
		  pcs->flags |= BIT(FLAGS_ANON_ONE_END);
		  return new_anon_station();
	       }
	    }
	 }
	 set_pos(&here);
      }
      ptr = pcs->Prefix;
   }

   i = 0;
   name = NULL;
   do {
      fNew = fFalse;
      if (name == NULL) {
	 /* Need a new name buffer */
	 name = osmalloc(name_len);
      }
      /* i==0 iff this is the first pass */
      if (i) {
	 i = 0;
	 nextch();
      }
      while (isNames(ch)) {
	 if (i < pcs->Truncate) {
	    /* truncate name */
	    name[i++] = (pcs->Case == LOWER ? tolower(ch) :
			 (pcs->Case == OFF ? ch : toupper(ch)));
	    if (i >= name_len) {
	       name_len = name_len + name_len;
	       name = osrealloc(name, name_len);
	    }
	 }
	 nextch();
      }
      if (isSep(ch)) {
	 fImplicitPrefix = fFalse;
	 get_pos(&fp_firstsep);
      }
      if (i == 0) {
	 osfree(name);
	 if (!f_optional) {
	    if (isEol(ch)) {
	       if (fSurvey) {
		  compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting survey name*/89);
	       } else {
		  compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting station name*/28);
	       }
	    } else {
	       /* TRANSLATORS: Here "station" is a survey station, not a train station. */
	       compile_diagnostic(DIAG_ERR|DIAG_COL, /*Character “%c” not allowed in station name (use *SET NAMES to set allowed characters)*/7, ch);
	    }
	    LONGJMP(file.jbSkipLine);
	 }
	 return (prefix *)NULL;
      }

      name[i++] = '\0';

      back_ptr = ptr;
      ptr = ptr->down;
      if (ptr == NULL) {
	 /* Special case first time around at each level */
	 name = osrealloc(name, i);
	 ptr = osnew(prefix);
	 ptr->ident = name;
	 name = NULL;
	 ptr->right = ptr->down = NULL;
	 ptr->pos = NULL;
	 ptr->shape = 0;
	 ptr->stn = NULL;
	 ptr->up = back_ptr;
	 ptr->filename = file.filename;
	 ptr->line = file.line;
	 ptr->min_export = ptr->max_export = 0;
	 ptr->sflags = BIT(SFLAGS_SURVEY);
	 if (fSuspectTypo && !fImplicitPrefix)
	    ptr->sflags |= BIT(SFLAGS_SUSPECTTYPO);
	 back_ptr->down = ptr;
	 fNew = fTrue;
      } else {
	 /* Use caching to speed up adding an increasing sequence to a
	  * large survey */
	 static prefix *cached_survey = NULL, *cached_station = NULL;
	 prefix *ptrPrev = NULL;
	 int cmp = 1; /* result of strcmp ( -ve for <, 0 for =, +ve for > ) */
	 if (cached_survey == back_ptr) {
	    cmp = strcmp(cached_station->ident, name);
	    if (cmp <= 0) ptr = cached_station;
	 }
	 while (ptr && (cmp = strcmp(ptr->ident, name))<0) {
	    ptrPrev = ptr;
	    ptr = ptr->right;
	 }
	 if (cmp) {
	    /* ie we got to one that was higher, or the end */
	    prefix *newptr;
	    name = osrealloc(name, i);
	    newptr = osnew(prefix);
	    newptr->ident = name;
	    name = NULL;
	    if (ptrPrev == NULL)
	       back_ptr->down = newptr;
	    else
	       ptrPrev->right = newptr;
	    newptr->right = ptr;
	    newptr->down = NULL;
	    newptr->pos = NULL;
	    newptr->shape = 0;
	    newptr->stn = NULL;
	    newptr->up = back_ptr;
	    newptr->filename = file.filename;
	    newptr->line = file.line;
	    newptr->min_export = newptr->max_export = 0;
	    newptr->sflags = BIT(SFLAGS_SURVEY);
	    if (fSuspectTypo && !fImplicitPrefix)
	       newptr->sflags |= BIT(SFLAGS_SUSPECTTYPO);
	    ptr = newptr;
	    fNew = fTrue;
	 }
	 cached_survey = back_ptr;
	 cached_station = ptr;
      }
      depth++;
      f_optional = fFalse; /* disallow after first level */
      if (isSep(ch)) get_pos(&fp_firstsep);
   } while (isSep(ch));
   if (name) osfree(name);

   /* don't warn about a station that is referred to twice */
   if (!fNew) ptr->sflags &= ~BIT(SFLAGS_SUSPECTTYPO);

   if (fNew) {
      /* fNew means SFLAGS_SURVEY is currently set */
      SVX_ASSERT(TSTBIT(ptr->sflags, SFLAGS_SURVEY));
      if (!fSurvey) {
	 ptr->sflags &= ~BIT(SFLAGS_SURVEY);
	 if (TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX;
      }
   } else {
      /* check that the same name isn't being used for a survey and station */
      if (fSurvey ^ TSTBIT(ptr->sflags, SFLAGS_SURVEY)) {
	 /* TRANSLATORS: Here "station" is a survey station, not a train station.
	  *
	  * Here "survey" is a "cave map" rather than list of questions - it should be
	  * translated to the terminology that cavers using the language would use.
	  */
	 compile_diagnostic(DIAG_ERR, /*“%s” can’t be both a station and a survey*/27,
			    sprint_prefix(ptr));
      }
      if (!fSurvey && TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX;
   }

   /* check the export level */
#if 0
   printf("R min %d max %d depth %d pfx %s\n",
	  ptr->min_export, ptr->max_export, depth, sprint_prefix(ptr));
#endif
   if (ptr->min_export == 0 || ptr->min_export == USHRT_MAX) {
      if (depth > ptr->max_export) ptr->max_export = depth;
   } else if (ptr->max_export < depth) {
      prefix *survey = ptr;
      char *s;
      const char *p;
      int level;
      for (level = ptr->max_export + 1; level; level--) {
	 survey = survey->up;
	 SVX_ASSERT(survey);
      }
      s = osstrdup(sprint_prefix(survey));
      p = sprint_prefix(ptr);
      if (survey->filename) {
	 compile_diagnostic_pfx(DIAG_ERR, survey,
				/*Station “%s” not exported from survey “%s”*/26,
				p, s);
      } else {
	 compile_diagnostic(DIAG_ERR, /*Station “%s” not exported from survey “%s”*/26, p, s);
      }
      osfree(s);
#if 0
      printf(" *** pfx %s warning not exported enough depth %d "
	     "ptr->max_export %d\n", sprint_prefix(ptr),
	     depth, ptr->max_export);
#endif
   }
   if (!fImplicitPrefix && (pfx_flags & PFX_WARN_SEPARATOR)) {
      filepos fp_tmp;
      get_pos(&fp_tmp);
      set_pos(&fp_firstsep);
      compile_diagnostic(DIAG_WARN|DIAG_COL, /*Separator in survey name*/392);
      set_pos(&fp_tmp);
   }
   return ptr;
}

/* if numeric expr is omitted: if f_optional return HUGE_REAL, else longjmp */
static real
read_number(bool f_optional)
{
   bool fPositive, fDigits = fFalse;
   real n = (real)0.0;
   filepos fp;
   int ch_old;

   get_pos(&fp);
   ch_old = ch;
   fPositive = !isMinus(ch);
   if (isSign(ch)) nextch();

   while (isdigit(ch)) {
      n = n * (real)10.0 + (char)(ch - '0');
      nextch();
      fDigits = fTrue;
   }

   if (isDecimal(ch)) {
      real mult = (real)1.0;
      nextch();
      while (isdigit(ch)) {
	 mult *= (real).1;
	 n += (char)(ch - '0') * mult;
	 fDigits = fTrue;
	 nextch();
      }
   }

   /* !'fRead' => !fDigits so fDigits => 'fRead' */
   if (fDigits) return (fPositive ? n : -n);

   /* didn't read a valid number.  If it's optional, reset filepos & return */
   set_pos(&fp);
   if (f_optional) {
      return HUGE_REAL;
   }

   if (isOmit(ch_old)) {
      compile_diagnostic(DIAG_ERR|DIAG_COL, /*Field may not be omitted*/8);
   } else {
      compile_diagnostic_token_show(DIAG_ERR, /*Expecting numeric field, found “%s”*/9);
   }
   LONGJMP(file.jbSkipLine);
   return 0.0; /* for brain-fried compilers */
}
コード例 #23
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;
}
コード例 #24
0
ファイル: img.c プロジェクト: mdornseif/therion
img *
img_open_write(const char *fnm, char *title_buf, bool fBinary)
{
   time_t tm;
   img *pimg;

   fBinary = fBinary;

   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 = fopen(fnm, "wb");
   if (!pimg->fh) {
      osfree(pimg->label_buf);
      osfree(pimg);
      img_errno = IMG_CANTOPENOUT;
      return NULL;
   }

   /* Output image file header */
   fputs("Survex 3D Image File\n", pimg->fh); /* file identifier string */
   if (img_output_version < 2) {
      pimg->version = 1;
      fputs("Bv0.01\n", pimg->fh); /* binary file format version number */
   } else {
      pimg->version = (img_output_version > LATEST_IMG_VERSION) ? LATEST_IMG_VERSION : img_output_version;
      fprintf(pimg->fh, "v%d\n", pimg->version); /* file format version no. */
   }
   fputsnl(title_buf, pimg->fh);
   tm = time(NULL);
   if (tm == (time_t)-1) {
      fputsnl(TIMENA, pimg->fh);
   } else {
      char date[256];
      /* output current date and time in format specified */
      strftime(date, 256, TIMEFMT, localtime(&tm));
      fputsnl(date, pimg->fh);
   }
#if 0
   if (img_output_version >= 5) {
       static const unsigned char codelengths[32] = {
	   4,  8,  8,  16, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
       };
       fwrite(codelengths, 32, 1, pimg->fh);
   }
#endif
   pimg->fRead = fFalse; /* writing to this file */
   img_errno = IMG_NONE;

   /* for version >= 3 we use label_buf to store the prefix for reuse */
   pimg->label_buf[0] = '\0';
   pimg->label_len = 0;

   pimg->date1 = 0;
   pimg->date2 = 0;

   pimg->olddate1 = 0;
   pimg->olddate2 = 0;

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

   pimg->n_legs = 0;
   pimg->length = 0.0;
   pimg->E = pimg->H = pimg->V = 0.0;

   /* Don't check for write errors now - let img_close() report them... */
   return pimg;
}
コード例 #25
0
ファイル: netartic.c プロジェクト: RobDeBagel/survex
extern void
articulate(void)
{
   node *stn, *stnStart;
   int i;
   long cFixed;

   component_list = NULL;
   articulation_list = NULL;
   artlist = NULL;
   fixedlist = NULL;

   /* find articulation points and components */
   colour = 0;
   stnStart = NULL;
   cMaxVisits = 0;
   FOR_EACH_STN(stn, stnlist) {
      if (fixed(stn)) {
	 remove_stn_from_list(&stnlist, stn);
	 add_stn_to_list(&fixedlist, stn);
	 colour++;
	 stn->colour = -colour;
#ifdef DEBUG_ARTIC
	 printf("Putting stn ");
	 print_prefix(stn->name);
	 printf(" on fixedlist\n");
#endif
      } else {
	 cMaxVisits++;
	 stn->colour = 0;
      }
   }
   dirn_stack = osmalloc(cMaxVisits);
   min_stack = osmalloc(cMaxVisits * sizeof(long));

   /* fixedlist can be NULL here if we've had a *solve followed by survey
    * which is all hanging. */
   cFixed = colour;
   while (fixedlist) {
      int c;
      stnStart = fixedlist;
      stn = stnStart;

      /* see if this is a fresh component - it may not be, we may be
       * processing the other way from a fixed point cut-line */
      if (stn->colour < 0) {
#ifdef DEBUG_ARTIC
	 printf("new component\n");
#endif
	 stn->colour = -stn->colour; /* fixed points are negative until we colour from them */
	 cComponents++;

	 /* FIXME: logic to count components isn't the same as the logic
	  * to start a new one - we should start a new one for a fixed point
	  * cut-line (see below) */
	 if (artlist) {
	     component *comp;
	     articulation *art;

	     art = osnew(articulation);
	     art->stnlist = artlist;
	     art->next = articulation_list;
	     articulation_list = art;
	     artlist = NULL;

	     comp = osnew(component);
	     comp->next = component_list;
	     comp->artic = articulation_list;
	     component_list = comp;
	     articulation_list = NULL;
	 }

#ifdef DEBUG_ARTIC
	 print_prefix(stn->name);
	 printf(" [%p] is root of component %ld\n", stn, cComponents);
	 printf(" and colour = %d/%d\n", stn->colour, cFixed);
#endif
      }

      c = 0;
      for (i = 0; i <= 2 && stn->leg[i]; i++) {
	 node *stn2 = stn->leg[i]->l.to;
	 if (stn2->colour < 0) {
	    stn2->colour = -stn2->colour;
	 } else if (stn2->colour == 0) {
	    /* Special case to check if start station is an articulation point
	     * which it is iff we have to colour from it in more than one dirn
	     *
	     * We're looking for articulation legs - these are those where
	     * colouring from here doesn't reach a fixed point (including
	     * stn - the fixed point we've started from)
	     *
	     * FIXME: this is a "fixed point cut-line" case where we could
	     * start a new component.
	     */
	    long col = visit(stn2, reverse_leg_dirn(stn->leg[i]));
#ifdef DEBUG_ARTIC
	    print_prefix(stn->name);
	    printf(" -> ");
	    print_prefix(stn2->name);
	    printf(" col %d cFixed %d\n", col, cFixed);
#endif
	    if (col > cFixed) {
		/* start new articulation - FIXME - overeager */
		articulation *art = osnew(articulation);
		art->stnlist = artlist;
		art->next = articulation_list;
		articulation_list = art;
		artlist = NULL;
		c |= 1 << i;
	    }
	 }
      }

      switch (c) {
       /* had to colour in 2 or 3 directions from start point */
       case 3: case 5: case 6: case 7:
#ifdef DEBUG_ARTIC
	 print_prefix(stn->name);
	 printf(" is a special case start articulation point [%d]\n", c);
#endif
	 for (i = 0; i <= 2 && stn->leg[i]; i++) {
	    if (TSTBIT(c, i)) {
	       /* flag leg as an articulation for loop error reporting */
	       stn->leg[i]->l.reverse |= FLAG_ARTICULATION;
#ifdef DEBUG_ARTIC
	       print_prefix(stn->leg[i]->l.to->name);
	       putnl();
#endif
	       reverse_leg(stn->leg[i])->l.reverse |= FLAG_ARTICULATION;
	    }
	 }
      }

#ifdef DEBUG_ARTIC
      printf("Putting FIXED stn ");
      print_prefix(stn->name);
      printf(" on artlist\n");
#endif
      remove_stn_from_list(&fixedlist, stn);
      add_stn_to_list(&artlist, stn);

      if (stnStart->colour == 1) {
#ifdef DEBUG_ARTIC
	 printf("%ld components\n",cComponents);
#endif
	 break;
      }
   }

   osfree(dirn_stack);
   dirn_stack = NULL;
   osfree(min_stack);
   min_stack = NULL;

   if (artlist) {
      articulation *art = osnew(articulation);
      art->stnlist = artlist;
      art->next = articulation_list;
      articulation_list = art;
      artlist = NULL;
   }
   if (articulation_list) {
      component *comp = osnew(component);
      comp->next = component_list;
      comp->artic = articulation_list;
      component_list = comp;
      articulation_list = NULL;
   }

   if (stnlist) {
      /* Any stations still in stnlist are unfixed, which is means we have
       * one or more hanging surveys.
       *
       * The cause of the problem is pretty likely to be a typo, so run the
       * checks which report errors and warnings about issues which such a
       * typo is likely to result in.
       */
      check_node_stats();

      /* Actually this error is fatal, but we want to list the survey
       * stations which aren't connected, so we report it as an error
       * and die after listing them...
       */
      bool fNotAttached = fFalse;
      error(/*Survey not all connected to fixed stations*/45);
      FOR_EACH_STN(stn, stnlist) {
	 /* Anonymous stations must be at the end of a trailing traverse (since
	  * the same anonymous station can't be referred to more than once),
	  * and trailing traverses have been removed at this point.
	  */
	 SVX_ASSERT(!TSTBIT(stn->name->sflags, SFLAGS_ANON));
	 if (stn->name->ident) {
	    if (!fNotAttached) {
	       fNotAttached = fTrue;
	       puts(msg(/*The following survey stations are not attached to a fixed point:*/71));
	    }
	    puts(sprint_prefix(stn->name));
	 }
      }
      exit(EXIT_FAILURE);
   }