libidav/davqlparser.c

Tue, 24 Mar 2015 15:49:51 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 24 Mar 2015 15:49:51 +0100
changeset 79
59c518ae0641
parent 76
4c48ce3b9045
child 80
a2832c054c98
permissions
-rw-r--r--

added parse function prototype + started writing a debugger

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2015 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "davqlparser.h"
#include <string.h>
#include <stdio.h>

static const char* _map_querytype(davqltype_t type) {
    switch(type) {
    case GET: return "GET";
    case SET: return "SET";
    default: return "unknown";
    }
}

#define dav_debug_print_sstr_t(s) fwrite((s).ptr, 1, (s).length, stdout);

static void dav_debug_ql_stmt_print(DavQLStatement *stmt) {
    
    // Basic information
    printf("Statement: ");
    dav_debug_print_sstr_t(stmt->srctext);
    printf("\nType: %s\nField count: %zu",
        _map_querytype(stmt->type),
        ucx_list_size(stmt->fields));
    
    // Has wildcard
    _Bool wildcard = 0;
    UCX_FOREACH(elm, stmt->fields) {
        DavQLExpression* expr = (DavQLExpression*)elm->data;
        if (expr->type == IDENTIFIER &&
            expr->srctext.length == 1 && *(expr->srctext.ptr) == '*') {
            wildcard = 1;
        }
    }
    printf(" with%s wildcard\n", wildcard?"":"out");
    
    // Pathname
    printf("Path: ");
    dav_debug_print_sstr_t(stmt->path.srctext);
    
    // Has where clause
    printf("\nHas where clause: %s\n", stmt->where ? "yes" : "no");
    if (stmt->type == SET) {
        printf("Value list size matches: %s",
            ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues)
            ? "yes" : "no");
    }
    
    // WITH attributes
    if (stmt->depth == SIZE_MAX) {
        printf("Depth: unbound\n");
    } else {
        printf("Depth: %zu\n", stmt->depth);
    }
}

static int dav_debug_ql_command() {
    printf("Command (type 'h' for help): ");
    
    char buffer[16];
    fgets(buffer, 16, stdin);
    if (!strcmp(buffer, "q\n")) {
        return 0;
    } else if (!strcmp(buffer, "ps\n")) {
        return 1;
    } else if (!strcmp(buffer, "h\n")) {
        return 100;
    } else {
        return -1;
    }
}

void dav_debug_ql_statement(DavQLStatement *stmt) {
    if (!stmt) {
        fprintf(stderr, "Debug DavQLStatement failed: null pointer");
        return;
    }

    printf("Starting DavQL debugger...\n\n");
    dav_debug_ql_stmt_print(stmt);
    
    while(1) {
        int cmd = dav_debug_ql_command();
        switch (cmd) {
        case 0: return;
        case 1: dav_debug_ql_stmt_print(stmt); break;
        case 100:
            printf(
                "\nCommands:\n"
                "ps:  print statement information\n"
                "q:   quit\n");
            break;
        default: printf("unknown command\n");
        }
    }
}

DavQLStatement* dav_parse_statement(sstr_t srctext) {
    DavQLStatement *stmt = malloc(sizeof(DavQLStatement));
    
    // default values
    memset(stmt, 0, sizeof(DavQLStatement));
    stmt->srctext = srctext;
    stmt->type = -1;
    stmt->depth = SIZE_MAX;
    
    
    return stmt;
}

mercurial