Skip to content

Commit

Permalink
binarybuffer: str_to_buf(): align prefix to TCL syntax
Browse files Browse the repository at this point in the history
Integer values are interpreted by TCL as decimal, binary, octal
or hexadecimal if prepended with '0d', '0b', '0o' or '0x'
respectively.
The case of '0' prefix has been interpreted as octal till TCL 8.6
but is interpreted as part of a decimal number by JimTCL and from
TCL 9.

Align str_to_buf() to latest TCL syntax by:
- addding support for '0d', '0b' and '0o' prefix;
- dropping support for '0' prefix.

Change-Id: I708ef72146d75b7bf429df329a0269cf48700a44
Signed-off-by: Antonio Borneo <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/8465
Tested-by: jenkins
Reviewed-by: Jan Matyas <[email protected]>
  • Loading branch information
borneoa committed Sep 7, 2024
1 parent e09bb72 commit 4680d6e
Showing 1 changed file with 33 additions and 46 deletions.
79 changes: 33 additions & 46 deletions src/helper/binarybuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,60 +192,47 @@ char *buf_to_hex_str(const void *_buf, unsigned buf_len)
return str;
}

static bool str_has_hex_prefix(const char *s)
{
/* Starts with "0x" or "0X" */
return (s[0] == '0') && (s[1] == 'x' || s[1] == 'X');
}

static bool str_has_octal_prefix(const char *s)
{
/* - starts with '0',
* - has at least two characters, and
* - the second character is not 'x' or 'X' */
return (s[0] == '0') && (s[1] != '\0') && (s[1] != 'x') && (s[1] != 'X');
}

/**
* Try to identify the radix of the number by looking at its prefix.
* No further validation of the number is preformed.
/*
* TCL standard prefix is '0b', '0o', '0d' or '0x' respectively for binary,
* octal, decimal or hexadecimal.
* The prefix '0' is interpreted by TCL <= 8.6 as octal, but is ignored and
* interpreted as part of a decimal number by JimTCL and by TCL >= 9.
*/
static unsigned int str_radix_guess(const char *str)
{
if (str_has_hex_prefix(str))
return 16;

if (str_has_octal_prefix(str))
return 8;

/* Otherwise assume a decimal number. */
return 10;
}

/** Strip leading "0x" or "0X" from hex numbers or "0" from octal numbers. */
static const char *str_strip_number_prefix(const char *str, unsigned int radix)
{
switch (radix) {
case 16:
return str + 2;
case 8:
return str + 1;
case 10:
default:
return str;
}
}

int str_to_buf(const char *str, void *_buf, unsigned int buf_bitsize)
{
assert(str);
assert(_buf);
assert(buf_bitsize > 0);

uint8_t *buf = _buf;
unsigned int radix = str_radix_guess(str);

str = str_strip_number_prefix(str, radix);
unsigned int radix = 10; /* default when no prefix */

if (str[0] == '0') {
switch (str[1]) {
case 'b':
case 'B':
radix = 2;
str += 2;
break;
case 'o':
case 'O':
radix = 8;
str += 2;
break;
case 'd':
case 'D':
radix = 10;
str += 2;
break;
case 'x':
case 'X':
radix = 16;
str += 2;
break;
default:
break;
}
}

const size_t str_len = strlen(str);
if (str_len == 0)
Expand Down

0 comments on commit 4680d6e

Please sign in to comment.