Skip to content

Commit

Permalink
string[1/2]: added more string manipulation functions.
Browse files Browse the repository at this point in the history
strpbrk, strstr, strsep, strcasecmp, strncasecmp.
fixed return type of snprintf.

Signed-off-by: Deepak Gupta <[email protected]>
  • Loading branch information
dkgupta-amzn committed Sep 4, 2020
1 parent 280e9fb commit dd61a7a
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
128 changes: 127 additions & 1 deletion include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef KTF_STRING_H
#define KTF_STRING_H
#include <asm-macros.h>
#include <slab.h>

static inline __used int isspace(int c) { return c == ' ' || c == '\t'; }

Expand Down Expand Up @@ -182,6 +183,21 @@ static inline int strcmp(const char *s1, const char *s2) {
return res;
}

static inline char *strncpy(char *d, const char *s, size_t n) {
char *copy = d;

while (n) {
*copy++ = *s++;
if (*s == '\0')
break;
n--;
}

memset(copy, '\0', n);

return d;
}

static inline char *strchr(const char *s, int c) {
if (NULL == s)
return NULL;
Expand Down Expand Up @@ -222,11 +238,121 @@ static inline int string_equal(const char *s1, const char *s2) {
return (!s1 || !s2) ? s1 == s2 : !strcmp(s1, s2);
}

static inline char *strpbrk(const char *s, const char *chars) {
for (int i = 0; s[i] != '\0'; i++) {
for (int j = 0; chars[j] != '\0'; j++) {
if (s[i] == chars[j]) {
return (char *) &s[i];
}
}
}

return NULL;
}

static inline char *strstr(const char *s1, const char *s2) {
char *a = NULL, *b = NULL;

b = (char *) s2;
/* s2 is NULL terminated, return entire s1 */
if ('\0' == *b) {
return (char *) s1;
}

/* first char match in s1 */
for (; *s1 != '\0'; s1++) {
if (*s1 != *b) {
continue;
}
/* record the position */
a = (char *) s1;

while (1) {
/* s2 has been searched, return s1 */
if (*b == '\0') {
return (char *) s1;
}
/* no match, break and find new a */
if (*a++ != *b++) {
break;
}
}
/* rewind b all the way back to s2 start */
b = (char *) s2;
}

return NULL;
}

static inline char *strsep(char **str, char *delim) {
char *spanp = NULL, *s = NULL;
int c, sc;
char *tok = NULL;

s = *str;
if (NULL == s)
return NULL;

for (tok = s;; ++s) {
c = *s;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == '\0') {
*str = NULL;
return (tok == s ? NULL : tok);
}
*s++ = '\0';
*str = s;
return tok;
}
} while (sc);
}
}

static inline int strcasecmp(const char *s1, const char *s2) {
unsigned char res, c1, c2;

if (s1 == s2)
return 0;

while (1) {
c1 = tolower(*(unsigned char *) s1);
s1++;
c2 = tolower(*(unsigned char *) s2);
s2++;
res = c1 - c2;
if ((res != 0 || c1 == 0 || c2 == 0))
break;
}

return res;
}

static inline int strncasecmp(const char *s1, const char *s2, size_t n) {
unsigned char res = 0, c1, c2;

if (s1 == s2)
return 0;

while (n--) {
c1 = tolower(*(unsigned char *) s1);
s1++;
c2 = tolower(*(unsigned char *) s2);
s2++;
res = c1 - c2;
if (res != 0 || c1 == 0 || c2 == 0)
break;
}

return res;
}

/* External declarations */

extern unsigned long strtoul(const char *nptr, char **endptr, int base);
extern long strtol(const char *nptr, char **endptr, int base);
extern int vsnprintf(char *str, size_t size, char const *fmt, va_list ap);
extern void snprintf(char *buf, size_t size, const char *fmt, ...);
extern int snprintf(char *buf, size_t size, const char *fmt, ...);

#endif /* KTF_STRING_H */
7 changes: 5 additions & 2 deletions lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,14 @@ reswitch: switch (ch = (unsigned char)*fmt++) {
#undef PCHAR
}

void snprintf(char *buf, size_t size, const char *fmt, ...) {
int snprintf(char *buf, size_t size, const char *fmt, ...) {
va_list args;
int retval = 0;

va_start(args, fmt);
vsnprintf(buf, size, fmt, args);
retval = vsnprintf(buf, size, fmt, args);
va_end(args);

return retval;
}
/* clang-format on */

0 comments on commit dd61a7a

Please sign in to comment.