shithub: rgbds

Download patch

ref: 8207dc57b7e74303e3bec0ba82db1b41a08a66b2
parent: d29057e747ea96c9398e516ec76a0e141f0a3feb
author: Rangi <35663410+Rangi42@users.noreply.github.com>
date: Sun Aug 28 11:12:43 EDT 2022

Add a `-Wunmapped-char` warning for characters not in the charmap (#1023)

Fixes #1022

--- a/contrib/bash_compl/_rgbasm.bash
+++ b/contrib/bash_compl/_rgbasm.bash
@@ -189,6 +189,7 @@
 				shift
 				shift-amount
 				truncation
+				unmapped-char
 				user
 				all
 				extra
--- a/contrib/zsh_compl/_rgbasm
+++ b/contrib/zsh_compl/_rgbasm
@@ -25,6 +25,7 @@
 		'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?
--- a/include/asm/warning.h
+++ b/include/asm/warning.h
@@ -24,7 +24,7 @@
 	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 @@
 	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,
--- a/man/rgbasm.1
+++ b/man/rgbasm.1
@@ -274,6 +274,12 @@
 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
--- a/src/asm/charmap.c
+++ b/src/asm/charmap.c
@@ -242,6 +242,7 @@
 				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);
@@ -253,6 +254,12 @@
 				*input += codepointLen;
 				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;
 
--- a/src/asm/warning.c
+++ b/src/asm/warning.c
@@ -38,6 +38,7 @@
 	[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 @@
 	"obsolete",
 	"shift",
 	"shift-amount",
+	"unmapped-char",
 	"user",
 
 	// Parametric warnings
@@ -160,6 +162,7 @@
 	WARNING_LONG_STR,
 	WARNING_NESTED_COMMENT,
 	WARNING_OBSOLETE,
+	WARNING_UNMAPPED_CHAR,
 	WARNING_NUMERIC_STRING_1,
 	META_WARNING_DONE
 };
@@ -191,6 +194,7 @@
 	WARNING_OBSOLETE,
 	WARNING_SHIFT,
 	WARNING_SHIFT_AMOUNT,
+	WARNING_UNMAPPED_CHAR,
 	WARNING_NUMERIC_STRING_1,
 	WARNING_NUMERIC_STRING_2,
 	WARNING_TRUNCATION_1,
--- a/test/asm/charlen-charsub.asm
+++ b/test/asm/charlen-charsub.asm
@@ -1,3 +1,4 @@
+	opt Wno-unmapped-char
 	charmap "<NULL>", $00
 	charmap "A", $10
 	charmap "B", $20
--- 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"
--- 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)!
--- /dev/null
+++ b/test/asm/unmapped-char.asm
@@ -1,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
--- /dev/null
+++ b/test/asm/unmapped-char.err
@@ -1,0 +1,4 @@
+warning: unmapped-char.asm(7): [-Wunmapped-char]
+    Unmapped character 'A'
+warning: unmapped-char.asm(13): [-Wunmapped-char]
+    Unmapped character 'A'
--- /dev/null
+++ b/test/asm/unmapped-char.out
@@ -1,0 +1,1 @@
+A
--- /dev/null
+++ b/test/asm/unmapped-char.out.bin
@@ -1,0 +1,1 @@
+AAAAA
\ No newline at end of file
--- a/test/asm/warn-numeric-string.asm
+++ b/test/asm/warn-numeric-string.asm
@@ -1,5 +1,5 @@
+opt Wno-unmapped-char
 charmap "<NULL>", $00
-
 
 SECTION "ROM", ROM0