Mail Archives: djgpp-workers/2013/11/14/15:30:53
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
X-Recipient: | djgpp-workers AT delorie DOT com
|
Message-ID: | <5285335D.8020407@gmx.de>
|
Date: | Thu, 14 Nov 2013 21:32:29 +0100
|
From: | Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
|
User-Agent: | Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2
|
MIME-Version: | 1.0
|
To: | djgpp-workers AT delorie DOT com
|
Subject: | Re: Implementations for strndup and strnlen.
|
References: | <527D6EA1 DOT 6030506 AT gmx DOT de>
|
In-Reply-To: | <527D6EA1.6030506@gmx.de>
|
X-Provags-ID: | V03:K0:ooAhUP/qEQvMSMyBvlnq1w2aSzXtOiStCuevTrFhP0TpnWXMoA5
|
| kBvfukoTenm69mrwDXAVxYYfgJpGf1/U23Qgk6EHeuJDPoQ0eU+xQrA8uFNGyF2UvshfMzY
|
| u4lV+wtWHD45/48Cqc+jCnraYPKCmTfioaRUGgTKZxIZpC1gGWXzUUnjRZavljxRJMc6tB2
|
| HYY5QFdo24BFTfs7+60Tg==
|
Reply-To: | djgpp-workers AT delorie DOT com
|
Am 09.11.2013 00:07, schrieb Juan Manuel Guerrero:
> The patch below provides implementations for strndup and strnlen together with
> some small test cases.
>
OFYI: I have committed the patch below.
Regards,
Juan M. Guerrero
2013-11-07 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* djgpp/include/string.h: Added declarations for strndup and strnlen.
* djgpp/src/libc/posix/string/makefile: strndup and strnlen added to goal list.
* djgpp/src/libc/compat/string/strndup.c: Implementation of strndup.
* djgpp/src/libc/compat/string/strndup.txh: Documentation of strndup.
* djgpp/src/libc/compat/string/strnlen.c: Implementation of strnlen.
* djgpp/src/libc/compat/string/strnlen.txh: Documentation of strnlen.
* djgpp/src/docs/kb/wc204.txi: Info about strndup and strnlen added.
* djgpp/tests/libc/posix/string/makefile: strndup and strnlen checks added to goal list.
* djgpp/tests/libc/posix/string/strndup.c: Check for strndup.
* djgpp/tests/libc/posix/string/strnlen.c: Check for strnlen.
diff -aprNU5 djgpp.orig/include/string.h djgpp/include/string.h
--- djgpp.orig/include/string.h 2012-09-23 07:49:12 +0100
+++ djgpp/include/string.h 2013-11-08 23:06:52 +0100
@@ -69,23 +69,25 @@ char * strtok_r(char * _s1, const char
int bcmp(const void *_ptr1, const void *_ptr2, int _length);
void bcopy(const void *_a, void *_b, size_t _len);
void bzero(void *ptr, size_t _len);
int ffs(int _mask);
char * index(const char *_string, int _c);
-void * memccpy(void *_to, const void *_from, int c, size_t n);
+void * memccpy(void *_to, const void *_from, int _c, size_t _n);
int memicmp(const void *_s1, const void *_s2, size_t _n);
char * rindex(const char *_string, int _c);
char * stpcpy(char *_dest, const char *_src);
char * stpncpy(char *_dest, const char *_src, size_t _n);
char * strdup(const char *_s);
+char * strndup(const char *_s, size_t _n);
size_t strlcat(char *_dest, const char *_src, size_t _size);
size_t strlcpy(char *_dest, const char *_src, size_t _size);
char * strlwr(char *_s);
int strcasecmp(const char *_s1, const char *_s2);
int stricmp(const char *_s1, const char *_s2);
int strncasecmp(const char *_s1, const char *_s2, size_t _n);
int strnicmp(const char *_s1, const char *_s2, size_t _n);
+size_t strnlen(const char *_s, size_t _n);
char * strsep(char **_stringp, const char *_delim);
char * strupr(char *_s);
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi 2013-11-08 23:05:16 +0100
+++ djgpp/src/docs/kb/wc204.txi 2013-11-08 23:33:56 +0100
@@ -1342,5 +1342,11 @@ The @acronym{C99} functions @code{lround
These functions are available in two versions.
@cindex @acronym{C99} compliance, @code{math.h}
@findex rintl AT r{ added}
The @acronym{C99} function @code{rintl} has been added to comply with the @acronym{C99} standard.
+
+@cindex @acronym{POSIX} compliance, @code{string.h}
+@findex strndup AT r{ added}
+@findex strnlen AT r{ added}
+The functions @code{strndup} and @code{strnlen} were added to comply with
+the @acronym{POSIX} 1003.1-2008 standard.
diff -aprNU5 djgpp.orig/src/libc/posix/string/makefile djgpp/src/libc/posix/string/makefile
--- djgpp.orig/src/libc/posix/string/makefile 2005-01-07 17:07:16 +0100
+++ djgpp/src/libc/posix/string/makefile 2013-11-08 23:06:52 +0100
@@ -1,7 +1,10 @@
+# Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details
# Copyright (C) 2005 DJ Delorie, see COPYING.DJ for details
TOP=../..
SRC += strtok_r.c
SRC += strerr_r.c
+SRC += strndup.c
+SRC += strnlen.c
include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/src/libc/posix/string/strndup.c djgpp/src/libc/posix/string/strndup.c
--- djgpp.orig/src/libc/posix/string/strndup.c 1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/string/strndup.c 2013-11-08 23:06:52 +0100
@@ -0,0 +1,24 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+#include <stdlib.h>
+
+char *
+strndup(const char *_s, size_t _n)
+{
+ if (_s == NULL)
+ return NULL;
+ else
+ {
+ register const size_t length = strlen(_s);
+ register const size_t bytes = length > _n ? _n : length;
+ register char *new_string = malloc(bytes + 1);
+
+ if (new_string)
+ {
+ memcpy(new_string, _s, bytes);
+ new_string[bytes] = '\0';
+ }
+
+ return new_string;
+ }
+}
diff -aprNU5 djgpp.orig/src/libc/posix/string/strndup.txh djgpp/src/libc/posix/string/strndup.txh
--- djgpp.orig/src/libc/posix/string/strndup.txh 1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/string/strndup.txh 2013-11-08 23:06:52 +0100
@@ -0,0 +1,34 @@
+@node strndup, string
+@findex strndup
+@subheading Syntax
+
+@example
+#include <string.h>
+
+char * strndup (const char *source, size_t size);
+@end example
+
+@subheading Description
+
+Returns a newly allocated area of memory that contains a duplicate of at most
+@var{size} of characters of the string pointed to by @var{source}. The memory
+returned by this call must be freed by the caller.
+
+@subheading Return Value
+
+Returns the newly allocated string, or @var{NULL} if there
+is no more memory.
+
+@subheading Portability
+
+@portability !ansi, posix-1003.1-2008
+
+@subheading Example
+
+@example
+char *foo()
+@{
+ return strndup("hello world", 5);
+@}
+@end example
+
diff -aprNU5 djgpp.orig/src/libc/posix/string/strnlen.c djgpp/src/libc/posix/string/strnlen.c
--- djgpp.orig/src/libc/posix/string/strnlen.c 1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/string/strnlen.c 2013-11-08 23:06:52 +0100
@@ -0,0 +1,19 @@
+/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
+#include <string.h>
+
+size_t
+strnlen(const char *_str, size_t _n)
+{
+ if (_str == NULL || *_str == '\0' || _n == 0)
+ return 0;
+ else
+ {
+ register size_t i;
+
+ for (i = 1; _str[i] && i < _n; i++)
+ ;
+
+ return i;
+ }
+}
+
diff -aprNU5 djgpp.orig/src/libc/posix/string/strnlen.txh djgpp/src/libc/posix/string/strnlen.txh
--- djgpp.orig/src/libc/posix/string/strnlen.txh 1970-01-01 01:00:00 +0100
+++ djgpp/src/libc/posix/string/strnlen.txh 2013-11-08 23:21:30 +0100
@@ -0,0 +1,34 @@
+@node strnlen, string
+@findex strnlen
+@subheading Syntax
+
+@example
+#include <string.h>
+
+size_t strnlen(const char *string, size_t size);
+@end example
+
+@subheading Description
+
+This function returns the number of characters in @var{string},
+but at most @var{size}. In doing this, the function looks only
+at the first @var{size} characters at @var{string} and never
+beyond @var{string} + @var{size}.
+
+@subheading Return Value
+
+The length of the string.
+
+@subheading Portability
+
+@portability !ansi, posix-1003.1-2008
+
+@subheading Example
+
+@example
+size_t max_string_length = 10000;
+
+if (strnlen(fname, max_string_length) > PATH_MAX)
+ invalid_file(fname);
+@end example
+
diff -aprNU5 djgpp.orig/tests/libc/posix/string/makefile djgpp/tests/libc/posix/string/makefile
--- djgpp.orig/tests/libc/posix/string/makefile 2005-01-07 17:07:16 +0100
+++ djgpp/tests/libc/posix/string/makefile 2013-11-08 23:06:52 +0100
@@ -1,5 +1,7 @@
TOP=../..
SRC += strerr_r.c
+SRC += strndup.c
+SRC += strnlen.c
include $(TOP)/../makefile.inc
diff -aprNU5 djgpp.orig/tests/libc/posix/string/strndup.c djgpp/tests/libc/posix/string/strndup.c
--- djgpp.orig/tests/libc/posix/string/strndup.c 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/posix/string/strndup.c 2013-11-08 23:06:52 +0100
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SOURCE "A string to duplicate."
+
+
+int main(void)
+{
+ char *psrc, src[] = SOURCE;
+ char *dst[10];
+ int rv = 0;
+ register int i;
+
+
+ dst[0] = strndup(src, sizeof(SOURCE));
+ if (!dst[0])
+ rv++;
+ else
+ {
+ for (i = 0; dst[0][i] == src[i]; i++)
+ ;
+ if (i != sizeof(SOURCE))
+ rv++;
+ }
+
+ dst[1] = strndup(src, sizeof(SOURCE) + 1);
+ if (!dst[1])
+ rv++;
+ else
+ {
+ for (i = 0; dst[1][i] == src[i]; i++)
+ ;
+ if (i != sizeof(SOURCE))
+ rv++;
+ }
+
+ dst[2] = strndup(src, sizeof(SOURCE) - 1);
+ if (!dst[2])
+ rv++;
+ else
+ {
+ for (i = 0; dst[2][i] == src[i]; i++)
+ ;
+ if (i != sizeof(SOURCE))
+ rv++;
+ }
+
+ dst[3] = strndup(src, sizeof(SOURCE) - 2);
+ if (!dst[3])
+ rv++;
+ else
+ {
+ for (i = 0; dst[3][i] == src[i]; i++)
+ ;
+ if (i != sizeof(SOURCE) - 2)
+ rv++;
+ }
+
+ dst[4] = strndup(src, 0);
+ if (!dst[4])
+ rv++;
+ else
+ {
+ for (i = 0; dst[4][i] == src[i]; i++)
+ ;
+ if (i != 0)
+ rv++;
+ }
+
+ src[0] = '\0';
+ dst[5] = strndup(src, 1000);
+ if (!dst[5])
+ rv++;
+ else
+ {
+ for (i = 0; dst[5][i] == src[i]; i++)
+ ;
+ if (i != 1)
+ rv++;
+ }
+
+ psrc = NULL;
+ dst[6] = strndup(psrc, 1000);
+ if (dst[6])
+ rv++;
+
+ for (i = 0; dst[i]; i++)
+ free(dst[i]);
+
+
+ printf("%d checks of strndup failed.\n", rv);
+ return rv;
+}
diff -aprNU5 djgpp.orig/tests/libc/posix/string/strnlen.c djgpp/tests/libc/posix/string/strnlen.c
--- djgpp.orig/tests/libc/posix/string/strnlen.c 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/posix/string/strnlen.c 2013-11-08 23:06:52 +0100
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SOURCE "A string to check."
+
+
+int main(void)
+{
+ char *psrc = NULL, src[] = SOURCE;
+ int rv = 0;
+
+
+ if (strnlen(src, sizeof(SOURCE) + 1000) != sizeof(SOURCE) - 1)
+ rv++;
+
+ if (strnlen(src, sizeof(SOURCE)) != sizeof(SOURCE) - 1)
+ rv++;
+
+ if (strnlen(src, sizeof(SOURCE) - 1) != sizeof(SOURCE) - 1)
+ rv++;
+
+ if (strnlen(src, sizeof(SOURCE) - 2) != sizeof(SOURCE) - 2)
+ rv++;
+
+ if (strnlen(src, 0) != 0)
+ rv++;
+
+ if (strnlen(psrc, sizeof(SOURCE) + 1000) != 0)
+ rv++;
+
+ src[sizeof(SOURCE) - 1] = 'z';
+ if (strnlen(src, sizeof(SOURCE) + 10) > sizeof(SOURCE) + 10)
+ rv++;
+
+ printf("%d checks of strnlen failed.\n", rv);
+ return rv;
+}
- Raw text -