aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-29 01:32:34 +0900
committernsfisis <nsfisis@gmail.com>2025-08-29 01:34:37 +0900
commitfc396d2b088a8b837f65b1e55a424372ade8bd37 (patch)
tree4fd534027318a9234dbd7fb1450495186b9efe94 /src
parent7c1f940960c3548b788b089c02e4dfd8277bf8fa (diff)
downloadducc-fc396d2b088a8b837f65b1e55a424372ade8bd37.tar.gz
ducc-fc396d2b088a8b837f65b1e55a424372ade8bd37.tar.zst
ducc-fc396d2b088a8b837f65b1e55a424372ade8bd37.zip
feat: support #error and #warning directives
Diffstat (limited to 'src')
-rw-r--r--src/preprocess.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/src/preprocess.c b/src/preprocess.c
index 893c0bb..3c71a53 100644
--- a/src/preprocess.c
+++ b/src/preprocess.c
@@ -1087,12 +1087,38 @@ static void preprocess_line_directive(Preprocessor* pp, int directive_token_pos)
unimplemented();
}
-static void preprocess_error_directive(Preprocessor* pp, int directive_token_pos) {
- unimplemented();
+// control-line:
+// ...
+// '#' 'error' pp-tokens? new-line
+static void preprocess_error_directive(Preprocessor* pp, int directive_token_pos, BOOL do_process) {
+ // The C23 standard does not specify format of diagnostic message caused by #error.
+ // Ducc assumes that #error takes exactly one argument consisting of a string literal.
+ // TODO: output some general message or something else if not.
+ skip_pp_token(pp, TokenKind_pp_directive_error);
+ skip_whitespaces(pp);
+ Token* msg = expect_pp_token(pp, TokenKind_literal_str);
+ skip_whitespaces(pp);
+ expect_pp_token(pp, TokenKind_newline);
+ if (do_process) {
+ fatal_error("%s:%d: %s", msg->loc.filename, msg->loc.line, msg->value.string);
+ }
}
-static void preprocess_warning_directive(Preprocessor* pp, int directive_token_pos) {
- unimplemented();
+// control-line:
+// ...
+// '#' 'warning' pp-tokens? new-line
+static void preprocess_warning_directive(Preprocessor* pp, int directive_token_pos, BOOL do_process) {
+ // The C23 standard does not specify format of diagnostic message caused by #warning.
+ // Ducc assumes that #warning takes exactly one argument consisting of a string literal.
+ // TODO: output some general message or something else if not.
+ skip_pp_token(pp, TokenKind_pp_directive_warning);
+ skip_whitespaces(pp);
+ Token* msg = expect_pp_token(pp, TokenKind_literal_str);
+ skip_whitespaces(pp);
+ expect_pp_token(pp, TokenKind_newline);
+ if (do_process) {
+ fprintf(stderr, "%s:%d: %s", msg->loc.filename, msg->loc.line, msg->value.string);
+ }
}
static void preprocess_pragma_directive(Preprocessor* pp, int directive_token_pos) {
@@ -1167,9 +1193,9 @@ static void preprocess_group_part(Preprocessor* pp, BOOL do_process) {
} else if (tok->kind == TokenKind_pp_directive_line) {
preprocess_line_directive(pp, first_token_pos);
} else if (tok->kind == TokenKind_pp_directive_error) {
- preprocess_error_directive(pp, first_token_pos);
+ preprocess_error_directive(pp, first_token_pos, do_process);
} else if (tok->kind == TokenKind_pp_directive_warning) {
- preprocess_warning_directive(pp, first_token_pos);
+ preprocess_warning_directive(pp, first_token_pos, do_process);
} else if (tok->kind == TokenKind_pp_directive_pragma) {
preprocess_pragma_directive(pp, first_token_pos);
} else if (tok->kind == TokenKind_pp_directive_nop) {