IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 29, 2019, 5:05:27 AM (7 years ago)
Author:
eugene
Message:

allow nested variables in lists (e.g., $ref = foo, $foo:n = a, $$ref:n = a); add list -file option

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/lib.shell/expand_vars.c

    r30614 r40652  
    2323
    2424  /* look for form $a$b..$n and expand only the last ones */
     25
     26  // expand from line (L) into newline (N)
    2527  for (L = line, N = newline; *L != 0; N++, L++) {  /* loop until end of line */
     28
     29    // look for end of line or start of variable ($)
    2630    for (done = FALSE; !done;) {
    2731      if (*L == 0) done = TRUE;
     32
     33      // look for the last $var
    2834      if (*L == '$') {
    2935        V1 = aftervar(L);
     
    3137        if (V1 == NULL) done = TRUE;
    3238      }
     39
     40      // copy into newline
    3341      if (!done) {
    3442        *N = *L;
     
    4452    }
    4553
     54    // end of the line
    4655    if (*L == 0) break;
    4756
     
    5059    /* note: V1 points to a fraction of L, it does not need to be freed */
    5160
    52     /* no variable name */
     61    /* no variable name, e.g., word$ or $$.  keep the $ intact */
    5362    if (V0 == NULL) {
    5463      *N = *L;
     
    6271    }
    6372
    64     /* variable assignment (skip these variables) */
     73    /* variable assignment ($ at start of the line) : skip these variables */
    6574    if ((L == line) && (V1 != NULL)) {
    6675      int isAssignment;
     
    8695    }
    8796
     97    // V0 is the name of a variable. 
     98    // $tree_$branch_$twig should work (e.g,. $foo_bar_baz exists, $twig = baz, $foo_bar_$twig )
     99    // $ref = name; echo $$ref:n word  need to expand $ref to get value of $name:n
     100
     101    // examples of valid nested variables, given $name = value, $ref = name, $name:n = 1, $name:0 = a, $i = 0
     102    // $$ref -> value
     103    // $$ref:n -> $name:n
     104    // $$ref:$i -> $$ref:0 $name:9
     105   
     106    // is there a $ in the previous character?
     107    // do not include ':' in the variable name
     108    int isRef = FALSE;
     109    if ((L != line) && (L[-1] == '$')) {
     110      free (V0);
     111      V0 = thisref(L);
     112      isRef = TRUE;
     113    }
     114
     115    // check for macro-arguments ($1, $2)
    88116    found = TRUE;
    89117    for (c = V0; isdigit(*c); c++); /* test if this is a macro argument variable (ie, $1.2) */
     
    100128      }
    101129    }
     130
     131    // we have something of the form $word, where V0 now is word.  expand it out:
    102132
    103133    Val = get_variable_ptr (V0);
     
    117147    N--; /* we overshoot on last loop */
    118148
    119     /* skip past the variable in the source line */
     149    /* skip past the variable (or reference) in the source line */
    120150    /* L currently points at $ */
    121151    L++;
    122152    if (*L == '?') L++;  /* skip past ? in $?name */
    123153
    124     while (ISVAR(*L)) L++;
     154    if (isRef) {
     155      while (ISREF(*L)) L++;
     156    } else {
     157      while (ISVAR(*L)) L++;
     158    }
    125159    L--; /* we overshoot */
    126160
Note: See TracChangeset for help on using the changeset viewer.