summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/__FEATURE_TEST_MACROS__/__STDC_WANT_LIB_EXT1__.c0
-rw-r--r--src/errno/errno_t.c7
-rw-r--r--src/stddef/rsize_t.c5
-rw-r--r--src/stdint/RSIZE_MAX.c5
-rw-r--r--src/stdio/L_tmpnam_s.c5
-rw-r--r--src/stdio/TMP_MAX_S.c5
-rw-r--r--src/stdio/fopen_s.c55
-rw-r--r--src/stdio/fprintf_s.c31
-rw-r--r--src/stdio/freopen_s.c36
-rw-r--r--src/stdio/fscanf_s.c32
-rw-r--r--src/stdio/gets_s.c33
-rw-r--r--src/stdio/printf_s.c32
-rw-r--r--src/stdio/scanf_s.c32
-rw-r--r--src/stdio/snprintf_s.c10
-rw-r--r--src/stdio/sprintf_s.c31
-rw-r--r--src/stdio/sscanf_s.c32
-rw-r--r--src/stdio/tmpfile_s.c26
-rw-r--r--src/stdio/tmpnam_s.c43
-rw-r--r--src/stdio/vfprintf_s.c38
-rw-r--r--src/stdio/vfscanf_s.c10
-rw-r--r--src/stdio/vprintf_s.c28
-rw-r--r--src/stdio/vscanf_s.c11
-rw-r--r--src/stdio/vsnprintf_s.c216
-rw-r--r--src/stdio/vsprintf_s.c29
-rw-r--r--src/stdio/vsscanf_s.c10
-rw-r--r--src/stdlib/abort_handler_s.c10
-rw-r--r--src/stdlib/bsearch_s.c49
-rw-r--r--src/stdlib/constraint_handler_t.c5
-rw-r--r--src/stdlib/getenv_s.c27
-rw-r--r--src/stdlib/ignore_handler_s.c24
-rw-r--r--src/stdlib/mbstowcs_s.c26
-rw-r--r--src/stdlib/qsort_s.c29
-rw-r--r--src/stdlib/set_constraint_handler_s.c11
-rw-r--r--src/stdlib/wcstombs_s.c28
-rw-r--r--src/stdlib/wctomb_s.c32
-rw-r--r--src/string/memcpy_s.c35
-rw-r--r--src/string/memmove_s.c34
-rw-r--r--src/string/memset_s.c33
-rw-r--r--src/string/strcat_s.c29
-rw-r--r--src/string/strcpy_s.c29
-rw-r--r--src/string/strerror_s.c35
-rw-r--r--src/string/strerrorlen_s.c13
-rw-r--r--src/string/strncat_s.c44
-rw-r--r--src/string/strncpy_s.c43
-rw-r--r--src/string/strnlen_s.c17
-rw-r--r--src/string/strtok_s.c26
-rw-r--r--src/time/asctime_s.c43
-rw-r--r--src/time/ctime_s.c24
-rw-r--r--src/time/gmtime_s.c26
-rw-r--r--src/time/localtime_s.c25
-rw-r--r--src/wchar/fwprintf_s.c16
-rw-r--r--src/wchar/fwscanf_s.c16
-rw-r--r--src/wchar/mbsrtowcs_s.c13
-rw-r--r--src/wchar/snwprintf_s.c15
-rw-r--r--src/wchar/swprintf_s.c16
-rw-r--r--src/wchar/swscanf_s.c15
-rw-r--r--src/wchar/vfwprintf_s.c20
-rw-r--r--src/wchar/vfwscanf_s.c12
-rw-r--r--src/wchar/vsnwprintf_s.c9
-rw-r--r--src/wchar/vswprintf_s.c12
-rw-r--r--src/wchar/vswscanf_s.c15
-rw-r--r--src/wchar/vwprintf_s.c12
-rw-r--r--src/wchar/vwscanf_s.c12
-rw-r--r--src/wchar/wcrtomb_s.c11
-rw-r--r--src/wchar/wcscat_s.c10
-rw-r--r--src/wchar/wcscpy_s.c10
-rw-r--r--src/wchar/wcsncat_s.c10
-rw-r--r--src/wchar/wcsncpy_s.c10
-rw-r--r--src/wchar/wcsnlen_s.c11
-rw-r--r--src/wchar/wcsrtombs_s.c13
-rw-r--r--src/wchar/wcstok_s.c11
-rw-r--r--src/wchar/wmemcpy_s.c10
-rw-r--r--src/wchar/wmemmove_s.c10
-rw-r--r--src/wchar/wprintf_s.c15
-rw-r--r--src/wchar/wscanf_s.c15
75 files changed, 1778 insertions, 0 deletions
diff --git a/src/__FEATURE_TEST_MACROS__/__STDC_WANT_LIB_EXT1__.c b/src/__FEATURE_TEST_MACROS__/__STDC_WANT_LIB_EXT1__.c
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/__FEATURE_TEST_MACROS__/__STDC_WANT_LIB_EXT1__.c
diff --git a/src/errno/errno_t.c b/src/errno/errno_t.c
new file mode 100644
index 00000000..bc8e0af5
--- /dev/null
+++ b/src/errno/errno_t.c
@@ -0,0 +1,7 @@
+typedef int errno_t;
+
+/** error numbers **/
+/* DEF */
+/*
+CEXT1(201112)
+*/
diff --git a/src/stddef/rsize_t.c b/src/stddef/rsize_t.c
new file mode 100644
index 00000000..67e304a0
--- /dev/null
+++ b/src/stddef/rsize_t.c
@@ -0,0 +1,5 @@
+typedef size_t rsize_t;
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdint/RSIZE_MAX.c b/src/stdint/RSIZE_MAX.c
new file mode 100644
index 00000000..c649ceb5
--- /dev/null
+++ b/src/stdint/RSIZE_MAX.c
@@ -0,0 +1,5 @@
+#define RSIZE_MAX (SIZE_MAX>>1)
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/L_tmpnam_s.c b/src/stdio/L_tmpnam_s.c
new file mode 100644
index 00000000..c014796b
--- /dev/null
+++ b/src/stdio/L_tmpnam_s.c
@@ -0,0 +1,5 @@
+#define L_tmpnam_s (255)
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/TMP_MAX_S.c b/src/stdio/TMP_MAX_S.c
new file mode 100644
index 00000000..69822bb4
--- /dev/null
+++ b/src/stdio/TMP_MAX_S.c
@@ -0,0 +1,5 @@
+#define TMP_MAX_S (10000)
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/fopen_s.c b/src/stdio/fopen_s.c
new file mode 100644
index 00000000..59385515
--- /dev/null
+++ b/src/stdio/fopen_s.c
@@ -0,0 +1,55 @@
+#include "stdio.h"
+#include "__stdio.h"
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/** open a file stream **/
+errno_t fopen_s(FILE * restrict * restrict streamptr,
+ const char * restrict filename,
+ const char * restrict mode);
+{
+ __C_EXT(1, 201112L);
+ return 0;
+}
+
+/***
+The fn(fopen) function opens a file stream associated with the file
+arg(filename).
+
+The type of file and allowed operations are determined by arg(mode):
+
+string(r) text file; read-only
+string(w) text file; write-only; truncate to 0 bytes
+string(a) text file; append
+string(rb) binary file; read-only
+string(wb) binary file; write-only; truncate to 0 bytes
+string(ab) binary file; append
+string(r+) text file; update (read and write)
+string(w+) text file; update (read and write); truncate to 0 bytes
+string(a+) text file; update (read and write); append data to end of file
+string(r+b) binary file; update (read and write)
+string(rb+) binary file; update (read and write)
+string(w+b) binary file; update (read and write); truncate to 0 bytes
+string(wb+) binary file; update (read and write); truncate to 0 bytes
+string(a+b) binary file; update (read and write); append data to end of file
+string(ab+) binary file; update (read and write); append data to end of file
+
+File streams are opened in fully buffered mode if and only if arg(filename) is
+not an interactive device.
+
+The error and end-of-file indicators are cleared.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN(NULL): failure */
+/* RETURN: a pointer to the new file stream */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/fprintf_s.c b/src/stdio/fprintf_s.c
new file mode 100644
index 00000000..b633dee8
--- /dev/null
+++ b/src/stdio/fprintf_s.c
@@ -0,0 +1,31 @@
+#include "stdio.h"
+#include "stdarg.h"
+
+/** write formatted output to a file stream **/
+int fprintf_s(FILE * restrict stream, const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vfprintf_s(stream, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(fprintf) function writes a formatted string to arg(stream). The format
+of arg(format) and the variadic arguments is the same as that for fn(printf).
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(NEG): an error occurred */
+/* RETURN: the number of characters written */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/freopen_s.c b/src/stdio/freopen_s.c
new file mode 100644
index 00000000..d646bec8
--- /dev/null
+++ b/src/stdio/freopen_s.c
@@ -0,0 +1,36 @@
+#include "stdio.h"
+#include "__stdio.h"
+#include <fcntl.h>
+#include <string.h>
+
+/** reopen a file stream with a new file **/
+errno_t freopen_s(FILE * restrict * restrict newstreamptr,
+ const char * restrict filename,
+ const char * restrict mode,
+ FILE * restrict stream)
+{
+ __C_EXT(1, 201112L);
+ return 0;
+}
+
+/***
+The fn(freopen) function changes the file associated with arg(stream) to
+arg(filename). The meaning of arg(mode) is the same as with fn(fopen).
+
+Whatever file is currently associated with arg(stream) is closed, ignoring any
+errors.
+
+The error and end-of-file indicators are cleared.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN(NULL): the open operation failed */
+/* RETURN: the value of arg(stream) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/fscanf_s.c b/src/stdio/fscanf_s.c
new file mode 100644
index 00000000..de7f9e98
--- /dev/null
+++ b/src/stdio/fscanf_s.c
@@ -0,0 +1,32 @@
+#include "stdio.h"
+#include "stdio.h"
+#include "stdarg.h"
+
+/** read formatted input from a file stream **/
+int fscanf_s(FILE * restrict stream, const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vfscanf_s(stream, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(fscanf) function reads formatted input from arg(stream). The format of
+arg(format) at the variadic arguments is the same as that for fn(scanf).
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(EOF): an input failure occurred */
+/* RETURN: the number of input items assigned */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/gets_s.c b/src/stdio/gets_s.c
new file mode 100644
index 00000000..5af016dd
--- /dev/null
+++ b/src/stdio/gets_s.c
@@ -0,0 +1,33 @@
+#include "stdio.h"
+#include <limits.h>
+
+/** read a line from stdin **/
+char * gets_s(char *s, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ return fgets(s, INT_MAX, stdin);
+}
+
+/***
+The fn(gets) function does no bounds checking, is marked obsolete in C99, and
+has been removed from C11. It is a security risk and should not be used.
+
+The fn(gets) function reads a line of input from macro(stdin) into the array
+arg(s). Input characters are read until a newline or end-of-file is reached. The
+newline will not be appended to arg(s). A char(\0) character will be written
+after the last character read into the array.
+
+If end-of-file is reached before any characters are read, the contents of arg(s)
+remain unchanged.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN(EOF): end-of-file was reached with no characters read; or, an error occurred */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/printf_s.c b/src/stdio/printf_s.c
new file mode 100644
index 00000000..b5917062
--- /dev/null
+++ b/src/stdio/printf_s.c
@@ -0,0 +1,32 @@
+#include "stdio.h"
+#include "stdarg.h"
+
+/** write formatted output **/
+int printf_s(const char *format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vfprintf_s(stdout, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(fprintf) function writes a formatted string to macro(stdout).
+
+FIXME: printf format goes here
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(NEG): an error occurred */
+/* RETURN: the number of characters written */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/scanf_s.c b/src/stdio/scanf_s.c
new file mode 100644
index 00000000..f67335f7
--- /dev/null
+++ b/src/stdio/scanf_s.c
@@ -0,0 +1,32 @@
+#include "stdio.h"
+#include "stdarg.h"
+
+/** read formatted input **/
+int scanf_s(const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vfscanf_s(stdin, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(scanf) function reads formatted input from macro(stdin).
+
+FIXME: scanf format goes here
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(EOF): an input failure occurred */
+/* RETURN: the number of input items assigned */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/snprintf_s.c b/src/stdio/snprintf_s.c
new file mode 100644
index 00000000..dcbdafaa
--- /dev/null
+++ b/src/stdio/snprintf_s.c
@@ -0,0 +1,10 @@
+#include "stdio.h"
+
+int snprintf_s( char * restrict s, rsize_t n, const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/sprintf_s.c b/src/stdio/sprintf_s.c
new file mode 100644
index 00000000..223e84c8
--- /dev/null
+++ b/src/stdio/sprintf_s.c
@@ -0,0 +1,31 @@
+#include "stdio.h"
+#include "stdarg.h"
+
+/** write formatted output to a string **/
+int sprintf_s(char * restrict s, rsize_t n, const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vsprintf(s, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(sprintf) function writes a formatted string to the buffer at arg(s). The
+format of arg(format) and the variadic arguments is the same as that for
+fn(printf).
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN: the number of characters written, not including the final char(\0) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/sscanf_s.c b/src/stdio/sscanf_s.c
new file mode 100644
index 00000000..c91786f6
--- /dev/null
+++ b/src/stdio/sscanf_s.c
@@ -0,0 +1,32 @@
+#include "stdio.h"
+#include "stdarg.h"
+
+/** read formatted input from a string **/
+int sscanf_s(const char * restrict s, const char * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vsscanf(s, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+/***
+The fn(sscanf) function reads formatted input from the string arg(s). The
+format of arg(format) at the variadic arguments is the same as that for
+fn(scanf).
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(EOF): an input failure occurred */
+/* RETURN: the number of input items assigned */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/tmpfile_s.c b/src/stdio/tmpfile_s.c
new file mode 100644
index 00000000..948425ad
--- /dev/null
+++ b/src/stdio/tmpfile_s.c
@@ -0,0 +1,26 @@
+#include "stdio.h"
+
+/* open a temporary file stream */
+errno_t tmpfile_s(FILE * restrict * restrict streamptr)
+{
+ __C_EXT(1, 201112L);
+ return 0;
+}
+
+/***
+The fn(tmpfile) function creates a temporary binary file stream for update (as
+when arg(mode) is specified as string(wb+) to fn(fopen)). The file stream will
+be automatically removed when closed by fn(fclose) or when the program exits.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: whether the temporary file is removed if the program terminates abnormally */
+/* LOCALE: - */
+
+/* RETURN(NULL): a temporary file stream could not be created */
+/* RETURN: a pointer to the temporary file stream */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/tmpnam_s.c b/src/stdio/tmpnam_s.c
new file mode 100644
index 00000000..176eb982
--- /dev/null
+++ b/src/stdio/tmpnam_s.c
@@ -0,0 +1,43 @@
+#include "stdio.h"
+
+/** generate a temporary file name **/
+errno_t tmpnam_s(char *s, rsize_t maxsize)
+{
+ __C_EXT(1, 201112L);
+ static int ntimescalled = 0;
+ static char path[L_tmpnam];
+
+ if (ntimescalled >= TMP_MAX) {
+ return 0;
+ }
+ ntimescalled++;
+
+ if (s == NULL) {
+ s = path;
+ }
+
+ return 0;
+}
+
+/***
+The fn(tmpnam) function generates a unique file name that can be used as a
+temporary file. A new file name is generated every time the function is called
+up to macro(TMP_MAX) times.
+
+If arg(s) is macro(NULL), the temporary name is stored in a static internal
+buffer. This buffer may be overwritten by additional calls to fn(tmpnam).
+
+If arg(s) is not macro(NULL), it should point to a type(char) array of at least
+macro(L_tmpnam) characters. The temporary name will be copied to this array.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: behavior if fn(tmpnam) is called more than macro(TMP_MAX) times */
+/* LOCALE: - */
+
+/* RETURN: a pointer to the temporary file name */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vfprintf_s.c b/src/stdio/vfprintf_s.c
new file mode 100644
index 00000000..e2d94c71
--- /dev/null
+++ b/src/stdio/vfprintf_s.c
@@ -0,0 +1,38 @@
+#include "stdio.h"
+#include "__stdio.h"
+#include <stdarg.h>
+
+/** write formatted output to a file stream **/
+int vfprintf_s(FILE * restrict stream, const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_copy(ap, arg);
+ int len = vsnprintf(NULL, 0, format, arg);
+ char *buf = malloc(len + 1);
+ len = vsnprintf(buf, len, format, ap);
+ va_end(ap);
+ len = (int)fwrite(buf, sizeof(*buf), len, stream);
+ free(buf);
+ return len;
+}
+
+/***
+The fn(vfprintf) function is equivalent to fn(fprintf), but with a type(va_list)
+argument instead of variadic arguments. The argument arg(arg) must be
+initialized with fnmacro(va_start) prior to calling fn(vfprintf). The
+fn(vfprintf) function does not call fnmacro(va_end), so the calling function is
+responsible for this.
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(NEG): an error occurred */
+/* RETURN: the number of characters written */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vfscanf_s.c b/src/stdio/vfscanf_s.c
new file mode 100644
index 00000000..82fb238c
--- /dev/null
+++ b/src/stdio/vfscanf_s.c
@@ -0,0 +1,10 @@
+#include "stdio.h"
+
+int vfscanf_s(FILE * restrict stream, const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vprintf_s.c b/src/stdio/vprintf_s.c
new file mode 100644
index 00000000..c13b1ead
--- /dev/null
+++ b/src/stdio/vprintf_s.c
@@ -0,0 +1,28 @@
+#include "stdio.h"
+
+/** write formatted output **/
+int vprintf_s(const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ return vfprintf(stdout, format, arg);
+}
+
+/***
+The fn(vprintf) function is equivalent to fn(printf), but with a type(va_list)
+argument instead of variadic arguments. The argument arg(arg) must be
+initialized with fnmacro(va_start) prior to calling fn(vprintf). The
+fn(vprintf) function does not call fnmacro(va_end), so the calling function is
+responsible for this.
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN(NEG): an error occurred */
+/* RETURN: the number of characters written */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vscanf_s.c b/src/stdio/vscanf_s.c
new file mode 100644
index 00000000..85f34e07
--- /dev/null
+++ b/src/stdio/vscanf_s.c
@@ -0,0 +1,11 @@
+#include "stdio.h"
+
+int vscanf_s(const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ return vfscanf(stdin, format, arg);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vsnprintf_s.c b/src/stdio/vsnprintf_s.c
new file mode 100644
index 00000000..48fbe425
--- /dev/null
+++ b/src/stdio/vsnprintf_s.c
@@ -0,0 +1,216 @@
+#include "internal_vsnprintf.c"
+#include <inttypes.h>
+
+int vsnprintf_s(char * restrict s, rsize_t n, const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ int nout = 0;
+
+ intmax_t argint = 0;
+ void *argptr = NULL;
+ char numbuf[NUMBUFLEN];
+
+ for (size_t i = 0; format[i] != 0; i++) {
+ if (format[i] != '%') {
+ if (nout < (int)n) {
+ s[nout] = format[i];
+ }
+ nout++;
+ continue;
+ }
+
+ //__asm int 3;
+ // zero of more flags "-+ #0"
+ // optional width "*" or decimal integer
+ // optional precision ".*" or ".[decimal]"
+ // optional length modifier "hh", "h", "l", "ll", "j",
+ // "z", "t", "L"
+ // conversion specifier "diouxXfFeEgGaAcspn%"
+ int flags = 0;
+ uintmax_t width = 0;
+ int step = 0;
+ int precision = 0;
+ int base = 10;
+ enum { def, hh, h, l, ll, j, z, t, L } length = def;
+
+ while (step == 0) {
+ i++;
+ switch (format[i]) {
+ case '-': flags |= LEFT; break;
+ case '+': flags |= SIGN; break;
+ case ' ': flags |= SPACE; break;
+ case '#': flags |= ALT; break;
+ case '0': flags |= ZERO; break;
+ default: step = 1; break;
+ }
+ }
+
+ if (format[i] == '*') {
+ i++;
+ } else if (isdigit(format[i])) {
+ char *end;
+ width = strtoumax(format + i, &end, 10);
+ i = end - format;
+ }
+
+ if (format[i] == '.') {
+ i++;
+ if (format[i] == '*') {
+ i++;
+ } else if (isdigit(format[i])) {
+ char *end;
+ precision = (int)strtoumax(format + i, &end, 10);
+ i = end - format;
+ } else {
+ // invalid precision
+ return -nout;
+ }
+ }
+
+ if (format[i] == 'h') {
+ i++;
+ if (format[i] == 'h') {
+ i++;
+ length = hh;
+ } else {
+ length = h;
+ }
+ } else if (format[i] == 'l') {
+ i++;
+ if (format[i] == 'l') {
+ i++;
+ length = ll;
+ } else {
+ length = l;
+ }
+ } else if (format[i] == 'j') {
+ i++;
+ length = j;
+ } else if (format[i] == 'z') {
+ i++;
+ length = z;
+ } else if (format[i] == 't') {
+ i++;
+ length = t;
+ } else if (format[i] == 'L') {
+ i++;
+ length = L;
+ }
+
+ if (isupper(format[i])) {
+ flags |= UPPER;
+ }
+
+ switch (format[i]) {
+ case 'o': // unsigned int
+ case 'u':
+ case 'x':
+ case 'X':
+ flags |= UNSIGNED;
+
+ case 'd': // int
+ case 'i':
+ switch (length) {
+ case hh: argint = (signed char)va_arg(arg, int); break;
+ case h: argint = (short int)va_arg(arg, int); break;
+ case l: argint = va_arg(arg, long int); break;
+ case ll: argint = va_arg(arg, long long int); break;
+ case j: argint = va_arg(arg, intmax_t); break;
+ case z: argint = va_arg(arg, size_t); break;
+ case t: argint = va_arg(arg, ptrdiff_t); break;
+ case L: return -nout;
+ default: argint = va_arg(arg, int); break;
+ }
+ if (format[i] == 'o') {
+ base = 8;
+ } else if (format[i] == 'x') {
+ base = 16;
+ } else if (format[i] == 'X') {
+ base = 16;
+ flags |= UPPER;
+ } else {
+ base = 10;
+ }
+ itos(numbuf, (long int)argint, flags, precision, base);
+ nout = append(s, numbuf, nout, n);
+ break;
+
+
+ case 'f': // double [-]ddd.ddd
+ case 'F':
+ break;
+
+ case 'e': // double [-]d.ddde+/-dd
+ case 'E':
+ break;
+
+ case 'g': // double f or e see docs
+ case 'G':
+ break;
+
+ case 'a': // double as hex
+ case 'A':
+ break;
+
+ case 'c': // char
+ if (length == def) {
+ char c = va_arg(arg, int);
+ if (nout < (int)n) {
+ s[nout] = c;
+ }
+ nout++;
+ } else if (length == l) {
+ //wint_t wc = va_arg(arg, wint_t);
+ //char mb[MB_CUR_MAX + 1] = "WC";
+ //wctomb(mb, wc);
+ //nout = append(s, mb, nout, n);
+ } else {
+ return -nout;
+ }
+ break;
+
+ case 's': // string
+ if (length == def) {
+ char *string = va_arg(arg, char *);
+ nout = append(s, string, nout, n);
+ } else if (length == l) {
+ //wchar_t *ws = va_arg(arg, wchar_t *);
+ //char *mbs = malloc(wcslen(ws) * MB_CUR_MAX + 1);
+ //wcstombs(mbs, ws, wcslen(ws) * MB_CUR_MAX + 1);
+ //nout = append(s, mbs, nout, n);
+ //free(mbs);
+ nout = append(s, "WIDE STRING", nout, n);
+ } else {
+ return -nout;
+ }
+
+ break;
+
+ case 'p': // pointer
+ argptr = va_arg(arg, void *);
+ nout = append(s, "0x", nout, n);
+ itos(numbuf, (intptr_t)argptr, ZERO, sizeof(argptr) * 2, 16);
+ nout = append(s, numbuf, nout, n);
+ break;
+
+ case 'n': // write-back
+ break;
+
+ case '%': // literal '%'
+ if (nout < (int)n) {
+ s[nout] = '%';
+ }
+ nout++;
+ break;
+
+ default: // undefined
+ return -nout;
+ }
+ }
+
+ return nout;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vsprintf_s.c b/src/stdio/vsprintf_s.c
new file mode 100644
index 00000000..98a7794f
--- /dev/null
+++ b/src/stdio/vsprintf_s.c
@@ -0,0 +1,29 @@
+#include "stdio.h"
+#include <stdarg.h>
+#include <stdint.h>
+
+/** write formatted output to a string **/
+int vsprintf_s(char *s, rsize_t n, const char *format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ return vsnprintf(s, SIZE_MAX, format, arg);
+}
+
+/***
+The fn(vsprintf) function is equivalent to fn(sprintf), but with a type(va_list)
+argument instead of variadic arguments. The argument arg(arg) must be
+initialized with fnmacro(va_start) prior to calling fn(vsprintf). The
+fn(vsprintf) function does not call fnmacro(va_end), so the calling function is
+responsible for this.
+***/
+
+/* UNSPECIFIED: ??? */
+/* UNDEFINED: ??? */
+/* IMPLEMENTATION: ??? */
+/* LOCALE: ??? */
+
+/* RETURN: the number of characters written, not including the final char(\0) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdio/vsscanf_s.c b/src/stdio/vsscanf_s.c
new file mode 100644
index 00000000..6ac2e6fa
--- /dev/null
+++ b/src/stdio/vsscanf_s.c
@@ -0,0 +1,10 @@
+#include "stdarg.h"
+
+int vsscanf_s(const char * restrict s, const char * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/abort_handler_s.c b/src/stdlib/abort_handler_s.c
new file mode 100644
index 00000000..8f7ef71a
--- /dev/null
+++ b/src/stdlib/abort_handler_s.c
@@ -0,0 +1,10 @@
+#include "stdlib.h"
+
+void abort_handler_s(const char * restrict msg, void * restrict ptr, errno_t error)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/bsearch_s.c b/src/stdlib/bsearch_s.c
new file mode 100644
index 00000000..12a19c25
--- /dev/null
+++ b/src/stdlib/bsearch_s.c
@@ -0,0 +1,49 @@
+#include <stddef.h>
+
+/** binary search **/
+void *bsearch_s(const void * key, const void * base,
+ rsize_t nmemb, rsize_t size,
+ int (*compar)(const void *x, const void *y, void * context),
+ void *context)
+{
+ __C_EXT(1, 201112L);
+ /* TODO: testing */
+ void *ret = NULL;
+ size_t i = nmemb / 2;
+ unsigned int trip = 1;
+
+ while (ret == NULL) {
+ int comp = compar(key, base+i);
+ if (comp == 0) {
+ return (void*)base+i;
+ } else if (comp > 0) {
+ i -= (nmemb >> trip);
+ } else {
+ i += (nmemb >> trip);
+ }
+ }
+ return NULL;
+}
+
+/***
+The fn(bsearch) function performs a binary search for arg(key) in the array
+arg(base), which contains arg(nmemb) members of arg(size) bytes each.
+
+The search is performed by calling arg(compar) with the first argument of
+arg(key), and the second being an element from the array at arg(base). The
+function must return less than 0 if arg(key) is less than the other element,
+0 if they are equal, and greater than 0 if arg(key) is greater than the other
+element.
+***/
+
+/* UNSPECIFIED: which element is matched if two elements are equal */
+/* UNDEFINED: the array at arg(base) is not sorted */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN(NULL): no match was found */
+/* RETURN: a pointer to the matching element */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/constraint_handler_t.c b/src/stdlib/constraint_handler_t.c
new file mode 100644
index 00000000..6c109471
--- /dev/null
+++ b/src/stdlib/constraint_handler_t.c
@@ -0,0 +1,5 @@
+typedef void (*constraint_handler_t)(const char * restrict msg, void * restrict ptr, errno_t error);
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/getenv_s.c b/src/stdlib/getenv_s.c
new file mode 100644
index 00000000..88156c1e
--- /dev/null
+++ b/src/stdlib/getenv_s.c
@@ -0,0 +1,27 @@
+#include <string.h>
+#include "stdlib.h"
+
+/** get an environment variable **/
+errno_t getenv_s(size_t * restrict len, char * restrict value, rsize_t maxsize, const char * restrict name)
+{
+ __C_EXT(1, 201112L);
+ return 0;
+}
+
+/***
+The fn(getenv) function read the environment variable arg(name) from the host
+environment.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: modifying the returned string */
+/* IMPLEMENTATION: the set of environment variable names */
+/* IMPLEMENTATION: the method of altering the environment */
+/* LOCALE: - */
+
+/* RETURN(NULL): the environment variable could not be found */
+/* RETURN: the value of the requested environment variable */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/ignore_handler_s.c b/src/stdlib/ignore_handler_s.c
new file mode 100644
index 00000000..0a4ef62c
--- /dev/null
+++ b/src/stdlib/ignore_handler_s.c
@@ -0,0 +1,24 @@
+#include "stdlib.h"
+
+/** ignore constraint violations **/
+void ignore_handler_s(const char * restrict msg, void * restrict ptr, errno_t error)
+{
+ __C_EXT(1, 201112L);
+ return;
+}
+
+/***
+The fn(ignore_handler_s) function is suitable for use as the system constraint
+handler as set by fn(set_constraint_handler_s).
+
+It simply returns to its caller.
+***/
+
+/* UNDEFINED: - */
+/* UNSPECIFIED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/mbstowcs_s.c b/src/stdlib/mbstowcs_s.c
new file mode 100644
index 00000000..70ef0433
--- /dev/null
+++ b/src/stdlib/mbstowcs_s.c
@@ -0,0 +1,26 @@
+#include "stdlib.h"
+
+/** convert multibyte string to wide character string **/
+errno_t mbstowcs_s(size_t * restrict retval, wchar_t * restrict dst, rsize_t dstmax, const char * restrict src, rsize_t len)
+{
+ __C_EXT(1, 201112L);
+}
+
+/***
+The fn(mbstowcs) function converts the string of multibyte characters arg(s)
+to a string of wide characters, which are stored at arg(pwcs). No more than
+arg(n) wide characters are stored at arg(pwcs). No further characters will
+be converted after a null character, which is converted.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: the memory regions of arg(s) and arg(pwcs) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: LC_CTYPE */
+
+/* RETURN(-1): an invalid multibyte character was encountered */
+/* RETURN: the number of wide characters converted, not counting any terminating zero */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/qsort_s.c b/src/stdlib/qsort_s.c
new file mode 100644
index 00000000..da12d505
--- /dev/null
+++ b/src/stdlib/qsort_s.c
@@ -0,0 +1,29 @@
+#include "stdlib.h"
+
+/** sort an array **/
+errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size,
+ int (*compar)(const void * x, const void * y, void *context),
+ void * context)
+{
+ __C_EXT(1, 201112L);
+ /* TODO */
+}
+
+/***
+The fn(qsort) function sorts the array at arg(base), which consists of
+arg(nmemb) elements of arg(size) bytes each.
+
+The sorting is performed by calling arg(compar) with two elements of the array.
+The function must return less than 0 if the first argument is less than the
+second, 0 if they are equal, and greater than 0 if the first argument is
+greater than the second.
+***/
+
+/* UNSPECIFIED: the order of equal elements */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/set_constraint_handler_s.c b/src/stdlib/set_constraint_handler_s.c
new file mode 100644
index 00000000..b32c9860
--- /dev/null
+++ b/src/stdlib/set_constraint_handler_s.c
@@ -0,0 +1,11 @@
+#include "stdlib.h"
+
+constraint_handler_t set_constraint_handler_s(constraint_handler_t handler)
+{
+ __C_EXT(1, 201112L);
+ return handler;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/wcstombs_s.c b/src/stdlib/wcstombs_s.c
new file mode 100644
index 00000000..b0a8980b
--- /dev/null
+++ b/src/stdlib/wcstombs_s.c
@@ -0,0 +1,28 @@
+#include "stdlib.h"
+
+/** convert wide character string to multibyte string **/
+errno_t wcstombs_s(size_t * restrict retval, char * restrict dst, rsize_t dstmax, const wchar_t * restrict src, rsize_t len)
+{
+ __C_EXT(1, 201112L);
+ /* TODO */
+ return 0;
+}
+
+/***
+The fn(wcstombs) function converts the wide character string arg(pwcs) to a
+multibyte string, which is stored at arg(s), beginning in the initial shift
+state. No more than arg(n) bytes are written to arg(s). Conversion stops
+after reaching a null wide character, which is converted and stored.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: the memory regions of arg(s) and arg(pwcs) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: LC_CTYPE */
+
+/* RETURN(-1): a code was encountered which does not correspond to a valid multibyte character */
+/* RETURN: the number of bytes modified, not counting any terminating null */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/stdlib/wctomb_s.c b/src/stdlib/wctomb_s.c
new file mode 100644
index 00000000..0a3f510e
--- /dev/null
+++ b/src/stdlib/wctomb_s.c
@@ -0,0 +1,32 @@
+#include "stdlib.h"
+
+/** convert wide character to multibyte character **/
+errno_t wctomb_s(int * restrict status, char * restrict s, rsize_t smax, wchar_t wc)
+{
+ __C_EXT(1, 201112L);
+ /* TODO */
+ return 0;
+}
+
+/***
+The fn(wctomb) function converts the wide character arg(wchar) to a multibyte
+character, which is stored at the address arg(s). At most macro(MB_CUR_MAX)
+bytes are stored.
+
+If arg(s) is macro(NULL), fn(wctomb) tests whether multibyte encodings carry
+state dependency.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: LC_CTYPE */
+
+/* RETURN(0): if arg(s) is macro(NULL), multibyte encodings do not have state dependencies */
+/* RETURN(NZ): if arg(s) is macro(NULL), multibyte encodings do have state dependencies */
+/* RETURN(-1): the value of arg(wchar) does not correspond to a valid multibyte character */
+/* RETURN: the number of bytes contained in the multibyte character corresponding to arg(wchar) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/memcpy_s.c b/src/string/memcpy_s.c
new file mode 100644
index 00000000..366a879c
--- /dev/null
+++ b/src/string/memcpy_s.c
@@ -0,0 +1,35 @@
+#include "string.h"
+#include "sys/_nonstd_.h"
+
+/** copy memory **/
+errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s1);
+ __ASSERT_NONNULL(s2);
+ __ASSERT_NOOVERLAP(s1, s2, n);
+
+ char *dst = (char*)s1, *src = (char*)s2;
+ int i = 0;
+ while (i < n) {
+ dst[i] = src[i];
+ i++;
+ }
+ return dst;
+}
+
+/***
+The fn(memcpy) copies arg(n) bytes from the object at arg(s2) to the object at
+arg(s1).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: if the objects overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/memmove_s.c b/src/string/memmove_s.c
new file mode 100644
index 00000000..c489161d
--- /dev/null
+++ b/src/string/memmove_s.c
@@ -0,0 +1,34 @@
+#include "string.h"
+#include "stdlib.h"
+#include "sys/_nonstd_.h"
+
+/** move memory **/
+errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s1);
+ __ASSERT_NONNULL(s2);
+
+ void *buf = malloc(n);
+ memcpy(buf, s2, n);
+ memcpy(s1, buf, n);
+ free(buf);
+ return s1;
+}
+
+/***
+The fn(memmove) function copies arg(n) bytes of memory from the object at
+arg(s2) to the object at arg(s1). If arg(s1) and arg(s2) overlap, the memory
+is copied so that the arg(n) bytes are safely written to arg(s1).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/memset_s.c b/src/string/memset_s.c
new file mode 100644
index 00000000..71e3add1
--- /dev/null
+++ b/src/string/memset_s.c
@@ -0,0 +1,33 @@
+#include "string.h"
+
+/** fill memory **/
+errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s);
+
+ unsigned char *_s = (unsigned char *)s;
+ int i = 0;
+
+ while (i < n) {
+ _s[i] = (unsigned char)c;
+ }
+
+ return s;
+}
+
+/***
+The fn(memset) function fills the first arg(n) bytes of memory at arg(s) with
+the value arg(c) (converted to an type(unsigned char)).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strcat_s.c b/src/string/strcat_s.c
new file mode 100644
index 00000000..14db822d
--- /dev/null
+++ b/src/string/strcat_s.c
@@ -0,0 +1,29 @@
+#include "string.h"
+
+/** concatenate strings **/
+errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s1);
+ __ASSERT_NONNULL(s2);
+ __ASSERT_NOOVERLAP(s1, s2, strlen(s1) + strlen(s2));
+
+ return strncat(s1, s2, strlen(s2));
+}
+
+/***
+The fn(strcat) function appends a copy of the string at arg(s2) to the end of
+the string at arg(s1). The first byte of arg(s2) will overwrite the terminating
+null character of arg(s1).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: if arg(s1) and arg(s2) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strcpy_s.c b/src/string/strcpy_s.c
new file mode 100644
index 00000000..15e624b4
--- /dev/null
+++ b/src/string/strcpy_s.c
@@ -0,0 +1,29 @@
+#include "string.h"
+#include <limits.h>
+
+/** copy string **/
+errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s1);
+ __ASSERT_NONNULL(s2);
+ __ASSERT_NOOVERLAP(s1, s2, strlen(s2));
+
+ return strncpy(s1, s2, strlen(s2));
+}
+
+/***
+The fn(strcpy) function copies the string at arg(s2) to arg(s1), up to and
+including the terminating char(\0).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: if arg(s1) and arg(s2) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strerror_s.c b/src/string/strerror_s.c
new file mode 100644
index 00000000..293bb81d
--- /dev/null
+++ b/src/string/strerror_s.c
@@ -0,0 +1,35 @@
+#include "string.h"
+#include "errno.h"
+#include "__strerror.h"
+
+/** convert error number to string **/
+errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum)
+{
+ __C_EXT(1, 201112L);
+ if (errnum > __nstrerror || __strerror[errnum] == NULL) {
+ if (snprintf(s, maxsize, "Uknown error [%d]", errnum) < maxsize) {
+ return 0;
+ }
+ return 1;
+ }
+
+ strncpy(s, __strerror[errnum], maxsize);
+ return errnum;
+}
+
+/***
+The fn(strerror_s) converts the error number arg(errnum) to an error message
+string. The string returned should not be modified, and may be overwritten by
+subsequent calls.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: LC_MESSAGES */
+
+/* RETURN: a pointer to the error message string */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strerrorlen_s.c b/src/string/strerrorlen_s.c
new file mode 100644
index 00000000..8b0d99bf
--- /dev/null
+++ b/src/string/strerrorlen_s.c
@@ -0,0 +1,13 @@
+#include "string.h"
+
+size_t strerrorlen_s(errno_t errnum)
+{
+ __C_EXT(1, 201112L);
+ char buffer[1024];
+ strerror_s(buffer, sizeof(buffer), errnum);
+ return strlen(buffer);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strncat_s.c b/src/string/strncat_s.c
new file mode 100644
index 00000000..2c6d65e6
--- /dev/null
+++ b/src/string/strncat_s.c
@@ -0,0 +1,44 @@
+#include "string.h"
+
+/** concatenate bounded string **/
+errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ //__ASSERT_NONNULL(s1);
+ //__ASSERT_NONNULL(s2);
+ //__ASSERT_NOOVERLAP(s1, s2, strlen(s1) + strlen(s2));
+
+ char *append = s1 + strlen(s1);
+ for (size_t i = 0; i < n; i++) {
+ *append = s2[i];
+ if (*append == '\0') {
+ break;
+ }
+ append++;
+ }
+
+ if (append[-1] != '\0') {
+ *append = '\0';
+ }
+
+ return s1;
+}
+
+/***
+The fn(strncat) function appends a copy of the frist arg(n) bytes of the string
+at arg(s2) to the end of the string at arg(s1). The first byte of arg(s2) will
+overwrite the terminating null character of arg(s1). No characters after the
+first char(\0) will be copied. The resulting string will always be null
+terminated.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: arg(s1) and arg(s2) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strncpy_s.c b/src/string/strncpy_s.c
new file mode 100644
index 00000000..39b045a9
--- /dev/null
+++ b/src/string/strncpy_s.c
@@ -0,0 +1,43 @@
+#include "string.h"
+
+/** copy bounded string **/
+errno_t strncpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+ __ASSERT_NONNULL(s1);
+ __ASSERT_NONNULL(s2);
+ __ASSERT_NOOVERLAP(s1, s2, n);
+
+ size_t i;
+ for (i = 0; i < n; i++) {
+ s1[i] = s2[i];
+ if (s1[i] == '\0') {
+ break;
+ }
+ }
+
+ while (i < n) {
+ s1[i++] = '\0';
+ }
+
+ return s1;
+}
+
+/***
+The fn(strncpy) function copies up to arg(n) bytes from the string at arg(s2)
+to arg(s1). If a char(\0) is encountered, null characters are appended to
+arg(s1) until arg(n) bytes have been written. If no null characters are copied
+in the first arg(n) bytes of arg(s2), the resulting string will not be null
+terminated.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: if arg(s1) and arg(s2) overlap */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: the value of arg(s1) */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strnlen_s.c b/src/string/strnlen_s.c
new file mode 100644
index 00000000..f1221961
--- /dev/null
+++ b/src/string/strnlen_s.c
@@ -0,0 +1,17 @@
+#include "string.h"
+
+size_t strnlen_s(const char *s, size_t maxsize)
+{
+ __C_EXT(1, 201112L);
+ size_t i = 0;
+ while (i < maxlen) {
+ if (s[i] == '\0')
+ return i;
+ i++;
+ }
+ return i;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/string/strtok_s.c b/src/string/strtok_s.c
new file mode 100644
index 00000000..9742d09c
--- /dev/null
+++ b/src/string/strtok_s.c
@@ -0,0 +1,26 @@
+#include "string.h"
+#include "stddef.h"
+
+char * strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char **restrict ptr)
+{
+ __C_EXT(1, 201112L);
+ int i = 0;
+
+ if (s == NULL)
+ s = *lasts;
+
+ while (i < strlen (s)) {
+ if (strchr (sep, s[i]) == NULL) {
+ i++;
+ } else {
+ s[i] = '\0';
+ *lasts = &(s[i+1]);
+ return s;
+ }
+ }
+ return NULL;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/time/asctime_s.c b/src/time/asctime_s.c
new file mode 100644
index 00000000..69f9fd33
--- /dev/null
+++ b/src/time/asctime_s.c
@@ -0,0 +1,43 @@
+#include "time.h"
+#include "stdio.h"
+
+/** convert broken down time to string **/
+errno_t asctime_s(char *s, rsize_t maxsize, const struct tm * timeptr)
+{
+ __C_EXT(1, 201112L);
+ static const char days[7][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char months[12][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ static char result[26];
+
+ sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ days[timeptr->tm_wday], months[timeptr->tm_mon],
+ timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min,
+ timeptr->tm_sec, timeptr->tm_year + 1900);
+ return result;
+}
+
+/***
+The fn(asctime) function converts the time specified at arg(timeptr) to a string
+in the format string(DDD MMM dd hh:mm:ss yyyy\n\0), where str(DDD) is the
+three-character abbreviated day of the week, str(MMM) is the three-character
+abbreviated month, string(dd) is the day of the month, str(hh) is the hour of
+the day (in the range (0,23)), str(mm) is the minute of the hour (in the range
+(0,59)), str(ss) is the second of the minute (in the range (0,61)), and
+str(yyyy) is the year.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: a pointer to the string */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/time/ctime_s.c b/src/time/ctime_s.c
new file mode 100644
index 00000000..8813247c
--- /dev/null
+++ b/src/time/ctime_s.c
@@ -0,0 +1,24 @@
+#include "time.h"
+
+/** convert arithmetic time to string **/
+errno_t ctime_s(char *s, rsize_t maxsize, const time_t *timer)
+{
+ __C_EXT(1, 201112L);
+ return asctime(localtime(timer));
+}
+
+/***
+The fn(ctime) converts the time at arg(timer) to a string in the same format as
+fn(asctime).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: a pointer to the string */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/time/gmtime_s.c b/src/time/gmtime_s.c
new file mode 100644
index 00000000..1629a651
--- /dev/null
+++ b/src/time/gmtime_s.c
@@ -0,0 +1,26 @@
+#include "time.h"
+
+/** convert arithmetic time to borken down time **/
+struct tm * gmtime_s(const time_t * restrict timer, struct tm * restrict result)
+{
+ __C_EXT(1, 201112L);
+ /* TODO */
+ return NULL;
+}
+
+/***
+The fn(gmtime) function converts the UTC time at arg(timer) to a filled out
+type(struct tm).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN(NULL): UTC is not available */
+/* RETURN: a pointer to the converted structure */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/time/localtime_s.c b/src/time/localtime_s.c
new file mode 100644
index 00000000..f8ad731a
--- /dev/null
+++ b/src/time/localtime_s.c
@@ -0,0 +1,25 @@
+#include "time.h"
+
+/** convert arithmetic time to broken down time **/
+struct tm * localtime_s(const time_t * restrict timer, struct tm * restrict result)
+{
+ __C_EXT(1, 201112L);
+ /* TODO */
+ return NULL;
+}
+
+/***
+The fn(localtime) function converts the locale time at arg(timer) to a filled
+out type(struct tm).
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: - */
+/* LOCALE: - */
+
+/* RETURN: a pointer to the converted object */
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/fwprintf_s.c b/src/wchar/fwprintf_s.c
new file mode 100644
index 00000000..c3011d8d
--- /dev/null
+++ b/src/wchar/fwprintf_s.c
@@ -0,0 +1,16 @@
+#include "stdio.h"
+#include "wchar.h"
+
+int fwprintf_s(FILE * restrict stream, const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vfwprintf_s(stream, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/fwscanf_s.c b/src/wchar/fwscanf_s.c
new file mode 100644
index 00000000..8f16dca7
--- /dev/null
+++ b/src/wchar/fwscanf_s.c
@@ -0,0 +1,16 @@
+#include "stdio.h"
+#include "wchar.h"
+
+int fwscanf_s(FILE * restrict stream, const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vfwscanf_s(stream, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/mbsrtowcs_s.c b/src/wchar/mbsrtowcs_s.c
new file mode 100644
index 00000000..28c89f61
--- /dev/null
+++ b/src/wchar/mbsrtowcs_s.c
@@ -0,0 +1,13 @@
+#include "wchar.h"
+
+errno_t mbsrtowcs_s(size_t * restrict retval,
+ wchar_t * restrict dst, rsize_t dstmax,
+ const char ** restrict src, rsize_t len,
+ mbstate_t * restrict ps)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/snwprintf_s.c b/src/wchar/snwprintf_s.c
new file mode 100644
index 00000000..20ebc8db
--- /dev/null
+++ b/src/wchar/snwprintf_s.c
@@ -0,0 +1,15 @@
+#include "wchar.h"
+
+int snwprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vsnwprintf_s(s, n, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/swprintf_s.c b/src/wchar/swprintf_s.c
new file mode 100644
index 00000000..ade55f4e
--- /dev/null
+++ b/src/wchar/swprintf_s.c
@@ -0,0 +1,16 @@
+#include "wchar.h"
+
+int swprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format,
+ ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vswprintf_s(s, n, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/swscanf_s.c b/src/wchar/swscanf_s.c
new file mode 100644
index 00000000..e89fb20c
--- /dev/null
+++ b/src/wchar/swscanf_s.c
@@ -0,0 +1,15 @@
+#include "wchar.h"
+
+int swscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vswscanf_s(s, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vfwprintf_s.c b/src/wchar/vfwprintf_s.c
new file mode 100644
index 00000000..3b18525f
--- /dev/null
+++ b/src/wchar/vfwprintf_s.c
@@ -0,0 +1,20 @@
+#include "stdio.h"
+#include "wchar.h"
+
+int vfwprintf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_copy(ap, arg);
+ int len = vsnwprintf(NULL, 0, format, arg);
+ wchar_t *buf = malloc((len + 1) * sizeof(wchar_t));
+ len = vsnprintf(buf, len, format, ap);
+ va_end(ap);
+ //len = (int)fwrite(buf, sizeof(*buf), len, stream);
+ free(buf);
+ return len;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vfwscanf_s.c b/src/wchar/vfwscanf_s.c
new file mode 100644
index 00000000..163741a1
--- /dev/null
+++ b/src/wchar/vfwscanf_s.c
@@ -0,0 +1,12 @@
+#include "stdio.h"
+#include "wchar.h"
+
+int vfwscanf_s(FILE * restrict stream, const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ // also maybe this one
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vsnwprintf_s.c b/src/wchar/vsnwprintf_s.c
new file mode 100644
index 00000000..103cd1ee
--- /dev/null
+++ b/src/wchar/vsnwprintf_s.c
@@ -0,0 +1,9 @@
+int vsnwprintf_s(whcar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ // the actual function
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vswprintf_s.c b/src/wchar/vswprintf_s.c
new file mode 100644
index 00000000..69912a57
--- /dev/null
+++ b/src/wchar/vswprintf_s.c
@@ -0,0 +1,12 @@
+#include "wchar.h"
+#include <stdarg.h>
+
+int vswprintf_s(wchar_t * restrict s, rsize_t n, const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ // wait
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vswscanf_s.c b/src/wchar/vswscanf_s.c
new file mode 100644
index 00000000..c65a8c79
--- /dev/null
+++ b/src/wchar/vswscanf_s.c
@@ -0,0 +1,15 @@
+#include "wchar.h"
+#include <stdarg.h>
+
+int vswscanf_s(const wchar_t * restrict s, const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ // fmemopen(a stream)
+ // vfwscanf_s(that stream)
+ // wcscpy(the results)
+ // return length
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vwprintf_s.c b/src/wchar/vwprintf_s.c
new file mode 100644
index 00000000..89709344
--- /dev/null
+++ b/src/wchar/vwprintf_s.c
@@ -0,0 +1,12 @@
+#include "wchar.h"
+#include <stdarg.h>
+
+int vwprintf_s(const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ return vfwprintf_s(stdout, format, arg);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/vwscanf_s.c b/src/wchar/vwscanf_s.c
new file mode 100644
index 00000000..780fb553
--- /dev/null
+++ b/src/wchar/vwscanf_s.c
@@ -0,0 +1,12 @@
+#include "wchar.h"
+#include <stdarg.h>
+
+int vwscanf_s(const wchar_t * restrict format, va_list arg)
+{
+ __C_EXT(1, 201112L);
+ return vwscanf_s(stdin, format, arg);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcrtomb_s.c b/src/wchar/wcrtomb_s.c
new file mode 100644
index 00000000..69f7b62d
--- /dev/null
+++ b/src/wchar/wcrtomb_s.c
@@ -0,0 +1,11 @@
+#include "wchar.h"
+
+errno_t wcrtomb_s(size_t * restrict retval, char * restrict s, rsize_t smax,
+ wchar_t wc, mbstate_t * restrict ps)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcscat_s.c b/src/wchar/wcscat_s.c
new file mode 100644
index 00000000..0b558b11
--- /dev/null
+++ b/src/wchar/wcscat_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wcscat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcscpy_s.c b/src/wchar/wcscpy_s.c
new file mode 100644
index 00000000..438d29a5
--- /dev/null
+++ b/src/wchar/wcscpy_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wcscpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcsncat_s.c b/src/wchar/wcsncat_s.c
new file mode 100644
index 00000000..673a407e
--- /dev/null
+++ b/src/wchar/wcsncat_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wcsncat_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcsncpy_s.c b/src/wchar/wcsncpy_s.c
new file mode 100644
index 00000000..4aba2220
--- /dev/null
+++ b/src/wchar/wcsncpy_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wcsncpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcsnlen_s.c b/src/wchar/wcsnlen_s.c
new file mode 100644
index 00000000..012c4459
--- /dev/null
+++ b/src/wchar/wcsnlen_s.c
@@ -0,0 +1,11 @@
+#include <wchar.h>
+
+size_t wcsnlen_s( const wchar_t *ws, size_t maxlen)
+{
+ __C_EXT(1, 201112L);
+ return 0;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcsrtombs_s.c b/src/wchar/wcsrtombs_s.c
new file mode 100644
index 00000000..c0f73aaa
--- /dev/null
+++ b/src/wchar/wcsrtombs_s.c
@@ -0,0 +1,13 @@
+#include "wchar.h"
+
+errno_t wcsrtombs_s(size_t * restrict retval,
+ char * restrict dst, rsize_t dstmax,
+ const wchar_t ** restrict src, rsize_t len,
+ mbstate_t * restrict ps)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wcstok_s.c b/src/wchar/wcstok_s.c
new file mode 100644
index 00000000..16ddfdce
--- /dev/null
+++ b/src/wchar/wcstok_s.c
@@ -0,0 +1,11 @@
+#include "wchar.h"
+
+wchar_t *wcstok_s(wchar_t * restrict s1, rsize_t * restrict s1max,
+ const wchar_t * restrict s2, wchar_t ** restrict ptr)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wmemcpy_s.c b/src/wchar/wmemcpy_s.c
new file mode 100644
index 00000000..1481fcd7
--- /dev/null
+++ b/src/wchar/wmemcpy_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wmemcpy_s(wchar_t * restrict s1, rsize_t s1max, const wchar_t * restrict s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wmemmove_s.c b/src/wchar/wmemmove_s.c
new file mode 100644
index 00000000..2a34b960
--- /dev/null
+++ b/src/wchar/wmemmove_s.c
@@ -0,0 +1,10 @@
+#include "wchar.h"
+
+errno_t wmemmove_s(whcar_t *s1, rsize_t s1max, const wchar_t *s2, rsize_t n)
+{
+ __C_EXT(1, 201112L);
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wprintf_s.c b/src/wchar/wprintf_s.c
new file mode 100644
index 00000000..b45bc077
--- /dev/null
+++ b/src/wchar/wprintf_s.c
@@ -0,0 +1,15 @@
+#include "wchar.h"
+
+int wprintf_s(const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vwprintf_s(format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/
diff --git a/src/wchar/wscanf_s.c b/src/wchar/wscanf_s.c
new file mode 100644
index 00000000..0359b546
--- /dev/null
+++ b/src/wchar/wscanf_s.c
@@ -0,0 +1,15 @@
+#include "wchar.h"
+
+int wscanf_s(const wchar_t * restrict format, ...)
+{
+ __C_EXT(1, 201112L);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vwscanf_s(format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/*
+CEXT1(201112)
+*/