glib/gfileutils.c glib/gfileutils.h glib/glib.symbols Rename g_makepath()
[platform/upstream/glib.git] / tests / testglib.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #undef G_DISABLE_ASSERT
30 #undef G_LOG_DOMAIN
31
32 #ifdef GLIB_COMPILATION
33 #undef GLIB_COMPILATION
34 #endif
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <errno.h>
39
40 #include "glib.h"
41 #include "gstdio.h"
42
43 #ifdef HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46
47 #ifdef G_OS_WIN32
48 #include <io.h>                 /* For read(), write() etc */
49 #endif
50
51 static int array[10000];
52 static gboolean failed = FALSE;
53
54 /* We write (m ? m : "") even in the m != NULL case to suppress a warning with GCC-3.1
55  */
56 #define TEST(m,cond)    G_STMT_START { failed = !(cond); \
57 if (failed) \
58   { if (!m) \
59       g_print ("\n(%s:%d) failed for: %s\n", __FILE__, __LINE__, ( # cond )); \
60     else \
61       g_print ("\n(%s:%d) failed for: %s: (%s)\n", __FILE__, __LINE__, ( # cond ), (gchar*)(m ? m : "")); \
62   } \
63 else \
64   g_print ("."); fflush (stdout); \
65 } G_STMT_END
66
67 #define C2P(c)          ((gpointer) ((long) (c)))
68 #define P2C(p)          ((gchar) ((long) (p)))
69
70 #define GLIB_TEST_STRING "el dorado "
71 #define GLIB_TEST_STRING_5 "el do"
72
73 static gboolean
74 node_build_string (GNode    *node,
75                    gpointer  data)
76 {
77   gchar **p = data;
78   gchar *string;
79   gchar c[2] = "_";
80
81   c[0] = P2C (node->data);
82
83   string = g_strconcat (*p ? *p : "", c, NULL);
84   g_free (*p);
85   *p = string;
86
87   return FALSE;
88 }
89
90 static void
91 g_node_test (void)
92 {
93   GNode *root;
94   GNode *node;
95   GNode *node_B;
96   GNode *node_F;
97   GNode *node_G;
98   GNode *node_J;
99   guint i;
100   gchar *tstring, *cstring;
101
102   g_print ("checking n-way trees: ");
103   failed = FALSE;
104
105   root = g_node_new (C2P ('A'));
106   TEST (NULL, g_node_depth (root) == 1 && g_node_max_height (root) == 1);
107
108   node_B = g_node_new (C2P ('B'));
109   g_node_append (root, node_B);
110   TEST (NULL, root->children == node_B);
111
112   g_node_append_data (node_B, C2P ('E'));
113   g_node_prepend_data (node_B, C2P ('C'));
114   g_node_insert (node_B, 1, g_node_new (C2P ('D')));
115
116   node_F = g_node_new (C2P ('F'));
117   g_node_append (root, node_F);
118   TEST (NULL, root->children->next == node_F);
119
120   node_G = g_node_new (C2P ('G'));
121   g_node_append (node_F, node_G);
122   node_J = g_node_new (C2P ('J'));
123   g_node_prepend (node_G, node_J);
124   g_node_insert (node_G, 42, g_node_new (C2P ('K')));
125   g_node_insert_data (node_G, 0, C2P ('H'));
126   g_node_insert (node_G, 1, g_node_new (C2P ('I')));
127
128   TEST (NULL, g_node_depth (root) == 1);
129   TEST (NULL, g_node_max_height (root) == 4);
130   TEST (NULL, g_node_depth (node_G->children->next) == 4);
131   TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_LEAFS) == 7);
132   TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS) == 4);
133   TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 11);
134   TEST (NULL, g_node_max_height (node_F) == 3);
135   TEST (NULL, g_node_n_children (node_G) == 4);
136   TEST (NULL, g_node_find_child (root, G_TRAVERSE_ALL, C2P ('F')) == node_F);
137   TEST (NULL, g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, C2P ('I')) == NULL);
138   TEST (NULL, g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, C2P ('J')) == node_J);
139
140   for (i = 0; i < g_node_n_children (node_B); i++)
141     {
142       node = g_node_nth_child (node_B, i);
143       TEST (NULL, P2C (node->data) == ('C' + i));
144     }
145   
146   for (i = 0; i < g_node_n_children (node_G); i++)
147     TEST (NULL, g_node_child_position (node_G, g_node_nth_child (node_G, i)) == i);
148
149   /* we have built:                    A
150    *                                 /   \
151    *                               B       F
152    *                             / | \       \
153    *                           C   D   E       G
154    *                                         / /\ \
155    *                                       H  I  J  K
156    *
157    * for in-order traversal, 'G' is considered to be the "left"
158    * child of 'F', which will cause 'F' to be the last node visited.
159    */
160
161   tstring = NULL;
162   g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
163   TEST (tstring, strcmp (tstring, "ABCDEFGHIJK") == 0);
164   g_free (tstring); tstring = NULL;
165   g_node_traverse (root, G_POST_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
166   TEST (tstring, strcmp (tstring, "CDEBHIJKGFA") == 0);
167   g_free (tstring); tstring = NULL;
168   g_node_traverse (root, G_IN_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
169   TEST (tstring, strcmp (tstring, "CBDEAHGIJKF") == 0);
170   g_free (tstring); tstring = NULL;
171   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
172   TEST (tstring, strcmp (tstring, "ABFCDEGHIJK") == 0);
173   g_free (tstring); tstring = NULL;
174   
175   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &tstring);
176   TEST (tstring, strcmp (tstring, "CDEHIJK") == 0);
177   g_free (tstring); tstring = NULL;
178   g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &tstring);
179   TEST (tstring, strcmp (tstring, "ABFG") == 0);
180   g_free (tstring); tstring = NULL;
181
182   g_node_reverse_children (node_B);
183   g_node_reverse_children (node_G);
184
185   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
186   TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0);
187   g_free (tstring); tstring = NULL;
188
189   cstring = NULL;
190   node = g_node_copy (root);
191   TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == g_node_n_nodes (node, G_TRAVERSE_ALL));
192   TEST (NULL, g_node_max_height (root) == g_node_max_height (node));
193   g_node_traverse (root, G_IN_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
194   g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &cstring);
195   TEST (cstring, strcmp (tstring, cstring) == 0);
196   g_free (tstring); tstring = NULL;
197   g_free (cstring); cstring = NULL;
198   g_node_destroy (node);
199
200   g_node_destroy (root);
201
202   /* allocation tests */
203
204   root = g_node_new (NULL);
205   node = root;
206
207   for (i = 0; i < 2048; i++)
208     {
209       g_node_append (node, g_node_new (NULL));
210       if ((i%5) == 4)
211         node = node->children->next;
212     }
213   TEST (NULL, g_node_max_height (root) > 100);
214   TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 1 + 2048);
215
216   g_node_destroy (root);
217   
218   if (!failed)
219     g_print ("ok\n");
220 }
221
222 static gboolean
223 my_hash_callback_remove (gpointer key,
224                          gpointer value,
225                          gpointer user_data)
226 {
227   int *d = value;
228
229   if ((*d) % 2)
230     return TRUE;
231
232   return FALSE;
233 }
234
235 static void
236 my_hash_callback_remove_test (gpointer key,
237                               gpointer value,
238                               gpointer user_data)
239 {
240   int *d = value;
241
242   if ((*d) % 2)
243     g_print ("bad!\n");
244 }
245
246 static void
247 my_hash_callback (gpointer key,
248                   gpointer value,
249                   gpointer user_data)
250 {
251   int *d = value;
252   *d = 1;
253 }
254
255 static guint
256 my_hash (gconstpointer key)
257 {
258   return (guint) *((const gint*) key);
259 }
260
261 static gboolean
262 my_hash_equal (gconstpointer a,
263                gconstpointer b)
264 {
265   return *((const gint*) a) == *((const gint*) b);
266 }
267
268 static gint
269 my_list_compare_one (gconstpointer a, gconstpointer b)
270 {
271   gint one = *((const gint*)a);
272   gint two = *((const gint*)b);
273   return one-two;
274 }
275
276 static gint
277 my_list_compare_two (gconstpointer a, gconstpointer b)
278 {
279   gint one = *((const gint*)a);
280   gint two = *((const gint*)b);
281   return two-one;
282 }
283
284 /* static void
285 my_list_print (gpointer a, gpointer b)
286 {
287   gint three = *((gint*)a);
288   g_print("%d", three);
289 }; */
290
291 static gint
292 my_compare (gconstpointer a,
293             gconstpointer b)
294 {
295   const char *cha = a;
296   const char *chb = b;
297
298   return *cha - *chb;
299 }
300
301 static gint
302 my_traverse (gpointer key,
303              gpointer value,
304              gpointer data)
305 {
306   char *ch = key;
307   g_print ("%c ", *ch);
308   return FALSE;
309 }
310
311 static gboolean 
312 find_first_that(gpointer key, 
313                 gpointer value, 
314                 gpointer user_data)
315 {
316   gint *v = value;
317   gint *test = user_data;
318   return (*v == *test);
319 }
320
321
322 static gboolean
323 test_g_mkdir_with_parents_1 (const gchar *base)
324 {
325   char *p0 = g_build_filename (base, "fum", NULL);
326   char *p1 = g_build_filename (p0, "tem", NULL);
327   char *p2 = g_build_filename (p1, "zap", NULL);
328   FILE *f;
329
330   g_remove (p2);
331   g_remove (p1);
332   g_remove (p0);
333
334   if (g_file_test (p0, G_FILE_TEST_EXISTS))
335     {
336       g_print ("failed, %s exists, cannot test g_mkdir_with_parents\n", p0);
337       return FALSE;
338     }
339
340   if (g_file_test (p1, G_FILE_TEST_EXISTS))
341     {
342       g_print ("failed, %s exists, cannot test g_mkdir_with_parents\n", p1);
343       return FALSE;
344     }
345
346   if (g_file_test (p2, G_FILE_TEST_EXISTS))
347     {
348       g_print ("failed, %s exists, cannot test g_mkdir_with_parents\n", p2);
349       return FALSE;
350     }
351
352   if (g_mkdir_with_parents (p2, 0666) == -1)
353     {
354       g_print ("failed, g_mkdir_with_parents(%s) failed: %s\n", p2, g_strerror (errno));
355       return FALSE;
356     }
357
358   if (!g_file_test (p2, G_FILE_TEST_IS_DIR))
359     {
360       g_print ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory\n", p2, p2);
361       return FALSE;
362     }
363
364   if (!g_file_test (p1, G_FILE_TEST_IS_DIR))
365     {
366       g_print ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory\n", p2, p1);
367       return FALSE;
368     }
369
370   if (!g_file_test (p0, G_FILE_TEST_IS_DIR))
371     {
372       g_print ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory\n", p2, p0);
373       return FALSE;
374     }
375
376   g_rmdir (p2);
377   if (g_file_test (p2, G_FILE_TEST_EXISTS))
378     {
379       g_print ("failed, did g_rmdir(%s), but %s is still there\n", p2, p2);
380       return FALSE;
381     }
382
383   g_rmdir (p1);
384   if (g_file_test (p1, G_FILE_TEST_EXISTS))
385     {
386       g_print ("failed, did g_rmdir(%s), but %s is still there\n", p1, p1);
387       return FALSE;
388     }
389
390   f = g_fopen (p1, "w");
391   if (f == NULL)
392     {
393       g_print ("failed, couldn't create file %s\n", p1);
394       return FALSE;
395     }
396   fclose (f);
397   
398   if (g_mkdir_with_parents (p1, 0666) == 0)
399     {
400       g_print ("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file\n", p1, p1);
401       return FALSE;
402     }
403
404   if (g_mkdir_with_parents (p2, 0666) == 0)
405     {
406       g_print ("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file\n", p2, p1);
407       return FALSE;
408     }
409
410   g_remove (p2);
411   g_remove (p1);
412   g_remove (p0);
413
414   return TRUE;
415 }
416
417 static gboolean
418 test_g_mkdir_with_parents (void)
419 {
420   g_print ("checking g_mkdir_with_parents()...");
421   if (!test_g_mkdir_with_parents_1 ("hum"))
422     return FALSE;
423   g_remove ("hum");
424   if (!test_g_mkdir_with_parents_1 ("hii///haa/hee"))
425     return FALSE;
426   g_remove ("hii/haa/hee");
427   g_remove ("hii/haa");
428   g_remove ("hii");
429   if (!test_g_mkdir_with_parents_1 (g_get_current_dir ()))
430     return FALSE;
431
432   return TRUE;
433 }
434
435 int
436 main (int   argc,
437       char *argv[])
438 {
439   const gchar *s;
440   gchar **sv;
441   GList *list, *t;
442   GSList *slist, *st;
443   GHashTable *hash_table;
444   GMemChunk *mem_chunk;
445   GStringChunk *string_chunk;
446   GTimer *timer, *timer2;
447   gdouble elapsed;
448   gulong elapsed_usecs;
449   gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
450   gint morenums[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6};
451   gchar *string;
452   gint value = 120; 
453   gint *pvalue=NULL; 
454   
455   gchar *mem[10000], *tmp_string = NULL, *tmp_string_2;
456   gint i, j;
457   GArray *garray;
458   GPtrArray *gparray;
459   GByteArray *gbarray;
460   GString *string1, *string2;
461   const gchar *charset;
462   GTree *tree;
463   char chars[62];
464   GRelation *relation;
465   GTuples *tuples;
466   gint data [1024];
467   struct {
468     gchar *filename;
469     gchar *dirname;
470   } dirname_checks[] = {
471     { "/", "/" },
472     { "////", "/" },
473     { ".////", "." },
474     { "../", ".." },
475     { "..////", ".." },
476     { "a/b", "a" },
477     { "a/b/", "a/b" },
478     { "c///", "c" },
479 #ifdef G_OS_WIN32
480     { "\\", "\\" },
481     { ".\\\\\\\\", "." },
482     { "..\\", ".." },
483     { "..\\\\\\\\", ".." },
484     { "a\\b", "a" },
485     { "a\\b/", "a\\b" },
486     { "a/b\\", "a/b" },
487     { "c\\\\/", "c" },
488     { "//\\", "/" },
489 #endif
490 #ifdef G_WITH_CYGWIN
491     { "//server/share///x", "//server/share" },
492 #endif
493     { ".", "." },
494     { "..", "." },
495     { "", "." },
496   };
497   guint n_dirname_checks = G_N_ELEMENTS (dirname_checks);
498
499   struct {
500     gchar *filename;
501     gchar *without_root;
502   } skip_root_checks[] = {
503     { "/", "" },
504     { "//", "" },
505     { "/foo", "foo" },
506     { "//foo", "foo" },
507     { "a/b", NULL },
508 #ifdef G_OS_WIN32
509     { "\\", "" },
510     { "\\foo", "foo" },
511     { "\\\\server\\foo", "" },
512     { "\\\\server\\foo\\bar", "bar" },
513     { "a\\b", NULL },
514 #endif
515 #ifdef G_WITH_CYGWIN
516     { "//server/share///x", "//x" },
517 #endif
518     { ".", NULL },
519     { "", NULL },
520   };
521   guint n_skip_root_checks = G_N_ELEMENTS (skip_root_checks);
522
523 #ifndef G_DISABLE_ASSERT
524   guint16 gu16t1 = 0x44afU, gu16t2 = 0xaf44U;
525   guint32 gu32t1 = 0x02a7f109U, gu32t2 = 0x09f1a702U;
526   guint64 gu64t1 = G_GINT64_CONSTANT(0x1d636b02300a7aa7U),
527           gu64t2 = G_GINT64_CONSTANT(0xa77a0a30026b631dU);
528 #endif
529   const char hello[] = "Hello, World";
530   const int hellolen = sizeof (hello) - 1;
531   int fd;
532   char template[32];
533   GError *error;
534   char *name_used;
535 #ifdef G_OS_WIN32
536   /* Can't calculate GLib DLL name at runtime. */
537   gchar *glib_dll = "libglib-2.0-0.dll";
538 #endif
539 #ifdef G_WITH_CYGWIN
540   gchar *glib_dll = "cygglib-2.0-0.dll";
541 #endif
542
543   g_print ("TestGLib v%u.%u.%u (i:%u b:%u)\n",
544            glib_major_version,
545            glib_minor_version,
546            glib_micro_version,
547            glib_interface_age,
548            glib_binary_age);
549
550   string = g_get_current_dir ();
551   g_print ("cwd: %s\n", string);
552   g_free (string);
553   g_print ("user: %s\n", g_get_user_name ());
554   g_print ("real: %s\n", g_get_real_name ());
555   g_print ("host: %s\n", g_get_host_name ());
556   s = g_get_home_dir ();
557   g_print ("home: %s\n", s ? s : "NULL!");
558   s = g_get_user_data_dir ();
559   g_print ("user_data: %s\n", s ? s : "NULL!");
560   s = g_get_user_config_dir ();
561   g_print ("user_config: %s\n", s ? s : "NULL!");
562   s = g_get_user_cache_dir ();
563   g_print ("user_cache: %s\n", s ? s : "NULL!");
564   sv = (gchar **) g_get_system_data_dirs ();
565   g_print ("system_data: %s\n", sv ? g_strjoinv (G_SEARCHPATH_SEPARATOR_S, sv) : "NULL!");
566   sv = (gchar **) g_get_system_config_dirs ();
567   g_print ("system_config: %s\n", s ? g_strjoinv (G_SEARCHPATH_SEPARATOR_S, sv) : "NULL!");
568   g_print ("tmp-dir: %s\n", g_get_tmp_dir ());
569   sv = (gchar **) g_get_language_names ();
570   g_print ("languages: %s\n", s ? g_strjoinv (":", sv) : "NULL!");
571
572   /* type sizes */
573   g_print ("checking size of gint8: %"    G_GSIZE_FORMAT, sizeof (gint8));
574   TEST (NULL, sizeof (gint8) == 1);
575   g_print ("\nchecking size of gint16: %" G_GSIZE_FORMAT, sizeof (gint16));
576   TEST (NULL, sizeof (gint16) == 2);
577   g_print ("\nchecking size of gint32: %" G_GSIZE_FORMAT, sizeof (gint32));
578   TEST (NULL, sizeof (gint32) == 4);
579   g_print ("\nchecking size of gsize: %"  G_GSIZE_FORMAT, sizeof (gsize));
580   g_print ("\nchecking size of gint64: %" G_GSIZE_FORMAT, sizeof (gint64));
581   TEST (NULL, sizeof (gint64) == 8);
582   g_print ("\n");
583
584   g_print ("checking g_path_get_basename()...");
585   string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "dir" G_DIR_SEPARATOR_S);
586   g_assert (strcmp (string, "dir") == 0);
587   g_free (string);
588   string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "file");
589   g_assert (strcmp (string, "file") == 0);
590   g_free (string);
591   g_print ("ok\n");
592 #ifdef G_OS_WIN32
593   string = g_path_get_basename ("/foo/dir/");
594   g_assert (strcmp (string, "dir") == 0);
595   g_free (string);
596   string = g_path_get_basename ("/foo/file");
597   g_assert (strcmp (string, "file") == 0);
598   g_free (string);
599 #endif
600
601   g_print ("checking g_path_get_dirname()...");
602   for (i = 0; i < n_dirname_checks; i++)
603     {
604       gchar *dirname;
605
606       dirname = g_path_get_dirname (dirname_checks[i].filename);
607       if (strcmp (dirname, dirname_checks[i].dirname) != 0)
608         {
609           g_print ("\nfailed for \"%s\"==\"%s\" (returned: \"%s\")\n",
610                    dirname_checks[i].filename,
611                    dirname_checks[i].dirname,
612                    dirname);
613           n_dirname_checks = 0;
614         }
615       g_free (dirname);
616     }
617   if (n_dirname_checks)
618     g_print ("ok\n");
619
620   g_print ("checking g_path_skip_root()...");
621   for (i = 0; i < n_skip_root_checks; i++)
622     {
623       const gchar *skipped;
624
625       skipped = g_path_skip_root (skip_root_checks[i].filename);
626       if ((skipped && !skip_root_checks[i].without_root) ||
627           (!skipped && skip_root_checks[i].without_root) ||
628           ((skipped && skip_root_checks[i].without_root) &&
629            strcmp (skipped, skip_root_checks[i].without_root)))
630         {
631           g_print ("\nfailed for \"%s\"==\"%s\" (returned: \"%s\")\n",
632                    skip_root_checks[i].filename,
633                    (skip_root_checks[i].without_root ?
634                     skip_root_checks[i].without_root : "<NULL>"),
635                    (skipped ? skipped : "<NULL>"));
636           n_skip_root_checks = 0;
637         }
638     }
639   if (n_skip_root_checks)
640     g_print ("ok\n");
641
642   if (test_g_mkdir_with_parents ())
643     g_print ("ok\n");
644
645   g_print ("checking doubly linked lists...");
646
647   list = NULL;
648   for (i = 0; i < 10; i++)
649     list = g_list_append (list, &nums[i]);
650   list = g_list_reverse (list);
651
652   for (i = 0; i < 10; i++)
653     {
654       t = g_list_nth (list, i);
655       if (*((gint*) t->data) != (9 - i))
656         g_error ("Regular insert failed");
657     }
658
659   for (i = 0; i < 10; i++)
660     if(g_list_position(list, g_list_nth (list, i)) != i)
661       g_error("g_list_position does not seem to be the inverse of g_list_nth\n");
662
663   g_list_free (list);
664   list = NULL;
665
666   for (i = 0; i < 10; i++)
667     list = g_list_insert_sorted (list, &morenums[i], my_list_compare_one);
668
669   /*
670   g_print("\n");
671   g_list_foreach (list, my_list_print, NULL);
672   */
673
674   for (i = 0; i < 10; i++)
675     {
676       t = g_list_nth (list, i);
677       if (*((gint*) t->data) != i)
678          g_error ("Sorted insert failed");
679     }
680
681   g_list_free (list);
682   list = NULL;
683
684   for (i = 0; i < 10; i++)
685     list = g_list_insert_sorted (list, &morenums[i], my_list_compare_two);
686
687   /*
688   g_print("\n");
689   g_list_foreach (list, my_list_print, NULL);
690   */
691
692   for (i = 0; i < 10; i++)
693     {
694       t = g_list_nth (list, i);
695       if (*((gint*) t->data) != (9 - i))
696          g_error ("Sorted insert failed");
697     }
698
699   g_list_free (list);
700   list = NULL;
701
702   for (i = 0; i < 10; i++)
703     list = g_list_prepend (list, &morenums[i]);
704
705   list = g_list_sort (list, my_list_compare_two);
706
707   /*
708   g_print("\n");
709   g_list_foreach (list, my_list_print, NULL);
710   */
711
712   for (i = 0; i < 10; i++)
713     {
714       t = g_list_nth (list, i);
715       if (*((gint*) t->data) != (9 - i))
716          g_error ("Merge sort failed");
717     }
718
719   g_list_free (list);
720
721   g_print ("ok\n");
722
723
724   g_print ("checking singly linked lists...");
725
726   slist = NULL;
727   for (i = 0; i < 10; i++)
728     slist = g_slist_append (slist, &nums[i]);
729   slist = g_slist_reverse (slist);
730
731   for (i = 0; i < 10; i++)
732     {
733       st = g_slist_nth (slist, i);
734       if (*((gint*) st->data) != (9 - i))
735         g_error ("failed");
736     }
737
738   g_slist_free (slist);
739   slist = NULL;
740
741   for (i = 0; i < 10; i++)
742     slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_one);
743
744   /*
745   g_print("\n");
746   g_slist_foreach (slist, my_list_print, NULL);
747   */
748
749   for (i = 0; i < 10; i++)
750     {
751       st = g_slist_nth (slist, i);
752       if (*((gint*) st->data) != i)
753          g_error ("Sorted insert failed");
754     }
755
756   g_slist_free(slist);
757   slist = NULL;
758
759   for (i = 0; i < 10; i++)
760     slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_two);
761
762   /*
763   g_print("\n");
764   g_slist_foreach (slist, my_list_print, NULL);
765   */
766
767   for (i = 0; i < 10; i++)
768     {
769       st = g_slist_nth (slist, i);
770       if (*((gint*) st->data) != (9 - i))
771          g_error("Sorted insert failed");
772     }
773
774   g_slist_free(slist);
775   slist = NULL;
776
777   for (i = 0; i < 10; i++)
778     slist = g_slist_prepend (slist, &morenums[i]);
779
780   slist = g_slist_sort (slist, my_list_compare_two);
781
782   /*
783   g_print("\n");
784   g_slist_foreach (slist, my_list_print, NULL);
785   */
786
787   for (i = 0; i < 10; i++)
788     {
789       st = g_slist_nth (slist, i);
790       if (*((gint*) st->data) != (9 - i))
791          g_error("Sorted insert failed");
792     }
793
794   g_slist_free(slist);
795
796   g_print ("ok\n");
797
798
799   g_print ("checking binary trees...\n");
800
801   tree = g_tree_new (my_compare);
802   i = 0;
803   for (j = 0; j < 10; j++, i++)
804     {
805       chars[i] = '0' + j;
806       g_tree_insert (tree, &chars[i], &chars[i]);
807     }
808   for (j = 0; j < 26; j++, i++)
809     {
810       chars[i] = 'A' + j;
811       g_tree_insert (tree, &chars[i], &chars[i]);
812     }
813   for (j = 0; j < 26; j++, i++)
814     {
815       chars[i] = 'a' + j;
816       g_tree_insert (tree, &chars[i], &chars[i]);
817     }
818
819   g_print ("tree height: %d\n", g_tree_height (tree));
820   g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
821
822   g_print ("tree: ");
823   g_tree_foreach (tree, my_traverse, NULL);
824   g_print ("\n");
825
826   for (i = 0; i < 10; i++)
827     g_tree_remove (tree, &chars[i]);
828
829   g_print ("tree height: %d\n", g_tree_height (tree));
830   g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
831
832   g_print ("tree: ");
833   g_tree_foreach (tree, my_traverse, NULL);
834   g_print ("\n");
835
836   g_print ("ok\n");
837
838
839   /* check n-way trees */
840   g_node_test ();
841
842   g_print ("checking mem chunks...");
843
844   mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
845
846   for (i = 0; i < 10000; i++)
847     {
848       mem[i] = g_chunk_new (gchar, mem_chunk);
849
850       for (j = 0; j < 50; j++)
851         mem[i][j] = i * j;
852     }
853
854   for (i = 0; i < 10000; i++)
855     {
856       g_mem_chunk_free (mem_chunk, mem[i]);
857     }
858
859   g_print ("ok\n");
860
861
862   g_print ("checking hash tables...");
863
864   hash_table = g_hash_table_new (my_hash, my_hash_equal);
865   for (i = 0; i < 10000; i++)
866     {
867       array[i] = i;
868       g_hash_table_insert (hash_table, &array[i], &array[i]);
869     }
870   pvalue = g_hash_table_find (hash_table, find_first_that, &value);
871   if (*pvalue != value)
872           g_print("g_hash_table_find failed");
873   
874   g_hash_table_foreach (hash_table, my_hash_callback, NULL);
875
876   for (i = 0; i < 10000; i++)
877     if (array[i] == 0)
878       g_print ("%d\n", i);
879
880   for (i = 0; i < 10000; i++)
881     g_hash_table_remove (hash_table, &array[i]);
882
883   for (i = 0; i < 10000; i++)
884     {
885       array[i] = i;
886       g_hash_table_insert (hash_table, &array[i], &array[i]);
887     }
888
889   if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 ||
890       g_hash_table_size (hash_table) != 5000)
891     g_print ("bad!\n");
892
893   g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL);
894
895
896   g_hash_table_destroy (hash_table);
897
898   g_print ("ok\n");
899
900
901   g_print ("checking string chunks...");
902
903   string_chunk = g_string_chunk_new (1024);
904
905   for (i = 0; i < 100000; i ++)
906     {
907       tmp_string = g_string_chunk_insert (string_chunk, "hi pete");
908
909       if (strcmp ("hi pete", tmp_string) != 0)
910         g_error ("string chunks are broken.\n");
911     }
912
913   tmp_string_2 = g_string_chunk_insert_const (string_chunk, tmp_string);
914
915   g_assert (tmp_string_2 != tmp_string &&
916             strcmp(tmp_string_2, tmp_string) == 0);
917
918   tmp_string = g_string_chunk_insert_const (string_chunk, tmp_string);
919
920   g_assert (tmp_string_2 == tmp_string);
921
922   g_string_chunk_free (string_chunk);
923
924   g_print ("ok\n");
925
926
927   g_print ("checking arrays...");
928
929   garray = g_array_new (FALSE, FALSE, sizeof (gint));
930   for (i = 0; i < 10000; i++)
931     g_array_append_val (garray, i);
932
933   for (i = 0; i < 10000; i++)
934     if (g_array_index (garray, gint, i) != i)
935       g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), i);
936
937   g_array_free (garray, TRUE);
938
939   garray = g_array_new (FALSE, FALSE, sizeof (gint));
940   for (i = 0; i < 100; i++)
941     g_array_prepend_val (garray, i);
942
943   for (i = 0; i < 100; i++)
944     if (g_array_index (garray, gint, i) != (100 - i - 1))
945       g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 100 - i - 1);
946
947   g_array_free (garray, TRUE);
948
949   g_print ("ok\n");
950
951
952   g_print ("checking strings...");
953
954   string1 = g_string_new ("hi pete!");
955   string2 = g_string_new ("");
956
957   g_assert (strcmp ("hi pete!", string1->str) == 0);
958
959   for (i = 0; i < 10000; i++)
960     g_string_append_c (string1, 'a'+(i%26));
961
962 #ifndef G_OS_WIN32
963   /* MSVC, mingw32 and LCC use the same run-time C library, which doesn't like
964      the %10000.10000f format... */
965   g_string_printf (string2, "%s|%0100d|%s|%s|%0*d|%*.*f|%10000.10000f",
966                    "this pete guy sure is a wuss, like he's the number ",
967                    1,
968                    " wuss.  everyone agrees.\n",
969                    string1->str,
970                    10, 666, 15, 15, 666.666666666, 666.666666666);
971 #else
972   g_string_printf (string2, "%s|%0100d|%s|%s|%0*d|%*.*f|%100.100f",
973                    "this pete guy sure is a wuss, like he's the number ",
974                    1,
975                    " wuss.  everyone agrees.\n",
976                    string1->str,
977                    10, 666, 15, 15, 666.666666666, 666.666666666);
978 #endif
979
980   g_print ("string2 length = %lu...\n", (gulong)string2->len);
981   string2->str[70] = '\0';
982   g_print ("first 70 chars:\n%s\n", string2->str);
983   string2->str[141] = '\0';
984   g_print ("next 70 chars:\n%s\n", string2->str+71);
985   string2->str[212] = '\0';
986   g_print ("and next 70:\n%s\n", string2->str+142);
987   g_print ("last 70 chars:\n%s\n", string2->str+string2->len - 70);
988
989   g_string_free (string1, TRUE);
990   g_string_free (string2, TRUE);
991
992   /* append */
993   string1 = g_string_new ("firsthalf");
994   g_string_append (string1, "lasthalf");
995   g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
996   g_string_free (string1, TRUE);
997
998   /* append_len */
999
1000   string1 = g_string_new ("firsthalf");
1001   g_string_append_len (string1, "lasthalfjunkjunk", strlen ("lasthalf"));
1002   g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
1003   g_string_free (string1, TRUE);  
1004   
1005   /* prepend */
1006   string1 = g_string_new ("lasthalf");
1007   g_string_prepend (string1, "firsthalf");
1008   g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
1009   g_string_free (string1, TRUE);
1010
1011   /* prepend_len */
1012   string1 = g_string_new ("lasthalf");
1013   g_string_prepend_len (string1, "firsthalfjunkjunk", strlen ("firsthalf"));
1014   g_assert (strcmp (string1->str, "firsthalflasthalf") == 0);
1015   g_string_free (string1, TRUE);
1016   
1017   /* insert */
1018   string1 = g_string_new ("firstlast");
1019   g_string_insert (string1, 5, "middle");
1020   g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
1021   g_string_free (string1, TRUE);
1022
1023   /* insert with pos == end of the string */
1024   string1 = g_string_new ("firstmiddle");
1025   g_string_insert (string1, strlen ("firstmiddle"), "last");
1026   g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
1027   g_string_free (string1, TRUE);
1028   
1029   /* insert_len */
1030
1031   string1 = g_string_new ("firstlast");
1032   g_string_insert_len (string1, 5, "middlejunkjunk", strlen ("middle"));
1033   g_assert (strcmp (string1->str, "firstmiddlelast") == 0);
1034   g_string_free (string1, TRUE);
1035
1036   /* insert_len with magic -1 pos for append */
1037   string1 = g_string_new ("first");
1038   g_string_insert_len (string1, -1, "lastjunkjunk", strlen ("last"));
1039   g_assert (strcmp (string1->str, "firstlast") == 0);
1040   g_string_free (string1, TRUE);
1041   
1042   /* insert_len with magic -1 len for strlen-the-string */
1043   string1 = g_string_new ("first");
1044   g_string_insert_len (string1, 5, "last", -1);
1045   g_assert (strcmp (string1->str, "firstlast") == 0);
1046   g_string_free (string1, TRUE);
1047   
1048   g_print ("ok\n");
1049
1050   /* g_string_equal */
1051   string1 = g_string_new ("test");
1052   string2 = g_string_new ("te");
1053   g_assert (! g_string_equal(string1, string2));
1054   g_string_append (string2, "st");
1055   g_assert (g_string_equal(string1, string2));
1056   g_string_free (string1, TRUE);
1057   g_string_free (string2, TRUE);
1058   
1059   /* Check handling of embedded ASCII 0 (NUL) characters in GString. */
1060   string1 = g_string_new ("fiddle");
1061   string2 = g_string_new ("fiddle");
1062   g_assert (g_string_equal(string1, string2));
1063   g_string_append_c(string1, '\0');
1064   g_assert (! g_string_equal(string1, string2));
1065   g_string_append_c(string2, '\0');
1066   g_assert (g_string_equal(string1, string2));
1067   g_string_append_c(string1, 'x');
1068   g_string_append_c(string2, 'y');
1069   g_assert (! g_string_equal(string1, string2));
1070   g_assert (string1->len == 8);
1071   g_string_append(string1, "yzzy");
1072   g_assert (string1->len == 12);
1073   g_assert ( memcmp(string1->str, "fiddle\0xyzzy", 13) == 0);
1074   g_string_insert(string1, 1, "QED");
1075   g_assert ( memcmp(string1->str, "fQEDiddle\0xyzzy", 16) == 0);
1076   g_string_free (string1, TRUE);
1077   g_string_free (string2, TRUE);
1078   
1079   g_print ("test positional printf formats (not supported): ");
1080   string = g_strdup_printf ("%.*s%s", 5, "a", "b");
1081   tmp_string = g_strdup_printf ("%2$*1$s", 5, "c");
1082   g_print ("%s%s\n", string, tmp_string);
1083   g_free (tmp_string);
1084   g_free (string);
1085
1086   g_print ("checking timers...\n");
1087   
1088   timer = g_timer_new ();
1089   g_print ("  spinning for 3 seconds...\n");
1090
1091   g_timer_start (timer);
1092   while (g_timer_elapsed (timer, NULL) < 3)
1093     ;
1094
1095   g_timer_stop (timer);
1096   g_timer_destroy (timer);
1097
1098   g_print ("ok\n");
1099
1100   g_print ("checking g_timer_continue...\n");
1101
1102   timer2 = g_timer_new ();
1103
1104   g_print ("\trun for 1 second...\n");
1105   timer = g_timer_new();
1106   g_usleep(G_USEC_PER_SEC); /* run timer for 1 second */
1107   g_timer_stop(timer);
1108
1109   g_print ("\tstop for 1 second...\n");
1110   g_usleep(G_USEC_PER_SEC); /* wait for 1 second */
1111   g_print ("\trun for 2 seconds...\n");
1112
1113   g_timer_continue(timer);
1114   g_usleep(2*G_USEC_PER_SEC); /* run timer for 2 seconds */
1115   g_timer_stop(timer);
1116
1117   g_print ("\tstop for 1.5 seconds...\n");
1118   g_usleep((3*G_USEC_PER_SEC)/2); /* wait for 1.5 seconds */
1119   g_print ("\trun for 0.2 seconds...\n");
1120
1121   g_timer_continue(timer);
1122   g_usleep(G_USEC_PER_SEC/5); /* run timer for 0.2 seconds */
1123   g_timer_stop(timer);
1124
1125   g_print ("\tstop for 4 seconds...\n");
1126   g_usleep(4*G_USEC_PER_SEC); /* wait for 4 seconds */
1127   g_print ("\trun for 5.8 seconds...\n");
1128
1129   g_timer_continue(timer);
1130   g_usleep((29*G_USEC_PER_SEC)/5); /* run timer for 5.8 seconds */
1131   g_timer_stop(timer);
1132
1133   elapsed = g_timer_elapsed (timer, &elapsed_usecs);
1134   g_print ("\t=> timer = %.6f = %d.%06ld (should be: 9.000000) (%.6f off)\n", elapsed, (int) elapsed, elapsed_usecs, ABS (elapsed - 9.));
1135
1136   if (elapsed > 8.8 && elapsed < 9.2)
1137     g_print ("g_timer_continue ... ok\n\n");
1138   else
1139     g_print ("g_timer_continue ... ***** FAILED *****\n\n");
1140
1141   g_timer_stop(timer2);
1142
1143   elapsed = g_timer_elapsed(timer2, &elapsed_usecs);
1144   g_print ("\t=> timer2 = %.6f = %d.%06ld (should be: %.6f) (%.6f off)\n\n", elapsed, (int) elapsed, elapsed_usecs, 9.+6.5, ABS (elapsed - (9.+6.5)));
1145
1146   if (elapsed > (8.8+6.5) && elapsed < (9.2+6.5))
1147     g_print ("timer2 ... ok\n\n");
1148   else
1149     g_print ("timer2 ... ***** FAILED *****\n\n");
1150
1151   g_timer_destroy(timer);
1152   g_timer_destroy(timer2);
1153
1154   g_print ("checking g_ascii_strcasecmp...");
1155   g_assert (g_ascii_strcasecmp ("FroboZZ", "frobozz") == 0);
1156   g_assert (g_ascii_strcasecmp ("frobozz", "frobozz") == 0);
1157   g_assert (g_ascii_strcasecmp ("frobozz", "FROBOZZ") == 0);
1158   g_assert (g_ascii_strcasecmp ("FROBOZZ", "froboz") > 0);
1159   g_assert (g_ascii_strcasecmp ("", "") == 0);
1160   g_assert (g_ascii_strcasecmp ("!#%&/()", "!#%&/()") == 0);
1161   g_assert (g_ascii_strcasecmp ("a", "b") < 0);
1162   g_assert (g_ascii_strcasecmp ("a", "B") < 0);
1163   g_assert (g_ascii_strcasecmp ("A", "b") < 0);
1164   g_assert (g_ascii_strcasecmp ("A", "B") < 0);
1165   g_assert (g_ascii_strcasecmp ("b", "a") > 0);
1166   g_assert (g_ascii_strcasecmp ("b", "A") > 0);
1167   g_assert (g_ascii_strcasecmp ("B", "a") > 0);
1168   g_assert (g_ascii_strcasecmp ("B", "A") > 0);
1169
1170   g_print ("ok\n");
1171
1172   g_print ("checking g_strdup...");
1173   g_assert(g_strdup(NULL) == NULL);
1174   string = g_strdup(GLIB_TEST_STRING);
1175   g_assert(string != NULL);
1176   g_assert(strcmp(string, GLIB_TEST_STRING) == 0);
1177   g_free(string);
1178
1179   g_print ("ok\n");
1180
1181   g_print ("checking g_strconcat...");
1182   string = g_strconcat(GLIB_TEST_STRING, NULL);
1183   g_assert(string != NULL);
1184   g_assert(strcmp(string, GLIB_TEST_STRING) == 0);
1185   g_free(string);
1186   string = g_strconcat(GLIB_TEST_STRING, GLIB_TEST_STRING, 
1187                        GLIB_TEST_STRING, NULL);
1188   g_assert(string != NULL);
1189   g_assert(strcmp(string, GLIB_TEST_STRING GLIB_TEST_STRING
1190                           GLIB_TEST_STRING) == 0);
1191   g_free(string);
1192   g_print ("ok\n");
1193   
1194
1195   g_print("checking g_strlcpy/g_strlcat...");
1196   /* The following is a torture test for strlcpy/strlcat, with lots of
1197    * checking; normal users wouldn't use them this way!
1198    */
1199   string = g_malloc (6);
1200   *(string + 5) = 'Z'; /* guard value, shouldn't change during test */
1201   *string = 'q';
1202   g_assert (g_strlcpy(string, "" , 5) == 0);
1203   g_assert ( *string == '\0' );
1204   *string = 'q';
1205   g_assert (g_strlcpy(string, "abc" , 5) == 3);
1206   g_assert ( *(string + 3) == '\0' );
1207   g_assert (g_str_equal(string, "abc"));
1208   g_assert (g_strlcpy(string, "abcd" , 5) == 4);
1209   g_assert ( *(string + 4) == '\0' );
1210   g_assert ( *(string + 5) == 'Z' );
1211   g_assert (g_str_equal(string, "abcd"));
1212   g_assert (g_strlcpy(string, "abcde" , 5) == 5);
1213   g_assert ( *(string + 4) == '\0' );
1214   g_assert ( *(string + 5) == 'Z' );
1215   g_assert (g_str_equal(string, "abcd"));
1216   g_assert (g_strlcpy(string, "abcdef" , 5) == 6);
1217   g_assert ( *(string + 4) == '\0' );
1218   g_assert ( *(string + 5) == 'Z' );
1219   g_assert (g_str_equal(string, "abcd"));
1220   *string = 'Y';
1221   *(string + 1)= '\0';
1222   g_assert (g_strlcpy(string, "Hello" , 0) == 5);
1223   g_assert (*string == 'Y');
1224   *string = '\0';
1225   g_assert (g_strlcat(string, "123" , 5) == 3);
1226   g_assert ( *(string + 3) == '\0' );
1227   g_assert (g_str_equal(string, "123"));
1228   g_assert (g_strlcat(string, "" , 5) == 3);
1229   g_assert ( *(string + 3) == '\0' );
1230   g_assert (g_str_equal(string, "123"));
1231   g_assert (g_strlcat(string, "4", 5) == 4);
1232   g_assert (g_str_equal(string, "1234"));
1233   g_assert (g_strlcat(string, "5", 5) == 5);
1234   g_assert ( *(string + 4) == '\0' );
1235   g_assert (g_str_equal(string, "1234"));
1236   g_assert ( *(string + 5) == 'Z' );
1237   *string = 'Y';
1238   *(string + 1)= '\0';
1239   g_assert (g_strlcat(string, "123" , 0) == 3);
1240   g_assert (*string == 'Y');
1241   
1242   /* A few more tests, demonstrating more "normal" use  */
1243   g_assert (g_strlcpy(string, "hi", 5) == 2);
1244   g_assert (g_str_equal(string, "hi"));
1245   g_assert (g_strlcat(string, "t", 5) == 3);
1246   g_assert (g_str_equal(string, "hit"));
1247   g_free(string);
1248
1249   g_print ("ok\n");
1250   
1251   
1252   g_print ("checking g_strdup_printf...");
1253   string = g_strdup_printf ("%05d %-5s", 21, "test");
1254   g_assert (string != NULL);
1255   g_assert (strcmp(string, "00021 test ") == 0);
1256   g_free (string);
1257
1258   g_print ("ok\n");
1259
1260   /* g_debug (argv[0]); */
1261
1262   /* Relation tests */
1263
1264   g_print ("checking relations...");
1265
1266   relation = g_relation_new (2);
1267
1268   g_relation_index (relation, 0, g_int_hash, g_int_equal);
1269   g_relation_index (relation, 1, g_int_hash, g_int_equal);
1270
1271   for (i = 0; i < 1024; i += 1)
1272     data[i] = i;
1273
1274   for (i = 1; i < 1023; i += 1)
1275     {
1276       g_relation_insert (relation, data + i, data + i + 1);
1277       g_relation_insert (relation, data + i, data + i - 1);
1278     }
1279
1280   for (i = 2; i < 1022; i += 1)
1281     {
1282       g_assert (! g_relation_exists (relation, data + i, data + i));
1283       g_assert (! g_relation_exists (relation, data + i, data + i + 2));
1284       g_assert (! g_relation_exists (relation, data + i, data + i - 2));
1285     }
1286
1287   for (i = 1; i < 1023; i += 1)
1288     {
1289       g_assert (g_relation_exists (relation, data + i, data + i + 1));
1290       g_assert (g_relation_exists (relation, data + i, data + i - 1));
1291     }
1292
1293   for (i = 2; i < 1022; i += 1)
1294     {
1295       g_assert (g_relation_count (relation, data + i, 0) == 2);
1296       g_assert (g_relation_count (relation, data + i, 1) == 2);
1297     }
1298
1299   g_assert (g_relation_count (relation, data, 0) == 0);
1300
1301   g_assert (g_relation_count (relation, data + 42, 0) == 2);
1302   g_assert (g_relation_count (relation, data + 43, 1) == 2);
1303   g_assert (g_relation_count (relation, data + 41, 1) == 2);
1304   g_relation_delete (relation, data + 42, 0);
1305   g_assert (g_relation_count (relation, data + 42, 0) == 0);
1306   g_assert (g_relation_count (relation, data + 43, 1) == 1);
1307   g_assert (g_relation_count (relation, data + 41, 1) == 1);
1308
1309   tuples = g_relation_select (relation, data + 200, 0);
1310
1311   g_assert (tuples->len == 2);
1312
1313 #if 0
1314   for (i = 0; i < tuples->len; i += 1)
1315     {
1316       printf ("%d %d\n",
1317               *(gint*) g_tuples_index (tuples, i, 0),
1318               *(gint*) g_tuples_index (tuples, i, 1));
1319     }
1320 #endif
1321
1322   g_assert (g_relation_exists (relation, data + 300, data + 301));
1323   g_relation_delete (relation, data + 300, 0);
1324   g_assert (!g_relation_exists (relation, data + 300, data + 301));
1325
1326   g_tuples_destroy (tuples);
1327
1328   g_relation_destroy (relation);
1329
1330   relation = NULL;
1331
1332   g_print ("ok\n");
1333
1334   g_print ("checking pointer arrays...");
1335
1336   gparray = g_ptr_array_new ();
1337   for (i = 0; i < 10000; i++)
1338     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
1339
1340   for (i = 0; i < 10000; i++)
1341     if (g_ptr_array_index (gparray, i) != GINT_TO_POINTER (i))
1342       g_print ("array fails: %p ( %p )\n", g_ptr_array_index (gparray, i), GINT_TO_POINTER (i));
1343
1344   g_ptr_array_free (gparray, TRUE);
1345
1346   g_print ("ok\n");
1347
1348
1349   g_print ("checking byte arrays...");
1350
1351   gbarray = g_byte_array_new ();
1352   for (i = 0; i < 10000; i++)
1353     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1354
1355   for (i = 0; i < 10000; i++)
1356     {
1357       g_assert (gbarray->data[4*i] == 'a');
1358       g_assert (gbarray->data[4*i+1] == 'b');
1359       g_assert (gbarray->data[4*i+2] == 'c');
1360       g_assert (gbarray->data[4*i+3] == 'd');
1361     }
1362
1363   g_byte_array_free (gbarray, TRUE);
1364   g_print ("ok\n");
1365
1366   g_printerr ("g_log tests:");
1367   g_warning ("harmless warning with parameters: %d %s %#x", 42, "Boo", 12345);
1368   g_message ("the next warning is a test:");
1369   string = NULL;
1370   g_print (string);
1371   g_message ("non-printable UTF-8: \"\xc3\xa4\xda\x85\"");
1372   g_message ("unsafe chars: \"\x10\x11\x12\n\t\x7f\x81\x82\x83\"");
1373
1374   g_print ("checking endian macros (host is ");
1375 #if G_BYTE_ORDER == G_BIG_ENDIAN
1376   g_print ("big endian)...");
1377 #else
1378   g_print ("little endian)...");
1379 #endif
1380   g_assert (GUINT16_SWAP_LE_BE (gu16t1) == gu16t2);  
1381   g_assert (GUINT32_SWAP_LE_BE (gu32t1) == gu32t2);  
1382   g_assert (GUINT64_SWAP_LE_BE (gu64t1) == gu64t2);  
1383
1384   g_print ("ok\n");
1385
1386   if (g_get_charset ((G_CONST_RETURN char**)&charset))
1387     g_print ("current charset is UTF-8: %s\n", charset);
1388   else
1389     g_print ("current charset is not UTF-8: %s\n", charset);
1390
1391 #ifdef G_PLATFORM_WIN32
1392   g_print ("current locale: %s\n", g_win32_getlocale ());
1393   g_print ("GLib DLL name tested for: %s\n", glib_dll);
1394
1395   g_print ("GLib installation directory, from Registry entry for %s if available: %s\n",
1396            GETTEXT_PACKAGE,
1397            g_win32_get_package_installation_directory (GETTEXT_PACKAGE, NULL));
1398   g_print ("Ditto, or from GLib DLL name: %s\n",
1399            g_win32_get_package_installation_directory (GETTEXT_PACKAGE, glib_dll));
1400   g_print ("Ditto, only from GLib DLL name: %s\n",
1401            g_win32_get_package_installation_directory (NULL, glib_dll));
1402   g_print ("locale subdirectory of GLib installation directory: %s\n",
1403            g_win32_get_package_installation_subdirectory (NULL, glib_dll, "lib\\locale"));
1404   g_print ("GTK+ 2.0 installation directory, if available: %s\n",
1405            g_win32_get_package_installation_directory ("gtk20", NULL));
1406
1407   g_print ("found more.com as %s\n", g_find_program_in_path ("more.com"));
1408   g_print ("found regedit as %s\n", g_find_program_in_path ("regedit"));
1409
1410   g_print ("a Win32 error message: %s\n", g_win32_error_message (2));
1411
1412 #endif
1413
1414   g_print ("checking file functions...\n");
1415
1416   strcpy (template, "foobar");
1417   fd = g_mkstemp (template);
1418   if (fd != -1)
1419     g_print ("g_mkstemp works even if template doesn't end in XXXXXX\n");
1420   close (fd);
1421   strcpy (template, "fooXXXXXX");
1422   fd = g_mkstemp (template);
1423   if (fd == -1)
1424     g_print ("g_mkstemp didn't work for template %s\n", template);
1425   i = write (fd, hello, hellolen);
1426   if (i == -1)
1427     g_print ("write() failed: %s\n", g_strerror (errno));
1428   else if (i != hellolen)
1429     g_print ("write() should have written %d bytes, wrote %d\n", hellolen, i);
1430
1431   lseek (fd, 0, 0);
1432   i = read (fd, chars, sizeof (chars));
1433   if (i == -1)
1434     g_print ("read() failed: %s\n", g_strerror (errno));
1435   else if (i != hellolen)
1436     g_print ("read() should have read %d bytes, got %d\n", hellolen, i);
1437
1438   chars[i] = 0;
1439   if (strcmp (chars, hello) != 0)
1440     g_print ("wrote '%s', but got '%s'\n", hello, chars);
1441
1442   close (fd);
1443   remove (template);
1444
1445   error = NULL;
1446   strcpy (template, "zap" G_DIR_SEPARATOR_S "barXXXXXX");
1447   fd = g_file_open_tmp (template, &name_used, &error);
1448   if (fd != -1)
1449     g_print ("g_file_open_tmp works even if template contains '%s'\n",
1450              G_DIR_SEPARATOR_S);
1451   else
1452     g_print ("g_file_open_tmp correctly returns error: %s\n",
1453              error->message);
1454   close (fd);
1455   g_clear_error (&error);
1456
1457 #ifdef G_OS_WIN32
1458   strcpy (template, "zap/barXXXXXX");
1459   fd = g_file_open_tmp (template, &name_used, &error);
1460   if (fd != -1)
1461     g_print ("g_file_open_tmp works even if template contains '/'\n");
1462   else
1463     g_print ("g_file_open_tmp correctly returns error: %s\n",
1464              error->message);
1465   close (fd);
1466   g_clear_error (&error);
1467 #endif
1468
1469   strcpy (template, "zapXXXXXX");
1470   fd = g_file_open_tmp (template, &name_used, &error);
1471   if (fd == -1)
1472     g_print ("g_file_open_tmp didn't work for template '%s': %s\n",
1473              template, error->message);
1474   else
1475     g_print ("g_file_open_tmp for template '%s' used name '%s'\n",
1476              template, name_used);
1477   close (fd);
1478   g_clear_error (&error);
1479   remove (name_used);
1480
1481   fd = g_file_open_tmp (NULL, &name_used, &error);
1482   if (fd == -1)
1483     g_print ("g_file_open_tmp didn't work for a NULL template: %s\n",
1484              error->message);
1485   else
1486     g_print ("g_file_open_tmp for NULL template used name '%s'\n",
1487              name_used);
1488   close (fd);
1489   g_clear_error (&error);
1490   remove (name_used);
1491   
1492   return 0;
1493 }
1494