- switch (node->type) {
- case Text:
- rc = check(closure, node->text);
- break;
- case And:
- rc = node_check(node->children[0], check, closure);
- if (rc)
- rc = node_check(node->children[1], check, closure);
- break;
- case Or:
- rc = node_check(node->children[0], check, closure);
- if (!rc)
- rc = node_check(node->children[1], check, closure);
- break;
- case Not:
- rc = !node_check(node->children[0], check, closure);
- break;
- }
- return rc;
-}
-
-/*********************************************************************
-*** SECTION parse
-*********************************************************************/
-
-/**
- * the symbol types
- */
-enum symbol
-{
- TEXT, /**< a common text, name of a permission */
- AND, /**< and keyword */
- OR, /**< or keyword */
- NOT, /**< not keyword */
- OBRA, /**< open bracket */
- CBRA, /**< close bracket */
- END /**< end of input */
-};
-
-/**
- * structure for parsing permission description
- */
-struct parse
-{
- const char *desc; /**< initial permission description */
- const char *symbol; /**< current symbol parsed */
- size_t symlen; /**< length of the current symbol */
- enum symbol type; /**< type of the current symbol */
-};
-
-/**
- * updates parse to point to the next symbol if any
- * @param parse parser state to update
- */
-static void parse_next(struct parse *parse)
-{
- const char *scan;
- size_t len;
-
- /* skip current symbol */
- scan = &parse->symbol[parse->symlen];
-
- /* skip white spaces */
- while (*scan && isspace(*scan))
- scan++;
-
- /* scan the symbol */
- switch (*scan) {
- case 0:
- len = 0;
- parse->type = END;
- break;
- case '(':
- len = 1;
- parse->type = OBRA;
- break;
- case ')':
- len = 1;
- parse->type = CBRA;
- break;
- default:
- /* compute the length */
- len = 0;
- while (scan[len] && !isspace(scan[len]) && scan[len] != ')' && scan[len] != '(')
- len++;
- parse->type = TEXT;
-
- /* fall to keyword if any */
- switch(len) {
- case 2:
- if (!strncasecmp(scan, "or", len))
- parse->type = OR;
- break;
- case 3:
- if (!strncasecmp(scan, "and", len))
- parse->type = AND;
- else if (!strncasecmp(scan, "not", len))
- parse->type = NOT;
- break;
- }
- break;
- }
- parse->symbol = scan;
- parse->symlen = len;
-}
-
-/**
- * Init the parser state 'parse' for the description 'desc'
- * @param parse the parser state to initialise
- * @param desc the description of the permissions to be parsed
- */
-static void parse_init(struct parse *parse, const char *desc)
-{
- parse->desc = desc;
- parse->symbol = desc;
- parse->symlen = 0;
- parse_next(parse);
-}
-
-/*********************************************************************
-*** SECTION node_parse
-*********************************************************************/
-
-static struct node *node_parse_or(struct parse *parse);
-
-/**
- * Parse a permission name
- * @param parser the parser state
- * @return the parsed node or NULL in case of error
- * in case of error errno is set to EINVAL or ENOMEM
- */
-static struct node *node_parse_text(struct parse *parse)
-{
- struct node *node;
-
- if (parse->type == TEXT) {
- node = node_make_text(Text, parse->symbol, parse->symlen);
- parse_next(parse);
- } else {
- errno = EINVAL;
- node = NULL;
- }
- return node;
-}
-
-/**
- * Parse a term that is either a name (text) or a sub expression
- * enclosed in brackets.
- * @param parser the parser state
- * @return the parsed node or NULL in case of error
- * in case of error errno is set to EINVAL or ENOMEM
- */
-static struct node *node_parse_term(struct parse *parse)
-{
- struct node *node;
-
- if (parse->type != OBRA)
- node = node_parse_text(parse);
- else {
- parse_next(parse);
- node = node_parse_or(parse);
- if (parse->type == CBRA)
- parse_next(parse);
- else {
- errno = EINVAL;
- node_free(node);
- node = NULL;
- }