📄 util.c
字号:
/* * This file was written by Bill Cox, originally in 1991, and maintained since. It is hereby * placed into the public domain. */#include <stdlib.h>#include <stdio.h>#include <time.h>#include <ctype.h>#include <string.h>#include <errno.h>#include "ddutil.h"#include "utmem.h"bool _utInitialized = false;utSymtab utTheSymtab;uint32 utSetjmpLine[UT_MAX_SETJMP_DEPTH];char *utSetjmpFile[UT_MAX_SETJMP_DEPTH];char *utConfigDirectory = NULL;char *utExeDirectory = NULL;char *utExeFullPath = NULL;char *utLogFileName = NULL;uint32 utDebugVal = 0;uint32 utVerboseVal = 0;#define UT_MAX_BUFFERS 42static char *utBuffers[UT_MAX_BUFFERS];static uint16 utNextBuffer;static uint32 utBufferSizes[UT_MAX_BUFFERS];static time_t utTimers[UT_MAX_BUFFERS];static uint16 utTimerDepth = 0;static utErrorProc utUserErrProc = NULL, utUserWarningProc = NULL, utUserStatusProc = NULL;static utExitProc utUserExitProc = NULL;static char *utVersion = NULL;uint32 utHashValue;int16 utSetjmpDepth = 0;static uint32 utSymNextIndex;/*-------------------------------------------------------------------------------------------------- Like ansi sprintf.--------------------------------------------------------------------------------------------------*/char *utSprintf( char *format, ...){ va_list ap; char *returnBuffer; va_start(ap, format); returnBuffer = utVsprintf(format, ap); va_end(ap); return returnBuffer;}/*-------------------------------------------------------------------------------------------------- Log a message to the debug file.--------------------------------------------------------------------------------------------------*/void utLogDebug( char *format, ...){ va_list ap; char *buff; FILE *logFile; if(utLogFileName == NULL) { return; } logFile = fopen(utLogFileName, "a"); if(logFile == NULL) { return; } va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); fputs("Debug: ", logFile); fputs(buff, logFile); fputs("\n", logFile); if(fclose(logFile) != 0) { utExit("utLogDebug: unable to close %s", utLogFileName); }}/*-------------------------------------------------------------------------------------------------- Log a message to the debug file.--------------------------------------------------------------------------------------------------*/void utLogString( char *format, ...){ va_list ap; char *buff; FILE *logFile; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); if(utUserStatusProc != NULL) { utStatus("%s", buff); } else { printf("%s", buff); } if(utLogFileName == NULL) { return; } logFile = fopen(utLogFileName, "a"); if(logFile == NULL) { return; } fputs(buff, logFile); if(fclose(logFile) != 0) { buff = utSprintf("utLogString: unable to close %s", utLogFileName); (utUserErrProc)(buff); return; }}/*-------------------------------------------------------------------------------------------------- Log a message to the debug file.--------------------------------------------------------------------------------------------------*/void utLogMessage( char *format, ...){ va_list ap; char *buff; FILE *logFile; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); if(utUserStatusProc != NULL) { utStatus("%s", buff); } else { printf("%s\n", buff); } if(utLogFileName == NULL) { return; } logFile = fopen(utLogFileName, "a"); if(logFile == NULL) { return; } fputs(buff, logFile); fputc('\n', logFile); if(fclose(logFile) != 0) { buff = utSprintf("utLogMessage: unable to close %s", utLogFileName); (utUserErrProc)(buff); return; }}/*-------------------------------------------------------------------------------------------------- Print a message, and start recording the time since this message.--------------------------------------------------------------------------------------------------*/uint32 utStartTimer( char *format, ...){ va_list ap; char *buff; uint timerID = utTimerDepth++; utTimers[timerID] = time(NULL); if(format != NULL) { va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); utLogMessage("%s", buff); } return timerID;}/*-------------------------------------------------------------------------------------------------- Print a message about the length of the current timer.--------------------------------------------------------------------------------------------------*/void utStopTimer( uint32 timerID, char *format, ...){ va_list ap; char *buff; uint32 deltaTime = (uint32)difftime(time(NULL), utTimers[--utTimerDepth]); uint32 hours, minutes, seconds; if(timerID != utTimerDepth) { utWarning("Timer start/stop mismatch!"); } hours = deltaTime/3600; deltaTime -= hours*3600; minutes = deltaTime/60; deltaTime -= minutes*60; seconds = deltaTime; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); utLogMessage("%s %u:%02u:%02u", buff, hours, minutes, seconds);}/*-------------------------------------------------------------------------------------------------- Purpose: Same as utLogDebug but without the newline & prefix.--------------------------------------------------------------------------------------------------*/bool utDebug( char *format, ...){ va_list ap; char *buff; FILE *logFile; if(utLogFileName == NULL) { return false; } logFile = fopen(utLogFileName, "a"); if(logFile == NULL) { return false; } va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); fputs(buff, logFile); if(fclose(logFile) != 0) { buff = utSprintf("utDebug: unable to close %s", utLogFileName); (utUserErrProc)(buff); } return true; /* So utDebug can be used in ',' expressions */}/*-------------------------------------------------------------------------------------------------- Function to log errors without a message box to log file.--------------------------------------------------------------------------------------------------*/void utLogError( char *format, ...){ va_list ap; char *buff1, *buff2; va_start(ap, format); buff1 = utVsprintf(format, ap); va_end(ap); buff2 = utSprintf("Error: %s\n", buff1); utLogMessage(buff2);}/*-------------------------------------------------------------------------------------------------- Function to Send a message to the log file. Prefix with a time stamp line and a comment character.--------------------------------------------------------------------------------------------------*/void utLogTimeStamp( char *message, ...){ time_t timeInt = time(NULL); char *timeStr = ctime(&timeInt); va_list ap; char *buff1, *buff2; va_start(ap, message); buff1 = utVsprintf(message, ap); va_end(ap); buff2 = utSprintf("%s: %s\n", buff1, timeStr); utLogMessage(buff2);}/*-------------------------------------------------------------------------------------------------- Function to log the status of a tool to log file--------------------------------------------------------------------------------------------------*/void utStatus( char *format, ...){ va_list ap; char *buff; va_start(ap, format); buff = utVsprintf(format, ap); va_end(ap); if(utUserStatusProc != NULL) { (utUserStatusProc)(buff); }}static char *utExitFileName;static uint32 utExitLineNum;/*-------------------------------------------------------------------------------------------------- Exit with a fatal error message.--------------------------------------------------------------------------------------------------*/void utExit_( char *format, ...){ va_list ap; char *buff; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); if(utExitFileName == NULL) { utLogMessage("Exit: %s", buff); } else { utLogMessage("Exit: %s:%u %s", utExitFileName, utExitLineNum, buff); } if(utUserErrProc != NULL) { (utUserErrProc)(buff); } exit(1);}/*-------------------------------------------------------------------------------------------------- Set the file and line globals so that utExit_ can print them. Return utExit_ so it can be called with the user's parameters.--------------------------------------------------------------------------------------------------*/utExitProcType utSetFileAndLineAndReturnExitFunc( char *fileName, uint32 lineNum){ utExitFileName = fileName; utExitLineNum = lineNum; return &utExit_;}/*-------------------------------------------------------------------------------------------------- Post a warning message.--------------------------------------------------------------------------------------------------*/void utWarning( char *format, ...){ va_list ap; char *buff; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); utLogMessage("Warning: %s", buff); if(utUserWarningProc != NULL) { (utUserWarningProc)(buff); }}/*-------------------------------------------------------------------------------------------------- Post a note.--------------------------------------------------------------------------------------------------*/void utNote( char *format, ...){ va_list ap; char *buff; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); utLogMessage("%s", buff); if(utUserErrProc != NULL) { (utUserErrProc)(buff); }}/*-------------------------------------------------------------------------------------------------- Post an error message, and longjump. This function just returns a value so that it can be used for inline macros as a return value.--------------------------------------------------------------------------------------------------*/uint32 utError( char *format, ...){ va_list ap; char *buff; va_start(ap, format); buff = utVsprintf((char *)format, ap); va_end(ap); utLogMessage("Error: %s", buff); if(utUserErrProc != NULL) { (utUserErrProc)(buff); } utLongjmp(); return 0; /* Dummy return */}/*-------------------------------------------------------------------------------------------------- Cry and die.--------------------------------------------------------------------------------------------------*/void utAssert_( char *fileName, uint32 line, char *text){ utMemCheck(); utExitFileName = NULL; /* we don't want "util.c" and the utAssert line number to print */ utExit_("Assertion failed in file %s on line %u: %s", fileName, line, text);}/*-------------------------------------------------------------------------------------------------- Set the name of the Error callback.--------------------------------------------------------------------------------------------------*/void utSetErrorCallback( utErrorProc errorProc){ utUserErrProc = errorProc;}/*-------------------------------------------------------------------------------------------------- Set the name of the Warning callback.--------------------------------------------------------------------------------------------------*/void utSetWarningCallback( utErrorProc warningProc){ utUserWarningProc = warningProc;}/*-------------------------------------------------------------------------------------------------- Set the name of the status update callback.--------------------------------------------------------------------------------------------------*/void utSetStatusCallback( utErrorProc statusProc){ utUserStatusProc = statusProc;}/*-------------------------------------------------------------------------------------------------- Set the name of the logging file and reset it.--------------------------------------------------------------------------------------------------*/void utInitLogFile( char *fileName){ FILE *file;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -