1 /* 2 * This file was written by Bill Cox, originally in 1991, and maintained since. It is hereby 3 * placed into the public domain. 4 */ 5 6 /*================================================================================================== 7 Module : Virtual Operating System 8 Purpose: Hide system specific operations from other modules. This should help in portability. 9 ==================================================================================================*/ 10 11 #ifndef DD_UTIL_H 12 #define DD_UTIL_H 13 14 #if __cplusplus 15 extern "C" { 16 #endif 17 18 #include <stdarg.h> /* For utVsprintf declaration */ 19 #include <setjmp.h> /* For utSetjmp */ 20 #include <stdio.h> /* Everyone uses it */ 21 #include <string.h> /* Has memset, used in generated macros */ 22 23 /*-------------------------------------------------------------------------------------------------- 24 Datadraw defined Data types 25 --------------------------------------------------------------------------------------------------*/ 26 27 #ifndef UTTYPES_H 28 #include "uttypes.h" 29 #endif 30 31 /*-------------------------------------------------------------------------------------------------- 32 Basic symbol table support. Note that user applications don't need to worry about which 33 header gets included here, since they should only be reading from symbols. 34 --------------------------------------------------------------------------------------------------*/ 35 #if defined(UT_USE_UTDATABASEUP_H) 36 #include "utdatabaseup.h" 37 #elif defined(UT_USE_UTDATABASEP_H) 38 #include "utdatabasep.h" 39 #elif defined(UT_USE_UTDATABASEU_H) 40 #include "utdatabasep.h" 41 #else 42 #include "utdatabase.h" 43 #endif 44 45 utSym utSymCreate(char *name); 46 utSym utSymCreateFormatted(char *format, ...); 47 utSym utUniqueSymCreate(char *name, char *suffix); 48 utSym utSymGetLowerSym(utSym sym); 49 50 /*-------------------------------------------------------------------------------------------------- 51 Basic memory management support. 52 --------------------------------------------------------------------------------------------------*/ 53 #ifndef UTMEM_H 54 #include "utmem.h" 55 #endif 56 57 #ifdef DMALLOC 58 #include "dmalloc.h" 59 #endif 60 61 /*-------------------------------------------------------------------------------------------------- 62 The max size of a string which the utFprintf, utExit, etc functions can print. 63 --------------------------------------------------------------------------------------------------*/ 64 #define UTSTRLEN 4096 65 66 extern uint32 utDebugVal; 67 extern uint32 utVerboseVal; 68 69 /*-------------------------------------------------------------------------------------------------- 70 Initialization, cleaning up. 71 --------------------------------------------------------------------------------------------------*/ 72 void utStop(bool reportTimeAndMemory); 73 void utStart(void); 74 extern bool _utInitialized; 75 #define utInitialized() _utInitialized 76 77 78 /*-------------------------------------------------------------------------------------------------- 79 Functions you may want to call after initialization. 80 --------------------------------------------------------------------------------------------------*/ 81 void utSetConfigDirectory(char *dirName); 82 void utSetExeFullPath(char *fullName); 83 void utSetVersion(char *version); 84 char *utGetVersion(void); 85 char *utGetExeDirectory(void); 86 char *utGetConfigDirectory(void); 87 char *utGetExeFullPath(void); 88 89 /*-------------------------------------------------------------------------------------------------- 90 Error Callback function to be provided by the user. 91 --------------------------------------------------------------------------------------------------*/ 92 typedef void(*utErrorProc)(char *message); 93 typedef bool(*utMessageYesNoProc)(char *message); 94 typedef void(*utExitProc)(void); 95 96 /*-------------------------------------------------------------------------------------------------- 97 Basic interface to file system. 98 --------------------------------------------------------------------------------------------------*/ 99 char *utGetcwd(void); 100 bool utChdir(char *dirName); 101 bool utFileExists(char *fileName); 102 bool utDirectoryExists(char *dirName); 103 bool utAccess(char *name, char *mode); 104 uint64 utFindFileSize(char *fileName); 105 char *utExecPath(char *name); 106 char *utFullPath(char *relativePath); 107 char *utFindInPath(char *name, char *path); 108 void utTruncateFile(char *fileName, uint64 length); 109 bool utDeleteFile(char *fileName); 110 111 /*-------------------------------------------------------------------------------------------------- 112 Portable interface to launch an application. 113 --------------------------------------------------------------------------------------------------*/ 114 bool utLaunchApp(char* cmdLine, char *wkgDir); 115 116 /*-------------------------------------------------------------------------------------------------- 117 Memory allocation. 118 There are things called malloc, calloc and free, but they deal in the 119 local heap, thus are to be avoided. 120 --------------------------------------------------------------------------------------------------*/ 121 extern uint64 utUsedMem; 122 #define utMalloc(sStruct, size) utMallocTrace(sStruct, size, __FILE__, __LINE__) 123 #define utCalloc(sStruct, size) utCallocTrace(sStruct, size, \ 124 __FILE__, __LINE__) 125 #define utRealloc(mem, numBlocks, size) \ 126 utReallocTrace((void *)mem, numBlocks, size, __FILE__, __LINE__) 127 #define utResizeArray(array, num) \ 128 ((array) = utRealloc((void *)(array), (num), sizeof(*(array)))) 129 #define utNew(type) (type *)utCalloc(1, sizeof(type)) 130 #define utNewA(type, num) (type *)utCalloc((num), sizeof(type)) 131 #define utFree(p) utFreeTrace(p, __FILE__, __LINE__) 132 #define utAllocString(string) strcpy(utNewA(char, strlen(string) + 1), string) 133 134 void * utReallocTrace(void *memPtr, size_t numBlocks, size_t size, char *fileName, 135 uint32 line); 136 void *utMallocTrace(size_t sStruct, size_t size, char *fileName, uint32 line); 137 void *utCallocTrace(size_t sStruct, size_t size, char *fileName, uint32 line); 138 void utFreeTrace(void *memPtr, char *fileName, uint32 line); 139 140 /* maxmimum memory usage */ 141 extern uint32 utmByte; 142 143 /*-------------------------------------------------------------------------------------------------- 144 Random number support. 145 --------------------------------------------------------------------------------------------------*/ 146 void utInitSeed(uint32 seed); 147 uint32 utRand(void); 148 #define utRandN(n) (utRand() % (n)) 149 #define utRandBool() ((bool) (utRand() & 1)) 150 uint8 *utRealRandom(uint32 length); 151 152 /*-------------------------------------------------------------------------------------------------- 153 String and temporary buffer manipulation. 154 --------------------------------------------------------------------------------------------------*/ 155 /* These use a queue of buffers */ 156 void *utMakeBuffer_(uint32 length); 157 #define utNewBufA(type, num) (type *)utMakeBuffer_((num)*sizeof(type)) 158 #define utNewBuf(type) (type *)utMakeBuffer_(sizeof(type)) 159 #define utMakeString(length) (char *)utMakeBuffer_(length) 160 char *utCopyString(char *string); 161 char *utCatStrings(char *string1, char *string2); 162 char *utStringToUpperCase(char *string); 163 char *utStringToLowerCase(char *string); 164 char *utSprintf(char *format, ...); 165 char *utReplaceSuffix(char *originalName, char *newSuffix); 166 char *utSuffix(char *name); 167 char *utBaseName(char *name); 168 char *utDirName(char *name); 169 char *utExpandEnvVariables(char *string); 170 char *utVsprintf(char *format, va_list ap); 171 void utSetEnvironmentVariable(char *name, char *value); 172 char *utGetEnvironmentVariable(char *name); 173 char *utFindHexString(uint8 *values, uint32 size); 174 bool utReadHex(uint8 *dest, char *value, uint32 size); 175 char *utMemoryUnits(uint64 memory); 176 bool utParseInteger(int64 *dest, char *string); 177 char *utConvertDirSepChars(char *path); 178 179 /*-------------------------------------------------------------------------------------------------- 180 Message loging, error reporting. 181 --------------------------------------------------------------------------------------------------*/ 182 typedef enum { 183 UT_MESSAGE_INFO, 184 UT_MESSAGE_WARNING, 185 UT_MESSAGE_ERROR, 186 UT_MESSAGE_EXIT, 187 UT_MESSAGE_DETAILS, 188 UT_MESSAGE_INTERNAL, 189 UT_MESSAGE_REPORT, 190 } utMessageType; 191 void utEnableMessageHeaders(bool value); 192 void utLogMessageType(utMessageType msgType, char *format, ...); 193 void utLogMessage(char *format, ...); 194 void utLogString(char *format, ...); 195 void utLogDebug(char *format, ...); 196 char *utGetCompileTime(void); 197 char *utCompileTime(void); 198 char *utGetDateAndTime(void); 199 bool utDebug(char *format,... ); 200 void utLogError(char *format, ...); 201 void utLogTimeStamp(char *message, ...); 202 uint32 utStartTimer(char *message, ...); 203 void utStopTimer(uint32 timerID, char *message, ...); 204 void utStatus(char *format, ...); 205 void utExit_ (char *format, ...); 206 typedef void(*utExitProcType)(char *format, ...); 207 utExitProcType utSetFileAndLineAndReturnExitFunc(char *fileName, uint32 lineNum); 208 #define utExit utSetFileAndLineAndReturnExitFunc(__FILE__, __LINE__) 209 void utWarning(char *format, ...); 210 void utNote(char *format, ...); 211 void utError(char *format, ...); 212 void utCriticalError(char *format, ...); 213 void utReport(char *format, ...); 214 /* Log a message to the log file and exit if false is passed. */ 215 void utAssert_(char *fileName, uint32 line, char *text); 216 #define utAssert(assertion) ((void)(utLikely(assertion) || (utAssert_(__FILE__, __LINE__, #assertion), 0))) 217 void utSetErrorCallback(utErrorProc errorProc); 218 void utSetWarningCallback(utErrorProc warningProc); 219 void utSetStatusCallback(utErrorProc statusProc); 220 void utSetLogMessageCallback(utErrorProc logMessageProc); 221 utErrorProc utGetErrorCallback(void); 222 utErrorProc utGetWarningCallback(void); 223 utErrorProc utGetStatusCallback(void); 224 utErrorProc utGetLogMessageCallback(void); 225 void utInitLogFile(char *fileName); 226 void utSetLogFile(char *fileName); 227 FILE *utGetLogFile(void); 228 char *utGetLogFileName(void); 229 void utInitReportFile(char *fileName); 230 void utSetReportFile(char *fileName); 231 FILE *utGetReportFile(void); 232 char *utGetReportFileName(void); 233 void utInitDebugFile(char *fileName); 234 void utSetDebugFile(char *fileName); 235 FILE *utGetDebugFile(void); 236 char *utGetDebugFileName(void); 237 #define utIfDebug(minVal) if(utUnlikely(utDebugVal >= minVal)) 238 #define utIfVerbose(minVal) if(utUnlikely(utVerboseVal >= minVal)) 239 240 #define UT_MAX_SETJMP_DEPTH 5 241 #if defined(_WINDOWS) && !defined(_WIN32) 242 #if !defined(CATCHBUF) 243 typedef int CATCHBUF[9]; 244 #endif 245 extern CATCHBUF utCatchBuf[UT_MAX_SETJMP_DEPTH]; 246 #else 247 extern jmp_buf utJmpBuf[UT_MAX_SETJMP_DEPTH]; 248 #endif 249 250 /*-------------------------------------------------------------------------------------------------- 251 Macros for computing simple hashed signatures. Hash signatures are uint32s. 252 --------------------------------------------------------------------------------------------------*/ 253 #define utHashValues(hash1, hash2) (((uint32)(hash1) ^ (uint32)(hash2))*1103515245 + 12345) 254 uint32 utHashData(void *data, uint32 length); 255 uint32 utHashString(char *string); 256 uint32 utHashFloat(float value); 257 uint32 utHashDouble(double value); 258 259 /*-------------------------------------------------------------------------------------------------- 260 Setjmp/longjmp stack. 261 --------------------------------------------------------------------------------------------------*/ 262 extern int16 utSetjmpDepth; 263 extern uint32 utSetjmpLine[UT_MAX_SETJMP_DEPTH]; 264 extern char *utSetjmpFile[UT_MAX_SETJMP_DEPTH]; 265 #define utUnsetjmp() (utSetjmpDepth--,\ 266 !strcmp(utSetjmpFile[utSetjmpDepth],__FILE__) ||\ 267 (utExit("Mismatched utUnsetjmp in file %s, line %u", __FILE__, __LINE__), 1)) 268 #define utSetjmp() (++utSetjmpDepth,\ 269 utSetjmpFile[utSetjmpDepth - 1] = __FILE__,\ 270 utSetjmpLine[utSetjmpDepth - 1] = __LINE__,\ 271 setjmp(utJmpBuf[utSetjmpDepth - 1])) 272 void utLongjmp(void); 273 274 /*-------------------------------------------------------------------------------------------------- 275 Functions supporting database persistence. 276 --------------------------------------------------------------------------------------------------*/ 277 278 #ifndef UTPERSIST_H 279 #include "utpersist.h" 280 #endif 281 282 /* These are used by DataDraw to manage the database, and can generally be ignored */ 283 uint8 utRegisterModule(char *prefix, bool persistent, uint32 hashValue, uint16 numClasses, uint16 numFields, 284 uint16 numEnums, uint16 globalSize, void *globalData, void (*start)(void), void (*stop)(void)); 285 void utUnregisterModule(uint8 moduleID); 286 void utRegisterClass(char *name, uint16 numFields, void *numUsedPtr, void *numAllocatedPtr, 287 void *firstFreePtr, uint16 nextFreeFieldIndex, uint8 referenceSize, 288 uint64 (*constructor)(void), void (*destructor)(uint64 objectIndex)); 289 void utRegisterBaseClass(char *baseModulePrefix, uint16 baseClassIndex); 290 void utRegisterField(char *name, void *arrayPtr, uint32 size, utFieldType type, 291 char *destName); 292 void utSetFieldHidden(void); 293 void utRegisterArray(uint32 *numUsedPtr, uint32 *numAllocatedPtr, 294 void *(*getValues)(uint64 objectNumber, uint32 *numValues), 295 void *(*allocValues)(uint64 objectNumber, uint32 numValues), 296 void (*compactArray)(void)); 297 void utRegisterFixedArray(uint32 length, void *(*getValues)(uint64 objectNumber, uint32 *numValues)); 298 void utRegisterEnum(char *name, uint16 numEntries); 299 void utRegisterEntry(char *name, uint32 value); 300 void utRegisterUnion(char *switchFieldName, uint16 numCases); 301 void utRegisterUnionCase(uint32 value, utFieldType type, uint32 size); 302 void utRecordField(uint8 moduleID, uint16 fieldIndex, uint64 objectNumber, bool undo); 303 void utRecordArray(uint8 moduleID, uint16 fieldIndex, uint32 dataIndex, uint32 length, bool undo); 304 void utRecordGlobal(uint8 moduleID, uint8 numBytes, void *location, bool undo); 305 void utRecordResize(uint8 moduleID, uint16 fieldIndex, uint64 length, bool undo); 306 void utAllocPersistenceObjects(void); 307 void utFreePersistenceObjects(void); 308 void utInitSymTable(void); 309 void utDatabaseManagerStart(void); 310 void utDatabaseManagerStop(void); 311 void utDumpRecentChanges(void); 312 void utDumpCommand(uint8 *command); 313 314 /* These are the useful functions */ 315 bool utStartPersistence(char *directory, bool useTextDatabaseFormat, bool keepBackup); 316 void utStopPersistence(void); 317 uint32 utUndo(uint32 numChanges); 318 uint32 utRedo(uint32 numChanges); 319 void utStartUndoRedo(void); 320 void utStopUndoRedo(void); 321 void utTransactionComplete(bool flushToDisk); 322 void utLoadBinaryDatabase(FILE *file); 323 void utSaveBinaryDatabase(FILE *file); 324 void utLoadTextDatabase(FILE *file); 325 void utSaveTextDatabase(FILE *file); 326 void utManager(void); 327 void utDatabaseShowObject(char *modulePrefix, char *className, uint64 objectNumber); 328 void utResetDatabase(void); 329 void utCompactDatabase(void); 330 331 /* Some dynamic array stuff */ 332 #ifdef DD_DEBUG 333 /* this double-evaluates and might cause side-effects */ 334 #define utDynarrayGetiValueType(Dynarray, type, x) (utAssert((uint32)(x) < utDynarrayGetSize( \ 335 Dynarray)), ((type *)(utDynarrayGetValues(Dynarray)))[x]) 336 #define utDynarraySetiValueType(Dynarray, type, x, Value) (utAssert((uint32)(x) < \ 337 utDynarrayGetSize(Dynarray)), ((type *)(utDynarrayGetValues(Dynarray)))[x] = (Value)) 338 #else 339 #define utDynarrayGetiValueType(Dynarray, type, x) (((type *)(utDynarrayGetValues(Dynarray)))[x]) 340 #define utDynarraySetiValueType(Dynarray, type, x, Value) \ 341 (((type *)utDynarrayGetValues(Dynarray))[x] = (Value)) 342 #endif 343 utDynarray utDynarrayCreate_(uint16 valueSize); 344 #define utDynarrayCreate(type) utDynarrayCreate_(sizeof(type)) 345 void utDynarrayResize(utDynarray dynarray, uint32 newSize); 346 #define utDynarrayAppendValue(dynarray, type, value) \ 347 (utDynarrayGetUsedValue(dynarray) == utDynarrayGetSize(dynarray) && \ 348 (utDynarrayResize((dynarray), 1 + utDynarrayGetSize(dynarray) + \ 349 (utDynarrayGetSize(dynarray) >> 1)), true),\ 350 utDynarraySetiValueType(dynarray, type, utDynarrayGetUsedValue(dynarray), (value)),\ 351 utDynarraySetUsedValue(dynarray, utDynarrayGetUsedValue(dynarray) + 1)) 352 #define utForeachDynarrayValue(dynarray, type, value) \ 353 {\ 354 uint32 _xValue;\ 355 for(_xValue = 0; _xValue < utDynarrayGetUsedValue(dynarray); _xValue++) {\ 356 (value) = utDynarrayGetiValueType((dynarray), type, _xValue); 357 #define utEndDynarrayValue }} 358 #define utDynarrayCopy(destDynarray, sourceDynarray, type) { \ 359 uint32 _xValue; \ 360 if (utDynarrayGetSize(destDynarray) < utDynarrayGetSize(sourceDynarray)) { \ 361 utDynarrayResize(destDynarray, utDynarrayGetSize(sourceDynarray)); \ 362 } \ 363 utDynarraySetUsedValue(destDynarray, utDynarrayGetUsedValue(sourceDynarray)); \ 364 for(_xValue = 0; _xValue < utDynarrayGetUsedValue(sourceDynarray); _xValue++) { \ 365 utDynarraySetiValueType((destDynarray), type, _xValue, \ 366 utDynarrayGetiValueType((sourceDynarray), type, _xValue)); \ 367 } \ 368 } 369 370 #if __cplusplus 371 } 372 #endif 373 374 #endif 375 376