From: Piotr Dymacz Date: Wed, 19 Mar 2014 10:01:45 +0000 (+0100) Subject: Add missing Hush shell code in other files X-Git-Tag: 2014-11-19~24^2~7 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=23955df2b92a923c319cc74b099e385c38955a81;p=oweals%2Fu-boot_mod.git Add missing Hush shell code in other files --- diff --git a/u-boot/common/cmd_bootm.c b/u-boot/common/cmd_bootm.c index 53634f2..c71d293 100755 --- a/u-boot/common/cmd_bootm.c +++ b/u-boot/common/cmd_bootm.c @@ -36,6 +36,10 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CFG_HUSH_PARSER +#include +#endif + /* cmd_boot.c */ extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -397,6 +401,28 @@ void print_image_hdr(tplink_image_header_t *hdr){ } #endif /* defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || defined(CONFIG_FOR_DLINK_DIR505_A1) || defined(CONFIG_FOR_DRAGINO_V2) */ +#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) +int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ + int rcode = 0; +#ifndef CFG_HUSH_PARSER + if(run_command (getenv ("bootcmd"), flag) < 0){ + rcode = 1; + } +#else + if(parse_string_outer(getenv("bootcmd"), FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){ + rcode = 1; + } +#endif + return(rcode); +} + +U_BOOT_CMD(boot, 1, 1, do_bootd, "boot default, i.e., run 'bootcmd'\n", NULL); + +/* keep old command name "bootd" for backward compatibility */ +U_BOOT_CMD(bootd, 1, 1, do_bootd, "boot default, i.e., run 'bootcmd'\n", NULL); + +#endif /* CONFIG_COMMANDS & CFG_CMD_BOOTD */ + #if (CONFIG_COMMANDS & CFG_CMD_IMI) int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ ulong addr; diff --git a/u-boot/common/command.c b/u-boot/common/command.c index d96b3a5..4678656 100755 --- a/u-boot/common/command.c +++ b/u-boot/common/command.c @@ -67,6 +67,152 @@ int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ U_BOOT_CMD(echo, CFG_MAXARGS, 1, do_echo, "echo args to console\n", "[args..]\n" "\t- echo args to console; \\c suppresses newline\n"); #endif /* CFG_CMD_ECHO */ + +#ifdef CFG_HUSH_PARSER +int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ + char **ap; + int left, adv, expr, last_expr, neg, last_cmp; + + /* args? */ + if (argc < 3){ + return(1); + } + +#if 0 + printf("test:"); + left = 1; + while (argv[left]){ + printf(" %s", argv[left++]); + } +#endif + + last_expr = 0; + left = argc - 1; ap = argv + 1; + + if(left > 0 && strcmp(ap[0], "!") == 0){ + neg = 1; + ap++; + left--; + } else { + neg = 0; + } + + expr = -1; + last_cmp = -1; + last_expr = -1; + + while(left > 0){ + + if(strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0){ + adv = 1; + } else if(strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0){ + adv = 2; + } else { + adv = 3; + } + + if(left < adv){ + expr = 1; + break; + } + + if(adv == 1){ + if (strcmp(ap[0], "-o") == 0){ + last_expr = expr; + last_cmp = 0; + } else if(strcmp(ap[0], "-a") == 0){ + last_expr = expr; + last_cmp = 1; + } else { + expr = 1; + break; + } + } + + if(adv == 2){ + if (strcmp(ap[0], "-z") == 0){ + expr = strlen(ap[1]) == 0 ? 1 : 0; + } else if(strcmp(ap[0], "-n") == 0){ + expr = strlen(ap[1]) == 0 ? 0 : 1; + } else { + expr = 1; + break; + } + + if(last_cmp == 0){ + expr = last_expr || expr; + } else if(last_cmp == 1){ + expr = last_expr && expr; + } + last_cmp = -1; + } + + if(adv == 3){ + if(strcmp(ap[1], "=") == 0){ + expr = strcmp(ap[0], ap[2]) == 0; + } else if(strcmp(ap[1], "!=") == 0){ + expr = strcmp(ap[0], ap[2]) != 0; + } else if(strcmp(ap[1], ">") == 0){ + expr = strcmp(ap[0], ap[2]) > 0; + } else if(strcmp(ap[1], "<") == 0){ + expr = strcmp(ap[0], ap[2]) < 0; + } else if(strcmp(ap[1], "-eq") == 0){ + expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10); + } else if(strcmp(ap[1], "-ne") == 0){ + expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10); + } else if(strcmp(ap[1], "-lt") == 0){ + expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10); + } else if(strcmp(ap[1], "-le") == 0){ + expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10); + } else if(strcmp(ap[1], "-gt") == 0){ + expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10); + } else if(strcmp(ap[1], "-ge") == 0){ + expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10); + } else { + expr = 1; + break; + } + + if(last_cmp == 0){ + expr = last_expr || expr; + } else if(last_cmp == 1){ + expr = last_expr && expr; + } + last_cmp = -1; + } + + ap += adv; left -= adv; + } + + if(neg){ + expr = !expr; + } + + expr = !expr; + +#if 0 + printf(": returns %d\n", expr); +#endif + + return(expr); +} + +U_BOOT_CMD(test, CFG_MAXARGS, 1, do_test, "minimal test like /bin/sh\n", "[args..]\n" +"\t- test functionality\n"); + +int do_exit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ + int r = 0; + + if(argc > 1){ + r = simple_strtoul(argv[1], NULL, 10); + } + + return(-r - 2); +} + +U_BOOT_CMD(exit, 2, 1, do_exit, "exit script\n", "\n\t- exit functionality\n"); +#endif /* CFG_HUSH_PARSER */ + /* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages diff --git a/u-boot/common/main.c b/u-boot/common/main.c index 65bef06..d5ff950 100755 --- a/u-boot/common/main.c +++ b/u-boot/common/main.c @@ -26,6 +26,10 @@ #include #include +#ifdef CFG_HUSH_PARSER +#include +#endif + #ifdef CONFIG_SILENT_CONSOLE DECLARE_GLOBAL_DATA_PTR; #endif @@ -116,16 +120,24 @@ static __inline__ int abortboot(int bootdelay){ /****************************************************************************/ void main_loop(void){ +#ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; +#endif int counter = 0; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; +#endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */ +#ifdef CFG_HUSH_PARSER + u_boot_hush_start(); +#endif + +#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) // get boot delay (seconds) s = getenv("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; @@ -220,7 +232,11 @@ void main_loop(void){ if(bootdelay >= 0 && s && !abortboot(bootdelay)){ // try to boot - run_command(s, 0); +#ifndef CFG_HUSH_PARSER + run_command(s, 0); +#else + parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); +#endif // something goes wrong! printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n"); @@ -231,6 +247,11 @@ void main_loop(void){ /* * Main Loop for Monitor Command Processing */ +#ifdef CFG_HUSH_PARSER + parse_file_outer(); + /* This point is never reached */ + for (;;); +#else for(;;){ len = readline(CFG_PROMPT); @@ -252,6 +273,7 @@ void main_loop(void){ lastcommand[0] = 0; } } +#endif /* CFG_HUSH_PARSER */ } /****************************************************************************/ @@ -654,10 +676,15 @@ int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){ printf("## Error: \"%s\" not defined\n", argv[i]); return(1); } - +#ifndef CFG_HUSH_PARSER if(run_command(arg, flag) == -1){ return(1); } +#else + if (parse_string_outer(arg, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){ + return(1); + } +#endif /* CFG_HUSH_PARSER */ } return(0); diff --git a/u-boot/lib_bootstrap/string.c b/u-boot/lib_bootstrap/string.c index 6675571..e0b793a 100755 --- a/u-boot/lib_bootstrap/string.c +++ b/u-boot/lib_bootstrap/string.c @@ -20,13 +20,50 @@ #include #include + +#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ +/** + * strnicmp - Case insensitive, length-limited string comparison + * @s1: One string + * @s2: The other string + * @len: the maximum number of characters to compare + */ +int strnicmp(const char *s1, const char *s2, size_t len) +{ + /* Yes, Virginia, it had better be unsigned */ + unsigned char c1, c2; + + c1 = 0; c2 = 0; + if (len) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if (!c1) + break; + if (!c2) + break; + if (c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while (--len); + } + return (int)c1 - (int)c2; +} +#endif + +char * ___strtok; + #ifndef __HAVE_ARCH_STRCPY /** * strcpy - Copy a %NUL terminated string * @dest: Where to copy the string to * @src: Where to copy the string from */ -char * strcpy(char * dest,const char *src){ +char * strcpy(char * dest,const char *src) +{ char *tmp = dest; while ((*dest++ = *src++) != '\0') @@ -46,7 +83,8 @@ char * strcpy(char * dest,const char *src){ * However, the result is not %NUL-terminated if the source exceeds * @count bytes. */ -char * strncpy(char * dest,const char *src,size_t count){ +char * strncpy(char * dest,const char *src,size_t count) +{ char *tmp = dest; while (count-- && (*dest++ = *src++) != '\0') @@ -62,7 +100,8 @@ char * strncpy(char * dest,const char *src,size_t count){ * @dest: The string to be appended to * @src: The string to append to it */ -char * strcat(char * dest, const char * src){ +char * strcat(char * dest, const char * src) +{ char *tmp = dest; while (*dest) @@ -74,13 +113,43 @@ char * strcat(char * dest, const char * src){ } #endif +#ifndef __HAVE_ARCH_STRNCAT +/** + * strncat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @count: The maximum numbers of bytes to copy + * + * Note that in contrast to strncpy, strncat ensures the result is + * terminated. + */ +char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} +#endif + #ifndef __HAVE_ARCH_STRCMP /** * strcmp - Compare two strings * @cs: One string * @ct: Another string */ -int strcmp(const char * cs,const char * ct){ +int strcmp(const char * cs,const char * ct) +{ register signed char __res; while (1) { @@ -99,7 +168,8 @@ int strcmp(const char * cs,const char * ct){ * @ct: Another string * @count: The maximum number of bytes to compare */ -int strncmp(const char * cs,const char * ct,size_t count){ +int strncmp(const char * cs,const char * ct,size_t count) +{ register signed char __res = 0; while (count) { @@ -118,7 +188,8 @@ int strncmp(const char * cs,const char * ct,size_t count){ * @s: The string to be searched * @c: The character to search for */ -char * strchr(const char * s, int c){ +char * strchr(const char * s, int c) +{ for(; *s != (char) c; ++s) if (*s == '\0') return NULL; @@ -126,12 +197,30 @@ char * strchr(const char * s, int c){ } #endif +#ifndef __HAVE_ARCH_STRRCHR +/** + * strrchr - Find the last occurrence of a character in a string + * @s: The string to be searched + * @c: The character to search for + */ +char * strrchr(const char * s, int c) +{ + const char *p = s + strlen(s); + do { + if (*p == (char)c) + return (char *)p; + } while (--p >= s); + return NULL; +} +#endif + #ifndef __HAVE_ARCH_STRLEN /** * strlen - Find the length of a string * @s: The string to be sized */ -size_t strlen(const char * s){ +size_t strlen(const char * s) +{ const char *sc; for (sc = s; *sc != '\0'; ++sc) @@ -146,7 +235,8 @@ size_t strlen(const char * s){ * @s: The string to be sized * @count: The maximum number of bytes to search */ -size_t strnlen(const char * s, size_t count){ +size_t strnlen(const char * s, size_t count) +{ const char *sc; for (sc = s; count-- && *sc != '\0'; ++sc) @@ -155,6 +245,21 @@ size_t strnlen(const char * s, size_t count){ } #endif +#ifndef __HAVE_ARCH_STRDUP +char * strdup(const char *s) +{ + char *new; + + if ((s == NULL) || + ((new = malloc (strlen(s) + 1)) == NULL) ) { + return NULL; + } + + strcpy (new, s); + return new; +} +#endif + #ifndef __HAVE_ARCH_STRSPN /** * strspn - Calculate the length of the initial substring of @s which only @@ -162,7 +267,8 @@ size_t strnlen(const char * s, size_t count){ * @s: The string to be searched * @accept: The string to search for */ -size_t strspn(const char *s, const char *accept){ +size_t strspn(const char *s, const char *accept) +{ const char *p; const char *a; size_t count = 0; @@ -187,7 +293,8 @@ size_t strspn(const char *s, const char *accept){ * @cs: The string to be searched * @ct: The characters to search for */ -char * strpbrk(const char * cs,const char * ct){ +char * strpbrk(const char * cs,const char * ct) +{ const char *sc1,*sc2; for( sc1 = cs; *sc1 != '\0'; ++sc1) { @@ -200,6 +307,91 @@ char * strpbrk(const char * cs,const char * ct){ } #endif +#ifndef __HAVE_ARCH_STRTOK +/** + * strtok - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * WARNING: strtok is deprecated, use strsep instead. + */ +char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} +#endif + +#ifndef __HAVE_ARCH_STRSEP +/** + * strsep - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * strsep() updates @s to point after the token, ready for the next call. + * + * It returns empty tokens, too, behaving exactly like the libc function + * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. + * Same semantics, slimmer shape. ;) + */ +char * strsep(char **s, const char *ct) +{ + char *sbegin = *s, *end; + + if (sbegin == NULL) + return NULL; + + end = strpbrk(sbegin, ct); + if (end) + *end++ = '\0'; + *s = end; + + return sbegin; +} +#endif + +#ifndef __HAVE_ARCH_STRSWAB +/** + * strswab - swap adjacent even and odd bytes in %NUL-terminated string + * s: address of the string + * + * returns the address of the swapped string or NULL on error. If + * string length is odd, last byte is untouched. + */ +char *strswab(const char *s) +{ + char *p, *q; + + if ((NULL == s) || ('\0' == *s)) { + return (NULL); + } + + for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) { + char tmp; + + tmp = *p; + *p = *q; + *q = tmp; + } + + return (char *) s; +} +#endif + #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value @@ -209,7 +401,8 @@ char * strpbrk(const char * cs,const char * ct){ * * Do not use memset() to access IO space, use memset_io() instead. */ -void * memset(void * s,int c,size_t count){ +void * memset(void * s,int c,size_t count) +{ char *xs = (char *) s; while (count--) @@ -219,6 +412,30 @@ void * memset(void * s,int c,size_t count){ } #endif +#ifndef __HAVE_ARCH_BCOPY +/** + * bcopy - Copy one area of memory to another + * @src: Where to copy from + * @dest: Where to copy to + * @count: The size of the area. + * + * Note that this is the same as memcpy(), with the arguments reversed. + * memcpy() is the standard, bcopy() is a legacy BSD function. + * + * You should not use this function to access IO space, use memcpy_toio() + * or memcpy_fromio() instead. + */ +char * bcopy(const char * src, char * dest, int count) +{ + char *tmp = dest; + + while (count--) + *tmp++ = *src++; + + return dest; +} +#endif + #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another @@ -229,7 +446,8 @@ void * memset(void * s,int c,size_t count){ * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void * dest,const void *src,size_t count){ +void * memcpy(void * dest,const void *src,size_t count) +{ char *tmp = (char *) dest, *s = (char *) src; while (count--) @@ -248,7 +466,8 @@ void * memcpy(void * dest,const void *src,size_t count){ * * Unlike memcpy(), memmove() copes with overlapping areas. */ -void * memmove(void * dest,const void *src,size_t count){ +void * memmove(void * dest,const void *src,size_t count) +{ char *tmp, *s; if (dest <= src) { @@ -275,7 +494,8 @@ void * memmove(void * dest,const void *src,size_t count){ * @ct: Another area of memory * @count: The size of the area. */ -int memcmp(const void * cs,const void * ct,size_t count){ +int memcmp(const void * cs,const void * ct,size_t count) +{ const unsigned char *su1, *su2; int res = 0; @@ -286,13 +506,38 @@ int memcmp(const void * cs,const void * ct,size_t count){ } #endif +#ifndef __HAVE_ARCH_MEMSCAN +/** + * memscan - Find a character in an area of memory. + * @addr: The memory area + * @c: The byte to search for + * @size: The size of the area. + * + * returns the address of the first occurrence of @c, or 1 byte past + * the area if @c is not found + */ +void * memscan(void * addr, int c, size_t size) +{ + unsigned char * p = (unsigned char *) addr; + + while (size) { + if (*p == c) + return (void *) p; + p++; + size--; + } + return (void *) p; +} +#endif + #ifndef __HAVE_ARCH_STRSTR /** * strstr - Find the first substring in a %NUL terminated string * @s1: The string to be searched * @s2: The string to search for */ -char * strstr(const char * s1,const char * s2){ +char * strstr(const char * s1,const char * s2) +{ int l1, l2; l2 = strlen(s2); @@ -308,3 +553,26 @@ char * strstr(const char * s1,const char * s2){ return NULL; } #endif + +#ifndef __HAVE_ARCH_MEMCHR +/** + * 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; +} + +#endif diff --git a/u-boot/lib_generic/string.c b/u-boot/lib_generic/string.c index 6675571..0e99d1b 100755 --- a/u-boot/lib_generic/string.c +++ b/u-boot/lib_generic/string.c @@ -20,13 +20,50 @@ #include #include + +#ifndef __HAVE_ARCH_STRNICMP +/** + * strnicmp - Case insensitive, length-limited string comparison + * @s1: One string + * @s2: The other string + * @len: the maximum number of characters to compare + */ +int strnicmp(const char *s1, const char *s2, size_t len) +{ + /* Yes, Virginia, it had better be unsigned */ + unsigned char c1, c2; + + c1 = 0; c2 = 0; + if (len) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if (!c1) + break; + if (!c2) + break; + if (c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while (--len); + } + return (int)c1 - (int)c2; +} +#endif + +char * ___strtok; + #ifndef __HAVE_ARCH_STRCPY /** * strcpy - Copy a %NUL terminated string * @dest: Where to copy the string to * @src: Where to copy the string from */ -char * strcpy(char * dest,const char *src){ +char * strcpy(char * dest,const char *src) +{ char *tmp = dest; while ((*dest++ = *src++) != '\0') @@ -46,7 +83,8 @@ char * strcpy(char * dest,const char *src){ * However, the result is not %NUL-terminated if the source exceeds * @count bytes. */ -char * strncpy(char * dest,const char *src,size_t count){ +char * strncpy(char * dest,const char *src,size_t count) +{ char *tmp = dest; while (count-- && (*dest++ = *src++) != '\0') @@ -62,7 +100,8 @@ char * strncpy(char * dest,const char *src,size_t count){ * @dest: The string to be appended to * @src: The string to append to it */ -char * strcat(char * dest, const char * src){ +char * strcat(char * dest, const char * src) +{ char *tmp = dest; while (*dest) @@ -74,13 +113,43 @@ char * strcat(char * dest, const char * src){ } #endif +#ifndef __HAVE_ARCH_STRNCAT +/** + * strncat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @count: The maximum numbers of bytes to copy + * + * Note that in contrast to strncpy, strncat ensures the result is + * terminated. + */ +char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} +#endif + #ifndef __HAVE_ARCH_STRCMP /** * strcmp - Compare two strings * @cs: One string * @ct: Another string */ -int strcmp(const char * cs,const char * ct){ +int strcmp(const char * cs,const char * ct) +{ register signed char __res; while (1) { @@ -99,7 +168,8 @@ int strcmp(const char * cs,const char * ct){ * @ct: Another string * @count: The maximum number of bytes to compare */ -int strncmp(const char * cs,const char * ct,size_t count){ +int strncmp(const char * cs,const char * ct,size_t count) +{ register signed char __res = 0; while (count) { @@ -118,7 +188,8 @@ int strncmp(const char * cs,const char * ct,size_t count){ * @s: The string to be searched * @c: The character to search for */ -char * strchr(const char * s, int c){ +char * strchr(const char * s, int c) +{ for(; *s != (char) c; ++s) if (*s == '\0') return NULL; @@ -126,12 +197,30 @@ char * strchr(const char * s, int c){ } #endif +#ifndef __HAVE_ARCH_STRRCHR +/** + * strrchr - Find the last occurrence of a character in a string + * @s: The string to be searched + * @c: The character to search for + */ +char * strrchr(const char * s, int c) +{ + const char *p = s + strlen(s); + do { + if (*p == (char)c) + return (char *)p; + } while (--p >= s); + return NULL; +} +#endif + #ifndef __HAVE_ARCH_STRLEN /** * strlen - Find the length of a string * @s: The string to be sized */ -size_t strlen(const char * s){ +size_t strlen(const char * s) +{ const char *sc; for (sc = s; *sc != '\0'; ++sc) @@ -146,7 +235,8 @@ size_t strlen(const char * s){ * @s: The string to be sized * @count: The maximum number of bytes to search */ -size_t strnlen(const char * s, size_t count){ +size_t strnlen(const char * s, size_t count) +{ const char *sc; for (sc = s; count-- && *sc != '\0'; ++sc) @@ -155,6 +245,21 @@ size_t strnlen(const char * s, size_t count){ } #endif +#ifndef __HAVE_ARCH_STRDUP +char * strdup(const char *s) +{ + char *new; + + if ((s == NULL) || + ((new = malloc (strlen(s) + 1)) == NULL) ) { + return NULL; + } + + strcpy (new, s); + return new; +} +#endif + #ifndef __HAVE_ARCH_STRSPN /** * strspn - Calculate the length of the initial substring of @s which only @@ -162,7 +267,8 @@ size_t strnlen(const char * s, size_t count){ * @s: The string to be searched * @accept: The string to search for */ -size_t strspn(const char *s, const char *accept){ +size_t strspn(const char *s, const char *accept) +{ const char *p; const char *a; size_t count = 0; @@ -187,7 +293,8 @@ size_t strspn(const char *s, const char *accept){ * @cs: The string to be searched * @ct: The characters to search for */ -char * strpbrk(const char * cs,const char * ct){ +char * strpbrk(const char * cs,const char * ct) +{ const char *sc1,*sc2; for( sc1 = cs; *sc1 != '\0'; ++sc1) { @@ -200,6 +307,91 @@ char * strpbrk(const char * cs,const char * ct){ } #endif +#ifndef __HAVE_ARCH_STRTOK +/** + * strtok - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * WARNING: strtok is deprecated, use strsep instead. + */ +char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} +#endif + +#ifndef __HAVE_ARCH_STRSEP +/** + * strsep - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * strsep() updates @s to point after the token, ready for the next call. + * + * It returns empty tokens, too, behaving exactly like the libc function + * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. + * Same semantics, slimmer shape. ;) + */ +char * strsep(char **s, const char *ct) +{ + char *sbegin = *s, *end; + + if (sbegin == NULL) + return NULL; + + end = strpbrk(sbegin, ct); + if (end) + *end++ = '\0'; + *s = end; + + return sbegin; +} +#endif + +#ifndef __HAVE_ARCH_STRSWAB +/** + * strswab - swap adjacent even and odd bytes in %NUL-terminated string + * s: address of the string + * + * returns the address of the swapped string or NULL on error. If + * string length is odd, last byte is untouched. + */ +char *strswab(const char *s) +{ + char *p, *q; + + if ((NULL == s) || ('\0' == *s)) { + return (NULL); + } + + for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) { + char tmp; + + tmp = *p; + *p = *q; + *q = tmp; + } + + return (char *) s; +} +#endif + #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value @@ -209,7 +401,8 @@ char * strpbrk(const char * cs,const char * ct){ * * Do not use memset() to access IO space, use memset_io() instead. */ -void * memset(void * s,int c,size_t count){ +void * memset(void * s,int c,size_t count) +{ char *xs = (char *) s; while (count--) @@ -219,6 +412,30 @@ void * memset(void * s,int c,size_t count){ } #endif +#ifndef __HAVE_ARCH_BCOPY +/** + * bcopy - Copy one area of memory to another + * @src: Where to copy from + * @dest: Where to copy to + * @count: The size of the area. + * + * Note that this is the same as memcpy(), with the arguments reversed. + * memcpy() is the standard, bcopy() is a legacy BSD function. + * + * You should not use this function to access IO space, use memcpy_toio() + * or memcpy_fromio() instead. + */ +char * bcopy(const char * src, char * dest, int count) +{ + char *tmp = dest; + + while (count--) + *tmp++ = *src++; + + return dest; +} +#endif + #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another @@ -229,7 +446,8 @@ void * memset(void * s,int c,size_t count){ * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void * dest,const void *src,size_t count){ +void * memcpy(void * dest,const void *src,size_t count) +{ char *tmp = (char *) dest, *s = (char *) src; while (count--) @@ -248,7 +466,8 @@ void * memcpy(void * dest,const void *src,size_t count){ * * Unlike memcpy(), memmove() copes with overlapping areas. */ -void * memmove(void * dest,const void *src,size_t count){ +void * memmove(void * dest,const void *src,size_t count) +{ char *tmp, *s; if (dest <= src) { @@ -275,7 +494,8 @@ void * memmove(void * dest,const void *src,size_t count){ * @ct: Another area of memory * @count: The size of the area. */ -int memcmp(const void * cs,const void * ct,size_t count){ +int memcmp(const void * cs,const void * ct,size_t count) +{ const unsigned char *su1, *su2; int res = 0; @@ -286,13 +506,38 @@ int memcmp(const void * cs,const void * ct,size_t count){ } #endif +#ifndef __HAVE_ARCH_MEMSCAN +/** + * memscan - Find a character in an area of memory. + * @addr: The memory area + * @c: The byte to search for + * @size: The size of the area. + * + * returns the address of the first occurrence of @c, or 1 byte past + * the area if @c is not found + */ +void * memscan(void * addr, int c, size_t size) +{ + unsigned char * p = (unsigned char *) addr; + + while (size) { + if (*p == c) + return (void *) p; + p++; + size--; + } + return (void *) p; +} +#endif + #ifndef __HAVE_ARCH_STRSTR /** * strstr - Find the first substring in a %NUL terminated string * @s1: The string to be searched * @s2: The string to search for */ -char * strstr(const char * s1,const char * s2){ +char * strstr(const char * s1,const char * s2) +{ int l1, l2; l2 = strlen(s2); @@ -308,3 +553,26 @@ char * strstr(const char * s1,const char * s2){ return NULL; } #endif + +#ifndef __HAVE_ARCH_MEMCHR +/** + * 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; +} + +#endif