Search
lxdream.org :: lxdream/src/tools/actparse.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/tools/actparse.c
changeset 1169:23a9613aceb1
prev981:79fcace1ab43
next1296:30ecee61f811
author nkeynes
date Sat Mar 03 15:52:59 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Swap between run + pause icons when pressed
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@1169
    19
#include <errno.h>
nkeynes@359
    20
#include <stdlib.h>
nkeynes@359
    21
#include <stdio.h>
nkeynes@359
    22
#include <string.h>
nkeynes@359
    23
#include <ctype.h>
nkeynes@359
    24
#include <sys/stat.h>
nkeynes@359
    25
#include <glib/gstrfuncs.h>
nkeynes@359
    26
#include "tools/gendec.h"
nkeynes@359
    27
nkeynes@979
    28
static int add_action( struct action *actions, struct ruleset *rules, char *operation, const char *file, int line, char *action )
nkeynes@359
    29
{
nkeynes@359
    30
    char *act = g_strchomp(action);
nkeynes@961
    31
    char opclean[strlen(operation)+1];
nkeynes@359
    32
    char *p = operation, *q = opclean;
nkeynes@359
    33
    int i;
nkeynes@359
    34
nkeynes@359
    35
    // Strip c-style comments 
nkeynes@359
    36
    while( *p ) {
nkeynes@736
    37
        if( *p == '/' && *(p+1) == '*' ) {
nkeynes@736
    38
            p+=2;
nkeynes@736
    39
            while( *p ) {
nkeynes@736
    40
                if( *p == '*' && *(p+1) == '/' ) {
nkeynes@736
    41
                    p+=2;
nkeynes@736
    42
                    break;
nkeynes@736
    43
                }
nkeynes@736
    44
                p++;
nkeynes@736
    45
            }
nkeynes@736
    46
        } else if( *p == '/' && *(p+1) == '/' ) {
nkeynes@736
    47
            p+=2;
nkeynes@736
    48
            while( *p && *p != '\n' ) {
nkeynes@736
    49
                p++;
nkeynes@736
    50
            }
nkeynes@736
    51
        } else {
nkeynes@736
    52
            *q++ = *p++;
nkeynes@736
    53
        }
nkeynes@359
    54
    }
nkeynes@359
    55
    *q = '\0';
nkeynes@979
    56
nkeynes@979
    57
    /* Drop any leading blank lines from the start of the action (and add them
nkeynes@979
    58
     * to the line number ) */ 
nkeynes@979
    59
    for( p=act; isspace(*p); p++ ) {
nkeynes@979
    60
        if( *p == '\n' ) {
nkeynes@979
    61
            act = p+1;
nkeynes@979
    62
            line++;
nkeynes@979
    63
        }
nkeynes@979
    64
    }
nkeynes@979
    65
    
nkeynes@359
    66
    strcpy( operation, g_strstrip(opclean) );
nkeynes@359
    67
nkeynes@359
    68
    for( i=0; i<rules->rule_count; i++ ) {
nkeynes@736
    69
        if( strcasecmp(rules->rules[i]->format, operation) == 0 ) {
nkeynes@979
    70
            if( actions[i].text != NULL ) {
nkeynes@981
    71
                fprintf( stderr, "gendec:%d: Duplicate actions for operation '%s' (previous action on line %d)\n", line, operation,
nkeynes@981
    72
                         actions[i].lineno );
nkeynes@736
    73
                return -1;
nkeynes@736
    74
            }
nkeynes@979
    75
            actions[i].filename = file;
nkeynes@979
    76
            actions[i].lineno = line;
nkeynes@979
    77
            actions[i].text = act;
nkeynes@736
    78
            return 0;
nkeynes@736
    79
        }
nkeynes@359
    80
    }
nkeynes@981
    81
    fprintf(stderr, "gendec:%d: No operation found matching '%s'\n", line, operation );
nkeynes@359
    82
    return -1;
nkeynes@359
    83
}
nkeynes@736
    84
nkeynes@948
    85
struct actionfile {
nkeynes@948
    86
    FILE *f;
nkeynes@979
    87
    const char *filename;
nkeynes@948
    88
    char *text;
nkeynes@948
    89
    int length;
nkeynes@948
    90
    int yyposn;
nkeynes@948
    91
    int yyline;
nkeynes@948
    92
    struct ruleset *rules;
nkeynes@948
    93
    struct actiontoken token;
nkeynes@948
    94
};
nkeynes@359
    95
nkeynes@948
    96
actionfile_t action_file_open( const char *filename, struct ruleset *rules )
nkeynes@359
    97
{
nkeynes@359
    98
    struct stat st;
nkeynes@948
    99
    FILE *f = fopen( filename, "ro" );
nkeynes@948
   100
    if( f == NULL ) 
nkeynes@948
   101
        return NULL;
nkeynes@948
   102
    fstat( fileno(f), &st );
nkeynes@948
   103
    
nkeynes@948
   104
    actionfile_t af = malloc( sizeof(struct actionfile) );
nkeynes@948
   105
    af->f = f;
nkeynes@979
   106
    af->filename = filename;
nkeynes@948
   107
    af->length = st.st_size+1;
nkeynes@948
   108
    af->text = malloc( st.st_size+1 );
nkeynes@1169
   109
    if( fread( af->text, st.st_size, 1, f ) != 1 ) {
nkeynes@1169
   110
        fprintf( stderr, "Error: unable to read from file '%s' (%s)\n", filename, strerror(errno));
nkeynes@1169
   111
        free(af);
nkeynes@1169
   112
        fclose(f);
nkeynes@1169
   113
        return NULL;
nkeynes@1169
   114
    }
nkeynes@948
   115
    af->text[st.st_size] = '\0';
nkeynes@979
   116
    af->yyline = 1;
nkeynes@948
   117
    af->yyposn = 0;
nkeynes@948
   118
    af->rules = rules;
nkeynes@948
   119
    af->token.symbol = NONE;
nkeynes@979
   120
    af->token.lineno = 1;
nkeynes@979
   121
    af->token.filename = filename;
nkeynes@948
   122
    return af;
nkeynes@948
   123
}
nkeynes@736
   124
nkeynes@948
   125
actiontoken_t action_file_next( actionfile_t af )
nkeynes@948
   126
{
nkeynes@979
   127
    af->token.lineno = af->yyline;
nkeynes@948
   128
    if( af->yyposn == af->length ) {
nkeynes@948
   129
        af->token.symbol = END;
nkeynes@948
   130
    } else if( af->token.symbol == TEXT || /* ACTIONS must follow TEXT */ 
nkeynes@961
   131
            (af->token.symbol == NONE && af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%') ) {
nkeynes@948
   132
        /* Begin action block */
nkeynes@948
   133
        af->token.symbol = ACTIONS;
nkeynes@981
   134
        memset( af->token.actions, 0, sizeof(af->token.actions) );
nkeynes@948
   135
nkeynes@948
   136
        char *operation = &af->text[af->yyposn];
nkeynes@948
   137
        while( af->yyposn < af->length ) {
nkeynes@948
   138
            if( af->text[af->yyposn] == '\n' ) {
nkeynes@979
   139
                af->yyline++;
nkeynes@948
   140
                if( af->text[af->yyposn+1] == '%' && af->text[af->yyposn+2] == '%' ) {
nkeynes@948
   141
                    af->yyposn += 3;
nkeynes@948
   142
                    break;
nkeynes@948
   143
                }
nkeynes@736
   144
            }
nkeynes@948
   145
nkeynes@948
   146
            if( af->text[af->yyposn] == '{' && af->text[af->yyposn+1] == ':' ) {
nkeynes@948
   147
                af->text[af->yyposn] = '\0';
nkeynes@979
   148
                int line = af->yyline;
nkeynes@948
   149
                af->yyposn+=2;
nkeynes@948
   150
                char *action = &af->text[af->yyposn];
nkeynes@948
   151
                while( af->yyposn < af->length ) {
nkeynes@948
   152
                    if( af->text[af->yyposn] == ':' && af->text[af->yyposn+1] == '}' ) {
nkeynes@948
   153
                        af->text[af->yyposn] = '\0';
nkeynes@948
   154
                        af->yyposn++;
nkeynes@979
   155
                        if( add_action( af->token.actions, af->rules, operation, af->filename, line, action ) != 0 ) {
nkeynes@948
   156
                            af->token.symbol = ERROR;
nkeynes@948
   157
                            return &af->token;
nkeynes@948
   158
                        }
nkeynes@948
   159
                        operation = &af->text[af->yyposn+1];
nkeynes@948
   160
                        break;
nkeynes@979
   161
                    } else if( af->text[af->yyposn] == '\n' ) {
nkeynes@979
   162
                        af->yyline++;
nkeynes@948
   163
                    }
nkeynes@948
   164
                    af->yyposn++;
nkeynes@948
   165
                }
nkeynes@948
   166
            }
nkeynes@948
   167
            af->yyposn++;
nkeynes@736
   168
        }
nkeynes@948
   169
    } else {
nkeynes@948
   170
        /* Text block */
nkeynes@948
   171
        af->token.symbol = TEXT;
nkeynes@948
   172
        af->token.text = &af->text[af->yyposn]; 
nkeynes@948
   173
        while( af->yyposn < af->length ) {
nkeynes@948
   174
            af->yyposn++;
nkeynes@948
   175
            if( af->text[af->yyposn-1] == '\n' ) {
nkeynes@948
   176
                af->yyline++;
nkeynes@948
   177
                if( af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%' ) {
nkeynes@948
   178
                    af->text[af->yyposn] = '\0';
nkeynes@948
   179
                    af->yyposn += 2;
nkeynes@736
   180
                    break;
nkeynes@736
   181
                }
nkeynes@736
   182
            }
nkeynes@736
   183
        }
nkeynes@359
   184
    }
nkeynes@948
   185
    return &af->token;
nkeynes@948
   186
}
nkeynes@359
   187
nkeynes@948
   188
void action_file_close( actionfile_t af )
nkeynes@948
   189
{
nkeynes@948
   190
    free( af->text );
nkeynes@948
   191
    fclose( af->f );
nkeynes@948
   192
    free( af );
nkeynes@948
   193
}
nkeynes@736
   194
.