home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / kpathsea / variable.c < prev    next >
C/C++ Source or Header  |  1993-07-31  |  5KB  |  175 lines

  1. /* variable.c: variable expansion.
  2.  
  3. Copyright (C) 1993 Karl Berry.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <kpathsea/config.h>
  20.  
  21. #include <kpathsea/c-ctype.h>
  22. #include <kpathsea/fn.h>
  23. #include <kpathsea/variable.h>
  24.  
  25.  
  26. /* Append the result of `getenv (var)' to EXPANSION, where `var' begins
  27.    at START and ends at END.  If `var' is not set, do not complain.  */
  28.  
  29. static void
  30. expand P3C(fn_type *, expansion, const_string, start,  const_string, end)
  31. {
  32.   string value;
  33.   unsigned len = end - start + 1;
  34.   string var = xmalloc (len + 1);
  35.   strncpy (var, start, len);
  36.   var[len] = 0;
  37.   
  38.   value = getenv (var);
  39.   if (value)
  40.     fn_grow (expansion, value, strlen (value));
  41.   
  42.   free (var);
  43. }
  44.  
  45. /* Can't think of when it would be useful to change these (and the
  46.    diagnostic messages assume them), but ... */
  47. #ifndef IS_VAR_START /* starts all variable references */
  48. #define IS_VAR_START(c) ((c) == '$')
  49. #endif
  50. #ifndef IS_VAR_CHAR  /* variable name constituent */
  51. #define IS_VAR_CHAR(c) (ISALNUM (c) || (c) == '_')
  52. #endif
  53. #ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */
  54. #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{')
  55. #endif
  56. #ifndef IS_VAR_END_DELIMITER
  57. #define IS_VAR_END_DELIMITER(c) ((c) == '}')
  58. #endif
  59.  
  60.  
  61. /* Maybe we should generalize to allow some or all of the various shell
  62.    ${...} constructs.  See comments at `kpse_make_specs' in
  63.    `tex-make.c', for example.  */
  64.  
  65. string
  66. kpse_var_expand P1C(const_string, src)
  67. {
  68.   const_string s;
  69.   string ret;
  70.   fn_type expansion;
  71.   expansion = fn_init ();
  72.   
  73.   /* Copy everything but variable constructs.  */
  74.   for (s = src; *s; s++)
  75.     {
  76.       if (IS_VAR_START (*s))
  77.         {
  78.           s++;
  79.           
  80.           /* Three cases: `$VAR', `${VAR}', `$<anything-else>'.  */
  81.           
  82.           if (IS_VAR_CHAR (*s))
  83.             { /* $V: collect name constituents, then expand.  */
  84.               const_string var_end = s;
  85.               
  86.               do
  87.                 var_end++;
  88.               while (IS_VAR_CHAR (*var_end));
  89.               
  90.               var_end--; /* had to go one past */
  91.               expand (&expansion, s, var_end);
  92.               s = var_end;
  93.             }
  94.  
  95.           else if (IS_VAR_BEGIN_DELIMITER (*s))
  96.             { /* ${: scan ahead for matching delimiter, then expand.  */
  97.               const_string var_end = ++s;
  98.               
  99.               while (*var_end && !IS_VAR_END_DELIMITER (*var_end))
  100.                 var_end++;
  101.               
  102.               if (! *var_end)
  103.                 {
  104.                   WARNING1 ("%s: No matching right brace for ${", src);
  105.                   s = var_end - 1; /* will incr to null at top of loop */
  106.                 }
  107.               else
  108.                 {
  109.                   expand (&expansion, s, var_end - 1);
  110.                   s = var_end; /* will incr past } at top of loop*/
  111.                 }
  112.             }
  113.  
  114.           else
  115.             { /* $<something-else>: error.  */
  116.               WARNING2 ("%s: Unrecognized variable construct `$%c'", src, *s);
  117.               /* Just ignore those chars and keep going.  */
  118.             }
  119.         }
  120.       else
  121.         fn_1grow (&expansion, *s);
  122.     }
  123.   fn_1grow (&expansion, 0);
  124.           
  125.   ret = FN_STRING (expansion);
  126.   return ret;
  127. }
  128.  
  129. #ifdef TEST
  130.  
  131. static void
  132. test_var (string test, string right_answer)
  133. {
  134.   string result = kpse_var_expand (test);
  135.   
  136.   printf ("expansion of `%s'\t=> %s", test, result);
  137.   if (!STREQ (result, right_answer))
  138.     printf (" [should be `%s']", right_answer);
  139.   putchar ('\n');
  140. }
  141.  
  142.  
  143. int
  144. main ()
  145. {
  146.    test_var ("a", "a");
  147.    test_var ("$foo", "");
  148.    test_var ("a$foo", "a");
  149.    test_var ("$foo a", " a");
  150.    test_var ("a$foo b", "a b");
  151.  
  152.    xputenv ("FOO", "foo value");
  153.    test_var ("a$FOO", "afoo value");
  154.    
  155.    xputenv ("Dollar", "$");
  156.    test_var ("$Dollar a", "$ a");
  157.    
  158.    test_var ("a${FOO}b", "afoo valueb");
  159.    test_var ("a${}b", "ab");
  160.    
  161.    test_var ("$$", ""); /* and error */
  162.    test_var ("a${oops", "a"); /* and error */
  163.    
  164.    return 0;
  165. }
  166.  
  167. #endif /* TEST */
  168.  
  169.  
  170. /*
  171. Local variables:
  172. standalone-compile-command: "gcc -posix -g -I. -I.. -DTEST variable.c kpathsea.a"
  173. End:
  174. */
  175.