diff options
Diffstat (limited to 'nuttx/lib')
-rw-r--r-- | nuttx/lib/Makefile | 5 | ||||
-rw-r--r-- | nuttx/lib/lib_fgets.c | 66 | ||||
-rw-r--r-- | nuttx/lib/lib_gets.c | 122 | ||||
-rw-r--r-- | nuttx/lib/lib_strtok.c | 87 | ||||
-rw-r--r-- | nuttx/lib/lib_strtokr.c | 196 |
5 files changed, 451 insertions, 25 deletions
diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile index cb77499c8..6d89ccaef 100644 --- a/nuttx/lib/Makefile +++ b/nuttx/lib/Makefile @@ -43,10 +43,11 @@ AOBJS = $(ASRCS:.S=$(OBJEXT)) MISC_SRCS = lib_init.c lib_streamsem.c lib_filesem.c STRING_SRCS = lib_memset.c lib_memcpy.c lib_memcmp.c lib_memmove.c \ lib_strcpy.c lib_strncpy.c lib_strcmp.c \ - lib_strlen.c lib_strdup.c lib_strtol.c lib_strchr.c + lib_strlen.c lib_strdup.c lib_strtol.c lib_strchr.c \ + lib_strtok.c lib_strtokr.c CTYPE_SRCS = STDIO_SRCS = lib_fopen.c lib_fclose.c \ - lib_fread.c lib_libfread.c lib_fgetc.c lib_fgets.c \ + lib_fread.c lib_libfread.c lib_fgetc.c lib_fgets.c lib_gets.c \ lib_fwrite.c lib_libfwrite.c lib_fflush.c \ lib_fputc.c lib_puts.c lib_fputs.c \ lib_ungetc.c \ diff --git a/nuttx/lib/lib_fgets.c b/nuttx/lib/lib_fgets.c index df18c239a..3076859f0 100644 --- a/nuttx/lib/lib_fgets.c +++ b/nuttx/lib/lib_fgets.c @@ -34,10 +34,6 @@ ************************************************************/ /************************************************************ - * Compilation Switches - ************************************************************/ - -/************************************************************ * Included Files ************************************************************/ @@ -50,6 +46,22 @@ * Definitions ************************************************************/ +/* In some systems, the underlying serial logic may + * automatically echo characters back to the console. We + * will assume that that is not the case here + */ + +#define CONFIG_FGETS_ECHO 1 + +/* Some environments may return CR as end-of-line, others LF, and + * others both. The logic here assumes either but not both. + */ + +#undef CONFIG_EOL_IS_CR +#undef CONFIG_EOL_IS_LF +#undef CONFIG_EOL_IS_BOTH_CRLF +#define CONFIG_EOL_IS_EITHER_CRLF 1 + /************************************************************ * Private Type Declarations ************************************************************/ @@ -97,20 +109,24 @@ static inline int _lib_rawgetc(int fd) * Name: _lib_consoleputc ************************************************************/ +#ifdef CONFIG_FGETS_ECHO static inline void _lib_consoleputc(int ch) { char buffer = ch; (void)write(1, &buffer, 1); } +#endif /************************************************************ * Name: _lib_consoleputs ************************************************************/ +#ifdef CONFIG_FGETS_ECHO static inline void _lib_consoleputs(char *s) { (void)write(1, s, strlen(s)); } +#endif /************************************************************ * Global Functions @@ -138,8 +154,10 @@ static inline void _lib_consoleputs(char *s) char *fgets(FAR char *s, int n, FILE *stream) { - int escape = 0; +#ifdef CONFIG_FGETS_ECHO boolean console; +#endif + int escape = 0; int nch = 0; /* Sanity checks */ @@ -157,6 +175,7 @@ char *fgets(FAR char *s, int n, FILE *stream) /* Check if the stream is stdin */ +#ifdef CONFIG_FGETS_ECHO console = (stream->fs_filedes == 0); /* <esc>[K is the VT100 command that erases to the end of the line. */ @@ -165,6 +184,7 @@ char *fgets(FAR char *s, int n, FILE *stream) { _lib_consoleputs("\033[K"); } +#endif /* Read characters until we have a full line. On each * the loop we must be assured that there are two free bytes @@ -213,12 +233,14 @@ char *fgets(FAR char *s, int n, FILE *stream) { nch--; +#ifdef CONFIG_FGETS_ECHO if (console) { /* Echo the backspace character on the console */ _lib_consoleputc(ch); } +#endif } } @@ -231,9 +253,18 @@ char *fgets(FAR char *s, int n, FILE *stream) escape = 1; } - /* Check for end-of-line or end-of-file */ + /* Check for end-of-line. This is tricky only in that some + * environments may return CR as end-of-line, others LF, and + * others both. + */ - else if (ch == 0x0d) +#if defined(CONFIG_EOL_IS_LF) || defined(CONFIG_EOL_IS_BOTH_CRLF) + else if (ch == '\n') +#elif defined(CONFIG_EOL_IS_CR) + else if (ch == '\r') +#elif CONFIG_EOL_IS_EITHER_CRLF + else if (ch == '\n' || ch == '\r') +#endif { /* The newline is stored in the buffer along * with the null terminator. @@ -242,17 +273,18 @@ char *fgets(FAR char *s, int n, FILE *stream) s[nch++] = '\n'; s[nch] = '\0'; +#ifdef CONFIG_FGETS_ECHO if (console) { /* Echo the newline to the console */ _lib_consoleputc('\n'); } - +#endif return s; } - /* Check for end-of-line or end-of-file */ + /* Check for end-of-file */ else if (ch == EOF) { @@ -270,13 +302,14 @@ char *fgets(FAR char *s, int n, FILE *stream) { s[nch++] = ch; +#ifdef CONFIG_FGETS_ECHO if (console) { /* Echo the character to the console */ _lib_consoleputc(ch); } - +#endif /* Check if there is room for another character * and the line's null terminator. If not then * we have to end the line now. @@ -291,16 +324,3 @@ char *fgets(FAR char *s, int n, FILE *stream) } } - -/************************************************************ - * Name: gets - * - * Description: - * gets() reads a line from stdin into the buffer pointed - * to by s until either a terminating newline or EOF, - * which it replaces with '\0'. No check for buffer - * overrun is performed - * - **********************************************************/ - -/* gets() is not supported because it is inherently un-safe */ diff --git a/nuttx/lib/lib_gets.c b/nuttx/lib/lib_gets.c new file mode 100644 index 000000000..8574a6691 --- /dev/null +++ b/nuttx/lib/lib_gets.c @@ -0,0 +1,122 @@ +/************************************************************ + * lib_gets.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <stdio.h> +#include <limits.h> +#include <string.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Global Function Prototypes + ************************************************************/ + +/************************************************************ + * Global Constant Data + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Constant Data + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Global Functions + ************************************************************/ + +/************************************************************ + * Name: gets + * + * Description: + * gets() reads a line from stdin into the buffer pointed + * to by s until either a terminating newline or EOF, + * which it replaces with '\0'. No check for buffer + * overrun is performed + * + * This API should not be used because it is inherently + * unsafe. Consider using fgets which is safer and + * slightly more efficient. + * + **********************************************************/ + +char *gets(char *s) +{ + /* gets is ALMOST the same as fgets using stdin and no + * lenght limit (hence, the unsafeness of gets). So let + * fgets do most of the work. + */ + + char *ret = fgets(s, INT_MAX, stdin); + if (ret) + { + /* Another subtle difference from fgets is that gets + * replaces end-of-line markers with null terminators. + * We will do that as a second step (with some loss + * in performance). + */ + + int len = strlen(ret); + if (len > 0 && ret[len-1] == '\n') + { + ret[len-1] = '\0'; + } + } + return ret; +} diff --git a/nuttx/lib/lib_strtok.c b/nuttx/lib/lib_strtok.c new file mode 100644 index 000000000..d72ef2383 --- /dev/null +++ b/nuttx/lib/lib_strtok.c @@ -0,0 +1,87 @@ +/************************************************************ + * lib_strtok.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <string.h> + +/************************************************************ + * Private Data + ************************************************************/ + +static char *g_saveptr = NULL; + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: strtok + * + * Description: + * The strtok() function parses a string into a + * sequence of tokens. On the first call to strtok() the + * string to be parsed should be specified in 'str'. In + * each subsequent call that should parse the same string, + * 'str' should be NULL. + * + * The 'delim' argument specifies a set of characters that + * delimit the tokens in the parsed string. The caller + * may specify different strings in delim in successive + * calls that parse the same string. + * + * Each call to strtok() returns a pointer to a null- + * terminated string containing the next token. This + * string does not include the delimiting character. If + * no more tokens are found, strtok() returns NULL. + * + * A sequence of two or more contiguous delimiter + * characters in the parsed string is considered to be a + * single delimiter. Delimiter characters at the start or + * end of the string are ignored. The tokens returned by + * strtok() are always non-empty strings. + * + * Return + * strtok() returns a pointer to the next token, or NULL + * if there are no more tokens. + * + ************************************************************/ + +char *strtok(char *str, const char *delim) +{ + return strtok_r(str, delim, &g_saveptr); +} diff --git a/nuttx/lib/lib_strtokr.c b/nuttx/lib/lib_strtokr.c new file mode 100644 index 000000000..be9c43797 --- /dev/null +++ b/nuttx/lib/lib_strtokr.c @@ -0,0 +1,196 @@ +/************************************************************ + * lib_strtokr.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <string.h> + +/************************************************************ + * Private Data + ************************************************************/ + +static char *g_saveptr = NULL; + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: strtok_r + * + * Description: + * The strtok_r() function is a reentrant version strtok(). + * Like strtok(), it parses a string into a sequence of + * tokens. On the first call to strtok() the string to be + * parsed should be specified in 'str'. In each subsequent + * call that should parse the same string, 'str' should be + * NULL. + * + * The 'saveptr' argument is a pointer to a char * + * variable that is used internally by strtok_r() in + * order to maintain context between successive calls + * that parse the same string. + * + * On the first call to strtok_r(), 'str' should point to the + * string to be parsed, and the value of 'saveptr' is + * ignored. In subsequent calls, 'str' should be NULL, and + * saveptr should be unchanged since the previous call. + * + * The 'delim' argument specifies a set of characters that + * delimit the tokens in the parsed string. The caller + * may specify different strings in delim in successive + * calls that parse the same string. + * + * Each call to strtok_r() returns a pointer to a null- + * terminated string containing the next token. This + * string does not include the delimiting character. If + * no more tokens are found, strtok_r() returns NULL. + * + * A sequence of two or more contiguous delimiter + * characters in the parsed string is considered to be a + * single delimiter. Delimiter characters at the start or + * end of the string are ignored. The tokens returned by + * strtok() are always non-empty strings. + * + * Return + * strtok_r() returns a pointer to the next token, or NULL + * if there are no more tokens. + * + ************************************************************/ + +char *strtok_r(char *str, const char *delim, char **saveptr) +{ + char *pbegin; + char *pend = NULL; + + /* Decide if we are starting a new string or continuing from + * the point we left off. + */ + + if (str) + { + pbegin = str; + } + else if (saveptr && *saveptr) + { + pbegin = *saveptr; + } + else + { + return NULL; + } + + /* Find the beginning of the next token */ + + for (; + *pbegin && strchr(delim, *pbegin) != NULL; + pbegin++); + + /* If we are at the end of the string with nothing + * but delimiters found, then return NULL. + */ + + if (!*pbegin) + { + return NULL; + } + + /* Find the end of the token */ + + for (pend = pbegin + 1; + *pend && strchr(delim, *pend) == NULL; + pend++); + + + /* pend either points to the end of the string or to + * the first delimiter after the string. + */ + + if (*pend) + { + /* Turn the delimiter into a null terminator */ + + *pend++ = '\0'; + } + + /* Save the pointer where we left off and return the + * beginning of the token. + */ + + if (saveptr) + { + *saveptr = pend; + } + return pbegin; +} + +/************************************************************ + * Name: strtok + * + * Description: + * The strtok() function parses a string into a + * sequence of tokens. On the first call to strtok() the + * string to be parsed should be specified in 'str'. In + * each subsequent call that should parse the same string, + * 'str' should be NULL. + * + * The 'delim' argument specifies a set of characters that + * delimit the tokens in the parsed string. The caller + * may specify different strings in delim in successive + * calls that parse the same string. + * + * Each call to strtok() returns a pointer to a null- + * terminated string containing the next token. This + * string does not include the delimiting character. If + * no more tokens are found, strtok() returns NULL. + * + * A sequence of two or more contiguous delimiter + * characters in the parsed string is considered to be a + * single delimiter. Delimiter characters at the start or + * end of the string are ignored. The tokens returned by + * strtok() are always non-empty strings. + * + * Return + * strtok() returns a pointer to the next token, or NULL + * if there are no more tokens. + * + ************************************************************/ + +char *strtok(char *str, const char *delim) +{ + return strtok_r(str, delim, &g_saveptr); +} |