Files.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /* voc 2.1.0 [2017/07/20]. Bootstrapping compiler for address size 8, alignment 8. tspaSF */
  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[101];
  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. static Files_FileDesc *Files_files;
  42. static INT16 Files_tempno;
  43. static CHAR Files_HOME[1024];
  44. static struct {
  45. ADDRESS len[1];
  46. CHAR data[1];
  47. } *Files_SearchPath;
  48. export ADDRESS *Files_FileDesc__typ;
  49. export ADDRESS *Files_BufDesc__typ;
  50. export ADDRESS *Files_Rider__typ;
  51. static void Files_Assert (BOOLEAN truth);
  52. export Files_File Files_Base (Files_Rider *r, ADDRESS *r__typ);
  53. static Files_File Files_CacheEntry (Platform_FileIdentity identity);
  54. export void Files_ChangeDirectory (CHAR *path, ADDRESS path__len, INT16 *res);
  55. export void Files_Close (Files_File f);
  56. static void Files_CloseOSFile (Files_File f);
  57. static void Files_Create (Files_File f);
  58. export void Files_Delete (CHAR *name, ADDRESS name__len, INT16 *res);
  59. static void Files_Deregister (CHAR *name, ADDRESS name__len);
  60. static void Files_Err (CHAR *s, ADDRESS s__len, Files_File f, INT16 errcode);
  61. static void Files_Finalize (SYSTEM_PTR o);
  62. static void Files_FlipBytes (SYSTEM_BYTE *src, ADDRESS src__len, SYSTEM_BYTE *dest, ADDRESS dest__len);
  63. static void Files_Flush (Files_Buffer buf);
  64. export void Files_GetDate (Files_File f, INT32 *t, INT32 *d);
  65. export void Files_GetName (Files_File f, CHAR *name, ADDRESS name__len);
  66. static void Files_GetTempName (CHAR *finalName, ADDRESS finalName__len, CHAR *name, ADDRESS name__len);
  67. static BOOLEAN Files_HasDir (CHAR *name, ADDRESS name__len);
  68. export INT32 Files_Length (Files_File f);
  69. static void Files_MakeFileName (CHAR *dir, ADDRESS dir__len, CHAR *name, ADDRESS name__len, CHAR *dest, ADDRESS dest__len);
  70. export Files_File Files_New (CHAR *name, ADDRESS name__len);
  71. export Files_File Files_Old (CHAR *name, ADDRESS name__len);
  72. export INT32 Files_Pos (Files_Rider *r, ADDRESS *r__typ);
  73. export void Files_Purge (Files_File f);
  74. export void Files_Read (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x);
  75. export void Files_ReadBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN *x);
  76. export void Files_ReadBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n);
  77. export void Files_ReadInt (Files_Rider *R, ADDRESS *R__typ, INT16 *x);
  78. export void Files_ReadLInt (Files_Rider *R, ADDRESS *R__typ, INT32 *x);
  79. export void Files_ReadLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL *x);
  80. export void Files_ReadLine (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  81. export void Files_ReadNum (Files_Rider *R, ADDRESS *R__typ, SYSTEM_BYTE *x, ADDRESS x__len);
  82. export void Files_ReadReal (Files_Rider *R, ADDRESS *R__typ, REAL *x);
  83. export void Files_ReadSet (Files_Rider *R, ADDRESS *R__typ, UINT32 *x);
  84. export void Files_ReadString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  85. export void Files_Register (Files_File f);
  86. export void Files_Rename (CHAR *old, ADDRESS old__len, CHAR *new, ADDRESS new__len, INT16 *res);
  87. static void Files_ScanPath (INT16 *pos, CHAR *dir, ADDRESS dir__len);
  88. export void Files_Set (Files_Rider *r, ADDRESS *r__typ, Files_File f, INT32 pos);
  89. export void Files_SetSearchPath (CHAR *path, ADDRESS path__len);
  90. export void Files_Write (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE x);
  91. export void Files_WriteBool (Files_Rider *R, ADDRESS *R__typ, BOOLEAN x);
  92. export void Files_WriteBytes (Files_Rider *r, ADDRESS *r__typ, SYSTEM_BYTE *x, ADDRESS x__len, INT32 n);
  93. export void Files_WriteInt (Files_Rider *R, ADDRESS *R__typ, INT16 x);
  94. export void Files_WriteLInt (Files_Rider *R, ADDRESS *R__typ, INT32 x);
  95. export void Files_WriteLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL x);
  96. export void Files_WriteNum (Files_Rider *R, ADDRESS *R__typ, INT64 x);
  97. export void Files_WriteReal (Files_Rider *R, ADDRESS *R__typ, REAL x);
  98. export void Files_WriteSet (Files_Rider *R, ADDRESS *R__typ, UINT32 x);
  99. export void Files_WriteString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len);
  100. #define Files_IdxTrap() __HALT(-1)
  101. static void Files_Assert (BOOLEAN truth)
  102. {
  103. if (!truth) {
  104. Out_Ln();
  105. __ASSERT(truth, 0);
  106. }
  107. }
  108. static void Files_Err (CHAR *s, ADDRESS s__len, Files_File f, INT16 errcode)
  109. {
  110. __DUP(s, s__len, CHAR);
  111. Out_Ln();
  112. Out_String((CHAR*)"-- ", 4);
  113. Out_String(s, s__len);
  114. Out_String((CHAR*)": ", 3);
  115. if (f != NIL) {
  116. if (f->registerName[0] != 0x00) {
  117. Out_String(f->registerName, 101);
  118. } else {
  119. Out_String(f->workName, 101);
  120. }
  121. if (f->fd != 0) {
  122. Out_String((CHAR*)"f.fd = ", 8);
  123. Out_Int(f->fd, 1);
  124. }
  125. }
  126. if (errcode != 0) {
  127. Out_String((CHAR*)" errcode = ", 12);
  128. Out_Int(errcode, 1);
  129. }
  130. Out_Ln();
  131. __HALT(99);
  132. __DEL(s);
  133. }
  134. static void Files_MakeFileName (CHAR *dir, ADDRESS dir__len, CHAR *name, ADDRESS name__len, CHAR *dest, ADDRESS dest__len)
  135. {
  136. INT16 i, j;
  137. __DUP(dir, dir__len, CHAR);
  138. __DUP(name, name__len, CHAR);
  139. i = 0;
  140. j = 0;
  141. while (dir[i] != 0x00) {
  142. dest[i] = dir[i];
  143. i += 1;
  144. }
  145. if (dest[i - 1] != '/') {
  146. dest[i] = '/';
  147. i += 1;
  148. }
  149. while (name[j] != 0x00) {
  150. dest[i] = name[j];
  151. i += 1;
  152. j += 1;
  153. }
  154. dest[i] = 0x00;
  155. __DEL(dir);
  156. __DEL(name);
  157. }
  158. static void Files_GetTempName (CHAR *finalName, ADDRESS finalName__len, CHAR *name, ADDRESS name__len)
  159. {
  160. INT32 n, i, j;
  161. __DUP(finalName, finalName__len, CHAR);
  162. Files_tempno += 1;
  163. n = Files_tempno;
  164. i = 0;
  165. if (finalName[0] != '/') {
  166. while (Platform_CWD[i] != 0x00) {
  167. name[i] = Platform_CWD[i];
  168. i += 1;
  169. }
  170. if (Platform_CWD[i - 1] != '/') {
  171. name[i] = '/';
  172. i += 1;
  173. }
  174. }
  175. j = 0;
  176. while (finalName[j] != 0x00) {
  177. name[i] = finalName[j];
  178. i += 1;
  179. j += 1;
  180. }
  181. i -= 1;
  182. while (name[i] != '/') {
  183. i -= 1;
  184. }
  185. name[i + 1] = '.';
  186. name[i + 2] = 't';
  187. name[i + 3] = 'm';
  188. name[i + 4] = 'p';
  189. name[i + 5] = '.';
  190. i += 6;
  191. while (n > 0) {
  192. name[i] = (CHAR)((int)__MOD(n, 10) + 48);
  193. n = __DIV(n, 10);
  194. i += 1;
  195. }
  196. name[i] = '.';
  197. i += 1;
  198. n = Platform_PID;
  199. while (n > 0) {
  200. name[i] = (CHAR)((int)__MOD(n, 10) + 48);
  201. n = __DIV(n, 10);
  202. i += 1;
  203. }
  204. name[i] = 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, 101);
  222. Files_GetTempName(osfile->registerName, 101, (void*)osfile->workName, 101);
  223. osfile->tempFile = 1;
  224. osfile->state = 0;
  225. error = Platform_Rename((void*)osfile->registerName, 101, (void*)osfile->workName, 101);
  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, 101, (void*)f->workName, 101);
  241. f->tempFile = 1;
  242. } else {
  243. __ASSERT(f->state == 2, 0);
  244. Files_Deregister(f->registerName, 101);
  245. __MOVE(f->registerName, f->workName, 101);
  246. f->registerName[0] = 0x00;
  247. f->tempFile = 0;
  248. }
  249. error = Platform_Unlink((void*)f->workName, 101);
  250. error = Platform_New((void*)f->workName, 101, &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[i] != NIL)) {
  302. Files_Flush(f->bufs[i]);
  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, 101);
  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)[*pos];
  339. while (ch == ' ' || ch == ';') {
  340. *pos += 1;
  341. ch = (Files_SearchPath->data)[*pos];
  342. }
  343. if (ch == '~') {
  344. *pos += 1;
  345. ch = (Files_SearchPath->data)[*pos];
  346. while (Files_HOME[i] != 0x00) {
  347. dir[i] = Files_HOME[i];
  348. i += 1;
  349. }
  350. if ((((((ch != '/' && ch != 0x00)) && ch != ';')) && ch != ' ')) {
  351. while ((i > 0 && dir[i - 1] != '/')) {
  352. i -= 1;
  353. }
  354. }
  355. }
  356. while ((ch != 0x00 && ch != ';')) {
  357. dir[i] = ch;
  358. i += 1;
  359. *pos += 1;
  360. ch = (Files_SearchPath->data)[*pos];
  361. }
  362. while ((i > 0 && dir[i - 1] == ' ')) {
  363. i -= 1;
  364. }
  365. }
  366. dir[i] = 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[i];
  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[i] != NIL) {
  391. f->bufs[i]->org = -1;
  392. f->bufs[i] = 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, 101);
  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[i] != NIL) {
  490. f->bufs[i]->org = -1;
  491. f->bufs[i] = 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[i] != NIL)) && org != f->bufs[i]->org)) {
  533. i += 1;
  534. }
  535. if (i < 4) {
  536. if (f->bufs[i] == NIL) {
  537. __NEW(buf, Files_BufDesc);
  538. buf->chg = 0;
  539. buf->org = -1;
  540. buf->f = f;
  541. f->bufs[i] = buf;
  542. } else {
  543. buf = f->bufs[i];
  544. }
  545. } else {
  546. f->swapper = __MASK(f->swapper + 1, -4);
  547. buf = f->bufs[f->swapper];
  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[offset];
  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[offset], (ADDRESS)&x[xpos], 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[offset] = 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[xpos], (ADDRESS)&buf->data[offset], 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, 101);
  782. Files_Rename(f->workName, 101, f->registerName, 101, &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, 101);
  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[j] = src[i];
  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[i] = 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[i]);
  865. i += 1;
  866. } while (!(x[i - 1] == 0x00 || x[i - 1] == 0x0a));
  867. if (x[i - 1] == 0x0a) {
  868. i -= 1;
  869. }
  870. if ((i > 0 && x[i - 1] == 0x0d)) {
  871. i -= 1;
  872. }
  873. x[i] = 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] = (CHAR)x;
  899. b[1] = (CHAR)__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] = (CHAR)x;
  906. b[1] = (CHAR)__ASHR(x, 8);
  907. b[2] = (CHAR)__ASHR(x, 16);
  908. b[3] = (CHAR)__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. i = (INT32)x;
  916. b[0] = (CHAR)i;
  917. b[1] = (CHAR)__ASHR(i, 8);
  918. b[2] = (CHAR)__ASHR(i, 16);
  919. b[3] = (CHAR)__ASHR(i, 24);
  920. Files_WriteBytes(&*R, R__typ, (void*)b, 4, 4);
  921. }
  922. void Files_WriteReal (Files_Rider *R, ADDRESS *R__typ, REAL x)
  923. {
  924. CHAR b[4];
  925. Files_FlipBytes((void*)&x, 4, (void*)b, 4);
  926. Files_WriteBytes(&*R, R__typ, (void*)b, 4, 4);
  927. }
  928. void Files_WriteLReal (Files_Rider *R, ADDRESS *R__typ, LONGREAL x)
  929. {
  930. CHAR b[8];
  931. Files_FlipBytes((void*)&x, 8, (void*)b, 8);
  932. Files_WriteBytes(&*R, R__typ, (void*)b, 8, 8);
  933. }
  934. void Files_WriteString (Files_Rider *R, ADDRESS *R__typ, CHAR *x, ADDRESS x__len)
  935. {
  936. INT16 i;
  937. i = 0;
  938. while (x[i] != 0x00) {
  939. i += 1;
  940. }
  941. Files_WriteBytes(&*R, R__typ, (void*)x, x__len * 1, i + 1);
  942. }
  943. void Files_WriteNum (Files_Rider *R, ADDRESS *R__typ, INT64 x)
  944. {
  945. while (x < -64 || x > 63) {
  946. Files_Write(&*R, R__typ, (CHAR)(__MASK(x, -128) + 128));
  947. x = __ASHR(x, 7);
  948. }
  949. Files_Write(&*R, R__typ, (CHAR)__MASK(x, -128));
  950. }
  951. void Files_GetName (Files_File f, CHAR *name, ADDRESS name__len)
  952. {
  953. __COPY(f->workName, name, name__len);
  954. }
  955. static void Files_CloseOSFile (Files_File f)
  956. {
  957. Files_File prev = NIL;
  958. INT16 error;
  959. if (Files_files == (void *) f) {
  960. Files_files = f->next;
  961. } else {
  962. prev = (Files_File)Files_files;
  963. while ((prev != NIL && prev->next != (void *) f)) {
  964. prev = (Files_File)prev->next;
  965. }
  966. if (prev->next != NIL) {
  967. prev->next = f->next;
  968. }
  969. }
  970. error = Platform_Close(f->fd);
  971. f->fd = -1;
  972. f->state = 1;
  973. Heap_FileCount -= 1;
  974. }
  975. static void Files_Finalize (SYSTEM_PTR o)
  976. {
  977. Files_File f = NIL;
  978. INT32 res;
  979. f = (Files_File)(ADDRESS)o;
  980. if (f->fd >= 0) {
  981. Files_CloseOSFile(f);
  982. if (f->tempFile) {
  983. res = Platform_Unlink((void*)f->workName, 101);
  984. }
  985. }
  986. }
  987. void Files_SetSearchPath (CHAR *path, ADDRESS path__len)
  988. {
  989. __DUP(path, path__len, CHAR);
  990. if (Strings_Length(path, path__len) != 0) {
  991. Files_SearchPath = __NEWARR(NIL, 1, 1, 1, 1, ((ADDRESS)((Strings_Length(path, path__len) + 1))));
  992. __COPY(path, Files_SearchPath->data, Files_SearchPath->len[0]);
  993. } else {
  994. Files_SearchPath = NIL;
  995. }
  996. __DEL(path);
  997. }
  998. static void EnumPtrs(void (*P)(void*))
  999. {
  1000. P(Files_SearchPath);
  1001. }
  1002. __TDESC(Files_FileDesc, 1, 4) = {__TDFLDS("FileDesc", 252), {228, 232, 236, 240, -20}};
  1003. __TDESC(Files_BufDesc, 1, 1) = {__TDFLDS("BufDesc", 4112), {0, -8}};
  1004. __TDESC(Files_Rider, 1, 1) = {__TDFLDS("Rider", 20), {8, -8}};
  1005. export void *Files__init(void)
  1006. {
  1007. __DEFMOD;
  1008. __MODULE_IMPORT(Heap);
  1009. __MODULE_IMPORT(Out);
  1010. __MODULE_IMPORT(Platform);
  1011. __MODULE_IMPORT(Strings);
  1012. __REGMOD("Files", EnumPtrs);
  1013. __INITYP(Files_FileDesc, Files_FileDesc, 0);
  1014. __INITYP(Files_BufDesc, Files_BufDesc, 0);
  1015. __INITYP(Files_Rider, Files_Rider, 0);
  1016. /* BEGIN */
  1017. Files_tempno = -1;
  1018. Heap_FileCount = 0;
  1019. Files_HOME[0] = 0x00;
  1020. Platform_GetEnv((CHAR*)"HOME", 5, (void*)Files_HOME, 1024);
  1021. __ENDMOD;
  1022. }