1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#include "path.h"
#include "xmalloc.h"
#include <stdlib.h>
#include <unistd.h>
void path_strip(char *str)
{
int i, s, d;
i = 0;
if (str[0] == '/')
i = 1;
while (str[i]) {
if (str[i] == '/') {
d = i;
s = i + 1;
while (str[s] && str[s] == '/')
s++;
s--;
do {
str[d++] = str[++s];
} while (str[s]);
} else if (i && str[i] == '.') {
if (str[i + 1] == '/') {
d = i;
s = i + 1;
do {
str[d++] = str[++s];
} while (str[s]);
} else if (str[i + 1] == 0) {
str[i] = 0;
break;
} else if (str[i + 1] == '.' &&
(str[i + 2] == '/' || str[i + 2] == 0)) {
/* aaa/bbb/../ccc */
/* aaa/ccc */
if (str[i + 2]) {
s = i + 3; /* ccc */
} else {
s = i + 2;
}
d = i - 1; /* /../ccc */
do {
if (d == 0)
break;
d--;
} while (str[d] != '/');
d++;
/* std[d] is bbb/../ccc */
i = d;
s--;
do {
str[d++] = str[++s];
} while (str[s]);
} else {
while (str[i] && str[i] != '/')
i++;
if (str[i])
i++;
}
} else {
while (str[i] && str[i] != '/')
i++;
if (str[i])
i++;
}
}
if (i > 1 && str[i - 1] == '/')
str[i - 1] = 0;
}
char *path_absolute_cwd(const char *src, const char *cwd)
{
char *str;
if (src[0] == '/') {
/* already absolute */
str = xstrdup(src);
} else {
int src_len;
int cwd_len;
src_len = strlen(src);
cwd_len = strlen(cwd);
str = xnew(char, cwd_len + 1 + src_len + 1);
memcpy(str, cwd, cwd_len);
str[cwd_len] = '/';
memcpy(str + cwd_len + 1, src, src_len + 1);
}
path_strip(str);
return str;
}
char *path_absolute(const char *src)
{
char cwd[1024];
if (!getcwd(cwd, sizeof(cwd))) {
cwd[0] = '/';
cwd[1] = 0;
}
return path_absolute_cwd(src, cwd);
}
|