glib_compat: lift string functions from glib. remove unused API g_win32_error_message()
This commit is contained in:
parent
c5b8fbfbc6
commit
520f335a2a
@ -24,11 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#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.
|
||||
*
|
||||
* <warning><para>The variable argument list <emphasis>must</emphasis> end
|
||||
* with %NULL. If you forget the %NULL, g_strconcat() will start appending
|
||||
* random memory junk to your string.</para></warning>
|
||||
*
|
||||
* 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 <windows.h>
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user