diff --git a/qemu/glib_compat.c b/qemu/glib_compat.c index 80e1d50f..955b2c1c 100644 --- a/qemu/glib_compat.c +++ b/qemu/glib_compat.c @@ -24,11 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include #include "glib_compat.h" #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define GPOINTER_TO_UINT(p) ((guint) (gulong) (p)) +#define G_MAXINT INT_MAX /* All functions below added to eliminate GLIB dependency */ @@ -1312,7 +1314,25 @@ gpointer g_renew_(size_t sz, gpointer mem, size_t n_structs) return g_realloc(mem, need); } -char *g_strconcat (const char *string1, ...) +/** + * g_strconcat: + * @string1: the first string to add, which must not be %NULL + * @Varargs: a %NULL-terminated list of strings to append to the string + * + * Concatenates all of the given strings into one long string. + * The returned string should be freed with g_free() when no longer needed. + * + * Note that this function is usually not the right function to use to + * assemble a translated message from pieces, since proper translation + * often requires the pieces to be reordered. + * + * The variable argument list must end + * with %NULL. If you forget the %NULL, g_strconcat() will start appending + * random memory junk to your string. + * + * Returns: a newly-allocated string containing all the string arguments + */ +gchar* g_strconcat (const gchar *string1, ...) { va_list ap; char *res; @@ -1336,64 +1356,76 @@ char *g_strconcat (const char *string1, ...) return res; } -char **g_strsplit(const char *string, const char *delimiter, int max_tokens) +/** + * g_strsplit: + * @string: a string to split. + * @delimiter: a string which specifies the places at which to split the string. + * The delimiter is not included in any of the resulting strings, unless + * @max_tokens is reached. + * @max_tokens: the maximum number of pieces to split @string into. If this is + * less than 1, the string is split completely. + * + * Splits a string into a maximum of @max_tokens pieces, using the given + * @delimiter. If @max_tokens is reached, the remainder of @string is appended + * to the last token. + * + * As a special case, the result of splitting the empty string "" is an empty + * vector, not a vector containing a single string. The reason for this + * special case is that being able to represent a empty vector is typically + * more useful than consistent handling of empty elements. If you do need + * to represent empty elements, you'll need to check for the empty string + * before calling g_strsplit(). + * + * Return value: a newly-allocated %NULL-terminated array of strings. Use + * g_strfreev() to free it. + **/ +gchar** g_strsplit (const gchar *string, + const gchar *delimiter, + gint max_tokens) { - char **res; - if (string == NULL || *string == 0) { - res = (char**)g_malloc(sizeof(char*)); - *res = NULL; - } else { - uint32_t ntokens, i, max = (uint32_t) max_tokens; - if (max == 0) max--; - int dlen = strlen(delimiter); - const char *p = string, *b; - for (ntokens = 1; ntokens < max; ntokens++) { - p = strstr(p, delimiter); - if (p == NULL) break; - p += dlen; - } - res = (char**)g_new_(sizeof(char*), ntokens + 1); - p = string; - for (b = p, i = 0; i < ntokens; b = p, i++) { - int len; - if (i == (ntokens - 1)) { - /* last piece special handling */ - res[i] = strdup(b); - } else { - p = strstr(b, delimiter); - len = p - b; - res[i] = (char*)g_malloc(len + 1); - memcpy(res[i], b, len); - res[i][len] = 0; - p += dlen; - } - } - res[ntokens] = NULL; - } - return res; + GSList *string_list = NULL, *slist; + gchar **str_array, *s; + guint n = 0; + const gchar *remainder; + + if (string == NULL) return NULL; + if (delimiter == NULL) return NULL; + if (delimiter[0] == '\0') return NULL; + + if (max_tokens < 1) + max_tokens = G_MAXINT; + + remainder = string; + s = strstr (remainder, delimiter); + if (s) + { + gsize delimiter_len = strlen (delimiter); + + while (--max_tokens && s) + { + gsize len; + + len = s - remainder; + string_list = g_slist_prepend (string_list, + g_strndup (remainder, len)); + n++; + remainder = s + delimiter_len; + s = strstr (remainder, delimiter); + } + } + if (*string) + { + n++; + string_list = g_slist_prepend (string_list, g_strdup (remainder)); + } + + str_array = g_new (gchar*, n + 1); + + str_array[n--] = NULL; + for (slist = string_list; slist; slist = slist->next) + str_array[n--] = slist->data; + + g_slist_free (string_list); + + return str_array; } - -#ifdef _WIN32 - -#include - -char *g_win32_error_message(int error) -{ - char *msg; - char *winMsg = NULL; - if (error == 0) { - return (char*)g_malloc0(1); - } - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL); - - /* give the caller something they can just free */ - msg = strdup(winMsg); - /* Free the allocated message. */ - HeapFree(GetProcessHeap(), 0, winMsg); - - return msg; -} - -#endif diff --git a/qemu/include/glib_compat.h b/qemu/include/glib_compat.h index b8bb9207..2ffa772d 100644 --- a/qemu/include/glib_compat.h +++ b/qemu/include/glib_compat.h @@ -45,6 +45,7 @@ typedef unsigned int guint; typedef char gchar; typedef int gboolean; typedef unsigned long gulong; +typedef unsigned long gsize; typedef gint (*GCompareDataFunc)(gconstpointer a, gconstpointer b, @@ -121,16 +122,14 @@ gpointer g_memdup(gconstpointer mem, size_t byte_size); gpointer g_new_(size_t sz, size_t n_structs); gpointer g_new0_(size_t sz, size_t n_structs); gpointer g_renew_(size_t sz, gpointer mem, size_t n_structs); -char *g_strconcat(const char *string1, ...); +gchar* g_strconcat (const gchar *string1, ...); +gchar** g_strsplit (const gchar *string, + const gchar *delimiter, + gint max_tokens); -char **g_strsplit(const char *string, const char *delimiter, int max_tokens); #define g_new(struct_type, n_structs) ((struct_type*)g_new_(sizeof(struct_type), n_structs)) #define g_new0(struct_type, n_structs) ((struct_type*)g_new0_(sizeof(struct_type), n_structs)) #define g_renew(struct_type, mem, n_structs) ((struct_type*)g_renew_(sizeof(struct_type), mem, n_structs)) -#ifdef _WIN32 -char *g_win32_error_message(int error); -#endif - #endif diff --git a/qemu/include/qapi/error.h b/qemu/include/qapi/error.h index d712089f..f73dd58b 100644 --- a/qemu/include/qapi/error.h +++ b/qemu/include/qapi/error.h @@ -38,16 +38,6 @@ void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) void error_set_errno(Error **errp, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5); -#ifdef _WIN32 -/** - * Set an indirect pointer to an error given a ErrorClass value and a - * printf-style human message, followed by a g_win32_error_message() string if - * @win32_err is not zero. - */ -void error_set_win32(Error **errp, int win32_err, ErrorClass err_class, - const char *fmt, ...) GCC_FMT_ATTR(4, 5); -#endif - /** * Same as error_set(), but sets a generic error */ @@ -56,11 +46,6 @@ void error_set_win32(Error **errp, int win32_err, ErrorClass err_class, #define error_setg_errno(errp, os_error, fmt, ...) \ error_set_errno(errp, os_error, ERROR_CLASS_GENERIC_ERROR, \ fmt, ## __VA_ARGS__) -#ifdef _WIN32 -#define error_setg_win32(errp, win32_err, fmt, ...) \ - error_set_win32(errp, win32_err, ERROR_CLASS_GENERIC_ERROR, \ - fmt, ## __VA_ARGS__) -#endif /** * Helper for open() errors diff --git a/qemu/util/error.c b/qemu/util/error.c index 9c49facb..7dc0bcc4 100644 --- a/qemu/util/error.c +++ b/qemu/util/error.c @@ -88,46 +88,6 @@ void error_setg_file_open(Error **errp, int os_errno, const char *filename) error_setg_errno(errp, os_errno, "Could not open '%s'", filename); } -#ifdef _WIN32 - -void error_set_win32(Error **errp, int win32_err, ErrorClass err_class, - const char *fmt, ...) -{ - Error *err; - char *msg1; - va_list ap; - - if (errp == NULL) { - return; - } - assert(*errp == NULL); - - err = g_malloc0(sizeof(*err)); - - va_start(ap, fmt); - msg1 = g_strdup_vprintf(fmt, ap); - if (win32_err != 0) { - char *msg2 = g_win32_error_message(win32_err); - err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2, - (unsigned)win32_err); - g_free(msg2); - g_free(msg1); - } else { - err->msg = msg1; - } - va_end(ap); - err->err_class = err_class; - - if (errp == &error_abort) { - // error_report("%s", error_get_pretty(err)); - abort(); - } - - *errp = err; -} - -#endif - Error *error_copy(const Error *err) { Error *err_new;