aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-07-07 15:05:39 +0100
committerMichael Brown <mcb30@ipxe.org>2023-07-07 15:14:00 +0100
commitc30b71ee9cc2dc2a1d2f225d99f2d70dd73de247 (patch)
tree57e80a0b4079fdcacfbc1b2082219ed0dafb3a28
parentf3036fc213b6e6cce0bf5572167b93b9e9959a3a (diff)
downloadipxe-keyvals.zip
ipxe-keyvals.tar.gz
ipxe-keyvals.tar.bz2
[console] Restore compatibility with "--key" values in existing scriptskeyvals
Commit 3ef4f7e ("[console] Avoid overlap between special keys and Unicode characters") renumbered the special key encoding to avoid collisions with Unicode key values outside the ASCII range. This change broke backwards compatibility with existing scripts that specify key values using e.g. "prompt --key" or "menu --key". Restore compatibility with existing scripts by tweaking the special key encoding so that the relative key value (i.e. the delta from KEY_MIN) is numerically equal to the old pre-Unicode key value, and by modifying parse_key() to accept a relative key value. Reported-by: Sven Dreyer <sven@dreyer-net.de> Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/core/parseopt.c15
-rw-r--r--src/include/ctype.h11
-rw-r--r--src/include/ipxe/keys.h8
3 files changed, 31 insertions, 3 deletions
diff --git a/src/core/parseopt.c b/src/core/parseopt.c
index 1dbfc7a..cd3b310 100644
--- a/src/core/parseopt.c
+++ b/src/core/parseopt.c
@@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <ipxe/netdevice.h>
@@ -35,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/settings.h>
#include <ipxe/params.h>
#include <ipxe/timer.h>
+#include <ipxe/keys.h>
#include <ipxe/parseopt.h>
#include <config/branding.h>
@@ -213,6 +215,7 @@ int parse_flag ( char *text __unused, int *flag ) {
* @ret rc Return status code
*/
int parse_key ( char *text, unsigned int *key ) {
+ int rc;
/* Interpret single characters as being a literal key character */
if ( text[0] && ! text[1] ) {
@@ -221,7 +224,17 @@ int parse_key ( char *text, unsigned int *key ) {
}
/* Otherwise, interpret as an integer */
- return parse_integer ( text, key );
+ if ( ( rc = parse_integer ( text, key ) ) < 0 )
+ return rc;
+
+ /* For backwards compatibility with existing scripts, treat
+ * integers between the ASCII range and special key range as
+ * being relative special key values.
+ */
+ if ( ( ! isascii ( *key ) ) && ( *key < KEY_MIN ) )
+ *key += KEY_MIN;
+
+ return 0;
}
/**
diff --git a/src/include/ctype.h b/src/include/ctype.h
index 0d79ecd..6fefd5d 100644
--- a/src/include/ctype.h
+++ b/src/include/ctype.h
@@ -10,6 +10,17 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
+ * Check if character is ASCII
+ *
+ * @v character Character
+ * @ret is_ascii Character is an ASCII character
+ */
+static inline int isascii ( int character ) {
+
+ return ( character <= '\x7f' );
+}
+
+/**
* Check if character is a decimal digit
*
* @v character ASCII character
diff --git a/src/include/ipxe/keys.h b/src/include/ipxe/keys.h
index 2335691..49e65fa 100644
--- a/src/include/ipxe/keys.h
+++ b/src/include/ipxe/keys.h
@@ -54,6 +54,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* The names are chosen to match those used by curses. The values are
* chosen to facilitate easy conversion from a received ANSI escape
* sequence to a KEY_XXX constant.
+ *
+ * Note that the values are exposed to iPXE commands via parse_key()
+ * and therefore may not be changed without breaking existing scripts.
*/
/**
@@ -79,7 +82,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @v terminator ANSI escape sequence terminating character
* @ret key Key value
*/
-#define KEY_ANSI( n, terminator ) ( KEY_MIN + ( (n) << 8 ) + (terminator) )
+#define KEY_ANSI( n, terminator ) \
+ ( KEY_MIN + ( ( (n) + 1 ) << 8 ) + (terminator) )
/**
* Extract ANSI escape sequence numeric portion
@@ -87,7 +91,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @v key Key value (or relative key value)
* @ret n ANSI escape sequence numeric portion, or 0 for none
*/
-#define KEY_ANSI_N( key ) ( ( (key) >> 8 ) & 0xff )
+#define KEY_ANSI_N( key ) ( ( ( (key) >> 8 ) & 0xff ) - 1 )
/**
* Extract ANSI escape sequence terminating character