Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
seriously, me
[simgrid.git] / src / xbt / xbt_str.c
index 9247f2d..fb1a0af 100644 (file)
@@ -1,12 +1,12 @@
 /* xbt_str.c - various helping functions to deal with strings               */
 
-/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+/* Copyright (c) 2007-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include "portable.h"
+#include "src/portable.h"
 #include "xbt/misc.h"
 #include "xbt/sysdep.h"
 #include "xbt/str.h"            /* headers of these functions */
@@ -124,50 +124,6 @@ void xbt_str_trim(char *s, const char *char_list)
   xbt_str_ltrim(s, char_list);
 }
 
-/**  @brief Replace double whitespaces (but no other characters) from the string.
- *
- * The function modifies the string so that each time that several spaces appear,
- * they are replaced by a single space. It will only do so for spaces (ASCII 32, 0x20).
- *
- * @param s The string to strip. Modified in place.
- *
- */
-void xbt_str_strip_spaces(char *s)
-{
-  char *p = s;
-  int e = 0;
-
-  if (!s)
-    return;
-
-  while (1) {
-    if (!*p)
-      goto end;
-
-    if (*p != ' ')
-      break;
-
-    p++;
-  }
-
-  e = 1;
-
-  do {
-    if (e)
-      *s++ = *p;
-
-    if (!*++p)
-      goto end;
-
-    if (e ^ (*p != ' '))
-      if ((e = !e))
-        *s++ = ' ';
-  } while (1);
-
-end:
-  *s = '\0';
-}
-
 /** @brief Substitutes a char for another in a string
  *
  * @param str the string to modify
@@ -520,53 +476,6 @@ char *xbt_str_join_array(const char *const *strs, const char *sep)
   return res;
 }
 
-/** @brief Get a single line from the stream (reimplementation of the GNU getline)
- *
- * This is a reimplementation of the GNU getline function, so that our code don't depends on the GNU libc.
- *
- * xbt_getline() reads an entire line from stream, storing the address of the
- * buffer containing the text into *buf.  The buffer is null-terminated and
- * includes the newline character, if one was found.
- *
- * If *buf is NULL, then xbt_getline() will allocate a buffer for storing the
- * line, which should be freed by the user program.
- *
- * Alternatively, before calling xbt_getline(), *buf can contain a pointer to a
- * malloc()-allocated buffer *n bytes in size.  If the buffer is not large
- * enough to hold the line, xbt_getline() resizes it with realloc(), updating
- * *buf and *n as necessary.
- *
- * In either case, on a successful call, *buf and *n will be updated to reflect
- * the buffer address and allocated size respectively.
- */
-ssize_t xbt_getline(char **buf, size_t *n, FILE *stream)
-{
-  ssize_t i;
-  int ch;
-
-  ch = getc(stream);
-  if (ferror(stream) || feof(stream))
-    return -1;
-
-  if (!*buf) {
-    *n = 512;
-    *buf = xbt_malloc(*n);
-  }
-
-  i = 0;
-  do {
-    if (i == *n)
-      *buf = xbt_realloc(*buf, *n += 512);
-    (*buf)[i++] = ch;
-  } while (ch != '\n' && (ch = getc(stream)) != EOF);
-
-  if (i == *n)
-    *buf = xbt_realloc(*buf, *n += 1);
-  (*buf)[i] = '\0';
-
-  return i;
-}
-
 /*
  * Diff related functions
  *
@@ -899,31 +808,46 @@ char *xbt_str_from_file(FILE * file)
   return res;
 }
 
-/* @brief Retrun 1 if string 'str' starts with string 'start'
+/** @brief Parse an integer out of a string, or raise an error
  *
- * \param str a string
- * \param start the string to search in str
- *
- * \return 1 if 'str' starts with 'start'
+ * The #str is passed as argument to your #error_msg, as follows:
+ *       THROWF(arg_error, 0, error_msg, str);
  */
-int xbt_str_start_with(const char* str, const char* start)
+long int xbt_str_parse_int(const char* str, const char* error_msg)
 {
-  int i;
-  size_t l_str = strlen(str);
-  size_t l_start = strlen(start);
+  char *endptr;
+  if (str == NULL || str[0] == '\0')
+    THROWF(arg_error, 0, error_msg, str);
 
-  if(l_start > l_str) return 0;
+  long int res = strtol(str, &endptr, 10);
+  if (endptr[0] != '\0')
+    THROWF(arg_error, 0, error_msg, str);
 
-  for(i = 0; i< l_start; i++){
-    if(str[i] != start[i]) return 0;
-  }
+  return res;
+}
+/** @brief Parse a double out of a string, or raise an error
+ *
+ * The #str is passed as argument to your #error_msg, as follows:
+ *       THROWF(arg_error, 0, error_msg, str);
+ */
+double xbt_str_parse_double(const char* str, const char* error_msg)
+{
+  char *endptr;
+  if (str == NULL || str[0] == '\0')
+    THROWF(arg_error, 0, error_msg, str);
+
+  double res = strtod(str, &endptr);
+  if (endptr[0] != '\0')
+    THROWF(arg_error, 0, error_msg, str);
 
-  return 1;
+  return res;
 }
 
 #ifdef SIMGRID_TEST
 #include "xbt/str.h"
 
+XBT_TEST_SUITE("xbt_str", "String Handling");
+
 #define mytest(name, input, expected) \
   xbt_test_add(name); \
   d=xbt_str_split_quoted(input); \
@@ -933,8 +857,6 @@ int xbt_str_start_with(const char* str, const char* start)
                    input,s,expected);\
                    free(s); \
                    xbt_dynar_free(&d);
-
-XBT_TEST_SUITE("xbt_str", "String Handling");
 XBT_TEST_UNIT("xbt_str_split_quoted", test_split_quoted, "test the function xbt_str_split_quoted")
 {
   xbt_dynar_t d;
@@ -1109,4 +1031,54 @@ XBT_TEST_UNIT("xbt_str_diff", test_diff, "test the function xbt_str_diff")
   }
 }
 
+#define test_parse_error(function, name, variable, str)                 \
+  do {                                                                  \
+    xbt_test_add(name);                                                 \
+    TRY {                                                               \
+      variable = function(str, "Parse error");                          \
+      xbt_test_fail("The test '%s' did not detect the problem",name );  \
+    } CATCH(e) {                                                        \
+      if (e.category != arg_error) {                                    \
+        xbt_test_exception(e);                                          \
+      } else {                                                          \
+        xbt_ex_free(e);                                                 \
+      }                                                                 \
+    }                                                                   \
+  } while (0)
+#define test_parse_ok(function, name, variable, str, value)             \
+  do {                                                                  \
+    xbt_test_add(name);                                                 \
+    TRY {                                                               \
+      variable = function(str, "Parse error");                          \
+    } CATCH(e) {                                                        \
+      xbt_test_exception(e);                                            \
+    }                                                                   \
+    xbt_test_assert(variable == value, "Fail to parse '%s'", str);      \
+  } while (0)
+
+XBT_TEST_UNIT("xbt_str_parse", test_parse, "Test the parsing functions")
+{
+  xbt_ex_t e;
+  int rint = -9999;
+  test_parse_ok(xbt_str_parse_int, "Parse int", rint, "42", 42);
+  test_parse_ok(xbt_str_parse_int, "Parse 0 as an int", rint, "0", 0);
+  test_parse_ok(xbt_str_parse_int, "Parse -1 as an int", rint, "-1", -1);
+
+  test_parse_error(xbt_str_parse_int, "Parse int + noise", rint, "342 cruft");
+  test_parse_error(xbt_str_parse_int, "Parse NULL as an int", rint, NULL);
+  test_parse_error(xbt_str_parse_int, "Parse '' as an int", rint, "");
+  test_parse_error(xbt_str_parse_int, "Parse cruft as an int", rint, "cruft");
+
+  double rdouble = -9999;
+  test_parse_ok(xbt_str_parse_double, "Parse 42 as a double", rdouble, "42", 42);
+  test_parse_ok(xbt_str_parse_double, "Parse 42.5 as a double", rdouble, "42.5", 42.5);
+  test_parse_ok(xbt_str_parse_double, "Parse 0 as a double", rdouble, "0", 0);
+  test_parse_ok(xbt_str_parse_double, "Parse -1 as a double", rdouble, "-1", -1);
+
+  test_parse_error(xbt_str_parse_double, "Parse double + noise", rdouble, "342 cruft");
+  test_parse_error(xbt_str_parse_double, "Parse NULL as a double", rdouble, NULL);
+  test_parse_error(xbt_str_parse_double, "Parse '' as a double", rdouble, "");
+  test_parse_error(xbt_str_parse_double, "Parse cruft as a double", rdouble, "cruft");
+}
+
 #endif                          /* SIMGRID_TEST */