Changeset 3468

Show
Ignore:
Timestamp:
08/09/07 17:46:10 (1 year ago)
Author:
tg
Message:

algorithm for variable expansion, dead simple:
• first, variables are looked up:

  • ${FOO} -> content of FOO
    syntax errors are handled by eating the dollar sign and braces:
  • $x -> x
  • ${x -> x

• then, all first backslashes are removed

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/common-nfo/tools/nfotiser/nfotiser.h

    r3465 r3468  
    6363void parser_free(struct parser_result *); 
    6464EXTERN char *parser_errpfx I__(NULL); 
     65struct parser_res *parse_lookupbyname(struct parser_result *, const char *); 
     66struct parser_res *parse_lookup(struct parser_result *, struct parser_res *); 
    6567__END_DECLS 
    6668 
  • branches/common-nfo/tools/nfotiser/pfile.c

    r3467 r3468  
    3535#include <errno.h> 
    3636#include <fcntl.h> 
     37#include <stdbool.h> 
    3738#include <stdint.h> 
    3839#include <stdio.h> 
     
    4041#include <string.h> 
    4142#include <unistd.h> 
    42  
    43 static void do_defaultvalues(struct parser_result *); 
    44 static void do_varexpand(struct parser_result *); 
    4543 
    4644enum kwords { 
     
    121119}; 
    122120 
     121static void do_defaultvalues(struct parser_result *); 
     122static void do_varexpand(struct parser_result *); 
     123 
    123124void 
    124125pfile(const char *fn) 
     
    168169do_varexpand(struct parser_result *head) 
    169170{ 
    170         /* ENOCOFFEE */; 
     171        struct parser_res *entry, *evar; 
     172        char ch, *cp, *tp, *dp; 
     173        bool do_again; 
     174 
     175 expand_loop: 
     176        do_again = false; 
     177        CIRCLEQ_FOREACH(entry, head, e) { 
     178                if ((cp = entry->value) == NULL) 
     179                        continue; 
     180                /* scan the value for variable references */ 
     181                while ((ch = *cp++)) 
     182                        if (ch == '\\') 
     183                                cp++; 
     184                        else if (ch == '$') 
     185                                break; 
     186                if (!ch) 
     187                        continue; 
     188                /* cp points to a dollar sign, copy head */ 
     189                dp = str_nsave(entry->value, cp - entry->value); 
     190                /* read variable name */ 
     191                if (*++cp != '{' /*}*/) 
     192                        goto copy_rest; 
     193                tp = ++cp; 
     194                while (*tp && (*tp != /*{*/ '}')) 
     195                        ++tp; 
     196                if (*tp != /*{*/ '}') 
     197                        goto copy_rest; 
     198                *tp++ = '\0'; 
     199                /* variable name in cp, rest of string in tp */ 
     200                evar = parse_lookupbyname(head, cp); 
     201                cp = tp; 
     202                /* variable content in evar, rest of string in cp */ 
     203                if (evar && evar->value) 
     204                        dp = str_add(dp, evar->value); 
     205 copy_rest: 
     206                dp = str_add(dp, cp); 
     207                free(entry->value); 
     208                entry->value = dp; 
     209                /* string was modified, so reloop */ 
     210                do_again = true; 
     211                break; 
     212        } 
     213        if (do_again) 
     214                goto expand_loop; 
     215        /* all variable references have been expanded */ 
     216        CIRCLEQ_FOREACH(entry, head, e) { 
     217                if ((cp = entry->value) == NULL) 
     218                        continue; 
     219                /* unescape backslashes */ 
     220                tp = dp = str_save(cp); 
     221                while ((ch = *cp++)) { 
     222                        if (ch == '\\') 
     223                                ch = *cp++; 
     224                        *tp++ = ch; 
     225                } 
     226                free(entry->value); 
     227                entry->value = dp; 
     228        } 
    171229}