hd44780-i2c
hd44780-i2c copied to clipboard
Small fix and add new escape sequence commands
Dear all,
please consider this PR composed by 4 commits:
- dcb7fbb -> small fix: after an if, before its body there is a ';'.
- ba097fa -> increase the buffer size, in order to make space for the '0'. I am not sure that this is a problem, however I think that it is better to have all the string 0 terminated.
-
ebd2ae2 -> add support for the
ESC [<r>;<c>H
command to allow the placing of the cursor at row 'r' and column 'c'. Also the following short versions are allowed:ESC [<r>H
andESC [;<c>H
. - d63a66c -> add further commands like:
- ESC c (RIS) reset to initial state
- ESC [ ? 25 h show cursor
- ESC [ ? 25 l hide cursor
- ESC [ 5 m blink on
- ESC [ 25 m blink of
ba097fa : Why do you care if this char array is anyhow terminated and if it's overwritten?
d63a66c : :+1:
ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)
Did you test all this stuff?
ba097fa : Why do you care if this char array is anyhow terminated and if it's overwritten?
This buffer is used by function like strcmp() which assumes the buffer is zero terminated. Event tough in this case there is no problem (strcmp works against static string with a length lesser than this buffer), I fear that in future developments this could lead to a buffer exploit.
ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)
The CUP escape sequence is quite complicate: all the following formats are allowed:
ESC [
(and the variants which end by 'f')
I tried also sscanf [*], but at the end I concluded that I would test all these cases separately (i.e. something like:
if (strcmp(buf, "[H") == 0) {
...
} else if (sscanf(buf, "[%dH", &r) == 1) {
....
} else if (sscanf(buf, "[;%dH", &c) == 1) {
....
} else if (sscanf(buf, "[%d;%dH", &r, &c) == 2) {
....
However sscanf don't check if the last char is 'H'....)
Did you test all this stuff?
Yes, see https://godbolt.org/z/C4gyHk
[*] If I used sscanf, the buffer would be needed terminated by '\0'....
ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)
The CUP escape sequence is quite complicate: all the following formats are allowed:
I tried to simplify the code. Let me know your opinion:
static inline int __isdigit(const char c)
{
return c >= '0' && c <= '9';
}
/*
* Be aware that the following function supports only positive conversion
*/
static inline int __atoi(const char *p)
{
int ret = 0;
while (__isdigit(*p))
ret = ret * 10 + *p++ - '0';
return ret;
}
static int hd44780_parse_cup_command(const char *p, int *pr, int *pc)
{
int r = 0;
*pr = *pc = -1;
if (*p != '[')
return -1;
p++;
while (r < 2) {
if (__isdigit(*p)) {
/* there is a numeric argument */
if (r==0)
/* first arg */
*pr = __atoi(p);
else
/* second arg */
*pc = __atoi(p);
while (__isdigit(*p))
p++;
} else if (*p == ';') {
/* there is another arg, continue */
p++;
r++;
} else if (*p == 'H'|| *p == 'f') {
/* no more arg, exit */
return 0;
} else {
/* unexpected char (not digit, nor ';' nor 'H'*/
return -2;
}
}
/* too much arg */
return -3;
}