| 184 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len); |
184 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len); |
| 185 newentry->displayname[newentry->displayname_len] = 0; |
185 newentry->displayname[newentry->displayname_len] = 0; |
| 186 |
186 |
| 187 newentry->st_mode = 0; |
187 newentry->st_mode = 0; |
| 188 |
188 |
| 189 /* Construct absolute pathname string */ |
189 /* Construct full pathname string */ |
| 190 size_t dirnamelen = strlen(scanner.dir); |
190 size_t dirnamelen = strlen(scanner.dir); |
| 191 char *filename = (char*) malloc(2+dirnamelen+newentry->displayname_len); |
191 char *filename = (char*) malloc(2+dirnamelen+newentry->displayname_len); |
| 192 memcpy(filename, scanner.dir, dirnamelen); |
192 memcpy(filename, scanner.dir, dirnamelen); |
| 193 filename[dirnamelen] = settings->fileSeparator; |
193 if (filename[dirnamelen - 1] != settings->fileSeparator) { |
| 194 memcpy(filename+dirnamelen+1, entry->d_name, newentry->displayname_len); |
194 filename[dirnamelen++] = settings->fileSeparator; |
| 195 filename[1+dirnamelen+newentry->displayname_len] = 0; |
195 } |
| |
196 memcpy(filename+dirnamelen, entry->d_name, newentry->displayname_len); |
| |
197 filename[dirnamelen+newentry->displayname_len] = 0; |
| 196 newentry->filename = filename; |
198 newentry->filename = filename; |
| 197 |
199 |
| 198 /* Obtain file extension */ |
200 /* Obtain file extension */ |
| 199 newentry->ext = strrchr(newentry->displayname, '.'); |
201 newentry->ext = strrchr(newentry->displayname, '.'); |
| 200 |
202 |
| 427 #ifdef _WIN32 |
429 #ifdef _WIN32 |
| 428 static char fs = '\\'; |
430 static char fs = '\\'; |
| 429 #else |
431 #else |
| 430 static char fs = '/'; |
432 static char fs = '/'; |
| 431 #endif /* _WIN32 */ |
433 #endif /* _WIN32 */ |
| |
434 char* abspath; |
| 432 if (path_is_relative(path)) { |
435 if (path_is_relative(path)) { |
| 433 if (cwdlen == 0) { |
436 if (cwdlen == 0) { |
| 434 get_working_dir(&cwd, &cwdlen); |
437 get_working_dir(&cwd, &cwdlen); |
| 435 } |
438 } |
| 436 size_t pathlen = strlen(path); |
439 size_t pathlen = strlen(path); |
| 442 partlen -= 2; |
445 partlen -= 2; |
| 443 } |
446 } |
| 444 memcpy(result, cwd, cwdlen); |
447 memcpy(result, cwd, cwdlen); |
| 445 memcpy(result+cwdlen, part, partlen); |
448 memcpy(result+cwdlen, part, partlen); |
| 446 result[cwdlen+partlen] = '\0'; |
449 result[cwdlen+partlen] = '\0'; |
| 447 return result; |
450 abspath = result; |
| 448 } else { |
451 } else { |
| 449 return strdup(path); |
452 abspath = strdup(path); |
| 450 } |
453 } |
| 451 } |
454 /* make path canonical */ |
| |
455 size_t abspathlen = strlen(abspath); |
| |
456 char* canonical = malloc(abspathlen + 1); |
| |
457 size_t canonicallen = 0; |
| |
458 for (size_t j = 0; j < abspathlen; j++) { |
| |
459 canonical[canonicallen++] = abspath[j]; |
| |
460 if (abspath[j] == fs) { |
| |
461 /* collapse consecutive separators */ |
| |
462 while (abspath[j + 1] == fs) j++; |
| |
463 } else if (abspath[j] == '.') { |
| |
464 if (abspath[j + 1] == fs) { |
| |
465 /* skip '.' segments */ |
| |
466 canonicallen--; |
| |
467 j++; |
| |
468 } else if (abspath[j + 1] == '.' && abspath[j + 2] == fs) { |
| |
469 /* trace back '..' segment */ |
| |
470 canonicallen -= 2; |
| |
471 while (canonical[canonicallen - 1] != fs) canonicallen--; |
| |
472 j += 2; |
| |
473 } |
| |
474 } |
| |
475 } |
| |
476 canonical[canonicallen] = '\0'; |
| |
477 free(abspath); |
| |
478 return canonical; |
| |
479 } |