int main(int argc, char *argv[]) { char *result, *argp; int errflg, absolute, canon, relative, nextArg; #if _WIN32 _setmode(1, _O_BINARY); #endif errflg = 0; canon = absolute = relative = 0; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "-a") == 0) { absolute++; } else if (strcmp(argp, "-c") == 0) { canon++; } else if (strcmp(argp, "-r") == 0) { relative++; } else { errflg++; } } if (!absolute && !relative && !canon) { canon = 1; } if (errflg || (absolute + relative + canon) > 1) { fprintf(stderr, "Usage: getpath [-arc] files...\n"); exit(2); } for (; nextArg < argc; ) { if (relative) { result = canonPath(relativePath(argv[nextArg])); } else if (absolute) { result = canonPath(absolutePath(argv[nextArg])); } else { result = canonPath(argv[nextArg]); } if (++nextArg < argc) { printf("%s ", result); } else { printf("%s", result); } } printf("\n"); return 0; }
/* * Return a relative path variation of path */ static char *relativePath(char *path) { char cwd[MAXPATH], **strSegments, **cwdSegments, *cp, *result; size_t len; int cwdCount, strCount, i, commonLevels, upLevels; if (path == NULL || *path == '\0') { return "."; } strSegments = getSegments(canonPath(absolutePath(path)), &strCount); cwd[sizeof(cwd) - 1] = '\0'; if (getcwd(cwd, sizeof(cwd) - 1) == 0) { fprintf(stderr, "Can't get working directory"); exit(255); } cwdSegments = getSegments(cwd, &cwdCount); len = min(cwdCount, strCount); for (i = 0; i < len; i++) { if (strcmp(strSegments[i], cwdSegments[i]) != 0) { break; } } commonLevels = i; upLevels = cwdCount - commonLevels; len = (upLevels * 3); for (; i < strCount; i++) { len += strlen(strSegments[i]) + 1; } cp = result = malloc(len + 1); for (i = 0; i < upLevels; i++) { strcpy(cp, "../"); cp += 3; } for (i = commonLevels; i < strCount; i++) { strcpy(cp, strSegments[i]); cp += strlen(strSegments[i]); if ((i + 1) < strCount) { *cp++ = '/'; } } *cp = '\0'; return result; }
static String canonicalPath(const String& path) { PlatformRefPtr<IFileMgr> fileMgr = createRefPtrInstance<IFileMgr>(AEECLSID_FILEMGR); // Get the buffer size required to resolve the path. int canonPathLen; IFILEMGR_ResolvePath(fileMgr.get(), path.utf8().data(), 0, &canonPathLen); // Resolve the path to the canonical path. Vector<char> canonPathBuffer(canonPathLen); IFILEMGR_ResolvePath(fileMgr.get(), path.utf8().data(), canonPathBuffer.data(), &canonPathLen); String canonPath(canonPathBuffer.data()); // Remove the trailing '/'. int lastDivPos = canonPath.reverseFind('/'); int endPos = canonPath.length(); if (lastDivPos == endPos - 1) canonPath = canonPath.substring(0, canonPath.length() - 1); return canonPath; }