Re: [PATCH v3 0/7] lib: string: add functions to case-convert strings
On 9 July 2016 at 20:13, Chris Metcalfwrote: > On 7/8/2016 6:43 PM, Markus Mayer wrote: >> >> This series introduces a family of generic string case conversion >> functions. This kind of functionality is needed in several places in >> the kernel. Right now, everybody seems to be implementing their own >> copy of this functionality. >> >> Based on the discussion of the previous version of this series[1] and >> the use cases found in the kernel, it does look like having several >> flavours of case conversion functions is beneficial. The use cases fall >> into three categories: >> - copying a string and converting the case while specifying a >>maximum length to mimic strlcpy() >> - copying a string and converting the case without specifying a >>length to mimic strcpy() >> - converting the case of a string in-place (i.e. modifying the >>string that was passed in) >> >> Consequently, I am proposing these new functions: >> void strlcpytoupper(char *dst, const char *src, size_t len); >> void strlcpytolower(char *dst, const char *src, size_t len); >> void strcpytoupper(char *dst, const char *src); >> void strcpytolower(char *dst, const char *src); >> void strtoupper(char *s); >> void strtolower(char *s); > > > You may want to read the article here: > > https://lwn.net/Articles/659214/ I'll read that. Thanks. > and follow up some of the discussion threads on LKML about the best > semantics to advertise for the strlcpy/strscpy variants. It might be > helpful to return some kind of overflow/truncation error from your > copy functions so people can error-check the result. I am inclined to agree. However, everybody has been telling me that these functions should be void. Originally they weren't. Regards, -Markus -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/7] lib: string: add functions to case-convert strings
On 9 July 2016 at 05:04, Luis de Bethencourtwrote: > On 08/07/16 23:43, Markus Mayer wrote: >> Add a collection of generic functions to convert strings to lowercase >> or uppercase. >> >> Changing the case of a string (with or without copying it first) seems >> to be a recurring requirement in the kernel that is currently being >> solved by several duplicated implementations doing the same thing. This >> change aims at reducing this code duplication. >> >> The new functions are >> void strlcpytoupper(char *dst, const char *src, size_t len); >> void strlcpytolower(char *dst, const char *src, size_t len); >> void strcpytoupper(char *dst, const char *src); >> void strcpytolower(char *dst, const char *src); >> void strtoupper(char *s); >> void strtolower(char *s); >> >> The "str[l]cpyto*" versions of the function take a destination string >> and a source string as arguments. The "strlcpyto*" versions additionally >> take a length argument like strlcpy() itself. Lastly, the strto* >> functions take a single string argument and modify the passed-in string. >> >> Like strlcpy(), and unlike strncpy(), the functions guarantee NULL >> termination of the destination string. >> >> Signed-off-by: Markus Mayer >> --- >> include/linux/string.h | 40 >> lib/string.c | 38 ++ >> 2 files changed, 78 insertions(+) >> >> diff --git a/include/linux/string.h b/include/linux/string.h >> index 26b6f6a..36c9d14 100644 >> --- a/include/linux/string.h >> +++ b/include/linux/string.h >> @@ -116,6 +116,8 @@ extern void * memchr(const void *,int,__kernel_size_t); >> #endif >> void *memchr_inv(const void *s, int c, size_t n); >> char *strreplace(char *s, char old, char new); >> +extern void strlcpytoupper(char *dst, const char *src, size_t len); >> +extern void strlcpytolower(char *dst, const char *src, size_t len); >> >> extern void kfree_const(const void *x); >> >> @@ -169,4 +171,42 @@ static inline const char *kbasename(const char *path) >> return tail ? tail + 1 : path; >> } >> >> +/** >> + * strcpytoupper - Copy string and convert to uppercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to uppercase. >> + */ >> +static inline void strcpytoupper(char *dst, const char *src) >> +{ >> + strlcpytoupper(dst, src, -1); >> +} >> + > > Why not use SIZE_MAX instead of -1? Sure. I'll change all four of them. Thanks. >> +/** >> + * strcpytolower - Copy string and convert to lowercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to lowercase. >> + */ >> +static inline void strcpytolower(char *dst, const char *src) >> +{ >> + strlcpytolower(dst, src, -1); >> +} >> + > > Same here, and the 2 below :) > > Thanks Markus, > Luis > >> +/** >> + * strtoupper - Convert string to uppercase. >> + * @s: The string to operate on. >> + */ >> +static inline void strtoupper(char *s) >> +{ >> + strlcpytoupper(s, s, -1); >> +} >> + >> +/** >> + * strtolower - Convert string to lowercase. >> + * @s: The string to operate on. >> + */ >> +static inline void strtolower(char *s) >> +{ >> + strlcpytolower(s, s, -1); >> +} >> + >> #endif /* _LINUX_STRING_H_ */ >> diff --git a/lib/string.c b/lib/string.c >> index ed83562..fd8c427 100644 >> --- a/lib/string.c >> +++ b/lib/string.c >> @@ -952,3 +952,41 @@ char *strreplace(char *s, char old, char new) >> return s; >> } >> EXPORT_SYMBOL(strreplace); >> + >> +/** >> + * strlcpytoupper - Copy a length-limited string and convert to uppercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to uppercase. >> + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. >> + */ >> +void strlcpytoupper(char *dst, const char *src, size_t len) >> +{ >> + size_t i; >> + >> + if (!len) >> + return; >> + >> + for (i = 0; i < len && src[i]; ++i) >> + dst[i] = toupper(src[i]); >> + dst[i < len ? i : i - 1] = '\0'; >> +} >> +EXPORT_SYMBOL(strlcpytoupper); >> + >> +/** >> + * strlcpytolower - Copy a length-limited string and convert to lowercase. >> + * @dst: The buffer to store the result. >> + * @src: The string to convert to lowercase. >> + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. >> + */ >> +void strlcpytolower(char *dst, const char *src, size_t len) >> +{ >> + size_t i; >> + >> + if (!len) >> + return; >> + >> + for (i = 0; i < len && src[i]; ++i) >> + dst[i] = tolower(src[i]); >> + dst[i < len ? i : i - 1] = '\0'; >> +} >> +EXPORT_SYMBOL(strlcpytolower); >> > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/7] lib: string: add functions to case-convert strings
On 08/07/16 23:43, Markus Mayer wrote: > Add a collection of generic functions to convert strings to lowercase > or uppercase. > > Changing the case of a string (with or without copying it first) seems > to be a recurring requirement in the kernel that is currently being > solved by several duplicated implementations doing the same thing. This > change aims at reducing this code duplication. > > The new functions are > void strlcpytoupper(char *dst, const char *src, size_t len); > void strlcpytolower(char *dst, const char *src, size_t len); > void strcpytoupper(char *dst, const char *src); > void strcpytolower(char *dst, const char *src); > void strtoupper(char *s); > void strtolower(char *s); > > The "str[l]cpyto*" versions of the function take a destination string > and a source string as arguments. The "strlcpyto*" versions additionally > take a length argument like strlcpy() itself. Lastly, the strto* > functions take a single string argument and modify the passed-in string. > > Like strlcpy(), and unlike strncpy(), the functions guarantee NULL > termination of the destination string. > > Signed-off-by: Markus Mayer> --- > include/linux/string.h | 40 > lib/string.c | 38 ++ > 2 files changed, 78 insertions(+) > > diff --git a/include/linux/string.h b/include/linux/string.h > index 26b6f6a..36c9d14 100644 > --- a/include/linux/string.h > +++ b/include/linux/string.h > @@ -116,6 +116,8 @@ extern void * memchr(const void *,int,__kernel_size_t); > #endif > void *memchr_inv(const void *s, int c, size_t n); > char *strreplace(char *s, char old, char new); > +extern void strlcpytoupper(char *dst, const char *src, size_t len); > +extern void strlcpytolower(char *dst, const char *src, size_t len); > > extern void kfree_const(const void *x); > > @@ -169,4 +171,42 @@ static inline const char *kbasename(const char *path) > return tail ? tail + 1 : path; > } > > +/** > + * strcpytoupper - Copy string and convert to uppercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to uppercase. > + */ > +static inline void strcpytoupper(char *dst, const char *src) > +{ > + strlcpytoupper(dst, src, -1); > +} > + Why not use SIZE_MAX instead of -1? > +/** > + * strcpytolower - Copy string and convert to lowercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to lowercase. > + */ > +static inline void strcpytolower(char *dst, const char *src) > +{ > + strlcpytolower(dst, src, -1); > +} > + Same here, and the 2 below :) Thanks Markus, Luis > +/** > + * strtoupper - Convert string to uppercase. > + * @s: The string to operate on. > + */ > +static inline void strtoupper(char *s) > +{ > + strlcpytoupper(s, s, -1); > +} > + > +/** > + * strtolower - Convert string to lowercase. > + * @s: The string to operate on. > + */ > +static inline void strtolower(char *s) > +{ > + strlcpytolower(s, s, -1); > +} > + > #endif /* _LINUX_STRING_H_ */ > diff --git a/lib/string.c b/lib/string.c > index ed83562..fd8c427 100644 > --- a/lib/string.c > +++ b/lib/string.c > @@ -952,3 +952,41 @@ char *strreplace(char *s, char old, char new) > return s; > } > EXPORT_SYMBOL(strreplace); > + > +/** > + * strlcpytoupper - Copy a length-limited string and convert to uppercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to uppercase. > + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. > + */ > +void strlcpytoupper(char *dst, const char *src, size_t len) > +{ > + size_t i; > + > + if (!len) > + return; > + > + for (i = 0; i < len && src[i]; ++i) > + dst[i] = toupper(src[i]); > + dst[i < len ? i : i - 1] = '\0'; > +} > +EXPORT_SYMBOL(strlcpytoupper); > + > +/** > + * strlcpytolower - Copy a length-limited string and convert to lowercase. > + * @dst: The buffer to store the result. > + * @src: The string to convert to lowercase. > + * @len: Maximum string length. May be SIZE_MAX (-1) to set no limit. > + */ > +void strlcpytolower(char *dst, const char *src, size_t len) > +{ > + size_t i; > + > + if (!len) > + return; > + > + for (i = 0; i < len && src[i]; ++i) > + dst[i] = tolower(src[i]); > + dst[i < len ? i : i - 1] = '\0'; > +} > +EXPORT_SYMBOL(strlcpytolower); > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html