summaryrefslogtreecommitdiff
path: root/src/string
diff options
context:
space:
mode:
Diffstat (limited to 'src/string')
-rw-r--r--src/string/NULL.ref3
-rw-r--r--src/string/memchr.c31
-rw-r--r--src/string/memcmp.c34
-rw-r--r--src/string/memcpy.c31
-rw-r--r--src/string/memmove.c35
-rw-r--r--src/string/memset.c28
-rw-r--r--src/string/size_t.ref3
-rw-r--r--src/string/strcat.c24
-rw-r--r--src/string/strchr.c22
-rw-r--r--src/string/strcmp.c29
-rw-r--r--src/string/strcoll.c44
-rw-r--r--src/string/strcpy.c29
-rw-r--r--src/string/strcspn.c28
-rw-r--r--src/string/strerror.c31
-rw-r--r--src/string/strlen.c25
-rw-r--r--src/string/strncat.c40
-rw-r--r--src/string/strncmp.c31
-rw-r--r--src/string/strncpy.c34
-rw-r--r--src/string/strpbrk.c28
-rw-r--r--src/string/strrchr.c30
-rw-r--r--src/string/strspn.c28
-rw-r--r--src/string/strstr.c43
-rw-r--r--src/string/strtok.c34
-rw-r--r--src/string/strxfrm.c32
24 files changed, 697 insertions, 0 deletions
diff --git a/src/string/NULL.ref b/src/string/NULL.ref
new file mode 100644
index 00000000..5d6e9890
--- /dev/null
+++ b/src/string/NULL.ref
@@ -0,0 +1,3 @@
+#include <string.h>
+REFERENCE(stddef/NULL.c)
+STDC(1)
diff --git a/src/string/memchr.c b/src/string/memchr.c
new file mode 100644
index 00000000..97f6b257
--- /dev/null
+++ b/src/string/memchr.c
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** search memory **/
+void * memchr(const void *s, int c, size_t n)
+{
+ char *p = (char*)s;
+ size_t i = 0;
+
+ ASSERT_NONNULL(s);
+
+ for (i = 0; i < n; i++) {
+ if (p[i] == (unsigned char)c) {
+ return p + i;
+ }
+ }
+
+ /*
+ RETURN_FAILURE(CONSTANT(NULL));
+ RETURN_SUCCESS(a pointer to the located byte);
+ */
+ return NULL;
+}
+
+/***
+searches the first ARGUMENT(n) bytes of memory at ARGUMENT(s) for
+ARGUMENT(c) (converted to an TYPE(unsigned char)).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/memcmp.c b/src/string/memcmp.c
new file mode 100644
index 00000000..64dcb464
--- /dev/null
+++ b/src/string/memcmp.c
@@ -0,0 +1,34 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** compare memory regions **/
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+ unsigned char *p = (unsigned char*)s1;
+ unsigned char *q = (unsigned char*)s2;
+ size_t i = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ for (i = 0; i < n; i++) {
+ if (p[i] != q[i]) {
+ break;
+ }
+ }
+
+ /*
+ RETURN(NEGATIVE, ARGUMENT(s1) is less than ARGUMENT(s2));
+ RETURN(ZERO, ARGUMENT(s1) and ARGUMENT(s2) are equal);
+ RETURN(POSITIVE(), ARGUMENT(s1) is greater than ARGUMENT(s2));
+ */
+ return p[i] - q[i];
+}
+
+/***
+compares the first ARGUMENT(n) bytes of memory at ARGUMENT(s1)
+and ARGUMENT(s2).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/memcpy.c b/src/string/memcpy.c
new file mode 100644
index 00000000..f53fe5d8
--- /dev/null
+++ b/src/string/memcpy.c
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** copy memory **/
+void * memcpy(void * restrict s1, const void * restrict s2, size_t n)
+{
+ char *dst = (char*)s1;
+ char *src = (char*)s2;
+ size_t i = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+ ASSERT_NOOVERLAP(s1, s2, n);
+
+ for (i = 0; i < n; i++) {
+ dst[i] = src[i];
+ }
+
+ /*
+ RETURN_ALWAYS(ARGUMENT(s1));
+ */
+ return dst;
+}
+
+/***
+copies ARGUMENT(n) bytes from the object at ARGUMENT(s2) to the object at
+ARGUMENT(s1).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/memmove.c b/src/string/memmove.c
new file mode 100644
index 00000000..33000e0e
--- /dev/null
+++ b/src/string/memmove.c
@@ -0,0 +1,35 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** move memory **/
+void * memmove(void *s1, const void *s2, size_t n)
+{
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ if (s1 < s2) {
+ return memcpy(s1, s2, n);
+ }
+
+ /* reverse memcpy() */
+ while (n > 0) {
+ ((char*)s1)[n] = ((char*)s2)[n];
+ n--;
+ }
+ /* last byte */
+ ((char*)s1)[n] = ((char*)s2)[n];
+
+ /*
+ RETURN_ALWAYS(ARGUMENT(s1));
+ */
+ return s1;
+}
+
+/***
+copies ARGUMENT(n) bytes of memory from the object at
+ARGUMENT(s2) to the object at ARGUMENT(s1). If ARGUMENT(s1) and ARGUMENT(s2) overlap, the memory
+is copied so that the ARGUMENT(n) bytes are safely written to ARGUMENT(s1).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/memset.c b/src/string/memset.c
new file mode 100644
index 00000000..1f3d14ff
--- /dev/null
+++ b/src/string/memset.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** fill memory **/
+void * memset(void *s, int c, size_t n)
+{
+ unsigned char *p = (unsigned char *)s;
+ size_t i = 0;
+
+ ASSERT_NONNULL(s);
+
+ for (i = 0; i < n; i++) {
+ p[i] = (unsigned char)c;
+ }
+
+ /*
+ RETURN_ALWAYS(ARGUMENT(s));
+ */
+ return s;
+}
+
+/***
+fills the first ARGUMENT(n) bytes of memory at ARGUMENT(s) with
+the value ARGUMENT(c) (converted to an TYPE(unsigned char)).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/size_t.ref b/src/string/size_t.ref
new file mode 100644
index 00000000..3c087e0b
--- /dev/null
+++ b/src/string/size_t.ref
@@ -0,0 +1,3 @@
+#include <string.h>
+REFERENCE(stddef/size_t.c)
+STDC(1)
diff --git a/src/string/strcat.c b/src/string/strcat.c
new file mode 100644
index 00000000..9526cd59
--- /dev/null
+++ b/src/string/strcat.c
@@ -0,0 +1,24 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** concatenate strings **/
+char * strcat(char * restrict s1, const char * restrict s2)
+{
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+ ASSERT_NOOVERLAP(s1, s2, strlen(s1) + strlen(s2));
+
+ /*
+ RETURN_ALWAYS(ARGUMENT(s1));
+ */
+ return strncat(s1, s2, strlen(s2));
+}
+
+/***
+appends a copy of the string at ARGUMENT(s2) to the end of
+the string at ARGUMENT(s1). The first byte of ARGUMENT(s2) will overwrite the terminating
+null character of ARGUMENT(s1).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strchr.c b/src/string/strchr.c
new file mode 100644
index 00000000..874db9be
--- /dev/null
+++ b/src/string/strchr.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** string search **/
+char * strchr(const char *s, int c)
+{
+ ASSERT_NONNULL(s);
+
+ /*
+ RETURN_FAILURE(CONSTANT(NULL));
+ RETURN_SUCCESS(a pointer to the located character);
+ */
+ return (char*)memchr(s, (char)c, strlen(s));
+}
+
+/***
+searches the string ARGUMENT(s) for the first occurrence of
+ARGUMENT(c) (converted to a TYPE(char)).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strcmp.c b/src/string/strcmp.c
new file mode 100644
index 00000000..ed089c77
--- /dev/null
+++ b/src/string/strcmp.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** compare strings **/
+int strcmp(const char *s1, const char *s2)
+{
+ size_t n1 = 0;
+ size_t n2 = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ n1 = strlen(s1);
+ n2 = strlen(s2);
+
+ /*
+ RETURN(NEGATIVE, ARGUMENT(s1) is less than ARGUMENT(s2));
+ RETURN(ZERO, ARGUMENT(s1) is equal to ARGUMENT(s2));
+ RETURN(POSITIVE, ARGUMENT(s1) is greater than ARGUMENT(s2));
+ */
+ return strncmp(s1, s2, n1 < n2 ? n1 : n2);
+}
+
+/***
+compares the strings at ARGUMENT(s1) and ARGUMENT(s2).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strcoll.c b/src/string/strcoll.c
new file mode 100644
index 00000000..8707ba73
--- /dev/null
+++ b/src/string/strcoll.c
@@ -0,0 +1,44 @@
+#include <string.h>
+#include "stdlib.h"
+#include "nonstd/assert.h"
+
+/** collate strings **/
+int strcoll(const char *s1, const char *s2)
+{
+ char *x1 = NULL;
+ char *x2 = NULL;
+ int ret = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ x1 = malloc(strxfrm(x1, s1, 0));
+ x2 = malloc(strxfrm(x2, s2, 0));
+
+ if (x1 && x2) {
+ strxfrm(x1, s1, 0);
+ strxfrm(x2, s2, 0);
+ ret = strcmp(x1, x2);
+ }
+
+ free(x1);
+ free(x2);
+
+ /*
+ RETURN(NEGATIVE, ARGUMENT(s1) collates before ARGUMENT(s2));
+ RETURN(ZERO, ARGUMENT(s1) collates equal to ARGUMENT(s2));
+ RETURN(POSITIVE, ARGUMENT(s1) collates after ARGUMENT(s2));
+ */
+ return ret;
+}
+
+/***
+compares the collation values of the strings at ARGUMENT(s1) and ARGUMENT(s2).
+***/
+
+/*
+LC_COLLATE
+*/
+/*
+STDC(1)
+*/
diff --git a/src/string/strcpy.c b/src/string/strcpy.c
new file mode 100644
index 00000000..cf4eeb21
--- /dev/null
+++ b/src/string/strcpy.c
@@ -0,0 +1,29 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** copy string **/
+char * strcpy(char * restrict s1, const char * restrict s2)
+{
+ char *p = s1;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+ ASSERT_NOOVERLAP(s1, s2, strlen(s2));
+
+ while ((*s1++ = *s2++) != '\0') {
+ continue;
+ }
+
+ /*
+ RETURN_ALWAYS(ARGUMENT(s1));
+ */
+ return p;
+}
+
+/***
+copies the string at ARGUMENT(s2) to ARGUMENT(s1), up to and
+including the terminating CHAR(\0).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strcspn.c b/src/string/strcspn.c
new file mode 100644
index 00000000..4bbdee2e
--- /dev/null
+++ b/src/string/strcspn.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** count non-matching characters **/
+size_t strcspn(const char *s1, const char *s2)
+{
+ size_t i = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ for (i = 0; s1[i] != '\0'; i++) {
+ if (strchr (s2, s1[i]) != NULL) {
+ break;
+ }
+ }
+
+ return i;
+}
+
+/***
+the number of characters that the beginning of
+the string ARGUMENT(s1) that are not in the string ARGUMENT(s2).
+***/
+/*
+ RETURN_ALWAYS(the number of non-matching characters);
+STDC(1)
+*/
diff --git a/src/string/strerror.c b/src/string/strerror.c
new file mode 100644
index 00000000..055a11f7
--- /dev/null
+++ b/src/string/strerror.c
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "errno.h"
+#include "stdio.h"
+# define __LONGEST_STRERR 64 /* FIXME */
+
+/** convert error number to string **/
+char * strerror(int errnum)
+{
+ static char errstr[__LONGEST_STRERR+1];
+
+ switch (errnum) {
+ #include "_strerror.h"
+ default:
+ sprintf(errstr, "unknown error [%d]", errnum);
+ break;
+ }
+
+ /*
+ RETURN_ALWAYS(a pointer to the message string);
+ */
+ return errstr;
+}
+
+/***
+converts the error number ARGUMENT(errnum) to an error message
+string. The string returned should not be modified, and may be overwritten by
+subsequent calls.
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strlen.c b/src/string/strlen.c
new file mode 100644
index 00000000..89ccbfcc
--- /dev/null
+++ b/src/string/strlen.c
@@ -0,0 +1,25 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** find string length **/
+size_t strlen(const char *s)
+{
+ size_t i = 0;
+
+ ASSERT_NONNULL(s);
+
+ for (i = 0; s[i] != '\0'; i++) {
+ continue;
+ }
+
+ return i;
+}
+
+/***
+counts the number of bytes in the string ARGUMENT(s), not
+including the terminating null character.
+***/
+/*
+ RETURN_ALWAYS(the length of the string);
+STDC(1)
+*/
diff --git a/src/string/strncat.c b/src/string/strncat.c
new file mode 100644
index 00000000..34800069
--- /dev/null
+++ b/src/string/strncat.c
@@ -0,0 +1,40 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** concatenate bounded string **/
+char * strncat(char * restrict s1, const char * restrict s2, size_t n)
+{
+ char *append = NULL;
+ size_t i;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+ ASSERT_NOOVERLAP(s1, s2, strlen(s1) + strlen(s2));
+
+ append = s1 + strlen(s1);
+
+ for (i = 0; i < n; i++) {
+ append[i] = s2[i];
+ if (append[i] == '\0') {
+ break;
+ }
+ }
+
+ if (append[i - 1] != '\0') {
+ append[i] = '\0';
+ }
+
+ return s1;
+}
+
+/***
+appends a copy of the frist ARGUMENT(n) bytes of the string
+at ARGUMENT(s2) to the end of the string at ARGUMENT(s1). The first byte of ARGUMENT(s2) will
+overwrite the terminating null character of ARGUMENT(s1). No characters after the
+first CHAR(\0) will be copied. The resulting string will always be null
+terminated.
+***/
+/*
+ RETURN_ALWAYS(ARGUMENT(s1));
+STDC(1)
+*/
diff --git a/src/string/strncmp.c b/src/string/strncmp.c
new file mode 100644
index 00000000..23c8104e
--- /dev/null
+++ b/src/string/strncmp.c
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** compare bound strings **/
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ if (strlen(s1) < n) {
+ n = strlen(s1);
+ }
+ if (strlen(s2) < n) {
+ n = strlen(s2);
+ }
+
+ /*
+ RETURN(NEGATIVE, ARGUMENT(s1) is less than ARGUMENT(s2));
+ RETURN(ZERO, ARGUMENT(s1) is equal to ARGUMENT(s2));
+ RETURN(POSITIVE, ARGUMENT(s1) is greater than ARGUMENT(s2));
+ */
+ return memcmp(s1, s2, n);
+}
+
+/***
+compares up to the first ARGUMENT(n) bytes of the strings at ARGUMENT(s1) and
+ARGUMENT(s2), or until the first CHAR(\0), whichever comes first.
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strncpy.c b/src/string/strncpy.c
new file mode 100644
index 00000000..ee632d69
--- /dev/null
+++ b/src/string/strncpy.c
@@ -0,0 +1,34 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** copy bounded string **/
+char * strncpy(char * restrict s1, const char * restrict s2, size_t n)
+{
+ size_t i;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+ ASSERT_NOOVERLAP(s1, s2, n);
+
+ for (i = 0; i < n; i++) {
+ s1[i] = s2[i];
+ if (s1[i] == '\0') {
+ memset(s1 + i, '\0', n - i);
+ break;
+ }
+ }
+
+ return s1;
+}
+
+/***
+copies up to ARGUMENT(n) bytes from the string at ARGUMENT(s2)
+to ARGUMENT(s1). If a CHAR(\0) is encountered, null characters are appended to
+ARGUMENT(s1) until ARGUMENT(n) bytes have been written. If no null characters are copied
+in the first ARGUMENT(n) bytes of ARGUMENT(s2), the resulting string will not be null
+terminated.
+***/
+/*
+ RETURN_ALWAYS(ARGUMENT(s1));
+STDC(1)
+*/
diff --git a/src/string/strpbrk.c b/src/string/strpbrk.c
new file mode 100644
index 00000000..0b88b999
--- /dev/null
+++ b/src/string/strpbrk.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** count matching characters **/
+char * strpbrk(const char *s1, const char *s2)
+{
+ size_t i;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ for (i = 0; i < strlen (s1); i++) {
+ if (strchr(s2, s1[i]) != NULL) {
+ return (char*)s1 + i;
+ }
+ }
+
+ return NULL;
+}
+
+/***
+locates the first occurence in ARGUMENT(s1) of any character in ARGUMENT(s2).
+***/
+/*
+ RETURN_FAILURE(CONSTANT(NULL));
+ RETURN_SUCCESS(a pointer to the located character);
+STDC(1)
+*/
diff --git a/src/string/strrchr.c b/src/string/strrchr.c
new file mode 100644
index 00000000..0427aa66
--- /dev/null
+++ b/src/string/strrchr.c
@@ -0,0 +1,30 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** search string from end **/
+char * strrchr(const char *s, int c)
+{
+ int i = 0;
+
+ ASSERT_NONNULL(s);
+
+ for (i = strlen(s) + 1; i >= 0; i--) {
+ if (s[i] == (char)c) {
+ return (char*)s + i;
+ }
+ }
+
+ /*
+ RETURN_SUCCESS(a pointer to the found character);
+ RETURN_FAILURE(CONSTANT(NULL));
+ */
+ return NULL;
+}
+
+/***
+finds the last occurence of ARGUMENT(c) (converted to TYPE(char)) in the
+string ARGUMENT(s).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strspn.c b/src/string/strspn.c
new file mode 100644
index 00000000..e67461a5
--- /dev/null
+++ b/src/string/strspn.c
@@ -0,0 +1,28 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** count matching characters **/
+size_t strspn(const char *s1, const char *s2)
+{
+ size_t i = 0;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ for (i = 0; i < strlen (s1); i++) {
+ if (strchr(s2, s1[i]) == NULL) {
+ break;
+ }
+ }
+
+ return i;
+}
+
+/***
+computes the length of the maximum initial segment of the ARGUMENT(s1) made
+up of characters from ARGUMENT(s2).
+***/
+/*
+ RETURN_ALWAYS(the number of matching characters);
+STDC(1)
+*/
diff --git a/src/string/strstr.c b/src/string/strstr.c
new file mode 100644
index 00000000..898db1be
--- /dev/null
+++ b/src/string/strstr.c
@@ -0,0 +1,43 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** search for substring **/
+char * strstr(const char *s1, const char *s2)
+{
+ size_t l1 = 0;
+ size_t l2 = 0;
+ char *p = (char*)s1;
+
+ ASSERT_NONNULL(s1);
+ ASSERT_NONNULL(s2);
+
+ l2 = strlen(s2);
+ if (l2 == 0) {
+ return p;
+ }
+
+ l1 = strlen(s1);
+
+ do {
+ p = memchr(p, *s2, l1);
+ if (p == NULL || strcmp(p + 1, s2 + 1) == 0) {
+ break;
+ }
+ p++;
+ } while (p < s1 + l2);
+
+ /*
+ RETURN_FAILURE(CONSTANT(NULL));
+ RETURN_SUCCESS(a pointer to the located string);
+ */
+ return p;
+}
+
+/***
+finds the first occurrence of the string ARGUMENT(s2) in the string
+ARGUMENT(s1). Specifying the empty string for ARGUMENT(s2) matches the first
+character of ARGUMENT(s1).
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strtok.c b/src/string/strtok.c
new file mode 100644
index 00000000..9a7137cf
--- /dev/null
+++ b/src/string/strtok.c
@@ -0,0 +1,34 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** split string into tokens **/
+char * strtok(char * restrict s1, const char * restrict s2)
+{
+ extern char * strtok_r(char *restr, const char *restrict, char **);
+ static char *current;
+
+ /* TODO */
+ ASSERT_NONNULL(s2);
+
+ /*
+ RETURN(CONSTANT(NULL), there are no further tokens, only token separators);
+ RETURN(NONNULL, a pointer to the first character of the next token);
+ */
+
+ return strtok_r (s1, s2, &current);
+}
+
+/***
+splits the string ARGUMENT(s1) into a series of tokens
+delimited by characters from the string ARGUMENT(s2).
+
+The first call in a sequence specifies a string for ARGUMENT(s1). Further calls
+specify CONSTANT(NULL) in order to continue from the end of the previous token.
+The list of token separators in ARGUMENT(s2) may vary from call to call.
+
+When tokens are found, the next token separate character is replaced with a
+CHAR(\0), terminating the token.
+***/
+/*
+STDC(1)
+*/
diff --git a/src/string/strxfrm.c b/src/string/strxfrm.c
new file mode 100644
index 00000000..b6ec62b6
--- /dev/null
+++ b/src/string/strxfrm.c
@@ -0,0 +1,32 @@
+#include <string.h>
+#include "nonstd/assert.h"
+
+/** transform string **/
+size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n)
+{
+ /* TODO */
+ (void)s1; (void)s2; (void)n;
+ ASSERT_NONNULL(s2);
+
+ if (n != 0) {
+ ASSERT_NONNULL(s1);
+ ASSERT_NOOVERLAP(s1, s2, n);
+ }
+
+ return 0;
+}
+
+/***
+transforms up to ARGUMENT(n) bytes of the string at ARGUMENT(s2),
+placing the transformed string at ARGUMENT(s1). The transformed string is the
+canonical form of the string used for collation purposes. If a CHAR(\0) is
+transformed, no further characters are transformed.
+***/
+
+/*
+UNDEFINED(ARGUMENT(n) is not ZERO and ARGUMENT(s1) is CONSTANT(NULL))
+*/
+/*
+ RETURN_ALWAYS(the length of the transformed string, not including the terminating CHAR(\0));
+STDC(1)
+*/