2006-08-21 Aaron Bockover <abockover@novell.com>
authorAaron Bockover <abockover@novell.com>
Mon, 21 Aug 2006 22:22:50 +0000 (22:22 -0000)
committerAaron Bockover <abockover@novell.com>
Mon, 21 Aug 2006 22:22:50 +0000 (22:22 -0000)
    * src/gstr.c: fixed bug/invalid read/write on malloc-only case (no
    realloc/delimiter token not found); use memcpy instead of strncpy for
    better performance

    * test/test.c (run_group): allow running specific tests under a group;
    added copied g_strsplit/g_strfreev from EGlib source as eg_strsplit
    and eg_strfreev to avoid performance skews in the driver

    * test/driver.c: allow user-specified group name to contain specific
    test to run under the group as 'group_name:test1,test2,...testN'

    * test/string-util.c: Added more g_strsplit tests

    * test/slist.c:
    * test/ptrarray.c:
    * test/fake.c:
    * test/string.c:
    * test/list.c:
    * test/array.c:
    * test/hashtable.c: make test names shorter (no need to prefix with
    the group since it runs under the group)

svn path=/trunk/mono/; revision=64167

13 files changed:
eglib/ChangeLog
eglib/src/gstr.c
eglib/test/array.c
eglib/test/driver.c
eglib/test/fake.c
eglib/test/hashtable.c
eglib/test/list.c
eglib/test/ptrarray.c
eglib/test/slist.c
eglib/test/string-util.c
eglib/test/string.c
eglib/test/test.c
eglib/test/test.h

index 3872a7c2aac812a8e3085265026b9f895756e342..123ab48f12e270775ecd260b0b7a3bd63ca3c9a3 100644 (file)
@@ -1,3 +1,27 @@
+2006-08-21  Aaron Bockover  <abockover@novell.com>
+
+       * src/gstr.c: fixed bug/invalid read/write on malloc-only case (no
+       realloc/delimiter token not found); use memcpy instead of strncpy for
+       better performance
+
+       * test/test.c (run_group): allow running specific tests under a group;
+       added copied g_strsplit/g_strfreev from EGlib source as eg_strsplit
+       and eg_strfreev to avoid performance skews in the driver
+       
+       * test/driver.c: allow user-specified group name to contain specific
+       test to run under the group as 'group_name:test1,test2,...testN'
+
+       * test/string-util.c: Added more g_strsplit tests
+
+       * test/slist.c:
+       * test/ptrarray.c:
+       * test/fake.c:
+       * test/string.c:
+       * test/list.c:
+       * test/array.c:
+       * test/hashtable.c: make test names shorter (no need to prefix with
+       the group since it runs under the group)
+
 2006-08-21  Miguel de Icaza  <miguel@novell.com>
 
        * src/glib.h (g_hash_table_new_full): Add missing prototype.
index 6d04199545375773cbb8b71f63bf55efc48e02eb..36951471944f166d8b22066c5f83c39291c6c06c 100644 (file)
@@ -171,24 +171,24 @@ g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens)
 
        g_return_val_if_fail(string != NULL, NULL);
        g_return_val_if_fail(delimiter != NULL, NULL);
-       g_return_val_if_fail(delimiter[0] != '\0', NULL);
+       g_return_val_if_fail(delimiter[0] != 0, NULL);
        
        token_length = strlen(string);
        string_c = (gchar *)g_malloc(token_length + 1);
-       strncpy(string_c, string, token_length);
-       string_c[token_length] = '\0';
+       memcpy(string_c, string, token_length);
+       string_c[token_length] = 0;
        
        vector = NULL;
        token = (gchar *)strtok_r(string_c, delimiter, &strtok_save);
-       
+
        while(token != NULL) {
                token_length = strlen(token);
                token_c = (gchar *)g_malloc(token_length + 1);
-               strncpy(token_c, token, token_length);
-               token_c[token_length] = '\0';
+               memcpy(token_c, token, token_length);
+               token_c[token_length] = 0;
 
                vector = vector == NULL ? 
-                       (gchar **)g_malloc(sizeof(vector)) :
+                       (gchar **)g_malloc(2 * sizeof(vector)) :
                        (gchar **)g_realloc(vector, (size + 1) * sizeof(vector));
        
                vector[size - 1] = token_c;     
@@ -205,7 +205,10 @@ g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens)
                }
        }
 
-       vector[size - 1] = NULL;
+       if(vector != NULL && size > 0) {
+               vector[size - 1] = NULL;
+       }
+       
        g_free(string_c);
        string_c = NULL;
 
index 64f7b427f97dbc58daef41b97f9f0cd32ec2074d..8acea5bbaba869f7136e772fe96b042219f9b859 100644 (file)
@@ -108,11 +108,11 @@ test_array_remove ()
 }
 
 static Test array_tests [] = {
-       {"array_big", test_array_big},
-       {"array_append", test_array_append},
-       {"array_index", test_array_index},
-       {"array_remove", test_array_remove},
-       {"array_append_zero_terminated", test_array_append_zero_terminated},
+       {"big", test_array_big},
+       {"append", test_array_append},
+       {"index", test_array_index},
+       {"remove", test_array_remove},
+       {"append_zero_term", test_array_append_zero_terminated},
        {NULL, NULL}
 };
 
index fa6a950476e2df1e321ea7a282626521960bc475..e53c7b2bf69be12c778593ae704204e89b76b798 100644 (file)
@@ -145,20 +145,34 @@ gint main(gint argc, gchar **argv)
        
        for(j = 0; test_groups[j].name != NULL; j++) {
                gboolean run = TRUE;
-                       
+               gchar *tests = NULL;
+               gchar *group = NULL;
+               
                if(tests_to_run != NULL) {
                        gint k;
                        run = FALSE;
-                       for(k = 0; k < tests_to_run->length; k++) {
-                               if(strcmp((char *)tests_to_run->strings[k], 
-                                       test_groups[j].name) == 0) {
+                       
+                       for(k = 0; k < tests_to_run->length; k++) {     
+                               gchar *user = tests_to_run->strings[k];
+                               const gchar *table = test_groups[j].name;
+                               gint user_len = strlen(user);
+                               gint table_len = strlen(table);
+                               
+                               if(strncmp(user, table, table_len) == 0) {
+                                       if(user_len > table_len && user[table_len] != ':') {
+                                               break;
+                                       }
+                                       
                                        run = TRUE;
+                                       group = tests_to_run->strings[k];
                                        break;
                                }
                        }
                }
-                       
+       
                if(run) {
+                       gchar **split = NULL;
+                       
                        if(debug && test_groups[j].handler != fake_tests_init) {
                                printf("Skipping %s, in driver debug mode\n", 
                                        test_groups[j].name);
@@ -166,9 +180,28 @@ gint main(gint argc, gchar **argv)
                        } else if(!debug && test_groups[j].handler == fake_tests_init) {
                                continue;
                        }
-               
+
+                       if(group != NULL) {
+                               split = eg_strsplit(group, ":", -1);    
+                               if(split != NULL) {
+                                       gint m;
+                                       for(m = 0; split[m] != NULL; m++) {
+                                               if(m == 1) {
+                                                       tests = strdup(split[m]);
+                                                       break;
+                                               }
+                                       }
+                                       eg_strfreev(split);
+                               }
+                       }
+                       
                        gboolean passed = run_group(&(test_groups[j]), 
-                               iterations, quiet, report_time);
+                               iterations, quiet, report_time, tests);
+
+                       if(tests != NULL) {
+                               g_free(tests);
+                       }
+
                        if(!passed && !global_failure) {
                                global_failure = TRUE;
                        }
index 5ceb65dab71ff1b9fa0db1c16017093ee47f77e9..c8d9af61165e486656084672c9358b33e40e28fb 100644 (file)
@@ -11,7 +11,7 @@ test_fake()
 }
 
 static Test fake_tests [] = {
-       {"test_fake", test_fake},
+       {"fake", test_fake},
        {NULL, NULL}
 };
 
index 621977522c60d92768d8b881c3f81ad60cee88aa..48b2d1696ebd29515acd085ad7d141de11de37ab 100644 (file)
@@ -131,11 +131,11 @@ RESULT hash_grow (void)
 }
 
 static Test hashtable_tests [] = {
-       {"hash_t1", hash_t1},
-       {"hash_t2", hash_t2},
-       {"hash_grow", hash_grow},
-       {"hash_default", hash_default},
-       {"hash_null_lookup", hash_null_lookup},
+       {"t1", hash_t1},
+       {"t2", hash_t2},
+       {"grow", hash_grow},
+       {"default", hash_default},
+       {"null_lookup", hash_null_lookup},
        {NULL, NULL}
 };
 
index 7460ec7b53edcf611ca38d7247e2214baeac5fdc..41bae3f19df5c096cfa4241f9c28588be7b49fe6 100644 (file)
@@ -300,18 +300,18 @@ test_list_insert_before ()
 }
 
 static Test list_tests [] = {
-       {"list_length", test_list_length},
-       {"list_nth", test_list_nth},
-       {"list_index", test_list_index},        
-       {"list_last", test_list_last},  
-       {"list_append", test_list_append},
-       {"list_concat", test_list_concat},
-       {"list_insert_sorted", test_list_insert_sorted},
-       {"list_insert_before", test_list_insert_before},
-       {"list_copy", test_list_copy},
-       {"list_reverse", test_list_reverse},
-       {"list_remove", test_list_remove},
-       {"list_remove_link", test_list_remove_link},
+       {"length", test_list_length},
+       {"nth", test_list_nth},
+       {"index", test_list_index},     
+       {"last", test_list_last},       
+       {"append", test_list_append},
+       {"concat", test_list_concat},
+       {"insert_sorted", test_list_insert_sorted},
+       {"insert_before", test_list_insert_before},
+       {"copy", test_list_copy},
+       {"reverse", test_list_reverse},
+       {"remove", test_list_remove},
+       {"remove_link", test_list_remove_link},
        {NULL, NULL}
 };
 
index 53f4584bf661e7dfd9ba3cde70286054014a091a..23c5cba1c5fed83965c94991e1ce22ccc3886bf0 100644 (file)
@@ -205,18 +205,18 @@ RESULT ptrarray_sort()
 {
        GPtrArray *array = g_ptr_array_new();
        gint i;
-       static const gchar *letters [] = { "A", "B", "C", "D", "E" };
+       gchar *letters [] = { "A", "B", "C", "D", "E" };
        
-       g_ptr_array_add(array, (gpointer)letters[1]);
-       g_ptr_array_add(array, (gpointer)letters[3]);
-       g_ptr_array_add(array, (gpointer)letters[0]);
-       g_ptr_array_add(array, (gpointer)letters[2]);
-       g_ptr_array_add(array, (gpointer)letters[4]);
+       g_ptr_array_add(array, letters[0]);
+       g_ptr_array_add(array, letters[1]);
+       g_ptr_array_add(array, letters[2]);
+       g_ptr_array_add(array, letters[3]);
+       g_ptr_array_add(array, letters[4]);
        
        g_ptr_array_sort(array, ptrarray_sort_compare);
 
        for(i = 0; i < array->len; i++) {
-               if(strcmp((const gchar *)array->pdata[i], letters[i]) != 0) {
+               if(array->pdata[i] != letters[i]) {
                        return FAILED("Array out of order, expected %s got %s", 
                                (gchar *)array->pdata[i], letters[i]);
                }
@@ -228,13 +228,13 @@ RESULT ptrarray_sort()
 }
 
 static Test ptrarray_tests [] = {
-       {"ptrarray_alloc", ptrarray_alloc},
-       {"ptrarray_for_iterate", ptrarray_for_iterate},
-       {"ptrarray_foreach_iterate", ptrarray_foreach_iterate},
-       {"ptrarray_set_size", ptrarray_set_size},
-       {"ptrarray_remove_index", ptrarray_remove_index},
-       {"ptrarray_remove", ptrarray_remove},
-       {"ptrarray_sort", ptrarray_sort},
+       {"alloc", ptrarray_alloc},
+       {"for_iterate", ptrarray_for_iterate},
+       {"foreach_iterate", ptrarray_foreach_iterate},
+       {"set_size", ptrarray_set_size},
+       {"remove_index", ptrarray_remove_index},
+       {"remove", ptrarray_remove},
+       {"sort", ptrarray_sort},
        {NULL, NULL}
 };
 
index 046eea417069b068fd50ac967402bc113372d846..f369dc9e27f17ec4aa85cf12e31ea147d07f40aa 100644 (file)
@@ -139,12 +139,12 @@ test_slist_insert_sorted ()
 }
 
 static Test slist_tests [] = {
-       {"slist_append", test_slist_append},
-       {"slist_concat", test_slist_concat},
-       {"slist_find", test_slist_find},
-       {"slist_remove", test_slist_remove},
-       {"slist_remove_link", test_slist_remove_link},
-       {"slist_insert_sorted", test_slist_insert_sorted},
+       {"append", test_slist_append},
+       {"concat", test_slist_concat},
+       {"find", test_slist_find},
+       {"remove", test_slist_remove},
+       {"remove_link", test_slist_remove_link},
+       {"insert_sorted", test_slist_insert_sorted},
        {NULL, NULL}
 };
 
index f6f53efffc62f022da7c618b67e1ec82ad175188..b519b871dcb847ef97e8422503d9248046dddd59 100644 (file)
@@ -32,19 +32,38 @@ test_concat ()
 RESULT
 test_split ()
 {
-       gchar **v = g_strsplit("Hello world, how are we doing today?", " ", 0);
-       int i = 0;
+       const gchar *to_split = "Hello world, how are we doing today?";
+       gint i;
+       gchar **v;
+       
+       v= g_strsplit(to_split, " ", 0);
        
        if(v == NULL) {
-               return "split failed, got NULL vector";
-       } else {
-               for(i = 0; v[i] != NULL; i++);
-               if(i != 7) {
-                       return FAILED("split failed, expected 7 tokens, got %d\n", i);
-               }
+               return FAILED("split failed, got NULL vector (1)");
+       }
+       
+       for(i = 0; v[i] != NULL; i++);
+       if(i != 7) {
+               return FAILED("split failed, expected 7 tokens, got %d", i);
        }
        
        g_strfreev(v);
+
+       v = g_strsplit(to_split, ":", -1);
+       if(v == NULL) {
+               return FAILED("split failed, got NULL vector (2)");
+       }
+
+       for(i = 0; v[i] != NULL; i++);
+       if(i != 1) {
+               return FAILED("split failed, expected 1 token, got %d", i);
+       }
+
+       if(strcmp(v[0], to_split) != 0) {
+               return FAILED("expected vector[0] to be '%s' but it was '%s'",
+                       to_split, v[0]);
+       }
+       
        return OK;
 }
 
index d75f11ca7c6f07de13674fe0e6e2b95c6f5c46ae..73fb86488eed65296dd0c19f6d921d044e9965b5 100644 (file)
@@ -204,8 +204,8 @@ test_appendlen ()
 static Test string_tests [] = {
        {"append-speed", test_append_speed},
     {"append_c-speed", test_append_c_speed},
-       {"constructors+append", test_gstring },
-       {"constructor-sized", test_sized },
+       {"ctor+append", test_gstring },
+       {"ctor+sized", test_sized },
        {"truncate", test_truncate },
        {"prepend", test_prepend },
        {"append_len", test_appendlen },
index 8400cde0fa0b1281c6bcee9a8628bc575b898f8a..d9da87180b9606425c16d6548d90fc4b97afacca 100644 (file)
@@ -52,12 +52,14 @@ run_test(Test *test, gchar **result_out)
 }
 
 gboolean
-run_group(Group *group, gint iterations, gboolean quiet, gboolean time)
+run_group(Group *group, gint iterations, gboolean quiet, 
+       gboolean time, gchar *tests_to_run_s)
 {
        Test *tests = group->handler();
-       gint i, j, passed = 0;
+       gint i, j, passed = 0, total = 0;
        gdouble start_time_group, start_time_test;
-       
+       gchar **tests_to_run = NULL;
+
        if(!quiet) {
                if(iterations > 1) {
                        printf("[%s] (%dx)\n", group->name, iterations);
@@ -66,12 +68,35 @@ run_group(Group *group, gint iterations, gboolean quiet, gboolean time)
                }
        }
 
+       if(tests_to_run_s != NULL) {
+               tests_to_run = eg_strsplit(tests_to_run_s, ",", -1);
+       }
+
        start_time_group = get_timestamp();
 
        for(i = 0; tests[i].name != NULL; i++) {
                gchar *result;
-               gboolean iter_pass;
-               
+               gboolean iter_pass, run;
+       
+               if(tests_to_run != NULL) {
+                       gint j;
+                       run = FALSE;
+                       for(j = 0; tests_to_run[j] != NULL; j++) {
+                               if(strcmp(tests_to_run[j], tests[i].name) == 0) {
+                                       run = TRUE;
+                                       break;
+                               }
+                       }
+               } else {
+                       run = TRUE;
+               }
+
+               if(!run) {
+                       continue;
+               }
+       
+               total++;
+       
                if(!quiet) {
                        printf("  %s: ", tests[i].name);
                }
@@ -107,16 +132,20 @@ run_group(Group *group, gint iterations, gboolean quiet, gboolean time)
        }
 
        if(!quiet) {
-               gdouble pass_percentage = ((gdouble)passed / (gdouble)i) * 100.0;
+               gdouble pass_percentage = ((gdouble)passed / (gdouble)total) * 100.0;
                if(time) {
-                       printf("  %d / %d (%g%%, %g)\n", passed, i,
+                       printf("  %d / %d (%g%%, %g)\n", passed, total,
                                pass_percentage, get_timestamp() - start_time_group);
                } else {
-                       printf("  %d / %d (%g%%)\n", passed, i, pass_percentage);
+                       printf("  %d / %d (%g%%)\n", passed, total, pass_percentage);
                }
        }
 
-       return passed == i;
+       if(tests_to_run != NULL) {
+               eg_strfreev(tests_to_run);
+       }
+
+       return passed == total;
 }
 
 RESULT
@@ -147,3 +176,77 @@ get_timestamp()
        return (gdouble)tp.tv_sec + (1.e-6) * tp.tv_usec;
 }
 
+/* 
+ * Duplicating code here from EGlib to avoid g_strsplit skew between
+ * EGLib and GLib
+ */
+gchar ** 
+eg_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens)
+{
+       gchar *string_c;
+       gchar *strtok_save, **vector;
+       gchar *token, *token_c;
+       gint size = 1;
+       gint token_length;
+
+       g_return_val_if_fail(string != NULL, NULL);
+       g_return_val_if_fail(delimiter != NULL, NULL);
+       g_return_val_if_fail(delimiter[0] != 0, NULL);
+       
+       token_length = strlen(string);
+       string_c = (gchar *)g_malloc(token_length + 1);
+       memcpy(string_c, string, token_length);
+       string_c[token_length] = 0;
+       
+       vector = NULL;
+       token = (gchar *)strtok_r(string_c, delimiter, &strtok_save);
+
+       while(token != NULL) {
+               token_length = strlen(token);
+               token_c = (gchar *)g_malloc(token_length + 1);
+               memcpy(token_c, token, token_length);
+               token_c[token_length] = 0;
+
+               vector = vector == NULL ? 
+                       (gchar **)g_malloc(2 * sizeof(vector)) :
+                       (gchar **)g_realloc(vector, (size + 1) * sizeof(vector));
+       
+               vector[size - 1] = token_c;     
+               size++;
+
+               if(max_tokens > 0 && size >= max_tokens) {
+                       if(size > max_tokens) {
+                               break;
+                       }
+
+                       token = strtok_save;
+               } else {
+                       token = (gchar *)strtok_r(NULL, delimiter, &strtok_save);
+               }
+       }
+
+       if(vector != NULL && size > 0) {
+               vector[size - 1] = NULL;
+       }
+       
+       g_free(string_c);
+       string_c = NULL;
+
+       return vector;
+}
+
+void
+eg_strfreev (gchar **str_array)
+{
+       gchar **orig = str_array;
+       if (str_array == NULL)
+               return;
+       while (*str_array != NULL){
+               g_free (*str_array);
+               str_array++;
+       }
+       g_free (orig);
+}
+
+
index 33a1c1f9c8fa206f607ffb31190c92b6afdd40ea..834cd9621bf887b33fea9e918b74d01793fe39eb 100644 (file)
@@ -51,9 +51,11 @@ struct _Group {
 };
 
 gboolean run_group(Group *group, gint iterations, gboolean quiet, 
-       gboolean time);
+       gboolean time, gchar *tests);
 RESULT FAILED(const gchar *format, ...);
 gdouble get_timestamp();
+gchar ** eg_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens);
+void eg_strfreev (gchar **str_array);
 
 #define OK NULL