diff --git a/arch/c5471/include/limits.h b/arch/c5471/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..554c9f1f1714dc1ca861ad1f8454d575d5284203 --- /dev/null +++ b/arch/c5471/include/limits.h @@ -0,0 +1,74 @@ +/************************************************************ + * limits.h + * + * 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. + * + ************************************************************/ + +#ifndef __ARCH_LIMITS_H +#define __ARCH_LIMITS_H + +/************************************************************ + * Included Files + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +#define SCHAR_MIN 0x80 +#define SCHAR_MAX 0x7f +#define UCHAR_MAX 0xff + +/* These could be different on machines where char is unsigned */ + +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN 0x8000 +#define SHRT_MAX 0x7fff +#define USHRT_MAX 0xffff + +#define INT_MIN 0x80000000 +#define INT_MAX 0x7fffffff +#define UINT_MAX 0xffffffff + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MAX 0x80000000 +#define LONG_MIN 0x7fffffff +#define ULONG_MAX 0xffffffff + +#define LLONG_MAX 0x8000000000000000 +#define LLONG_MIN 0x7fffffffffffffff +#define ULLONG_MAX 0xffffffffffffffff + +#endif /* __ARCH_LIMITS_H */ diff --git a/arch/pjrc-8051/include/limits.h b/arch/pjrc-8051/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..c0b91e63dc405c91078a72b3a37e2e25137ed99d --- /dev/null +++ b/arch/pjrc-8051/include/limits.h @@ -0,0 +1,70 @@ +/************************************************************ + * limits.h + * + * 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. + * + ************************************************************/ + +#ifndef __ARCH_LIMITS_H +#define __ARCH_LIMITS_H + +/************************************************************ + * Included Files + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +#define SCHAR_MIN 0x80 +#define SCHAR_MAX 0x7f +#define UCHAR_MAX 0xff + +/* These could be different on machines where char is unsigned */ + +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN 0x8000 +#define SHRT_MAX 0x7fff +#define USHRT_MAX 0xffff + +#define INT_MIN 0x8000 +#define INT_MAX 0x7fff +#define UINT_MAX 0xffff + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MAX 0x80000000 +#define LONG_MIN 0x7fffffff +#define ULONG_MAX 0xffffffff + +#endif /* __ARCH_LIMITS_H */ diff --git a/arch/sim/include/limits.h b/arch/sim/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..554c9f1f1714dc1ca861ad1f8454d575d5284203 --- /dev/null +++ b/arch/sim/include/limits.h @@ -0,0 +1,74 @@ +/************************************************************ + * limits.h + * + * 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. + * + ************************************************************/ + +#ifndef __ARCH_LIMITS_H +#define __ARCH_LIMITS_H + +/************************************************************ + * Included Files + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +#define SCHAR_MIN 0x80 +#define SCHAR_MAX 0x7f +#define UCHAR_MAX 0xff + +/* These could be different on machines where char is unsigned */ + +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN 0x8000 +#define SHRT_MAX 0x7fff +#define USHRT_MAX 0xffff + +#define INT_MIN 0x80000000 +#define INT_MAX 0x7fffffff +#define UINT_MAX 0xffffffff + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MAX 0x80000000 +#define LONG_MIN 0x7fffffff +#define ULONG_MAX 0xffffffff + +#define LLONG_MAX 0x8000000000000000 +#define LLONG_MIN 0x7fffffffffffffff +#define ULLONG_MAX 0xffffffffffffffff + +#endif /* __ARCH_LIMITS_H */ diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c index 9c3d4ab006f204ff2d5bb6fba2308d90834b83aa..aa98a4e74021106f10654cc1f32dd72f19d4aef4 100644 --- a/examples/nsh/nsh_main.c +++ b/examples/nsh/nsh_main.c @@ -42,7 +42,9 @@ ************************************************************/ #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <sched.h> /************************************************************ * Definitions @@ -50,16 +52,220 @@ #define CONFIG_NSH_LINE_SIZE 80 +/************************************************************ + * Private Types + ************************************************************/ + +typedef void (*cmd_t)(const char *cmd, const char *arg); +typedef void (*exec_t)(void); + +struct cmdmap_s +{ + const char *cmd; + cmd_t handler; + const char *usage; +}; + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +static void cmd_echo(const char *cmd, const char *arg); +static void cmd_exec(const char *cmd, const char *arg); +static void cmd_help(const char *cmd, const char *arg); +static void cmd_ls(const char *cmd, const char *arg); +static void cmd_ps(const char *cmd, const char *arg); + /************************************************************ * Private Data ************************************************************/ static char line[CONFIG_NSH_LINE_SIZE]; +static const char delim[] = " \t\n"; + +static const struct cmdmap_s g_cmdmap[] = +{ + { "echo", cmd_echo, "<string>" }, + { "exec", cmd_exec, "<hex-address>" }, + { "help", cmd_help, NULL }, + { "ls", cmd_ls, "<path>" }, + { "ps", cmd_ps, NULL }, + { NULL, NULL, NULL } +}; + +static const char *g_statenames[] = +{ + "INVALID ", + "PENDING ", + "READY ", + "RUNNING ", + "INACTIVE", + "WAITSEM ", +#ifndef CONFIG_DISABLE_MQUEUE + "WAITSIG ", +#endif +#ifndef CONFIG_DISABLE_MQUEUE + "MQNEMPTY", + "MQNFULL " +#endif +}; + +static const char g_fmtargrequired[] = "nsh: %s: argument required\n"; +static const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n"; +static const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n"; +static const char g_fmtcmdnotimpl[] = "nsh: %s: command not implemented\n"; /************************************************************ * Private Functions ************************************************************/ +static char *trim_arg(char *arg) +{ + if (arg) + { + int len; + + /* Skip any leading white space */ + + while (strchr(" \t", *arg) != NULL) arg++; + + /* Skip any leading white space */ + + len = strlen(arg); + if (len > 0) + { + char *ptr; + + for (ptr = &arg[strlen(arg)-1]; + ptr >= arg && + strchr(" \t\n", *ptr) != NULL; + ptr--) + { + *ptr = '\0'; + } + } + } + return arg; +} + +/************************************************************ + * Name: cmd_echo + ************************************************************/ + +static void cmd_echo(const char *cmd, const char *arg) +{ + /* Echo the rest of the line */ + + puts(arg); +} + +/************************************************************ + * Name: cmd_exec + ************************************************************/ + +static void cmd_exec(const char *cmd, const char *arg) +{ + char *endptr; + long addr; + + if (!arg) + { + printf(g_fmtargrequired, "exec"); + return; + } + + addr = strtol(arg, &endptr, 0); + if (!addr || endptr == arg || *endptr != '\0') + { + printf(g_fmtarginvalid, "exec"); + return; + } + + printf("Calling %p\n", (exec_t)addr); + ((exec_t)addr)(); +} + +/************************************************************ + * Name: cmd_help + ************************************************************/ + +static void cmd_help(const char *cmd, const char *arg) +{ + const struct cmdmap_s *ptr; + + printf("NSH commands:\n"); + for (ptr = g_cmdmap; ptr->cmd; ptr++) + { + if (ptr->usage) + { + printf(" %s %s\n", ptr->cmd, ptr->usage); + } + else + { + printf(" %s\n", ptr->cmd); + } + } +} + +/************************************************************ + * Name: cmd_ls + ************************************************************/ + +static void cmd_ls(const char *cmd, const char *arg) +{ + printf(g_fmtcmdnotimpl, cmd); +} + +/************************************************************ + * Name: ps_task + ************************************************************/ + +static void ps_task(FAR _TCB *tcb, FAR void *arg) +{ + boolean needcomma = FALSE; + int i; + printf("%5d %3d %4s %7s%c%c %8s ", + tcb->pid, tcb->sched_priority, + tcb->flags & TCB_FLAG_ROUND_ROBIN ? "RR " : "FIFO", + tcb->flags & TCB_FLAG_PTHREAD ? "PTHREAD" : "TASK ", + tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : ' ', + tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ', + g_statenames[tcb->task_state]); + + printf("%s(", tcb->argv[0]); + for (i = 1; i < NUM_TASK_ARGS+1 && tcb->argv[i]; i++) + { + if (needcomma) + { + printf(", %p", tcb->argv[i]); + } + else + { + printf("%p", tcb->argv[i]); + } + } + printf(")\n"); +} + +/************************************************************ + * Name: cmd_ps + ************************************************************/ + +static void cmd_ps(const char *cmd, const char *arg) +{ + printf("PID PRI SCHD TYPE NP STATE NAME\n"); + sched_foreach(ps_task, NULL); +} + +/************************************************************ + * Name: cmd_unrecognized + ************************************************************/ + +static void cmd_unrecognized(const char *cmd, const char *arg) +{ + printf(g_fmtcmdnotfound, cmd); +} + /************************************************************ * Public Functions ************************************************************/ @@ -84,9 +290,32 @@ int user_start(int parm1, int parm2, int parm3, int parm4) for (;;) { - fflush(stdout); + const struct cmdmap_s *cmd; + cmd_t handler = cmd_unrecognized; + char *saveptr; + char *token; + + /* Get the next line of input */ + fgets(line, CONFIG_NSH_LINE_SIZE, stdin); - puts(line); + + /* Parse out the command at the beginning of the line */ + + token = strtok_r(line, " \t\n", &saveptr); + if (token) + { + /* See if the command is one that we understand */ + + for (cmd = g_cmdmap; cmd->cmd; cmd++) + { + if (strcmp(cmd->cmd, token) == 0) + { + handler = cmd->handler; + break; + } + } + handler(token, trim_arg(saveptr)); + } fflush(stdout); } } diff --git a/include/limits.h b/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..bb043c442e736ab5d8109c8605770574376cdcb5 --- /dev/null +++ b/include/limits.h @@ -0,0 +1,49 @@ +/************************************************************ + * limits.h + * + * 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. + * + ************************************************************/ + +#ifndef __LIMITS_H +#define __LIMITS_H + +/************************************************************ + * Included Files + ************************************************************/ + +#include <arch/limits.h> + +/************************************************************ + * Definitions + ************************************************************/ + +#endif /* __LIMITS_H */ diff --git a/include/stdio.h b/include/stdio.h index 426b237147d5b86e1a24c2fd5b30c75c088d6113..58f398b46a0e395f8b0fcae5878843050ab8561b 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -224,6 +224,7 @@ EXTERN size_t fread(void *ptr, size_t size, size_t n_items, EXTERN int fseek(FILE *stream, long int offset, int whence); EXTERN size_t fwrite(const void *ptr, size_t size, size_t n_items, FILE *stream); +EXTERN char *gets(char *s); EXTERN int printf(const char *format, ...); EXTERN int puts(const char *s); diff --git a/include/string.h b/include/string.h index a5c1a1a9e85d4ca68f426ef983be542593097add..38163eb0302ee0a67f83f11b1c74f141b14d891c 100644 --- a/include/string.h +++ b/include/string.h @@ -75,6 +75,7 @@ EXTERN size_t strspn(const char *, const char *); EXTERN size_t strcspn(const char *, const char *); EXTERN char *strstr(const char *, const char *); EXTERN char *strtok(char *, const char *); +EXTERN char *strtok_r(char *, const char *, char **); EXTERN void *memset(void *s, int c, size_t n); EXTERN void *memcpy(void *dest, const void *src, size_t n); diff --git a/lib/Makefile b/lib/Makefile index cb77499c82f752e80b7190d58d2f9becd8409323..6d89ccaef7e94849a81f1fddd92fc6578782ef3e 100644 --- a/lib/Makefile +++ b/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/lib/lib_fgets.c b/lib/lib_fgets.c index df18c239ad5d98958949225662fc8946a42b35d4..3076859f0039e4353df17af750cff6e68d20c032 100644 --- a/lib/lib_fgets.c +++ b/lib/lib_fgets.c @@ -33,10 +33,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/lib/lib_gets.c b/lib/lib_gets.c new file mode 100644 index 0000000000000000000000000000000000000000..8574a6691e8bebe034941f7b0e05062780cabfa6 --- /dev/null +++ b/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/lib/lib_strtok.c b/lib/lib_strtok.c new file mode 100644 index 0000000000000000000000000000000000000000..d72ef23832708267e29f98b5eb8892a6a90fbd39 --- /dev/null +++ b/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/lib/lib_strtokr.c b/lib/lib_strtokr.c new file mode 100644 index 0000000000000000000000000000000000000000..be9c437973667ccac06985ff656b04716c532b99 --- /dev/null +++ b/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); +} diff --git a/sched/sem_trywait.c b/sched/sem_trywait.c index dc65f8f58e7247b1b2bcbdd78972c7fae09a2261..e634e1781bd4693bf979f4e8d3c5e9aac7410a00 100644 --- a/sched/sem_trywait.c +++ b/sched/sem_trywait.c @@ -102,12 +102,9 @@ int sem_trywait(sem_t *sem) irqstate_t saved_state; int ret = ERROR; - if (up_interrupt_context()) - { - /* We do not want to set the errno in this case */ + /* This API should not be called from interrupt handlers */ - return ERROR; - } + DEBUGASSERT(!up_interrupt_context()) /* Assume any errors reported are due to invalid arguments. */ diff --git a/sched/sem_wait.c b/sched/sem_wait.c index 4d82dd41a11f5602c7bac3dbb6a69c064abf36c5..8734dc1f7cacbaeb640c355f7d36362be7024ce0 100644 --- a/sched/sem_wait.c +++ b/sched/sem_wait.c @@ -105,12 +105,7 @@ int sem_wait(sem_t *sem) /* This API should not be called from interrupt handlers */ - if (up_interrupt_context()) - { - /* We do not want to set the errno in this case */ - - return ERROR; - } + DEBUGASSERT(!up_interrupt_context()) /* Assume any errors reported are due to invalid arguments. */