aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-08-19 14:04:36 +0200
committerMattias Andrée <maandree@operamail.com>2015-08-19 14:04:36 +0200
commite8f32d09348b2e7504d3c33c97f3c854f3f75dec (patch)
tree935d1dd1ae9eb550d5fe9d86989d06871672adb0
parentput full_send in libmdsserver, clients that only has one socket uses a macro to remove the socket parameter (diff)
downloadmds-e8f32d09348b2e7504d3c33c97f3c854f3f75dec.tar.gz
mds-e8f32d09348b2e7504d3c33c97f3c854f3f75dec.tar.bz2
mds-e8f32d09348b2e7504d3c33c97f3c854f3f75dec.tar.xz
add strict_atoj and strict_atouj
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--doc/info/mds.texinfo24
-rw-r--r--src/libmdsserver/util.c95
-rw-r--r--src/libmdsserver/util.h24
3 files changed, 141 insertions, 2 deletions
diff --git a/doc/info/mds.texinfo b/doc/info/mds.texinfo
index 8d44bdb..7835753 100644
--- a/doc/info/mds.texinfo
+++ b/doc/info/mds.texinfo
@@ -6535,6 +6535,30 @@ string is not a 10-radix integer or has a value
outside [@code{min}, @code{max}], @code{-1} is
returned, otherwise zero is returned.
+@item @code{strict_atoj} [(@code{const char* str, intmax_t* value, intmax_t min, intmax_t max}) @arrow{} @code{int}]
+@fnindex @code{strict_atoj}
+@fnindex @code{atoj}
+@cpindex Integer parsing
+@cpindex Error management
+A version of @code{atoj} that is strict about the
+syntax and bounds. Parses the string @code{str} into
+an @code{int} and stores it in @code{*value}. If the
+string is not a 10-radix integer or has a value
+outside [@code{min}, @code{max}], @code{-1} is
+returned, otherwise zero is returned.
+
+@item @code{strict_atouj} [(@code{const char* str, uintmax_t* value, uintmax_t min, uintmax_t max}) @arrow{} @code{int}]
+@fnindex @code{strict_atouj}
+@fnindex @code{atouj}
+@cpindex Integer parsing
+@cpindex Error management
+A version of @code{atouj} that is strict about the
+syntax and bounds. Parses the string @code{str} into
+an @code{int} and stores it in @code{*value}. If the
+string is not a 10-radix integer or has a value
+outside [@code{min}, @code{max}], @code{-1} is
+returned, otherwise zero is returned.
+
@item @code{full_write} [(@code{int fd, const char* buffer, size_t length}) @arrow{} @code{int}]
@fnindex @code{full_write}
@cpindex File writing
diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c
index eb79bff..f62abd2 100644
--- a/src/libmdsserver/util.c
+++ b/src/libmdsserver/util.c
@@ -241,6 +241,101 @@ int strict_atoi(const char* str, int* value, int min, int max)
/**
+ * A version of `atoj` that is strict about the syntax and bounds
+ *
+ * @param str The text to parse
+ * @param value Slot in which to store the value
+ * @param min The minimum accepted value
+ * @param max The maximum accepted value
+ * @return Zero on success, -1 on syntax error
+ */
+int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max)
+{
+ static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' };
+ intmax_t r = 0;
+ char c;
+ int neg = 0;
+
+ if (*str == '-')
+ {
+ if (*minstr == '\0')
+ sprintf(minstr, "%j", INTMAX_MIN);
+ if (!strcmp(str, minstr))
+ {
+ r = INTMAX_MIN;
+ goto done;
+ }
+ neg = 1, str++;
+ }
+
+ if (*str == '\0')
+ return -1;
+
+ while ((c = *str))
+ if (('0' <= c) && (c <= '9'))
+ {
+ if (r > INTMAX_MAX / 10)
+ return -1;
+ else if (r == INTMAX_MAX / 10)
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ r = r * 10 + (c & 15);
+ }
+ else
+ return -1;
+
+ if (neg)
+ r = -r;
+
+ done:
+
+ if ((r < min) || (r > max))
+ return -1;
+
+ *value = r;
+ return 0;
+}
+
+
+/**
+ * A version of `atouj` that is strict about the syntax and bounds
+ *
+ * @param str The text to parse
+ * @param value Slot in which to store the value
+ * @param min The minimum accepted value
+ * @param max The maximum accepted value
+ * @return Zero on success, -1 on syntax error
+ */
+int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max)
+{
+ uintmax_t r = 0;
+ char c;
+
+ if (*str == '\0')
+ return -1;
+
+ while ((c = *str))
+ if (('0' <= c) && (c <= '9'))
+ {
+ if (r > INTMAX_MAX / 10)
+ return -1;
+ else if (r == INTMAX_MAX / 10)
+ if ((c & 15) > INTMAX_MAX % 10)
+ return -1;
+ r = r * 10 + (c & 15);
+ }
+ else
+ return -1;
+
+ if ((r < min) || (r > max))
+ return -1;
+
+ *value = r;
+ return 0;
+}
+
+
+/**
* Send a buffer into a file and ignore interruptions
*
* @param fd The file descriptor
diff --git a/src/libmdsserver/util.h b/src/libmdsserver/util.h
index accf038..c84156d 100644
--- a/src/libmdsserver/util.h
+++ b/src/libmdsserver/util.h
@@ -110,6 +110,28 @@ size_t send_message(int socket, const char* message, size_t length);
int strict_atoi(const char* str, int* value, int min, int max);
/**
+ * A version of `atoj` that is strict about the syntax and bounds
+ *
+ * @param str The text to parse
+ * @param value Slot in which to store the value
+ * @param min The minimum accepted value
+ * @param max The maximum accepted value
+ * @return Zero on success, -1 on syntax error
+ */
+int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max);
+
+/**
+ * A version of `atouj` that is strict about the syntax and bounds
+ *
+ * @param str The text to parse
+ * @param value Slot in which to store the value
+ * @param min The minimum accepted value
+ * @param max The maximum accepted value
+ * @return Zero on success, -1 on syntax error
+ */
+int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max);
+
+/**
* Send a buffer into a file and ignore interruptions
*
* @param fd The file descriptor
@@ -128,7 +150,6 @@ int full_write(int fd, const char* buffer, size_t length);
*/
char* full_read(int fd, size_t* length);
-
/**
* Send a full message even if interrupted
*
@@ -139,7 +160,6 @@ char* full_read(int fd, size_t* length);
*/
int full_send(int socket, const char* message, size_t length);
-
/**
* Check whether a string begins with a specific string,
* where neither of the strings are necessarily NUL-terminated