#include <string.h> #include <ctype.h> //String manipulation functions void strtrim(char **str, const char *trim) { //skip all the delimiter chars at the beginning while(**str && strchr(trim, **str)) (*str)++; //if we still have a non null string, trim from the back if (**str) { char *end = *str + strlen(*str); while(strchr(trim, *(--end))); *(++end) = 0; } } size_t strlen(const char *str) { size_t s = 0; while(*str++) s++; return s; } size_t strnlen(const char *str, size_t num) { size_t s = 0; while(*str++ && num--) s++; return s; } size_t wstrlen(const uint16_t *str) { size_t s = 0; while(*str++) s++; return s; } char* strcat(char *dest, const char *src) { char *rv = dest; while(*dest) dest++; do { *dest++ = *src; }while(*src++); return rv; } char* strncat(char *dest, const char *src, size_t num) { char *rv = dest; while(*dest) dest++; while(*src && num--) { *dest++ = *src++; } *dest = 0; return rv; } char* strchr(const char *str, char c) { while(*str) { if (*str == c) return (char*)str; str++; } if (*str == c) return (char*)str; else return 0; } int strcmp(const char *str1, const char *str2) { while(*str1 && *str2) { if ((*str1) > (*str2)) return 1; else if ((*str1) < (*str2)) return -1; str1++; str2++; } if (*str1) return 1; else if (*str2) return -1; return 0; } int strncmp(const char *str1, const char *str2, size_t num) { while(*str1 && *str2 && num) { if ((*str1) > (*str2)) return 1; else if ((*str1) < (*str2)) return -1; str1++; str2++; num--; } if (num == 0) return 0; else if (*str1) return 1; else if (*str2) return -1; return 0; } int stricmp(const char *str1, const char *str2) { while(*str1 && *str2) { if (tolower(*str1) > tolower(*str2)) return 1; else if (tolower(*str1) < tolower(*str2)) return -1; str1++; str2++; } if (*str1) return 1; else if (*str2) return -1; return 0; } int strincmp(const char *str1, const char *str2, size_t num) { while(*str1 && *str2 && num) { if (tolower(*str1) > tolower(*str2)) return 1; else if (tolower(*str1) < tolower(*str2)) return -1; str1++; str2++; num--; } if (num == 0) return 0; else if (*str1) return 1; else if (*str2) return -1; return 0; } char* strcpy(char *dest, const char *src) { char *rv = dest; do { *dest++ = *src; }while(*src++); return rv; } char* strncpy(char *dest, const char *src, size_t num) { char *rv = dest; while(*src && num) { *dest++ = *src++; num--; } while(num--) *dest++ = 0; return rv; } size_t strspn(const char *str1, const char *str2) { size_t span = 0; while(*str1 && strchr(str2, *str1)) { str1++; span++; } return span; } size_t strcspn(const char *str1, const char *str2) { size_t span = 0; while(*str1 && !strchr(str2, *str1)) { str1++; span++; } return span; } //char *strdup(const char *s1); //const char* strpbrk(const char *str1, const char *str2); char* strpbrk(char *str1, const char *str2) { while(*str1) { if (strchr(str2, *str1)) return str1; str1++; } return 0; } /* const char* strstr(const char *str1, const char *str2) { const char *ptr1 = str1; const char *ptr2 = str2; while(*str1) { if (*ptr2 == 0) return str1; if (*ptr1 == *ptr2) { ptr1++; ptr2++; } else { ptr2 = str2; str1++; ptr1 = str1; } } return 0; } */ char* strstr(char *str1, const char *str2) { char *ptr1 = str1; const char *ptr2 = str2; while(*str1) { if (*ptr2 == 0) return str1; if (*ptr1 == *ptr2) { ptr1++; ptr2++; } else { ptr2 = str2; str1++; ptr1 = str1; } } return 0; } char* stristr(char *str1, const char *str2) { char *ptr1 = str1; const char *ptr2 = str2; while(*str1) { if (*ptr2 == 0) return str1; if (tolower(*ptr1) == tolower(*ptr2)) { ptr1++; ptr2++; } else { ptr2 = str2; str1++; ptr1 = str1; } } return 0; } char* strtok(char *str, const char *delim) { static char *saveptr; if (str) saveptr = str; if (*saveptr == 0) return 0; //find first non-delimiter while(*saveptr && strchr(delim, *saveptr)) saveptr++; char *result = saveptr; while(*saveptr && !strchr(delim, *saveptr)) saveptr++; if (*saveptr) *saveptr++ = 0; return result; } char* strtok_r(char *str, const char *delim, char **saveptr) { if (str) *saveptr = str; if (**saveptr == 0) return 0; //find first non-delimiter while(**saveptr && strchr(delim, **saveptr)) (*saveptr)++; char *result = *saveptr; while(**saveptr && !strchr(delim, **saveptr)) (*saveptr)++; if (**saveptr) *(*saveptr)++ = 0; return result; } char* strtok_m(char *str, const char *delim, const char* token_markers) { static char *saveptr; if (str) saveptr = str; if (*saveptr == 0) return 0; const size_t stm = strlen(token_markers); uint8_t tm_count[stm]; memset(tm_count, 0, sizeof(tm_count)); //find first non-delimiter while(*saveptr && strchr(delim, *saveptr)) saveptr++; char *result = saveptr; uint8_t inside = 0; while(*saveptr) { char *ptr; ptr = strchr(token_markers, *saveptr); if (ptr) { ptrdiff_t i = ptr - token_markers; tm_count[i] = !tm_count[i]; inside = 0; for(uint32_t i = 0; i < stm; i++) if (tm_count[i]) { inside = 1; break; } } else { //check if inside token marker if (!inside && strchr(delim, *saveptr)) break; } saveptr++; } if (*saveptr) *saveptr++ = 0; return result; } char* strtok_rm(char *str, const char *delim, char **saveptr, const char* token_markers) { if (str) *saveptr = str; if (**saveptr == 0) return 0; const size_t stm = strlen(token_markers); uint8_t tm_count[stm]; memset(tm_count, 0, sizeof(tm_count)); //find first non-delimiter while(**saveptr && strchr(delim, **saveptr)) (*saveptr)++; char *result = *saveptr; uint8_t inside = 0; while(**saveptr) { char *ptr; ptr = strchr(token_markers, **saveptr); if (ptr) { ptrdiff_t i = ptr - token_markers; tm_count[i] = !tm_count[i]; inside = 0; for(uint32_t i = 0; i < stm; i++) if (tm_count[i]) { inside = 1; break; } } else { if (!inside && strchr(delim, **saveptr)) break; } (*saveptr)++; } if (**saveptr) *(*saveptr)++ = 0; return result; } //memory functions void* memcpy(void* dest, const void* src, size_t num) { #define BLOCK_SIZE (sizeof(uint32_t) << 2) if (num) { const uint8_t* sptr = (const uint8_t*)src; uint8_t* dptr = (uint8_t*)dest; if ((num >= BLOCK_SIZE) && (((uintptr_t)sptr & (sizeof(uint32_t) - 1)) == 0) && (((uintptr_t)dptr & (sizeof(uint32_t) - 1)) == 0)) { const uint32_t* sptr_aligned = (const uint32_t*)sptr; uint32_t* dptr_aligned = (uint32_t*)dptr; while(num >= BLOCK_SIZE) { *dptr_aligned++ = *sptr_aligned++; *dptr_aligned++ = *sptr_aligned++; *dptr_aligned++ = *sptr_aligned++; *dptr_aligned++ = *sptr_aligned++; num -= BLOCK_SIZE; } while(num >= sizeof(uint32_t)) { *dptr_aligned++ = *sptr_aligned++; num -= sizeof(uint32_t); } sptr = (const uint8_t*)sptr_aligned; dptr = (uint8_t*)dptr_aligned; } while(num--) *dptr++ = *sptr++; } return dest; } void* memmove(void* dest, const void* src, size_t num) { if (dest == src) return dest; const uint8_t* src_p8 = (const uint8_t*)src; uint8_t* dest_p8 = (uint8_t*)dest; if (src < dest) { //copy from back src_p8 += num - 1; dest_p8 += num - 1; while(num--) *dest_p8-- = *src_p8--; } else { //copy from front while(num--) *dest_p8++ = *src_p8++; } return dest; } //const void* memchr(const void *ptr, uint8_t value, size_t num); //void* memchr(void *ptr, uint8_t value, size_t num); int memcmp(const void* ptr1, const void* ptr2, size_t num) { const uint8_t* l_ptr8 = (const uint8_t*)ptr1; const uint8_t* r_ptr8 = (const uint8_t*)ptr2; while(num--) { if (*l_ptr8 > *r_ptr8) return 1; else if (*l_ptr8 < *r_ptr8) return -1; l_ptr8++; r_ptr8++; } return 0; } void* memset(void* ptr, uint8_t value, size_t num) { #define BLOCK_SIZE (sizeof(uint32_t) << 2) if (num) { uint8_t* dptr = (uint8_t*)ptr; if ((num >= BLOCK_SIZE) && (((uintptr_t)dptr & (sizeof(uint32_t) - 1)) == 0)) { const uint32_t value32 = ((uint32_t)value << 24) + ((uint32_t)value << 16) + ((uint32_t)value << 8) + (uint32_t)value; uint32_t* dptr_aligned = (uint32_t*)dptr; while(num >= BLOCK_SIZE) { *dptr_aligned++ = value32; *dptr_aligned++ = value32; *dptr_aligned++ = value32; *dptr_aligned++ = value32; num -= BLOCK_SIZE; } while(num >= sizeof(uint32_t)) { *dptr_aligned++ = value32; num -= sizeof(uint32_t); } dptr = (uint8_t*)dptr_aligned; } while(num--) *dptr++ = value; } return ptr; } const char* strfile(const char *fullpath) { const char *ptr = fullpath + strlen(fullpath); while(ptr >= fullpath) { if (*ptr == '/') return ptr + 1; ptr--; } return fullpath; }