| 315 | } |
| 316 | |
| 317 | int PU::SimplifyExternalPath(const char * path, const char * currentDir, char * buffer, int bufSize) { |
| 318 | if (buffer == NULL || bufSize <= 1) |
| 319 | return -1; |
| 320 | |
| 321 | if (currentDir == NULL && path[0] != '/') //relative paths only supported if curDir is given |
| 322 | return -1; |
| 323 | |
| 324 | size_t pathlen = strlen(path); |
| 325 | size_t dirlen = strlen(currentDir); |
| 326 | char * temp = new char[pathlen+dirlen+2]; //pathlen + '/' + dirlen + '\0' |
| 327 | temp[0] = 0; |
| 328 | if (path[0] != '/') { |
| 329 | strcpy(temp, currentDir); |
| 330 | strcat(temp, "/"); |
| 331 | } |
| 332 | strcat(temp, path); |
| 333 | |
| 334 | std::vector<const char*> dirs; |
| 335 | const char * name = strtok(temp,"/"); |
| 336 | while (name != NULL) { |
| 337 | dirs.push_back(name); |
| 338 | name = strtok(NULL, "/"); |
| 339 | } |
| 340 | |
| 341 | size_t size = dirs.size(); |
| 342 | size_t i = 0; |
| 343 | while(i < size) { |
| 344 | if (!strcmp(dirs[i], ".")) { |
| 345 | dirs.erase(dirs.begin()+i); |
| 346 | size--; |
| 347 | continue; |
| 348 | } |
| 349 | if (!strcmp(dirs[i], "..")) { |
| 350 | dirs.erase(dirs.begin()+i); |
| 351 | size--; |
| 352 | if (i > 0) { |
| 353 | dirs.erase(dirs.begin()+i-1); |
| 354 | size--; |
| 355 | i--; |
| 356 | } |
| 357 | continue; |
| 358 | } |
| 359 | |
| 360 | i++; |
| 361 | } |
| 362 | |
| 363 | buffer[0] = '/'; |
| 364 | buffer[1] = 0; |
| 365 | size_t totalLen = 1; |
| 366 | i = 0; |
| 367 | for(; i < dirs.size(); i++) { |
| 368 | size_t len = strlen(dirs[i]); |
| 369 | if (totalLen+len >= (size_t)bufSize) { |
| 370 | delete [] temp; |
| 371 | return -1; |
| 372 | } |
| 373 | strcat(buffer, dirs[i]); |
| 374 | totalLen += len; |