aboutsummaryrefslogtreecommitdiffstats
path: root/src/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdio')
-rw-r--r--src/stdio/scanf.c641
1 files changed, 641 insertions, 0 deletions
diff --git a/src/stdio/scanf.c b/src/stdio/scanf.c
new file mode 100644
index 0000000..446a38d
--- /dev/null
+++ b/src/stdio/scanf.c
@@ -0,0 +1,641 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <string.h>
+#include <wchar.h>
+/* #include <slibc-scan.h> */
+
+
+#define V(C) \
+ int r; \
+ va_list args; \
+ va_start(args, format); \
+ r = v##C; \
+ va_end(args); \
+ return r
+
+#define S_CHAR(UNDERLAYING, MAXIMUM, LIMITED, DATA) \
+ return vgeneric_scanf((generic_scanf_read_func_t)UNDERLAYING, NULL, \
+ MAXIMUM, LIMITED, NULL, DATA, format, data)
+
+#define S_WCHAR(UNDERLAYING, MAXIMUM, LIMITED, DATA) \
+ return vgeneric_wscanf((generic_wscanf_read_func_t)UNDERLAYING, NULL, \
+ MAXIMUM, LIMITED, NULL, DATA, format, data)
+
+#define FLOCK(F) /* TODO lock stream */
+#define FUNLOCK(F) /* TODO unlock stream */
+
+
+
+/**
+ * This function is identical to `fscanf` with
+ * `stdout` as the first argument.
+ *
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int scanf(const char* restrict format, ...)
+{
+ V(scanf(format, args));
+}
+
+
+/**
+ * Parse data from from a text stream.
+ *
+ * TODO list format rules for fscanf
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int fscanf(FILE* restrict stream, const char* restrict format, ...)
+{
+ V(fscanf(stream, format, args));
+}
+
+
+/**
+ * This function is identical to `fscanf`,
+ * except it reads from a string rather than
+ * a file.
+ *
+ * @param input The formatted string.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int sscanf(const char* restrict input, const char* restrict format, ...)
+{
+ V(sscanf(input, format, args));
+}
+
+
+/**
+ * This function is identical to `fscanf`,
+ * except it does not lock the stream.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int fscanf_unlocked(FILE* restrict stream, const char* restrict format, ...)
+{
+ V(fscanf_unlocked(stream, format, args));
+}
+
+
+/**
+ * This function is identical to `scanf`,
+ * except it will stop parsing the string
+ * after a selected number of bytes, or
+ * at the end of the string.
+ *
+ * This is a slibc extension.
+ *
+ * @param input The formatted string.
+ * @param length The maximum number of bytes to read.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int snscanf(const char* restrict input, size_t length, const char* restrict format, ...)
+{
+ V(snscanf(input, length, format, args));
+}
+
+
+/**
+ * This function is identical to `fscanf`,
+ * except it is limited to file descriptor-backed
+ * streams, and uses the file descriptor as the
+ * first argument rather than the stream.
+ *
+ * This is a slibc extension.
+ *
+ * @param fd The file descriptor.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int dscanf(int fd, const char* restrict format, ...)
+{
+ V(dscanf(fd, format, args));
+}
+
+
+/**
+ * This function is identical to `scanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vscanf(const char* restrict format, va_list args)
+{
+ return vscanf(stdout, format, args);
+}
+
+
+/**
+ * This function is identical to `fscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vfscanf(FILE* restrict stream, const char* restrict format, va_list args)
+{
+ int r, saved_errno;
+ FLOCK(stream);
+ r = vfscanf_unlocked(stream, format, args);
+ saved_errno = errno;
+ FUNLOCK(stream);
+ return errno = saved_errno, r;
+}
+
+
+/**
+ * This function is identical to `sscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param input The formatted string.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vsscanf(const char* restrict input, const char* restrict format, va_list args)
+{
+ S_CHAR(read_string, 0, 0, input);
+}
+
+
+/**
+ * This function is identical to `fscanf_unlocked`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vfscanf_unlocked(FILE* restrict stream, const char* restrict format, va_list args)
+{
+ S_CHAR(read_stream, 0, 0, stream);
+}
+
+
+/**
+ * This function is identical to `snscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param input The formatted string.
+ * @param length The maximum number of bytes to read.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vsnscanf(const char* restrict input, size_t length, const char* restrict format, va_list args)
+{
+ S_CHAR(read_string, length, 1, input);
+}
+
+
+/**
+ * This function is identical to `sscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param fd The file descriptor.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vdscanf(int fd, const char* restrict format, va_list args)
+{
+ S_CHAR(read_fd, 0, 0, &fd);
+}
+
+
+/**
+ * This function is identical to `scanf`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int wscanf(const wchar_t* restrict format, ...)
+{
+ V(wscanf(format, args));
+}
+
+
+/**
+ * This function is identical to `fscanf`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...)
+{
+ V(fwscanf(stream, format, args));
+}
+
+
+/**
+ * This function is identical to `sscanf`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * @param input The formatted string.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int swscanf(const wchar_t* restrict input, const wchar_t* restrict format, ...)
+{
+ V(swscanf(input, format, args));
+}
+
+
+/**
+ * This function is identical to `fscanf_unlocked`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int fwscanf_unlocked(FILE* restrict stream, const wchar_t* restrict format, ...)
+{
+ V(fwscanf_unlocked(stream, format, args));
+}
+
+
+/**
+ * This function is identical to `snscanf`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * This is a slibc extension.
+ *
+ * @param input The formatted string.
+ * @param length The maximum number of characters to read.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int snwscanf(const wchar_t* restrict input, size_t length, const wchar_t* restrict format, ...)
+{
+ V(snscanf(input, length, format, args));
+}
+
+
+/**
+ * This function is identical to `dscanf`,
+ * except it uses `wchar_t` instead of `char`.
+ *
+ * This is a slibc extension.
+ *
+ * @param fd The file descriptor.
+ * @param format The format of the string.
+ * @param ... The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int dwscanf(int fd, const wchar_t* restrict format, ...)
+{
+ V(dwscanf(fd, format, args));
+}
+
+
+/**
+ * This function is identical to `wscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vwscanf(const wchar_t* restrict format, va_list args)
+{
+ return vwscanf(stdout, format, args);
+}
+
+
+/**
+ * This function is identical to `fwscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list args)
+{
+ int r, saved_errno;
+ FLOCK(stream);
+ r = vfwscanf_unlocked(stream, format, args);
+ saved_errno = errno;
+ FUNLOCK(stream);
+ return errno = saved_errno, r;
+}
+
+
+/**
+ * This function is identical to `swscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * @param input The formatted string.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vswscanf(const wchar_t* restrict input, const wchar_t* restrict format, va_list args)
+{
+ S_WCHAR(wread_string, 0, 0, input);
+}
+
+
+/**
+ * This function is identical to `fwscanf_unlocked`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The input stream.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vfwscanf_unlocked(FILE* restrict stream, const wchar_t* restrict format, va_list args)
+{
+ S_WCHAR(wread_stream, 0, 0, stream);
+}
+
+
+/**
+ * This function is identical to `snwscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param input The formatted string.
+ * @param length The maximum number of characters to read.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vsnwscanf(const wchar_t* restrict input, size_t length, const wchar_t* restrict format, va_list args)
+{
+ S_WCHAR(wread_string, length, 1, input);
+}
+
+
+/**
+ * This function is identical to `swscanf`,
+ * except it uses `va_list` instead of variadic arguments.
+ *
+ * This is a slibc extension.
+ *
+ * @param fd The file descriptor.
+ * @param format The format of the string.
+ * @param args The output parameter for the encoded values.
+ * @return The number successfully converted argument
+ * (may be less than specified.) `EOF` is returned
+ * if the end of the input is reached before the
+ * first argument is successfully converted, or
+ * on error.
+ */
+int vdwscanf(int fd, const wchar_t* restrict format, va_list args)
+{
+ S_WCHAR(wread_fd, 0, 0, &fd);
+}
+
+
+
+/**
+ * This function is identical to `scanf`.
+ */
+int __isoc99_scanf(const char* restrict format, ...)
+{
+ V(scanf(format, args));
+}
+
+/**
+ * This function is identical to `fscanf`.
+ */
+int __isoc99_fscanf(FILE* restrict stream, const char* restrict format, ...)
+{
+ V(fscanf(stream, format, args));
+}
+
+/**
+ * This function is identical to `sscanf`.
+ */
+int __isoc99_sscanf(const char* restrict input, const char* restrict format, ...)
+{
+ V(sscanf(input, format, args));
+}
+
+/**
+ * This function is identical to `vscanf`.
+ */
+int __isoc99_vscanf(const char* restrict format, va_list args)
+{
+ return vscanf(format, args);
+}
+
+/**
+ * This function is identical to `vfscanf`.
+ */
+int __isoc99_vfscanf(FILE* restrict stream, const char* restrict format, va_list args)
+{
+ return vfscanf(stream, format, args);
+}
+
+/**
+ * This function is identical to `vsscanf`.
+ */
+int __isoc99_vsscanf(const char* restrict input, const char* restrict format, va_list args)
+{
+ return vsscanf(input, format, args);
+}
+
+/**
+ * This function is identical to `wscanf`.
+ */
+int __isoc99_wscanf(const wchar_t* restrict format, ...)
+{
+ V(wscanf(format, args));
+}
+
+/**
+ * This function is identical to `fwscanf`.
+ */
+int __isoc99_fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...)
+{
+ V(fwscanf(stream, format, args));
+}
+
+/**
+ * This function is identical to `swscanf`.
+ */
+int __isoc99_swscanf(const wchar_t* restrict input, const wchar_t* restrict format, ...)
+{
+ V(swscanf(input, format, args));
+}
+
+/**
+ * This function is identical to `vwscanf`.
+ */
+int __isoc99_vwscanf(const wchar_t* restrict format, va_list args)
+{
+ return vwscanf(format, args);
+}
+
+/**
+ * This function is identical to `vfwscanf`.
+ */
+int __isoc99_vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list args)
+{
+ return vfwscanf(stream, format, args);
+}
+
+/**
+ * This function is identical to `vswscanf`.
+ */
+int __isoc99_vswscanf(const wchar_t* restrict input, const wchar_t* restrict format, va_list args)
+{
+ return vswscanf(input, format, args);
+}
+