2021-05-30 07:14:16 +08:00
|
|
|
/*
|
|
|
|
* Copyright 2018, University Corporation for Atmospheric Research
|
|
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2022-04-29 05:51:20 +08:00
|
|
|
#ifdef HAVE_GETOPT_H
|
|
|
|
#include <getopt.h>
|
|
|
|
#endif
|
|
|
|
|
2021-05-30 07:14:16 +08:00
|
|
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
|
|
|
#include "XGetopt.h"
|
2021-09-03 07:04:26 +08:00
|
|
|
#else
|
|
|
|
#include <getopt.h>
|
2021-05-30 07:14:16 +08:00
|
|
|
#endif
|
|
|
|
|
2021-09-03 07:04:26 +08:00
|
|
|
#include "netcdf.h"
|
2021-05-30 07:14:16 +08:00
|
|
|
#include "ncpathmgr.h"
|
|
|
|
|
2021-12-24 13:18:56 +08:00
|
|
|
static const char* USAGE =
|
2022-05-15 06:05:48 +08:00
|
|
|
"ncpathcvt [-c|-C|-m|-u|-w] [-h] [-e] [-F] [-d <driveletter>] [-B<char>] [-k] [-p] PATH\n"
|
2021-12-24 13:18:56 +08:00
|
|
|
"Options\n"
|
|
|
|
" -h help"
|
|
|
|
" -e add backslash escapes to '\' and ' '\n"
|
|
|
|
" -d <driveletter> use driveletter when needed; defaults to 'c'\n"
|
2022-05-15 06:05:48 +08:00
|
|
|
" -B <char> convert occurrences of <char> to blank\n"
|
|
|
|
" -F convert occurrences of '\\' to '/'"
|
2021-12-24 13:18:56 +08:00
|
|
|
"Output type options:\n"
|
|
|
|
" -c convert to Cygwin form of path\n"
|
|
|
|
" -C return canonical form of path\n"
|
|
|
|
" -m convert to MSYS form of path\n"
|
|
|
|
" -u convert to Unix form of path\n"
|
|
|
|
" -w convert to Windows form of path\n"
|
|
|
|
"Other options:\n"
|
|
|
|
" -k return kind of the local environment\n"
|
|
|
|
" -p return kind of the input path\n"
|
|
|
|
"\n"
|
|
|
|
"Default is to convert to the format used by the platform.\n"
|
|
|
|
;
|
2021-05-30 07:14:16 +08:00
|
|
|
|
2021-09-03 07:04:26 +08:00
|
|
|
#undef DEBUG
|
2021-05-30 07:14:16 +08:00
|
|
|
|
|
|
|
struct Options {
|
|
|
|
int target;
|
2021-06-06 04:12:21 +08:00
|
|
|
int escapes;
|
|
|
|
int drive;
|
2021-05-30 07:14:16 +08:00
|
|
|
int debug;
|
2021-12-24 13:18:56 +08:00
|
|
|
int canon;
|
|
|
|
int blank;
|
2022-05-15 06:05:48 +08:00
|
|
|
int slash;
|
2021-12-24 13:18:56 +08:00
|
|
|
int pathkind;
|
2021-05-30 07:14:16 +08:00
|
|
|
} cvtoptions;
|
|
|
|
|
2021-05-31 06:12:40 +08:00
|
|
|
static char* escape(const char* path);
|
|
|
|
static void usage(const char* msg);
|
2021-05-30 07:14:16 +08:00
|
|
|
|
2021-09-03 07:04:26 +08:00
|
|
|
static void
|
|
|
|
usage(const char* msg)
|
|
|
|
{
|
|
|
|
if(msg != NULL) fprintf(stderr,"%s\n",msg);
|
2021-12-24 13:18:56 +08:00
|
|
|
fprintf(stderr,"%s",USAGE);
|
2021-09-03 07:04:26 +08:00
|
|
|
if(msg == NULL) exit(0); else exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
escape(const char* path)
|
|
|
|
{
|
|
|
|
size_t slen = strlen(path);
|
|
|
|
const char* p;
|
|
|
|
char* q;
|
|
|
|
char* epath = NULL;
|
|
|
|
const char* escapes = " \\";
|
|
|
|
|
|
|
|
epath = (char*)malloc((2*slen) + 1);
|
|
|
|
if(epath == NULL) usage("out of memtory");
|
|
|
|
p = path;
|
|
|
|
q = epath;
|
|
|
|
for(;*p;p++) {
|
|
|
|
if(strchr(escapes,*p) != NULL)
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = *p;
|
|
|
|
}
|
|
|
|
*q = '\0';
|
|
|
|
return epath;
|
|
|
|
}
|
|
|
|
|
2022-05-15 06:05:48 +08:00
|
|
|
static char*
|
|
|
|
slash(const char* path)
|
|
|
|
{
|
|
|
|
size_t slen = strlen(path);
|
|
|
|
const char* p;
|
|
|
|
char* q;
|
|
|
|
char* epath = NULL;
|
|
|
|
|
|
|
|
epath = (char*)malloc(slen + 1);
|
|
|
|
if(epath == NULL) usage("out of memtory");
|
|
|
|
p = path;
|
|
|
|
q = epath;
|
|
|
|
for(;*p;p++) {
|
|
|
|
if(*p == '\\')
|
|
|
|
*q++ = '/';
|
|
|
|
else *q++ = *p;
|
|
|
|
}
|
|
|
|
*q = '\0';
|
|
|
|
return epath;
|
|
|
|
}
|
|
|
|
|
2021-12-24 13:18:56 +08:00
|
|
|
void
|
|
|
|
printlocalkind(void)
|
|
|
|
{
|
|
|
|
const char* s = NULL;
|
|
|
|
int kind = NCgetlocalpathkind();
|
|
|
|
switch (kind) {
|
|
|
|
case NCPD_NIX: s = "unix"; break;
|
|
|
|
case NCPD_MSYS: s = "msys"; break;
|
|
|
|
case NCPD_CYGWIN: s = "cygwin"; break;
|
|
|
|
case NCPD_WIN: s = "win"; break;
|
|
|
|
default: s = "unknown"; break;
|
|
|
|
}
|
|
|
|
printf("%s",s);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
printenv(void)
|
|
|
|
{
|
|
|
|
#ifdef __CYGWIN__
|
|
|
|
printf(" __CYGWIN__");
|
|
|
|
#else
|
|
|
|
printf(" !__CYGWIN__");
|
|
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
printf(" _MSC_VER");
|
|
|
|
#else
|
|
|
|
printf(" !_MSC_VER");
|
|
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
|
|
printf(" _WIN32");
|
|
|
|
#else
|
|
|
|
printf(" !_WIN32");
|
|
|
|
#endif
|
|
|
|
#ifdef __MSYS__
|
|
|
|
printf(" __MSYS__");
|
|
|
|
#else
|
|
|
|
printf(" !__MSYS__");
|
|
|
|
#endif
|
|
|
|
#ifdef __MSYS2__
|
|
|
|
printf(" __MSYS2__");
|
|
|
|
#else
|
|
|
|
printf(" !__MSYS2__");
|
|
|
|
#endif
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
printf(" __MINGW32__");
|
|
|
|
#else
|
|
|
|
printf(" !__MINGW32__");
|
|
|
|
#endif
|
|
|
|
printf("\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
printpathkind(const char* path)
|
|
|
|
{
|
|
|
|
const char* s = NULL;
|
|
|
|
int kind = NCgetinputpathkind(path);
|
|
|
|
switch (kind) {
|
|
|
|
case NCPD_NIX: s = "unix"; break;
|
|
|
|
case NCPD_MSYS: s = "msys"; break;
|
|
|
|
case NCPD_CYGWIN: s = "cygwin"; break;
|
|
|
|
case NCPD_WIN: s = "win"; break;
|
|
|
|
case NCPD_REL: s = "relative"; break;
|
|
|
|
default: s = "unknown"; break;
|
|
|
|
}
|
|
|
|
printf("%s",s);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2021-05-30 07:14:16 +08:00
|
|
|
int
|
|
|
|
main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
char* cvtpath = NULL;
|
2022-06-08 04:28:01 +08:00
|
|
|
char* inpath, *canon = NULL;
|
2021-05-30 07:14:16 +08:00
|
|
|
|
|
|
|
memset((void*)&cvtoptions,0,sizeof(cvtoptions));
|
2021-06-06 04:12:21 +08:00
|
|
|
cvtoptions.drive = 'c';
|
2021-05-30 07:14:16 +08:00
|
|
|
|
2022-05-15 06:05:48 +08:00
|
|
|
while ((c = getopt(argc, argv, "B:CFcD:d:ehkmpuwX")) != EOF) {
|
2021-05-30 07:14:16 +08:00
|
|
|
switch(c) {
|
|
|
|
case 'c': cvtoptions.target = NCPD_CYGWIN; break;
|
2021-06-06 04:12:21 +08:00
|
|
|
case 'd': cvtoptions.drive = optarg[0]; break;
|
|
|
|
case 'e': cvtoptions.escapes = 1; break;
|
2021-05-30 07:14:16 +08:00
|
|
|
case 'h': usage(NULL); break;
|
2021-12-24 13:18:56 +08:00
|
|
|
case 'k': printlocalkind(); break;
|
2021-05-30 07:14:16 +08:00
|
|
|
case 'm': cvtoptions.target = NCPD_MSYS; break;
|
2021-12-24 13:18:56 +08:00
|
|
|
case 'p': cvtoptions.pathkind = 1; break;
|
2021-05-30 07:14:16 +08:00
|
|
|
case 'u': cvtoptions.target = NCPD_NIX; break;
|
|
|
|
case 'w': cvtoptions.target = NCPD_WIN; break;
|
2021-12-24 13:18:56 +08:00
|
|
|
case 'B':
|
2021-12-24 14:10:44 +08:00
|
|
|
cvtoptions.blank = optarg[0];
|
2021-12-24 13:18:56 +08:00
|
|
|
if(cvtoptions.blank < ' ' || cvtoptions.blank == '\177')
|
|
|
|
usage("Bad -B argument");
|
|
|
|
break;
|
|
|
|
case 'C': cvtoptions.canon = 1; break;
|
2022-05-15 06:05:48 +08:00
|
|
|
case 'F': cvtoptions.slash = 1; break;
|
2021-05-30 07:14:16 +08:00
|
|
|
case 'D':
|
|
|
|
sscanf(optarg,"%d",&cvtoptions.debug);
|
|
|
|
break;
|
2021-12-24 13:18:56 +08:00
|
|
|
case 'X': printenv(); break;
|
2021-05-30 07:14:16 +08:00
|
|
|
case '?':
|
|
|
|
usage("unknown option");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
/* If no file arguments left or more than one, print usage message. */
|
|
|
|
if (argc == 0)
|
|
|
|
usage("no path specified");
|
|
|
|
if (argc > 1)
|
|
|
|
usage("more than one path specified");
|
2021-12-24 13:18:56 +08:00
|
|
|
|
|
|
|
/* translate blanks */
|
|
|
|
inpath = (char*)malloc(strlen(argv[0])+1);
|
|
|
|
if(inpath == NULL) usage("Out of memory");
|
|
|
|
{
|
|
|
|
const char* p = argv[0];
|
|
|
|
char* q = inpath;
|
|
|
|
for(;*p;p++) {
|
|
|
|
char c = *p;
|
|
|
|
if(c == cvtoptions.blank) c = ' ';
|
|
|
|
*q++ = c;
|
|
|
|
}
|
|
|
|
*q = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if(cvtoptions.pathkind) {
|
|
|
|
printpathkind(inpath);
|
|
|
|
goto done;
|
|
|
|
}
|
2021-09-03 07:04:26 +08:00
|
|
|
|
|
|
|
/* Canonicalize */
|
|
|
|
if(NCpathcanonical(inpath,&canon))
|
|
|
|
usage("Could not convert to canonical form");
|
|
|
|
|
2021-12-24 13:18:56 +08:00
|
|
|
if(cvtoptions.canon) {
|
|
|
|
cvtpath = canon; canon = NULL;
|
|
|
|
} else if(cvtoptions.target == NCPD_UNKNOWN) {
|
2021-09-03 07:04:26 +08:00
|
|
|
cvtpath = NCpathcvt(canon);
|
2021-12-24 13:18:56 +08:00
|
|
|
} else {
|
2021-09-03 07:04:26 +08:00
|
|
|
cvtpath = NCpathcvt_test(canon,cvtoptions.target,(char)cvtoptions.drive);
|
2021-12-24 13:18:56 +08:00
|
|
|
}
|
|
|
|
|
2021-06-06 04:12:21 +08:00
|
|
|
if(cvtpath && cvtoptions.escapes) {
|
2021-05-31 06:12:40 +08:00
|
|
|
char* path = cvtpath; cvtpath = NULL;
|
|
|
|
cvtpath = escape(path);
|
|
|
|
free(path);
|
|
|
|
}
|
2022-05-15 06:05:48 +08:00
|
|
|
if(cvtpath && cvtoptions.slash) {
|
|
|
|
char* path = cvtpath; cvtpath = NULL;
|
|
|
|
cvtpath = slash(path);
|
|
|
|
free(path);
|
|
|
|
}
|
2021-05-30 07:14:16 +08:00
|
|
|
printf("%s",cvtpath);
|
2021-12-24 13:18:56 +08:00
|
|
|
done:
|
2021-09-03 07:04:26 +08:00
|
|
|
if(canon) free(canon);
|
2021-12-24 13:18:56 +08:00
|
|
|
if(inpath) free(inpath);
|
2021-05-30 07:14:16 +08:00
|
|
|
if(cvtpath) free(cvtpath);
|
|
|
|
return 0;
|
|
|
|
}
|
2021-05-31 06:12:40 +08:00
|
|
|
|