basename.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include "../git-compat-util.h"
  2. #include "../strbuf.h"
  3. /* Adapted from libiberty's basename.c. */
  4. char *gitbasename (char *path)
  5. {
  6. const char *base;
  7. if (path)
  8. skip_dos_drive_prefix(&path);
  9. if (!path || !*path)
  10. return ".";
  11. for (base = path; *path; path++) {
  12. if (!is_dir_sep(*path))
  13. continue;
  14. do {
  15. path++;
  16. } while (is_dir_sep(*path));
  17. if (*path)
  18. base = path;
  19. else
  20. while (--path != base && is_dir_sep(*path))
  21. *path = '\0';
  22. }
  23. return (char *)base;
  24. }
  25. char *gitdirname(char *path)
  26. {
  27. static struct strbuf buf = STRBUF_INIT;
  28. char *p = path, *slash = NULL, c;
  29. int dos_drive_prefix;
  30. if (!p)
  31. return ".";
  32. if ((dos_drive_prefix = skip_dos_drive_prefix(&p)) && !*p)
  33. goto dot;
  34. /*
  35. * POSIX.1-2001 says dirname("/") should return "/", and dirname("//")
  36. * should return "//", but dirname("///") should return "/" again.
  37. */
  38. if (is_dir_sep(*p)) {
  39. if (!p[1] || (is_dir_sep(p[1]) && !p[2]))
  40. return path;
  41. slash = ++p;
  42. }
  43. while ((c = *(p++)))
  44. if (is_dir_sep(c)) {
  45. char *tentative = p - 1;
  46. /* POSIX.1-2001 says to ignore trailing slashes */
  47. while (is_dir_sep(*p))
  48. p++;
  49. if (*p)
  50. slash = tentative;
  51. }
  52. if (slash) {
  53. *slash = '\0';
  54. return path;
  55. }
  56. dot:
  57. strbuf_reset(&buf);
  58. strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path);
  59. return buf.buf;
  60. }