ErrorCodes.Mod 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. MODULE ErrorCodes;
  2. (**
  3. AUTHOR: Alexey Morozov and Timothee Martiel, HighDim GmbH, 2015
  4. PURPOSE: generic error management runtime
  5. *)
  6. IMPORT
  7. Modules;
  8. CONST
  9. ErrorCodeRangeSize* = 4096;
  10. MaxNumModules* = 128;
  11. Ok* = 0;
  12. (** New line types *)
  13. LnCRLF* = 0;
  14. LnCR* = 1;
  15. LnLF* = 2;
  16. LnType* = LnCRLF;
  17. TYPE
  18. Module = POINTER TO RECORD
  19. name: Modules.Name;
  20. errorBase: LONGINT;
  21. END;
  22. VAR
  23. modules: ARRAY MaxNumModules OF Module;
  24. numModules: LONGINT;
  25. ln: ARRAY 3 OF CHAR;
  26. acquire*, release*: PROCEDURE{DELEGATE}(); (** plugable locks for thread-safety if required *)
  27. (**
  28. Register a module by name and get its corresponding error base
  29. *)
  30. PROCEDURE RegisterModule*(CONST modName: ARRAY OF CHAR; VAR errorBase: LONGINT);
  31. VAR mod: Module;
  32. BEGIN
  33. IF acquire # NIL THEN acquire; END;
  34. mod := modules[numModules];
  35. IF mod = NIL THEN NEW(mod); END;
  36. COPY(modName,mod.name);
  37. IF numModules > 0 THEN
  38. errorBase := mod.errorBase+ErrorCodeRangeSize;
  39. ELSE errorBase := 0;
  40. END;
  41. mod.errorBase := errorBase;
  42. modules[numModules] := mod;
  43. INC(numModules);
  44. IF release # NIL THEN release; END;
  45. END RegisterModule;
  46. (**
  47. Unregister a module by its name
  48. *)
  49. PROCEDURE UnregisterModule*(CONST modName: ARRAY OF CHAR);
  50. VAR i: LONGINT;
  51. BEGIN
  52. IF acquire # NIL THEN acquire; END;
  53. i := 0;
  54. WHILE (i < numModules) & (modules[i].name # modName) DO INC(i); END;
  55. IF i < numModules THEN
  56. FOR i := i TO numModules-2 DO modules[i] := modules[i+1]; END;
  57. DEC(numModules);
  58. END;
  59. IF release # NIL THEN release; END;
  60. END UnregisterModule;
  61. (**
  62. Get error code for the module at the specified level
  63. *)
  64. PROCEDURE Get*(error: LONGINT; level: LONGINT; VAR modName: ARRAY OF CHAR; VAR modError: LONGINT);
  65. BEGIN
  66. modError := (error DIV (level*ErrorCodeRangeSize)) MOD ErrorCodeRangeSize;
  67. COPY(modules[level].name,modName);
  68. END Get;
  69. (**
  70. Get the error base for a module with a given name
  71. Returns -1 in case if the module was not found in the list of registered modules
  72. *)
  73. PROCEDURE GetErrorBase*(CONST modName: ARRAY OF CHAR): LONGINT;
  74. VAR i, errorBase: LONGINT;
  75. BEGIN
  76. IF acquire # NIL THEN acquire; END;
  77. i := 0;
  78. WHILE (i < numModules) & (modules[i].name # modName) DO INC(i); END;
  79. IF i < numModules THEN
  80. errorBase := modules[i].errorBase;
  81. ELSE errorBase := -1;
  82. END;
  83. IF release # NIL THEN release; END;
  84. RETURN errorBase;
  85. END GetErrorBase;
  86. (*
  87. Get a string representation of an integer (in decimal format)
  88. *)
  89. PROCEDURE IntToStr(x: HUGEINT; VAR str: ARRAY OF CHAR);
  90. VAR
  91. i, j: LONGINT;
  92. ch: CHAR;
  93. BEGIN
  94. IF x < 0 THEN
  95. IF x = MIN(HUGEINT) THEN
  96. str := "-9223372036854775808";
  97. RETURN;
  98. ELSE
  99. str[0] := "-";
  100. i := 1;
  101. x := -x;
  102. END;
  103. END;
  104. REPEAT
  105. str[i] := CHR((x MOD 10)+48);
  106. x := x DIV 10;
  107. INC(i);
  108. UNTIL x = 0;
  109. (* reverse the output string *)
  110. DEC(i);
  111. FOR j := 0 TO (i DIV 2) BY 1 DO
  112. ch := str[j];
  113. str[j] := str[i-j];
  114. str[i-j] := ch;
  115. END;
  116. END IntToStr;
  117. (**
  118. Produce trace-back error printout
  119. errorOnly: TRUE for printing only errors
  120. *)
  121. PROCEDURE TraceBack*(error: LONGINT; errorOnly: BOOLEAN; tracer: PROCEDURE{DELEGATE}(CONST str: ARRAY OF CHAR));
  122. VAR
  123. level, modError: LONGINT;
  124. str: ARRAY 32 OF CHAR;
  125. BEGIN
  126. IF acquire # NIL THEN acquire; END;
  127. FOR level := 0 TO numModules-1 DO
  128. modError := error MOD ErrorCodeRangeSize;
  129. IF (modError # Ok) OR ~errorOnly THEN
  130. tracer(modules[level].name);
  131. tracer(": "); IntToStr(modError,str); tracer(str);
  132. tracer(ln);
  133. END;
  134. error := error DIV ErrorCodeRangeSize;
  135. END;
  136. IF release # NIL THEN release; END;
  137. END TraceBack;
  138. BEGIN
  139. numModules := 0;
  140. CASE LnType OF
  141. |LnCRLF: ln[0] := 0DX; ln[1] := 0AX; ln[2] := 0X;
  142. |LnCR: ln[0] := 0DX; ln[1] := 0X;
  143. |LnLF: ln[0] := 0AX; ln[1] := 0X;
  144. END;
  145. END ErrorCodes.