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