[X2Go-Commits] [libx2goclient] 07/09: src/x2goclient-utils.{c, h}: add x2goclient_str_to_int ().

git-admin at x2go.org git-admin at x2go.org
Sat Apr 4 17:55:27 CEST 2020


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository libx2goclient.

commit a31d40ee8c640215023c801a2b64ccf0ba4acb37
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Sat Mar 28 09:24:29 2020 +0100

    src/x2goclient-utils.{c,h}: add x2goclient_str_to_int ().
    
    Helper function that converts a string number to a long-long-type.
---
 src/x2goclient-utils.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/x2goclient-utils.h |   4 ++
 2 files changed, 122 insertions(+)

diff --git a/src/x2goclient-utils.c b/src/x2goclient-utils.c
index ccdd82c..39e448a 100644
--- a/src/x2goclient-utils.c
+++ b/src/x2goclient-utils.c
@@ -22,6 +22,9 @@
    Boston, MA 02110-1301, USA.
  */
 
+#include <errno.h>
+#include <stdlib.h>
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -31,3 +34,118 @@
 void x2goclient_clear_strings (gpointer data) {
   g_free (data);
 }
+
+/**
+ * x2goclient_str_to_int:
+ * @str: (in) (not optional) (not nullable): input string
+ * @min: (in): true if a minimum limit should be checked for
+ * @limit_min: (in): the minimum limit to check for
+ * @max: (in): true if a maximum limit should be checked for
+ * @limit_max: (in) the maximum limit to check for
+ * @end: (out) (optional) (nullable): pointer to final string after the scanned
+ *                                    value
+ * @conv_err: (out) (not optional) (not nullable): will be set to true on
+ *                                                 conversion errors
+ * @min_err: (out) (not optional) (not nullable): will be set to true if value
+ *                                                falls short of minimum limit
+ *                                                and on underflows
+ * @max_err: (out) (not optional) (not nullable): will be set to true if value
+ *                                                exceeds maximum limit and on
+ *                                                overflows
+ *
+ * Takes a string and converts it into a #long long integer.
+ *
+ * The error output parameters @conv_err, @min_err and @max_err MUST NOT be
+ * %NULL at any time.
+ *
+ * Multiple error conditions exist:
+ *    - If the value pointed to by @conv_err is %TRUE and the values pointed to
+ *      by @min_err and @max_err are both %FALSE, there was an error converting
+ *      the initial string to a proper integer value. The return value will not
+ *      contain a meaningful value.
+ *    - If the values pointed to by @conv_err and @min_err are both %TRUE, an
+ *      underflow occurred and the scanned input value was smaller than the
+ *      minimum representable value by #long long. The return value will
+ *      not contain a meaningful value.
+ *    - If the values pointed to by @conv_err and @max_err are both %TRUE, an
+ *      overflow occurred and the scanned input value was higher than the
+ *      maximum representable value by #long long. The return value will
+ *      not contain a meaningful value.
+ *    - If the value pointed to by @conv_err is %FALSE and the value pointed to
+ *      by @min_err is %TRUE, the value was converted successfully but was
+ *      lower than the value passed via @limit_min and failed the minimum
+ *      check. The return value will still contain the originally converted
+ *      number.
+ *    - If the value pointed to by @conv_err is %FALSE and the value pointed to
+ *      by @max_err is %TRUE, the value was converted successfully but was
+ *      higher than the value passed via @limit_max and failed the maximum
+ *      check. The returned value will still contain the originally converted
+ *      number.
+ *
+ * The values pointed to by @conv_err, @min_err and @max_err SHOULD never be
+ * all set to %TRUE by this function at the same time. Otherwise, that's a bug.
+ *
+ * If the value pointed to by @min is %FALSE, @limit_min will not be touched
+ * and has no meaning to the function. The same logic applies to @max and
+ * @limit_max.
+ *
+ * If the pointer passed as @end is not %NULL its value will be set to the
+ * first character after the parsed integer value like strtoll() does under
+ * the following circumstances:
+ *   - If %conv_err is %FALSE.
+ *   - If %conv_err is %TRUE and %min_err is %TRUE.
+ *   - If %conv_err is %TRUE and %max_err is %TRUE.
+ * Otherwise, the pointer value will not be a meaningful one and you should not
+ * use or rely on it.
+ *
+ * Returns: the converted value as a #long long, unless an error occurred
+ */
+long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long limit_min, _Bool max, long long limit_max, const gchar **restrict end, _Bool *restrict conv_err, _Bool *restrict min_err, _Bool *restrict max_err) {
+  long long ret = 42;
+
+  *min_err = *max_err = FALSE;
+
+  if (end) {
+    *end = NULL;
+  }
+
+  errno = 0;
+  int saved_errno = 0;
+  gchar *endptr = NULL;
+  ret = strtoll (str, &endptr, 10);
+  saved_errno = errno;
+
+  if (0 != saved_errno) {
+    *conv_err = TRUE;
+    ret = 42;
+
+    if (ERANGE == saved_errno) {
+      if (end) {
+        *end = endptr;
+      }
+
+      if (LLONG_MIN == ret) {
+        *min_err = TRUE;
+      }
+      else if (LLONG_MAX == ret) {
+        *max_err = TRUE;
+      }
+    }
+  }
+  else {
+    *conv_err = FALSE;
+
+    if (end) {
+      *end = endptr;
+    }
+
+    if ((min) && (limit_min > ret)) {
+      *min_err = TRUE;
+    }
+    else if ((max) && (limit_max < ret)) {
+      *max_err = TRUE;
+    }
+  }
+
+  return (ret);
+}
diff --git a/src/x2goclient-utils.h b/src/x2goclient-utils.h
index 0959a32..1a100d2 100644
--- a/src/x2goclient-utils.h
+++ b/src/x2goclient-utils.h
@@ -25,12 +25,16 @@
 #ifndef x2goclient_utils_h
 #define x2goclient_utils_h
 
+#include <stdbool.h>
+
 #include <gmodule.h>
 
 G_BEGIN_DECLS
 
 void x2goclient_clear_strings (gpointer data);
 
+long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long limit_min, _Bool max, long long limit_max, const gchar **restrict end, _Bool *restrict conv_err, _Bool *restrict min_err, _Bool *restrict max_err);
+
 G_END_DECLS
 
 #endif /* x2goclient_utils_h */

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git


More information about the x2go-commits mailing list