fix strptokspn, add strcspn, fix splash.c

fix off by 1 error in strptokspn, add strcspn, fix fallout in splash.c

Change-Id: I61475d9633fc35db5a8ae30cbe588f69f2f7fabc
This commit is contained in:
William Wilgus 2022-11-13 00:43:43 -05:00 committed by William Wilgus
parent ffe2df2e92
commit a634557a88
5 changed files with 65 additions and 36 deletions

View file

@ -73,11 +73,11 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
if (!next) if (!next)
return false; /* nothing to display */ return false; /* nothing to display */
lines[line].len = next_len + 1; lines[line].len = next_len;
lines[line].str = next; lines[line].str = next;
while (true) while (true)
{ {
w = font_getstringnsize(next, next_len + 1, NULL, NULL, fontnum); w = font_getstringnsize(next, next_len, NULL, NULL, fontnum);
if (lastbreak) if (lastbreak)
{ {
len = next - lastbreak; len = next - lastbreak;
@ -90,18 +90,19 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
break; /* screen full or out of lines */ break; /* screen full or out of lines */
x = 0; x = 0;
y += chr_h; y += chr_h;
lines[++line].len = next_len + len; lines[++line].len = next_len;
lines[line].str = next; lines[line].str = next;
} }
else else
{ {
/* restore & calculate spacing */ /* restore & calculate spacing */
lines[line].len += next_len + len + 1; lines[line].len += next_len + 1;
x += next_w; x += next_w;
} }
} }
x += w; x += w;
lastbreak = next + next_len + 1;
lastbreak = next + next_len;
lastbrkchr = *lastbreak; lastbrkchr = *lastbreak;
next = strptokspn_r(NULL, matchstr, &next_len, &store); next = strptokspn_r(NULL, matchstr, &next_len, &store);

View file

@ -1483,7 +1483,7 @@ static bool audio_init_codec(struct track_info *track_infop,
enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE }; enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE };
static bool autoresumable(struct mp3entry *id3) static bool autoresumable(struct mp3entry *id3)
{ {
char *endp, *path; char *path;
size_t len; size_t len;
bool is_resumable; bool is_resumable;
@ -1501,13 +1501,7 @@ static bool autoresumable(struct mp3entry *id3)
if (*path == ':') /* Skip empty search patterns */ if (*path == ':') /* Skip empty search patterns */
continue; continue;
/* FIXME: As soon as strcspn or strchrnul are made available in len = strcspn(path, ":");
the core, the following can be made more efficient. */
endp = strchr(path, ':');
if (endp)
len = endp - path;
else
len = strlen(path);
/* Note: At this point, len is always > 0 */ /* Note: At this point, len is always > 0 */

View file

@ -271,7 +271,7 @@ libc/strcat.c
libc/strchr.c libc/strchr.c
libc/strcmp.c libc/strcmp.c
libc/strcpy.c libc/strcpy.c
libc/strcspn.c
libc/strncmp.c libc/strncmp.c
libc/strrchr.c libc/strrchr.c
libc/strstr.c libc/strstr.c

View file

@ -39,40 +39,29 @@
* Pointer **end * Pointer **end
* *
* Note the returned token is NOT NULL terminated by the function as in strtok_r * Note the returned token is NOT NULL terminated by the function as in strtok_r
* However the caller can use ret[len+1] = '\0'; to emulate a call to strtok_r * However the caller can use ret[len] = '\0'; to emulate a call to strtok_r
*/ */
const char *strptokspn_r(const char *ptr, const char *sep, size_t *len, const char **end) const char *strptokspn_r(const char *ptr, const char *sep, size_t *len, const char **end)
{ {
*len = 0; if (ptr == NULL) /* we got NULL input so then we get last position instead */
if (!ptr) {
/* we got NULL input so then we get our last position instead */
ptr = *end; ptr = *end;
}
/* pass all letters that are including in the separator string */ /* pass all letters that are including in the separator string */
while (*ptr && strchr(sep, *ptr)) while (*ptr && strchr(sep, *ptr))
++ptr; ++ptr;
if (*ptr) { if (*ptr != '\0')
{
/* so this is where the next piece of string starts */ /* so this is where the next piece of string starts */
const char *start = ptr; const char *start = ptr;
*len = strcspn(ptr, sep); /* Get span until any sep character in string */
/* set the end pointer to the first byte after the start */ *end = ptr + *len;
*end = start + 1; if (**end) /* the end is not a null byte */
/* scan through the string to find where it ends, it ends on a
null byte or a character that exists in the separator string */
while (**end && !strchr(sep, **end))
++*end; ++*end;
*len = (*end - start) - 1; /* this would be the string len if there actually was a NULL */ return start;
if (**end) { /* the end is not a null byte */
++*end; /* advance last pointer to beyond the match */
}
return start; /* return the position where the string starts */
} }
/* we ended up on a null byte, there are no more strings to find! */
return NULL; return NULL;
} }
@ -82,7 +71,7 @@ char * strtok_r(char *ptr, const char *sep, char **end)
size_t len; size_t len;
char * ret = (char*) strptokspn_r((const char*)ptr, sep, &len, (const char**) end); char * ret = (char*) strptokspn_r((const char*)ptr, sep, &len, (const char**) end);
if (ret) if (ret)
ret[len + 1] = '\0'; ret[len] = '\0';
return ret; return ret;
} }
#endif #endif

45
firmware/libc/strcspn.c Normal file
View file

@ -0,0 +1,45 @@
/*
FUNCTION
<<strcspn>>---count characters not in string
INDEX
strcspn
ANSI_SYNOPSIS
size_t strcspn(const char *<[s1]>, const char *<[s2]>);
TRAD_SYNOPSIS
size_t strcspn(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
DESCRIPTION
This function computes the length of the initial part of
the string pointed to by <[s1]> which consists entirely of
characters <[NOT]> from the string pointed to by <[s2]>
(excluding the terminating null character).
RETURNS
<<strcspn>> returns the length of the substring found.
PORTABILITY
<<strcspn>> is ANSI C.
<<strcspn>> requires no supporting OS subroutines.
*/
#include <string.h>
#include "_ansi.h" /* for _DEFUN */
size_t
_DEFUN (strcspn, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *s = s1;
_CONST char *c;
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
return s1 - s;
}