Mercurial > hg > dmlib
view src/dmlib.c @ 2070:41df24d1dfb6
Cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 05 Dec 2018 14:41:25 +0200 |
parents | 3d40a6767a4e |
children | 69a5af2eb1ea |
line wrap: on
line source
#include "dmlib.h" #include <errno.h> int dmVerbosity = 0; char *dmProgName = NULL, *dmProgDesc = NULL, *dmProgVersion = NULL, *dmProgAuthor = NULL, *dmProgLicense = NULL; void dmInitProg(char *name, char *desc, char *version, char *author, char *license) { dmProgName = name; dmProgDesc = desc; dmProgVersion = version; dmProgAuthor = author != NULL ? author : DM_PROG_AUTHOR; dmProgLicense = license != NULL ? license : DM_PROG_LICENSE; } void dmPrintBanner(FILE *outFile, const char *name, const char *usage) { fprintf(outFile, "%s", dmProgName); if (dmProgVersion != NULL) fprintf(outFile, " v%s", dmProgVersion); if (dmProgDesc != NULL) fprintf(outFile, " (%s)", dmProgDesc); fprintf(outFile, "\n"); if (dmProgAuthor != NULL) fprintf(outFile, "%s\n", dmProgAuthor); if (dmProgLicense != NULL) fprintf(outFile, "%s\n", dmProgLicense); fprintf(outFile, "Usage: %s %s\n", name, usage); } void dmMsgVA(int level, const char *fmt, va_list ap) { if (dmVerbosity >= level) { fprintf(stderr, "%s: ", dmProgName); vfprintf(stderr, fmt, ap); } } void dmPrintVA(int level, const char *fmt, va_list ap) { if (dmVerbosity >= level) { vfprintf(stderr, fmt, ap); } } void dmMsg(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); dmMsgVA(level, fmt, ap); va_end(ap); } void dmPrint(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); dmPrintVA(level, fmt, ap); va_end(ap); } /* Memory handling routines */ void *dmMalloc(size_t len) { return malloc(len); } void *dmMalloc0(size_t len) { return calloc(1, len); } void *dmCalloc(size_t n, size_t len) { return calloc(n, len); } void *dmRealloc(void *ptr, size_t len) { return realloc(ptr, len); } void dmFree(void *ptr) { /* Check for NULL pointers for portability due to some libc * implementations not handling free(NULL) too well. */ if (ptr) free(ptr); } void dmFreeRReal(void **ptr) { if (ptr != NULL) { dmFree(*ptr); *ptr = NULL; } } #ifndef DM_HAVE_MEMSET void * dmMemset(void *ptr, const int c, size_t n) { Uint8 *p = (Uint8 *) ptr; while (n--) *p++ = c; return ptr; } #endif BOOL dmGetIntVal(const char *str, unsigned int *value, BOOL *neg) { int ch; BOOL hex = FALSE; // Is the value negative? if (*str == '-') { if (neg == NULL) return FALSE; *neg = TRUE; str++; } else if (neg != NULL) *neg = FALSE; // Is it hexadecimal? if (*str == '$') { hex = TRUE; str++; } else if (str[0] == '0' && str[1] == 'x') { hex = TRUE; str += 2; } // Parse the value *value = 0; if (hex) { while ((ch = *str++)) { if (ch >= '0' && ch <= '9') { *value <<= 4; *value |= ch - '0'; } else if (ch >= 'A' && ch <= 'F') { *value <<= 4; *value |= ch - 'A' + 10; } else if (ch >= 'a' && ch <= 'f') { *value <<= 4; *value |= ch - 'a' + 10; } else return FALSE; } } else { while ((ch = *str++)) { if (ch >= '0' && ch <= '9') { *value *= 10; *value += ch - '0'; } else return FALSE; } } return TRUE; } /* * Error handling and messages */ #define DM_SYSTEM_ERRORS 100000 int dmGetErrno() { return DM_SYSTEM_ERRORS + errno; } const char *dmErrorStr(const int error) { if (error >= DM_SYSTEM_ERRORS) return strerror(error - DM_SYSTEM_ERRORS); switch (error) { case DMERR_OK: return "No error"; case DMERR_FOPEN: return "File open error"; case DMERR_FREAD: return "Read error"; case DMERR_FWRITE: return "Write error"; case DMERR_FSEEK: return "Seek error"; case DMERR_NOT_FOUND: return "Resource not found"; case DMERR_INVALID_DATA: return "Invalid data"; case DMERR_MALLOC: return "Memory allocation failure"; case DMERR_ALREADY_INIT: return "Already initialized"; case DMERR_INIT_FAIL: return "Initialization failed"; case DMERR_INVALID_ARGS: return "Invalid arguments"; case DMERR_NULLPTR: return "NULL pointer"; case DMERR_NOT_SUPPORTED: return "Operation not supported"; case DMERR_OUT_OF_DATA: return "Out of data"; case DMERR_EXTRA_DATA: return "Extra data"; case DMERR_BOUNDS: return "Bounds check failed"; case DMERR_DATA_ERROR: return "Data decoding/encoding/parsing error"; case DMERR_VERSION: return "Unsupported file format version"; case DMERR_NOTPACK: return "File is not a PACK"; case DMERR_PACK_VERSION: return "Unsupported PACK version"; case DMERR_INVALID: return "Invalid data, corrupted file"; case DMERR_COMPRESSION: return "Error in compression"; default: return "Unknown error"; } } int dmErrorVA(const int error, const char *fmt, va_list ap) { if (dmProgName != NULL) fprintf(stderr, "%s: ", dmProgName); vfprintf(stderr, fmt, ap); return error; } int dmError(const int error, const char *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = dmErrorVA(error, fmt, ap); va_end(ap); return ret; } void dmErrorMsg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); dmErrorVA(DMERR_INTERNAL, fmt, ap); va_end(ap); } /* * Mutex debugging */ #ifdef DM_MUTEX_DEBUG static DMMutexLock * dmGetMutexThreadIDLock(DMMutex *mutex) { Uint32 id = SDL_ThreadID(); int i; for (i = 0; i < 8; i++) { DMMutexLock *lock = &(mutex->locks[i]); if (lock->used && lock->id == id) return lock; } return NULL; } static void dmPrintMutexLocks(DMMutex *mutex, const char *state, const char *file, const int line) { int i; fprintf(stderr, "----------------------\n" "%s --> %p @ %s:%d\n" "Current thread: %d\n" "Mutex : %p (created @ %s:%d)\n", state, mutex, file, line, SDL_ThreadID(), mutex, mutex->cr_file, mutex->cr_line); for (i = 0; i < 8; i++) { DMMutexLock *lock = &(mutex->locks[i]); if (lock->used) { fprintf(stderr, "Lock #%d: thread=%d, state=%d\n", i, lock->id, lock->state); } } } int dmDOMutexLock(DMMutex *mutex, const char *file, const int line) { if (mutex != NULL) { dmPrintMutexLocks(mutex, "LOCKING", file, line); DMMutexLock *lock = dmGetMutexThreadIDLock(mutex); if (lock != NULL) { int res; if (lock->state == 0) res = SDL_mutexP(mutex->m); else res = 1; lock->state++; fprintf(stderr, "LOCKING %p @ thread=%d done [1].\n", mutex, SDL_ThreadID()); return res; } else { int i; for (i = 0; i < 8; i++) { DMMutexLock *lock = &(mutex->locks[i]); if (!lock->used) { int res; lock->used = TRUE; lock->id = SDL_ThreadID(); lock->state++; res = SDL_mutexP(mutex->m); fprintf(stderr, "LOCKING %p @ thread=%d done [2].\n", mutex, SDL_ThreadID()); return res; } } return -2; } } return -1; } int dmDOMutexUnlock(DMMutex *mutex, const char *file, const int line) { if (mutex != NULL) { dmPrintMutexLocks(mutex, "UN-LOCKING", file, line); DMMutexLock *lock = dmGetMutexThreadIDLock(mutex); if (lock != NULL) { int res; lock->state--; if (lock->state == 0) res = SDL_mutexV(mutex->m); else res = lock->state; return res; } else { return -2; } } return -1; } DMMutex * dmDOCreateMutex(const char *file, const int line) { DMMutex *mutex = dmMalloc0(sizeof(DMMutex)); if (mutex == NULL) return NULL; mutex->cr_file = dm_strdup(file); mutex->cr_line = line; mutex->m = SDL_CreateMutex(); return mutex; } void dmDestroyMutex(DMMutex *mutex) { if (mutex != NULL) { SDL_DestroyMutex(mutex->m); dmFree(mutex); } } #endif