diff options
| -rw-r--r-- | include/stdarg.h | 20 | ||||
| -rw-r--r-- | preprocess.c | 91 | ||||
| -rw-r--r-- | tests/066.sh | 15 |
3 files changed, 100 insertions, 26 deletions
diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 0000000..43138b6 --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,20 @@ +// System V Application Binary Interface +// AMD64 Architecture Processor Supplement +// (With LP64 and ILP32 Programming Models) +// Version 1.0 +// Figure 3.34: va_list Type Declaration +struct __va_list__ { + // unsigned int gp_offset; + // unsigned int fp_offset; + int gp_offset; + int fp_offset; + void* overflow_arg_area; + void* reg_save_area; +}; +// ducc currently does not support array type. +// typedef struct __va_list__ va_list[1]; +typedef struct __va_list__* va_list; + +// va_start() is currently implemented as a special form due to the limitation of #define macro. +void va_end(va_list args) { +} diff --git a/preprocess.c b/preprocess.c index 35aebad..4ffe12e 100644 --- a/preprocess.c +++ b/preprocess.c @@ -395,41 +395,80 @@ PpToken* process_ifdef_directive(Preprocessor* pp, PpToken* tok) { return NULL; } -PpToken* process_include_directive(Preprocessor* pp, PpToken* tok) { - PpToken* tok2 = skip_whitespace(tok + 1); - if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "include")) { +PpToken* read_include_header_name(PpToken* tok2, String* include_name) { + if (tok2->kind == PpTokenKind_string_literal) { + include_name->data = tok2->raw.data; + include_name->len = tok2->raw.len; ++tok2; - tok2 = skip_whitespace(tok2); - if (tok2->kind == PpTokenKind_string_literal) { - PpToken* include_name = tok2; + return tok2; + } else if (tok2->kind == PpTokenKind_punctuator && string_equals_cstr(&tok2->raw, "<")) { + char* include_name_start = tok2->raw.data; + ++tok2; + int include_name_len = 0; + while (tok2->kind != PpTokenKind_eof) { + if (tok2->kind == PpTokenKind_punctuator && string_equals_cstr(&tok2->raw, ">")) { + break; + } + include_name_len += tok2->raw.len; ++tok2; + } + if (tok2->kind == PpTokenKind_eof) { + fatal_error("invalid #include: <> not balanced"); + } + ++tok2; + include_name->data = include_name_start; + include_name->len = include_name_len + 2; + return tok2; + } +} - char* include_name_buf = calloc(include_name->raw.len - 2 + 1, sizeof(char)); - sprintf(include_name_buf, "%.*s", include_name->raw.len - 2, include_name->raw.data + 1); +const char* resolve_include_name(Preprocessor* pp, String* include_name) { + char* buf; + if (include_name->data[0] == '"') { + buf = calloc(include_name->len - 2 + 1, sizeof(char)); + sprintf(buf, "%.*s", include_name->len - 2, include_name->data + 1); + } else { + buf = calloc(include_name->len - 2 + 1 + strlen("/home/ken/src/ducc/include/"), sizeof(char)); + sprintf(buf, "/home/ken/src/ducc/include/%.*s", include_name->len - 2, include_name->data + 1); + } + return buf; +} - remove_directive_tokens(tok, tok2 + 1); +PpToken* replace_include_directive(Preprocessor* pp, PpToken* tok, PpToken* tok2, const char* include_name_buf) { + remove_directive_tokens(tok, tok2 + 1); - FILE* include_file = fopen(include_name_buf, "rb"); - if (include_file == NULL) { - fatal_error("cannot open include file: %s", include_name_buf); - } - char* include_source = read_all(include_file); - fclose(include_file); + FILE* include_file = fopen(include_name_buf, "rb"); + if (include_file == NULL) { + fatal_error("cannot open include file: %s", include_name_buf); + } + char* include_source = read_all(include_file); + fclose(include_file); - PpToken* include_pp_tokens = do_preprocess(include_source, pp->include_depth + 1, pp->pp_defines); + PpToken* include_pp_tokens = do_preprocess(include_source, pp->include_depth + 1, pp->pp_defines); - int n_include_pp_tokens = 0; - while (include_pp_tokens[n_include_pp_tokens].kind != PpTokenKind_eof) { - ++n_include_pp_tokens; - } + int n_include_pp_tokens = 0; + while (include_pp_tokens[n_include_pp_tokens].kind != PpTokenKind_eof) { + ++n_include_pp_tokens; + } - int n_pp_tokens_after_include = pp->n_pp_tokens - (tok - pp->pp_tokens); - memmove(tok + n_include_pp_tokens, tok, n_pp_tokens_after_include * sizeof(PpToken)); - memcpy(tok, include_pp_tokens, n_include_pp_tokens * sizeof(PpToken)); - pp->n_pp_tokens += n_include_pp_tokens; + int n_pp_tokens_after_include = pp->n_pp_tokens - (tok - pp->pp_tokens); + memmove(tok + n_include_pp_tokens, tok, n_pp_tokens_after_include * sizeof(PpToken)); + memcpy(tok, include_pp_tokens, n_include_pp_tokens * sizeof(PpToken)); + pp->n_pp_tokens += n_include_pp_tokens; - return tok + n_include_pp_tokens; - } + return tok + n_include_pp_tokens; +} + +PpToken* process_include_directive(Preprocessor* pp, PpToken* tok) { + PpToken* tok2 = skip_whitespace(tok + 1); + + if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "include")) { + ++tok2; + tok2 = skip_whitespace(tok2); + String* include_name = calloc(1, sizeof(String)); + tok2 = read_include_header_name(tok2, include_name); + const char* include_name_buf = resolve_include_name(pp, include_name); + return replace_include_directive(pp, tok, tok2, include_name_buf); } return NULL; } diff --git a/tests/066.sh b/tests/066.sh new file mode 100644 index 0000000..7ff5ed5 --- /dev/null +++ b/tests/066.sh @@ -0,0 +1,15 @@ +set -e + +cat <<'EOF' > expected +8 +EOF + +bash ../../test_diff.sh <<'EOF' +#include <stdarg.h> + +int printf(); + +int main() { + printf("%d\n", sizeof(va_list)); +} +EOF |
