| ... | ... | @@ -25,6 +25,7 @@ static int usage(char *arg0) { |
| 25 | 25 | fprintf(stderr, "Usage: %s --output outfile code.zig\n" |
| 26 | 26 | "Other options:\n" |
| 27 | 27 | "--version print version number and exit\n" |
| 28 | "-Ipath add path to header include path\n" |
| 28 | 29 | , arg0); |
| 29 | 30 | return EXIT_FAILURE; |
| 30 | 31 | } |
| ... | ... | @@ -377,6 +378,8 @@ struct Preprocess { |
| 377 | 378 | Buf *out_buf; |
| 378 | 379 | Buf *in_buf; |
| 379 | 380 | Token *token; |
| 381 | ZigList<char *> *include_paths; |
| 382 | Buf *cur_dir_path; |
| 380 | 383 | }; |
| 381 | 384 | |
| 382 | 385 | __attribute__ ((format (printf, 2, 3))) |
| ... | ... | @@ -395,8 +398,33 @@ enum IncludeState { |
| 395 | 398 | IncludeStateQuote, |
| 396 | 399 | }; |
| 397 | 400 | |
| 398 | | static void render_include(Preprocess *p, Buf *include_path, char unquote_char) { |
| 399 | | fprintf(stderr, "render_include \"%s\" '%c'\n", buf_ptr(include_path), unquote_char); |
| 401 | static Buf *find_include_file(Preprocess *p, char *dir_path, char *file_path) { |
| 402 | Buf *full_path = buf_sprintf("%s/%s", dir_path, file_path); |
| 403 | |
| 404 | FILE *f = fopen(buf_ptr(full_path), "rb"); |
| 405 | if (!f) |
| 406 | return nullptr; |
| 407 | |
| 408 | return fetch_file(f); |
| 409 | } |
| 410 | |
| 411 | static void render_include(Preprocess *p, Buf *target_path, char unquote_char) { |
| 412 | if (unquote_char == '"') { |
| 413 | Buf *file_contents = find_include_file(p, buf_ptr(p->cur_dir_path), buf_ptr(target_path)); |
| 414 | if (file_contents) { |
| 415 | buf_append_buf(p->out_buf, file_contents); |
| 416 | return; |
| 417 | } |
| 418 | } |
| 419 | for (int i = 0; i < p->include_paths->length; i += 1) { |
| 420 | char *include_path = p->include_paths->at(i); |
| 421 | Buf *file_contents = find_include_file(p, include_path, buf_ptr(target_path)); |
| 422 | if (file_contents) { |
| 423 | buf_append_buf(p->out_buf, file_contents); |
| 424 | return; |
| 425 | } |
| 426 | } |
| 427 | preprocess_error(p, "include path \"%s\" not found", buf_ptr(target_path)); |
| 400 | 428 | } |
| 401 | 429 | |
| 402 | 430 | static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) { |
| ... | ... | @@ -469,10 +497,14 @@ static void render_token(Preprocess *p) { |
| 469 | 497 | } |
| 470 | 498 | } |
| 471 | 499 | |
| 472 | | static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) { |
| 500 | static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens, |
| 501 | ZigList<char *> *include_paths, Buf *cur_dir_path) |
| 502 | { |
| 473 | 503 | Preprocess p = {0}; |
| 474 | 504 | p.out_buf = buf_alloc(); |
| 475 | 505 | p.in_buf = in_buf; |
| 506 | p.include_paths = include_paths; |
| 507 | p.cur_dir_path = cur_dir_path; |
| 476 | 508 | for (int i = 0; i < tokens->length; i += 1) { |
| 477 | 509 | p.token = &tokens->at(i); |
| 478 | 510 | render_token(&p); |
| ... | ... | @@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) { |
| 480 | 512 | return p.out_buf; |
| 481 | 513 | } |
| 482 | 514 | |
| 515 | char cur_dir[1024]; |
| 516 | |
| 483 | 517 | int main(int argc, char **argv) { |
| 484 | 518 | char *arg0 = argv[0]; |
| 485 | 519 | char *in_file = NULL; |
| 486 | 520 | char *out_file = NULL; |
| 521 | ZigList<char *> include_paths = {0}; |
| 487 | 522 | for (int i = 1; i < argc; i += 1) { |
| 488 | 523 | char *arg = argv[i]; |
| 489 | 524 | if (arg[0] == '-' && arg[1] == '-') { |
| ... | ... | @@ -500,6 +535,8 @@ int main(int argc, char **argv) { |
| 500 | 535 | return usage(arg0); |
| 501 | 536 | } |
| 502 | 537 | } |
| 538 | } else if (arg[0] == '-' && arg[1] == 'I') { |
| 539 | include_paths.append(arg + 2); |
| 503 | 540 | } else if (!in_file) { |
| 504 | 541 | in_file = arg; |
| 505 | 542 | } else { |
| ... | ... | @@ -511,12 +548,18 @@ int main(int argc, char **argv) { |
| 511 | 548 | return usage(arg0); |
| 512 | 549 | |
| 513 | 550 | FILE *in_f; |
| 551 | Buf *cur_dir_path; |
| 514 | 552 | if (strcmp(in_file, "-") == 0) { |
| 515 | 553 | in_f = stdin; |
| 554 | char *result = getcwd(cur_dir, sizeof(cur_dir)); |
| 555 | if (!result) |
| 556 | zig_panic("unable to get current working directory: %s", strerror(errno)); |
| 557 | cur_dir_path = buf_from_str(result); |
| 516 | 558 | } else { |
| 517 | 559 | in_f = fopen(in_file, "rb"); |
| 518 | 560 | if (!in_f) |
| 519 | 561 | zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno)); |
| 562 | cur_dir_path = buf_dirname(buf_from_str(in_file)); |
| 520 | 563 | } |
| 521 | 564 | |
| 522 | 565 | Buf *in_data = fetch_file(in_f); |
| ... | ... | @@ -528,7 +571,7 @@ int main(int argc, char **argv) { |
| 528 | 571 | fprintf(stderr, "\nTokens:\n"); |
| 529 | 572 | print_tokens(in_data, tokens); |
| 530 | 573 | |
| 531 | | Buf *preprocessed_source = preprocess(in_data, tokens); |
| 574 | Buf *preprocessed_source = preprocess(in_data, tokens, &include_paths, cur_dir_path); |
| 532 | 575 | |
| 533 | 576 | fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source)); |
| 534 | 577 | |