Files.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. /* voc 2.1.0 [2021/07/05]. Bootstrapping compiler for address size 8, alignment 8. xrtspaSF */
  2. #define SHORTINT INT8
  3. #define INTEGER INT16
  4. #define LONGINT INT32
  5. #define SET UINT32
  6. #include "SYSTEM.h"
  7. #include "Heap.h"
  8. #include "Out.h"
  9. #include "Platform.h"
  10. #include "Strings.h"
  11. typedef
  12. struct Files_FileDesc *Files_File;
  13. typedef
  14. struct Files_BufDesc {
  15. Files_File f;
  16. BOOLEAN chg;
  17. INT32 org, size;
  18. SYSTEM_BYTE data[4096];
  19. } Files_BufDesc;
  20. typedef
  21. Files_BufDesc *Files_Buffer;
  22. typedef
  23. CHAR Files_FileName[256];
  24. typedef
  25. struct Files_FileDesc {
  26. Files_FileName workName, registerName;
  27. BOOLEAN tempFile;
  28. Platform_FileIdentity identity;
  29. INT32 fd, len, pos;
  30. Files_Buffer bufs[4];
  31. INT16 swapper, state;
  32. struct Files_FileDesc *next;
  33. } Files_FileDesc;
  34. typedef
  35. struct Files_Rider {
  36. INT32 res;
  37. BOOLEAN eof;
  38. Files_Buffer buf;
  39. INT32 org, offset;
  40. } Files_Rider;
  41. export INT16 Files_MaxPathLength, Files_MaxNameLength;
  42. static Files_FileDesc *Files_files;
  43. static INT16 Files_tempno;
  44. static CHAR Files_HOME[1024];
  45. static struct {
  46. ADDRESS len[1];
  47. CHAR data[1];
  48. } *Files_SearchPath;
  49. export ADDRESS *Files_FileDesc__typ;
  50. export ADDRESS *Files_BufDesc__typ;
  51. export ADDRESS *Files_Rider__typ;
  52. static void Files_Assert (BOOLEAN truth);
  53. export Files_File Files_Base (Files_Rider *r, ADDRESS *r__typ);
  54. static Files_File Files_CacheEntry (Platform_FileIdentity identity);
  55. export void Files_ChangeDirectory (CHAR *path, ADDRESS path__len, INT16 *res);
  56. export void Files_Close (Files_File f);
  57. static void Files_CloseOSFile (Files_File f);
  58. static void Files_Create (Files_File f);
  59. export void Files_Delete (CHAR *name, ADDRESS name__len, INT16 *res);
  60. static void Files_Deregister (CHAR *name, ADDRESS name__len);
  61. static void Files_Err (CHAR *s, ADDRESS s__len, Files_File f, INT16 errcode);
  62. static void Files_Finalize (SYSTEM_PTR o);
  63. static void Files_FlipBytes (SYSTEM_BYTE *src, ADDRESS src__len, SYSTEM_BYTE *dest, ADDRESS dest__len);
  64. static void Files_Flush (Files_Buffer buf);
  65. export void Files_GetDate (Files_File f, INT32 *t, INT32 *d);
  66. export void Files_GetName (Files_File f, CHAR *name, ADDRESS name__len);
  67. static void Files_GetTempName (CHAR *finalName, ADDRESS finalName__len, CHAR *name, ADDRESS name__len);
  68. static BOOLEAN Files_HasDir (CHAR *name, ADDRESS name__len);
  69. export INT32 Files_Length (Files_File f);
  70. static void Files_MakeFileName (CHAR *dir, ADDRESS dir__len, CHAR *name, ADDRESS name__len, CHAR *dest, ADDRESS dest__len);
  71. export Files_File Files_New (CHAR *name, ADDRESS name__len);
  72. export Files_File Files_Old (CHAR *name, ADDRESS name__len);
  73. export INT32 Files_Pos (Files_Rider *r, ADDRESS *r__typ);
  74. export void Files_Purge (Files_File f);
  75. export void Files_Read (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x);
  76. export void Files_ReadBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN *x);
  77. export void Files_ReadBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n);
  78. export void Files_ReadInt (Files_Rider *R, ADDRESS *R__typ, INT16 *x);
  79. export void Files_ReadLInt (Files_Rider *R, ADDRESS *R__typ, INT32 *x);
  80. export void Files_ReadLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL *x);
  81. export void Files_ReadLine (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  82. export void Files_ReadNum (Files_Rider *R, ADDRESS *R__typ, SYSTEM_BYTE *x, ADDRESS x__len);
  83. export void Files_ReadReal (Files_Rider *R, ADDRESS *R__typ, REAL *x);
  84. export void Files_ReadSet (Files_Rider *R, ADDRESS *R__typ, UINT32 *x);
  85. export void Files_ReadString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  86. export void Files_Register (Files_File f);
  87. export void Files_Rename (CHAR *old, ADDRESS old__len, CHAR *new, ADDRESS new__len, INT16 *res);
  88. static void Files_ScanPath (INT16 *pos, CHAR *dir, ADDRESS dir__len);
  89. export void Files_Set (Files_Rider *r, ADDRESS *r__typ, Files_File f, INT32 pos);
  90. export void Files_SetSearchPath (CHAR *path, ADDRESS path__len);
  91. export void Files_Write (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE x);
  92. export void Files_WriteBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN x);
  93. export void Files_WriteBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n);
  94. export void Files_WriteInt (Files_Rider *R, ADDRESS *R__typ, INT16 x);
  95. export void Files_WriteLInt (Files_Rider *R, ADDRESS *R__typ, INT32 x);
  96. export void Files_WriteLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL x);
  97. export void Files_WriteNum (Files_Rider *R, ADDRESS *R__typ, INT64 x);
  98. export void Files_WriteReal (Files_Rider *R, ADDRESS *R__typ, REAL x);
  99. export void Files_WriteSet (Files_Rider *R, ADDRESS *R__typ, UINT32 x);
  100. export void Files_WriteString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  101. #define Files_IdxTrap() __HALT(-1)
  102. static void Files_Assert (BOOLEAN truth)
  103. {
  104. if (!truth) {
  105. Out_Ln();
  106. __ASSERT(truth, 0);
  107. }
  108. }
  109. static void Files_Err (CHAR *s, ADDRESS s__len, Files_File f, INT16 errcode)
  110. {
  111. __DUP(s, s__len, CHAR);
  112. Out_Ln();
  113. Out_String((CHAR*)"-- ", 4);
  114. Out_String(s, s__len);
  115. Out_String((CHAR*)": ", 3);
  116. if (f != NIL) {
  117. if (f->registerName[0] != 0x00) {
  118. Out_String(f->registerName, 256);
  119. } else {
  120. Out_String(f->workName, 256);
  121. }
  122. if (f->fd != 0) {
  123. Out_String((CHAR*)", f.fd = ", 10);
  124. Out_Int(f->fd, 1);
  125. }
  126. }
  127. if (errcode != 0) {
  128. Out_String((CHAR*)", errcode = ", 13);
  129. Out_Int(errcode, 1);
  130. }
  131. Out_Ln();
  132. __HALT(99);
  133. __DEL(s);
  134. }
  135. static void Files_MakeFileName (CHAR *dir, ADDRESS dir__len, CHAR *name, ADDRESS name__len, CHAR *dest, ADDRESS dest__len)
  136. {
  137. INT16 i, j, ld, ln;
  138. __DUP(dir, dir__len, CHAR);
  139. __DUP(name, name__len, CHAR);
  140. ld = Strings_Length(dir, dir__len);
  141. ln = Strings_Length(name, name__len);
  142. while ((ld > 0 && dir[__X(ld - 1, dir__len)] == '/')) {
  143. ld -= 1;
  144. }
  145. if (((ld + ln) + 2) > dest__len) {
  146. Files_Err((CHAR*)"File name too long", 19, NIL, 0);
  147. }
  148. i = 0;
  149. while (i < ld) {
  150. dest[__X(i, dest__len)] = dir[__X(i, dir__len)];
  151. i += 1;
  152. }
  153. if (i > 0) {
  154. dest[__X(i, dest__len)] = '/';
  155. i += 1;
  156. }
  157. j = 0;
  158. while (j < ln) {
  159. dest[__X(i, dest__len)] = name[__X(j, name__len)];
  160. i += 1;
  161. j += 1;
  162. }
  163. dest[__X(i, dest__len)] = 0x00;
  164. __DEL(dir);
  165. __DEL(name);
  166. }
  167. static void Files_GetTempName (CHAR *finalName, ADDRESS finalName__len, CHAR *name, ADDRESS name__len)
  168. {
  169. INT16 i, n;
  170. __DUP(finalName, finalName__len, CHAR);
  171. if (finalName[0] == '/') {
  172. __COPY(finalName, name, name__len);
  173. } else {
  174. Files_MakeFileName(Platform_CWD, 256, finalName, finalName__len, (void*)name, name__len);
  175. }
  176. i = Strings_Length(name, name__len) - 1;
  177. while ((i > 0 && name[__X(i, name__len)] != '/')) {
  178. i -= 1;
  179. }
  180. if ((i + 16) >= name__len) {
  181. Files_Err((CHAR*)"File name too long", 19, NIL, 0);
  182. }
  183. Files_tempno += 1;
  184. n = Files_tempno;
  185. name[__X(i + 1, name__len)] = '.';
  186. name[__X(i + 2, name__len)] = 't';
  187. name[__X(i + 3, name__len)] = 'm';
  188. name[__X(i + 4, name__len)] = 'p';
  189. name[__X(i + 5, name__len)] = '.';
  190. i += 6;
  191. while (n > 0) {
  192. name[__X(i, name__len)] = __CHR((int)__MOD(n, 10) + 48);
  193. n = __DIV(n, 10);
  194. i += 1;
  195. }
  196. name[__X(i, name__len)] = '.';
  197. i += 1;
  198. n = Platform_PID;
  199. while (n > 0) {
  200. name[__X(i, name__len)] = __CHR((int)__MOD(n, 10) + 48);
  201. n = __DIV(n, 10);
  202. i += 1;
  203. }
  204. name[__X(i, name__len)] = 0x00;
  205. __DEL(finalName);
  206. }
  207. static void Files_Deregister (CHAR *name, ADDRESS name__len)
  208. {
  209. Platform_FileIdentity identity;
  210. Files_File osfile = NIL;
  211. INT16 error;
  212. __DUP(name, name__len, CHAR);
  213. if (Platform_IdentifyByName(name, name__len, &identity, Platform_FileIdentity__typ) == 0) {
  214. osfile = (Files_File)Files_files;
  215. while ((osfile != NIL && !Platform_SameFile(osfile->identity, identity))) {
  216. osfile = (Files_File)osfile->next;
  217. }
  218. if (osfile != NIL) {
  219. __ASSERT(!osfile->tempFile, 0);
  220. __ASSERT(osfile->fd >= 0, 0);
  221. __MOVE(osfile->workName, osfile->registerName, 256);
  222. Files_GetTempName(osfile->registerName, 256, (void*)osfile->workName, 256);
  223. osfile->tempFile = 1;
  224. osfile->state = 0;
  225. error = Platform_Rename((void*)osfile->registerName, 256, (void*)osfile->workName, 256);
  226. if (error != 0) {
  227. Files_Err((CHAR*)"Couldn't rename previous version of file being registered", 58, osfile, error);
  228. }
  229. }
  230. }
  231. __DEL(name);
  232. }
  233. static void Files_Create (Files_File f)
  234. {
  235. BOOLEAN done;
  236. INT16 error;
  237. CHAR err[32];
  238. if (f->fd == -1) {
  239. if (f->state == 1) {
  240. Files_GetTempName(f->registerName, 256, (void*)f->workName, 256);
  241. f->tempFile = 1;
  242. } else {
  243. __ASSERT(f->state == 2, 0);
  244. Files_Deregister(f->registerName, 256);
  245. __MOVE(f->registerName, f->workName, 256);
  246. f->registerName[0] = 0x00;
  247. f->tempFile = 0;
  248. }
  249. error = Platform_Unlink((void*)f->workName, 256);
  250. error = Platform_New((void*)f->workName, 256, &f->fd);
  251. done = error == 0;
  252. if (done) {
  253. f->next = Files_files;
  254. Files_files = f;
  255. Heap_FileCount += 1;
  256. Heap_RegisterFinalizer((void*)f, Files_Finalize);
  257. f->state = 0;
  258. f->pos = 0;
  259. error = Platform_Identify(f->fd, &f->identity, Platform_FileIdentity__typ);
  260. } else {
  261. if (Platform_NoSuchDirectory(error)) {
  262. __MOVE("no such directory", err, 18);
  263. } else if (Platform_TooManyFiles(error)) {
  264. __MOVE("too many files open", err, 20);
  265. } else {
  266. __MOVE("file not created", err, 17);
  267. }
  268. Files_Err(err, 32, f, error);
  269. }
  270. }
  271. }
  272. static void Files_Flush (Files_Buffer buf)
  273. {
  274. INT16 error;
  275. Files_File f = NIL;
  276. if (buf->chg) {
  277. f = buf->f;
  278. Files_Create(f);
  279. if (buf->org != f->pos) {
  280. error = Platform_Seek(f->fd, buf->org, Platform_SeekSet);
  281. }
  282. error = Platform_Write(f->fd, (ADDRESS)buf->data, buf->size);
  283. if (error != 0) {
  284. Files_Err((CHAR*)"error writing file", 19, f, error);
  285. }
  286. f->pos = buf->org + buf->size;
  287. buf->chg = 0;
  288. error = Platform_Identify(f->fd, &f->identity, Platform_FileIdentity__typ);
  289. if (error != 0) {
  290. Files_Err((CHAR*)"error identifying file", 23, f, error);
  291. }
  292. }
  293. }
  294. void Files_Close (Files_File f)
  295. {
  296. INT32 i;
  297. INT16 error;
  298. if (f->state != 1 || f->registerName[0] != 0x00) {
  299. Files_Create(f);
  300. i = 0;
  301. while ((i < 4 && f->bufs[__X(i, 4)] != NIL)) {
  302. Files_Flush(f->bufs[__X(i, 4)]);
  303. i += 1;
  304. }
  305. }
  306. }
  307. INT32 Files_Length (Files_File f)
  308. {
  309. return f->len;
  310. }
  311. Files_File Files_New (CHAR *name, ADDRESS name__len)
  312. {
  313. Files_File f = NIL;
  314. __DUP(name, name__len, CHAR);
  315. __NEW(f, Files_FileDesc);
  316. f->workName[0] = 0x00;
  317. __COPY(name, f->registerName, 256);
  318. f->fd = -1;
  319. f->state = 1;
  320. f->len = 0;
  321. f->pos = 0;
  322. f->swapper = -1;
  323. __DEL(name);
  324. return f;
  325. }
  326. static void Files_ScanPath (INT16 *pos, CHAR *dir, ADDRESS dir__len)
  327. {
  328. INT16 i;
  329. CHAR ch;
  330. i = 0;
  331. if (Files_SearchPath == NIL) {
  332. if (*pos == 0) {
  333. dir[0] = '.';
  334. i = 1;
  335. *pos += 1;
  336. }
  337. } else {
  338. ch = (Files_SearchPath->data)[__X(*pos, Files_SearchPath->len[0])];
  339. while (ch == ' ' || ch == ';') {
  340. *pos += 1;
  341. ch = (Files_SearchPath->data)[__X(*pos, Files_SearchPath->len[0])];
  342. }
  343. if (ch == '~') {
  344. *pos += 1;
  345. ch = (Files_SearchPath->data)[__X(*pos, Files_SearchPath->len[0])];
  346. while (Files_HOME[__X(i, 1024)] != 0x00) {
  347. dir[__X(i, dir__len)] = Files_HOME[__X(i, 1024)];
  348. i += 1;
  349. }
  350. if ((((((ch != '/' && ch != 0x00)) && ch != ';')) && ch != ' ')) {
  351. while ((i > 0 && dir[__X(i - 1, dir__len)] != '/')) {
  352. i -= 1;
  353. }
  354. }
  355. }
  356. while ((ch != 0x00 && ch != ';')) {
  357. dir[__X(i, dir__len)] = ch;
  358. i += 1;
  359. *pos += 1;
  360. ch = (Files_SearchPath->data)[__X(*pos, Files_SearchPath->len[0])];
  361. }
  362. while ((i > 0 && dir[__X(i - 1, dir__len)] == ' ')) {
  363. i -= 1;
  364. }
  365. }
  366. dir[__X(i, dir__len)] = 0x00;
  367. }
  368. static BOOLEAN Files_HasDir (CHAR *name, ADDRESS name__len)
  369. {
  370. INT16 i;
  371. CHAR ch;
  372. i = 0;
  373. ch = name[0];
  374. while ((ch != 0x00 && ch != '/')) {
  375. i += 1;
  376. ch = name[__X(i, name__len)];
  377. }
  378. return ch == '/';
  379. }
  380. static Files_File Files_CacheEntry (Platform_FileIdentity identity)
  381. {
  382. Files_File f = NIL;
  383. INT16 i, error;
  384. f = (Files_File)Files_files;
  385. while (f != NIL) {
  386. if (Platform_SameFile(identity, f->identity)) {
  387. if (!Platform_SameFileTime(identity, f->identity)) {
  388. i = 0;
  389. while (i < 4) {
  390. if (f->bufs[__X(i, 4)] != NIL) {
  391. f->bufs[__X(i, 4)]->org = -1;
  392. f->bufs[__X(i, 4)] = NIL;
  393. }
  394. i += 1;
  395. }
  396. f->swapper = -1;
  397. f->identity = identity;
  398. error = Platform_Size(f->fd, &f->len);
  399. }
  400. return f;
  401. }
  402. f = (Files_File)f->next;
  403. }
  404. return NIL;
  405. }
  406. Files_File Files_Old (CHAR *name, ADDRESS name__len)
  407. {
  408. Files_File f = NIL;
  409. INT32 fd;
  410. INT16 pos;
  411. BOOLEAN done;
  412. CHAR dir[256], path[256];
  413. INT16 error;
  414. Platform_FileIdentity identity;
  415. __DUP(name, name__len, CHAR);
  416. if (name[0] != 0x00) {
  417. if (Files_HasDir((void*)name, name__len)) {
  418. dir[0] = 0x00;
  419. __COPY(name, path, 256);
  420. } else {
  421. pos = 0;
  422. Files_ScanPath(&pos, (void*)dir, 256);
  423. Files_MakeFileName(dir, 256, name, name__len, (void*)path, 256);
  424. Files_ScanPath(&pos, (void*)dir, 256);
  425. }
  426. for (;;) {
  427. error = Platform_OldRW((void*)path, 256, &fd);
  428. done = error == 0;
  429. if ((!done && Platform_TooManyFiles(error))) {
  430. Files_Err((CHAR*)"too many files open", 20, f, error);
  431. }
  432. if ((!done && Platform_Inaccessible(error))) {
  433. error = Platform_OldRO((void*)path, 256, &fd);
  434. done = error == 0;
  435. }
  436. if ((!done && !Platform_Absent(error))) {
  437. Out_String((CHAR*)"Warning: Files.Old ", 20);
  438. Out_String(name, name__len);
  439. Out_String((CHAR*)" error = ", 10);
  440. Out_Int(error, 0);
  441. Out_Ln();
  442. }
  443. if (done) {
  444. error = Platform_Identify(fd, &identity, Platform_FileIdentity__typ);
  445. f = Files_CacheEntry(identity);
  446. if (f != NIL) {
  447. error = Platform_Close(fd);
  448. __DEL(name);
  449. return f;
  450. } else {
  451. __NEW(f, Files_FileDesc);
  452. Heap_RegisterFinalizer((void*)f, Files_Finalize);
  453. f->fd = fd;
  454. f->state = 0;
  455. f->pos = 0;
  456. f->swapper = -1;
  457. error = Platform_Size(fd, &f->len);
  458. __COPY(name, f->workName, 256);
  459. f->registerName[0] = 0x00;
  460. f->tempFile = 0;
  461. f->identity = identity;
  462. f->next = Files_files;
  463. Files_files = f;
  464. Heap_FileCount += 1;
  465. __DEL(name);
  466. return f;
  467. }
  468. } else if (dir[0] == 0x00) {
  469. __DEL(name);
  470. return NIL;
  471. } else {
  472. Files_MakeFileName(dir, 256, name, name__len, (void*)path, 256);
  473. Files_ScanPath(&pos, (void*)dir, 256);
  474. }
  475. }
  476. } else {
  477. __DEL(name);
  478. return NIL;
  479. }
  480. __RETCHK;
  481. }
  482. void Files_Purge (Files_File f)
  483. {
  484. INT16 i;
  485. Platform_FileIdentity identity;
  486. INT16 error;
  487. i = 0;
  488. while (i < 4) {
  489. if (f->bufs[__X(i, 4)] != NIL) {
  490. f->bufs[__X(i, 4)]->org = -1;
  491. f->bufs[__X(i, 4)] = NIL;
  492. }
  493. i += 1;
  494. }
  495. if (f->fd != -1) {
  496. error = Platform_Truncate(f->fd, 0);
  497. error = Platform_Seek(f->fd, 0, Platform_SeekSet);
  498. }
  499. f->pos = 0;
  500. f->len = 0;
  501. f->swapper = -1;
  502. error = Platform_Identify(f->fd, &identity, Platform_FileIdentity__typ);
  503. Platform_SetMTime(&f->identity, Platform_FileIdentity__typ, identity);
  504. }
  505. void Files_GetDate (Files_File f, INT32 *t, INT32 *d)
  506. {
  507. Platform_FileIdentity identity;
  508. INT16 error;
  509. Files_Create(f);
  510. error = Platform_Identify(f->fd, &identity, Platform_FileIdentity__typ);
  511. Platform_MTimeAsClock(identity, &*t, &*d);
  512. }
  513. INT32 Files_Pos (Files_Rider *r, ADDRESS *r__typ)
  514. {
  515. Files_Assert((*r).offset <= 4096);
  516. return (*r).org + (*r).offset;
  517. }
  518. void Files_Set (Files_Rider *r, ADDRESS *r__typ, Files_File f, INT32 pos)
  519. {
  520. INT32 org, offset, i, n;
  521. Files_Buffer buf = NIL;
  522. INT16 error;
  523. if (f != NIL) {
  524. if (pos > f->len) {
  525. pos = f->len;
  526. } else if (pos < 0) {
  527. pos = 0;
  528. }
  529. offset = __MASK(pos, -4096);
  530. org = pos - offset;
  531. i = 0;
  532. while ((((i < 4 && f->bufs[__X(i, 4)] != NIL)) && org != f->bufs[__X(i, 4)]->org)) {
  533. i += 1;
  534. }
  535. if (i < 4) {
  536. if (f->bufs[__X(i, 4)] == NIL) {
  537. __NEW(buf, Files_BufDesc);
  538. buf->chg = 0;
  539. buf->org = -1;
  540. buf->f = f;
  541. f->bufs[__X(i, 4)] = buf;
  542. } else {
  543. buf = f->bufs[__X(i, 4)];
  544. }
  545. } else {
  546. f->swapper = __MASK(f->swapper + 1, -4);
  547. buf = f->bufs[__X(f->swapper, 4)];
  548. Files_Flush(buf);
  549. }
  550. if (buf->org != org) {
  551. if (org == f->len) {
  552. buf->size = 0;
  553. } else {
  554. Files_Create(f);
  555. if (f->pos != org) {
  556. error = Platform_Seek(f->fd, org, Platform_SeekSet);
  557. }
  558. error = Platform_ReadBuf(f->fd, (void*)buf->data, 4096, &n);
  559. if (error != 0) {
  560. Files_Err((CHAR*)"read from file not done", 24, f, error);
  561. }
  562. f->pos = org + n;
  563. buf->size = n;
  564. }
  565. buf->org = org;
  566. buf->chg = 0;
  567. }
  568. } else {
  569. buf = NIL;
  570. org = 0;
  571. offset = 0;
  572. }
  573. Files_Assert(offset <= 4096);
  574. (*r).buf = buf;
  575. (*r).org = org;
  576. (*r).offset = offset;
  577. (*r).eof = 0;
  578. (*r).res = 0;
  579. }
  580. void Files_Read (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x)
  581. {
  582. INT32 offset;
  583. Files_Buffer buf = NIL;
  584. buf = (*r).buf;
  585. offset = (*r).offset;
  586. if ((*r).org != buf->org) {
  587. Files_Set(&*r, r__typ, buf->f, (*r).org + offset);
  588. buf = (*r).buf;
  589. offset = (*r).offset;
  590. }
  591. Files_Assert(offset <= buf->size);
  592. if (offset < buf->size) {
  593. *x = buf->data[__X(offset, 4096)];
  594. (*r).offset = offset + 1;
  595. } else if ((*r).org + offset < buf->f->len) {
  596. Files_Set(&*r, r__typ, (*r).buf->f, (*r).org + offset);
  597. *x = (*r).buf->data[0];
  598. (*r).offset = 1;
  599. } else {
  600. *x = 0x00;
  601. (*r).eof = 1;
  602. }
  603. }
  604. void Files_ReadBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n)
  605. {
  606. INT32 xpos, min, restInBuf, offset;
  607. Files_Buffer buf = NIL;
  608. if (n > x__len) {
  609. Files_IdxTrap();
  610. }
  611. xpos = 0;
  612. buf = (*r).buf;
  613. offset = (*r).offset;
  614. while (n > 0) {
  615. if ((*r).org != buf->org || offset >= 4096) {
  616. Files_Set(&*r, r__typ, buf->f, (*r).org + offset);
  617. buf = (*r).buf;
  618. offset = (*r).offset;
  619. }
  620. restInBuf = buf->size - offset;
  621. if (restInBuf == 0) {
  622. (*r).res = n;
  623. (*r).eof = 1;
  624. return;
  625. } else if (n > restInBuf) {
  626. min = restInBuf;
  627. } else {
  628. min = n;
  629. }
  630. __MOVE((ADDRESS)&buf->data[__X(offset, 4096)], (ADDRESS)&x[__X(xpos, x__len)], min);
  631. offset += min;
  632. (*r).offset = offset;
  633. xpos += min;
  634. n -= min;
  635. Files_Assert(offset <= 4096);
  636. }
  637. (*r).res = 0;
  638. (*r).eof = 0;
  639. }
  640. Files_File Files_Base (Files_Rider *r, ADDRESS *r__typ)
  641. {
  642. return (*r).buf->f;
  643. }
  644. void Files_Write (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE x)
  645. {
  646. Files_Buffer buf = NIL;
  647. INT32 offset;
  648. buf = (*r).buf;
  649. offset = (*r).offset;
  650. Files_Assert(offset <= 4096);
  651. if ((*r).org != buf->org || offset >= 4096) {
  652. Files_Set(&*r, r__typ, buf->f, (*r).org + offset);
  653. buf = (*r).buf;
  654. offset = (*r).offset;
  655. }
  656. Files_Assert(offset < 4096);
  657. buf->data[__X(offset, 4096)] = x;
  658. buf->chg = 1;
  659. if (offset == buf->size) {
  660. buf->size += 1;
  661. buf->f->len += 1;
  662. }
  663. (*r).offset = offset + 1;
  664. (*r).res = 0;
  665. }
  666. void Files_WriteBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n)
  667. {
  668. INT32 xpos, min, restInBuf, offset;
  669. Files_Buffer buf = NIL;
  670. if (n > x__len) {
  671. Files_IdxTrap();
  672. }
  673. xpos = 0;
  674. buf = (*r).buf;
  675. offset = (*r).offset;
  676. while (n > 0) {
  677. Files_Assert(offset <= 4096);
  678. if ((*r).org != buf->org || offset >= 4096) {
  679. Files_Set(&*r, r__typ, buf->f, (*r).org + offset);
  680. buf = (*r).buf;
  681. offset = (*r).offset;
  682. }
  683. Files_Assert(offset <= 4096);
  684. restInBuf = 4096 - offset;
  685. if (n > restInBuf) {
  686. min = restInBuf;
  687. } else {
  688. min = n;
  689. }
  690. __MOVE((ADDRESS)&x[__X(xpos, x__len)], (ADDRESS)&buf->data[__X(offset, 4096)], min);
  691. offset += min;
  692. (*r).offset = offset;
  693. Files_Assert(offset <= 4096);
  694. if (offset > buf->size) {
  695. buf->f->len += offset - buf->size;
  696. buf->size = offset;
  697. }
  698. xpos += min;
  699. n -= min;
  700. buf->chg = 1;
  701. }
  702. (*r).res = 0;
  703. }
  704. void Files_Delete (CHAR *name, ADDRESS name__len, INT16 *res)
  705. {
  706. __DUP(name, name__len, CHAR);
  707. Files_Deregister(name, name__len);
  708. *res = Platform_Unlink((void*)name, name__len);
  709. __DEL(name);
  710. }
  711. void Files_Rename (CHAR *old, ADDRESS old__len, CHAR *new, ADDRESS new__len, INT16 *res)
  712. {
  713. INT32 fdold, fdnew, n;
  714. INT16 error, ignore;
  715. Platform_FileIdentity oldidentity, newidentity;
  716. CHAR buf[4096];
  717. __DUP(old, old__len, CHAR);
  718. __DUP(new, new__len, CHAR);
  719. error = Platform_IdentifyByName(old, old__len, &oldidentity, Platform_FileIdentity__typ);
  720. if (error == 0) {
  721. error = Platform_IdentifyByName(new, new__len, &newidentity, Platform_FileIdentity__typ);
  722. if ((error != 0 && !Platform_SameFile(oldidentity, newidentity))) {
  723. Files_Delete(new, new__len, &error);
  724. }
  725. error = Platform_Rename((void*)old, old__len, (void*)new, new__len);
  726. if (!Platform_DifferentFilesystems(error)) {
  727. *res = error;
  728. __DEL(old);
  729. __DEL(new);
  730. return;
  731. } else {
  732. error = Platform_OldRO((void*)old, old__len, &fdold);
  733. if (error != 0) {
  734. *res = 2;
  735. __DEL(old);
  736. __DEL(new);
  737. return;
  738. }
  739. error = Platform_New((void*)new, new__len, &fdnew);
  740. if (error != 0) {
  741. error = Platform_Close(fdold);
  742. *res = 3;
  743. __DEL(old);
  744. __DEL(new);
  745. return;
  746. }
  747. error = Platform_Read(fdold, (ADDRESS)buf, 4096, &n);
  748. while (n > 0) {
  749. error = Platform_Write(fdnew, (ADDRESS)buf, n);
  750. if (error != 0) {
  751. ignore = Platform_Close(fdold);
  752. ignore = Platform_Close(fdnew);
  753. Files_Err((CHAR*)"cannot move file", 17, NIL, error);
  754. }
  755. error = Platform_Read(fdold, (ADDRESS)buf, 4096, &n);
  756. }
  757. ignore = Platform_Close(fdold);
  758. ignore = Platform_Close(fdnew);
  759. if (n == 0) {
  760. error = Platform_Unlink((void*)old, old__len);
  761. *res = 0;
  762. } else {
  763. Files_Err((CHAR*)"cannot move file", 17, NIL, error);
  764. }
  765. }
  766. } else {
  767. *res = 2;
  768. }
  769. __DEL(old);
  770. __DEL(new);
  771. }
  772. void Files_Register (Files_File f)
  773. {
  774. INT16 idx, errcode;
  775. Files_File f1 = NIL;
  776. if ((f->state == 1 && f->registerName[0] != 0x00)) {
  777. f->state = 2;
  778. }
  779. Files_Close(f);
  780. if (f->registerName[0] != 0x00) {
  781. Files_Deregister(f->registerName, 256);
  782. Files_Rename(f->workName, 256, f->registerName, 256, &errcode);
  783. if (errcode != 0) {
  784. Files_Err((CHAR*)"Couldn't rename temp name as register name", 43, f, errcode);
  785. }
  786. __MOVE(f->registerName, f->workName, 256);
  787. f->registerName[0] = 0x00;
  788. f->tempFile = 0;
  789. }
  790. }
  791. void Files_ChangeDirectory (CHAR *path, ADDRESS path__len, INT16 *res)
  792. {
  793. __DUP(path, path__len, CHAR);
  794. *res = Platform_Chdir((void*)path, path__len);
  795. __DEL(path);
  796. }
  797. static void Files_FlipBytes (SYSTEM_BYTE *src, ADDRESS src__len, SYSTEM_BYTE *dest, ADDRESS dest__len)
  798. {
  799. INT32 i, j;
  800. if (!Platform_LittleEndian) {
  801. i = src__len;
  802. j = 0;
  803. while (i > 0) {
  804. i -= 1;
  805. dest[__X(j, dest__len)] = src[__X(i, src__len)];
  806. j += 1;
  807. }
  808. } else {
  809. __MOVE((ADDRESS)src, (ADDRESS)dest, src__len);
  810. }
  811. }
  812. void Files_ReadBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN *x)
  813. {
  814. Files_Read(&*R, R__typ, (CHAR*)(void*)&*x);
  815. }
  816. void Files_ReadInt (Files_Rider *R, ADDRESS *R__typ, INT16 *x)
  817. {
  818. CHAR b[2];
  819. Files_ReadBytes(&*R, R__typ, (void*)b, 2, 2);
  820. *x = (INT16)b[0] + __ASHL((INT16)b[1], 8);
  821. }
  822. void Files_ReadLInt (Files_Rider *R, ADDRESS *R__typ, INT32 *x)
  823. {
  824. CHAR b[4];
  825. Files_ReadBytes(&*R, R__typ, (void*)b, 4, 4);
  826. *x = (((INT16)b[0] + __ASHL((INT16)b[1], 8)) + __ASHL(b[2], 16)) + __ASHL(b[3], 24);
  827. }
  828. void Files_ReadSet (Files_Rider *R, ADDRESS *R__typ, UINT32 *x)
  829. {
  830. CHAR b[4];
  831. INT32 l;
  832. Files_ReadBytes(&*R, R__typ, (void*)b, 4, 4);
  833. l = (((INT16)b[0] + __ASHL((INT16)b[1], 8)) + __ASHL(b[2], 16)) + __ASHL(b[3], 24);
  834. *x = (UINT32)l;
  835. }
  836. void Files_ReadReal (Files_Rider *R, ADDRESS *R__typ, REAL *x)
  837. {
  838. CHAR b[4];
  839. Files_ReadBytes(&*R, R__typ, (void*)b, 4, 4);
  840. Files_FlipBytes((void*)b, 4, (void*)&*x, 4);
  841. }
  842. void Files_ReadLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL *x)
  843. {
  844. CHAR b[8];
  845. Files_ReadBytes(&*R, R__typ, (void*)b, 8, 8);
  846. Files_FlipBytes((void*)b, 8, (void*)&*x, 8);
  847. }
  848. void Files_ReadString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len)
  849. {
  850. INT16 i;
  851. CHAR ch;
  852. i = 0;
  853. do {
  854. Files_Read(&*R, R__typ, (void*)&ch);
  855. x[__X(i, x__len)] = ch;
  856. i += 1;
  857. } while (!(ch == 0x00));
  858. }
  859. void Files_ReadLine (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len)
  860. {
  861. INT16 i;
  862. i = 0;
  863. do {
  864. Files_Read(&*R, R__typ, (void*)&x[__X(i, x__len)]);
  865. i += 1;
  866. } while (!(x[__X(i - 1, x__len)] == 0x00 || x[__X(i - 1, x__len)] == 0x0a));
  867. if (x[__X(i - 1, x__len)] == 0x0a) {
  868. i -= 1;
  869. }
  870. if ((i > 0 && x[__X(i - 1, x__len)] == 0x0d)) {
  871. i -= 1;
  872. }
  873. x[__X(i, x__len)] = 0x00;
  874. }
  875. void Files_ReadNum (Files_Rider *R, ADDRESS *R__typ, SYSTEM_BYTE *x, ADDRESS x__len)
  876. {
  877. INT8 s, b;
  878. INT64 q;
  879. s = 0;
  880. q = 0;
  881. Files_Read(&*R, R__typ, (void*)&b);
  882. while (b < 0) {
  883. q += (INT64)__ASH(((INT16)b + 128), s);
  884. s += 7;
  885. Files_Read(&*R, R__typ, (void*)&b);
  886. }
  887. q += (INT64)__ASH((__MASK(b, -64) - __ASHL(__ASHR(b, 6), 6)), s);
  888. Files_Assert(x__len <= 8);
  889. __MOVE((ADDRESS)&q, (ADDRESS)x, x__len);
  890. }
  891. void Files_WriteBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN x)
  892. {
  893. Files_Write(&*R, R__typ, __VAL(CHAR, x));
  894. }
  895. void Files_WriteInt (Files_Rider *R, ADDRESS *R__typ, INT16 x)
  896. {
  897. CHAR b[2];
  898. b[0] = __CHR(x);
  899. b[1] = __CHR(__ASHR(x, 8));
  900. Files_WriteBytes(&*R, R__typ, (void*)b, 2, 2);
  901. }
  902. void Files_WriteLInt (Files_Rider *R, ADDRESS *R__typ, INT32 x)
  903. {
  904. CHAR b[4];
  905. b[0] = __CHR(x);
  906. b[1] = __CHR(__ASHR(x, 8));
  907. b[2] = __CHR(__ASHR(x, 16));
  908. b[3] = __CHR(__ASHR(x, 24));
  909. Files_WriteBytes(&*R, R__typ, (void*)b, 4, 4);
  910. }
  911. void Files_WriteSet (Files_Rider *R, ADDRESS *R__typ, UINT32 x)
  912. {
  913. CHAR b[4];
  914. INT32 i;
  915. UINT64 y;
  916. y = x;
  917. i = __VAL(INT32, y);
  918. b[0] = __CHR(i);
  919. b[1] = __CHR(__ASHR(i, 8));
  920. b[2] = __CHR(__ASHR(i, 16));
  921. b[3] = __CHR(__ASHR(i, 24));
  922. Files_WriteBytes(&*R, R__typ, (void*)b, 4, 4);
  923. }
  924. void Files_WriteReal (Files_Rider *R, ADDRESS *R__typ, REAL x)
  925. {
  926. CHAR b[4];
  927. Files_FlipBytes((void*)&x, 4, (void*)b, 4);
  928. Files_WriteBytes(&*R, R__typ, (void*)b, 4, 4);
  929. }
  930. void Files_WriteLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL x)
  931. {
  932. CHAR b[8];
  933. Files_FlipBytes((void*)&x, 8, (void*)b, 8);
  934. Files_WriteBytes(&*R, R__typ, (void*)b, 8, 8);
  935. }
  936. void Files_WriteString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len)
  937. {
  938. INT16 i;
  939. i = 0;
  940. while (x[__X(i, x__len)] != 0x00) {
  941. i += 1;
  942. }
  943. Files_WriteBytes(&*R, R__typ, (void*)x, x__len * 1, i + 1);
  944. }
  945. void Files_WriteNum (Files_Rider *R, ADDRESS *R__typ, INT64 x)
  946. {
  947. while (x < -64 || x > 63) {
  948. Files_Write(&*R, R__typ, __CHR(__MASK(x, -128) + 128));
  949. x = __ASHR(x, 7);
  950. }
  951. Files_Write(&*R, R__typ, __CHR(__MASK(x, -128)));
  952. }
  953. void Files_GetName (Files_File f, CHAR *name, ADDRESS name__len)
  954. {
  955. __COPY(f->workName, name, name__len);
  956. }
  957. static void Files_CloseOSFile (Files_File f)
  958. {
  959. Files_File prev = NIL;
  960. INT16 error;
  961. if (Files_files == (void *) f) {
  962. Files_files = f->next;
  963. } else {
  964. prev = (Files_File)Files_files;
  965. while ((prev != NIL && prev->next != (void *) f)) {
  966. prev = (Files_File)prev->next;
  967. }
  968. if (prev->next != NIL) {
  969. prev->next = f->next;
  970. }
  971. }
  972. error = Platform_Close(f->fd);
  973. f->fd = -1;
  974. f->state = 1;
  975. Heap_FileCount -= 1;
  976. }
  977. static void Files_Finalize (SYSTEM_PTR o)
  978. {
  979. Files_File f = NIL;
  980. INT32 res;
  981. f = (Files_File)(ADDRESS)o;
  982. if (f->fd >= 0) {
  983. Files_CloseOSFile(f);
  984. if (f->tempFile) {
  985. res = Platform_Unlink((void*)f->workName, 256);
  986. }
  987. }
  988. }
  989. void Files_SetSearchPath (CHAR *path, ADDRESS path__len)
  990. {
  991. __DUP(path, path__len, CHAR);
  992. if (Strings_Length(path, path__len) != 0) {
  993. Files_SearchPath = __NEWARR(NIL, 1, 1, 1, 1, ((ADDRESS)((Strings_Length(path, path__len) + 1))));
  994. __COPY(path, Files_SearchPath->data, Files_SearchPath->len[0]);
  995. } else {
  996. Files_SearchPath = NIL;
  997. }
  998. __DEL(path);
  999. }
  1000. static void EnumPtrs(void (*P)(void*))
  1001. {
  1002. P(Files_SearchPath);
  1003. }
  1004. __TDESC(Files_FileDesc, 1, 4) = {__TDFLDS("FileDesc", 564), {540, 544, 548, 552, -20}};
  1005. __TDESC(Files_BufDesc, 1, 1) = {__TDFLDS("BufDesc", 4112), {0, -8}};
  1006. __TDESC(Files_Rider, 1, 1) = {__TDFLDS("Rider", 20), {8, -8}};
  1007. export void *Files__init(void)
  1008. {
  1009. __DEFMOD;
  1010. __MODULE_IMPORT(Heap);
  1011. __MODULE_IMPORT(Out);
  1012. __MODULE_IMPORT(Platform);
  1013. __MODULE_IMPORT(Strings);
  1014. __REGMOD("Files", EnumPtrs);
  1015. __INITYP(Files_FileDesc, Files_FileDesc, 0);
  1016. __INITYP(Files_BufDesc, Files_BufDesc, 0);
  1017. __INITYP(Files_Rider, Files_Rider, 0);
  1018. /* BEGIN */
  1019. Files_tempno = -1;
  1020. Heap_FileCount = 0;
  1021. Files_HOME[0] = 0x00;
  1022. Platform_GetEnv((CHAR*)"HOME", 5, (void*)Files_HOME, 1024);
  1023. Files_MaxPathLength = Platform_MaxPathLength();
  1024. Files_MaxNameLength = Platform_MaxNameLength();
  1025. __ENDMOD;
  1026. }