所以,这里是你会如何去了解它在ç上的Linux一个工作草图。这是一种快速入侵,我并不认为它是典型的代码,高效的等等。它(ab)使用PATH_MAX,使用“坏”字符串函数,并且可能会泄漏内存,吃掉你的猫,并且存在段错误等等。 当它打破,你会保持两个部分。
其基本思想是通过给定的路径,使用“/”作为分隔符将其分解为“单词”。然后,通过列表,将“单词”推到堆栈上,但忽略空或“。”,如果“..”则弹出,然后从底部开始序列化堆栈并在其间堆积一个带斜杠的字符串。
#include
#include
#include
#include
typedef struct stack_s {
char *data[PATH_MAX];
int top;
} stack_s;
void stack_push(stack_s *s, char *c) {
s->data[s->top++] = c;
}
char *stack_pop(stack_s *s) {
if(s->top <= 0) {
return NULL;
}
s->top--;
return s->data[s->top];
}
// DANGER! DANGER! Returns malloc()ed pointer that you must free()
char *stack_serialize(stack_s *s) {
int i;
char *buf;
int len=1;
for(i=0; itop; i++) {
len += strlen(s->data[i]);
len++; // For a slash
}
buf = malloc(len);
*buf = '\0';
for(i=0; itop-1; i++) {
strcat(buf, s->data[i]);
strcat(buf, "/");
}
strcat(buf, s->data[i]);
return buf;
}
// DANGER! DANGER! Returns malloc()ed pointer that you must free()
char *semicanonicalize(char *src) {
char *word[PATH_MAX] = {NULL};
int w=0;
int n_words;
char *buf;
int len;
char *p, *q;
stack_s dir_stack = {{NULL},0};
// Make a copy of the input string:
len = strlen(src);
buf = strdup(src);
// Replace slashes with NULs and record the start of each "word"
q = buf+len;
word[0]=buf;
for(p=buf,w=0; p
if(*p=='/') {
*p = '\0';
word[++w] = p+1;
}
}
n_words=w+1;
// We push w[0] unconditionally to preserve slashes and dots at the
// start of the source path:
stack_push(&dir_stack, word[0]);
for(w=1; w
len = strlen(word[w]);
if(len == 0) {
// Must've hit a double slash
continue;
}
if(*word[w] == '.') {
if(len == 1) {
// Must've hit a dot
continue;
}
if(len == 2 && *(word[w]+1)=='.') {
// Must've hit a '..'
(void)stack_pop(&dir_stack);
continue;
}
}
// If we get to here, the current "word" isn't "", ".", or "..", so
// we push it on the stack:
stack_push(&dir_stack, word[w]);
}
p = stack_serialize(&dir_stack);
free(buf);
return p;
}
int main(void)
{
char *in[] = { "/home/emmet/../foo//./bar/quux/../.",
"../home/emmet/../foo//./bar/quux/../.",
"./home/emmet/../foo//./bar/quux/../.",
"home/emmet/../foo//./bar/quux/../."
};
char *out;
for(int i=0; i<4; i++) {
out = semicanonicalize(in[i]);
printf("%s \t->\t %s\n", in[i], out);
free(out);
}
return 0;
}