#define CHAZ_USE_SHORT_NAMES
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "Charmonizer/Core/Util.h"
/* global verbosity setting */
int chaz_Util_verbosity = 1;
void
chaz_Util_write_file(const char *filename, const char *content,
size_t content_len)
{
FILE *fh = fopen(filename, "w+");
if (fh == NULL)
die("Couldn't open '%s': %s", filename, strerror(errno));
fwrite(content, sizeof(char), content_len, fh);
if (fclose(fh))
die("Error when closing '%s': %s", filename, strerror(errno));
}
char*
chaz_Util_slurp_file(char *file_path, size_t *len_ptr)
{
FILE *const file = fopen(file_path, "r");
char *contents;
size_t len;
long check_val;
/* sanity check */
if (file == NULL)
die("Error opening file '%s': %s", file_path, strerror(errno));
/* find length; return NULL if the file has a zero-length */
len = flength(file);
if (len == 0) {
*len_ptr = 0;
return NULL;
}
/* allocate memory and read the file */
contents = (char*)malloc(len * sizeof(char) + 1);
if (contents == NULL)
die("Out of memory at %d, %s", __FILE__, __LINE__);
contents[len] = '\0';
check_val = fread(contents, sizeof(char), len, file);
/* weak error check, because CRLF might result in fewer chars read */
if (check_val <= 0)
die("Tried to read %d characters of '%s', got %d", (int)len,
file_path, check_val);
/* set length pointer for benefit of caller */
*len_ptr = check_val;
/* clean up */
if (fclose(file))
die("Error closing file '%s': %s", file_path, strerror(errno));
return contents;
}
long
chaz_Util_flength(FILE *f)
{
const long bookmark = ftell(f);
long check_val;
long len;
/* seek to end of file and check length */
check_val = fseek(f, 0, SEEK_END);
if (check_val == -1)
die("fseek error : %s\n", strerror(errno));
len = ftell(f);
if (len == -1)
die("ftell error : %s\n", strerror(errno));
/* return to where we were */
check_val = fseek(f, bookmark, SEEK_SET);
if (check_val == -1)
die("fseek error : %s\n", strerror(errno));
return len;
}
void
chaz_Util_die(char* format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
exit(1);
}
void
chaz_Util_warn(char* format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
}
int
chaz_Util_remove_and_verify(char *file_path)
{
/* try to remove the file */
remove(file_path);
/* return what *might* be success or failure */
return can_open_file(file_path) ? 0 : 1;
}
int
chaz_Util_can_open_file(char *file_path)
{
FILE *garbage_fh;
/* use fopen as a portable test for the existence of a file */
garbage_fh = fopen(file_path, "r");
if (garbage_fh == NULL) {
return 0;
}
else {
fclose(garbage_fh);
return 1;
}
}
size_t
chaz_Util_grow_buf(char **buf, size_t old_len, size_t new_len)
{
/* grow buffer only if necessary */
if (new_len > 0 && new_len >= old_len) {
*buf = realloc(*buf, new_len + 1);
if (*buf == NULL)
die("buffer allocation failed");
*((*buf) + new_len) = '\0';
}
/* return whatever the buffer size is now */
return new_len > old_len ? new_len : old_len;
}
size_t
chaz_Util_append_strings(char **buf, size_t buf_len, ...)
{
va_list args;
size_t retval;
/* delegate to vappend_strings */
va_start(args, buf_len);
retval = vappend_strings(buf, buf_len, args);
va_end(args);
return retval;
}
size_t
chaz_Util_vappend_strings(char **buf, size_t buf_len, va_list args)
{
char *str;
size_t new_len = buf_len == 0 ? 0 : strlen(*buf);
/* start with a null-terminated empty string if necessary */
if (buf_len == 0) {
buf_len = grow_buf(buf, buf_len, 1);
(*buf)[0] = '\0';
}
/* concat, reallocating along the way as needed */
while ( (str = va_arg(args, char*)) != NULL ) {
new_len += strlen(str);
if (new_len >= buf_len) {
/* inefficient, but portable */
*buf = realloc(*buf, new_len + 1);
buf_len = new_len + 1;
}
strcat(*buf, str);
}
return new_len;
}
size_t
chaz_Util_join_strings(char **buf, size_t buf_len, ...)
{
va_list args;
size_t retval;
/* delegate to vjoin_strings */
va_start(args, buf_len);
retval = vjoin_strings(buf, buf_len, args);
va_end(args);
return retval;
}
size_t
chaz_Util_vjoin_strings(char **buf, size_t buf_len, va_list args)
{
/* start with en empty string for vappend to append to */
if (*buf != NULL)
(*buf)[0] = '\0';
return vappend_strings(buf, buf_len, args);
}
/* Copyright 2006-2007 Marvin Humphrey
*
* This program is free software; you can redistribute it and/or modify
* under the same terms as Perl itself.
*/