26 int errno; /* External symbol */
28 char *node_to_abspath(const struct node *node)
32 const struct node *tmp;
36 while (tmp && node_name(tmp)) {
37 len += strlen(node_name(tmp)) + 1; /* trail '/' */
38 tmp = node_parent(tmp);
41 path = malloc(len + 3); /* '/' and '\0' */
55 while (tmp && node_name(tmp)) {
56 ptr -= (strlen(node_name(tmp)) + 1);
58 strncpy(ptr + 1, node_name(tmp), strlen(node_name(tmp)));
59 tmp = node_parent(tmp);
66 static inline int next_state(int from, char ch)
85 static inline void abspath(const char* pBuffer, char* pRet)
91 int src_len = strlen(pBuffer);
95 while (src_idx <= src_len) {
97 state = next_state(from, pBuffer[src_idx]);
102 pRet[idx] = pBuffer[src_idx];
112 pRet[idx] = pBuffer[src_idx];
117 // Only can go to the 1 or 4
124 while (idx > 1 && pRet[idx] != '/') {
125 idx--; /* Remove .. */
127 if (idx > 1 && pRet[idx] == '/') {
130 while (idx > 1 && pRet[idx] != '/') {
131 idx--; /* Remove parent folder */
135 pRet[idx] = pBuffer[src_idx];
145 struct node *node_find(const struct node *node, const char *path)
152 while (node->parent && path[0] == '.' && path[1] == '.') {
153 if (path[2] != '/' && path[2] != '\0') {
158 path += (path[2] == '/');
163 buffer = malloc(strlen(path) + 3); /* add 2 more bytes */
165 printf("Error: %s\n", strerror(errno));
169 abspath(path, buffer);
173 ptr += (*ptr == '/');
174 for (len = 0; ptr[len] && ptr[len] != '/'; len++);
179 if (!strncmp("..", ptr, len)) {
181 node = node->parent ? node->parent : node;
185 if (!strncmp(".", ptr, len)) {
196 if (!strncmp(node->name, ptr, len) && node->name[len] == '\0') {
201 node = node->sibling.next;
203 } while (*ptr && node);
206 return (struct node *)node;
209 struct node *node_create(struct node *parent, const char *name, enum node_type type)
213 node = malloc(sizeof(*node));
215 printf("Error: %s\n", strerror(errno));
219 node->parent = parent;
222 node->name = strdup(name);
224 printf("Error: %s\n", strerror(errno));
234 node->sibling.next = NULL;
235 node->sibling.prev = NULL;
244 while (tmp->sibling.next) {
245 tmp = tmp->sibling.next;
248 tmp->sibling.next = node;
249 node->sibling.prev = tmp;
251 parent->child = node;
257 void *node_destroy(struct node *node)
268 void node_delete(struct node *node, void (del_cb)(struct node *node))
274 if (node->sibling.prev) {
275 node->sibling.prev->sibling.next = node->sibling.next;
278 if (node->sibling.next) {
279 node->sibling.next->sibling.prev = node->sibling.prev;
282 /* Isolate the node */
283 node->sibling.prev = NULL;
284 node->sibling.next = NULL;
287 if (node->parent->child == node) {
288 node->parent->child = NULL;
296 /* Reach to the leaf node */
301 parent = tmp->parent;
302 next = tmp->sibling.next;
304 if (parent && parent->child == tmp) {
305 parent->child = NULL;
324 struct node * const node_next_sibling(const struct node *node)
326 return node->sibling.next;
329 struct node * const node_prev_sibling(const struct node *node)
331 return node->sibling.prev;
334 void node_set_mode(struct node *node, int mode)
339 void node_set_data(struct node *node, void *data)
344 void node_set_type(struct node *node, enum node_type type)
349 struct node * const node_child(const struct node *node)
354 struct node * const node_parent(const struct node *node)
359 const int const node_mode(const struct node *node)
364 void * const node_data(const struct node *node)
369 const enum node_type const node_type(const struct node *node)
374 const char * const node_name(const struct node *node)
379 void node_set_age(struct node *node, int age)
384 int node_age(struct node *node)