FileReader.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "tokenizer/FileReader.h"
  6. typedef char String[64];
  7. #define STRING_LENGTH ((int)sizeof(String))
  8. #define END_IF "#endif"
  9. #define END_IF_LENGTH ((int)sizeof(END_IF) - 1)
  10. static Error* error;
  11. typedef struct {
  12. String name;
  13. } Define;
  14. #define DEFINES 256
  15. static Define defines[DEFINES];
  16. static int defineIndex = 0;
  17. static bool frHasError() {
  18. return error->message[0] != '\0';
  19. }
  20. static bool frStringCompare(const String a, const char* b) {
  21. return strcmp(a, b) == 0;
  22. }
  23. static void frInitFileReader(FileReader* fr, const char* path) {
  24. fr->data = NULL;
  25. fr->path = path;
  26. fr->length = 0;
  27. fr->readIndex = 0;
  28. fr->line = 1;
  29. }
  30. static void frSystemError(const char* msg, FileReader* fr) {
  31. eInitError(error, fr->line, "%s '%s': %s", msg, fr->path, strerror(errno));
  32. }
  33. static void frFullRead(FILE* file, FileReader* fr) {
  34. if(fseek(file, 0, SEEK_END)) {
  35. frSystemError("cannot seek end of file", fr);
  36. return;
  37. }
  38. long length = ftell(file);
  39. if(length < 0) {
  40. frSystemError("cannot tell end of file", fr);
  41. return;
  42. }
  43. rewind(file);
  44. fr->data = malloc(length + 1);
  45. fr->length = length;
  46. int readValues = fread(fr->data, 1, length, file);
  47. if(readValues != length) {
  48. frSystemError("cannot read file", fr);
  49. fr->data[0] = '\0';
  50. fr->length = 0;
  51. return;
  52. }
  53. fr->data[length] = '\0';
  54. }
  55. static void frFullReadFile(FileReader* fr) {
  56. FILE* file = fopen(fr->path, "r");
  57. if(file == NULL) {
  58. frSystemError("cannot open file", fr);
  59. return;
  60. }
  61. frFullRead(file, fr);
  62. }
  63. static int frReadUntil(int from, char end, String s, FileReader* fr) {
  64. int index = 0;
  65. while(from < fr->length && index < STRING_LENGTH - 1 &&
  66. fr->data[from] != end) {
  67. s[index++] = fr->data[from];
  68. from++;
  69. }
  70. s[index] = '\0';
  71. return index;
  72. }
  73. static int frReadUntilOrLine(int from, char end, String s, FileReader* fr) {
  74. int index = 0;
  75. while(from < fr->length && index < STRING_LENGTH - 1 &&
  76. fr->data[from] != end && fr->data[from] != '\n') {
  77. s[index++] = fr->data[from];
  78. from++;
  79. }
  80. s[index] = '\0';
  81. return index;
  82. }
  83. static void frMakePath(String fullPath, const char* parent, String name) {
  84. int i = 0;
  85. int lastSlash = 0;
  86. while(i < STRING_LENGTH - 1 && parent[i] != '\0') {
  87. fullPath[i] = parent[i];
  88. lastSlash = parent[i] == '/' ? i : lastSlash;
  89. i++;
  90. }
  91. i = lastSlash + 1;
  92. int nameI = 0;
  93. while(i < STRING_LENGTH - 1 && name[nameI] != '\0') {
  94. fullPath[i] = name[nameI];
  95. i++;
  96. nameI++;
  97. }
  98. fullPath[i] = '\0';
  99. }
  100. static void frReplace(int from, int to, FileReader* fr,
  101. FileReader* replacement) {
  102. int replaceLength = replacement->length - 1;
  103. replaceLength = replaceLength < 0 ? 0 : replaceLength;
  104. int newLength = fr->length + replaceLength - (to - from);
  105. unsigned char* newData = malloc(newLength + 1);
  106. memcpy(newData, fr->data, from);
  107. memcpy(newData + from, replacement->data, replaceLength);
  108. memcpy(newData + from + replaceLength, fr->data + to, fr->length - to);
  109. newData[newLength] = '\0';
  110. free(fr->data);
  111. fr->data = newData;
  112. fr->length = newLength;
  113. }
  114. static int skipSpaces(int index, FileReader* fr) {
  115. while(index < fr->length && fr->data[index] == ' ') {
  116. index++;
  117. }
  118. return index;
  119. }
  120. static void frHandleInclude(int from, int length, FileReader* fr) {
  121. int index = from + length;
  122. index = skipSpaces(index, fr);
  123. if(index >= fr->length || fr->data[index] != '"') {
  124. eInitError(error, fr->line, "expected '\"' and not '%c' in '%s'",
  125. fr->data[index], fr->path);
  126. return;
  127. }
  128. index++;
  129. String s;
  130. int pathLength = frReadUntil(index, '"', s, fr) + 1;
  131. String fullPath;
  132. frMakePath(fullPath, fr->path, s);
  133. FileReader include;
  134. frInitFileReader(&include, fullPath);
  135. frFullReadFile(&include);
  136. if(frHasError()) {
  137. frDelete(&include);
  138. return;
  139. }
  140. frReplace(from, index + pathLength, fr, &include);
  141. frDelete(&include);
  142. }
  143. static int frReadWord(String s, int from, FileReader* fr) {
  144. int index = skipSpaces(from, fr);
  145. int wordLength = frReadUntilOrLine(index, ' ', s, fr);
  146. return index + wordLength;
  147. }
  148. static bool frIsDefined(String s) {
  149. for(int i = 0; i < defineIndex; i++) {
  150. if(frStringCompare(defines[i].name, s)) {
  151. return true;
  152. }
  153. }
  154. return false;
  155. }
  156. static bool frIsMatching(int from, FileReader* fr, const char* s) {
  157. int i = 0;
  158. while(true) {
  159. if(s[i] == '\0') {
  160. return true;
  161. } else if(from >= fr->length || fr->data[from] != s[i]) {
  162. return false;
  163. }
  164. from++;
  165. i++;
  166. }
  167. }
  168. static int frFindEndIf(int from, FileReader* fr) {
  169. int layer = 0;
  170. for(int i = from; i < fr->length; i++) {
  171. if(frIsMatching(i, fr, END_IF)) {
  172. if(layer == 0) {
  173. return i;
  174. }
  175. layer--;
  176. } else if(frIsMatching(i, fr, "#ifndef")) {
  177. layer++;
  178. }
  179. }
  180. return -1;
  181. }
  182. static void frHandleIfNotDefined(int from, int length, FileReader* fr) {
  183. String s;
  184. int end = frReadWord(s, from + length, fr);
  185. int endIf = frFindEndIf(end, fr);
  186. if(endIf == -1) {
  187. eInitError(error, fr->line, "cannot find #endif in '%s'", fr->path);
  188. return;
  189. }
  190. if(frIsDefined(s)) {
  191. memset(fr->data + from, ' ', endIf - from + END_IF_LENGTH);
  192. } else {
  193. memset(fr->data + from, ' ', end - from);
  194. memset(fr->data + endIf, ' ', END_IF_LENGTH);
  195. }
  196. }
  197. static void frHandleDefine(int from, int length, FileReader* fr) {
  198. if(defineIndex >= DEFINES) {
  199. eInitError(error, fr->line, "too much defines in '%s'", fr->path);
  200. return;
  201. }
  202. String s;
  203. int end = frReadWord(s, from + length, fr);
  204. if(frIsDefined(s)) {
  205. puts("already defined");
  206. return;
  207. }
  208. strncpy(defines[defineIndex].name, s, STRING_LENGTH);
  209. defineIndex++;
  210. printf("defined '%s'\n", s);
  211. memset(fr->data + from, ' ', end - from);
  212. }
  213. static void frParseInstruction(int from, FileReader* fr) {
  214. String s;
  215. int length = frReadUntil(from, ' ', s, fr);
  216. if(frStringCompare(s, "#include")) {
  217. frHandleInclude(from, length, fr);
  218. } else if(frStringCompare(s, "#ifndef")) {
  219. frHandleIfNotDefined(from, length, fr);
  220. } else if(frStringCompare(s, "#define")) {
  221. frHandleDefine(from, length, fr);
  222. } else {
  223. eInitError(error, fr->line, "unknown preprocessor token '%s' in '%s'",
  224. s, fr->path);
  225. }
  226. }
  227. static void frSearchInstruction(FileReader* fr) {
  228. if(fr->data == NULL) {
  229. return;
  230. }
  231. for(int i = 0; i < fr->length && !frHasError(); i++) {
  232. unsigned char c = fr->data[i];
  233. if(c == '#') {
  234. frParseInstruction(i, fr);
  235. i--;
  236. } else if(c == '\n') {
  237. fr->line++;
  238. }
  239. }
  240. }
  241. void frInit(const char* path, FileReader* fr, Error* e) {
  242. defineIndex = 0;
  243. error = e;
  244. eInitSuccess(error);
  245. frInitFileReader(fr, path);
  246. frFullReadFile(fr);
  247. frSearchInstruction(fr);
  248. if(fr->data != NULL) {
  249. printf((char*)fr->data);
  250. }
  251. }
  252. void frDelete(FileReader* fr) {
  253. free(fr->data);
  254. fr->data = NULL;
  255. fr->path = NULL;
  256. fr->length = 0;
  257. fr->readIndex = 0;
  258. }
  259. int frRead(FileReader* fr) {
  260. if(fr->readIndex < fr->length) {
  261. return fr->data[fr->readIndex++];
  262. }
  263. return -1;
  264. }
  265. int frPeek(FileReader* fr) {
  266. if(fr->readIndex < fr->length) {
  267. return fr->data[fr->readIndex];
  268. }
  269. return -1;
  270. }
  271. bool frReadIf(FileReader* fr, int c) {
  272. if(frPeek(fr) == c) {
  273. frRead(fr);
  274. return true;
  275. }
  276. return false;
  277. }
  278. /*#define MAX_INDEX 50
  279. typedef struct {
  280. char* content;
  281. int size;
  282. int index;
  283. int arrayIndex;
  284. bool newLines;
  285. char* path;
  286. FILE* file;
  287. } OpenFile;
  288. typedef struct {
  289. int fileIndex;
  290. int index;
  291. } FilePointer;
  292. typedef struct {
  293. FilePointer name;
  294. FilePointer code;
  295. } Define;
  296. typedef struct {
  297. int fileIndex;
  298. int defineIndex;
  299. OpenFile files[MAX_INDEX];
  300. Define defines[MAX_INDEX];
  301. FilePointer readIndex;
  302. FileError error;
  303. } OpenFiles;
  304. static OpenFiles files;
  305. static int lastChar = 0;
  306. static int stackIndex = 0;
  307. static FilePointer stack[MAX_INDEX];
  308. static void fAdd(OpenFile* of, const void* data, int size) {
  309. while(of->index + size > of->size) {
  310. of->size *= 2;
  311. of->content = realloc(of->content, of->size);
  312. }
  313. memcpy(of->content + of->index, data, size);
  314. of->index += size;
  315. }
  316. static void fAddChar(OpenFile* of, int ic) {
  317. char c = ic;
  318. fAdd(of, &c, 1);
  319. }
  320. static int fReserverInt(OpenFile* of) {
  321. int address = of->index;
  322. int empty = 0;
  323. fAdd(of, &empty, sizeof(int));
  324. return address;
  325. }
  326. static void fSetInt(OpenFile* of, int address, int i) {
  327. memcpy(of->content + address, &i, sizeof(int));
  328. }
  329. static int fReadInt(OpenFile* of, int address) {
  330. int i = 0;
  331. memcpy(&i, of->content + address, sizeof(int));
  332. of->index += sizeof(int);
  333. return i;
  334. }
  335. static int fGet(OpenFile* of) {
  336. int c = fgetc(of->file);
  337. if(!of->newLines && c == '\n') {
  338. return ' ';
  339. }
  340. return c;
  341. }
  342. static bool fReadCommandString(OpenFile* of, char* buffer, int size) {
  343. int index = 0;
  344. int c = fGet(of);
  345. while(c == ' ') {
  346. c = fGet(of);
  347. }
  348. int text = 0;
  349. while(true) {
  350. if(c == EOF) {
  351. files.error("unexpected end of file");
  352. } else if(index >= size - 1) {
  353. files.error("unknown too long command");
  354. } else if(c == '"' && text < 2) {
  355. text++;
  356. buffer[index++] = c;
  357. } else if((isLetter(c) || text == 1) && text < 2) {
  358. buffer[index++] = c;
  359. } else if(c == ' ' || c == '\n') {
  360. buffer[index] = '\0';
  361. return c == '\n';
  362. } else {
  363. files.error("unexpected character '%c'", (char)c);
  364. }
  365. c = fGet(of);
  366. }
  367. }
  368. static const char* fGetDefineName(Define* d) {
  369. return files.files[d->name.fileIndex].content + d->name.index;
  370. }
  371. static int fStartDefine(OpenFile* of, bool* newLine) {
  372. fAddChar(of, '#');
  373. int end = fReserverInt(of);
  374. int nameFileIndex = fReserverInt(of);
  375. int nameIndex = fReserverInt(of);
  376. int codeFileIndex = fReserverInt(of);
  377. int codeIndex = fReserverInt(of);
  378. char command[64];
  379. *newLine = fReadCommandString(of, command, 64);
  380. fSetInt(of, nameFileIndex, of->arrayIndex);
  381. fSetInt(of, nameIndex, of->index);
  382. fAdd(of, command, strlen(command) + 1);
  383. fSetInt(of, codeFileIndex, of->arrayIndex);
  384. fSetInt(of, codeIndex, of->index);
  385. return end;
  386. }
  387. static void fFinishDefine(OpenFile* of, int end, int newLines) {
  388. fAddChar(of, '\0');
  389. fSetInt(of, end, of->index);
  390. for(int i = 0; i < newLines; i++) {
  391. fAddChar(of, '\n');
  392. }
  393. }
  394. static void fDefine(OpenFile* of) {
  395. bool newLine = false;
  396. int end = fStartDefine(of, &newLine);
  397. int newLines = newLine;
  398. while(true) {
  399. int c = fGet(of);
  400. if(c == '#') {
  401. char end[64];
  402. newLines += fReadCommandString(of, end, 64);
  403. if(strcmp(end, "end") == 0) {
  404. break;
  405. }
  406. files.error("invalid command '%s' inside define region", end);
  407. } else if(c == EOF) {
  408. files.error("unclosed #define");
  409. }
  410. if(c == '\n') {
  411. newLines++;
  412. c = ' ';
  413. }
  414. fAddChar(of, c);
  415. }
  416. fFinishDefine(of, end, newLines);
  417. }
  418. static void fReadFile(const char* path, bool newLines);
  419. static void fEnter(FilePointer* fp);
  420. static int fConcat(char* buffer, int size, const char* s) {
  421. int l = strlen(s) + 1;
  422. if(l > size) {
  423. files.error("too long include path");
  424. }
  425. memcpy(buffer, s, l);
  426. return l;
  427. }
  428. static void fInclude(OpenFile* of) {
  429. char path[64];
  430. if(fReadCommandString(of, path, 64)) {
  431. fAddChar(of, '\n');
  432. }
  433. int l = strlen(path);
  434. if(l < 2 || path[0] != '"' || path[l - 1] != '"') {
  435. files.error("invalid include path '%s'", path);
  436. }
  437. path[l - 1] = '\0';
  438. const char* cutPath = path + 1;
  439. char fullName[256];
  440. int index = fConcat(fullName, 256, of->path);
  441. while(index > 0 && fullName[index - 1] != '/') {
  442. index--;
  443. }
  444. fConcat(fullName + index, 256 - index, cutPath);
  445. FilePointer fp = {files.fileIndex, 0};
  446. fEnter(&fp);
  447. fReadFile(fullName, false);
  448. }
  449. static void fReadCommand(OpenFile* of) {
  450. char command[64];
  451. fReadCommandString(of, command, 64);
  452. if(strcmp(command, "define") == 0) {
  453. fDefine(of);
  454. } else if(strcmp(command, "include") == 0) {
  455. fInclude(of);
  456. } else {
  457. files.error("invalid command '%s'", command);
  458. }
  459. }
  460. static void fReadFile(const char* path, bool newLines) {
  461. if(files.fileIndex >= MAX_INDEX) {
  462. files.error("cannot read file '%s': too many open files", path);
  463. }
  464. OpenFile* of = files.files + files.fileIndex;
  465. of->arrayIndex = files.fileIndex++;
  466. of->index = 0;
  467. of->size = 16;
  468. of->newLines = newLines;
  469. of->content = malloc(of->size);
  470. of->file = fopen(path, "r");
  471. of->path = strdup(path);
  472. if(of->file == NULL) {
  473. files.error("cannot read file '%s'", path);
  474. }
  475. while(true) {
  476. int c = fGet(of);
  477. if(c == '#') {
  478. fReadCommand(of);
  479. continue;
  480. }
  481. fAddChar(of, c);
  482. if(c == EOF) {
  483. break;
  484. }
  485. }
  486. fAddChar(of, '\0');
  487. }
  488. void fOpen(const char* path, FileError fe) {
  489. files.fileIndex = 0;
  490. files.defineIndex = 0;
  491. files.readIndex.fileIndex = 0;
  492. files.readIndex.index = 0;
  493. files.error = fe;
  494. lastChar = 0;
  495. stackIndex = 0;
  496. fReadFile(path, true);
  497. }
  498. void fClose() {
  499. for(int i = 0; i < files.fileIndex; i++) {
  500. if(files.files[i].file != NULL) {
  501. fclose(files.files[i].file);
  502. }
  503. free(files.files[i].path);
  504. free(files.files[i].content);
  505. }
  506. }
  507. static OpenFile* currentFile() {
  508. return files.files + files.readIndex.fileIndex;
  509. }
  510. static int fReadChar() {
  511. return currentFile()->content[files.readIndex.index];
  512. }
  513. static bool fCompare(const char* a, const char* b, unsigned int bLength) {
  514. return strncmp(a, b, bLength) == 0 && strlen(a) == bLength;
  515. }
  516. static void fEnter(FilePointer* fp) {
  517. if(stackIndex >= MAX_INDEX) {
  518. files.error("define stack overflow");
  519. }
  520. stack[stackIndex++] = files.readIndex;
  521. files.readIndex = *fp;
  522. }
  523. static bool fCheckForReplacement() {
  524. OpenFile* of = currentFile();
  525. int start = files.readIndex.index;
  526. int index = start;
  527. while(index < of->index && isLetter(of->content[index])) {
  528. index++;
  529. }
  530. for(int i = 0; i < files.defineIndex; i++) {
  531. Define* d = files.defines + i;
  532. const char* name = fGetDefineName(d);
  533. if(fCompare(name, of->content + start, index - start)) {
  534. files.readIndex.index = index;
  535. fEnter(&d->code);
  536. return true;
  537. }
  538. }
  539. return false;
  540. }
  541. static void fReadDefine() {
  542. int base = files.readIndex.index + 1;
  543. int end = fReadInt(currentFile(), base);
  544. int nameFileIndex = fReadInt(currentFile(), base + sizeof(int));
  545. int nameIndex = fReadInt(currentFile(), base + sizeof(int) * 2);
  546. int codeFileIndex = fReadInt(currentFile(), base + sizeof(int) * 3);
  547. int codeIndex = fReadInt(currentFile(), base + sizeof(int) * 4);
  548. const char* name = files.files[nameFileIndex].content + nameIndex;
  549. if(files.defineIndex >= MAX_INDEX) {
  550. files.error("too many defines");
  551. }
  552. Define* d = files.defines + files.defineIndex++;
  553. for(int i = 0; i < files.defineIndex - 1; i++) {
  554. if(strcmp(name, fGetDefineName(files.defines + i)) == 0) {
  555. d = files.defines + i;
  556. files.defineIndex--;
  557. break;
  558. }
  559. }
  560. d->name.fileIndex = nameFileIndex;
  561. d->name.index = nameIndex;
  562. d->code.fileIndex = codeFileIndex;
  563. d->code.index = codeIndex;
  564. files.readIndex.index = end;
  565. }
  566. static void fPrepareChar() {
  567. while(true) {
  568. int c = fReadChar();
  569. if(c == '\0') {
  570. if(stackIndex <= 0) {
  571. files.error("define stack underflow");
  572. }
  573. files.readIndex = stack[--stackIndex];
  574. } else if(c == EOF && stackIndex > 0) {
  575. files.readIndex = stack[--stackIndex];
  576. } else if(c == '#') {
  577. fReadDefine();
  578. } else if(isLetter(c) && !isLetter(lastChar)) {
  579. if(fCheckForReplacement()) {
  580. continue;
  581. }
  582. break;
  583. } else {
  584. break;
  585. }
  586. }
  587. }
  588. static int fReadI() {
  589. fPrepareChar();
  590. lastChar = fReadChar();
  591. return currentFile()->content[files.readIndex.index++];
  592. }
  593. int fRead() {
  594. int i = fReadI();
  595. // putchar(i);
  596. return i;
  597. }
  598. int fPeek() {
  599. fPrepareChar();
  600. return fReadChar();
  601. }
  602. bool fReadIf(int c) {
  603. if(fPeek() == c) {
  604. fRead();
  605. return true;
  606. }
  607. return false;
  608. }*/