Logo Search packages:      
Sourcecode: hexec version File versions  Download package

parser.c

/***************************************************************************
 *   Copyright (C) 2008 by Alexander Block                                 *
 *   ablock@blocksoftware.net                                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "parser.h"
#include "common/buf.h"
#include "common/args.h"
#include "common/expr.h"
#include "common/error.h"

#include <string.h>
#include <assert.h>
#include <stdbool.h>
#include <ctype.h>

void hexec_parser_init(struct hexec_parser* p, struct hexec_buf* buf, struct args_t* args, int first_arg)
{
    p->buf = buf;
    p->args = args;
    p->cur_arg = first_arg;
    p->result = -1;

    int shm_header = hexec_buf_alloc(p->buf, sizeof(struct hexec_expr_shm_header));
    assert(shm_header == 0);

    p->shm_header = (struct hexec_expr_shm_header*)buf->buf;
    p->shm_header->root_expr = -1;
}

static void alloc_expr(struct hexec_parser* p, int* ptr, struct hexec_expr** e)
{
    *ptr = hexec_buf_alloc(p->buf, sizeof(struct hexec_expr));
    *e = (struct hexec_expr*)(p->buf->buf + (*ptr));
}

int hexec_parser_build_not(struct hexec_parser* p, int expr)
{
    int ei;
    struct hexec_expr* e;
    alloc_expr(p, &ei, &e);
    e->type = hexec_expr_not;
    e->expr1 = expr;
    return ei;
}

int hexec_parser_build_and(struct hexec_parser* p, int left, int right)
{
    int ei;
    struct hexec_expr* e;
    alloc_expr(p, &ei, &e);
    e->type = hexec_expr_and;
    e->expr1 = left;
    e->expr2 = right;
    return ei;
}

int hexec_parser_build_or(struct hexec_parser* p, int left, int right)
{
    int ei;
    struct hexec_expr* e;
    alloc_expr(p, &ei, &e);
    e->type = hexec_expr_or;
    e->expr1 = left;
    e->expr2 = right;
    return ei;
}

bool hexec_action_parse_print(struct hexec_parser* p, int* action)
{
    struct hexec_expr* e;
    alloc_expr(p, action, &e);
    e->type = hexec_expr_action_print;
    return true;
}

bool hexec_action_parse_fname_match(struct hexec_parser* p, int* action, int type, bool case_insensitive)
{
    if(p->cur_arg >= p->args->argc) 
    {
        hexec_error("expression misses argument\n");
        return false;
    }
    char* str = p->args->argv[p->cur_arg++];
    struct hexec_expr* e;
    alloc_expr(p, action, &e);
    e->type = type;
    e->case_insensitive = case_insensitive;
    e->str = hexec_buf_alloc(p->buf, strlen(str) + 1);
    
    char* str2 = p->buf->buf + e->str;
    strcpy(str2, str);

    if(type == hexec_expr_contains && case_insensitive)
    {
        // make the string lower case as we will need to do a 
        // lot of string compares in the future
        for(int i = 0; str2[i]; i++)
            str2[i] = tolower(str2[i]);
    }

    return true;
}

bool hexec_action_parse_exec(struct hexec_parser* p, int* action)
{
    if(p->cur_arg >= p->args->argc)
    {
        hexec_error("-exec misses command\n");
        return false;
    }

    int argc = 0;
    bool found_term = false;
    for(int i = p->cur_arg; i < p->args->argc; i++)
    {
        if(!strcmp(";", p->args->argv[i]))
        {
            found_term = true;
            break;
        }
        argc++;
    }
    if(argc == 0)
    {
        hexec_error("-exec misses command\n");
        return false;
    }
    if(!found_term)
    {
        hexec_error("-exec must be terminated with ;\n");
        return false;
    }

    int argv = hexec_buf_alloc(p->buf, sizeof(int) * argc);
    int* argv1 = (int*)(p->buf->buf + argv);
    for(int i = 0; i < argc; i++)
    {
        argv1[i] = hexec_buf_alloc(p->buf, strlen(p->args->argv[i + p->cur_arg]) + 1);
        strcpy(p->buf->buf + argv1[i], p->args->argv[i + p->cur_arg]);
    }
    struct hexec_expr* e;
    alloc_expr(p, action, &e);
    e->type = hexec_expr_action_exec;
    e->argc = argc;
    e->argv = argv;

    p->cur_arg += argc + 1; // +1 for ;

    return true;
}

bool hexec_action_parse_sh(struct hexec_parser* p, int* action)
{
    if(p->cur_arg >= p->args->argc)
    {
        hexec_error("-sh misses arguments\n");
        return false;
    }

    // This expression is internally handled as '-exec -sh -c <script> ;'

    const char* script = p->args->argv[p->cur_arg];

    struct hexec_expr* e;
    alloc_expr(p, action, &e);
    e->type = hexec_expr_action_exec;
    e->argc = 3;
    e->argv = hexec_buf_alloc(p->buf, sizeof(int) * e->argc);

    int* argv1 = (int*)(p->buf->buf + e->argv);
    argv1[0] = hexec_buf_strdup(p->buf, "/bin/sh");
    argv1[1] = hexec_buf_strdup(p->buf, "-c");
    argv1[2] = hexec_buf_strdup(p->buf, script);

    p->cur_arg += 1;

    return true;
}

Generated by  Doxygen 1.6.0   Back to index