first.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <sys/wait.h>
  4. /* #define STR_SIZE_LIMIT 65536 */
  5. #define STR_SIZE_LIMIT 5458264
  6. #define IMP
  7. #define WANT_BUILD
  8. #define WANT_CSTR
  9. #define WANT_STR
  10. #define WANT_MAP
  11. #define WANT_TOKENIZER
  12. #define WANT_DYN_ARR
  13. #define WANT_PATH
  14. #define WANT_ENV
  15. #define WANT_SLOP
  16. #define WANT_CMD
  17. #include "./src/lib.h"
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. /*
  21. # define DIE(f, e) \
  22. (f); \
  23. if ( (e) != ERR_OK ) {\
  24. fprintf(stderr, \
  25. "Error while running `" #f "`: %s\n", \
  26. err_to_name[(e)]); \
  27. goto exit_err; \
  28. }
  29. # define PPP(f) \
  30. printf("PRE: `" #f "`\n"); \
  31. f; \
  32. printf("POST: `" #f "`\n");
  33. */
  34. int
  35. main(int argc, char *argv[])
  36. {
  37. enum err err = ERR_OK;
  38. struct cmd cmd = {0};
  39. cmd = cmd_create_ns("/bin/echo", &err);
  40. cmd_append_arg_ns(&cmd, "This is a test of execve", &err);
  41. cmd_exec(&cmd, &err);
  42. cmd_destroy(&cmd, &err);
  43. if ( err != ERR_OK ) {
  44. cmd_destroy(&cmd, NULL);
  45. fprintf(stderr, "Failed cmd: %s\n", err_to_name[err]);
  46. return 1;
  47. }
  48. /*
  49. bool was_rebuild = false;
  50. struct dyn_arr dirs = {0};
  51. size_t i = 0;
  52. was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
  53. if ( was_rebuild == true ) {
  54. return 0;
  55. }
  56. dirs = dir_list_with_ext("./src", ".c", &err);
  57. free(dirs);
  58. */
  59. UNUSED(argc);
  60. UNUSED(argv);
  61. return 0;
  62. }
  63. bool skip_token(struct tokenizer *tkn, char c);
  64. enum c_token_type {
  65. _TT = TK_LAST,
  66. TK_PP_DEF,
  67. TK_PP_INC
  68. };
  69. struct pp_def {
  70. struct str name;
  71. struct str val;
  72. };
  73. # define PP_DEF_DESTROY(Var) \
  74. if ( (Var) != NULL ) { \
  75. STR_DESTROY((Var)->name); \
  76. STR_DESTROY((Var)->val); \
  77. LIB_FREE((Var)); \
  78. }
  79. struct var_decl {
  80. bool is_ptr;
  81. struct str type;
  82. struct str name;
  83. };
  84. # define VAR_DECL_DESTROY(Var) \
  85. if ( (Var) != NULL ) { \
  86. STR_DESTROY((Var)->type); \
  87. STR_DESTROY((Var)->name); \
  88. }
  89. struct func_decl {
  90. struct str ret_type;
  91. struct str name;
  92. struct {
  93. struct var_decl *data;
  94. u64 size;
  95. u64 cap;
  96. } args;
  97. };
  98. void func_decl_destroy(struct func_decl *fd);
  99. void
  100. func_decl_destroy(struct func_decl *fd)
  101. {
  102. u64 i = 0;
  103. if ( fd == NULL ) return;
  104. STR_DESTROY(fd->ret_type);
  105. STR_DESTROY(fd->name);
  106. for ( i = 0; i < fd->args.size; ++i ) {
  107. STR_DESTROY(fd->args.data[i].type);
  108. STR_DESTROY(fd->args.data[i].name);
  109. }
  110. LIB_FREE(fd->args.data);
  111. LIB_FREE(fd);
  112. }
  113. bool tkn_expect(struct tokenizer *tkn, enum token_type type,
  114. struct token *out_tk, enum err *out_err);
  115. bool tkn_expect_id(struct tokenizer *tkn, const char *cstr,
  116. struct token *out_tk, enum err *out_err);
  117. bool tkn_parse_function(struct tokenizer *tkn);
  118. bool run_function(struct str str);
  119. bool tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  120. enum err *out_err);
  121. bool tkn_parse_var(struct tokenizer *tkn, struct token *out_tk,
  122. enum err *out_err);
  123. bool tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk,
  124. enum err *out_err);
  125. bool is_space(char c);
  126. bool
  127. is_space(char c)
  128. {
  129. return (c == ' ') || (c == '\r') || (c == '\n')
  130. || (c == '\t') || (c == '\v');
  131. }
  132. int main2(int argc, char *argv[]);
  133. int
  134. main2(int argc, char *argv[])
  135. {
  136. enum err err = ERR_OK;
  137. struct path src_path = {0};
  138. struct file f = {0};
  139. struct str code = {0};
  140. struct tokenizer tkn = {0};
  141. struct tokenizer_options tkn_opts = {0};
  142. struct token tk = {0};
  143. struct dyn_arr tk_da = {0};
  144. tk_da = dyn_arr_create(sizeof(struct token), &err);
  145. src_path = path_from_cstr_ns("./first.c", &err);
  146. f = path_file_read_all(&src_path, &err);
  147. code = str_from_cstr((char*)f.data, f.size, &err);
  148. tkn_opts.skip_token = skip_token;
  149. tkn = tokenizer_create(code, src_path, &tkn_opts, &err);
  150. tk = tokenizer_next_token(&tkn, &err);
  151. do {
  152. if ( err != ERR_OK ) {
  153. fprintf(stderr, "ERROR: Failed tokenizing `%.*s`: %s\n",
  154. (int) src_path.size, src_path.data, err_to_name[err]);
  155. goto error_exit;
  156. }
  157. switch ( tk.type ) {
  158. case TK_POUND: {
  159. if ( ! tkn_parse_pp_directive(&tkn, NULL, &err) ) goto error_exit;
  160. } break;
  161. case TK_ID: if ( ! tkn_parse_decl(&tkn, NULL, &err) ) goto error_exit;
  162. case TK_NL: break;
  163. case TK_SLASH: {
  164. if ( ! tkn_expect(&tkn, TK_ASTERISK, NULL, &err) ) goto error_exit;
  165. while ( tk.type != TK_ASTERISK )
  166. tk = tokenizer_next_token(&tkn, &err);
  167. if ( ! tkn_expect(&tkn, TK_SLASH, NULL, &err) ) goto error_exit;
  168. } break;
  169. default: fprintf(stderr, "%s ERROR: Invalid Token `%s`\n",
  170. tokenizer_token_loc_temp(&tkn, &tk, TLF_VIM, NULL),
  171. token_to_cstr(tk.type));
  172. goto error_exit;
  173. }
  174. tk = tokenizer_next_token(&tkn, &err);
  175. } while ( tk.type != TK_EOF );
  176. printf("%s\n", err_to_name[err]);
  177. error_exit:
  178. if ( f.data != NULL ) free(f.data);
  179. if ( tk_da.data != NULL ) dyn_arr_destroy(&tk_da, NULL);
  180. (void) argc; (void) argv;
  181. return 0;
  182. }
  183. bool
  184. skip_token(struct tokenizer *tkn, char c)
  185. {
  186. UNUSED(tkn);
  187. return (c == ' ') || (c == '\r') || (c == '\t');
  188. }
  189. bool
  190. tkn_expect(struct tokenizer *tkn, enum token_type type, struct token *out_tk,
  191. enum err *out_err)
  192. {
  193. enum err err = ERR_OK;
  194. enum err *perr = &err;
  195. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  196. if ( tokenizer_is_next(tkn, type, out_tk, perr) == false ) {
  197. struct token tk = {0};
  198. tk = tokenizer_next_token(tkn, perr);
  199. if ( err != ERR_OK ) {
  200. fprintf(stderr, "Failed to get next token: %s\n",
  201. err_to_name[err]);
  202. return false;
  203. }
  204. fprintf(stderr, "%s ERRRO: Got wrong token, expected: %s, got: %s\n",
  205. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  206. token_to_cstr(type), token_to_cstr(tk.type));
  207. return false;
  208. }
  209. return true;
  210. }
  211. bool
  212. tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
  213. enum err *out_err)
  214. {
  215. enum err err = ERR_OK;
  216. struct str str = {0};
  217. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  218. LIB_ARG_MUST_NOT_BE_NULL(cstr, out_err, false);
  219. str = str_from_cstr_ns(cstr, &err);
  220. if ( tokenizer_is_next_id(tkn, str, out_tk, &err) == false ) {
  221. struct token tk = {0};
  222. tk = tokenizer_next_token(tkn, &err);
  223. if ( err != ERR_OK ) {
  224. fprintf(stderr, "Failed to get next token: %s\n",
  225. err_to_name[err]);
  226. return false;
  227. }
  228. if ( tk.type != TK_ID ) {
  229. fprintf(stderr,
  230. "%s ERROR: Got wrong token, expected: TK_ID, got: %s\n",
  231. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  232. token_to_cstr(tk.type));
  233. return false;
  234. }
  235. fprintf(stderr, "%s ERROR: Got wrong id, expected: %s, got: %.*s\n",
  236. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  237. cstr, (int) tk.string.size, tk.string.data);
  238. return false;
  239. }
  240. return true;
  241. }
  242. bool
  243. tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  244. enum err *out_err)
  245. {
  246. struct token tk = {0};
  247. enum err err = ERR_OK;
  248. enum err *perr = &err;
  249. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  250. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  251. if ( out_err != NULL ) {
  252. perr = out_err;
  253. }
  254. tk = tokenizer_next_token(tkn, perr);
  255. if ( *perr != ERR_OK ) {
  256. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  257. return false;
  258. }
  259. if ( tk.type != TK_ID ) {
  260. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  261. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  262. token_to_cstr(tk.type));
  263. return false;
  264. }
  265. if ( str_eq_cstr(tk.string, "define", 6) == true ) {
  266. struct token tk_def = {0};
  267. struct pp_def *def = NULL;
  268. def = malloc(sizeof(struct pp_def));
  269. if ( def == NULL ) {
  270. *perr = ERR_FAILED_ALLOC;
  271. goto def_exit_err;
  272. }
  273. memset(def, 0, sizeof(struct pp_def));
  274. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto def_exit_err;
  275. tk_def.loc_start = tk.loc_start;
  276. def->name = str_dup(tk.string);
  277. tk = tokenizer_next_token(tkn, &err);
  278. if ( err != ERR_OK ) {
  279. fprintf(stderr, "Failed to get next token: %s\n",
  280. err_to_name[err]);
  281. goto def_exit_err;
  282. }
  283. switch ( tk.type ) {
  284. case TK_ID:
  285. case TK_STR_LIT:
  286. case TK_NUM_LIT:
  287. break;
  288. case TK_NL: goto def_wout_value;
  289. default:
  290. fprintf(stderr,
  291. "%s Got wrong token, expected:"
  292. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  293. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  294. token_to_cstr(tk.type));
  295. goto def_exit_err;
  296. }
  297. def->val = str_dup(tk.string);
  298. tk_def.loc_end = tk.loc_end;
  299. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto def_exit_err;
  300. def_wout_value:
  301. tk_def.extra = def;
  302. if ( out_tk != NULL ) {
  303. *out_tk = tk_def;
  304. } else {
  305. PP_DEF_DESTROY(def);
  306. }
  307. return true;
  308. def_exit_err:
  309. PP_DEF_DESTROY(def);
  310. return false;
  311. }
  312. if ( str_eq_cstr(tk.string, "include", 7) == true ) {
  313. struct token tk_inc = {0};
  314. tk_inc.type = (enum token_type) TK_PP_INC;
  315. tk = tokenizer_next_token(tkn, &err);
  316. if ( err != ERR_OK ) {
  317. fprintf(stderr, "Failed to get next token: %s\n",
  318. err_to_name[err]);
  319. return false;
  320. }
  321. if ( tk.type == TK_STR_LIT ) {
  322. tk_inc.loc_start = tk.loc_start;
  323. tk_inc.loc_end = tk.loc_end;
  324. tk_inc.string = str_dup(tk.string);
  325. goto inc_str_lit;
  326. } else if ( tk.type != TK_L_ANG_BRACKET) {
  327. fprintf(stderr,
  328. "%s Got wrong token, expected:"
  329. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  330. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  331. token_to_cstr(tk.type));
  332. goto inc_exit_err;
  333. }
  334. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto inc_exit_err;
  335. tk_inc.loc_start = tk.loc_start;
  336. tk_inc.loc_end = tk.loc_end;
  337. tk_inc.string = str_dup(tk.string);
  338. if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) goto inc_exit_err;
  339. if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) goto inc_exit_err;
  340. if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) )
  341. goto inc_exit_err;
  342. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto inc_exit_err;
  343. inc_str_lit:
  344. if ( out_tk != NULL ) {
  345. *out_tk = tk_inc;
  346. } else {
  347. STR_DESTROY(tk_inc.string);
  348. }
  349. return true;
  350. inc_exit_err:
  351. STR_DESTROY(tk_inc.string);
  352. return false;
  353. }
  354. if ( str_eq_cstr(tk.string, "if", 2) == true ) {
  355. return true;
  356. }
  357. if ( str_eq_cstr(tk.string, "ifdef", 2) == true ) {
  358. return true;
  359. }
  360. if ( str_eq_cstr(tk.string, "ifndef", 2) == true ) {
  361. return true;
  362. }
  363. *perr = -1;
  364. fprintf(stderr, "%s ERROR: Invalid Pre-Compiler directive `%.*s`\n",
  365. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  366. (int) tk.string.size, tk.string.data);
  367. return false;
  368. }
  369. bool
  370. tkn_parse_var(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
  371. {
  372. enum err err = ERR_OK;
  373. enum err *perr = &err;
  374. struct token tk = {0};
  375. struct var_decl *vd = NULL;
  376. struct {
  377. char *data;
  378. u64 size;
  379. u64 cap;
  380. } type = {0};
  381. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  382. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  383. if ( out_err != NULL ) {
  384. perr = out_err;
  385. }
  386. vd = malloc(sizeof(*vd));
  387. if ( vd == NULL ) {
  388. *perr = ERR_FAILED_ALLOC;
  389. goto exit_err;
  390. }
  391. memset(vd, 0, sizeof(*vd));
  392. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
  393. DA_APPEND_DATA(type, tk.string.data, tk.string.size, perr);
  394. DA_APPEND(type, ' ', perr);
  395. while ( true ) {
  396. /* bool is_name = false;*/
  397. /*enum token_type ntt = tokenizer_peek_token_type(tkn, NULL);*/
  398. /*is_name = ( ntt == TK_COMMA ) || ( ntt == TK_SEMICOLON )
  399. || ( ntt == TK_ASTERISK ) || ( ntt == TK_EQUAL );*/
  400. tk = tokenizer_next_token(tkn, NULL);
  401. switch ( tk.type ) {
  402. case TK_ID: break;
  403. case TK_ASTERISK: break;
  404. case TK_COMMA: break;
  405. case TK_SEMICOLON: break;
  406. default:
  407. fprintf(stderr,
  408. "%s Got wrong token, expected:"
  409. " TK_ID/TK_ASTERISK/TK_COMMA/TK_SEMICOLON, got: %s\n",
  410. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  411. token_to_cstr(tk.type));
  412. goto exit_err;
  413. }
  414. }
  415. TODO("Rest of var decl!");
  416. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
  417. vd->name = str_dup(tk.string);
  418. if ( ! tkn_expect(tkn, TK_COMMA, NULL, perr) ) goto exit_err;
  419. if ( out_tk != NULL ) {
  420. *out_tk = tk;
  421. }
  422. exit_err:
  423. LIB_FREE(vd);
  424. LIB_FREE(type.data);
  425. if ( *perr == ERR_OK ) *perr = ERR_GENERAL_ERROR;
  426. return false;
  427. }
  428. bool
  429. tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
  430. {
  431. struct token tk = {0};
  432. struct token tk_type = {0};
  433. enum err err = ERR_OK;
  434. enum err *perr = &err;
  435. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  436. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  437. if ( out_err != NULL ) {
  438. perr = out_err;
  439. }
  440. tk_type = tkn->last;
  441. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  442. switch ( tokenizer_next_token_type(tkn, perr) ) {
  443. case TK_L_BRACES: {
  444. struct token tk_fd = {0};
  445. struct func_decl *fd = NULL;
  446. fd = malloc(sizeof(struct func_decl));
  447. if ( fd == NULL ) {
  448. *out_err = ERR_FAILED_ALLOC;
  449. goto func_decl_exit_err;
  450. }
  451. memset(fd, 0, sizeof(*fd));
  452. fd->args.cap = 32;
  453. fd->args.data = malloc(sizeof(*fd->args.data) * fd->args.cap);
  454. if ( fd->args.data == NULL ) {
  455. *out_err = ERR_FAILED_ALLOC;
  456. goto func_decl_exit_err;
  457. }
  458. memset(fd->args.data, 0, sizeof(*fd->args.data) * fd->args.cap);
  459. tk_fd.loc_start = tk_type.loc_start;
  460. fd->ret_type = str_dup(tk_type.string);
  461. fd->name = str_dup(tk.string);
  462. while ( true ) {
  463. struct token tk_vd = {0};
  464. struct var_decl *vd = NULL;
  465. tkn_parse_var(tkn, &tk_vd, perr);
  466. if ( *perr != ERR_OK ) goto func_decl_exit_err;
  467. vd = tk_vd.extra;
  468. DA_APPEND(fd->args, *vd, perr);
  469. };
  470. if ( out_tk != NULL ) {
  471. *out_tk = tk_fd;
  472. } else {
  473. func_decl_destroy(fd);
  474. }
  475. return true;
  476. func_decl_exit_err:
  477. func_decl_destroy(fd);
  478. return false;
  479. /*
  480. struct func_decl {
  481. struct str ret_type;
  482. struct str name;
  483. struct {
  484. struct str *data;
  485. u64 size;
  486. u64 cap;
  487. } args;
  488. };
  489. */
  490. } break;
  491. case TK_INVALID:
  492. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  493. return false;
  494. default:
  495. fprintf(stderr,
  496. "%s Got wrong token, expected: TK_L_BRACES, got: %s\n",
  497. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  498. token_to_cstr(tk.type));
  499. }
  500. /*
  501. tk = tokenizer_next_token(tkn, perr);
  502. if ( *perr != ERR_OK ) {
  503. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  504. return false;
  505. }
  506. if ( tk.type != TK_ID ) {
  507. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  508. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  509. token_to_cstr(tk.type));
  510. return false;
  511. }
  512. */
  513. UNUSED(tk_type);
  514. UNUSED(out_tk);
  515. *perr = ERR_OK;
  516. fprintf(stderr, "%s ERROR: Invalid declaration id `%.*s`\n",
  517. tokenizer_token_loc_temp(tkn, &tkn->last, TLF_VIM, NULL),
  518. (int) tk.string.size, tk.string.data);
  519. return false;
  520. }
  521. /*
  522. int
  523. main(void)
  524. {
  525. }
  526. */