Search
lxdream.org :: lxdream/src/tools/actparse.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/tools/actparse.c
changeset 948:545c85cc56f1
prev736:a02d1475ccfd
next961:3541b280e0f1
author nkeynes
date Tue Jan 13 11:56:28 2009 +0000 (15 years ago)
permissions -rw-r--r--
last change Merge lxdream-mem branch back to trunk
file annotate diff log raw
nkeynes@561
     1
/**
nkeynes@561
     2
 * $Id$
nkeynes@561
     3
 *
nkeynes@561
     4
 * gendec action file parser. 
nkeynes@561
     5
 *
nkeynes@561
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@561
     7
 *
nkeynes@561
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@561
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@561
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@561
    11
 * (at your option) any later version.
nkeynes@561
    12
 *
nkeynes@561
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@561
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@561
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@561
    16
 * GNU General Public License for more details.
nkeynes@561
    17
 */
nkeynes@561
    18
nkeynes@359
    19
#include <stdlib.h>
nkeynes@359
    20
#include <stdio.h>
nkeynes@359
    21
#include <string.h>
nkeynes@359
    22
#include <ctype.h>
nkeynes@359
    23
#include <sys/stat.h>
nkeynes@359
    24
#include <glib/gstrfuncs.h>
nkeynes@359
    25
#include "tools/gendec.h"
nkeynes@359
    26
nkeynes@359
    27
static int yyline;
nkeynes@359
    28
nkeynes@420
    29
struct action *new_action() {
nkeynes@359
    30
    struct action *action = malloc( sizeof( struct action ) );
nkeynes@359
    31
    memset( action, 0, sizeof( struct action ) );
nkeynes@359
    32
    return action;
nkeynes@359
    33
}
nkeynes@359
    34
nkeynes@948
    35
int add_action( char **actions, struct ruleset *rules, char *operation, char *action )
nkeynes@359
    36
{
nkeynes@359
    37
    char *act = g_strchomp(action);
nkeynes@359
    38
nkeynes@359
    39
    char opclean[strlen(operation)];
nkeynes@359
    40
    char *p = operation, *q = opclean;
nkeynes@359
    41
    int i;
nkeynes@359
    42
nkeynes@359
    43
    // Strip c-style comments 
nkeynes@359
    44
    while( *p ) {
nkeynes@736
    45
        if( *p == '/' && *(p+1) == '*' ) {
nkeynes@736
    46
            p+=2;
nkeynes@736
    47
            while( *p ) {
nkeynes@736
    48
                if( *p == '*' && *(p+1) == '/' ) {
nkeynes@736
    49
                    p+=2;
nkeynes@736
    50
                    break;
nkeynes@736
    51
                }
nkeynes@736
    52
                p++;
nkeynes@736
    53
            }
nkeynes@736
    54
        } else if( *p == '/' && *(p+1) == '/' ) {
nkeynes@736
    55
            p+=2;
nkeynes@736
    56
            while( *p && *p != '\n' ) {
nkeynes@736
    57
                p++;
nkeynes@736
    58
            }
nkeynes@736
    59
        } else {
nkeynes@736
    60
            *q++ = *p++;
nkeynes@736
    61
        }
nkeynes@359
    62
    }
nkeynes@359
    63
    *q = '\0';
nkeynes@359
    64
    strcpy( operation, g_strstrip(opclean) );
nkeynes@359
    65
nkeynes@359
    66
    for( i=0; i<rules->rule_count; i++ ) {
nkeynes@736
    67
        if( strcasecmp(rules->rules[i]->format, operation) == 0 ) {
nkeynes@948
    68
            if( actions[i] != NULL ) {
nkeynes@736
    69
                fprintf( stderr, "Duplicate actions for operation '%s'\n", operation );
nkeynes@736
    70
                return -1;
nkeynes@736
    71
            }
nkeynes@948
    72
            actions[i] = act;
nkeynes@736
    73
            return 0;
nkeynes@736
    74
        }
nkeynes@359
    75
    }
nkeynes@359
    76
    fprintf(stderr, "No operation found matching '%s'\n", operation );
nkeynes@359
    77
    return -1;
nkeynes@359
    78
}
nkeynes@736
    79
nkeynes@948
    80
struct actionfile {
nkeynes@948
    81
    FILE *f;
nkeynes@948
    82
    char *text;
nkeynes@948
    83
    int length;
nkeynes@948
    84
    int yyposn;
nkeynes@948
    85
    int yyline;
nkeynes@948
    86
    struct ruleset *rules;
nkeynes@948
    87
    struct actiontoken token;
nkeynes@948
    88
};
nkeynes@359
    89
nkeynes@948
    90
actionfile_t action_file_open( const char *filename, struct ruleset *rules )
nkeynes@359
    91
{
nkeynes@359
    92
    struct stat st;
nkeynes@948
    93
    FILE *f = fopen( filename, "ro" );
nkeynes@948
    94
    if( f == NULL ) 
nkeynes@948
    95
        return NULL;
nkeynes@948
    96
    fstat( fileno(f), &st );
nkeynes@948
    97
    
nkeynes@948
    98
    actionfile_t af = malloc( sizeof(struct actionfile) );
nkeynes@948
    99
    af->f = f;
nkeynes@948
   100
    af->length = st.st_size+1;
nkeynes@948
   101
    af->text = malloc( st.st_size+1 );
nkeynes@948
   102
    fread( af->text, st.st_size, 1, f );
nkeynes@948
   103
    af->text[st.st_size] = '\0';
nkeynes@948
   104
    af->yyline = 0;
nkeynes@948
   105
    af->yyposn = 0;
nkeynes@948
   106
    af->rules = rules;
nkeynes@948
   107
    af->token.symbol = NONE;
nkeynes@948
   108
    
nkeynes@948
   109
    return af;
nkeynes@948
   110
}
nkeynes@736
   111
nkeynes@948
   112
actiontoken_t action_file_next( actionfile_t af )
nkeynes@948
   113
{
nkeynes@948
   114
    if( af->token.symbol == ACTIONS ) {
nkeynes@948
   115
        /* Destroy previous actions */
nkeynes@948
   116
        memset( af->token.actions, 0, sizeof(af->token.actions) );
nkeynes@948
   117
    }
nkeynes@948
   118
    
nkeynes@948
   119
    if( af->yyposn == af->length ) {
nkeynes@948
   120
        af->token.symbol = END;
nkeynes@948
   121
    } else if( af->token.symbol == TEXT || /* ACTIONS must follow TEXT */ 
nkeynes@948
   122
            (af->token.symbol == NONE && af->text[af->yyposn] == '\%' && af->text[af->yyposn+1] == '%') ) {
nkeynes@948
   123
        /* Begin action block */
nkeynes@948
   124
        af->token.symbol = ACTIONS;
nkeynes@948
   125
nkeynes@948
   126
        char *operation = &af->text[af->yyposn];
nkeynes@948
   127
        while( af->yyposn < af->length ) {
nkeynes@948
   128
            if( af->text[af->yyposn] == '\n' ) {
nkeynes@948
   129
                yyline++;
nkeynes@948
   130
                if( af->text[af->yyposn+1] == '%' && af->text[af->yyposn+2] == '%' ) {
nkeynes@948
   131
                    af->yyposn += 3;
nkeynes@948
   132
                    break;
nkeynes@948
   133
                }
nkeynes@736
   134
            }
nkeynes@948
   135
nkeynes@948
   136
            if( af->text[af->yyposn] == '{' && af->text[af->yyposn+1] == ':' ) {
nkeynes@948
   137
                af->text[af->yyposn] = '\0';
nkeynes@948
   138
                af->yyposn+=2;
nkeynes@948
   139
                char *action = &af->text[af->yyposn];
nkeynes@948
   140
                while( af->yyposn < af->length ) {
nkeynes@948
   141
                    if( af->text[af->yyposn] == ':' && af->text[af->yyposn+1] == '}' ) {
nkeynes@948
   142
                        af->text[af->yyposn] = '\0';
nkeynes@948
   143
                        af->yyposn++;
nkeynes@948
   144
                        if( add_action( af->token.actions, af->rules, operation, action ) != 0 ) {
nkeynes@948
   145
                            af->token.symbol = ERROR;
nkeynes@948
   146
                            return &af->token;
nkeynes@948
   147
                        }
nkeynes@948
   148
                        operation = &af->text[af->yyposn+1];
nkeynes@948
   149
                        break;
nkeynes@948
   150
                    }
nkeynes@948
   151
                    af->yyposn++;
nkeynes@948
   152
                }
nkeynes@948
   153
            }
nkeynes@948
   154
            af->yyposn++;
nkeynes@736
   155
        }
nkeynes@948
   156
    } else {
nkeynes@948
   157
        /* Text block */
nkeynes@948
   158
        af->token.symbol = TEXT;
nkeynes@948
   159
        af->token.text = &af->text[af->yyposn]; 
nkeynes@948
   160
        while( af->yyposn < af->length ) {
nkeynes@948
   161
            af->yyposn++;
nkeynes@948
   162
            if( af->text[af->yyposn-1] == '\n' ) {
nkeynes@948
   163
                af->yyline++;
nkeynes@948
   164
                if( af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%' ) {
nkeynes@948
   165
                    af->text[af->yyposn] = '\0';
nkeynes@948
   166
                    af->yyposn += 2;
nkeynes@736
   167
                    break;
nkeynes@736
   168
                }
nkeynes@736
   169
            }
nkeynes@736
   170
        }
nkeynes@359
   171
    }
nkeynes@948
   172
    return &af->token;
nkeynes@948
   173
}
nkeynes@359
   174
nkeynes@948
   175
void action_file_close( actionfile_t af )
nkeynes@948
   176
{
nkeynes@948
   177
    free( af->text );
nkeynes@948
   178
    fclose( af->f );
nkeynes@948
   179
    free( af );
nkeynes@948
   180
}
nkeynes@736
   181
.