X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=nucleus%2Flibrary%2Ffilesystem%2Ffilename.cpp;h=843b286cf099bf0fcdd0a1fbfe6e74933b2c7862;hb=cf3d63de321ae4a18860c4be8a968eb906ddd2fe;hp=a77035baeabb3f795ad586b79ba471da3c62e0f9;hpb=1d0e3f784ca8c86185013026e8500f8460aefe8e;p=feisty_meow.git diff --git a/nucleus/library/filesystem/filename.cpp b/nucleus/library/filesystem/filename.cpp index a77035ba..843b286c 100644 --- a/nucleus/library/filesystem/filename.cpp +++ b/nucleus/library/filesystem/filename.cpp @@ -20,14 +20,14 @@ #include #include #include +#include #include #include #include -#ifdef __UNIX__ +#if defined(__UNIX__) || defined(__GNU_WINDOWS__) #include -#endif -#ifdef __WIN32__ +#else #include #endif @@ -43,13 +43,13 @@ class status_info : public stat namespace filesystem { -#if defined(__WIN32__) || defined(__VMS__) - const char DEFAULT_SEPARATOR = '\\'; -#elif defined(__UNIX__) +//#if defined(__WIN32__) || defined(__VMS__) +// const char DEFAULT_SEPARATOR = '\\'; +//#elif defined(__UNIX__) const char DEFAULT_SEPARATOR = '/'; -#else - #error "We have no idea what the default path separator is." -#endif +//#else +// #error "We have no idea what the default path separator is." +//#endif const char *NO_PARENT_DEFAULT = "."; // used when no directory name can be popped off. @@ -100,6 +100,12 @@ bool filename::good() const { return exists(); } bool filename::unlink() const { return ::unlink(observe()) == 0; } +void filename::reset(const astring &name) { + *this = name; + _had_directory = true; // until we know better. + canonicalize(); +} + astring filename::null_device() { #ifdef __WIN32__ @@ -185,14 +191,24 @@ void filename::canonicalize() // on windows, we want to translate away from any cygwin or msys format into a more palatable // version that the rest of windows understands. // first, cygwin... - const astring CYGDRIVE_PATH = astring(astring(DEFAULT_SEPARATOR, 1) + "cygdrive" - + astring(DEFAULT_SEPARATOR, 1)); +//hmmm: make these into statics! + const astring CYGDRIVE_SENTINEL = "cygdrive"; + const astring CYGDRIVE_PATH = astring(astring(DEFAULT_SEPARATOR, 1) + + CYGDRIVE_SENTINEL + astring(DEFAULT_SEPARATOR, 1)); + // must be at least as long as the string we're looking for, plus a drive letter afterwards. - if ( (length() > CYGDRIVE_PATH.length() + 1) && begins(CYGDRIVE_PATH) ) { + if ( (length() >= CYGDRIVE_PATH.length() + 1) + && separator(get(0)) + && separator(get(CYGDRIVE_PATH.length() - 1)) + && compare(CYGDRIVE_SENTINEL, 1, + 0, CYGDRIVE_SENTINEL.length(), true) ) { zap(0, CYGDRIVE_PATH.length() - 1); // whack the cygdrive portion plus two slashes. insert(1, ":"); // add a colon after the imputed drive letter. -LOG(astring("turned cygdrive string into: ") + *this); +//LOG(astring("turned cygdrive path string into: ") + *this); + } else { +//LOG(astring("path didn't match so left as: ") + *this); } + // now we convert msys... if ( (length() >= 2) && (get(0) == DEFAULT_SEPARATOR) && textual::parser_bits::is_alpha(get(1)) ) { @@ -210,9 +226,43 @@ LOG(astring("turned cygdrive string into: ") + *this); // then only on the near defunct windows platform. zap(0, 0); // take off initial slash. insert(1, ":"); // add the obligatory colon. -LOG(astring("turned msys string into: ") + *this); +//LOG(astring("turned msys string into: ") + *this); } } + + // if we still have a unix style path here on windows, then there will be + // trouble when we pass that to the OS. we are not using any cygwin or + // other virtualization libraries directly, so we can't rely on those to + // fix the path. but if we built under something like cygwin, we should + // have stored the real dos-style location of the virtual unix root. we + // will use that to replace the root '/' and this should fix most of that + // style of path. + bool inject_root = false; // assume we don't need to do anything. + +//LOG(astring("before root injection: ") + raw()); + + // condition here just checks if the path is only the root. + if ( (length() == 1) && separator(get(0)) ) { inject_root = true; } + +//if (inject_root) LOG("decided to inject root since path is '/'."); + + // condition is looking for first character being a slash, and second char as alphanumeric or dash or underscore. + // we will currently fail detecting freaky paths that don't start off with alphanumeric or one of that small set of special chars. + if ( (length() >= 2) + && separator(get(0)) + && ( textual::parser_bits::is_alphanumeric(get(1)) || ('-' == get(1)) || ('_' == get(1)) ) ) { + inject_root = true; +//if (inject_root) LOG(astring("decided to inject root since path is compatible: ") + *this); + } + +//LOG(astring("after second phase root injection: ") + raw()); + + if (inject_root) { + // inject the actual path to the unix root in front, if we know it. + // if we don't know it, then a default path that's unlikely to work is idiotically plugged in. + insert(0, FEISTY_MEOW_VIRTUAL_UNIX_ROOT); +//LOG(astring("turned cygdrive path string into: ") + raw()); + } #endif // we don't crop the last separator if the name's too small. for msdos @@ -309,10 +359,15 @@ bool filename::is_normal() const status_info fill; if (!get_info(&fill)) return false; +#if defined(__WIN32__) || defined(__VMS__) +//hmmm: is there a corresponding set of functions for windows, where applicable? + bool weird = false; +#else bool weird = S_ISCHR(fill.st_mode) || S_ISBLK(fill.st_mode) || S_ISFIFO(fill.st_mode) || S_ISSOCK(fill.st_mode); +#endif return !weird; } @@ -372,11 +427,10 @@ bool filename::exists() const { if (is_directory()) return true; + // if the file name is empty, that cannot exist. if (!length()) return false; return is_readable(); -/// byte_filer opened(observe(), "rb"); -/// return opened.good(); } bool filename::legal_character(char to_check)