static const void *__ft_get_prop(struct ft_cxt *cxt, void *node, const char *propname, unsigned int *len) { struct ft_atom atom; int depth = 0; while ((node = ft_next(cxt, node, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: ++depth; break; case OF_DT_PROP: if (depth != 1 || strcmp(atom.name, propname)) break; if (len) *len = atom.size; return atom.data; case OF_DT_END_NODE: if (--depth <= 0) return NULL; } } return NULL; }
int ft_search_flag(t_glob *g, char *str, int *i) { int tab[2]; char *tmp2; tab[0] = 0; tab[1] = 0; tmp2 = NULL; while (str[*i] && (ft_strchr("-+ #.hlLjz", str[*i]) != NULL || ft_isdigit(str[*i]))) { if (ft_isdigit(str[*i]) && str[*i] != '0') tab[1] = 1; if (ft_next(g, str, i, &tab[0]) == -1) return (-1); if (str[*i] == '0' && str[i[0] + 1] && str[i[0] + 1] != '%' && !ft_isdigit(str[i[0] - 1]) && str[i[0] - 1] != '.') { g->flag_0 = 1; tab[1] = 1; } if (ft_next2(str, i, tab, g) == -1) return (-1); ft_assigne(str, i, g, &tab[0]); } return (ft_trie(g, str, i)); }
int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname) { struct ft_atom atom; void *node; char *p, *next; int size; node = ft_node_ph2node(cxt, phandle); if (node == NULL) return -1; p = node; while ((next = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: case OF_DT_END_NODE: return -1; case OF_DT_PROP: if (strcmp(atom.name, propname)) break; /* found the property, remove it */ size = 12 + -_ALIGN(atom.size, 4); cxt->p = p; if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size)) return -1; return 0; } p = next; } return -1; }
void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path) { struct ft_atom atom; char *p; const char *cp, *q; int cl; int depth = -1; int dmatch = 0; const char *path_comp[FT_MAX_DEPTH]; cp = srch_path; cl = 0; p = top; while ((p = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: ++depth; if (depth != dmatch) break; cxt->genealogy[depth] = atom.data; cxt->genealogy[depth + 1] = NULL; if (depth && !(strncmp(atom.name, cp, cl) == 0 && (atom.name[cl] == '/' || atom.name[cl] == '\0' || atom.name[cl] == '@'))) break; path_comp[dmatch] = cp; /* it matches so far, advance to next path component */ cp += cl; /* skip slashes */ while (*cp == '/') ++cp; /* we're done if this is the end of the string */ if (*cp == 0) return atom.data; /* look for end of this component */ q = strchr(cp, '/'); if (q) cl = q - cp; else cl = strlen(cp); ++dmatch; break; case OF_DT_END_NODE: if (depth == 0) return NULL; if (dmatch > depth) { --dmatch; cl = cp - path_comp[dmatch] - 1; cp = path_comp[dmatch]; while (cl > 0 && cp[cl - 1] == '/') --cl; } --depth; break; } } return NULL; }
void *__ft_get_parent(struct ft_cxt *cxt, void *node) { int d; struct ft_atom atom; char *p; for (d = 0; cxt->genealogy[d] != NULL; ++d) if (cxt->genealogy[d] == node) return d > 0 ? cxt->genealogy[d - 1] : NULL; /* have to do it the hard way... */ p = ft_root_node(cxt); d = 0; while ((p = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: cxt->genealogy[d] = atom.data; if (node == atom.data) { /* found it */ cxt->genealogy[d + 1] = NULL; return d > 0 ? cxt->genealogy[d - 1] : NULL; } ++d; break; case OF_DT_END_NODE: --d; break; } } return NULL; }
void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *path) { struct ft_atom atom; char *p, *next; int depth = 0; p = cxt->rgn[FT_STRUCT].start; while ((next = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: ++depth; if (depth == 1 && strcmp(atom.name, path) == 0) /* duplicate node path, return error */ return NULL; break; case OF_DT_END_NODE: --depth; if (depth > 0) break; /* end of node, insert here */ cxt->p = p; ft_begin_node(cxt, path); ft_end_node(cxt); return p; } p = next; } return NULL; }
int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, void *buf, const unsigned int buflen) { struct ft_atom atom; void *node; char *p; int depth; unsigned int size; node = ft_node_ph2node(cxt, phandle); if (node == NULL) return -1; depth = 0; p = (char *)node; while ((p = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: ++depth; break; case OF_DT_PROP: if ((depth != 1) || strcmp(atom.name, propname)) break; size = min(atom.size, buflen); memcpy(buf, atom.data, size); return atom.size; case OF_DT_END_NODE: if (--depth <= 0) return -1; } } return -1; }
/* Returns the start of the path within the provided buffer, or NULL on * error. */ char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len) { const char *path_comp[FT_MAX_DEPTH]; struct ft_atom atom; char *p, *next, *pos; int depth = 0, i; void *node; node = ft_node_ph2node(cxt, phandle); if (node == NULL) return NULL; p = ft_root_node(cxt); while ((next = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: path_comp[depth++] = atom.name; if (p == node) goto found; break; case OF_DT_END_NODE: if (--depth == 0) return NULL; } p = next; } found: pos = buf; for (i = 1; i < depth; i++) { int this_len; if (len <= 1) return NULL; *pos++ = '/'; len--; strncpy(pos, path_comp[i], len); if (pos[len - 1] != 0) return NULL; this_len = strlen(pos); len -= this_len; pos += this_len; } return buf; }
int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, const void *buf, const unsigned int buflen) { struct ft_atom atom; void *node; char *p, *next; int nextra; node = ft_node_ph2node(cxt, phandle); if (node == NULL) return -1; next = ft_next(cxt, node, &atom); if (atom.tag != OF_DT_BEGIN_NODE) /* phandle didn't point to a node */ return -1; p = next; while ((next = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: /* properties must go before subnodes */ case OF_DT_END_NODE: /* haven't found the property, insert here */ cxt->p = p; return ft_prop(cxt, propname, buf, buflen); case OF_DT_PROP: if (strcmp(atom.name, propname)) break; /* found an existing property, overwrite it */ nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4); cxt->p = atom.data; if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT, nextra)) return -1; *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen); ft_put_bin(cxt, buf, buflen); return 0; } p = next; } return -1; }
void ft_decode(char *buf, t_inv *move) { int i; int t; i = -1; t = 0; while (buf[++i]) { ft_next(0, &i, buf); if (buf[i + 1] == '#') ft_plus_one(i, &t, buf, move); else if (buf[i + 4] == '#') ft_plus_four(i, &t, buf, move); else if (buf[i + 5] == '#') ft_plus_five(i, &t, buf, move); ft_next(42, &i, buf); } TAB[t] = 0; }
/* Calculate the size of the struct region by stepping through it */ static unsigned long struct_size(struct ft_cxt *cxt) { char *p = cxt->rgn[FT_STRUCT].start; char *next; struct ft_atom atom; /* make check in ft_next happy */ if (cxt->rgn[FT_STRUCT].size == 0) cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p; while ((next = ft_next(cxt, p, &atom)) != NULL) p = next; return p + 4 - cxt->rgn[FT_STRUCT].start; }
/* add `adj' on to all string offset values in the struct area */ static void adjust_string_offsets(struct ft_cxt *cxt, int adj) { char *p = cxt->rgn[FT_STRUCT].start; char *next; struct ft_atom atom; int off; while ((next = ft_next(cxt, p, &atom)) != NULL) { if (atom.tag == OF_DT_PROP) { off = be32_to_cpu(*(u32 *) (p + 8)); *(u32 *) (p + 8) = cpu_to_be32(off + adj); } p = next; } }
void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev, const char *propname, const char *propval, unsigned int proplen) { struct ft_atom atom; char *p = ft_root_node(cxt); char *next; int past_prev = prev ? 0 : 1; int depth = -1; while ((next = ft_next(cxt, p, &atom)) != NULL) { const void *data; unsigned int size; switch (atom.tag) { case OF_DT_BEGIN_NODE: depth++; if (prev == p) { past_prev = 1; break; } if (!past_prev || depth < 1) break; data = __ft_get_prop(cxt, p, propname, &size); if (!data || size != proplen) break; if (memcmp(data, propval, size)) break; return p; case OF_DT_END_NODE: if (depth-- == 0) return NULL; break; } p = next; } return NULL; }
void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name) { struct ft_atom atom; char *p, *next, *ret; int depth = 0; if (parent) { p = ft_node_ph2node(cxt, parent); if (!p) return NULL; } else { p = ft_root_node(cxt); } while ((next = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: ++depth; if (depth == 1 && strcmp(atom.name, name) == 0) /* duplicate node name, return error */ return NULL; break; case OF_DT_END_NODE: --depth; if (depth > 0) break; /* end of node, insert here */ cxt->p = p; ret = ft_begin_node(cxt, name); ft_end_node(cxt); return ft_get_phandle(cxt, ret); } p = next; } return NULL; }
void *ft_get_parent(struct ft_cxt *cxt, const void *phandle) { void *node; int d; struct ft_atom atom; char *p; node = ft_node_ph2node(cxt, phandle); if (node == NULL) return NULL; for (d = 0; cxt->genealogy[d] != NULL; ++d) if (cxt->genealogy[d] == node) return cxt->genealogy[d > 0 ? d - 1 : 0]; /* have to do it the hard way... */ p = cxt->rgn[FT_STRUCT].start; d = 0; while ((p = ft_next(cxt, p, &atom)) != NULL) { switch (atom.tag) { case OF_DT_BEGIN_NODE: cxt->genealogy[d] = atom.data; if (node == atom.data) { /* found it */ cxt->genealogy[d + 1] = NULL; return d > 0 ? cxt->genealogy[d - 1] : node; } ++d; break; case OF_DT_END_NODE: --d; break; } } return NULL; }