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, int mode)
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;
259 void *node_destroy(struct node *node)
270 void node_delete(struct node *node, void (del_cb)(struct node *node))
276 if (node->sibling.prev) {
277 node->sibling.prev->sibling.next = node->sibling.next;
280 if (node->sibling.next) {
281 node->sibling.next->sibling.prev = node->sibling.prev;
284 /* Isolate the node */
285 node->sibling.prev = NULL;
286 node->sibling.next = NULL;
289 if (node->parent->child == node) {
290 node->parent->child = NULL;
298 /* Reach to the leaf node */
303 parent = tmp->parent;
304 next = tmp->sibling.next;
306 if (parent && parent->child == tmp) {
307 parent->child = NULL;
326 struct node * const node_next_sibling(const struct node *node)
328 return node->sibling.next;
331 struct node * const node_prev_sibling(const struct node *node)
333 return node->sibling.prev;
336 void node_set_mode(struct node *node, int mode)
341 void node_set_data(struct node *node, void *data)
346 void node_set_type(struct node *node, enum node_type type)
351 struct node * const node_child(const struct node *node)
356 struct node * const node_parent(const struct node *node)
361 const int const node_mode(const struct node *node)
366 void * const node_data(const struct node *node)
371 const enum node_type const node_type(const struct node *node)
376 const char * const node_name(const struct node *node)
381 void node_set_age(struct node *node, int age)
386 int node_age(struct node *node)