return res;
}
+/**
+ * \brief This functions splits a string after using another string as separator
+ * For example A##B##C splitted after ## will return the dynar {A,B,C}
+ * \return An array of dynars containing the string tokens
+*/
+xbt_dynar_t xbt_str_split_str(const char *s, const char *sep) {
+ xbt_dynar_t res = xbt_dynar_new(sizeof(char*), free_string);
+ int done;
+ const char *p, *q;
+
+ p = q = s;
+ done = 0;
+
+ if (s[0] == '\0')
+ return res;
+ if (sep[0] == '\0') {
+ s = xbt_strdup(s);
+ xbt_dynar_push(res, &s);
+ return res;
+ }
+
+ while (!done) {
+ char *to_push;
+ int v = 0;
+ //get the start of the first occurence of the substring
+ q = strstr(p, sep);
+ //if substring was not found add the entire string
+ if (NULL == q) {
+ v = strlen(p);
+ to_push = malloc(v + 1);
+ memcpy(to_push, p, v);
+ to_push[v] = '\0';
+ xbt_dynar_push(res, &to_push);
+ done = 1;
+ }
+ else {
+ //get the appearance
+ to_push = malloc(q - p + 1);
+ memcpy(to_push, p, q - p);
+ //add string terminator
+ to_push[q - p] = '\0';
+ xbt_dynar_push(res, &to_push);
+ p = q +strlen(sep);
+ }
+ }
+ return res;
+}
+
/** @brief Splits a string into a dynar of strings, taking quotes into account
*
* It basically does the same argument separation than the shell, where white
}
#ifdef SIMGRID_TEST
+#include "xbt/str.h"
+
#define mytest(name, input, expected) \
xbt_test_add0(name); \
d=xbt_str_split_quoted(input); \
mytest("Backslashed quotes + quotes", "'toto \\'tutu' tata", "toto 'tutuXXXtata");
}
+
+#define mytest_str(name, input, separator, expected) \
+ xbt_test_add0(name); \
+ d=xbt_str_split_str(input, separator); \
+ s=xbt_str_join(d,"XXX"); \
+ xbt_test_assert3(!strcmp(s,expected),\
+ "Input (%s) leads to (%s) instead of (%s)", \
+ input,s,expected);\
+ free(s); \
+ xbt_dynar_free(&d);
+
+XBT_TEST_UNIT("xbt_str_split_str",test_split_str, "test the function xbt_str_split_str") {
+ xbt_dynar_t d;
+ char *s;
+
+ mytest_str("Empty string and separator", "", "", "");
+ mytest_str("Empty string", "", "##", "");
+ mytest_str("Empty separator", "toto", "", "toto");
+ mytest_str("String with no separator in it", "toto", "##", "toto");
+ mytest_str("Basic test", "toto##tutu", "##", "totoXXXtutu");
+}
#endif /* SIMGRID_TEST */
/** @brief Join a set of strings as a single string */
char *xbt_str_join(xbt_dynar_t dyn, const char*sep) {
int len=1,dyn_len=xbt_dynar_length(dyn);
- int cpt;
+ unsigned int cpt;
char *cursor;
char *res,*p;
res = xbt_malloc(len);
p=res;
xbt_dynar_foreach(dyn,cpt,cursor) {
- if (cpt<dyn_len-1)
+ if ((int)cpt<dyn_len-1)
p+=sprintf(p,"%s%s",cursor,sep);
else
p+=sprintf(p,"%s",cursor);
}
#if !defined(HAVE_GETLINE) || defined(DOXYGEN)
+/* prototype here, just in case */
+long getline(char **buf, size_t *n, FILE *stream);
+
/** @brief Get a single line from the stream (reimplementation of the GNU getline)
*
* This is a redefinition of the GNU getline function, used on platforms where it does not exists.
*/
long getline(char **buf, size_t *n, FILE *stream) {
- int i, ch;
+ size_t i;
+ int ch;
if (!*buf) {
*buf = xbt_malloc(512);
static xbt_matrix_t diff_build_LCS(xbt_dynar_t da, xbt_dynar_t db) {
xbt_matrix_t C = xbt_matrix_new(xbt_dynar_length(da),xbt_dynar_length(db),
sizeof(int),NULL);
- int i,j;
+ unsigned long i,j;
/* Compute the LCS */
/*
C[i,j] := max(C[i,j-1], C[i-1,j])
return C[m,n]
*/
- for (i=0; i<xbt_dynar_length(da); i++)
- *((int*) xbt_matrix_get_ptr(C,i,0) ) = 0;
+ if (xbt_dynar_length(db) != 0)
+ for (i=0; i<xbt_dynar_length(da); i++)
+ *((int*) xbt_matrix_get_ptr(C,i,0) ) = 0;
if (xbt_dynar_length(da) != 0)
for (j=0; j<xbt_dynar_length(db); j++)
topush = bprintf(" %s",xbt_dynar_get_as(da,i,char*));
xbt_dynar_push(res, &topush);
} else if (j>=0 &&
- (i<=0 || xbt_matrix_get_as(C,i,j-1,int) >= xbt_matrix_get_as(C,i-1,j,int))) {
+ (i<=0 ||j==0|| xbt_matrix_get_as(C,i,j-1,int) >= xbt_matrix_get_as(C,i-1,j,int))) {
diff_build_diff(res,C,da,db,i,j-1);
topush = bprintf("+ %s",xbt_dynar_get_as(db,j,char*));
xbt_dynar_push(res,&topush);