#include #include #include #include "locus.h" #include "yyloc.h" #include "mimetypes.h" struct mimetypes_string { char *ptr; size_t len; }; #define LL_ENTRY(type) \ struct \ { \ struct type *lle_next; /* next element */ \ struct type *lle_prev; /* previous element */ \ } #define LL_HEAD(name, type) \ struct name \ { \ struct type *ll_head; \ struct type *ll_tail; \ size_t ll_count; \ } #define LL_HEAD_INIT(head) \ do \ { \ (head)->ll_head = (head)->ll_tail = NULL; \ (head)->ll_count = 0; \ } \ while (0) #define LL_HEAD_INITIALIZER \ { NULL, NULL, 0 } #define LL_FIRST(head) \ (head)->ll_head #define LL_LAST(head) \ (head)->ll_tail #define LL_COUNT(head) \ (head)->ll_count #define LLE_NEXT(elt,field) \ (elt)->field.lle_next #define LLE_PREV(elt,field) \ (elt)->field.lle_prev #define LLE_APPEND(head,elt,field) \ do \ { \ if (((elt)->field.lle_prev = LL_LAST (head)) == NULL) \ LL_FIRST (head) = (elt); \ else \ (elt)->field.lle_prev->field.lle_next = (elt); \ (elt)->field.lle_next = NULL; \ LL_LAST (head) = (elt); \ (head)->ll_count++; \ } \ while (0) #define LLE_UNLINK(head,elt,field) \ do \ { \ if ((elt)->field.lle_next != NULL) \ (elt)->field.lle_next->field.lle_prev = (elt)->field.lle_prev; \ else \ LL_LAST (head) = (elt)->field.lle_prev; \ if ((elt)->field.lle_prev != NULL) \ (elt)->field.lle_prev->field.lle_next = (elt)->field.lle_next; \ else \ LL_FIRST (head) = (elt)->field.lle_next; \ (head)->ll_count--; \ } \ while (0) #define LL_FOREACH(head,elt,field) \ for (elt = LL_FIRST (head); elt; elt = LLE_NEXT (elt,field)) #define L_OR 0 #define L_AND 1 enum node_type { true_node, functional_node, binary_node, negation_node, suffix_node }; struct rule { char *type; int priority; struct locus_range loc; struct node *node; LL_ENTRY(rule) link; }; LL_HEAD(rule_list, rule); union argument { struct mimetypes_string string; unsigned number; int c; regex_t rx; }; struct filebuf { char const *name; FILE *fp; }; typedef int (*builtin_t) (union argument *args, struct filebuf const *fb); struct node { enum node_type type; struct locus_range loc; union { struct { builtin_t fun; union argument *args; } function; struct node *arg; struct { int op; struct node *arg1; struct node *arg2; } bin; struct mimetypes_string suffix; } v; }; struct builtin_tab { char *name; char *args; builtin_t handler; }; struct builtin_tab const *find_builtin (char const *ident); struct arg_elt { struct mimetypes_string string; LL_ENTRY(arg_elt) link; }; LL_HEAD(arg_list, arg_elt); ssize_t mimetypes_error_format (char **pbuf, size_t *psize, struct locus_range const *lr, char const *fmt, va_list ap); void mimetypes_error_at (struct locus_range const *lr, char const *fmt, ...); void mimetypes_error (char const *fmt, ...); void print_locus_range (FILE *fp, struct locus_range const *lr); void mimetypes_nomem (void); int mimetypes_open (const char *name); void mimetypes_close (void); void lex_next_rule (void); extern struct rule_list rule_list;