OPM.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. /* voc 2.1.0 [2017/07/20]. Bootstrapping compiler for address size 8, alignment 8. xtspaSF */
  2. #define SHORTINT INT8
  3. #define INTEGER INT16
  4. #define LONGINT INT32
  5. #define SET UINT32
  6. #include "SYSTEM.h"
  7. #include "Configuration.h"
  8. #include "Files.h"
  9. #include "Modules.h"
  10. #include "Out.h"
  11. #include "Platform.h"
  12. #include "Strings.h"
  13. #include "Texts.h"
  14. #include "VT100.h"
  15. typedef
  16. CHAR OPM_FileName[32];
  17. static CHAR OPM_SourceFileName[256];
  18. static CHAR OPM_GlobalModel[10];
  19. export CHAR OPM_Model[10];
  20. static INT16 OPM_GlobalAddressSize;
  21. export INT16 OPM_AddressSize;
  22. static INT16 OPM_GlobalAlignment;
  23. export INT16 OPM_Alignment;
  24. export UINT32 OPM_GlobalOptions, OPM_Options;
  25. export INT16 OPM_ShortintSize, OPM_IntegerSize, OPM_LongintSize;
  26. export INT64 OPM_MaxIndex;
  27. export LONGREAL OPM_MinReal, OPM_MaxReal, OPM_MinLReal, OPM_MaxLReal;
  28. export BOOLEAN OPM_noerr;
  29. export INT32 OPM_curpos, OPM_errpos, OPM_breakpc;
  30. export INT16 OPM_currFile, OPM_level, OPM_pc, OPM_entno;
  31. export CHAR OPM_modName[32];
  32. export CHAR OPM_objname[64];
  33. static INT32 OPM_ErrorLineStartPos, OPM_ErrorLineLimitPos, OPM_ErrorLineNumber, OPM_lasterrpos;
  34. static Texts_Reader OPM_inR;
  35. static Texts_Text OPM_Log, OPM_Errors;
  36. static Files_Rider OPM_oldSF, OPM_newSF;
  37. static Files_Rider OPM_R[3];
  38. static Files_File OPM_oldSFile, OPM_newSFile, OPM_HFile, OPM_BFile, OPM_HIFile;
  39. static INT16 OPM_S;
  40. export CHAR OPM_InstallDir[1024];
  41. export CHAR OPM_ResourceDir[1024];
  42. static void OPM_Append (Files_Rider *R, ADDRESS *R__typ, Files_File F);
  43. export void OPM_CloseFiles (void);
  44. export void OPM_CloseOldSym (void);
  45. export void OPM_DeleteObj (CHAR *modulename, ADDRESS modulename__len);
  46. export void OPM_DeleteSym (CHAR *modulename, ADDRESS modulename__len);
  47. export void OPM_FPrint (INT32 *fp, INT64 val);
  48. export void OPM_FPrintLReal (INT32 *fp, LONGREAL val);
  49. export void OPM_FPrintReal (INT32 *fp, REAL val);
  50. export void OPM_FPrintSet (INT32 *fp, UINT64 val);
  51. static void OPM_FindInstallDir (void);
  52. static void OPM_FindLine (Files_File f, Files_Rider *r, ADDRESS *r__typ, INT64 pos);
  53. static void OPM_FingerprintBytes (INT32 *fp, SYSTEM_BYTE *bytes, ADDRESS bytes__len);
  54. export void OPM_Get (CHAR *ch);
  55. export void OPM_Init (BOOLEAN *done);
  56. export void OPM_InitOptions (void);
  57. export INT16 OPM_Integer (INT64 n);
  58. static BOOLEAN OPM_IsProbablyInstallDir (CHAR *s, ADDRESS s__len);
  59. export void OPM_LogCompiling (CHAR *modname, ADDRESS modname__len);
  60. static void OPM_LogErrMsg (INT16 n);
  61. export void OPM_LogVT100 (CHAR *vt100code, ADDRESS vt100code__len);
  62. export void OPM_LogW (CHAR ch);
  63. export void OPM_LogWLn (void);
  64. export void OPM_LogWNum (INT64 i, INT64 len);
  65. export void OPM_LogWStr (CHAR *s, ADDRESS s__len);
  66. export INT32 OPM_Longint (INT64 n);
  67. static void OPM_MakeFileName (CHAR *name, ADDRESS name__len, CHAR *FName, ADDRESS FName__len, CHAR *ext, ADDRESS ext__len);
  68. export void OPM_Mark (INT16 n, INT32 pos);
  69. export void OPM_NewSym (CHAR *modName, ADDRESS modName__len);
  70. export void OPM_OldSym (CHAR *modName, ADDRESS modName__len, BOOLEAN *done);
  71. export void OPM_OpenFiles (CHAR *moduleName, ADDRESS moduleName__len);
  72. export BOOLEAN OPM_OpenPar (void);
  73. export void OPM_RegisterNewSym (void);
  74. static void OPM_ScanOptions (CHAR *s, ADDRESS s__len);
  75. static void OPM_ShowLine (INT64 pos);
  76. export INT64 OPM_SignedMaximum (INT32 bytecount);
  77. export INT64 OPM_SignedMinimum (INT32 bytecount);
  78. export void OPM_SymRCh (CHAR *ch);
  79. export INT32 OPM_SymRInt (void);
  80. export INT64 OPM_SymRInt64 (void);
  81. export void OPM_SymRLReal (LONGREAL *lr);
  82. export void OPM_SymRReal (REAL *r);
  83. export void OPM_SymRSet (UINT64 *s);
  84. export void OPM_SymWCh (CHAR ch);
  85. export void OPM_SymWInt (INT64 i);
  86. export void OPM_SymWLReal (LONGREAL lr);
  87. export void OPM_SymWReal (REAL r);
  88. export void OPM_SymWSet (UINT64 s);
  89. export void OPM_Write (CHAR ch);
  90. export void OPM_WriteHex (INT64 i);
  91. export void OPM_WriteInt (INT64 i);
  92. export void OPM_WriteLn (void);
  93. export void OPM_WriteReal (LONGREAL r, CHAR suffx);
  94. export void OPM_WriteString (CHAR *s, ADDRESS s__len);
  95. export void OPM_WriteStringVar (CHAR *s, ADDRESS s__len);
  96. export BOOLEAN OPM_eofSF (void);
  97. export void OPM_err (INT16 n);
  98. #define OPM_GetAlignment(a) struct {char c; long long l;} _s; *a = (char*)&_s.l - (char*)&_s
  99. void OPM_LogW (CHAR ch)
  100. {
  101. Out_Char(ch);
  102. }
  103. void OPM_LogWStr (CHAR *s, ADDRESS s__len)
  104. {
  105. __DUP(s, s__len, CHAR);
  106. Out_String(s, s__len);
  107. __DEL(s);
  108. }
  109. void OPM_LogWNum (INT64 i, INT64 len)
  110. {
  111. Out_Int(i, len);
  112. }
  113. void OPM_LogWLn (void)
  114. {
  115. Out_Ln();
  116. }
  117. void OPM_LogVT100 (CHAR *vt100code, ADDRESS vt100code__len)
  118. {
  119. __DUP(vt100code, vt100code__len, CHAR);
  120. if ((Out_IsConsole && !__IN(16, OPM_Options, 32))) {
  121. VT100_SetAttr(vt100code, vt100code__len);
  122. }
  123. __DEL(vt100code);
  124. }
  125. void OPM_LogCompiling (CHAR *modname, ADDRESS modname__len)
  126. {
  127. __DUP(modname, modname__len, CHAR);
  128. OPM_LogWStr((CHAR*)"Compiling ", 11);
  129. OPM_LogWStr(modname, modname__len);
  130. if (__IN(18, OPM_Options, 32)) {
  131. OPM_LogWStr((CHAR*)", s:", 5);
  132. OPM_LogWNum(__ASHL(OPM_ShortintSize, 3), 1);
  133. OPM_LogWStr((CHAR*)" i:", 4);
  134. OPM_LogWNum(__ASHL(OPM_IntegerSize, 3), 1);
  135. OPM_LogWStr((CHAR*)" l:", 4);
  136. OPM_LogWNum(__ASHL(OPM_LongintSize, 3), 1);
  137. OPM_LogWStr((CHAR*)" adr:", 6);
  138. OPM_LogWNum(__ASHL(OPM_AddressSize, 3), 1);
  139. OPM_LogWStr((CHAR*)" algn:", 7);
  140. OPM_LogWNum(__ASHL(OPM_Alignment, 3), 1);
  141. }
  142. OPM_LogW('.');
  143. __DEL(modname);
  144. }
  145. INT64 OPM_SignedMaximum (INT32 bytecount)
  146. {
  147. INT64 result;
  148. result = 1;
  149. result = __LSH(result, __ASHL(bytecount, 3) - 1, 64);
  150. return result - 1;
  151. }
  152. INT64 OPM_SignedMinimum (INT32 bytecount)
  153. {
  154. return -OPM_SignedMaximum(bytecount) - 1;
  155. }
  156. INT32 OPM_Longint (INT64 n)
  157. {
  158. return __VAL(INT32, n);
  159. }
  160. INT16 OPM_Integer (INT64 n)
  161. {
  162. return __VAL(INT16, n);
  163. }
  164. static void OPM_ScanOptions (CHAR *s, ADDRESS s__len)
  165. {
  166. INT16 i;
  167. __DUP(s, s__len, CHAR);
  168. i = 1;
  169. while (s[__X(i, s__len)] != 0x00) {
  170. switch (s[__X(i, s__len)]) {
  171. case 'p':
  172. OPM_Options = OPM_Options ^ 0x20;
  173. break;
  174. case 'a':
  175. OPM_Options = OPM_Options ^ 0x80;
  176. break;
  177. case 'r':
  178. OPM_Options = OPM_Options ^ 0x04;
  179. break;
  180. case 't':
  181. OPM_Options = OPM_Options ^ 0x08;
  182. break;
  183. case 'x':
  184. OPM_Options = OPM_Options ^ 0x01;
  185. break;
  186. case 'e':
  187. OPM_Options = OPM_Options ^ 0x0200;
  188. break;
  189. case 's':
  190. OPM_Options = OPM_Options ^ 0x10;
  191. break;
  192. case 'F':
  193. OPM_Options = OPM_Options ^ 0x020000;
  194. break;
  195. case 'm':
  196. OPM_Options = OPM_Options ^ 0x0400;
  197. break;
  198. case 'M':
  199. OPM_Options = OPM_Options ^ 0x8000;
  200. break;
  201. case 'S':
  202. OPM_Options = OPM_Options ^ 0x2000;
  203. break;
  204. case 'c':
  205. OPM_Options = OPM_Options ^ 0x4000;
  206. break;
  207. case 'f':
  208. OPM_Options = OPM_Options ^ 0x010000;
  209. break;
  210. case 'V':
  211. OPM_Options = OPM_Options ^ 0x040000;
  212. break;
  213. case 'O':
  214. if (i + 1 >= Strings_Length(s, s__len)) {
  215. OPM_LogWStr((CHAR*)"-O option requires following size model character.", 51);
  216. OPM_LogWLn();
  217. } else {
  218. OPM_Model[0] = s[__X(i + 1, s__len)];
  219. OPM_Model[1] = 0x00;
  220. if ((((OPM_Model[0] != '2' && OPM_Model[0] != 'C')) && OPM_Model[0] != 'V')) {
  221. OPM_LogWStr((CHAR*)"Unrecognised size model character following -O.", 48);
  222. OPM_LogWLn();
  223. }
  224. i += 1;
  225. }
  226. break;
  227. case 'A':
  228. if (i + 2 >= Strings_Length(s, s__len)) {
  229. OPM_LogWStr((CHAR*)"-M option requires two following digits.", 41);
  230. OPM_LogWLn();
  231. } else {
  232. OPM_AddressSize = (INT16)s[__X(i + 1, s__len)] - 48;
  233. OPM_Alignment = (INT16)s[__X(i + 2, s__len)] - 48;
  234. i += 2;
  235. }
  236. break;
  237. default:
  238. OPM_LogWStr((CHAR*)" warning: option ", 19);
  239. OPM_LogW('-');
  240. OPM_LogW(s[__X(i, s__len)]);
  241. OPM_LogWStr((CHAR*)" ignored", 9);
  242. OPM_LogWLn();
  243. break;
  244. }
  245. i += 1;
  246. }
  247. __DEL(s);
  248. }
  249. BOOLEAN OPM_OpenPar (void)
  250. {
  251. CHAR s[256];
  252. if (Modules_ArgCount == 1) {
  253. OPM_LogWLn();
  254. OPM_LogWStr((CHAR*)"Oberon-2 compiler v", 20);
  255. OPM_LogWStr(Configuration_versionLong, 76);
  256. OPM_LogW('.');
  257. OPM_LogWLn();
  258. OPM_LogWStr((CHAR*)"Based on Ofront by J. Templ and Software Templ OEG.", 52);
  259. OPM_LogWLn();
  260. OPM_LogWStr((CHAR*)"Further development by Norayr Chilingarian, David Brown and others.", 68);
  261. OPM_LogWLn();
  262. OPM_LogWStr((CHAR*)"Loaded from ", 13);
  263. OPM_LogWStr(Modules_BinaryDir, 1024);
  264. OPM_LogWLn();
  265. OPM_LogWLn();
  266. OPM_LogWStr((CHAR*)"Usage:", 7);
  267. OPM_LogWLn();
  268. OPM_LogWLn();
  269. OPM_LogWStr((CHAR*)" ", 3);
  270. OPM_LogWStr((CHAR*)"voc", 4);
  271. OPM_LogWStr((CHAR*)" options {files {options}}.", 28);
  272. OPM_LogWLn();
  273. OPM_LogWLn();
  274. OPM_LogWStr((CHAR*)"Options:", 9);
  275. OPM_LogWLn();
  276. OPM_LogWLn();
  277. OPM_LogWStr((CHAR*)" Run time safety", 18);
  278. OPM_LogWLn();
  279. OPM_LogWStr((CHAR*)" -p Initialise pointers to NIL. On by default.", 52);
  280. OPM_LogWLn();
  281. OPM_LogWStr((CHAR*)" -a Halt on assertion failures. On by default.", 52);
  282. OPM_LogWLn();
  283. OPM_LogWStr((CHAR*)" -r Halt on range check failures.", 39);
  284. OPM_LogWLn();
  285. OPM_LogWStr((CHAR*)" -t Halt on type guard failure. On by default.", 52);
  286. OPM_LogWLn();
  287. OPM_LogWStr((CHAR*)" -x Halt on index out of range. On by default.", 52);
  288. OPM_LogWLn();
  289. OPM_LogWLn();
  290. OPM_LogWStr((CHAR*)" Symbol file management", 25);
  291. OPM_LogWLn();
  292. OPM_LogWStr((CHAR*)" -e Allow extension of old symbol file.", 45);
  293. OPM_LogWLn();
  294. OPM_LogWStr((CHAR*)" -s Allow generation of new symbol file.", 46);
  295. OPM_LogWLn();
  296. OPM_LogWStr((CHAR*)" -F Force generation of new symbol file.", 46);
  297. OPM_LogWLn();
  298. OPM_LogWLn();
  299. OPM_LogWStr((CHAR*)" C compiler and linker control", 32);
  300. OPM_LogWLn();
  301. OPM_LogWStr((CHAR*)" -m This module is main. Link dynamically.", 48);
  302. OPM_LogWLn();
  303. OPM_LogWStr((CHAR*)" -M This module is main. Link statically.", 47);
  304. OPM_LogWLn();
  305. OPM_LogWStr((CHAR*)" -S Don't call C compiler", 31);
  306. OPM_LogWLn();
  307. OPM_LogWStr((CHAR*)" -c Don't link.", 21);
  308. OPM_LogWLn();
  309. OPM_LogWLn();
  310. OPM_LogWStr((CHAR*)" Miscellaneous", 16);
  311. OPM_LogWLn();
  312. OPM_LogWStr((CHAR*)" -f Disable VT100 control characters in status output.", 60);
  313. OPM_LogWLn();
  314. OPM_LogWStr((CHAR*)" -V Display compiler debugging messages.", 46);
  315. OPM_LogWLn();
  316. OPM_LogWLn();
  317. OPM_LogWStr((CHAR*)" Size model for elementary types (default O2)", 47);
  318. OPM_LogWLn();
  319. OPM_LogWStr((CHAR*)" -O2 Original Oberon / Oberon-2: 8 bit SHORTINT, 16 bit INTEGER, 32 bit LONGINT and SET.", 95);
  320. OPM_LogWLn();
  321. OPM_LogWStr((CHAR*)" -OC Component Pascal: 16 bit SHORTINT, 32 bit INTEGER, 64 bit LONGINT and SET.", 95);
  322. OPM_LogWLn();
  323. OPM_LogWStr((CHAR*)" -OV Alternate large model: 8 bit SHORTINT, 32 bit INTEGER, 64 bit LONGINT and SET.", 95);
  324. OPM_LogWLn();
  325. OPM_LogWLn();
  326. OPM_LogWStr((CHAR*)" Target machine address size and alignment (default is that of the running compiler binary)", 93);
  327. OPM_LogWLn();
  328. OPM_LogWStr((CHAR*)" -A44 32 bit addresses, 32 bit alignment (e.g. Unix/linux 32 bit on x86).", 79);
  329. OPM_LogWLn();
  330. OPM_LogWStr((CHAR*)" -A48 32 bit addresses, 64 bit alignment (e.g. Windows 32 bit on x86, linux 32 bit on arm).", 97);
  331. OPM_LogWLn();
  332. OPM_LogWStr((CHAR*)" -A88 64 bit addresses, 64 bit alignment (e.g. 64 bit platforms).", 71);
  333. OPM_LogWLn();
  334. OPM_LogWLn();
  335. OPM_LogWStr((CHAR*)"All options are off by default, except where noted above.", 58);
  336. OPM_LogWLn();
  337. OPM_LogWStr((CHAR*)"Initial options specify defaults for all files.", 48);
  338. OPM_LogWLn();
  339. OPM_LogWStr((CHAR*)"Options following a filename are specific to that file.", 56);
  340. OPM_LogWLn();
  341. OPM_LogWStr((CHAR*)"Repeating an option toggles its value.", 39);
  342. OPM_LogWLn();
  343. return 0;
  344. } else {
  345. OPM_AddressSize = 4;
  346. OPM_GetAlignment(&OPM_Alignment);
  347. __MOVE("2", OPM_Model, 2);
  348. OPM_Options = 0xa9;
  349. OPM_S = 1;
  350. s[0] = 0x00;
  351. Modules_GetArg(OPM_S, (void*)s, 256);
  352. while (s[0] == '-') {
  353. OPM_ScanOptions(s, 256);
  354. OPM_S += 1;
  355. s[0] = 0x00;
  356. Modules_GetArg(OPM_S, (void*)s, 256);
  357. }
  358. OPM_GlobalAddressSize = OPM_AddressSize;
  359. OPM_GlobalAlignment = OPM_Alignment;
  360. __MOVE(OPM_Model, OPM_GlobalModel, 10);
  361. OPM_GlobalOptions = OPM_Options;
  362. return 1;
  363. }
  364. __RETCHK;
  365. }
  366. void OPM_InitOptions (void)
  367. {
  368. CHAR s[256];
  369. CHAR searchpath[1024], modules[1024];
  370. CHAR MODULES[1024];
  371. OPM_Options = OPM_GlobalOptions;
  372. __MOVE(OPM_GlobalModel, OPM_Model, 10);
  373. OPM_Alignment = OPM_GlobalAlignment;
  374. OPM_AddressSize = OPM_GlobalAddressSize;
  375. s[0] = 0x00;
  376. Modules_GetArg(OPM_S, (void*)s, 256);
  377. while (s[0] == '-') {
  378. OPM_ScanOptions(s, 256);
  379. OPM_S += 1;
  380. s[0] = 0x00;
  381. Modules_GetArg(OPM_S, (void*)s, 256);
  382. }
  383. if (__IN(15, OPM_Options, 32)) {
  384. OPM_Options |= __SETOF(10,32);
  385. }
  386. OPM_MaxIndex = OPM_SignedMaximum(OPM_AddressSize);
  387. switch (OPM_Model[0]) {
  388. case '2':
  389. OPM_ShortintSize = 1;
  390. OPM_IntegerSize = 2;
  391. OPM_LongintSize = 4;
  392. break;
  393. case 'C':
  394. OPM_ShortintSize = 2;
  395. OPM_IntegerSize = 4;
  396. OPM_LongintSize = 8;
  397. break;
  398. case 'V':
  399. OPM_ShortintSize = 1;
  400. OPM_IntegerSize = 4;
  401. OPM_LongintSize = 8;
  402. break;
  403. default:
  404. OPM_ShortintSize = 1;
  405. OPM_IntegerSize = 2;
  406. OPM_LongintSize = 4;
  407. break;
  408. }
  409. __MOVE(OPM_InstallDir, OPM_ResourceDir, 1024);
  410. if (OPM_ResourceDir[0] != 0x00) {
  411. Strings_Append((CHAR*)"/", 2, (void*)OPM_ResourceDir, 1024);
  412. Strings_Append(OPM_Model, 10, (void*)OPM_ResourceDir, 1024);
  413. }
  414. modules[0] = 0x00;
  415. Platform_GetEnv((CHAR*)"MODULES", 8, (void*)modules, 1024);
  416. __MOVE(".", searchpath, 2);
  417. Platform_GetEnv((CHAR*)"OBERON", 7, (void*)searchpath, 1024);
  418. Strings_Append((CHAR*)";.;", 4, (void*)searchpath, 1024);
  419. Strings_Append(modules, 1024, (void*)searchpath, 1024);
  420. Strings_Append((CHAR*)";", 2, (void*)searchpath, 1024);
  421. Strings_Append(OPM_ResourceDir, 1024, (void*)searchpath, 1024);
  422. Strings_Append((CHAR*)"/sym;", 6, (void*)searchpath, 1024);
  423. Files_SetSearchPath(searchpath, 1024);
  424. }
  425. void OPM_Init (BOOLEAN *done)
  426. {
  427. Texts_Text T = NIL;
  428. INT32 beg, end, time;
  429. CHAR s[256];
  430. *done = 0;
  431. OPM_curpos = 0;
  432. if (OPM_S >= Modules_ArgCount) {
  433. return;
  434. }
  435. s[0] = 0x00;
  436. Modules_GetArg(OPM_S, (void*)s, 256);
  437. __NEW(T, Texts_TextDesc);
  438. Texts_Open(T, s, 256);
  439. OPM_LogWStr(s, 256);
  440. OPM_LogWStr((CHAR*)" ", 3);
  441. __COPY(s, OPM_SourceFileName, 256);
  442. if (T->len == 0) {
  443. OPM_LogWStr(s, 256);
  444. OPM_LogWStr((CHAR*)" not found.", 12);
  445. OPM_LogWLn();
  446. } else {
  447. Texts_OpenReader(&OPM_inR, Texts_Reader__typ, T, 0);
  448. *done = 1;
  449. }
  450. OPM_S += 1;
  451. OPM_level = 0;
  452. OPM_noerr = 1;
  453. OPM_errpos = OPM_curpos;
  454. OPM_lasterrpos = OPM_curpos - 10;
  455. OPM_ErrorLineStartPos = 0;
  456. OPM_ErrorLineLimitPos = 0;
  457. OPM_ErrorLineNumber = 0;
  458. }
  459. void OPM_Get (CHAR *ch)
  460. {
  461. OPM_curpos = Texts_Pos(&OPM_inR, Texts_Reader__typ);
  462. Texts_Read(&OPM_inR, Texts_Reader__typ, &*ch);
  463. if ((*ch < 0x09 && !OPM_inR.eot)) {
  464. *ch = ' ';
  465. }
  466. }
  467. static void OPM_MakeFileName (CHAR *name, ADDRESS name__len, CHAR *FName, ADDRESS FName__len, CHAR *ext, ADDRESS ext__len)
  468. {
  469. INT16 i, j;
  470. CHAR ch;
  471. __DUP(ext, ext__len, CHAR);
  472. i = 0;
  473. for (;;) {
  474. ch = name[__X(i, name__len)];
  475. if (ch == 0x00) {
  476. break;
  477. }
  478. FName[__X(i, FName__len)] = ch;
  479. i += 1;
  480. }
  481. j = 0;
  482. do {
  483. ch = ext[__X(j, ext__len)];
  484. FName[__X(i, FName__len)] = ch;
  485. i += 1;
  486. j += 1;
  487. } while (!(ch == 0x00));
  488. __DEL(ext);
  489. }
  490. static void OPM_LogErrMsg (INT16 n)
  491. {
  492. INT16 l;
  493. Texts_Scanner S;
  494. CHAR c;
  495. if (n >= 0) {
  496. OPM_LogVT100((CHAR*)"31m", 4);
  497. OPM_LogWStr((CHAR*)" err ", 7);
  498. OPM_LogVT100((CHAR*)"0m", 3);
  499. } else {
  500. OPM_LogVT100((CHAR*)"35m", 4);
  501. OPM_LogWStr((CHAR*)" warning ", 11);
  502. n = -n;
  503. OPM_LogVT100((CHAR*)"0m", 3);
  504. }
  505. OPM_LogWNum(n, 1);
  506. OPM_LogWStr((CHAR*)" ", 3);
  507. if (OPM_Errors == NIL) {
  508. __NEW(OPM_Errors, Texts_TextDesc);
  509. Texts_Open(OPM_Errors, (CHAR*)"Errors.Txt", 11);
  510. }
  511. Texts_OpenScanner(&S, Texts_Scanner__typ, OPM_Errors, 0);
  512. do {
  513. l = S.line;
  514. Texts_Scan(&S, Texts_Scanner__typ);
  515. } while (!((((l != S.line && S.class == 3)) && S.i == n) || S.eot));
  516. if (!S.eot) {
  517. Texts_Read((void*)&S, Texts_Scanner__typ, &c);
  518. while ((!S.eot && c >= ' ')) {
  519. Out_Char(c);
  520. Texts_Read((void*)&S, Texts_Scanner__typ, &c);
  521. }
  522. }
  523. }
  524. static void OPM_FindLine (Files_File f, Files_Rider *r, ADDRESS *r__typ, INT64 pos)
  525. {
  526. CHAR ch, cheol;
  527. if (pos < (INT64)OPM_ErrorLineStartPos) {
  528. OPM_ErrorLineStartPos = 0;
  529. OPM_ErrorLineLimitPos = 0;
  530. OPM_ErrorLineNumber = 0;
  531. }
  532. if (pos < (INT64)OPM_ErrorLineLimitPos) {
  533. Files_Set(&*r, r__typ, f, OPM_ErrorLineStartPos);
  534. return;
  535. }
  536. Files_Set(&*r, r__typ, f, OPM_ErrorLineLimitPos);
  537. Files_Read(&*r, r__typ, (void*)&ch);
  538. while (((INT64)OPM_ErrorLineLimitPos < pos && !(*r).eof)) {
  539. OPM_ErrorLineStartPos = OPM_ErrorLineLimitPos;
  540. OPM_ErrorLineNumber += 1;
  541. while ((((ch != 0x00 && ch != 0x0d)) && ch != 0x0a)) {
  542. Files_Read(&*r, r__typ, (void*)&ch);
  543. OPM_ErrorLineLimitPos += 1;
  544. }
  545. cheol = ch;
  546. Files_Read(&*r, r__typ, (void*)&ch);
  547. OPM_ErrorLineLimitPos += 1;
  548. if ((cheol == 0x0d && ch == 0x0a)) {
  549. OPM_ErrorLineLimitPos += 1;
  550. Files_Read(&*r, r__typ, (void*)&ch);
  551. }
  552. }
  553. Files_Set(&*r, r__typ, f, OPM_ErrorLineStartPos);
  554. }
  555. static void OPM_ShowLine (INT64 pos)
  556. {
  557. Files_File f = NIL;
  558. Files_Rider r;
  559. CHAR line[1023];
  560. INT16 i;
  561. CHAR ch;
  562. f = Files_Old(OPM_SourceFileName, 256);
  563. OPM_FindLine(f, &r, Files_Rider__typ, pos);
  564. i = 0;
  565. Files_Read(&r, Files_Rider__typ, (void*)&ch);
  566. while ((((((ch != 0x00 && ch != 0x0d)) && ch != 0x0a)) && i < 1022)) {
  567. line[__X(i, 1023)] = ch;
  568. i += 1;
  569. Files_Read(&r, Files_Rider__typ, (void*)&ch);
  570. }
  571. line[__X(i, 1023)] = 0x00;
  572. OPM_LogWLn();
  573. OPM_LogWLn();
  574. OPM_LogWNum(OPM_ErrorLineNumber, 4);
  575. OPM_LogWStr((CHAR*)": ", 3);
  576. OPM_LogWStr(line, 1023);
  577. OPM_LogWLn();
  578. OPM_LogWStr((CHAR*)" ", 7);
  579. if (pos >= (INT64)OPM_ErrorLineLimitPos) {
  580. pos = OPM_ErrorLineLimitPos - 1;
  581. }
  582. i = (INT16)OPM_Longint(pos - (INT64)OPM_ErrorLineStartPos);
  583. while (i > 0) {
  584. OPM_LogW(' ');
  585. i -= 1;
  586. }
  587. OPM_LogVT100((CHAR*)"32m", 4);
  588. OPM_LogW('^');
  589. OPM_LogVT100((CHAR*)"0m", 3);
  590. }
  591. void OPM_Mark (INT16 n, INT32 pos)
  592. {
  593. if (pos == -1) {
  594. pos = 0;
  595. }
  596. if (n >= 0) {
  597. OPM_noerr = 0;
  598. if (pos < OPM_lasterrpos || OPM_lasterrpos + 9 < pos) {
  599. OPM_lasterrpos = pos;
  600. OPM_ShowLine(pos);
  601. OPM_LogWLn();
  602. OPM_LogWStr((CHAR*)" ", 3);
  603. if (n < 249) {
  604. OPM_LogWStr((CHAR*)" pos", 6);
  605. OPM_LogWNum(pos, 6);
  606. OPM_LogErrMsg(n);
  607. } else if (n == 255) {
  608. OPM_LogWStr((CHAR*)"pos", 4);
  609. OPM_LogWNum(pos, 6);
  610. OPM_LogWStr((CHAR*)" pc ", 6);
  611. OPM_LogWNum(OPM_breakpc, 1);
  612. } else if (n == 254) {
  613. OPM_LogWStr((CHAR*)"pc not found", 13);
  614. } else {
  615. OPM_LogWStr(OPM_objname, 64);
  616. if (n == 253) {
  617. OPM_LogWStr((CHAR*)" is new, compile with option e", 31);
  618. } else if (n == 252) {
  619. OPM_LogWStr((CHAR*)" is redefined, compile with option s", 37);
  620. } else if (n == 251) {
  621. OPM_LogWStr((CHAR*)" is redefined (private part only), compile with option s", 57);
  622. } else if (n == 250) {
  623. OPM_LogWStr((CHAR*)" is no longer visible, compile with option s", 45);
  624. } else if (n == 249) {
  625. OPM_LogWStr((CHAR*)" is not consistently imported, recompile imports", 49);
  626. }
  627. }
  628. }
  629. } else {
  630. if (pos >= 0) {
  631. OPM_ShowLine(pos);
  632. OPM_LogWLn();
  633. OPM_LogWStr((CHAR*)" pos", 6);
  634. OPM_LogWNum(pos, 6);
  635. }
  636. OPM_LogErrMsg(n);
  637. if (pos < 0) {
  638. OPM_LogWLn();
  639. }
  640. }
  641. }
  642. void OPM_err (INT16 n)
  643. {
  644. OPM_Mark(n, OPM_errpos);
  645. }
  646. static void OPM_FingerprintBytes (INT32 *fp, SYSTEM_BYTE *bytes, ADDRESS bytes__len)
  647. {
  648. INT16 i;
  649. INT32 l;
  650. __ASSERT(__MASK(bytes__len, -4) == 0, 0);
  651. i = 0;
  652. while (i < bytes__len) {
  653. __GET((ADDRESS)&bytes[__X(i, bytes__len)], l, INT32);
  654. *fp = __ROTL((INT32)((UINT32)*fp ^ (UINT32)l), 1, 32);
  655. i += 4;
  656. }
  657. }
  658. void OPM_FPrint (INT32 *fp, INT64 val)
  659. {
  660. OPM_FingerprintBytes(&*fp, (void*)&val, 8);
  661. }
  662. void OPM_FPrintSet (INT32 *fp, UINT64 val)
  663. {
  664. OPM_FingerprintBytes(&*fp, (void*)&val, 8);
  665. }
  666. void OPM_FPrintReal (INT32 *fp, REAL val)
  667. {
  668. OPM_FingerprintBytes(&*fp, (void*)&val, 4);
  669. }
  670. void OPM_FPrintLReal (INT32 *fp, LONGREAL val)
  671. {
  672. OPM_FingerprintBytes(&*fp, (void*)&val, 8);
  673. }
  674. void OPM_SymRCh (CHAR *ch)
  675. {
  676. Files_Read(&OPM_oldSF, Files_Rider__typ, (void*)&*ch);
  677. }
  678. INT32 OPM_SymRInt (void)
  679. {
  680. INT32 k;
  681. Files_ReadNum(&OPM_oldSF, Files_Rider__typ, (void*)&k, 4);
  682. return k;
  683. }
  684. INT64 OPM_SymRInt64 (void)
  685. {
  686. INT64 k;
  687. Files_ReadNum(&OPM_oldSF, Files_Rider__typ, (void*)&k, 8);
  688. return k;
  689. }
  690. void OPM_SymRSet (UINT64 *s)
  691. {
  692. Files_ReadNum(&OPM_oldSF, Files_Rider__typ, (void*)&*s, 8);
  693. }
  694. void OPM_SymRReal (REAL *r)
  695. {
  696. Files_ReadReal(&OPM_oldSF, Files_Rider__typ, &*r);
  697. }
  698. void OPM_SymRLReal (LONGREAL *lr)
  699. {
  700. Files_ReadLReal(&OPM_oldSF, Files_Rider__typ, &*lr);
  701. }
  702. void OPM_CloseOldSym (void)
  703. {
  704. Files_Close(Files_Base(&OPM_oldSF, Files_Rider__typ));
  705. }
  706. void OPM_OldSym (CHAR *modName, ADDRESS modName__len, BOOLEAN *done)
  707. {
  708. CHAR tag, ver;
  709. OPM_FileName fileName;
  710. INT16 res;
  711. OPM_oldSFile = NIL;
  712. *done = 0;
  713. OPM_MakeFileName((void*)modName, modName__len, (void*)fileName, 32, (CHAR*)".sym", 5);
  714. OPM_oldSFile = Files_Old(fileName, 32);
  715. *done = OPM_oldSFile != NIL;
  716. if (*done) {
  717. Files_Set(&OPM_oldSF, Files_Rider__typ, OPM_oldSFile, 0);
  718. Files_Read(&OPM_oldSF, Files_Rider__typ, (void*)&tag);
  719. Files_Read(&OPM_oldSF, Files_Rider__typ, (void*)&ver);
  720. if (tag != 0xf7 || ver != 0x83) {
  721. if (!__IN(4, OPM_Options, 32)) {
  722. OPM_err(-306);
  723. }
  724. OPM_CloseOldSym();
  725. *done = 0;
  726. }
  727. }
  728. }
  729. BOOLEAN OPM_eofSF (void)
  730. {
  731. return OPM_oldSF.eof;
  732. }
  733. void OPM_SymWCh (CHAR ch)
  734. {
  735. Files_Write(&OPM_newSF, Files_Rider__typ, ch);
  736. }
  737. void OPM_SymWInt (INT64 i)
  738. {
  739. Files_WriteNum(&OPM_newSF, Files_Rider__typ, i);
  740. }
  741. void OPM_SymWSet (UINT64 s)
  742. {
  743. Files_WriteNum(&OPM_newSF, Files_Rider__typ, (INT64)s);
  744. }
  745. void OPM_SymWReal (REAL r)
  746. {
  747. Files_WriteReal(&OPM_newSF, Files_Rider__typ, r);
  748. }
  749. void OPM_SymWLReal (LONGREAL lr)
  750. {
  751. Files_WriteLReal(&OPM_newSF, Files_Rider__typ, lr);
  752. }
  753. void OPM_RegisterNewSym (void)
  754. {
  755. if (__STRCMP(OPM_modName, "SYSTEM") != 0 || __IN(10, OPM_Options, 32)) {
  756. Files_Register(OPM_newSFile);
  757. }
  758. }
  759. void OPM_DeleteSym (CHAR *modulename, ADDRESS modulename__len)
  760. {
  761. OPM_FileName fn;
  762. INT16 res;
  763. OPM_MakeFileName((void*)modulename, modulename__len, (void*)fn, 32, (CHAR*)".sym", 5);
  764. Files_Delete(fn, 32, &res);
  765. }
  766. void OPM_DeleteObj (CHAR *modulename, ADDRESS modulename__len)
  767. {
  768. OPM_FileName fn;
  769. INT16 res;
  770. OPM_MakeFileName((void*)modulename, modulename__len, (void*)fn, 32, (CHAR*)".o", 3);
  771. Files_Delete(fn, 32, &res);
  772. }
  773. void OPM_NewSym (CHAR *modName, ADDRESS modName__len)
  774. {
  775. OPM_FileName fileName;
  776. OPM_MakeFileName((void*)modName, modName__len, (void*)fileName, 32, (CHAR*)".sym", 5);
  777. OPM_newSFile = Files_New(fileName, 32);
  778. if (OPM_newSFile != NIL) {
  779. Files_Set(&OPM_newSF, Files_Rider__typ, OPM_newSFile, 0);
  780. Files_Write(&OPM_newSF, Files_Rider__typ, 0xf7);
  781. Files_Write(&OPM_newSF, Files_Rider__typ, 0x83);
  782. } else {
  783. OPM_err(153);
  784. }
  785. }
  786. void OPM_Write (CHAR ch)
  787. {
  788. Files_Write(&OPM_R[__X(OPM_currFile, 3)], Files_Rider__typ, ch);
  789. }
  790. void OPM_WriteString (CHAR *s, ADDRESS s__len)
  791. {
  792. INT16 i;
  793. i = 0;
  794. while (s[__X(i, s__len)] != 0x00) {
  795. i += 1;
  796. }
  797. Files_WriteBytes(&OPM_R[__X(OPM_currFile, 3)], Files_Rider__typ, (void*)s, s__len * 1, i);
  798. }
  799. void OPM_WriteStringVar (CHAR *s, ADDRESS s__len)
  800. {
  801. INT16 i;
  802. i = 0;
  803. while (s[__X(i, s__len)] != 0x00) {
  804. i += 1;
  805. }
  806. Files_WriteBytes(&OPM_R[__X(OPM_currFile, 3)], Files_Rider__typ, (void*)s, s__len * 1, i);
  807. }
  808. void OPM_WriteHex (INT64 i)
  809. {
  810. CHAR s[3];
  811. INT32 digit;
  812. digit = __ASHR((INT32)i, 4);
  813. if (digit < 10) {
  814. s[0] = (CHAR)(48 + digit);
  815. } else {
  816. s[0] = (CHAR)(87 + digit);
  817. }
  818. digit = __MASK((INT32)i, -16);
  819. if (digit < 10) {
  820. s[1] = (CHAR)(48 + digit);
  821. } else {
  822. s[1] = (CHAR)(87 + digit);
  823. }
  824. s[2] = 0x00;
  825. OPM_WriteString(s, 3);
  826. }
  827. void OPM_WriteInt (INT64 i)
  828. {
  829. CHAR s[26];
  830. INT64 i1, k;
  831. if ((i == OPM_SignedMinimum(2) || i == OPM_SignedMinimum(4)) || i == OPM_SignedMinimum(8)) {
  832. OPM_Write('(');
  833. OPM_WriteInt(i + 1);
  834. OPM_WriteString((CHAR*)"-1)", 4);
  835. } else {
  836. i1 = __ABS(i);
  837. if (i1 <= 2147483647) {
  838. k = 0;
  839. } else {
  840. __MOVE("LL", s, 3);
  841. k = 2;
  842. }
  843. s[__X(k, 26)] = (CHAR)(__MOD(i1, 10) + 48);
  844. i1 = __DIV(i1, 10);
  845. k += 1;
  846. while (i1 > 0) {
  847. s[__X(k, 26)] = (CHAR)(__MOD(i1, 10) + 48);
  848. i1 = __DIV(i1, 10);
  849. k += 1;
  850. }
  851. if (i < 0) {
  852. s[__X(k, 26)] = '-';
  853. k += 1;
  854. }
  855. while (k > 0) {
  856. k -= 1;
  857. OPM_Write(s[__X(k, 26)]);
  858. }
  859. }
  860. }
  861. void OPM_WriteReal (LONGREAL r, CHAR suffx)
  862. {
  863. Texts_Writer W;
  864. Texts_Text T = NIL;
  865. Texts_Reader R;
  866. CHAR s[32];
  867. CHAR ch;
  868. INT16 i;
  869. if ((((r < OPM_SignedMaximum(OPM_LongintSize) && r > OPM_SignedMinimum(OPM_LongintSize))) && r == ((INT32)__ENTIER(r)))) {
  870. if (suffx == 'f') {
  871. OPM_WriteString((CHAR*)"(REAL)", 7);
  872. } else {
  873. OPM_WriteString((CHAR*)"(LONGREAL)", 11);
  874. }
  875. OPM_WriteInt((INT32)__ENTIER(r));
  876. } else {
  877. Texts_OpenWriter(&W, Texts_Writer__typ);
  878. if (suffx == 'f') {
  879. Texts_WriteLongReal(&W, Texts_Writer__typ, r, 16);
  880. } else {
  881. Texts_WriteLongReal(&W, Texts_Writer__typ, r, 23);
  882. }
  883. __NEW(T, Texts_TextDesc);
  884. Texts_Open(T, (CHAR*)"", 1);
  885. Texts_Append(T, W.buf);
  886. Texts_OpenReader(&R, Texts_Reader__typ, T, 0);
  887. i = 0;
  888. Texts_Read(&R, Texts_Reader__typ, &ch);
  889. while (ch != 0x00) {
  890. s[__X(i, 32)] = ch;
  891. i += 1;
  892. Texts_Read(&R, Texts_Reader__typ, &ch);
  893. }
  894. s[__X(i, 32)] = 0x00;
  895. i = 0;
  896. ch = s[0];
  897. while ((ch != 'D' && ch != 0x00)) {
  898. i += 1;
  899. ch = s[__X(i, 32)];
  900. }
  901. if (ch == 'D') {
  902. s[__X(i, 32)] = 'e';
  903. }
  904. OPM_WriteString(s, 32);
  905. }
  906. }
  907. void OPM_WriteLn (void)
  908. {
  909. Files_Write(&OPM_R[__X(OPM_currFile, 3)], Files_Rider__typ, 0x0a);
  910. }
  911. static void OPM_Append (Files_Rider *R, ADDRESS *R__typ, Files_File F)
  912. {
  913. Files_Rider R1;
  914. CHAR buffer[4096];
  915. if (F != NIL) {
  916. Files_Set(&R1, Files_Rider__typ, F, 0);
  917. Files_ReadBytes(&R1, Files_Rider__typ, (void*)buffer, 4096, 4096);
  918. while (4096 - R1.res > 0) {
  919. Files_WriteBytes(&*R, R__typ, (void*)buffer, 4096, 4096 - R1.res);
  920. Files_ReadBytes(&R1, Files_Rider__typ, (void*)buffer, 4096, 4096);
  921. }
  922. }
  923. }
  924. void OPM_OpenFiles (CHAR *moduleName, ADDRESS moduleName__len)
  925. {
  926. OPM_FileName FName;
  927. __COPY(moduleName, OPM_modName, 32);
  928. OPM_HFile = Files_New((CHAR*)"", 1);
  929. if (OPM_HFile != NIL) {
  930. Files_Set(&OPM_R[0], Files_Rider__typ, OPM_HFile, 0);
  931. } else {
  932. OPM_err(153);
  933. }
  934. OPM_MakeFileName((void*)moduleName, moduleName__len, (void*)FName, 32, (CHAR*)".c", 3);
  935. OPM_BFile = Files_New(FName, 32);
  936. if (OPM_BFile != NIL) {
  937. Files_Set(&OPM_R[1], Files_Rider__typ, OPM_BFile, 0);
  938. } else {
  939. OPM_err(153);
  940. }
  941. OPM_MakeFileName((void*)moduleName, moduleName__len, (void*)FName, 32, (CHAR*)".h", 3);
  942. OPM_HIFile = Files_New(FName, 32);
  943. if (OPM_HIFile != NIL) {
  944. Files_Set(&OPM_R[2], Files_Rider__typ, OPM_HIFile, 0);
  945. } else {
  946. OPM_err(153);
  947. }
  948. }
  949. void OPM_CloseFiles (void)
  950. {
  951. OPM_FileName FName;
  952. INT16 res;
  953. if (OPM_noerr) {
  954. OPM_LogWStr((CHAR*)" ", 3);
  955. OPM_LogWNum(Files_Pos(&OPM_R[1], Files_Rider__typ), 0);
  956. OPM_LogWStr((CHAR*)" chars.", 8);
  957. }
  958. if (OPM_noerr) {
  959. if (__STRCMP(OPM_modName, "SYSTEM") == 0) {
  960. if (!__IN(10, OPM_Options, 32)) {
  961. Files_Register(OPM_BFile);
  962. }
  963. } else if (!__IN(10, OPM_Options, 32)) {
  964. OPM_Append(&OPM_R[2], Files_Rider__typ, OPM_HFile);
  965. Files_Register(OPM_HIFile);
  966. Files_Register(OPM_BFile);
  967. } else {
  968. OPM_MakeFileName((void*)OPM_modName, 32, (void*)FName, 32, (CHAR*)".h", 3);
  969. Files_Delete(FName, 32, &res);
  970. OPM_MakeFileName((void*)OPM_modName, 32, (void*)FName, 32, (CHAR*)".sym", 5);
  971. Files_Delete(FName, 32, &res);
  972. Files_Register(OPM_BFile);
  973. }
  974. }
  975. OPM_HFile = NIL;
  976. OPM_BFile = NIL;
  977. OPM_HIFile = NIL;
  978. OPM_newSFile = NIL;
  979. OPM_oldSFile = NIL;
  980. Files_Set(&OPM_R[0], Files_Rider__typ, NIL, 0);
  981. Files_Set(&OPM_R[1], Files_Rider__typ, NIL, 0);
  982. Files_Set(&OPM_R[2], Files_Rider__typ, NIL, 0);
  983. Files_Set(&OPM_newSF, Files_Rider__typ, NIL, 0);
  984. Files_Set(&OPM_oldSF, Files_Rider__typ, NIL, 0);
  985. }
  986. static BOOLEAN OPM_IsProbablyInstallDir (CHAR *s, ADDRESS s__len)
  987. {
  988. CHAR testpath[4096];
  989. Platform_FileIdentity identity;
  990. BOOLEAN result;
  991. __DUP(s, s__len, CHAR);
  992. __COPY(OPM_InstallDir, testpath, 4096);
  993. Strings_Append((CHAR*)"/voc.exe", 9, (void*)testpath, 4096);
  994. result = Platform_IdentifyByName(testpath, 4096, &identity, Platform_FileIdentity__typ) != 0;
  995. if (!result) {
  996. __COPY(OPM_InstallDir, testpath, 4096);
  997. Strings_Append((CHAR*)"/voc", 5, (void*)testpath, 4096);
  998. result = Platform_IdentifyByName(testpath, 4096, &identity, Platform_FileIdentity__typ) != 0;
  999. }
  1000. __DEL(s);
  1001. return result;
  1002. }
  1003. static void OPM_FindInstallDir (void)
  1004. {
  1005. __COPY(Modules_BinaryDir, OPM_InstallDir, 1024);
  1006. if (!OPM_IsProbablyInstallDir(OPM_InstallDir, 1024)) {
  1007. __COPY("../data/bin/voc", OPM_InstallDir, 1024);
  1008. }
  1009. __COPY("../data/bin/voc", OPM_InstallDir, 1024);
  1010. }
  1011. static void EnumPtrs(void (*P)(void*))
  1012. {
  1013. __ENUMR(&OPM_inR, Texts_Reader__typ, 48, 1, P);
  1014. P(OPM_Log);
  1015. P(OPM_Errors);
  1016. __ENUMR(&OPM_oldSF, Files_Rider__typ, 20, 1, P);
  1017. __ENUMR(&OPM_newSF, Files_Rider__typ, 20, 1, P);
  1018. __ENUMR(OPM_R, Files_Rider__typ, 20, 3, P);
  1019. P(OPM_oldSFile);
  1020. P(OPM_newSFile);
  1021. P(OPM_HFile);
  1022. P(OPM_BFile);
  1023. P(OPM_HIFile);
  1024. }
  1025. export void *OPM__init(void)
  1026. {
  1027. __DEFMOD;
  1028. __MODULE_IMPORT(Configuration);
  1029. __MODULE_IMPORT(Files);
  1030. __MODULE_IMPORT(Modules);
  1031. __MODULE_IMPORT(Out);
  1032. __MODULE_IMPORT(Platform);
  1033. __MODULE_IMPORT(Strings);
  1034. __MODULE_IMPORT(Texts);
  1035. __MODULE_IMPORT(VT100);
  1036. __REGMOD("OPM", EnumPtrs);
  1037. __REGCMD("CloseFiles", OPM_CloseFiles);
  1038. __REGCMD("CloseOldSym", OPM_CloseOldSym);
  1039. __REGCMD("InitOptions", OPM_InitOptions);
  1040. __REGCMD("LogWLn", OPM_LogWLn);
  1041. __REGCMD("RegisterNewSym", OPM_RegisterNewSym);
  1042. __REGCMD("WriteLn", OPM_WriteLn);
  1043. /* BEGIN */
  1044. OPM_MaxReal = 3.40282346000000e+038;
  1045. OPM_MaxLReal = 1.79769296342094e+308;
  1046. OPM_MinReal = -OPM_MaxReal;
  1047. OPM_MinLReal = -OPM_MaxLReal;
  1048. OPM_FindInstallDir();
  1049. __ENDMOD;
  1050. }