/* * $Id$ * * Code (c)2006 Bruno Cornec * * Main file of mr_mem : a very small and simple * library for memory management * * Provided under the GPLv2 */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include "mr_err.h" #include "mr_msg.h" /* * Function that frees memory if necessary * A pointer to the memory pointed is passed to it. * *allocated variable points then to the original content * pointed to by the caller * In case of NULL pointer it just logs it */ void mr_free_int(void **allocated, int line, const char *file) { /* free man pages says that if allocated is NULL * nothing happens */ if (*allocated != NULL) { free(*allocated); *allocated = NULL; } else { mr_msg_int(8,line,file,"Attempt to free NULL pointer"); } } /* encapsulation function for malloc */ void *mr_malloc_int(size_t size, int line, const char *file) { void *ret; ret = malloc(size); if (ret == NULL) { mr_msg_int(1,line,file,"Unable to alloc memory in mr_malloc\nExiting..."); mr_exit(-1,"Unable to alloc memory in mr_malloc"); } return(ret); } /* encapsulation function for getline */ void mr_getline_int(char **lineptr, size_t *n, FILE *fd, int line, const char *file) { ssize_t ret; ret = getline(lineptr,n,fd); if ((ret == -1) && (! feof(fd))) { mr_msg_int(1,line,file,"Unable to alloc memory in mr_getline\nExiting..."); mr_exit(-1,"Unable to alloc memory in mr_getline"); } } /* encapsulation function for asprintf */ void mr_asprintf_int(char **strp, int line, const char *file, const char *fmt, ...) { int res = 0; va_list args; va_start(args,fmt); res = vasprintf(strp, fmt, args); if (res == -1) { mr_msg_int(1,line,file,"Unable to alloc memory in mr_asprintf\nExiting..."); mr_exit(-1,"Unable to alloc memory in mr_asprintf"); } va_end(args); } /* * Function that properly allocates a string from another one * freeing it before in any case */ void mr_allocstr_int(char *alloc, const char *orig, int line, const char *file) { if (alloc != NULL) { mr_free_int((void **)&alloc, line, file); } mr_asprintf_int(&alloc, line, file, orig); } /* * Function that properly put a variable in the environment */ void mr_setenv_int(const char *name, const char *value, int line, char *file) { if (name == NULL) { mr_msg_int(1,line,file,"Unable to setenv a NULL variable\nExiting..."); mr_exit(-1, "Unable to setenv a NULL variable"); } if (value == NULL) { mr_msg_int(1,line,file,"Unable to affect NULL to %s\nExiting...", name); mr_exit(-1, "Unable to affect a NULL variable"); } if (setenv(name, value, 1) != 0) { mr_msg_int(1,line,file,"Unable to put %s in environment", name); mr_exit(-1,"Unable to put in environment"); } } /* * Equivalent function of strcat but safe * from memory allocation point of view * and richer from an interface point of view */ void mr_strcat_int(char **in, int line, const char *file, const char *fmt, ...) { char *p = NULL; char *fmt2 = NULL; va_list args; int res = 0; if (fmt == NULL) { return; } if (in == NULL) { mr_msg_int(1,line,file,"Unable to add to NULL pointer\nExiting..."); mr_exit(-1, "Unable to add to a NULL pointer"); } va_start(args,fmt); if (*in == NULL) { res = vasprintf(in, fmt, args); if (res == -1) { mr_msg_int(1,line,file,"Unable to alloc memory in mr_strcat\nExiting..."); mr_exit(-1,"Unable to alloc memory in mr_strcat"); } } else { mr_asprintf_int(&fmt2, line, file, "%s%s", *in, fmt); mr_free_int((void **)in,line,file); res = vasprintf(in, fmt2, args); if (res == -1) { mr_msg_int(1,line,file,"Unable to alloc memory in mr_strcat\nExiting..."); mr_exit(-1,"Unable to alloc memory in mr_strcat"); } mr_free_int((void **)&fmt2,line,file); } va_end(args); }