| ... | @@ -25,6 +25,7 @@ static int usage(char *arg0) { | ... | @@ -25,6 +25,7 @@ static int usage(char *arg0) { |
| 25 | fprintf(stderr, "Usage: %s --output outfile code.zig\n" | 25 | fprintf(stderr, "Usage: %s --output outfile code.zig\n" |
| 26 | "Other options:\n" | 26 | "Other options:\n" |
| 27 | "--version print version number and exit\n" | 27 | "--version print version number and exit\n" |
| | 28 | "-Ipath add path to header include path\n" |
| 28 | , arg0); | 29 | , arg0); |
| 29 | return EXIT_FAILURE; | 30 | return EXIT_FAILURE; |
| 30 | } | 31 | } |
| ... | @@ -377,6 +378,8 @@ struct Preprocess { | ... | @@ -377,6 +378,8 @@ struct Preprocess { |
| 377 | Buf *out_buf; | 378 | Buf *out_buf; |
| 378 | Buf *in_buf; | 379 | Buf *in_buf; |
| 379 | Token *token; | 380 | Token *token; |
| | 381 | ZigList<char *> *include_paths; |
| | 382 | Buf *cur_dir_path; |
| 380 | }; | 383 | }; |
| 381 | | 384 | |
| 382 | __attribute__ ((format (printf, 2, 3))) | 385 | __attribute__ ((format (printf, 2, 3))) |
| ... | @@ -395,8 +398,33 @@ enum IncludeState { | ... | @@ -395,8 +398,33 @@ enum IncludeState { |
| 395 | IncludeStateQuote, | 398 | IncludeStateQuote, |
| 396 | }; | 399 | }; |
| 397 | | 400 | |
| 398 | static void render_include(Preprocess *p, Buf *include_path, char unquote_char) { | 401 | static Buf *find_include_file(Preprocess *p, char *dir_path, char *file_path) { |
| 399 | fprintf(stderr, "render_include \"%s\" '%c'\n", buf_ptr(include_path), unquote_char); | 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 | static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) { | 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,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 | Preprocess p = {0}; | 503 | Preprocess p = {0}; |
| 474 | p.out_buf = buf_alloc(); | 504 | p.out_buf = buf_alloc(); |
| 475 | p.in_buf = in_buf; | 505 | p.in_buf = in_buf; |
| | 506 | p.include_paths = include_paths; |
| | 507 | p.cur_dir_path = cur_dir_path; |
| 476 | for (int i = 0; i < tokens->length; i += 1) { | 508 | for (int i = 0; i < tokens->length; i += 1) { |
| 477 | p.token = &tokens->at(i); | 509 | p.token = &tokens->at(i); |
| 478 | render_token(&p); | 510 | render_token(&p); |
| ... | @@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) { | ... | @@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) { |
| 480 | return p.out_buf; | 512 | return p.out_buf; |
| 481 | } | 513 | } |
| 482 | | 514 | |
| | 515 | char cur_dir[1024]; |
| | 516 | |
| 483 | int main(int argc, char **argv) { | 517 | int main(int argc, char **argv) { |
| 484 | char *arg0 = argv[0]; | 518 | char *arg0 = argv[0]; |
| 485 | char *in_file = NULL; | 519 | char *in_file = NULL; |
| 486 | char *out_file = NULL; | 520 | char *out_file = NULL; |
| | 521 | ZigList<char *> include_paths = {0}; |
| 487 | for (int i = 1; i < argc; i += 1) { | 522 | for (int i = 1; i < argc; i += 1) { |
| 488 | char *arg = argv[i]; | 523 | char *arg = argv[i]; |
| 489 | if (arg[0] == '-' && arg[1] == '-') { | 524 | if (arg[0] == '-' && arg[1] == '-') { |
| ... | @@ -500,6 +535,8 @@ int main(int argc, char **argv) { | ... | @@ -500,6 +535,8 @@ int main(int argc, char **argv) { |
| 500 | return usage(arg0); | 535 | return usage(arg0); |
| 501 | } | 536 | } |
| 502 | } | 537 | } |
| | 538 | } else if (arg[0] == '-' && arg[1] == 'I') { |
| | 539 | include_paths.append(arg + 2); |
| 503 | } else if (!in_file) { | 540 | } else if (!in_file) { |
| 504 | in_file = arg; | 541 | in_file = arg; |
| 505 | } else { | 542 | } else { |
| ... | @@ -511,12 +548,18 @@ int main(int argc, char **argv) { | ... | @@ -511,12 +548,18 @@ int main(int argc, char **argv) { |
| 511 | return usage(arg0); | 548 | return usage(arg0); |
| 512 | | 549 | |
| 513 | FILE *in_f; | 550 | FILE *in_f; |
| | 551 | Buf *cur_dir_path; |
| 514 | if (strcmp(in_file, "-") == 0) { | 552 | if (strcmp(in_file, "-") == 0) { |
| 515 | in_f = stdin; | 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 | } else { | 558 | } else { |
| 517 | in_f = fopen(in_file, "rb"); | 559 | in_f = fopen(in_file, "rb"); |
| 518 | if (!in_f) | 560 | if (!in_f) |
| 519 | zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno)); | 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 | Buf *in_data = fetch_file(in_f); | 565 | Buf *in_data = fetch_file(in_f); |
| ... | @@ -528,7 +571,7 @@ int main(int argc, char **argv) { | ... | @@ -528,7 +571,7 @@ int main(int argc, char **argv) { |
| 528 | fprintf(stderr, "\nTokens:\n"); | 571 | fprintf(stderr, "\nTokens:\n"); |
| 529 | print_tokens(in_data, tokens); | 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 | fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source)); | 576 | fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source)); |
| 534 | | 577 | |