5 #if defined(ECERE_BOOTSTRAP)
15 #if defined(__WIN32__)
17 #define WIN32_LEAN_AND_MEAN
19 #define GetFreeSpace _GetFreeSpace
20 #define String String_
25 #elif defined(__unix__) || defined(__APPLE__)
46 FILE *eC_stdout(void);
47 FILE *eC_stderr(void);
49 // IMPLEMENTED IN _System.c
50 bool System_MoveFile(const char * source, const char * dest, uint replaceAndFlush);
51 bool System_RenameFile(const char * oldName, const char * newName);
52 bool System_DeleteFile(const char * fileName);
53 bool System_MakeDir(const char * path);
54 bool System_RemoveDir(const char * path);
55 char * System_GetWorkingDir(char * buf, int size);
56 bool System_ChangeWorkingDir(const char * buf);
57 char * System_GetEnvironment(const char * envName, char * envValue, int max);
58 void System_SetEnvironment(const char * envName, const char * envValue);
59 void System_UnsetEnvironment(const char * envName);
60 bool System_Execute(const char * env, const char * command, va_list args, bool wait);
61 bool System_ShellOpen(const char * fileName, va_list args);
62 void System_GetFreeSpace(const char * path, FileSize64 * size);
66 #if !defined(ECERE_BOOTSTRAP)
69 //#if !defined(__EMSCRIPTEN__)
79 import "GuiApplication"
82 public enum LoggingMode { noLogging, stdOut, stdErr, debug, logFile, msgBox, buffer };
84 // GENERAL ERROR CODES
85 public enum ErrorLevel
93 public define AllErrors = ErrorLevel::minor;
95 public class ErrorCode
98 ErrorLevel level:2:12;
102 // TODO: Support enums resolved in compiling pass to allow moving this to GuiApplication.ec
103 public enum SysErrorCode : ErrorCode
105 allocationFailed = ErrorCode { fatal, 0x001 },
106 nameInexistant = ErrorCode { fatal, 0x002 },
107 nameExists = ErrorCode { fatal, 0x003 },
108 missingLibrary = ErrorCode { fatal, 0x004 },
109 fileNotFound = ErrorCode { minor, 0x005 },
110 writeFailed = ErrorCode { major, 0x006 }
113 public enum GuiErrorCode : ErrorCode
115 driverNotSupported = ErrorCode { veryFatal, 0x101 },
116 windowCreationFailed = ErrorCode { veryFatal, 0x102 },
117 graphicsLoadingFailed = ErrorCode { veryFatal, 0x103 },
118 modeSwitchFailed = ErrorCode { veryFatal, 0x104 }
121 static define DEFAULT_BUFFER_SIZE = 100 * MAX_F_STRING;
123 static Array<const String> sysErrorMessages
126 $"Memory allocation failed",
127 $"Inexistant string identifier specified",
128 $"Identic string identifier already exists",
129 $"Shared library loading failed",
131 $"Couldn't write to file"
134 static Array<const String> guiErrorMessages
137 $"Graphics driver not supported by any user interface system",
138 $"Window creation failed",
139 $"Window graphics loading failed",
140 $"Driver/Mode switch failed"
143 static Array<Array<const String>> errorMessages { [ sysErrorMessages, guiErrorMessages ] };
145 // --- File, directory & environment manipulation ---
149 public bool MoveFile(const char * source, const char * dest)
151 return System_MoveFile(source, dest, 0);
154 public class MoveFileOptions : uint32 { public: bool overwrite:1; bool sync:1; };
156 public bool MoveFileEx(const char * source, const char * dest, MoveFileOptions options)
158 return System_MoveFile(source, dest, options);
161 public bool RenameFile(const char * oldName, const char * newName)
163 return System_RenameFile(oldName, newName);
168 public bool DeleteFile(const char * fileName)
170 return System_DeleteFile(fileName);
173 public bool MakeDir(const char * path)
175 return System_MakeDir(path);
178 public bool RemoveDir(const char * path)
180 return System_RemoveDir(path);
183 public char * GetWorkingDir(char * buf, int size)
185 return System_GetWorkingDir(buf, size);
188 public bool ChangeWorkingDir(const char * buf)
190 return System_ChangeWorkingDir(buf);
193 public char * GetEnvironment(const char * envName, char * envValue, int max)
195 return System_GetEnvironment(envName, envValue, max);
198 public void SetEnvironment(const char * envName, const char * envValue)
200 System_SetEnvironment(envName, envValue);
203 public void UnsetEnvironment(const char * envName)
205 System_UnsetEnvironment(envName);
208 public bool Execute(const char * command, ...)
212 va_start(args, command);
213 result = System_Execute(null, command, args, false);
218 public bool ExecuteWait(const char * command, ...)
222 va_start(args, command);
223 result = System_Execute(null, command, args, true);
228 public bool ExecuteEnv(const char * env, const char * command, ...)
232 va_start(args, command);
233 result = System_Execute(env, command, args, false);
238 public bool ShellOpen(const char * fileName, ...)
242 va_start(args, fileName);
243 result = System_ShellOpen(fileName, args);
248 public void GetFreeSpace(const char * path, FileSize64 * size)
250 System_GetFreeSpace(path, size);
253 // --- Uncagotegorized Functions ---
254 public void Logf(const char * format, ...)
257 char string[MAX_F_STRING];
258 va_start(args, format);
259 vsnprintf(string, sizeof(string), format, args);
260 string[sizeof(string)-1] = 0;
265 public void Log(const char * text)
267 switch(globalSystem.errorLoggingMode)
270 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
272 uint16 * _wtext = UTF8toUTF16(text, null);
273 OutputDebugString(_wtext);
279 fputs(text, eC_stdout());
283 fputs(text, eC_stderr());
289 if((f = FileOpen(globalSystem.logFile, append)))
298 strcat(globalSystem.errorBuffer, text);
303 public void DumpErrors(bool display)
305 if(globalSystem.errorBuffer && globalSystem.errorBuffer[0])
309 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
310 if(globalSystem.errorLoggingMode == buffer)
311 printf(globalSystem.errorBuffer);
315 sprintf(title, "%s - Error Log", guiApp.appName);
316 MessageBoxA(HWND_DESKTOP, globalSystem.errorBuffer, title, MB_OK|MB_ICONWARNING);
319 printf("%s", globalSystem.errorBuffer);
322 globalSystem.errorBuffer[0] = '\0';
326 public void LogErrorCode(ErrorCode errorCode, const char * details)
328 if(errorCode.level <= globalSystem.errorLevel)
330 int cat = (errorCode.code & 0xF00) >> 8;
331 int code = errorCode.code & 0xFF;
333 Logf("System Error [%d]: %s (%s).\n",
335 errorMessages[cat][code],
338 Logf("System Error [%d]: %s.\n",
340 errorMessages[cat][code]);
342 globalSystem.lastErrorCode = errorCode;
345 public uint GetLastErrorCode()
347 return globalSystem.lastErrorCode;
350 public void ResetError()
352 globalSystem.lastErrorCode = 0;
355 public void SetErrorLevel(ErrorLevel level)
357 globalSystem.errorLevel = level;
360 public void SetLoggingMode(LoggingMode mode, void * where)
362 globalSystem.errorLoggingMode = mode;
367 strcpy(globalSystem.logFile, where);
368 file = FileOpen(globalSystem.logFile, write);
371 else if(mode == buffer || mode == msgBox)
373 if(!globalSystem.errorBuffer)
375 globalSystem.errorBufferSize = DEFAULT_BUFFER_SIZE;
376 globalSystem.errorBuffer = new char[DEFAULT_BUFFER_SIZE];
378 globalSystem.errorBuffer[0] = 0;
380 else if(mode == debug)
382 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
383 uint16 * _wappName = UTF8toUTF16(guiApp.appName, null);
384 OutputDebugString(L"\n");
385 OutputDebugString(_wappName);
386 OutputDebugString(L" - Logging Errors...\n");
393 if(globalSystem.errorBuffer)
395 delete globalSystem.errorBuffer;
396 globalSystem.errorBufferSize = 0;
401 static define errorLogMsg = $"\n\nWould you like to view the error log?";
403 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
404 static DWORD REAL_ExceptionHandler(EXCEPTION_POINTERS *exception)
406 EXCEPTION_RECORD * record = exception->ExceptionRecord;
407 char exceptionString[1024] = "", title[1024];
409 switch(record->ExceptionCode)
411 case EXCEPTION_ACCESS_VIOLATION:
412 if(record->ExceptionInformation[0])
413 sprintf(exceptionString, "Access Violation Writing to 0x%p", (void *)record->ExceptionInformation[1]);
415 sprintf(exceptionString, "Access Violation Reading from 0x%p", (void *)record->ExceptionInformation[1]);
417 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
418 sprintf(exceptionString, "Array Bounds Exceeded");
420 case EXCEPTION_BREAKPOINT:
421 sprintf(exceptionString, "Breakpoint Encountered");
423 case EXCEPTION_DATATYPE_MISALIGNMENT:
424 sprintf(exceptionString, "Data Type Misalignment");
426 case EXCEPTION_FLT_DENORMAL_OPERAND:
427 sprintf(exceptionString, "Floating-Point Denormal Operand");
429 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
430 sprintf(exceptionString, "Floating-Point Divide by Zero");
432 case EXCEPTION_FLT_INEXACT_RESULT:
433 sprintf(exceptionString, "Floating-Point Inexact Result");
435 case EXCEPTION_FLT_INVALID_OPERATION:
436 sprintf(exceptionString, "Floating-Point Invalid Operation");
438 case EXCEPTION_FLT_OVERFLOW:
439 sprintf(exceptionString, "Floating-Point Overflow");
441 case EXCEPTION_FLT_STACK_CHECK:
442 sprintf(exceptionString, "Floating-Point Stack Check");
444 case EXCEPTION_FLT_UNDERFLOW:
445 sprintf(exceptionString, "Floating-Point Underflow");
447 case EXCEPTION_ILLEGAL_INSTRUCTION:
448 sprintf(exceptionString, "Illegal Instruction");
450 case EXCEPTION_IN_PAGE_ERROR:
451 sprintf(exceptionString, "In Page Error");
453 case EXCEPTION_INT_DIVIDE_BY_ZERO:
454 sprintf(exceptionString, "Integer Divide by Zero");
456 case EXCEPTION_INT_OVERFLOW:
457 sprintf(exceptionString, "Integer Overflow");
459 case EXCEPTION_INVALID_DISPOSITION:
460 sprintf(exceptionString, "Invalid Disposition");
462 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
463 sprintf(exceptionString, "Non Continuable Exception");
465 case EXCEPTION_PRIV_INSTRUCTION:
466 sprintf(exceptionString, "Unallowed Instruction");
468 case EXCEPTION_SINGLE_STEP:
469 sprintf(exceptionString, "Single Step Exception");
471 case EXCEPTION_STACK_OVERFLOW:
472 return EXCEPTION_CONTINUE_SEARCH;
473 //sprintf(exceptionString, "Stack Overflow");
477 sprintf(title, "%s - Fatal Error", guiApp.appName);
479 if(globalSystem.errorBuffer && globalSystem.errorBuffer[0])
481 strcat(exceptionString, errorLogMsg);
482 if(MessageBoxA(HWND_DESKTOP, exceptionString, title, MB_YESNO|MB_ICONERROR) == IDYES)
486 MessageBoxA(HWND_DESKTOP, exceptionString, title, MB_OK|MB_ICONERROR);
488 return EXCEPTION_EXECUTE_HANDLER;
493 private struct System
495 LoggingMode errorLoggingMode;
498 char logFile[MAX_LOCATION];
499 ErrorCode lastErrorCode;
500 ErrorLevel errorLevel;
502 #ifndef ECERE_BOOTSTRAP
503 #if !defined(__EMSCRIPTEN__)
504 Semaphore eventSemaphore;
507 //FileSystem fileSystems;
510 OldList fileMonitors;
511 #if !defined(__EMSCRIPTEN__)
512 Mutex fileMonitorMutex;
513 Thread fileMonitorThread;
515 bool systemTerminate;