diff --git a/contrib/bash_compl/_rgbasm.bash b/contrib/bash_compl/_rgbasm.bash index f07a0ab4..4a70fabd 100755 --- a/contrib/bash_compl/_rgbasm.bash +++ b/contrib/bash_compl/_rgbasm.bash @@ -189,6 +189,7 @@ _rgbasm_completions() { shift shift-amount truncation + unmapped-char user all extra diff --git a/contrib/zsh_compl/_rgbasm b/contrib/zsh_compl/_rgbasm index 03619e21..a27fe46c 100644 --- a/contrib/zsh_compl/_rgbasm +++ b/contrib/zsh_compl/_rgbasm @@ -25,6 +25,7 @@ _rgbasm_warnings() { 'shift:Warn when shifting negative values' 'shift-amount:Warn when a shift'\''s operand it negative or \> 32' 'truncation:Warn when implicit truncation loses bits' + 'unmapped-char:Warn on unmapped character' 'user:Warn when executing the WARN built-in' ) # TODO: handle `no-` and `error=` somehow? diff --git a/include/asm/warning.h b/include/asm/warning.h index f49ed95b..1cadc59d 100644 --- a/include/asm/warning.h +++ b/include/asm/warning.h @@ -24,7 +24,7 @@ enum WarningID { WARNING_ASSERT, // Assertions WARNING_BACKWARDS_FOR, // `for` loop with backwards range WARNING_BUILTIN_ARG, // Invalid args to builtins - WARNING_CHARMAP_REDEF, // Charmap entry re-definition + WARNING_CHARMAP_REDEF, // Charmap entry re-definition WARNING_DIV, // Division undefined behavior WARNING_EMPTY_DATA_DIRECTIVE, // `db`, `dw` or `dl` directive without data in ROM WARNING_EMPTY_MACRO_ARG, // Empty macro argument @@ -36,6 +36,7 @@ enum WarningID { WARNING_OBSOLETE, // Obsolete things WARNING_SHIFT, // Shifting undefined behavior WARNING_SHIFT_AMOUNT, // Strange shift amount + WARNING_UNMAPPED_CHAR, // Character without charmap entry WARNING_USER, // User warnings NB_PLAIN_WARNINGS, diff --git a/man/rgbasm.1 b/man/rgbasm.1 index e19e907c..f12e9dbf 100644 --- a/man/rgbasm.1 +++ b/man/rgbasm.1 @@ -274,6 +274,12 @@ warns when an N-bit value's absolute value is 2**N or greater. or just .Fl Wtruncation also warns when an N-bit value is less than -2**(N-1), which will not fit in two's complement encoding. +.It Fl Wunmapped-char +Warn when a character goes through charmap conversion but has no defined mapping. +This warning is always disabled if the active charmap is empty, and/or is the default charmap +.Sq main . +This warning is enabled by +.Fl Wall . .It Fl Wno-user Warn when the .Ic WARN diff --git a/src/asm/charmap.c b/src/asm/charmap.c index 13d120f4..c8a780d6 100644 --- a/src/asm/charmap.c +++ b/src/asm/charmap.c @@ -242,6 +242,7 @@ size_t charmap_ConvertNext(char const **input, uint8_t **output) return 1; } else if (**input) { // No match found, but there is some input left + int firstChar = **input; // This will write the codepoint's value to `output`, little-endian size_t codepointLen = readUTF8Char(output ? *output : NULL, *input); @@ -254,6 +255,12 @@ size_t charmap_ConvertNext(char const **input, uint8_t **output) if (output) *output += codepointLen; + // Check if the character map is not the default "main" one, or if + // it has any mappings defined + if (strcmp(charmap->name, "main") || charmap->usedNodes > 1) + warning(WARNING_UNMAPPED_CHAR, + "Unmapped character %s\n", printChar(firstChar)); + return codepointLen; } else { // End of input diff --git a/src/asm/warning.c b/src/asm/warning.c index 12dfca56..ab59f3d8 100644 --- a/src/asm/warning.c +++ b/src/asm/warning.c @@ -38,6 +38,7 @@ static const enum WarningState defaultWarnings[ARRAY_SIZE(warningStates)] = { [WARNING_OBSOLETE] = WARNING_ENABLED, [WARNING_SHIFT] = WARNING_DISABLED, [WARNING_SHIFT_AMOUNT] = WARNING_DISABLED, + [WARNING_UNMAPPED_CHAR] = WARNING_ENABLED, [WARNING_USER] = WARNING_ENABLED, [WARNING_NUMERIC_STRING_1] = WARNING_ENABLED, @@ -85,6 +86,7 @@ static const char * const warningFlags[NB_WARNINGS] = { "obsolete", "shift", "shift-amount", + "unmapped-char", "user", // Parametric warnings @@ -160,6 +162,7 @@ static uint8_t const _wallCommands[] = { WARNING_LONG_STR, WARNING_NESTED_COMMENT, WARNING_OBSOLETE, + WARNING_UNMAPPED_CHAR, WARNING_NUMERIC_STRING_1, META_WARNING_DONE }; @@ -191,6 +194,7 @@ static uint8_t const _weverythingCommands[] = { WARNING_OBSOLETE, WARNING_SHIFT, WARNING_SHIFT_AMOUNT, + WARNING_UNMAPPED_CHAR, WARNING_NUMERIC_STRING_1, WARNING_NUMERIC_STRING_2, WARNING_TRUNCATION_1, diff --git a/test/asm/charlen-charsub.asm b/test/asm/charlen-charsub.asm index c2ae8bbb..0fb7f682 100644 --- a/test/asm/charlen-charsub.asm +++ b/test/asm/charlen-charsub.asm @@ -1,3 +1,4 @@ + opt Wno-unmapped-char charmap "", $00 charmap "A", $10 charmap "B", $20 diff --git a/test/asm/multiple-charmaps.asm b/test/asm/multiple-charmaps.asm index 2be557f2..5b709ff5 100644 --- a/test/asm/multiple-charmaps.asm +++ b/test/asm/multiple-charmaps.asm @@ -1,3 +1,5 @@ +opt Wno-unmapped-char + new_: MACRO IF _NARG > 1 println "newcharmap \1, \2" diff --git a/test/asm/multiple-charmaps.err b/test/asm/multiple-charmaps.err index 22d25d28..1abc37ad 100644 --- a/test/asm/multiple-charmaps.err +++ b/test/asm/multiple-charmaps.err @@ -1,19 +1,19 @@ -warning: multiple-charmaps.asm(39) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(41) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -warning: multiple-charmaps.asm(47) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(49) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -warning: multiple-charmaps.asm(66) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(68) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -warning: multiple-charmaps.asm(89) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(91) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -warning: multiple-charmaps.asm(90) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(92) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -warning: multiple-charmaps.asm(98) -> multiple-charmaps.asm::print_mapped(27): [-Wnumeric-string] +warning: multiple-charmaps.asm(100) -> multiple-charmaps.asm::print_mapped(29): [-Wnumeric-string] Treating 2-character string as a number -error: multiple-charmaps.asm(100) -> multiple-charmaps.asm::new_(7): +error: multiple-charmaps.asm(102) -> multiple-charmaps.asm::new_(9): Charmap 'map1' already exists -error: multiple-charmaps.asm(102) -> multiple-charmaps.asm::set_(13): +error: multiple-charmaps.asm(104) -> multiple-charmaps.asm::set_(15): Charmap 'map5' doesn't exist -error: multiple-charmaps.asm(104) -> multiple-charmaps.asm::pop_(23): +error: multiple-charmaps.asm(106) -> multiple-charmaps.asm::pop_(25): No entries in the charmap stack error: Assembly aborted (3 errors)! diff --git a/test/asm/unmapped-char.asm b/test/asm/unmapped-char.asm new file mode 100644 index 00000000..1627fb3a --- /dev/null +++ b/test/asm/unmapped-char.asm @@ -0,0 +1,18 @@ +SECTION "test", ROM0 + + db "A" ; OK, default empty charmap + + pushc + newcharmap custom + db "A" ; unmapped in non-default charmap + popc + + db "A" ; OK, default empty charmap again + + charmap "B", $42 + db "A" ; unmapped in non-empty charmap + + println "A" ; does not use charmap + + opt Wno-unmapped-char + db "A" ; warning silenced diff --git a/test/asm/unmapped-char.err b/test/asm/unmapped-char.err new file mode 100644 index 00000000..e87e80e4 --- /dev/null +++ b/test/asm/unmapped-char.err @@ -0,0 +1,4 @@ +warning: unmapped-char.asm(7): [-Wunmapped-char] + Unmapped character 'A' +warning: unmapped-char.asm(13): [-Wunmapped-char] + Unmapped character 'A' diff --git a/test/asm/unmapped-char.out b/test/asm/unmapped-char.out new file mode 100644 index 00000000..f70f10e4 --- /dev/null +++ b/test/asm/unmapped-char.out @@ -0,0 +1 @@ +A diff --git a/test/asm/unmapped-char.out.bin b/test/asm/unmapped-char.out.bin new file mode 100644 index 00000000..6a64303c --- /dev/null +++ b/test/asm/unmapped-char.out.bin @@ -0,0 +1 @@ +AAAAA \ No newline at end of file diff --git a/test/asm/warn-numeric-string.asm b/test/asm/warn-numeric-string.asm index 7140e43f..38bbee8c 100644 --- a/test/asm/warn-numeric-string.asm +++ b/test/asm/warn-numeric-string.asm @@ -1,6 +1,6 @@ +opt Wno-unmapped-char charmap "", $00 - SECTION "ROM", ROM0 MACRO try