httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n.@apache.org
Subject cvs commit: httpd-2.0/modules/filters mod_include.c
Date Mon, 25 Aug 2003 00:16:04 GMT
nd          2003/08/24 17:16:04

  Modified:    modules/filters mod_include.c
  Log:
  Ha! Wrote this combined tree dumper and consistency checker just for fun.
  
  ...and saw that the expression parser generates inconsistent trees under
  some circumstances. So I've decided that the dumper code may be of public
  interest :). The actual bugfixes will follow later.
  
  Revision  Changes    Path
  1.260     +154 -8    httpd-2.0/modules/filters/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/filters/mod_include.c,v
  retrieving revision 1.259
  retrieving revision 1.260
  diff -u -r1.259 -r1.260
  --- mod_include.c	24 Aug 2003 16:16:36 -0000	1.259
  +++ mod_include.c	25 Aug 2003 00:16:04 -0000	1.260
  @@ -148,6 +148,9 @@
       token_t token;
       int value;
       int done;
  +#ifdef DEBUG_INCLUDE
  +    int dump_done;
  +#endif
   } parse_node_t;
   
   typedef enum {
  @@ -255,6 +258,19 @@
    */
   
   #ifdef DEBUG_INCLUDE
  +
  +#define TYPE_TOKEN(token, ttype) do { \
  +    (token)->type = ttype;            \
  +    (token)->s = #ttype;              \
  +} while(0)
  +
  +#define CREATE_NODE(ctx, name) do {                       \
  +    (name) = apr_palloc((ctx)->dpool, sizeof(*(name)));   \
  +    (name)->parent = (name)->left = (name)->right = NULL; \
  +    (name)->done = 0;                                     \
  +    (name)->dump_done = 0;                                \
  +} while(0)
  +
   static void debug_printf(include_ctx_t *ctx, const char *fmt, ...)
   {
       va_list ap;
  @@ -269,6 +285,132 @@
                               ctx->intern->debug.f->c->bucket_alloc));
   }
   
  +#define DUMP__CHILD(ctx, is, node, child) if (1) {                           \
  +    parse_node_t *d__c = node->child;                                        \
  +    if (d__c) {                                                              \
  +        if (!d__c->dump_done) {                                              \
  +            if (d__c->parent != node) {                                      \
  +                debug_printf(ctx, "!!! Parse tree is not consistent !!!\n"); \
  +                if (!d__c->parent) {                                         \
  +                    debug_printf(ctx, "Parent of " #child " child node is "  \
  +                                 "NULL.\n");                                 \
  +                }                                                            \
  +                else {                                                       \
  +                    debug_printf(ctx, "Parent of " #child " child node "     \
  +                                 "points to another node (of type %s)!\n",   \
  +                                 d__c->parent->token.s);                     \
  +                }                                                            \
  +                return;                                                      \
  +            }                                                                \
  +            node = d__c;                                                     \
  +            continue;                                                        \
  +        }                                                                    \
  +    }                                                                        \
  +    else {                                                                   \
  +        debug_printf(ctx, "%s(missing)\n", is);                              \
  +    }                                                                        \
  +}
  +
  +static void debug_dump_tree(include_ctx_t *ctx, parse_node_t *root)
  +{
  +    parse_node_t *current;
  +    char *is;
  +
  +    if (!root) {
  +        debug_printf(ctx, "     -- Parse Tree empty --\n\n");
  +        return;
  +    }
  +
  +    debug_printf(ctx, "     ----- Parse Tree -----\n");
  +    current = root;
  +    is = "     ";
  +
  +    while (current) {
  +        switch (current->token.type) {
  +        case TOKEN_STRING:
  +        case TOKEN_RE:
  +            debug_printf(ctx, "%s%s (%s)\n", is, current->token.s,
  +                         current->token.value);
  +            current->dump_done = 1;
  +            current = current->parent;
  +            continue;
  +
  +        case TOKEN_AND:
  +        case TOKEN_OR:
  +        case TOKEN_EQ:
  +        case TOKEN_NE:
  +        case TOKEN_GE:
  +        case TOKEN_LE:
  +        case TOKEN_GT:
  +        case TOKEN_LT:
  +            if (!current->dump_done) {
  +                debug_printf(ctx, "%s%s\n", is, current->token.s);
  +                is = apr_pstrcat(ctx->dpool, is, "    ", NULL);
  +                current->dump_done = 1;
  +            }
  +
  +            DUMP__CHILD(ctx, is, current, left)
  +            DUMP__CHILD(ctx, is, current, right)
  +
  +            if ((!current->left || current->left->dump_done) &&
  +                (!current->right || current->right->dump_done)) {
  +
  +                is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);
  +                if (current->left) current->left->dump_done = 0;
  +                if (current->right) current->right->dump_done = 0;
  +                current = current->parent;
  +            }
  +            continue;
  +
  +        case TOKEN_NOT:
  +        case TOKEN_GROUP:
  +            if (!current->dump_done) {
  +                debug_printf(ctx, "%s%s\n", is, current->token.s);
  +                is = apr_pstrcat(ctx->dpool, is, "    ", NULL);
  +                current->dump_done = 1;
  +            }
  +
  +            DUMP__CHILD(ctx, is, current, right)
  +
  +            if (!current->right || current->right->dump_done) {
  +                is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);
  +                if (current->right) current->right->dump_done = 0;
  +                current = current->parent;
  +            }
  +            continue;
  +
  +        case TOKEN_RBRACE:
  +        case TOKEN_LBRACE:
  +            if (!current->dump_done) {
  +                debug_printf(ctx, "%sunmatched %s\n", is, current->token.s);
  +                is = apr_pstrcat(ctx->dpool, is, "    ", NULL);
  +                current->dump_done = 1;
  +            }
  +
  +            DUMP__CHILD(ctx, is, current, right)
  +
  +            if (!current->right || current->right->dump_done) {
  +                is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);
  +                if (current->right) current->right->dump_done = 0;
  +                current = current->parent;
  +            }
  +            continue;
  +        }
  +    }
  +
  +    /* it is possible to call this function within the parser loop, to see
  +     * how the tree is built. That way, we must cleanup after us to dump
  +     * always the whole tree
  +     */
  +    root->dump_done = 0;
  +    if (root->left) root->left->dump_done = 0;
  +    if (root->right) root->right->dump_done = 0;
  +
  +    debug_printf(ctx, "     --- End Parse Tree ---\n\n");
  +
  +    return;
  +}
  +
   #define DEBUG_INIT(ctx, filter, brigade) do { \
       (ctx)->intern->debug.f = filter;          \
       (ctx)->intern->debug.bb = brigade;        \
  @@ -276,11 +418,6 @@
   
   #define DEBUG_PRINTF(arg) debug_printf arg
   
  -#define TYPE_TOKEN(token, ttype) do { \
  -    (token)->type = ttype;            \
  -    (token)->s = #ttype;              \
  -} while(0)
  -
   #define DEBUG_DUMP_TOKEN(ctx, token) do {                                     \
       token_t *d__t = (token);                                                  \
                                                                                 \
  @@ -302,14 +439,24 @@
       DEBUG_PRINTF(((ctx), "**** %s cond status=\"%c\"\n", (text),   \
                     ((ctx)->flags & SSI_FLAG_COND_TRUE) ? '1' : '0'))
   
  +#define DEBUG_DUMP_TREE(ctx, root) debug_dump_tree(ctx, root)
  +
   #else /* DEBUG_INCLUDE */
   
   #define TYPE_TOKEN(token, ttype) (token)->type = ttype
  +
  +#define CREATE_NODE(ctx, name) do {                       \
  +    (name) = apr_palloc((ctx)->dpool, sizeof(*(name)));   \
  +    (name)->parent = (name)->left = (name)->right = NULL; \
  +    (name)->done = 0;                                     \
  +} while(0)
  +
   #define DEBUG_INIT(ctx, f, bb)
   #define DEBUG_PRINTF(arg)
   #define DEBUG_DUMP_TOKEN(ctx, token)
   #define DEBUG_DUMP_UNMATCHED(ctx, unmatched)
   #define DEBUG_DUMP_COND(ctx, text)
  +#define DEBUG_DUMP_TREE(ctx, root)
   
   #endif /* !DEBUG_INCLUDE */
   
  @@ -1009,9 +1156,8 @@
   
       /* Create Parse Tree */
       while (1) {
  -        new = apr_palloc(ctx->dpool, sizeof(*new));
  -        new->parent = new->left = new->right = NULL;
  -        new->done = 0;
  +        DEBUG_DUMP_TREE(ctx, root);
  +        CREATE_NODE(ctx, new);
   
           was_unmatched = get_ptoken(ctx->dpool, &parse, &new->token);
           if (!parse) {
  
  
  

Mime
View raw message