/** * Constructs the path to the file instide the bundle that we're keen on. * * @returns IPRT status code. * @param pszPath Path to the bundle on input, on successful * return it's the path to the desired file. This * a RTPATH_MAX size buffer. * @param cchPath The length of the path up to the bundle name. * @param cchName The length of the bundle name. * @param pszSubDir The bundle subdirectory the file lives in. * @param papszSuffixes Pointer to an array of bundle suffixes. */ static int rtDbgSymCacheConstructBundlePath(char *pszPath, size_t cchPath, size_t cchName, const char *pszSubDir, const char * const *papszSuffixes) { int rc = RTPathAppend(pszPath, RTPATH_MAX, pszSubDir); if (RT_SUCCESS(rc)) { /* Strip off the bundle suffix. */ const char *pszEnd = &pszPath[cchPath + cchName]; for (unsigned i = 0; papszSuffixes[i]; i++) { Assert(papszSuffixes[i][0] == '.'); size_t cchSuff = strlen(papszSuffixes[i]); if ( cchSuff < cchName && !memcmp(&pszEnd[-(ssize_t)cchSuff], papszSuffixes[i], cchSuff)) { cchName -= cchSuff; break; } } /* Add the name. */ rc = RTPathAppendEx(pszPath, RTPATH_MAX, &pszPath[cchPath], cchName); } if (RT_FAILURE(rc)) { pszPath[cchPath + cchName] = '\0'; return RTMsgErrorRc(rc, "Error constructing image bundle path for '%s': %Rrc", pszPath, rc); } return VINF_SUCCESS; }
/** * Constructs the path to the file instide the bundle that we're keen on. * * @returns IPRT status code. * @param pszPath Path to the bundle on input, on successful * return it's the path to the desired file. This * a RTPATH_MAX size buffer. * @param cchPath The length of the path up to the bundle name. * @param cchName The length of the bundle name. * @param pszSubDir The bundle subdirectory the file lives in. * @param papszSuffixes Pointer to an array of bundle suffixes. */ static int rtDbgSymCacheConstructBundlePath(char *pszPath, size_t cchPath, size_t cchName, const char *pszSubDir, const char * const *papszSuffixes) { /* * Calc the name without the bundle extension. */ size_t const cchOrgName = cchName; const char *pszEnd = &pszPath[cchPath + cchName]; for (unsigned i = 0; papszSuffixes[i]; i++) { Assert(papszSuffixes[i][0] == '.'); size_t cchSuff = strlen(papszSuffixes[i]); if ( cchSuff < cchName && !memcmp(&pszEnd[-(ssize_t)cchSuff], papszSuffixes[i], cchSuff)) { cchName -= cchSuff; break; } } /* * Check the immediate directory first, in case it's layed out like * IOPCIFamily.kext. */ int rc = RTPathAppendEx(pszPath, RTPATH_MAX, &pszPath[cchPath], cchName); if (RT_FAILURE(rc) || !RTFileExists(pszPath)) { /* * Not there, ok then try the given subdirectory + name. */ pszPath[cchPath + cchOrgName] = '\0'; rc = RTPathAppend(pszPath, RTPATH_MAX, pszSubDir); if (RT_SUCCESS(rc)) rc = RTPathAppendEx(pszPath, RTPATH_MAX, &pszPath[cchPath], cchName); if (RT_FAILURE(rc)) { pszPath[cchPath + cchOrgName] = '\0'; return RTMsgErrorRc(rc, "Error constructing image bundle path for '%s': %Rrc", pszPath, rc); } } return VINF_SUCCESS; }
RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst, const char *pszPathSrc, size_t cchPathSrcMax, const char *pszAppend, size_t cchAppendMax) { AssertPtr(pszPathDst); AssertPtr(pszPathSrc); AssertPtr(pszAppend); /* * The easy way: Copy the path into the buffer and call RTPathAppend. */ size_t cchPathSrc = RTStrNLen(pszPathSrc, cchPathSrcMax); if (cchPathSrc >= cbPathDst) return VERR_BUFFER_OVERFLOW; memcpy(pszPathDst, pszPathSrc, cchPathSrc); pszPathDst[cchPathSrc] = '\0'; return RTPathAppendEx(pszPathDst, cbPathDst, pszAppend, cchAppendMax); }
RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend) { return RTPathAppendEx(pszPath, cbPathDst, pszAppend, RTSTR_MAX); }