3 #if defined(ECERE_BOOTSTRAP)
13 #if defined(__WIN32__)
15 #define WIN32_LEAN_AND_MEAN
17 #define GetFreeSpace _GetFreeSpace
18 #define String String_
23 #elif defined(__unix__) || defined(__APPLE__)
44 FILE *eC_stdout(void);
45 FILE *eC_stderr(void);
47 // IMPLEMENTED IN _System.c
48 bool System_MoveFile(const char * source, const char * dest);
49 bool System_RenameFile(const char * oldName, const char * newName);
50 bool System_DeleteFile(const char * fileName);
51 bool System_MakeDir(const char * path);
52 bool System_RemoveDir(const char * path);
53 char * System_GetWorkingDir(char * buf, int size);
54 bool System_ChangeWorkingDir(const char * buf);
55 char * System_GetEnvironment(const char * envName, char * envValue, int max);
56 void System_SetEnvironment(const char * envName, const char * envValue);
57 void System_UnsetEnvironment(const char * envName);
58 bool System_Execute(const char * env, const char * command, va_list args, bool wait);
59 bool System_ShellOpen(const char * fileName, va_list args);
60 void System_GetFreeSpace(const char * path, FileSize64 * size);
64 #if !defined(ECERE_BOOTSTRAP)
75 import "GuiApplication"
78 public enum LoggingMode { noLogging, stdOut, stdErr, debug, logFile, msgBox, buffer };
80 // GENERAL ERROR CODES
81 public enum ErrorLevel
89 public define AllErrors = ErrorLevel::minor;
91 public class ErrorCode
94 ErrorLevel level:2:12;
98 // TODO: Support enums resolved in compiling pass to allow moving this to GuiApplication.ec
99 public enum SysErrorCode : ErrorCode
101 allocationFailed = ErrorCode { fatal, 0x001 },
102 nameInexistant = ErrorCode { fatal, 0x002 },
103 nameExists = ErrorCode { fatal, 0x003 },
104 missingLibrary = ErrorCode { fatal, 0x004 },
105 fileNotFound = ErrorCode { minor, 0x005 },
106 writeFailed = ErrorCode { major, 0x006 }
109 public enum GuiErrorCode : ErrorCode
111 driverNotSupported = ErrorCode { veryFatal, 0x101 },
112 windowCreationFailed = ErrorCode { veryFatal, 0x102 },
113 graphicsLoadingFailed = ErrorCode { veryFatal, 0x103 },
114 modeSwitchFailed = ErrorCode { veryFatal, 0x104 }
117 static define DEFAULT_BUFFER_SIZE = 100 * MAX_F_STRING;
119 static Array<const String> sysErrorMessages
122 $"Memory allocation failed",
123 $"Inexistant string identifier specified",
124 $"Identic string identifier already exists",
125 $"Shared library loading failed",
127 $"Couldn't write to file"
130 static Array<const String> guiErrorMessages
133 $"Graphics driver not supported by any user interface system",
134 $"Window creation failed",
135 $"Window graphics loading failed",
136 $"Driver/Mode switch failed"
139 static Array<Array<const String>> errorMessages { [ sysErrorMessages, guiErrorMessages ] };
141 // --- File, directory & environment manipulation ---
144 public bool MoveFile(const char * source, const char * dest)
146 return System_MoveFile(source, dest);
149 public bool RenameFile(const char * oldName, const char * newName)
151 return System_RenameFile(oldName, newName);
156 public bool DeleteFile(const char * fileName)
158 return System_DeleteFile(fileName);
161 public bool MakeDir(const char * path)
163 return System_MakeDir(path);
166 public bool RemoveDir(const char * path)
168 return System_RemoveDir(path);
171 public char * GetWorkingDir(char * buf, int size)
173 return System_GetWorkingDir(buf, size);
176 public bool ChangeWorkingDir(const char * buf)
178 return System_ChangeWorkingDir(buf);
181 public char * GetEnvironment(const char * envName, char * envValue, int max)
183 return System_GetEnvironment(envName, envValue, max);
186 public void SetEnvironment(const char * envName, const char * envValue)
188 System_SetEnvironment(envName, envValue);
191 public void UnsetEnvironment(const char * envName)
193 System_UnsetEnvironment(envName);
196 public bool Execute(const char * command, ...)
200 va_start(args, command);
201 result = System_Execute(null, command, args, false);
206 public bool ExecuteWait(const char * command, ...)
210 va_start(args, command);
211 result = System_Execute(null, command, args, true);
216 public bool ExecuteEnv(const char * env, const char * command, ...)
220 va_start(args, command);
221 result = System_Execute(env, command, args, false);
226 public bool ShellOpen(const char * fileName, ...)
230 va_start(args, fileName);
231 result = System_ShellOpen(fileName, args);
236 public void GetFreeSpace(const char * path, FileSize64 * size)
238 System_GetFreeSpace(path, size);
241 // --- Uncagotegorized Functions ---
242 public void Logf(const char * format, ...)
245 char string[MAX_F_STRING];
246 va_start(args, format);
247 vsnprintf(string, sizeof(string), format, args);
248 string[sizeof(string)-1] = 0;
253 public void Log(const char * text)
255 switch(globalSystem.errorLoggingMode)
258 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
260 uint16 * _wtext = UTF8toUTF16(text, null);
261 OutputDebugString(_wtext);
267 fputs(text, eC_stdout());
271 fputs(text, eC_stderr());
277 if((f = FileOpen(globalSystem.logFile, append)))
286 strcat(globalSystem.errorBuffer, text);
291 public void DumpErrors(bool display)
293 if(globalSystem.errorBuffer && globalSystem.errorBuffer[0])
297 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
298 if(globalSystem.errorLoggingMode == buffer)
299 printf(globalSystem.errorBuffer);
303 sprintf(title, "%s - Error Log", guiApp.appName);
304 MessageBoxA(HWND_DESKTOP, globalSystem.errorBuffer, title, MB_OK|MB_ICONWARNING);
307 printf("%s", globalSystem.errorBuffer);
310 globalSystem.errorBuffer[0] = '\0';
314 public void LogErrorCode(ErrorCode errorCode, const char * details)
316 if(errorCode.level <= globalSystem.errorLevel)
318 int cat = (errorCode.code & 0xF00) >> 8;
319 int code = errorCode.code & 0xFF;
321 Logf("System Error [%d]: %s (%s).\n",
323 errorMessages[cat][code],
326 Logf("System Error [%d]: %s.\n",
328 errorMessages[cat][code]);
330 globalSystem.lastErrorCode = errorCode;
333 public uint GetLastErrorCode()
335 return globalSystem.lastErrorCode;
338 public void ResetError()
340 globalSystem.lastErrorCode = 0;
343 public void SetErrorLevel(ErrorLevel level)
345 globalSystem.errorLevel = level;
348 public void SetLoggingMode(LoggingMode mode, void * where)
350 globalSystem.errorLoggingMode = mode;
355 strcpy(globalSystem.logFile, where);
356 file = FileOpen(globalSystem.logFile, write);
359 else if(mode == buffer || mode == msgBox)
361 if(!globalSystem.errorBuffer)
363 globalSystem.errorBufferSize = DEFAULT_BUFFER_SIZE;
364 globalSystem.errorBuffer = new char[DEFAULT_BUFFER_SIZE];
366 globalSystem.errorBuffer[0] = 0;
368 else if(mode == debug)
370 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
371 uint16 * _wappName = UTF8toUTF16(guiApp.appName, null);
372 OutputDebugString(L"\n");
373 OutputDebugString(_wappName);
374 OutputDebugString(L" - Logging Errors...\n");
381 if(globalSystem.errorBuffer)
383 delete globalSystem.errorBuffer;
384 globalSystem.errorBufferSize = 0;
389 static define errorLogMsg = $"\n\nWould you like to view the error log?";
391 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
392 static DWORD REAL_ExceptionHandler(EXCEPTION_POINTERS *exception)
394 EXCEPTION_RECORD * record = exception->ExceptionRecord;
395 char exceptionString[1024] = "", title[1024];
397 switch(record->ExceptionCode)
399 case EXCEPTION_ACCESS_VIOLATION:
400 if(record->ExceptionInformation[0])
401 sprintf(exceptionString, "Access Violation Writing to 0x%p", (void *)record->ExceptionInformation[1]);
403 sprintf(exceptionString, "Access Violation Reading from 0x%p", (void *)record->ExceptionInformation[1]);
405 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
406 sprintf(exceptionString, "Array Bounds Exceeded");
408 case EXCEPTION_BREAKPOINT:
409 sprintf(exceptionString, "Breakpoint Encountered");
411 case EXCEPTION_DATATYPE_MISALIGNMENT:
412 sprintf(exceptionString, "Data Type Misalignment");
414 case EXCEPTION_FLT_DENORMAL_OPERAND:
415 sprintf(exceptionString, "Floating-Point Denormal Operand");
417 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
418 sprintf(exceptionString, "Floating-Point Divide by Zero");
420 case EXCEPTION_FLT_INEXACT_RESULT:
421 sprintf(exceptionString, "Floating-Point Inexact Result");
423 case EXCEPTION_FLT_INVALID_OPERATION:
424 sprintf(exceptionString, "Floating-Point Invalid Operation");
426 case EXCEPTION_FLT_OVERFLOW:
427 sprintf(exceptionString, "Floating-Point Overflow");
429 case EXCEPTION_FLT_STACK_CHECK:
430 sprintf(exceptionString, "Floating-Point Stack Check");
432 case EXCEPTION_FLT_UNDERFLOW:
433 sprintf(exceptionString, "Floating-Point Underflow");
435 case EXCEPTION_ILLEGAL_INSTRUCTION:
436 sprintf(exceptionString, "Illegal Instruction");
438 case EXCEPTION_IN_PAGE_ERROR:
439 sprintf(exceptionString, "In Page Error");
441 case EXCEPTION_INT_DIVIDE_BY_ZERO:
442 sprintf(exceptionString, "Integer Divide by Zero");
444 case EXCEPTION_INT_OVERFLOW:
445 sprintf(exceptionString, "Integer Overflow");
447 case EXCEPTION_INVALID_DISPOSITION:
448 sprintf(exceptionString, "Invalid Disposition");
450 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
451 sprintf(exceptionString, "Non Continuable Exception");
453 case EXCEPTION_PRIV_INSTRUCTION:
454 sprintf(exceptionString, "Unallowed Instruction");
456 case EXCEPTION_SINGLE_STEP:
457 sprintf(exceptionString, "Single Step Exception");
459 case EXCEPTION_STACK_OVERFLOW:
460 return EXCEPTION_CONTINUE_SEARCH;
461 //sprintf(exceptionString, "Stack Overflow");
465 sprintf(title, "%s - Fatal Error", guiApp.appName);
467 if(globalSystem.errorBuffer && globalSystem.errorBuffer[0])
469 strcat(exceptionString, errorLogMsg);
470 if(MessageBoxA(HWND_DESKTOP, exceptionString, title, MB_YESNO|MB_ICONERROR) == IDYES)
474 MessageBoxA(HWND_DESKTOP, exceptionString, title, MB_OK|MB_ICONERROR);
476 return EXCEPTION_EXECUTE_HANDLER;
481 private struct System
483 LoggingMode errorLoggingMode;
486 char logFile[MAX_LOCATION];
487 ErrorCode lastErrorCode;
488 ErrorLevel errorLevel;
490 #ifndef ECERE_BOOTSTRAP
491 Semaphore eventSemaphore;
493 //FileSystem fileSystems;
496 OldList fileMonitors;
497 Mutex fileMonitorMutex;
498 Thread fileMonitorThread;
499 bool systemTerminate;