void buffer_strcat(buffer_type * buffer , const char * string) { if (buffer->content_size == 0) buffer_fwrite_char_ptr( buffer , string ); else { if (buffer->data[ buffer->content_size - 1] == '\0') { buffer_fseek( buffer , -1 , SEEK_END); buffer_fwrite_char_ptr( buffer , string ); } } }
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; } } }
static void subst_list_eval_funcs____(const subst_list_type * subst_list , const parser_type * parser , buffer_type * buffer) { { int index; for (index = 0; index < vector_get_size( subst_list->func_data); index++) { const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index ); const char * func_name = subst_func->name; bool match; buffer_rewind( buffer ); do { size_t match_pos; match = buffer_strstr( buffer , func_name ); match_pos = buffer_get_offset( buffer ); if (match) { bool update = false; char * arg_start = buffer_get_data( buffer ); arg_start += buffer_get_offset( buffer ) + strlen( func_name ); if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */ char * arg_end = strchr( arg_start , ')'); if (arg_end != NULL) { /* OK - we found an enclosing () pair. */ char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1); stringlist_type * arg_list = parser_tokenize_buffer( parser , arg_content , true); char * func_eval = subst_list_func_eval( subst_func , arg_list ); int old_len = strlen(func_name) + strlen( arg_content) + 2; if (func_eval != NULL) { buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len); buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval ); free( func_eval ); update = true; } free( arg_content ); stringlist_free( arg_list ); } } if (!update) buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET); } } while (match); } } if (subst_list->parent != NULL) subst_list_eval_funcs____( subst_list->parent , parser , buffer ); }
void subst_list_filter_file(const subst_list_type * subst_list , const char * src_file , const char * target_file) { char * backup_file = NULL; buffer_type * buffer = buffer_fread_alloc( src_file ); buffer_fseek( buffer , 0 , SEEK_END ); /* Ensure that the buffer is a \0 terminated string. */ buffer_fwrite_char( buffer , '\0'); /*****************************************************************/ /* Backup file ?? */ if (util_same_file(src_file , target_file)) { char * backup_prefix = util_alloc_sprintf("%s-%s" , src_file , __func__); backup_file = util_alloc_tmp_file("/tmp" , backup_prefix , false); free(backup_prefix); } /* Writing backup file */ if (backup_file != NULL) { FILE * stream = util_fopen(backup_file , "w"); buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */ fclose(stream); } /* Doing the actual update */ subst_list_update_buffer(subst_list , buffer); /* Writing updated file */ { FILE * stream = util_mkdir_fopen(target_file , "w"); buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */ fclose(stream); } /* OK - all went hunka dory - unlink the backup file and leave the building. */ if (backup_file != NULL) { remove( backup_file ); free( backup_file ); } free(buffer); }
void buffer_replace_data(buffer_type * buffer , size_t offset , size_t old_size , const void * new_data , size_t new_size) { ssize_t shift = new_size - old_size; buffer_memshift( buffer , offset , shift ); buffer_fseek( buffer , offset , SEEK_SET ); buffer_fwrite( buffer , new_data , 1 , new_size ); }
void buffer_fskip_bool(buffer_type * buffer) { buffer_fseek( buffer , sizeof( bool ) , SEEK_CUR ); }
void buffer_fskip_long(buffer_type * buffer) { buffer_fseek( buffer , sizeof( long ) , SEEK_CUR ); }
void buffer_fskip_int(buffer_type * buffer) { buffer_fseek( buffer , sizeof( int ) , SEEK_CUR ); }
void buffer_fskip_time_t(buffer_type * buffer) { buffer_fseek( buffer , sizeof(time_t) , SEEK_CUR ); }
void buffer_fskip(buffer_type * buffer, ssize_t offset) { buffer_fseek( buffer , offset , SEEK_CUR ); }
void buffer_rewind(buffer_type * buffer ) { buffer_fseek( buffer , 0 , SEEK_SET); }