From: Sebastien Bourdeauducq Date: Fri, 25 May 2012 21:26:43 +0000 (+0200) Subject: software: more string functions X-Git-Tag: 24jan2021_ls180~3158 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4dbc938f7c1655c80f5ef84f64b90c4eda6ea4d5;p=litex.git software: more string functions --- diff --git a/software/bios/main.c b/software/bios/main.c index 275017f0..2eb1d49d 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/software/include/base/ctype.h b/software/include/base/ctype.h index a6c0dfbe..a996b288 100644 --- a/software/include/base/ctype.h +++ b/software/include/base/ctype.h @@ -1,51 +1,55 @@ #ifndef __CTYPE_H #define __CTYPE_H -static inline int isdigit(char c) -{ - return (c >= '0') && (c <= '9'); -} - -static inline int isxdigit(char c) -{ - return isdigit(c) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')); -} - -static inline int isupper(char c) -{ - return (c >= 'A') && (c <= 'Z'); -} - -static inline int islower(char c) -{ - return (c >= 'a') && (c <= 'z'); -} - -static inline unsigned char tolower(unsigned char c) +/* + * NOTE! This ctype does not handle EOF like the standard C + * library is required to. + */ + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +extern const unsigned char _ctype[]; + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +/* Note: isspace() must return false for %NUL-terminator */ +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) { if (isupper(c)) c -= 'A'-'a'; return c; } -static inline unsigned char toupper(unsigned char c) +static inline unsigned char __toupper(unsigned char c) { if (islower(c)) c -= 'a'-'A'; return c; } -static inline char isspace(unsigned char c) -{ - if(c == ' ' - || c == '\f' - || c == '\n' - || c == '\r' - || c == '\t' - || c == '\v') - return 1; - - return 0; -} +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) #endif /* __CTYPE_H */ diff --git a/software/include/base/stdlib.h b/software/include/base/stdlib.h index a31093ad..d51c5de8 100644 --- a/software/include/base/stdlib.h +++ b/software/include/base/stdlib.h @@ -44,7 +44,7 @@ static inline long atol(const char *nptr) { } char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type); long strtol(const char *nptr, char **endptr, int base); -float atof(const char *s); +double strtod(const char *str, char **endptr); #define RAND_MAX 2147483647 diff --git a/software/include/base/string.h b/software/include/base/string.h index 667d2d88..41705a36 100644 --- a/software/include/base/string.h +++ b/software/include/base/string.h @@ -19,9 +19,10 @@ #ifndef __STRING_H #define __STRING_H -#include +#include char *strchr(const char *s, int c); +char *strpbrk(const char *,const char *); char *strrchr(const char *s, int c); char *strnchr(const char *s, size_t count, int c); char *strcpy(char *dest, const char *src); @@ -30,10 +31,12 @@ int strcmp(const char *cs, const char *ct); int strncmp(const char *cs, const char *ct, size_t count); size_t strlen(const char *s); size_t strnlen(const char *s, size_t count); +size_t strspn(const char *s, const char *accept); int memcmp(const void *cs, const void *ct, size_t count); void *memset(void *s, int c, size_t count); void *memcpy(void *to, const void *from, size_t n); void *memmove(void *dest, const void *src, size_t count); char *strstr(const char *s1, const char *s2); +void *memchr(const void *s, int c, size_t n); #endif /* __STRING_H */ diff --git a/software/libbase/libc.c b/software/libbase/libc.c index 9d41e4cd..78e3823f 100644 --- a/software/libbase/libc.c +++ b/software/libbase/libc.c @@ -38,6 +38,24 @@ char *strchr(const char *s, int c) return (char *)s; } +/** + * strpbrk - Find the first occurrence of a set of characters + * @cs: The string to be searched + * @ct: The characters to search for + */ +char *strpbrk(const char *cs, const char *ct) +{ + const char *sc1, *sc2; + + for (sc1 = cs; *sc1 != '\0'; ++sc1) { + for (sc2 = ct; *sc2 != '\0'; ++sc2) { + if (*sc1 == *sc2) + return (char *)sc1; + } + } + return NULL; +} + /** * strrchr - Find the last occurrence of a character in a string * @s: The string to be searched @@ -171,6 +189,29 @@ size_t strnlen(const char *s, size_t count) return sc - s; } +/** + * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept + * @s: The string to be searched + * @accept: The string to search for + */ +size_t strspn(const char *s, const char *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) { + for (a = accept; *a != '\0'; ++a) { + if (*p == *a) + break; + } + if (*a == '\0') + return count; + ++count; + } + return count; +} + /** * memcmp - Compare two areas of memory * @cs: One area of memory @@ -303,6 +344,26 @@ char *strstr(const char *s1, const char *s2) return NULL; } +/** + * memchr - Find a character in an area of memory. + * @s: The memory area + * @c: The byte to search for + * @n: The size of the area. + * + * returns the address of the first occurrence of @c, or %NULL + * if @c is not found + */ +void *memchr(const void *s, int c, size_t n) +{ + const unsigned char *p = s; + while (n-- != 0) { + if ((unsigned char)c == *p++) { + return (void *)(p - 1); + } + } + return NULL; +} + /** * strtoul - convert a string to an unsigned long * @nptr: The start of the string @@ -561,6 +622,33 @@ int sprintf(char * buf, const char *fmt, ...) return i; } +/* From linux/lib/ctype.c, Copyright (C) 1991, 1992 Linus Torvalds */ +const unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + /** * rand - Returns a pseudo random number */