static struct grecs_value * parse_label(const char *str) { struct grecs_value *val = NULL; size_t i; struct wordsplit ws; size_t len = strlen (str); if (len > 1 && str[0] == '(' && str[len-1] == ')') { struct grecs_list *lst; ws.ws_delim = ","; if (wordsplit_len (str + 1, len - 2, &ws, WRDSF_DEFFLAGS|WRDSF_DELIM| WRDSF_WS)) { return NULL; } lst = grecs_value_list_create(); for (i = 0; i < ws.ws_wordc; i++) { struct grecs_value *p = grecs_zalloc(sizeof(*p)); p->type = GRECS_TYPE_STRING; p->v.string = ws.ws_wordv[i]; grecs_list_append(lst, p); } val = grecs_malloc(sizeof(*val)); val->type = GRECS_TYPE_LIST; val->v.list = lst; } else { if (wordsplit(str, &ws, WRDSF_DEFFLAGS)) return NULL; val = grecs_zalloc(sizeof(*val)); if (ws.ws_wordc == 1) { val->type = GRECS_TYPE_STRING; val->v.string = ws.ws_wordv[0]; } else { val->type = GRECS_TYPE_ARRAY; val->v.arg.c = ws.ws_wordc; val->v.arg.v = grecs_calloc(ws.ws_wordc, sizeof(val->v.arg.v[0])); for (i = 0; i < ws.ws_wordc; i++) { val->v.arg.v[i] = grecs_zalloc(sizeof(*val->v.arg.v[0])); val->v.arg.v[i]->type = GRECS_TYPE_STRING; val->v.arg.v[i]->v.string = ws.ws_wordv[i]; } } } ws.ws_wordc = 0; wordsplit_free(&ws); return val; }
struct grecs_node * grecs_match_first(struct grecs_node *tree, const char *pattern, struct grecs_match_buf **pbuf) { int i; struct grecs_node *node; struct grecs_match_buf *buf; if (tree->type != grecs_node_root) { errno = EINVAL; return NULL; } errno = 0; if (strcmp(pattern, ".") == 0) { *pbuf = NULL; return tree; } buf = grecs_zalloc(sizeof(*buf)); if (split_cfg_path(pattern, &buf->argc, &buf->argv, &buf->labelv)) { free(buf); return NULL; } /* FIXME: Compress argv/argc by replacing contiguous sequences of *'s with a single *. */ for (i = 0; i < buf->argc; i++) { if (ISWC(buf->argv[i], '*')) { int j; for (j = i + 1; j < buf->argc && ISWC(buf->argv[j], '*'); j++) free(buf->argv[j]); j -= i; if (j > 1) { memmove(&buf->argv[i+1], &buf->argv[i+j], (buf->argc - (i + j)) * sizeof(buf->argv[0])); memmove(&buf->labelv[i+1], &buf->labelv[i+j], (buf->argc - (i + j)) * sizeof(buf->labelv[0])); buf->argc -= j - 1; } } } buf->argi = 0; buf->node = grecs_tree_first_node(tree); *pbuf = buf; if (grecs_match(buf)) node = buf->node; else node = grecs_match_next(buf); if (!node) { grecs_match_buf_free(buf); *pbuf = NULL; } return node; }
struct grecs_sockaddr * grecs_sockaddr_new(size_t s) { struct grecs_sockaddr *sp = grecs_malloc(sizeof(*sp)); sp->next = NULL; sp->sa = grecs_zalloc(s); sp->len = s; return sp; }