+2006-08-16 Miguel de Icaza <miguel@novell.com>
+
+ * src/Makefile.am: Added -Wall,-Werror, corrected lots of
+ mistakes.
+
+ * src/gstring.c: Gstring implementation.
+
+ * test/str.c (test_gstring): string tests.
+
2006-08-16 Aaron Bockover <abockover@novell.com>
* src/gstr.c: Added g_strsplit implementation
--- /dev/null
+
+* Code that we will drop from Mono, because we do not really need this:
+
+ Directory, File manipulation:
+
+ g_dir_open, g_dir_close, g_dir_read_name,
+ G_FILE_ERROR_*
+
+ These will be replaced in io-layer with direct Unix calls.
+
+ These will be replaced in metadata with two code paths, native
+ Unix and native Windows.
+
+ g_unichar_
+
+ We probably do not need these anymore, we should kill the unmanaged
+ string collation and just leave the unmanaged string collation in
+ place.
+
+Routines missing from eglib, by count number:
+
+ 103 g_string_sprintfa
+ 82 g_list_prepend
+ 59 g_list_free
+ 54 g_string_append_c
+ 49 g_string_new
+ 49 g_string_free
+ 36 g_ptr_array_index
+ 31 g_string_append_printf
+ 29 g_getenv
+ 28 g_module_symbol
+ 28 g_list_append
+ 27 g_build_filename
+ 25 g_slist_free
+ 24 g_utf16_to_utf8
+ 22 g_strsplit
+ 22 g_list_length
+ 21 g_snprintf
+ 21 g_slist_prepend
+ 21 g_ptr_array_free
+ 21 g_ptr_array_add
+ 20 g_utf8_to_utf16
+ 17 g_ptr_array_new
+ 16 g_list_delete_link
+ 15 g_list_remove
+ 14 g_memdup
+ 14 g_list_find
+ 13 g_error_free
+ 12 g_build_path
+ 11 g_module_open
+ 11 g_file_test
+ 10 g_strlcpy
+ 10 g_slist_append
+ 10 g_path_get_dirname
+ 10 g_ascii_xdigit_value
+ 10 g_ascii_isspace
+ 10 g_array_index
+ 9 g_path_get_basename
+ 8 g_module_error
+ 8 g_get_home_dir
+ 8 g_ascii_strncasecmp
+ 7 g_strcasecmp
+ 7 g_slist_remove
+ 7 g_slist_next
+ 7 g_list_reverse
+ 6 g_strstrip
+ 6 g_slist_find
+ 6 g_renew
+ 6 g_memmove
+ 6 g_io_channel_unix_get_fd
+ 5 g_timer_elapsed
+ 5 g_ptr_array_sort
+ 5 g_path_is_absolute
+ 5 g_newa
+ 5 g_module_build_path
+ 5 g_list_first
+ 5 g_get_current_dir
+ 5 g_file_get_contents
+ 5 g_ascii_strcasecmp
+ 4 g_unsetenv
+ 4 g_strdown
+ 4 g_slist_length
+ 4 g_get_tmp_dir
+ 3 g_utf8_validate
+ 3 g_thread_supported
+ 3 g_thread_init
+ 3 g_spaced_primes_closest
+ 3 g_slist_insert_sorted
+ 3 g_shell_quote
+ 3 g_setenv
+ 3 g_locale_to_utf8
+ 3 g_list_prepend_mempool
+ 3 g_list_next
+ 3 g_list_insert_sorted
+ 3 g_list_insert_before
+ 3 g_list_foreach
+ 3 g_file_open_tmp
+ 3 g_convert
+ 3 g_array_new
+ 3 g_array_free
+ 2 g_timer_stop
+ 2 g_timer_start
+ 2 g_timer_new
+ 2 g_strreverse
+ 2 g_string_printf
+ 2 g_string_append_len
+ 2 g_strdelimit
+ 2 g_slist_remove_link
+ 2 g_slist_append_mempool
+ 2 g_slist_alloc
+ 2 g_shell_parse_argv
+ 2 g_set_prgname
+ 2 g_queue_pop_head
+ 2 g_queue_is_empty
+ 2 g_ptr_array_set_size
+ 2 g_ptr_array_remove
+ 2 g_printerr
+ 2 g_pattern_spec_new
+ 2 g_pattern_spec_free
+ 2 g_pattern_match_string
+ 2 g_markup_parse_context_parse
+ 2 g_markup_parse_context_new
+ 2 g_markup_parse_context_free
+ 2 g_markup_parse_context_end_parse
+ 2 g_list_sort
+ 2 g_list_index
+ 2 g_get_current_time
+ 2 g_find_program_in_path
+ 2 g_filename_to_uri
+ 2 g_filename_from_uri
+ 2 g_concat_dir_and_file
+ 2 g_atexit
+ 2 g_ascii_isalpha
+ 2 g_array_insert_val
+ 2 g_array_append_val
+ 2 g_alloca
+ 1 g_win32_getlocale
+ 1 g_timer_destroy
+ 1 g_strjoin
+ 1 g_string_truncate
+ 1 g_string_sized_new
+ 1 g_string_prepend
+ 1 g_string_new_len
+ 1 g_strescape
+ 1 g_strchug
+ 1 g_spawn_command_line_sync
+ 1 g_spawn_async_with_pipes
+ 1 g_source_unref
+ 1 g_source_set_callback
+ 1 g_source_remove
+ 1 g_source_attach
+ 1 g_slist_reverse
+ 1 g_slist_free_1
+ 1 g_slist_delete_link
+ 1 g_shell_unquote
+ 1 g_queue_push_head
+ 1 g_queue_new
+ 1 g_queue_free
+ 1 g_module_close
+ 1 g_mem_set_vtable
+ 1 g_main_loop_run
+ 1 g_main_context_new
+ 1 g_main_context_iteration
+ 1 g_log_set_handler
+ 1 g_locale_from_utf8
+ 1 g_list_remove_link
+ 1 g_list_nth
+ 1 g_list_copy
+ 1 g_io_create_watch
+ 1 g_io_channel_unref
+ 1 g_io_channel_unix_new
+ 1 g_io_channel_shutdown
+ 1 g_io_channel_set_encoding
+ 1 g_io_channel_set_buffered
+ 1 g_io_channel_get_buffer_condition
+ 1 g_io_add_watch
+ 1 g_get_user_name
+ 1 g_get_prgname
+ 1 g_get_charset
+ 1 g_filename_from_utf8
+ 1 g_bit_nth_msf
+ 1 g_ascii_strdown
+ 1 g_ascii_isprint
+ 1 g_array_remove_index
+
+Macros:
+ 124 G_GNUC_PRETTY_FUNCTION
+ 40 G_GSIZE_FORMAT
+ 40 G_GNUC_UNUSED
+ 20 G_LITTLE_ENDIAN
+ 16 G_DIR_SEPARATOR_S
+ 12 G_BREAKPOINT
+ 11 G_MODULE_BIND_LAZY
+ 10 G_STMT_START
+ 10 G_STMT_END
+ 9 G_GUINT64_FORMAT
+ 7 G_FILE_TEST_IS_DIR
+ 6 G_UNLIKELY
+ 6 G_HASH_TABLE_RESIZE
+ 6 G_DIR_SEPARATOR
+ 5 G_UNLOCK
+ 5 G_LOCK
+ 4 G_LIKELY
+ 4 G_GNUC_NORETURN
+ 4 G_FILE_TEST_IS_REGULAR
+ 3 G_SEARCHPATH_SEPARATOR_S
+ 2 G_USEC_PER_SEC
+ 2 G_STRLOC
+ 2 G_IO_NVAL
+ 2 G_BIG_ENDIAN
+ 1 G_SPAWN_SEARCH_PATH
+ 1 G_IO_PRI
+ 1 G_ALLOC_ONLY
+
+Unlikely that we will implement:
+
+ 2 g_unichar_type
+ 2 g_unichar_tolower
libeglib_la_SOURCES = \
ghashtable.c \
goutput.c \
- gstr.c
+ gstr.c \
+ gstring.c
+
+libeglib_la_CFLAGS = -Wall -Werror
INCLUDES = -I$(srcdir)
static void
adjust_threshold (GHashTable *hash)
{
- int size = hash->table_size;
-
hash->threshold = (int) hash->table_size * 0.75;
if (hash->threshold >= hash->table_size)
hash->threshold = hash->table_size-1;
hash->threshold = 1;
}
-static void
-set_table (GHashTable *hash, Slot **table)
-{
- hash->table = table;
- adjust_threshold (hash);
-}
-
GHashTable *
g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
{
guint
g_hash_table_size (GHashTable *hash)
{
- g_return_if_fail (hash != NULL);
+ g_return_val_if_fail (hash != NULL, 0);
return hash->in_use;
}
Slot *s;
guint hashcode;
- g_return_if_fail (hash != NULL);
+ g_return_val_if_fail (hash != NULL, FALSE);
equal = hash->key_equal_func;
hashcode = ((*hash->hash_func) (key)) % hash->table_size;
{
int i;
- g_return_if_fail (hash != NULL);
- g_return_if_fail (predicate != NULL);
+ g_return_val_if_fail (hash != NULL, NULL);
+ g_return_val_if_fail (predicate != NULL, NULL);
for (i = 0; i < hash->table_size; i++){
Slot *s;
for (s = hash->table [i]; s != NULL; s = s->next)
if ((*predicate)(s->key, s->value, user_data))
- return;
+ return s->value;
}
+ return NULL;
}
gboolean
}
if (count > 0)
rehash (hash);
+ return count;
}
void
gboolean g_str_equal (gconstpointer v1, gconstpointer v2);
guint g_str_hash (gconstpointer v1);
-#define g_assert(x) do { fprintf (stderr, "* Assertion at %s:%d, condition `%s' not met\n", __FILE__, __LINE__, #x); abort (); } while (0)
-#define g_assert_not_reached() do { fprintf (stderr, "* This line should not be reached at %s:%d\n", __FILE__, __LINE__); } while (0)
+#define g_assert(x) do { if (!(x)) g_error ("* Assertion at %s:%d, condition `%s' not met\n", __FILE__, __LINE__, #x); } while (0)
+#define g_assert_not_reached() do { g_error ("* Assertion: should not be reached at %s:%d\n", __FILE__, __LINE__); } while (0)
/*
- * Strings
+ * Strings utility
*/
-gchar *g_strdup_printf (const gchar *format, ...);
-gchar *g_strndup (const gchar *str, gsize n);
-const gchar *g_strerror (gint errnum);
-gchar *g_strndup (const gchar *str, gsize n);
-void g_strfreev (gchar **str_array);
-gchar *g_strconcat (const gchar *first, ...);
-
+gchar *g_strdup_printf (const gchar *format, ...);
+gchar *g_strdup_vprintf (const gchar *format, va_list args);
+gchar *g_strndup (const gchar *str, gsize n);
+const gchar *g_strerror (gint errnum);
+gchar *g_strndup (const gchar *str, gsize n);
+void g_strfreev (gchar **str_array);
+gchar *g_strconcat (const gchar *first, ...);
+gchar **g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens);
+/*
+ * String type
+ */
+typedef struct {
+ char *str;
+ gsize len;
+ gsize allocated_len;
+} GString;
+
+GString *g_string_new (const gchar *init);
+GString *g_string_new_len (const gchar *init, gsize len);
+GString *g_string_sized_new (gsize default_size);
+gchar *g_string_free (GString *string, gboolean free_segment);
+GString *g_string_append (GString *string, const gchar *val);
+void g_string_printf (GString *string, const gchar *format, ...);
+void g_string_append_printf (GString *string, const gchar *format, ...);
+GString *g_string_append_c (GString *string, gchar c);
+GString *g_string_append (GString *string, const gchar *val);
+
+#define g_string_sprintfa g_string_append_printf
/*
* Messages
*/
* if we decide to set G_LOG_DOMAIN (we probably should) we should implement
* this.
*/
+ return fatal_mask;
}
void
log_domain != NULL ? log_domain : "",
log_domain != NULL ? ": " : "",
format);
- g_free (format);
if (log_level & fatal)
abort ();
}
g_free (orig);
}
+gchar *
+g_strdup_vprintf (const gchar *format, va_list args)
+{
+ int n;
+ char *ret;
+
+ n = vasprintf (&ret, format, args);
+ if (n == -1)
+ return NULL;
+
+ return ret;
+}
+
gchar *
g_strdup_printf (const gchar *format, ...)
{
#include <stdio.h>
#include <glib.h>
+GString *
+g_string_new (const gchar *init)
+{
+ GString *ret = g_new (GString, 1);
+ int len, alloc;
+
+ len = strlen (init);
+ if (len < 15)
+ alloc = 16;
+ else
+ alloc = len+1;
+ ret->str = g_malloc (alloc);
+ ret->len = len;
+ ret->allocated_len = alloc;
+ strcpy (ret->str, init);
+
+ return ret;
+}
+
+GString *
+g_string_new_len (const gchar *init, gsize len)
+{
+ GString *ret = g_new (GString, 1);
+
+ ret->str = g_malloc (len+1);
+ ret->allocated_len = len + 1;
+ ret->len = len;
+
+ memcpy (ret->str, init, len);
+ ret->str [len] = 0;
+
+ return ret;
+}
+
+GString *
+g_string_sized_new (gsize default_size)
+{
+ GString *ret = g_new (GString, 1);
+
+ ret->str = g_malloc (default_size);
+ ret->str [0] = 0;
+ ret->len = 0;
+ ret->allocated_len = default_size;
+
+ return ret;
+}
+
gchar *
-g_strdup_printf (const gchar *format, ...)
+g_string_free (GString *string, gboolean free_segment)
+{
+ char *data;
+ g_return_val_if_fail (string != NULL, NULL);
+
+ data = string->str;
+ if (free_segment)
+ g_free (data);
+ g_free (string);
+
+ if (free_segment)
+ return NULL;
+ else
+ return data;
+
+}
+
+GString *
+g_string_append (GString *string, const gchar *val)
+{
+ int len, size;
+ char *new;
+
+ g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (val != NULL, string);
+
+ len = strlen (val);
+ if ((string->len + len) < string->allocated_len){
+ strcat (string->str, val);
+ string->len += len;
+ return string;
+ }
+ size = (len + string->len + 16) * 2;
+ new = g_malloc (size);
+ memcpy (new, string->str, string->len);
+ memcpy (new + string->len, val, len);
+ g_free (string->str);
+ string->str = new;
+ string->allocated_len = size;
+ string->len += len;
+ new [string->len] = 0;
+
+ return string;
+}
+
+GString *
+g_string_append_c (GString *string, gchar c)
+{
+ gsize size;
+ char *new;
+
+ g_return_val_if_fail (string != NULL, NULL);
+
+ if (string->len + 1 < string->allocated_len){
+ string->str [string->len] = c;
+ string->str [string->len+1] = 0;
+ string->len++;
+ return string;
+ }
+ size = (string->allocated_len + 16) * 2;
+ new = g_malloc (size);
+ memcpy (new, string->str, string->len);
+ new [string->len] = c;
+ new [string->len+1] = 0;
+
+ g_free (string->str);
+ string->allocated_len = size;
+ string->len++;
+ string->str = new;
+
+ return string;
+}
+
+GString *
+g_string_append_len (GString *string, const gchar *val, gsize len)
+{
+ int size;
+ char *new;
+
+ g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (val != NULL, string);
+
+ if ((string->len + len) < string->allocated_len){
+ memcpy (string->str+string->len, val, len);
+ string->len += len;
+ return string;
+ }
+ size = (len + string->len + 16) * 2;
+ new = g_malloc (size);
+ memcpy (new, string->str, string->len);
+ memcpy (new + string->len, val, len);
+ g_free (string->str);
+ string->str = new;
+ string->allocated_len = size;
+ string->len += len;
+ new [string->len] = 0;
+
+ return string;
+}
+
+void
+g_string_append_printf (GString *string, const gchar *format, ...)
{
- gchar *ret;
+ char *ret;
va_list args;
- int n;
+
+ g_return_if_fail (string != NULL);
+ g_return_if_fail (format != NULL);
va_start (args, format);
- n = vasprintf (&ret, format, args);
+ ret = g_strdup_vprintf (format, args);
va_end (args);
- if (n == -1)
- return NULL;
+ g_string_append (string, ret);
- return ret;
+ free (ret);
+}
+
+void
+g_string_printf (GString *string, const gchar *format, ...)
+{
+ va_list args;
+
+ g_return_if_fail (string != NULL);
+ g_return_if_fail (format != NULL);
+
+ g_free (string->str);
+
+ va_start (args, format);
+ string->str = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ string->len = strlen (string->str);
+ string->allocated_len = string->len+1;
}
test ("s-freev", test_strfreev);
test ("s-concat", test_concat);
test ("s-split", test_split);
+ test ("s-gstring", test_gstring);
}
#include <glib.h>
+#include <stdio.h>
/* This test is just to be used with valgrind */
char *
return NULL;
}
+#define sfail(k,p) if (s->str [p] != k) return g_strdup_printf ("Failed at %d, expected '%c'", p, k);
+
+char *
+test_gstring ()
+{
+ GString *s = g_string_new_len ("My stuff", 2);
+ char *ret;
+ int i;
+
+ if (strcmp (s->str, "My") != 0)
+ return "Expected only 'My' on the string";
+ g_string_free (s, TRUE);
+
+ s = g_string_new_len ("My\0\0Rest", 6);
+ if (s->str [2] != 0)
+ return "Null was not copied";
+ if (strcmp (s->str+4, "Re") != 0){
+ return "Did not find the 'Re' part";
+ }
+
+ g_string_append (s, "lalalalalalalalalalalalalalalalalalalalalalal");
+ if (s->str [2] != 0)
+ return "Null as not copied";
+ if (strncmp (s->str+4, "Relala", 6) != 0){
+ printf ("got: %s\n", s->str+4);
+ return "Did not copy correctly";
+ }
+
+ g_string_free (s, TRUE);
+ s = g_string_new ("");
+ for (i = 0; i < 1024; i++){
+ g_string_append (s, "x");
+ }
+ if (strlen (s->str) != 1024){
+ printf ("got: %s %d\n", s->str, strlen (s->str));
+ return "Incorrect string size";
+ }
+ g_string_free (s, TRUE);
+
+ s = g_string_new ("");
+ for (i = 0; i < 1024; i++){
+ g_string_append_c (s, 'x');
+ }
+ if (strlen (s->str) != 1024){
+ printf ("got: %s %d\n", s->str, strlen (s->str));
+ return "Incorrect string size";
+ }
+ g_string_free (s, TRUE);
+
+ s = g_string_new ("hola");
+ g_string_sprintfa (s, "%s%d", ", bola", 5);
+ if (strcmp (s->str, "hola, bola5") != 0){
+ printf ("got: %s\n", s->str);
+ return "Got incorrect data";
+ }
+ g_string_free (s, TRUE);
+
+ s = g_string_new ("Hola");
+ g_string_printf (s, "Dingus");
+
+ /* Test that it does not release it */
+ ret = g_string_free (s, FALSE);
+ g_free (ret);
+
+ s = g_string_new ("H\0y");
+ g_string_append_len (s, "1\02", 3);
+ printf ("got: %s\n", s->str);
+ sfail ('H', 0);
+ sfail (0, 1);
+ sfail ('y', 2);
+ sfail ('1', 3);
+ sfail (0, 4);
+ sfail ('2', 5);
+ g_string_free (s, TRUE);
+
+ return NULL;
+}
+
char *
test_split ()
{
g_strfreev(v);
return NULL;
}
-