// Pre: pathComp forms a valid path for the platform. void composePath(const uio_PathComp *pathComp, uio_bool absolute, char **path, size_t *pathLen) { size_t len; const uio_PathComp *ptr; char *result; char *pathPtr; assert(pathComp != NULL); // First determine how much space is required. len = 0; if (absolute) len++; ptr = pathComp; while (ptr != NULL) { len += ptr->nameLen; ptr = ptr->next; } // Allocate the required space. result = (char *) uio_malloc(len + 1); // Fill the path. pathPtr = result; ptr = pathComp; if (absolute) { #ifdef HAVE_UNC_PATHS if (ptr->name[0] == '\\') { // UNC path assert(ptr->name[1] == '\\'); // Nothing to do. } else #endif /* HAVE_UNC_PATHS */ #ifdef HAVE_DRIVE_LETTERS if (ptr->nameLen == 2 && ptr->name[1] == ':' && isDriveLetter(ptr->name[0])) { // Nothing to do. } else #endif /* HAVE_DRIVE_LETTERS */ { *(pathPtr++) = '/'; } } for (;;) { memcpy(pathPtr, ptr->name, ptr->nameLen); pathPtr += ptr->nameLen; ptr = ptr->next; if (ptr == NULL) break; *(pathPtr++) = '/'; } *path = result; *pathLen = len; }
// Gets the length of the prefix of [path] that defines its absolute root. // // Returns 1 the leading "/". On Windows, also handles drive letters ("C:" or // "C:\"). // // If the path is not absolute, returns 0. static size_t absolutePrefixLength(const char* path) { #ifdef _WIN32 // Drive letter. if (isDriveLetter(path[0]) && path[1] == ':') { if (isSeparator(path[2])) { // Fully absolute path. return 3; } else { // "Half-absolute" path like "C:", which is relative to the current // working directory on drive. It's absolute for our purposes. return 2; } } // TODO: UNC paths. #endif // POSIX-style absolute path or absolute path in the current drive on Windows. if (isSeparator(path[0])) return 1; // Not absolute. return 0; }
// Первичная проверка, может ли asFilePath быть путем bool IsFilePath(LPCWSTR asFilePath, bool abFullRequired /*= false*/) { if (!asFilePath || !*asFilePath) return false; // Если в пути встречаются недопустимые символы if (wcschr(asFilePath, L'"') || wcschr(asFilePath, L'>') || wcschr(asFilePath, L'<') || wcschr(asFilePath, L'|') // '/' не проверяем для совместимости с cygwin? ) return false; // Пропуск UNC "\\?\" if (asFilePath[0] == L'\\' && asFilePath[1] == L'\\' && asFilePath[2] == L'?' && asFilePath[3] == L'\\') asFilePath += 4; //-V112 // Если asFilePath содержит два (и более) ":\" LPCWSTR pszColon = wcschr(asFilePath, L':'); if (pszColon) { // Если есть ":", то это должен быть путь вида "X:\xxx", т.е. ":" - второй символ if (pszColon != (asFilePath+1)) return false; if (!isDriveLetter(asFilePath[0])) return false; if (wcschr(pszColon+1, L':')) return false; } if (abFullRequired) { if ((asFilePath[0] == L'\\' && asFilePath[1] == L'\\' && asFilePath[2] && wcschr(asFilePath+3,L'\\')) || (isDriveLetter(asFilePath[0]) && asFilePath[1] == L':' && asFilePath[2])) return true; return false; } // May be file path return true; }
// Decomposes a path into its components. // If isAbsolute is not NULL, *isAbsolute will be set to true // iff the path is absolute. // As POSIX considers multiple consecutive slashes to be equivalent to // a single slash, so will uio (but not in the "\\MACHINE\share" part // of a Windows UNC path). int decomposePath(const char *path, uio_PathComp **pathComp, uio_bool *isAbsolute) { uio_PathComp *result; uio_PathComp *last; uio_PathComp **endResult = &result; uio_bool absolute = false; char *name; #ifdef HAVE_UNC_PATHS size_t nameLen; #endif /* HAVE_UNC_PATHS */ if (path[0] == '\0') { errno = ENOENT; return -1; } last = NULL; #ifdef HAVE_UNC_PATHS path += uio_getUNCServerShare(path, &name, &nameLen); if (name != NULL) { // UNC path *endResult = uio_PathComp_new(name, nameLen, last); last = *endResult; endResult = &last->next; absolute = true; } else #endif /* HAVE_UNC_PATHS */ #ifdef HAVE_DRIVE_LETTERS if (isDriveLetter(path[0]) && path[1] == ':') { // DOS/Windows drive letter. if (path[2] != '\0' && !isPathDelimiter(path[2])) { errno = ENOENT; return -1; } name = uio_memdup0(path, 2); *endResult = uio_PathComp_new(name, 2, last); last = *endResult; endResult = &last->next; absolute = true; } else #endif /* HAVE_DRIVE_LETTERS */ { if (isPathDelimiter(*path)) { absolute = true; do { path++; } while (isPathDelimiter(*path)); } } while (*path != '\0') { const char *start = path; while (*path != '\0' && !isPathDelimiter(*path)) path++; name = uio_memdup0(path, path - start); *endResult = uio_PathComp_new(name, path - start, last); last = *endResult; endResult = &last->next; while (isPathDelimiter(*path)) path++; } *endResult = NULL; *pathComp = result; if (isAbsolute != NULL) *isAbsolute = absolute; return 0; }
Int16u FNSplit (const char * pathP, char * driveP, char * dirP, char * nameP, char * extP) { Int16u Ret; //Set all string to default value zero Ret = 0; if (driveP) *driveP = 0; if (dirP) *dirP = 0; if (nameP) *nameP = 0; if (extP) *extP = 0; if (pathP == 0) return 0; const char * cursor = pathP, * dirStart = 0, * lastSlash = 0; // check for a drive letter if (isDriveLetter (cursor) && *AnsiNext (cursor) == ':') { if (driveP != 0) StrCpyN (driveP, cursor, MAXDRIVE); cursor = AnsiNext (AnsiNext (cursor)); Ret |= DRIVE; } dirStart = cursor; // now find the last slash while (*cursor != '\0') { if (*cursor == '/' || *cursor == '\\') lastSlash = cursor; cursor = AnsiNext (cursor); } if (lastSlash != 0) { // a slash was seen if (dirP != 0) { Int16u bytesToCopy = lastSlash - dirStart + 1 // for '/' + 1; // for '\0' if (bytesToCopy > MAXDIR) bytesToCopy = MAXDIR; StrCpyN (dirP, dirStart, bytesToCopy); } cursor = lastSlash + 1; Ret |= DIRECTORY; } else cursor = dirStart; // cursor now points to the start of the filename // check for wildcards if (AnsiStrChr (cursor, '*') != 0 || AnsiStrChr (cursor, '?') != 0) Ret |= WILDCARDS; // now see if there's an extension const char * period = AnsiStrChr (cursor, '.'); if (period != 0) { Int16u bytesToCopy = period - cursor + 1; // for '\0' if (bytesToCopy > MAXFILE) bytesToCopy = MAXFILE; if (bytesToCopy > 0) { if (nameP != 0) StrCpyN (nameP, cursor, bytesToCopy); Ret |= FILENAME; } if (extP != 0) StrCpyN (extP, period, MAXEXT); Ret |= EXTENSION; } else { if (*cursor != '\0') { if (nameP != 0) StrCpyN (nameP, cursor, MAXFILE); Ret |= FILENAME; } } #if defined (DEBUG_FNSPLIT) static char buffer [MAXPATH + MAXPATH + 32]; wsprintf (buffer, "pathP:[%s] driveP:[%s] dirP:[%s] nameP:[%s] extP:[%s]", pathP, driveP != NULL ? driveP : "<NULL>", dirP != NULL ? dirP : "<NULL>", nameP != NULL ? nameP : "<NULL>", extP != NULL ? extP : "<NULL>"); MessageBox (GetActiveWindow (), buffer, "FNSplit", MB_OK); #endif //(DEBUG_FNSPLIT) return Ret; }