char * util_alloc_envvar( const char * value ) {
  if (value == NULL)
    return NULL;
  else {
    buffer_type * buffer = buffer_alloc( 1024 );               /* Start by filling up a buffer instance with 
                                                                  the current content of @value. */
    buffer_fwrite_char_ptr( buffer , value );
    buffer_fwrite_char( buffer , '\0' );
    buffer_rewind( buffer );
    
    
    while (true) {
      if (buffer_strchr( buffer , '$')) {
        const char * data = buffer_get_data( buffer );
        int offset        = buffer_get_offset( buffer ) + 1;    /* Points at the first character following the '$' */
        int var_length = 0;
        
        /* Find the length of the variable name */
        while (true) {
          char c;
          c = data[offset + var_length];
          if (!(isalnum( c ) || c == '_'))      /* Any character which is NOT in the set [a-Z,0-9_] marks the end of the variable. */
            break;             
          
          if (c == '\0')                        /* The end of the string. */
            break;
          
          var_length += 1;
        }

        {
          char * var_name        = util_alloc_substring_copy( data , offset - 1 , var_length + 1);  /* Include the leading $ */
          const char * var_value = getenv( &var_name[1] );
          
          if (var_value != NULL)
            buffer_search_replace( buffer , var_name , var_value);                                      /* The actual string replacement. */
          else  
            buffer_fseek( buffer , var_length , SEEK_CUR );                                      /* The variable is not defined, and we leave the $name. */
          
          free( var_name );
        }
      } else break;  /* No more $ to replace */
    }
    
    
    buffer_shrink_to_fit( buffer );
    {
      char * expanded_value = buffer_get_data( buffer );
      buffer_free_container( buffer );
      return expanded_value;
    }
  }
}
Example #2
0
/**
   Updates the buffer inplace with all the string substitutions in the
   subst_list. This is the lowest level function, which does *NOT*
   consider the parent pointer.
*/
static void subst_list_replace_strings__(const subst_list_type * subst_list , buffer_type * buffer) {
  int index;
  for (index = 0; index < vector_get_size( subst_list->string_data ); index++) {
    const subst_list_string_type * node = vector_iget_const( subst_list->string_data , index );
    if (node->value != NULL) {
      bool    match;
      buffer_rewind( buffer );
      do {
        match = buffer_search_replace( buffer , node->key , node->value);
      } while (match);
    }
  }
}