Mercurial > hg > dmlib
view src/dmlib.c @ 2576:812b16ee49db
I had been living under apparent false impression that "realfft.c"
on which the FFT implementation in DMLIB was basically copied from
was released in public domain at some point, but it could very well
be that it never was. Correct license is (or seems to be) GNU GPL.
Thus I removing the code from DMLIB, and profusely apologize to the
author, Philip Van Baren.
It was never my intention to distribute code based on his original
work under a more liberal license than originally intended.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 11 Mar 2022 16:32:50 +0200 |
parents | 69a5af2eb1ea |
children | 9807ae37ad69 |
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; } } 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