FileReader.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "tokenizer/FileReader.h"
  6. static void frFullRead(FILE* file, const char* path, FileReader* fr, Error* e) {
  7. if(fseek(file, 0, SEEK_END)) {
  8. eInitError(e, 1, "cannot seek end of file '%s': %s", path,
  9. strerror(errno));
  10. return;
  11. }
  12. long length = ftell(file);
  13. if(length < 0) {
  14. eInitError(e, 1, "cannot tell end of file '%s': %s", path,
  15. strerror(errno));
  16. return;
  17. }
  18. rewind(file);
  19. fr->data = malloc(length + 1);
  20. fr->length = length;
  21. int readValues = fread(fr->data, 1, length, file);
  22. if(readValues != length) {
  23. eInitError(e, 1, "cannot read file '%s': %s", path, strerror(errno));
  24. fr->data[0] = '\0';
  25. return;
  26. }
  27. fr->data[length] = '\0';
  28. eInitSuccess(e);
  29. }
  30. void frInit(const char* path, FileReader* fr, Error* e) {
  31. fr->data = NULL;
  32. fr->length = 0;
  33. fr->readIndex = 0;
  34. FILE* file = fopen(path, "r");
  35. if(file == NULL) {
  36. eInitError(e, 1, "cannot open file '%s': %s", path, strerror(errno));
  37. return;
  38. }
  39. frFullRead(file, path, fr, e);
  40. fclose(file);
  41. }
  42. void frDelete(FileReader* fr) {
  43. free(fr->data);
  44. fr->data = NULL;
  45. fr->length = 0;
  46. fr->readIndex = 0;
  47. }
  48. int frRead(FileReader* fr) {
  49. if(fr->readIndex < fr->length) {
  50. return fr->data[fr->readIndex++];
  51. }
  52. return -1;
  53. }
  54. int frPeek(FileReader* fr) {
  55. if(fr->readIndex < fr->length) {
  56. return fr->data[fr->readIndex];
  57. }
  58. return -1;
  59. }
  60. bool frReadIf(FileReader* fr, int c) {
  61. if(frPeek(fr) == c) {
  62. frRead(fr);
  63. return true;
  64. }
  65. return false;
  66. }
  67. /*#define MAX_INDEX 50
  68. typedef struct {
  69. char* content;
  70. int size;
  71. int index;
  72. int arrayIndex;
  73. bool newLines;
  74. char* path;
  75. FILE* file;
  76. } OpenFile;
  77. typedef struct {
  78. int fileIndex;
  79. int index;
  80. } FilePointer;
  81. typedef struct {
  82. FilePointer name;
  83. FilePointer code;
  84. } Define;
  85. typedef struct {
  86. int fileIndex;
  87. int defineIndex;
  88. OpenFile files[MAX_INDEX];
  89. Define defines[MAX_INDEX];
  90. FilePointer readIndex;
  91. FileError error;
  92. } OpenFiles;
  93. static OpenFiles files;
  94. static int lastChar = 0;
  95. static int stackIndex = 0;
  96. static FilePointer stack[MAX_INDEX];
  97. static void fAdd(OpenFile* of, const void* data, int size) {
  98. while(of->index + size > of->size) {
  99. of->size *= 2;
  100. of->content = realloc(of->content, of->size);
  101. }
  102. memcpy(of->content + of->index, data, size);
  103. of->index += size;
  104. }
  105. static void fAddChar(OpenFile* of, int ic) {
  106. char c = ic;
  107. fAdd(of, &c, 1);
  108. }
  109. static int fReserverInt(OpenFile* of) {
  110. int address = of->index;
  111. int empty = 0;
  112. fAdd(of, &empty, sizeof(int));
  113. return address;
  114. }
  115. static void fSetInt(OpenFile* of, int address, int i) {
  116. memcpy(of->content + address, &i, sizeof(int));
  117. }
  118. static int fReadInt(OpenFile* of, int address) {
  119. int i = 0;
  120. memcpy(&i, of->content + address, sizeof(int));
  121. of->index += sizeof(int);
  122. return i;
  123. }
  124. static int fGet(OpenFile* of) {
  125. int c = fgetc(of->file);
  126. if(!of->newLines && c == '\n') {
  127. return ' ';
  128. }
  129. return c;
  130. }
  131. static bool fReadCommandString(OpenFile* of, char* buffer, int size) {
  132. int index = 0;
  133. int c = fGet(of);
  134. while(c == ' ') {
  135. c = fGet(of);
  136. }
  137. int text = 0;
  138. while(true) {
  139. if(c == EOF) {
  140. files.error("unexpected end of file");
  141. } else if(index >= size - 1) {
  142. files.error("unknown too long command");
  143. } else if(c == '"' && text < 2) {
  144. text++;
  145. buffer[index++] = c;
  146. } else if((isLetter(c) || text == 1) && text < 2) {
  147. buffer[index++] = c;
  148. } else if(c == ' ' || c == '\n') {
  149. buffer[index] = '\0';
  150. return c == '\n';
  151. } else {
  152. files.error("unexpected character '%c'", (char)c);
  153. }
  154. c = fGet(of);
  155. }
  156. }
  157. static const char* fGetDefineName(Define* d) {
  158. return files.files[d->name.fileIndex].content + d->name.index;
  159. }
  160. static int fStartDefine(OpenFile* of, bool* newLine) {
  161. fAddChar(of, '#');
  162. int end = fReserverInt(of);
  163. int nameFileIndex = fReserverInt(of);
  164. int nameIndex = fReserverInt(of);
  165. int codeFileIndex = fReserverInt(of);
  166. int codeIndex = fReserverInt(of);
  167. char command[64];
  168. *newLine = fReadCommandString(of, command, 64);
  169. fSetInt(of, nameFileIndex, of->arrayIndex);
  170. fSetInt(of, nameIndex, of->index);
  171. fAdd(of, command, strlen(command) + 1);
  172. fSetInt(of, codeFileIndex, of->arrayIndex);
  173. fSetInt(of, codeIndex, of->index);
  174. return end;
  175. }
  176. static void fFinishDefine(OpenFile* of, int end, int newLines) {
  177. fAddChar(of, '\0');
  178. fSetInt(of, end, of->index);
  179. for(int i = 0; i < newLines; i++) {
  180. fAddChar(of, '\n');
  181. }
  182. }
  183. static void fDefine(OpenFile* of) {
  184. bool newLine = false;
  185. int end = fStartDefine(of, &newLine);
  186. int newLines = newLine;
  187. while(true) {
  188. int c = fGet(of);
  189. if(c == '#') {
  190. char end[64];
  191. newLines += fReadCommandString(of, end, 64);
  192. if(strcmp(end, "end") == 0) {
  193. break;
  194. }
  195. files.error("invalid command '%s' inside define region", end);
  196. } else if(c == EOF) {
  197. files.error("unclosed #define");
  198. }
  199. if(c == '\n') {
  200. newLines++;
  201. c = ' ';
  202. }
  203. fAddChar(of, c);
  204. }
  205. fFinishDefine(of, end, newLines);
  206. }
  207. static void fReadFile(const char* path, bool newLines);
  208. static void fEnter(FilePointer* fp);
  209. static int fConcat(char* buffer, int size, const char* s) {
  210. int l = strlen(s) + 1;
  211. if(l > size) {
  212. files.error("too long include path");
  213. }
  214. memcpy(buffer, s, l);
  215. return l;
  216. }
  217. static void fInclude(OpenFile* of) {
  218. char path[64];
  219. if(fReadCommandString(of, path, 64)) {
  220. fAddChar(of, '\n');
  221. }
  222. int l = strlen(path);
  223. if(l < 2 || path[0] != '"' || path[l - 1] != '"') {
  224. files.error("invalid include path '%s'", path);
  225. }
  226. path[l - 1] = '\0';
  227. const char* cutPath = path + 1;
  228. char fullName[256];
  229. int index = fConcat(fullName, 256, of->path);
  230. while(index > 0 && fullName[index - 1] != '/') {
  231. index--;
  232. }
  233. fConcat(fullName + index, 256 - index, cutPath);
  234. FilePointer fp = {files.fileIndex, 0};
  235. fEnter(&fp);
  236. fReadFile(fullName, false);
  237. }
  238. static void fReadCommand(OpenFile* of) {
  239. char command[64];
  240. fReadCommandString(of, command, 64);
  241. if(strcmp(command, "define") == 0) {
  242. fDefine(of);
  243. } else if(strcmp(command, "include") == 0) {
  244. fInclude(of);
  245. } else {
  246. files.error("invalid command '%s'", command);
  247. }
  248. }
  249. static void fReadFile(const char* path, bool newLines) {
  250. if(files.fileIndex >= MAX_INDEX) {
  251. files.error("cannot read file '%s': too many open files", path);
  252. }
  253. OpenFile* of = files.files + files.fileIndex;
  254. of->arrayIndex = files.fileIndex++;
  255. of->index = 0;
  256. of->size = 16;
  257. of->newLines = newLines;
  258. of->content = malloc(of->size);
  259. of->file = fopen(path, "r");
  260. of->path = strdup(path);
  261. if(of->file == NULL) {
  262. files.error("cannot read file '%s'", path);
  263. }
  264. while(true) {
  265. int c = fGet(of);
  266. if(c == '#') {
  267. fReadCommand(of);
  268. continue;
  269. }
  270. fAddChar(of, c);
  271. if(c == EOF) {
  272. break;
  273. }
  274. }
  275. fAddChar(of, '\0');
  276. }
  277. void fOpen(const char* path, FileError fe) {
  278. files.fileIndex = 0;
  279. files.defineIndex = 0;
  280. files.readIndex.fileIndex = 0;
  281. files.readIndex.index = 0;
  282. files.error = fe;
  283. lastChar = 0;
  284. stackIndex = 0;
  285. fReadFile(path, true);
  286. }
  287. void fClose() {
  288. for(int i = 0; i < files.fileIndex; i++) {
  289. if(files.files[i].file != NULL) {
  290. fclose(files.files[i].file);
  291. }
  292. free(files.files[i].path);
  293. free(files.files[i].content);
  294. }
  295. }
  296. static OpenFile* currentFile() {
  297. return files.files + files.readIndex.fileIndex;
  298. }
  299. static int fReadChar() {
  300. return currentFile()->content[files.readIndex.index];
  301. }
  302. static bool fCompare(const char* a, const char* b, unsigned int bLength) {
  303. return strncmp(a, b, bLength) == 0 && strlen(a) == bLength;
  304. }
  305. static void fEnter(FilePointer* fp) {
  306. if(stackIndex >= MAX_INDEX) {
  307. files.error("define stack overflow");
  308. }
  309. stack[stackIndex++] = files.readIndex;
  310. files.readIndex = *fp;
  311. }
  312. static bool fCheckForReplacement() {
  313. OpenFile* of = currentFile();
  314. int start = files.readIndex.index;
  315. int index = start;
  316. while(index < of->index && isLetter(of->content[index])) {
  317. index++;
  318. }
  319. for(int i = 0; i < files.defineIndex; i++) {
  320. Define* d = files.defines + i;
  321. const char* name = fGetDefineName(d);
  322. if(fCompare(name, of->content + start, index - start)) {
  323. files.readIndex.index = index;
  324. fEnter(&d->code);
  325. return true;
  326. }
  327. }
  328. return false;
  329. }
  330. static void fReadDefine() {
  331. int base = files.readIndex.index + 1;
  332. int end = fReadInt(currentFile(), base);
  333. int nameFileIndex = fReadInt(currentFile(), base + sizeof(int));
  334. int nameIndex = fReadInt(currentFile(), base + sizeof(int) * 2);
  335. int codeFileIndex = fReadInt(currentFile(), base + sizeof(int) * 3);
  336. int codeIndex = fReadInt(currentFile(), base + sizeof(int) * 4);
  337. const char* name = files.files[nameFileIndex].content + nameIndex;
  338. if(files.defineIndex >= MAX_INDEX) {
  339. files.error("too many defines");
  340. }
  341. Define* d = files.defines + files.defineIndex++;
  342. for(int i = 0; i < files.defineIndex - 1; i++) {
  343. if(strcmp(name, fGetDefineName(files.defines + i)) == 0) {
  344. d = files.defines + i;
  345. files.defineIndex--;
  346. break;
  347. }
  348. }
  349. d->name.fileIndex = nameFileIndex;
  350. d->name.index = nameIndex;
  351. d->code.fileIndex = codeFileIndex;
  352. d->code.index = codeIndex;
  353. files.readIndex.index = end;
  354. }
  355. static void fPrepareChar() {
  356. while(true) {
  357. int c = fReadChar();
  358. if(c == '\0') {
  359. if(stackIndex <= 0) {
  360. files.error("define stack underflow");
  361. }
  362. files.readIndex = stack[--stackIndex];
  363. } else if(c == EOF && stackIndex > 0) {
  364. files.readIndex = stack[--stackIndex];
  365. } else if(c == '#') {
  366. fReadDefine();
  367. } else if(isLetter(c) && !isLetter(lastChar)) {
  368. if(fCheckForReplacement()) {
  369. continue;
  370. }
  371. break;
  372. } else {
  373. break;
  374. }
  375. }
  376. }
  377. static int fReadI() {
  378. fPrepareChar();
  379. lastChar = fReadChar();
  380. return currentFile()->content[files.readIndex.index++];
  381. }
  382. int fRead() {
  383. int i = fReadI();
  384. // putchar(i);
  385. return i;
  386. }
  387. int fPeek() {
  388. fPrepareChar();
  389. return fReadChar();
  390. }
  391. bool fReadIf(int c) {
  392. if(fPeek() == c) {
  393. fRead();
  394. return true;
  395. }
  396. return false;
  397. }*/