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 | /* |
---|
28 | * MT safe |
---|
29 | */ |
---|
30 | |
---|
31 | #include "config.h" |
---|
32 | |
---|
33 | #define _GNU_SOURCE /* For stpcpy */ |
---|
34 | |
---|
35 | #include <stdarg.h> |
---|
36 | #include <stdio.h> |
---|
37 | #include <stdlib.h> |
---|
38 | #include <string.h> |
---|
39 | #include <locale.h> |
---|
40 | #include <errno.h> |
---|
41 | #include <ctype.h> /* For tolower() */ |
---|
42 | #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL) |
---|
43 | #include <signal.h> |
---|
44 | #endif |
---|
45 | |
---|
46 | #include "glib.h" |
---|
47 | #include "gprintfint.h" |
---|
48 | |
---|
49 | #ifdef G_OS_WIN32 |
---|
50 | #include <windows.h> |
---|
51 | #endif |
---|
52 | |
---|
53 | /* do not include <unistd.h> in this place since it |
---|
54 | * inteferes with g_strsignal() on some OSes |
---|
55 | */ |
---|
56 | |
---|
57 | static const guint16 ascii_table_data[256] = { |
---|
58 | 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
---|
59 | 0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004, |
---|
60 | 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
---|
61 | 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, |
---|
62 | 0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, |
---|
63 | 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, |
---|
64 | 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, |
---|
65 | 0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, |
---|
66 | 0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253, |
---|
67 | 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, |
---|
68 | 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, |
---|
69 | 0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, |
---|
70 | 0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073, |
---|
71 | 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, |
---|
72 | 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, |
---|
73 | 0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004 |
---|
74 | /* the upper 128 are all zeroes */ |
---|
75 | }; |
---|
76 | |
---|
77 | #if defined(G_PLATFORM_WIN32) && defined(__GNUC__) |
---|
78 | __declspec(dllexport) |
---|
79 | #endif |
---|
80 | const guint16 * const g_ascii_table = ascii_table_data; |
---|
81 | |
---|
82 | gchar* |
---|
83 | g_strdup (const gchar *str) |
---|
84 | { |
---|
85 | gchar *new_str; |
---|
86 | |
---|
87 | if (str) |
---|
88 | { |
---|
89 | new_str = g_new (char, strlen (str) + 1); |
---|
90 | strcpy (new_str, str); |
---|
91 | } |
---|
92 | else |
---|
93 | new_str = NULL; |
---|
94 | |
---|
95 | return new_str; |
---|
96 | } |
---|
97 | |
---|
98 | gpointer |
---|
99 | g_memdup (gconstpointer mem, |
---|
100 | guint byte_size) |
---|
101 | { |
---|
102 | gpointer new_mem; |
---|
103 | |
---|
104 | if (mem) |
---|
105 | { |
---|
106 | new_mem = g_malloc (byte_size); |
---|
107 | memcpy (new_mem, mem, byte_size); |
---|
108 | } |
---|
109 | else |
---|
110 | new_mem = NULL; |
---|
111 | |
---|
112 | return new_mem; |
---|
113 | } |
---|
114 | |
---|
115 | gchar* |
---|
116 | g_strndup (const gchar *str, |
---|
117 | gsize n) |
---|
118 | { |
---|
119 | gchar *new_str; |
---|
120 | |
---|
121 | if (str) |
---|
122 | { |
---|
123 | new_str = g_new (gchar, n + 1); |
---|
124 | strncpy (new_str, str, n); |
---|
125 | new_str[n] = '\0'; |
---|
126 | } |
---|
127 | else |
---|
128 | new_str = NULL; |
---|
129 | |
---|
130 | return new_str; |
---|
131 | } |
---|
132 | |
---|
133 | gchar* |
---|
134 | g_strnfill (gsize length, |
---|
135 | gchar fill_char) |
---|
136 | { |
---|
137 | gchar *str; |
---|
138 | |
---|
139 | str = g_new (gchar, length + 1); |
---|
140 | memset (str, (guchar)fill_char, length); |
---|
141 | str[length] = '\0'; |
---|
142 | |
---|
143 | return str; |
---|
144 | } |
---|
145 | |
---|
146 | /** |
---|
147 | * g_stpcpy: |
---|
148 | * @dest: destination buffer. |
---|
149 | * @src: source string. |
---|
150 | * |
---|
151 | * Copies a nul-terminated string into the dest buffer, include the |
---|
152 | * trailing nul, and return a pointer to the trailing nul byte. |
---|
153 | * This is useful for concatenating multiple strings together |
---|
154 | * without having to repeatedly scan for the end. |
---|
155 | * |
---|
156 | * Return value: a pointer to trailing nul byte. |
---|
157 | **/ |
---|
158 | gchar * |
---|
159 | g_stpcpy (gchar *dest, |
---|
160 | const gchar *src) |
---|
161 | { |
---|
162 | #ifdef HAVE_STPCPY |
---|
163 | g_return_val_if_fail (dest != NULL, NULL); |
---|
164 | g_return_val_if_fail (src != NULL, NULL); |
---|
165 | return stpcpy (dest, src); |
---|
166 | #else |
---|
167 | register gchar *d = dest; |
---|
168 | register const gchar *s = src; |
---|
169 | |
---|
170 | g_return_val_if_fail (dest != NULL, NULL); |
---|
171 | g_return_val_if_fail (src != NULL, NULL); |
---|
172 | do |
---|
173 | *d++ = *s; |
---|
174 | while (*s++ != '\0'); |
---|
175 | |
---|
176 | return d - 1; |
---|
177 | #endif |
---|
178 | } |
---|
179 | |
---|
180 | gchar* |
---|
181 | g_strdup_vprintf (const gchar *format, |
---|
182 | va_list args1) |
---|
183 | { |
---|
184 | gchar *buffer; |
---|
185 | #ifdef HAVE_VASPRINTF |
---|
186 | if (_g_vasprintf (&buffer, format, args1) < 0) |
---|
187 | buffer = NULL; |
---|
188 | else if (!g_mem_is_system_malloc ()) |
---|
189 | { |
---|
190 | gchar *buffer1 = g_strdup (buffer); |
---|
191 | free (buffer); |
---|
192 | buffer = buffer1; |
---|
193 | } |
---|
194 | #else |
---|
195 | va_list args2; |
---|
196 | |
---|
197 | G_VA_COPY (args2, args1); |
---|
198 | |
---|
199 | buffer = g_new (gchar, g_printf_string_upper_bound (format, args1)); |
---|
200 | |
---|
201 | _g_vsprintf (buffer, format, args2); |
---|
202 | va_end (args2); |
---|
203 | #endif |
---|
204 | return buffer; |
---|
205 | } |
---|
206 | |
---|
207 | gchar* |
---|
208 | g_strdup_printf (const gchar *format, |
---|
209 | ...) |
---|
210 | { |
---|
211 | gchar *buffer; |
---|
212 | va_list args; |
---|
213 | |
---|
214 | va_start (args, format); |
---|
215 | buffer = g_strdup_vprintf (format, args); |
---|
216 | va_end (args); |
---|
217 | |
---|
218 | return buffer; |
---|
219 | } |
---|
220 | |
---|
221 | gchar* |
---|
222 | g_strconcat (const gchar *string1, ...) |
---|
223 | { |
---|
224 | gsize l; |
---|
225 | va_list args; |
---|
226 | gchar *s; |
---|
227 | gchar *concat; |
---|
228 | gchar *ptr; |
---|
229 | |
---|
230 | g_return_val_if_fail (string1 != NULL, NULL); |
---|
231 | |
---|
232 | l = 1 + strlen (string1); |
---|
233 | va_start (args, string1); |
---|
234 | s = va_arg (args, gchar*); |
---|
235 | while (s) |
---|
236 | { |
---|
237 | l += strlen (s); |
---|
238 | s = va_arg (args, gchar*); |
---|
239 | } |
---|
240 | va_end (args); |
---|
241 | |
---|
242 | concat = g_new (gchar, l); |
---|
243 | ptr = concat; |
---|
244 | |
---|
245 | ptr = g_stpcpy (ptr, string1); |
---|
246 | va_start (args, string1); |
---|
247 | s = va_arg (args, gchar*); |
---|
248 | while (s) |
---|
249 | { |
---|
250 | ptr = g_stpcpy (ptr, s); |
---|
251 | s = va_arg (args, gchar*); |
---|
252 | } |
---|
253 | va_end (args); |
---|
254 | |
---|
255 | return concat; |
---|
256 | } |
---|
257 | |
---|
258 | /** |
---|
259 | * g_strtod: |
---|
260 | * @nptr: the string to convert to a numeric value. |
---|
261 | * @endptr: if non-%NULL, it returns the character after |
---|
262 | * the last character used in the conversion. |
---|
263 | * |
---|
264 | * Converts a string to a #gdouble value. |
---|
265 | * It calls the standard strtod() function to handle the conversion, but |
---|
266 | * if the string is not completely converted it attempts the conversion |
---|
267 | * again with g_ascii_strtod(), and returns the best match. |
---|
268 | * |
---|
269 | * This function should seldomly be used. The normal situation when reading |
---|
270 | * numbers not for human consumption is to use g_ascii_strtod(). Only when |
---|
271 | * you know that you must expect both locale formatted and C formatted numbers |
---|
272 | * should you use this. Make sure that you don't pass strings such as comma |
---|
273 | * separated lists of values, since the commas may be interpreted as a decimal |
---|
274 | * point in some locales, causing unexpected results. |
---|
275 | * |
---|
276 | * Return value: the #gdouble value. |
---|
277 | **/ |
---|
278 | gdouble |
---|
279 | g_strtod (const gchar *nptr, |
---|
280 | gchar **endptr) |
---|
281 | { |
---|
282 | gchar *fail_pos_1; |
---|
283 | gchar *fail_pos_2; |
---|
284 | gdouble val_1; |
---|
285 | gdouble val_2 = 0; |
---|
286 | |
---|
287 | g_return_val_if_fail (nptr != NULL, 0); |
---|
288 | |
---|
289 | fail_pos_1 = NULL; |
---|
290 | fail_pos_2 = NULL; |
---|
291 | |
---|
292 | val_1 = strtod (nptr, &fail_pos_1); |
---|
293 | |
---|
294 | if (fail_pos_1 && fail_pos_1[0] != 0) |
---|
295 | val_2 = g_ascii_strtod (nptr, &fail_pos_2); |
---|
296 | |
---|
297 | if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2) |
---|
298 | { |
---|
299 | if (endptr) |
---|
300 | *endptr = fail_pos_1; |
---|
301 | return val_1; |
---|
302 | } |
---|
303 | else |
---|
304 | { |
---|
305 | if (endptr) |
---|
306 | *endptr = fail_pos_2; |
---|
307 | return val_2; |
---|
308 | } |
---|
309 | } |
---|
310 | |
---|
311 | /** |
---|
312 | * g_ascii_strtod: |
---|
313 | * @nptr: the string to convert to a numeric value. |
---|
314 | * @endptr: if non-%NULL, it returns the character after |
---|
315 | * the last character used in the conversion. |
---|
316 | * |
---|
317 | * Converts a string to a #gdouble value. |
---|
318 | * This function behaves like the standard strtod() function |
---|
319 | * does in the C locale. It does this without actually |
---|
320 | * changing the current locale, since that would not be |
---|
321 | * thread-safe. |
---|
322 | * |
---|
323 | * This function is typically used when reading configuration |
---|
324 | * files or other non-user input that should be locale independent. |
---|
325 | * To handle input from the user you should normally use the |
---|
326 | * locale-sensitive system strtod() function. |
---|
327 | * |
---|
328 | * To convert from a string to #gdouble in a locale-insensitive |
---|
329 | * way, use g_ascii_dtostr(). |
---|
330 | * |
---|
331 | * If the correct value would cause overflow, plus or minus %HUGE_VAL |
---|
332 | * is returned (according to the sign of the value), and %ERANGE is |
---|
333 | * stored in %errno. If the correct value would cause underflow, |
---|
334 | * zero is returned and %ERANGE is stored in %errno. |
---|
335 | * |
---|
336 | * This function resets %errno before calling strtod() so that |
---|
337 | * you can reliably detect overflow and underflow. |
---|
338 | * |
---|
339 | * Return value: the #gdouble value. |
---|
340 | **/ |
---|
341 | gdouble |
---|
342 | g_ascii_strtod (const gchar *nptr, |
---|
343 | gchar **endptr) |
---|
344 | { |
---|
345 | gchar *fail_pos; |
---|
346 | gdouble val; |
---|
347 | struct lconv *locale_data; |
---|
348 | const char *decimal_point; |
---|
349 | int decimal_point_len; |
---|
350 | const char *p, *decimal_point_pos; |
---|
351 | const char *end = NULL; /* Silence gcc */ |
---|
352 | |
---|
353 | g_return_val_if_fail (nptr != NULL, 0); |
---|
354 | |
---|
355 | fail_pos = NULL; |
---|
356 | |
---|
357 | locale_data = localeconv (); |
---|
358 | decimal_point = locale_data->decimal_point; |
---|
359 | decimal_point_len = strlen (decimal_point); |
---|
360 | |
---|
361 | g_assert (decimal_point_len != 0); |
---|
362 | |
---|
363 | decimal_point_pos = NULL; |
---|
364 | if (decimal_point[0] != '.' || |
---|
365 | decimal_point[1] != 0) |
---|
366 | { |
---|
367 | p = nptr; |
---|
368 | /* Skip leading space */ |
---|
369 | while (g_ascii_isspace (*p)) |
---|
370 | p++; |
---|
371 | |
---|
372 | /* Skip leading optional sign */ |
---|
373 | if (*p == '+' || *p == '-') |
---|
374 | p++; |
---|
375 | |
---|
376 | if (p[0] == '0' && |
---|
377 | (p[1] == 'x' || p[1] == 'X')) |
---|
378 | { |
---|
379 | p += 2; |
---|
380 | /* HEX - find the (optional) decimal point */ |
---|
381 | |
---|
382 | while (g_ascii_isxdigit (*p)) |
---|
383 | p++; |
---|
384 | |
---|
385 | if (*p == '.') |
---|
386 | { |
---|
387 | decimal_point_pos = p++; |
---|
388 | |
---|
389 | while (g_ascii_isxdigit (*p)) |
---|
390 | p++; |
---|
391 | |
---|
392 | if (*p == 'p' || *p == 'P') |
---|
393 | p++; |
---|
394 | if (*p == '+' || *p == '-') |
---|
395 | p++; |
---|
396 | while (g_ascii_isdigit (*p)) |
---|
397 | p++; |
---|
398 | end = p; |
---|
399 | } |
---|
400 | } |
---|
401 | else |
---|
402 | { |
---|
403 | while (g_ascii_isdigit (*p)) |
---|
404 | p++; |
---|
405 | |
---|
406 | if (*p == '.') |
---|
407 | { |
---|
408 | decimal_point_pos = p++; |
---|
409 | |
---|
410 | while (g_ascii_isdigit (*p)) |
---|
411 | p++; |
---|
412 | |
---|
413 | if (*p == 'e' || *p == 'E') |
---|
414 | p++; |
---|
415 | if (*p == '+' || *p == '-') |
---|
416 | p++; |
---|
417 | while (g_ascii_isdigit (*p)) |
---|
418 | p++; |
---|
419 | end = p; |
---|
420 | } |
---|
421 | } |
---|
422 | /* For the other cases, we need not convert the decimal point */ |
---|
423 | } |
---|
424 | |
---|
425 | /* Set errno to zero, so that we can distinguish zero results |
---|
426 | and underflows */ |
---|
427 | errno = 0; |
---|
428 | |
---|
429 | if (decimal_point_pos) |
---|
430 | { |
---|
431 | char *copy, *c; |
---|
432 | |
---|
433 | /* We need to convert the '.' to the locale specific decimal point */ |
---|
434 | copy = g_malloc (end - nptr + 1 + decimal_point_len); |
---|
435 | |
---|
436 | c = copy; |
---|
437 | memcpy (c, nptr, decimal_point_pos - nptr); |
---|
438 | c += decimal_point_pos - nptr; |
---|
439 | memcpy (c, decimal_point, decimal_point_len); |
---|
440 | c += decimal_point_len; |
---|
441 | memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); |
---|
442 | c += end - (decimal_point_pos + 1); |
---|
443 | *c = 0; |
---|
444 | |
---|
445 | val = strtod (copy, &fail_pos); |
---|
446 | |
---|
447 | if (fail_pos) |
---|
448 | { |
---|
449 | if (fail_pos > decimal_point_pos) |
---|
450 | fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); |
---|
451 | else |
---|
452 | fail_pos = (char *)nptr + (fail_pos - copy); |
---|
453 | } |
---|
454 | |
---|
455 | g_free (copy); |
---|
456 | |
---|
457 | } |
---|
458 | else |
---|
459 | val = strtod (nptr, &fail_pos); |
---|
460 | |
---|
461 | if (endptr) |
---|
462 | *endptr = fail_pos; |
---|
463 | |
---|
464 | return val; |
---|
465 | } |
---|
466 | |
---|
467 | |
---|
468 | /** |
---|
469 | * g_ascii_dtostr: |
---|
470 | * @buffer: A buffer to place the resulting string in |
---|
471 | * @buf_len: The length of the buffer. |
---|
472 | * @d: The #gdouble to convert |
---|
473 | * |
---|
474 | * Converts a #gdouble to a string, using the '.' as |
---|
475 | * decimal point. |
---|
476 | * |
---|
477 | * This functions generates enough precision that converting |
---|
478 | * the string back using g_strtod() gives the same machine-number |
---|
479 | * (on machines with IEEE compatible 64bit doubles). It is |
---|
480 | * guaranteed that the size of the resulting string will never |
---|
481 | * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes. |
---|
482 | * |
---|
483 | * Return value: The pointer to the buffer with the converted string. |
---|
484 | **/ |
---|
485 | gchar * |
---|
486 | g_ascii_dtostr (gchar *buffer, |
---|
487 | gint buf_len, |
---|
488 | gdouble d) |
---|
489 | { |
---|
490 | return g_ascii_formatd (buffer, buf_len, "%.17g", d); |
---|
491 | } |
---|
492 | |
---|
493 | /** |
---|
494 | * g_ascii_formatd: |
---|
495 | * @buffer: A buffer to place the resulting string in |
---|
496 | * @buf_len: The length of the buffer. |
---|
497 | * @format: The printf-style format to use for the |
---|
498 | * code to use for converting. |
---|
499 | * @d: The #gdouble to convert |
---|
500 | * |
---|
501 | * Converts a #gdouble to a string, using the '.' as |
---|
502 | * decimal point. To format the number you pass in |
---|
503 | * a printf-style formating string. Allowed conversion |
---|
504 | * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. |
---|
505 | * |
---|
506 | * If you just want to want to serialize the value into a |
---|
507 | * string, use g_ascii_dtostr(). |
---|
508 | * |
---|
509 | * Return value: The pointer to the buffer with the converted string. |
---|
510 | **/ |
---|
511 | gchar * |
---|
512 | g_ascii_formatd (gchar *buffer, |
---|
513 | gint buf_len, |
---|
514 | const gchar *format, |
---|
515 | gdouble d) |
---|
516 | { |
---|
517 | struct lconv *locale_data; |
---|
518 | const char *decimal_point; |
---|
519 | int decimal_point_len; |
---|
520 | gchar *p; |
---|
521 | int rest_len; |
---|
522 | gchar format_char; |
---|
523 | |
---|
524 | g_return_val_if_fail (buffer != NULL, NULL); |
---|
525 | g_return_val_if_fail (format[0] == '%', NULL); |
---|
526 | g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); |
---|
527 | |
---|
528 | format_char = format[strlen (format) - 1]; |
---|
529 | |
---|
530 | g_return_val_if_fail (format_char == 'e' || format_char == 'E' || |
---|
531 | format_char == 'f' || format_char == 'F' || |
---|
532 | format_char == 'g' || format_char == 'G', |
---|
533 | NULL); |
---|
534 | |
---|
535 | if (format[0] != '%') |
---|
536 | return NULL; |
---|
537 | |
---|
538 | if (strpbrk (format + 1, "'l%")) |
---|
539 | return NULL; |
---|
540 | |
---|
541 | if (!(format_char == 'e' || format_char == 'E' || |
---|
542 | format_char == 'f' || format_char == 'F' || |
---|
543 | format_char == 'g' || format_char == 'G')) |
---|
544 | return NULL; |
---|
545 | |
---|
546 | |
---|
547 | _g_snprintf (buffer, buf_len, format, d); |
---|
548 | |
---|
549 | locale_data = localeconv (); |
---|
550 | decimal_point = locale_data->decimal_point; |
---|
551 | decimal_point_len = strlen (decimal_point); |
---|
552 | |
---|
553 | g_assert (decimal_point_len != 0); |
---|
554 | |
---|
555 | if (decimal_point[0] != '.' || |
---|
556 | decimal_point[1] != 0) |
---|
557 | { |
---|
558 | p = buffer; |
---|
559 | |
---|
560 | if (*p == '+' || *p == '-') |
---|
561 | p++; |
---|
562 | |
---|
563 | while (isdigit ((guchar)*p)) |
---|
564 | p++; |
---|
565 | |
---|
566 | if (strncmp (p, decimal_point, decimal_point_len) == 0) |
---|
567 | { |
---|
568 | *p = '.'; |
---|
569 | p++; |
---|
570 | if (decimal_point_len > 1) { |
---|
571 | rest_len = strlen (p + (decimal_point_len-1)); |
---|
572 | memmove (p, p + (decimal_point_len-1), |
---|
573 | rest_len); |
---|
574 | p[rest_len] = 0; |
---|
575 | |
---|
576 | } |
---|
577 | } |
---|
578 | } |
---|
579 | |
---|
580 | return buffer; |
---|
581 | } |
---|
582 | |
---|
583 | /** |
---|
584 | * g_ascii_strtoull: |
---|
585 | * @nptr: the string to convert to a numeric value. |
---|
586 | * @endptr: if non-%NULL, it returns the character after |
---|
587 | * the last character used in the conversion. |
---|
588 | * @base: to be used for the conversion, 2..36 or 0 |
---|
589 | * |
---|
590 | * Converts a string to a #guint64 value. |
---|
591 | * This function behaves like the standard strtoull() function |
---|
592 | * does in the C locale. It does this without actually |
---|
593 | * changing the current locale, since that would not be |
---|
594 | * thread-safe. |
---|
595 | * |
---|
596 | * This function is typically used when reading configuration |
---|
597 | * files or other non-user input that should be locale independent. |
---|
598 | * To handle input from the user you should normally use the |
---|
599 | * locale-sensitive system strtoull() function. |
---|
600 | * |
---|
601 | * If the correct value would cause overflow, %G_MAXUINT64 |
---|
602 | * is returned, and %ERANGE is stored in %errno. |
---|
603 | * |
---|
604 | * Return value: the #guint64 value. |
---|
605 | * |
---|
606 | * Since: 2.2 |
---|
607 | **/ |
---|
608 | guint64 |
---|
609 | g_ascii_strtoull (const gchar *nptr, |
---|
610 | gchar **endptr, |
---|
611 | guint base) |
---|
612 | { |
---|
613 | /* this code is based on on the strtol(3) code from GNU libc released under |
---|
614 | * the GNU Lesser General Public License. |
---|
615 | * |
---|
616 | * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02 |
---|
617 | * Free Software Foundation, Inc. |
---|
618 | */ |
---|
619 | #define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ |
---|
620 | (c) == '\r' || (c) == '\t' || (c) == '\v') |
---|
621 | #define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') |
---|
622 | #define ISLOWER(c) ((c) >= 'a' && (c) <= 'z') |
---|
623 | #define ISALPHA(c) (ISUPPER (c) || ISLOWER (c)) |
---|
624 | #define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c)) |
---|
625 | #define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c)) |
---|
626 | gboolean negative, overflow; |
---|
627 | guint64 cutoff; |
---|
628 | guint64 cutlim; |
---|
629 | guint64 ui64; |
---|
630 | const gchar *s, *save; |
---|
631 | guchar c; |
---|
632 | |
---|
633 | g_return_val_if_fail (nptr != NULL, 0); |
---|
634 | |
---|
635 | if (base == 1 || base > 36) |
---|
636 | { |
---|
637 | errno = EINVAL; |
---|
638 | return 0; |
---|
639 | } |
---|
640 | |
---|
641 | save = s = nptr; |
---|
642 | |
---|
643 | /* Skip white space. */ |
---|
644 | while (ISSPACE (*s)) |
---|
645 | ++s; |
---|
646 | if (!*s) |
---|
647 | goto noconv; |
---|
648 | |
---|
649 | /* Check for a sign. */ |
---|
650 | negative = FALSE; |
---|
651 | if (*s == '-') |
---|
652 | { |
---|
653 | negative = TRUE; |
---|
654 | ++s; |
---|
655 | } |
---|
656 | else if (*s == '+') |
---|
657 | ++s; |
---|
658 | |
---|
659 | /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ |
---|
660 | if (*s == '0') |
---|
661 | { |
---|
662 | if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X') |
---|
663 | { |
---|
664 | s += 2; |
---|
665 | base = 16; |
---|
666 | } |
---|
667 | else if (base == 0) |
---|
668 | base = 8; |
---|
669 | } |
---|
670 | else if (base == 0) |
---|
671 | base = 10; |
---|
672 | |
---|
673 | /* Save the pointer so we can check later if anything happened. */ |
---|
674 | save = s; |
---|
675 | cutoff = G_MAXUINT64 / base; |
---|
676 | cutlim = G_MAXUINT64 % base; |
---|
677 | |
---|
678 | overflow = FALSE; |
---|
679 | ui64 = 0; |
---|
680 | c = *s; |
---|
681 | for (; c; c = *++s) |
---|
682 | { |
---|
683 | if (c >= '0' && c <= '9') |
---|
684 | c -= '0'; |
---|
685 | else if (ISALPHA (c)) |
---|
686 | c = TOUPPER (c) - 'A' + 10; |
---|
687 | else |
---|
688 | break; |
---|
689 | if (c >= base) |
---|
690 | break; |
---|
691 | /* Check for overflow. */ |
---|
692 | if (ui64 > cutoff || (ui64 == cutoff && c > cutlim)) |
---|
693 | overflow = TRUE; |
---|
694 | else |
---|
695 | { |
---|
696 | ui64 *= base; |
---|
697 | ui64 += c; |
---|
698 | } |
---|
699 | } |
---|
700 | |
---|
701 | /* Check if anything actually happened. */ |
---|
702 | if (s == save) |
---|
703 | goto noconv; |
---|
704 | |
---|
705 | /* Store in ENDPTR the address of one character |
---|
706 | past the last character we converted. */ |
---|
707 | if (endptr) |
---|
708 | *endptr = (gchar*) s; |
---|
709 | |
---|
710 | if (overflow) |
---|
711 | { |
---|
712 | errno = ERANGE; |
---|
713 | return G_MAXUINT64; |
---|
714 | } |
---|
715 | |
---|
716 | /* Return the result of the appropriate sign. */ |
---|
717 | return negative ? -ui64 : ui64; |
---|
718 | |
---|
719 | noconv: |
---|
720 | /* We must handle a special case here: the base is 0 or 16 and the |
---|
721 | first two characters are '0' and 'x', but the rest are no |
---|
722 | hexadecimal digits. This is no error case. We return 0 and |
---|
723 | ENDPTR points to the `x`. */ |
---|
724 | if (endptr) |
---|
725 | { |
---|
726 | if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X' |
---|
727 | && save[-2] == '0') |
---|
728 | *endptr = (gchar*) &save[-1]; |
---|
729 | else |
---|
730 | /* There was no number to convert. */ |
---|
731 | *endptr = (gchar*) nptr; |
---|
732 | } |
---|
733 | return 0; |
---|
734 | } |
---|
735 | |
---|
736 | |
---|
737 | G_CONST_RETURN gchar* |
---|
738 | g_strerror (gint errnum) |
---|
739 | { |
---|
740 | static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; |
---|
741 | char *msg; |
---|
742 | |
---|
743 | #ifdef HAVE_STRERROR |
---|
744 | const char *msg_locale; |
---|
745 | |
---|
746 | msg_locale = strerror (errnum); |
---|
747 | if (g_get_charset (NULL)) |
---|
748 | return msg_locale; |
---|
749 | else |
---|
750 | { |
---|
751 | gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL); |
---|
752 | if (msg_utf8) |
---|
753 | { |
---|
754 | /* Stick in the quark table so that we can return a static result |
---|
755 | */ |
---|
756 | GQuark msg_quark = g_quark_from_string (msg_utf8); |
---|
757 | g_free (msg_utf8); |
---|
758 | |
---|
759 | return g_quark_to_string (msg_quark); |
---|
760 | } |
---|
761 | } |
---|
762 | #elif NO_SYS_ERRLIST |
---|
763 | switch (errnum) |
---|
764 | { |
---|
765 | #ifdef E2BIG |
---|
766 | case E2BIG: return "argument list too long"; |
---|
767 | #endif |
---|
768 | #ifdef EACCES |
---|
769 | case EACCES: return "permission denied"; |
---|
770 | #endif |
---|
771 | #ifdef EADDRINUSE |
---|
772 | case EADDRINUSE: return "address already in use"; |
---|
773 | #endif |
---|
774 | #ifdef EADDRNOTAVAIL |
---|
775 | case EADDRNOTAVAIL: return "can't assign requested address"; |
---|
776 | #endif |
---|
777 | #ifdef EADV |
---|
778 | case EADV: return "advertise error"; |
---|
779 | #endif |
---|
780 | #ifdef EAFNOSUPPORT |
---|
781 | case EAFNOSUPPORT: return "address family not supported by protocol family"; |
---|
782 | #endif |
---|
783 | #ifdef EAGAIN |
---|
784 | case EAGAIN: return "try again"; |
---|
785 | #endif |
---|
786 | #ifdef EALIGN |
---|
787 | case EALIGN: return "EALIGN"; |
---|
788 | #endif |
---|
789 | #ifdef EALREADY |
---|
790 | case EALREADY: return "operation already in progress"; |
---|
791 | #endif |
---|
792 | #ifdef EBADE |
---|
793 | case EBADE: return "bad exchange descriptor"; |
---|
794 | #endif |
---|
795 | #ifdef EBADF |
---|
796 | case EBADF: return "bad file number"; |
---|
797 | #endif |
---|
798 | #ifdef EBADFD |
---|
799 | case EBADFD: return "file descriptor in bad state"; |
---|
800 | #endif |
---|
801 | #ifdef EBADMSG |
---|
802 | case EBADMSG: return "not a data message"; |
---|
803 | #endif |
---|
804 | #ifdef EBADR |
---|
805 | case EBADR: return "bad request descriptor"; |
---|
806 | #endif |
---|
807 | #ifdef EBADRPC |
---|
808 | case EBADRPC: return "RPC structure is bad"; |
---|
809 | #endif |
---|
810 | #ifdef EBADRQC |
---|
811 | case EBADRQC: return "bad request code"; |
---|
812 | #endif |
---|
813 | #ifdef EBADSLT |
---|
814 | case EBADSLT: return "invalid slot"; |
---|
815 | #endif |
---|
816 | #ifdef EBFONT |
---|
817 | case EBFONT: return "bad font file format"; |
---|
818 | #endif |
---|
819 | #ifdef EBUSY |
---|
820 | case EBUSY: return "mount device busy"; |
---|
821 | #endif |
---|
822 | #ifdef ECHILD |
---|
823 | case ECHILD: return "no children"; |
---|
824 | #endif |
---|
825 | #ifdef ECHRNG |
---|
826 | case ECHRNG: return "channel number out of range"; |
---|
827 | #endif |
---|
828 | #ifdef ECOMM |
---|
829 | case ECOMM: return "communication error on send"; |
---|
830 | #endif |
---|
831 | #ifdef ECONNABORTED |
---|
832 | case ECONNABORTED: return "software caused connection abort"; |
---|
833 | #endif |
---|
834 | #ifdef ECONNREFUSED |
---|
835 | case ECONNREFUSED: return "connection refused"; |
---|
836 | #endif |
---|
837 | #ifdef ECONNRESET |
---|
838 | case ECONNRESET: return "connection reset by peer"; |
---|
839 | #endif |
---|
840 | #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK)) |
---|
841 | case EDEADLK: return "resource deadlock avoided"; |
---|
842 | #endif |
---|
843 | #ifdef EDEADLOCK |
---|
844 | case EDEADLOCK: return "resource deadlock avoided"; |
---|
845 | #endif |
---|
846 | #ifdef EDESTADDRREQ |
---|
847 | case EDESTADDRREQ: return "destination address required"; |
---|
848 | #endif |
---|
849 | #ifdef EDIRTY |
---|
850 | case EDIRTY: return "mounting a dirty fs w/o force"; |
---|
851 | #endif |
---|
852 | #ifdef EDOM |
---|
853 | case EDOM: return "math argument out of range"; |
---|
854 | #endif |
---|
855 | #ifdef EDOTDOT |
---|
856 | case EDOTDOT: return "cross mount point"; |
---|
857 | #endif |
---|
858 | #ifdef EDQUOT |
---|
859 | case EDQUOT: return "disk quota exceeded"; |
---|
860 | #endif |
---|
861 | #ifdef EDUPPKG |
---|
862 | case EDUPPKG: return "duplicate package name"; |
---|
863 | #endif |
---|
864 | #ifdef EEXIST |
---|
865 | case EEXIST: return "file already exists"; |
---|
866 | #endif |
---|
867 | #ifdef EFAULT |
---|
868 | case EFAULT: return "bad address in system call argument"; |
---|
869 | #endif |
---|
870 | #ifdef EFBIG |
---|
871 | case EFBIG: return "file too large"; |
---|
872 | #endif |
---|
873 | #ifdef EHOSTDOWN |
---|
874 | case EHOSTDOWN: return "host is down"; |
---|
875 | #endif |
---|
876 | #ifdef EHOSTUNREACH |
---|
877 | case EHOSTUNREACH: return "host is unreachable"; |
---|
878 | #endif |
---|
879 | #ifdef EIDRM |
---|
880 | case EIDRM: return "identifier removed"; |
---|
881 | #endif |
---|
882 | #ifdef EINIT |
---|
883 | case EINIT: return "initialization error"; |
---|
884 | #endif |
---|
885 | #ifdef EINPROGRESS |
---|
886 | case EINPROGRESS: return "operation now in progress"; |
---|
887 | #endif |
---|
888 | #ifdef EINTR |
---|
889 | case EINTR: return "interrupted system call"; |
---|
890 | #endif |
---|
891 | #ifdef EINVAL |
---|
892 | case EINVAL: return "invalid argument"; |
---|
893 | #endif |
---|
894 | #ifdef EIO |
---|
895 | case EIO: return "I/O error"; |
---|
896 | #endif |
---|
897 | #ifdef EISCONN |
---|
898 | case EISCONN: return "socket is already connected"; |
---|
899 | #endif |
---|
900 | #ifdef EISDIR |
---|
901 | case EISDIR: return "is a directory"; |
---|
902 | #endif |
---|
903 | #ifdef EISNAME |
---|
904 | case EISNAM: return "is a name file"; |
---|
905 | #endif |
---|
906 | #ifdef ELBIN |
---|
907 | case ELBIN: return "ELBIN"; |
---|
908 | #endif |
---|
909 | #ifdef EL2HLT |
---|
910 | case EL2HLT: return "level 2 halted"; |
---|
911 | #endif |
---|
912 | #ifdef EL2NSYNC |
---|
913 | case EL2NSYNC: return "level 2 not synchronized"; |
---|
914 | #endif |
---|
915 | #ifdef EL3HLT |
---|
916 | case EL3HLT: return "level 3 halted"; |
---|
917 | #endif |
---|
918 | #ifdef EL3RST |
---|
919 | case EL3RST: return "level 3 reset"; |
---|
920 | #endif |
---|
921 | #ifdef ELIBACC |
---|
922 | case ELIBACC: return "can not access a needed shared library"; |
---|
923 | #endif |
---|
924 | #ifdef ELIBBAD |
---|
925 | case ELIBBAD: return "accessing a corrupted shared library"; |
---|
926 | #endif |
---|
927 | #ifdef ELIBEXEC |
---|
928 | case ELIBEXEC: return "can not exec a shared library directly"; |
---|
929 | #endif |
---|
930 | #ifdef ELIBMAX |
---|
931 | case ELIBMAX: return "attempting to link in more shared libraries than system limit"; |
---|
932 | #endif |
---|
933 | #ifdef ELIBSCN |
---|
934 | case ELIBSCN: return ".lib section in a.out corrupted"; |
---|
935 | #endif |
---|
936 | #ifdef ELNRNG |
---|
937 | case ELNRNG: return "link number out of range"; |
---|
938 | #endif |
---|
939 | #ifdef ELOOP |
---|
940 | case ELOOP: return "too many levels of symbolic links"; |
---|
941 | #endif |
---|
942 | #ifdef EMFILE |
---|
943 | case EMFILE: return "too many open files"; |
---|
944 | #endif |
---|
945 | #ifdef EMLINK |
---|
946 | case EMLINK: return "too many links"; |
---|
947 | #endif |
---|
948 | #ifdef EMSGSIZE |
---|
949 | case EMSGSIZE: return "message too long"; |
---|
950 | #endif |
---|
951 | #ifdef EMULTIHOP |
---|
952 | case EMULTIHOP: return "multihop attempted"; |
---|
953 | #endif |
---|
954 | #ifdef ENAMETOOLONG |
---|
955 | case ENAMETOOLONG: return "file name too long"; |
---|
956 | #endif |
---|
957 | #ifdef ENAVAIL |
---|
958 | case ENAVAIL: return "not available"; |
---|
959 | #endif |
---|
960 | #ifdef ENET |
---|
961 | case ENET: return "ENET"; |
---|
962 | #endif |
---|
963 | #ifdef ENETDOWN |
---|
964 | case ENETDOWN: return "network is down"; |
---|
965 | #endif |
---|
966 | #ifdef ENETRESET |
---|
967 | case ENETRESET: return "network dropped connection on reset"; |
---|
968 | #endif |
---|
969 | #ifdef ENETUNREACH |
---|
970 | case ENETUNREACH: return "network is unreachable"; |
---|
971 | #endif |
---|
972 | #ifdef ENFILE |
---|
973 | case ENFILE: return "file table overflow"; |
---|
974 | #endif |
---|
975 | #ifdef ENOANO |
---|
976 | case ENOANO: return "anode table overflow"; |
---|
977 | #endif |
---|
978 | #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR)) |
---|
979 | case ENOBUFS: return "no buffer space available"; |
---|
980 | #endif |
---|
981 | #ifdef ENOCSI |
---|
982 | case ENOCSI: return "no CSI structure available"; |
---|
983 | #endif |
---|
984 | #ifdef ENODATA |
---|
985 | case ENODATA: return "no data available"; |
---|
986 | #endif |
---|
987 | #ifdef ENODEV |
---|
988 | case ENODEV: return "no such device"; |
---|
989 | #endif |
---|
990 | #ifdef ENOENT |
---|
991 | case ENOENT: return "no such file or directory"; |
---|
992 | #endif |
---|
993 | #ifdef ENOEXEC |
---|
994 | case ENOEXEC: return "exec format error"; |
---|
995 | #endif |
---|
996 | #ifdef ENOLCK |
---|
997 | case ENOLCK: return "no locks available"; |
---|
998 | #endif |
---|
999 | #ifdef ENOLINK |
---|
1000 | case ENOLINK: return "link has be severed"; |
---|
1001 | #endif |
---|
1002 | #ifdef ENOMEM |
---|
1003 | case ENOMEM: return "not enough memory"; |
---|
1004 | #endif |
---|
1005 | #ifdef ENOMSG |
---|
1006 | case ENOMSG: return "no message of desired type"; |
---|
1007 | #endif |
---|
1008 | #ifdef ENONET |
---|
1009 | case ENONET: return "machine is not on the network"; |
---|
1010 | #endif |
---|
1011 | #ifdef ENOPKG |
---|
1012 | case ENOPKG: return "package not installed"; |
---|
1013 | #endif |
---|
1014 | #ifdef ENOPROTOOPT |
---|
1015 | case ENOPROTOOPT: return "bad proocol option"; |
---|
1016 | #endif |
---|
1017 | #ifdef ENOSPC |
---|
1018 | case ENOSPC: return "no space left on device"; |
---|
1019 | #endif |
---|
1020 | #ifdef ENOSR |
---|
1021 | case ENOSR: return "out of stream resources"; |
---|
1022 | #endif |
---|
1023 | #ifdef ENOSTR |
---|
1024 | case ENOSTR: return "not a stream device"; |
---|
1025 | #endif |
---|
1026 | #ifdef ENOSYM |
---|
1027 | case ENOSYM: return "unresolved symbol name"; |
---|
1028 | #endif |
---|
1029 | #ifdef ENOSYS |
---|
1030 | case ENOSYS: return "function not implemented"; |
---|
1031 | #endif |
---|
1032 | #ifdef ENOTBLK |
---|
1033 | case ENOTBLK: return "block device required"; |
---|
1034 | #endif |
---|
1035 | #ifdef ENOTCONN |
---|
1036 | case ENOTCONN: return "socket is not connected"; |
---|
1037 | #endif |
---|
1038 | #ifdef ENOTDIR |
---|
1039 | case ENOTDIR: return "not a directory"; |
---|
1040 | #endif |
---|
1041 | #ifdef ENOTEMPTY |
---|
1042 | case ENOTEMPTY: return "directory not empty"; |
---|
1043 | #endif |
---|
1044 | #ifdef ENOTNAM |
---|
1045 | case ENOTNAM: return "not a name file"; |
---|
1046 | #endif |
---|
1047 | #ifdef ENOTSOCK |
---|
1048 | case ENOTSOCK: return "socket operation on non-socket"; |
---|
1049 | #endif |
---|
1050 | #ifdef ENOTTY |
---|
1051 | case ENOTTY: return "inappropriate device for ioctl"; |
---|
1052 | #endif |
---|
1053 | #ifdef ENOTUNIQ |
---|
1054 | case ENOTUNIQ: return "name not unique on network"; |
---|
1055 | #endif |
---|
1056 | #ifdef ENXIO |
---|
1057 | case ENXIO: return "no such device or address"; |
---|
1058 | #endif |
---|
1059 | #ifdef EOPNOTSUPP |
---|
1060 | case EOPNOTSUPP: return "operation not supported on socket"; |
---|
1061 | #endif |
---|
1062 | #ifdef EPERM |
---|
1063 | case EPERM: return "not owner"; |
---|
1064 | #endif |
---|
1065 | #ifdef EPFNOSUPPORT |
---|
1066 | case EPFNOSUPPORT: return "protocol family not supported"; |
---|
1067 | #endif |
---|
1068 | #ifdef EPIPE |
---|
1069 | case EPIPE: return "broken pipe"; |
---|
1070 | #endif |
---|
1071 | #ifdef EPROCLIM |
---|
1072 | case EPROCLIM: return "too many processes"; |
---|
1073 | #endif |
---|
1074 | #ifdef EPROCUNAVAIL |
---|
1075 | case EPROCUNAVAIL: return "bad procedure for program"; |
---|
1076 | #endif |
---|
1077 | #ifdef EPROGMISMATCH |
---|
1078 | case EPROGMISMATCH: return "program version wrong"; |
---|
1079 | #endif |
---|
1080 | #ifdef EPROGUNAVAIL |
---|
1081 | case EPROGUNAVAIL: return "RPC program not available"; |
---|
1082 | #endif |
---|
1083 | #ifdef EPROTO |
---|
1084 | case EPROTO: return "protocol error"; |
---|
1085 | #endif |
---|
1086 | #ifdef EPROTONOSUPPORT |
---|
1087 | case EPROTONOSUPPORT: return "protocol not suppored"; |
---|
1088 | #endif |
---|
1089 | #ifdef EPROTOTYPE |
---|
1090 | case EPROTOTYPE: return "protocol wrong type for socket"; |
---|
1091 | #endif |
---|
1092 | #ifdef ERANGE |
---|
1093 | case ERANGE: return "math result unrepresentable"; |
---|
1094 | #endif |
---|
1095 | #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED)) |
---|
1096 | case EREFUSED: return "EREFUSED"; |
---|
1097 | #endif |
---|
1098 | #ifdef EREMCHG |
---|
1099 | case EREMCHG: return "remote address changed"; |
---|
1100 | #endif |
---|
1101 | #ifdef EREMDEV |
---|
1102 | case EREMDEV: return "remote device"; |
---|
1103 | #endif |
---|
1104 | #ifdef EREMOTE |
---|
1105 | case EREMOTE: return "pathname hit remote file system"; |
---|
1106 | #endif |
---|
1107 | #ifdef EREMOTEIO |
---|
1108 | case EREMOTEIO: return "remote i/o error"; |
---|
1109 | #endif |
---|
1110 | #ifdef EREMOTERELEASE |
---|
1111 | case EREMOTERELEASE: return "EREMOTERELEASE"; |
---|
1112 | #endif |
---|
1113 | #ifdef EROFS |
---|
1114 | case EROFS: return "read-only file system"; |
---|
1115 | #endif |
---|
1116 | #ifdef ERPCMISMATCH |
---|
1117 | case ERPCMISMATCH: return "RPC version is wrong"; |
---|
1118 | #endif |
---|
1119 | #ifdef ERREMOTE |
---|
1120 | case ERREMOTE: return "object is remote"; |
---|
1121 | #endif |
---|
1122 | #ifdef ESHUTDOWN |
---|
1123 | case ESHUTDOWN: return "can't send afer socket shutdown"; |
---|
1124 | #endif |
---|
1125 | #ifdef ESOCKTNOSUPPORT |
---|
1126 | case ESOCKTNOSUPPORT: return "socket type not supported"; |
---|
1127 | #endif |
---|
1128 | #ifdef ESPIPE |
---|
1129 | case ESPIPE: return "invalid seek"; |
---|
1130 | #endif |
---|
1131 | #ifdef ESRCH |
---|
1132 | case ESRCH: return "no such process"; |
---|
1133 | #endif |
---|
1134 | #ifdef ESRMNT |
---|
1135 | case ESRMNT: return "srmount error"; |
---|
1136 | #endif |
---|
1137 | #ifdef ESTALE |
---|
1138 | case ESTALE: return "stale remote file handle"; |
---|
1139 | #endif |
---|
1140 | #ifdef ESUCCESS |
---|
1141 | case ESUCCESS: return "Error 0"; |
---|
1142 | #endif |
---|
1143 | #ifdef ETIME |
---|
1144 | case ETIME: return "timer expired"; |
---|
1145 | #endif |
---|
1146 | #ifdef ETIMEDOUT |
---|
1147 | case ETIMEDOUT: return "connection timed out"; |
---|
1148 | #endif |
---|
1149 | #ifdef ETOOMANYREFS |
---|
1150 | case ETOOMANYREFS: return "too many references: can't splice"; |
---|
1151 | #endif |
---|
1152 | #ifdef ETXTBSY |
---|
1153 | case ETXTBSY: return "text file or pseudo-device busy"; |
---|
1154 | #endif |
---|
1155 | #ifdef EUCLEAN |
---|
1156 | case EUCLEAN: return "structure needs cleaning"; |
---|
1157 | #endif |
---|
1158 | #ifdef EUNATCH |
---|
1159 | case EUNATCH: return "protocol driver not attached"; |
---|
1160 | #endif |
---|
1161 | #ifdef EUSERS |
---|
1162 | case EUSERS: return "too many users"; |
---|
1163 | #endif |
---|
1164 | #ifdef EVERSION |
---|
1165 | case EVERSION: return "version mismatch"; |
---|
1166 | #endif |
---|
1167 | #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) |
---|
1168 | case EWOULDBLOCK: return "operation would block"; |
---|
1169 | #endif |
---|
1170 | #ifdef EXDEV |
---|
1171 | case EXDEV: return "cross-domain link"; |
---|
1172 | #endif |
---|
1173 | #ifdef EXFULL |
---|
1174 | case EXFULL: return "message tables full"; |
---|
1175 | #endif |
---|
1176 | } |
---|
1177 | #else /* NO_SYS_ERRLIST */ |
---|
1178 | extern int sys_nerr; |
---|
1179 | extern char *sys_errlist[]; |
---|
1180 | |
---|
1181 | if ((errnum > 0) && (errnum <= sys_nerr)) |
---|
1182 | return sys_errlist [errnum]; |
---|
1183 | #endif /* NO_SYS_ERRLIST */ |
---|
1184 | |
---|
1185 | msg = g_static_private_get (&msg_private); |
---|
1186 | if (!msg) |
---|
1187 | { |
---|
1188 | msg = g_new (gchar, 64); |
---|
1189 | g_static_private_set (&msg_private, msg, g_free); |
---|
1190 | } |
---|
1191 | |
---|
1192 | _g_sprintf (msg, "unknown error (%d)", errnum); |
---|
1193 | |
---|
1194 | return msg; |
---|
1195 | } |
---|
1196 | |
---|
1197 | G_CONST_RETURN gchar* |
---|
1198 | g_strsignal (gint signum) |
---|
1199 | { |
---|
1200 | static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; |
---|
1201 | char *msg; |
---|
1202 | |
---|
1203 | #ifdef HAVE_STRSIGNAL |
---|
1204 | const char *msg_locale; |
---|
1205 | |
---|
1206 | #if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN) |
---|
1207 | extern const char *strsignal(int); |
---|
1208 | #else |
---|
1209 | /* this is declared differently (const) in string.h on BeOS */ |
---|
1210 | extern char *strsignal (int sig); |
---|
1211 | #endif /* !G_OS_BEOS && !G_WITH_CYGWIN */ |
---|
1212 | msg_locale = strsignal (signum); |
---|
1213 | if (g_get_charset (NULL)) |
---|
1214 | return msg_locale; |
---|
1215 | else |
---|
1216 | { |
---|
1217 | gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL); |
---|
1218 | if (msg_utf8) |
---|
1219 | { |
---|
1220 | /* Stick in the quark table so that we can return a static result |
---|
1221 | */ |
---|
1222 | GQuark msg_quark = g_quark_from_string (msg_utf8); |
---|
1223 | g_free (msg_utf8); |
---|
1224 | |
---|
1225 | return g_quark_to_string (msg_quark); |
---|
1226 | } |
---|
1227 | } |
---|
1228 | #elif NO_SYS_SIGLIST |
---|
1229 | switch (signum) |
---|
1230 | { |
---|
1231 | #ifdef SIGHUP |
---|
1232 | case SIGHUP: return "Hangup"; |
---|
1233 | #endif |
---|
1234 | #ifdef SIGINT |
---|
1235 | case SIGINT: return "Interrupt"; |
---|
1236 | #endif |
---|
1237 | #ifdef SIGQUIT |
---|
1238 | case SIGQUIT: return "Quit"; |
---|
1239 | #endif |
---|
1240 | #ifdef SIGILL |
---|
1241 | case SIGILL: return "Illegal instruction"; |
---|
1242 | #endif |
---|
1243 | #ifdef SIGTRAP |
---|
1244 | case SIGTRAP: return "Trace/breakpoint trap"; |
---|
1245 | #endif |
---|
1246 | #ifdef SIGABRT |
---|
1247 | case SIGABRT: return "IOT trap/Abort"; |
---|
1248 | #endif |
---|
1249 | #ifdef SIGBUS |
---|
1250 | case SIGBUS: return "Bus error"; |
---|
1251 | #endif |
---|
1252 | #ifdef SIGFPE |
---|
1253 | case SIGFPE: return "Floating point exception"; |
---|
1254 | #endif |
---|
1255 | #ifdef SIGKILL |
---|
1256 | case SIGKILL: return "Killed"; |
---|
1257 | #endif |
---|
1258 | #ifdef SIGUSR1 |
---|
1259 | case SIGUSR1: return "User defined signal 1"; |
---|
1260 | #endif |
---|
1261 | #ifdef SIGSEGV |
---|
1262 | case SIGSEGV: return "Segmentation fault"; |
---|
1263 | #endif |
---|
1264 | #ifdef SIGUSR2 |
---|
1265 | case SIGUSR2: return "User defined signal 2"; |
---|
1266 | #endif |
---|
1267 | #ifdef SIGPIPE |
---|
1268 | case SIGPIPE: return "Broken pipe"; |
---|
1269 | #endif |
---|
1270 | #ifdef SIGALRM |
---|
1271 | case SIGALRM: return "Alarm clock"; |
---|
1272 | #endif |
---|
1273 | #ifdef SIGTERM |
---|
1274 | case SIGTERM: return "Terminated"; |
---|
1275 | #endif |
---|
1276 | #ifdef SIGSTKFLT |
---|
1277 | case SIGSTKFLT: return "Stack fault"; |
---|
1278 | #endif |
---|
1279 | #ifdef SIGCHLD |
---|
1280 | case SIGCHLD: return "Child exited"; |
---|
1281 | #endif |
---|
1282 | #ifdef SIGCONT |
---|
1283 | case SIGCONT: return "Continued"; |
---|
1284 | #endif |
---|
1285 | #ifdef SIGSTOP |
---|
1286 | case SIGSTOP: return "Stopped (signal)"; |
---|
1287 | #endif |
---|
1288 | #ifdef SIGTSTP |
---|
1289 | case SIGTSTP: return "Stopped"; |
---|
1290 | #endif |
---|
1291 | #ifdef SIGTTIN |
---|
1292 | case SIGTTIN: return "Stopped (tty input)"; |
---|
1293 | #endif |
---|
1294 | #ifdef SIGTTOU |
---|
1295 | case SIGTTOU: return "Stopped (tty output)"; |
---|
1296 | #endif |
---|
1297 | #ifdef SIGURG |
---|
1298 | case SIGURG: return "Urgent condition"; |
---|
1299 | #endif |
---|
1300 | #ifdef SIGXCPU |
---|
1301 | case SIGXCPU: return "CPU time limit exceeded"; |
---|
1302 | #endif |
---|
1303 | #ifdef SIGXFSZ |
---|
1304 | case SIGXFSZ: return "File size limit exceeded"; |
---|
1305 | #endif |
---|
1306 | #ifdef SIGVTALRM |
---|
1307 | case SIGVTALRM: return "Virtual time alarm"; |
---|
1308 | #endif |
---|
1309 | #ifdef SIGPROF |
---|
1310 | case SIGPROF: return "Profile signal"; |
---|
1311 | #endif |
---|
1312 | #ifdef SIGWINCH |
---|
1313 | case SIGWINCH: return "Window size changed"; |
---|
1314 | #endif |
---|
1315 | #ifdef SIGIO |
---|
1316 | case SIGIO: return "Possible I/O"; |
---|
1317 | #endif |
---|
1318 | #ifdef SIGPWR |
---|
1319 | case SIGPWR: return "Power failure"; |
---|
1320 | #endif |
---|
1321 | #ifdef SIGUNUSED |
---|
1322 | case SIGUNUSED: return "Unused signal"; |
---|
1323 | #endif |
---|
1324 | } |
---|
1325 | #else /* NO_SYS_SIGLIST */ |
---|
1326 | |
---|
1327 | #ifdef NO_SYS_SIGLIST_DECL |
---|
1328 | extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/ |
---|
1329 | #endif |
---|
1330 | |
---|
1331 | return (char*) /* this function should return const --josh */ sys_siglist [signum]; |
---|
1332 | #endif /* NO_SYS_SIGLIST */ |
---|
1333 | |
---|
1334 | msg = g_static_private_get (&msg_private); |
---|
1335 | if (!msg) |
---|
1336 | { |
---|
1337 | msg = g_new (gchar, 64); |
---|
1338 | g_static_private_set (&msg_private, msg, g_free); |
---|
1339 | } |
---|
1340 | |
---|
1341 | _g_sprintf (msg, "unknown signal (%d)", signum); |
---|
1342 | |
---|
1343 | return msg; |
---|
1344 | } |
---|
1345 | |
---|
1346 | /* Functions g_strlcpy and g_strlcat were originally developed by |
---|
1347 | * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code. |
---|
1348 | * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3 |
---|
1349 | * for more information. |
---|
1350 | */ |
---|
1351 | |
---|
1352 | #ifdef HAVE_STRLCPY |
---|
1353 | /* Use the native ones, if available; they might be implemented in assembly */ |
---|
1354 | gsize |
---|
1355 | g_strlcpy (gchar *dest, |
---|
1356 | const gchar *src, |
---|
1357 | gsize dest_size) |
---|
1358 | { |
---|
1359 | g_return_val_if_fail (dest != NULL, 0); |
---|
1360 | g_return_val_if_fail (src != NULL, 0); |
---|
1361 | |
---|
1362 | return strlcpy (dest, src, dest_size); |
---|
1363 | } |
---|
1364 | |
---|
1365 | gsize |
---|
1366 | g_strlcat (gchar *dest, |
---|
1367 | const gchar *src, |
---|
1368 | gsize dest_size) |
---|
1369 | { |
---|
1370 | g_return_val_if_fail (dest != NULL, 0); |
---|
1371 | g_return_val_if_fail (src != NULL, 0); |
---|
1372 | |
---|
1373 | return strlcat (dest, src, dest_size); |
---|
1374 | } |
---|
1375 | |
---|
1376 | #else /* ! HAVE_STRLCPY */ |
---|
1377 | /* g_strlcpy |
---|
1378 | * |
---|
1379 | * Copy string src to buffer dest (of buffer size dest_size). At most |
---|
1380 | * dest_size-1 characters will be copied. Always NUL terminates |
---|
1381 | * (unless dest_size == 0). This function does NOT allocate memory. |
---|
1382 | * Unlike strncpy, this function doesn't pad dest (so it's often faster). |
---|
1383 | * Returns size of attempted result, strlen(src), |
---|
1384 | * so if retval >= dest_size, truncation occurred. |
---|
1385 | */ |
---|
1386 | gsize |
---|
1387 | g_strlcpy (gchar *dest, |
---|
1388 | const gchar *src, |
---|
1389 | gsize dest_size) |
---|
1390 | { |
---|
1391 | register gchar *d = dest; |
---|
1392 | register const gchar *s = src; |
---|
1393 | register gsize n = dest_size; |
---|
1394 | |
---|
1395 | g_return_val_if_fail (dest != NULL, 0); |
---|
1396 | g_return_val_if_fail (src != NULL, 0); |
---|
1397 | |
---|
1398 | /* Copy as many bytes as will fit */ |
---|
1399 | if (n != 0 && --n != 0) |
---|
1400 | do |
---|
1401 | { |
---|
1402 | register gchar c = *s++; |
---|
1403 | |
---|
1404 | *d++ = c; |
---|
1405 | if (c == 0) |
---|
1406 | break; |
---|
1407 | } |
---|
1408 | while (--n != 0); |
---|
1409 | |
---|
1410 | /* If not enough room in dest, add NUL and traverse rest of src */ |
---|
1411 | if (n == 0) |
---|
1412 | { |
---|
1413 | if (dest_size != 0) |
---|
1414 | *d = 0; |
---|
1415 | while (*s++) |
---|
1416 | ; |
---|
1417 | } |
---|
1418 | |
---|
1419 | return s - src - 1; /* count does not include NUL */ |
---|
1420 | } |
---|
1421 | |
---|
1422 | /* g_strlcat |
---|
1423 | * |
---|
1424 | * Appends string src to buffer dest (of buffer size dest_size). |
---|
1425 | * At most dest_size-1 characters will be copied. |
---|
1426 | * Unlike strncat, dest_size is the full size of dest, not the space left over. |
---|
1427 | * This function does NOT allocate memory. |
---|
1428 | * This always NUL terminates (unless siz == 0 or there were no NUL characters |
---|
1429 | * in the dest_size characters of dest to start with). |
---|
1430 | * Returns size of attempted result, which is |
---|
1431 | * MIN (dest_size, strlen (original dest)) + strlen (src), |
---|
1432 | * so if retval >= dest_size, truncation occurred. |
---|
1433 | */ |
---|
1434 | gsize |
---|
1435 | g_strlcat (gchar *dest, |
---|
1436 | const gchar *src, |
---|
1437 | gsize dest_size) |
---|
1438 | { |
---|
1439 | register gchar *d = dest; |
---|
1440 | register const gchar *s = src; |
---|
1441 | register gsize bytes_left = dest_size; |
---|
1442 | gsize dlength; /* Logically, MIN (strlen (d), dest_size) */ |
---|
1443 | |
---|
1444 | g_return_val_if_fail (dest != NULL, 0); |
---|
1445 | g_return_val_if_fail (src != NULL, 0); |
---|
1446 | |
---|
1447 | /* Find the end of dst and adjust bytes left but don't go past end */ |
---|
1448 | while (*d != 0 && bytes_left-- != 0) |
---|
1449 | d++; |
---|
1450 | dlength = d - dest; |
---|
1451 | bytes_left = dest_size - dlength; |
---|
1452 | |
---|
1453 | if (bytes_left == 0) |
---|
1454 | return dlength + strlen (s); |
---|
1455 | |
---|
1456 | while (*s != 0) |
---|
1457 | { |
---|
1458 | if (bytes_left != 1) |
---|
1459 | { |
---|
1460 | *d++ = *s; |
---|
1461 | bytes_left--; |
---|
1462 | } |
---|
1463 | s++; |
---|
1464 | } |
---|
1465 | *d = 0; |
---|
1466 | |
---|
1467 | return dlength + (s - src); /* count does not include NUL */ |
---|
1468 | } |
---|
1469 | #endif /* ! HAVE_STRLCPY */ |
---|
1470 | |
---|
1471 | /** |
---|
1472 | * g_ascii_strdown: |
---|
1473 | * @str: a string. |
---|
1474 | * @len: length of @str in bytes, or -1 if @str is nul-terminated. |
---|
1475 | * |
---|
1476 | * Converts all upper case ASCII letters to lower case ASCII letters. |
---|
1477 | * |
---|
1478 | * Return value: a newly-allocated string, with all the upper case |
---|
1479 | * characters in @str converted to lower case, with |
---|
1480 | * semantics that exactly match g_ascii_tolower(). (Note |
---|
1481 | * that this is unlike the old g_strdown(), which modified |
---|
1482 | * the string in place.) |
---|
1483 | **/ |
---|
1484 | gchar* |
---|
1485 | g_ascii_strdown (const gchar *str, |
---|
1486 | gssize len) |
---|
1487 | { |
---|
1488 | gchar *result, *s; |
---|
1489 | |
---|
1490 | g_return_val_if_fail (str != NULL, NULL); |
---|
1491 | |
---|
1492 | if (len < 0) |
---|
1493 | len = strlen (str); |
---|
1494 | |
---|
1495 | result = g_strndup (str, len); |
---|
1496 | for (s = result; *s; s++) |
---|
1497 | *s = g_ascii_tolower (*s); |
---|
1498 | |
---|
1499 | return result; |
---|
1500 | } |
---|
1501 | |
---|
1502 | /** |
---|
1503 | * g_ascii_strup: |
---|
1504 | * @str: a string. |
---|
1505 | * @len: length of @str in bytes, or -1 if @str is nul-terminated. |
---|
1506 | * |
---|
1507 | * Converts all lower case ASCII letters to upper case ASCII letters. |
---|
1508 | * |
---|
1509 | * Return value: a newly allocated string, with all the lower case |
---|
1510 | * characters in @str converted to upper case, with |
---|
1511 | * semantics that exactly match g_ascii_toupper(). (Note |
---|
1512 | * that this is unlike the old g_strup(), which modified |
---|
1513 | * the string in place.) |
---|
1514 | **/ |
---|
1515 | gchar* |
---|
1516 | g_ascii_strup (const gchar *str, |
---|
1517 | gssize len) |
---|
1518 | { |
---|
1519 | gchar *result, *s; |
---|
1520 | |
---|
1521 | g_return_val_if_fail (str != NULL, NULL); |
---|
1522 | |
---|
1523 | if (len < 0) |
---|
1524 | len = strlen (str); |
---|
1525 | |
---|
1526 | result = g_strndup (str, len); |
---|
1527 | for (s = result; *s; s++) |
---|
1528 | *s = g_ascii_toupper (*s); |
---|
1529 | |
---|
1530 | return result; |
---|
1531 | } |
---|
1532 | |
---|
1533 | /** |
---|
1534 | * g_strdown: |
---|
1535 | * @string: the string to convert. |
---|
1536 | * |
---|
1537 | * Converts a string to lower case. |
---|
1538 | * |
---|
1539 | * Return value: the string |
---|
1540 | * |
---|
1541 | * Deprecated: This function is totally broken for the reasons discussed in |
---|
1542 | * the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown() |
---|
1543 | * instead. |
---|
1544 | **/ |
---|
1545 | gchar* |
---|
1546 | g_strdown (gchar *string) |
---|
1547 | { |
---|
1548 | register guchar *s; |
---|
1549 | |
---|
1550 | g_return_val_if_fail (string != NULL, NULL); |
---|
1551 | |
---|
1552 | s = (guchar *) string; |
---|
1553 | |
---|
1554 | while (*s) |
---|
1555 | { |
---|
1556 | if (isupper (*s)) |
---|
1557 | *s = tolower (*s); |
---|
1558 | s++; |
---|
1559 | } |
---|
1560 | |
---|
1561 | return (gchar *) string; |
---|
1562 | } |
---|
1563 | |
---|
1564 | /** |
---|
1565 | * g_strup: |
---|
1566 | * @string: the string to convert. |
---|
1567 | * |
---|
1568 | * Converts a string to upper case. |
---|
1569 | * |
---|
1570 | * Return value: the string |
---|
1571 | * |
---|
1572 | * Deprecated: This function is totally broken for the reasons discussed in |
---|
1573 | * the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead. |
---|
1574 | **/ |
---|
1575 | gchar* |
---|
1576 | g_strup (gchar *string) |
---|
1577 | { |
---|
1578 | register guchar *s; |
---|
1579 | |
---|
1580 | g_return_val_if_fail (string != NULL, NULL); |
---|
1581 | |
---|
1582 | s = (guchar *) string; |
---|
1583 | |
---|
1584 | while (*s) |
---|
1585 | { |
---|
1586 | if (islower (*s)) |
---|
1587 | *s = toupper (*s); |
---|
1588 | s++; |
---|
1589 | } |
---|
1590 | |
---|
1591 | return (gchar *) string; |
---|
1592 | } |
---|
1593 | |
---|
1594 | gchar* |
---|
1595 | g_strreverse (gchar *string) |
---|
1596 | { |
---|
1597 | g_return_val_if_fail (string != NULL, NULL); |
---|
1598 | |
---|
1599 | if (*string) |
---|
1600 | { |
---|
1601 | register gchar *h, *t; |
---|
1602 | |
---|
1603 | h = string; |
---|
1604 | t = string + strlen (string) - 1; |
---|
1605 | |
---|
1606 | while (h < t) |
---|
1607 | { |
---|
1608 | register gchar c; |
---|
1609 | |
---|
1610 | c = *h; |
---|
1611 | *h = *t; |
---|
1612 | h++; |
---|
1613 | *t = c; |
---|
1614 | t--; |
---|
1615 | } |
---|
1616 | } |
---|
1617 | |
---|
1618 | return string; |
---|
1619 | } |
---|
1620 | |
---|
1621 | /** |
---|
1622 | * g_ascii_tolower: |
---|
1623 | * @c: any character. |
---|
1624 | * |
---|
1625 | * Convert a character to ASCII lower case. |
---|
1626 | * |
---|
1627 | * Unlike the standard C library tolower() function, this only |
---|
1628 | * recognizes standard ASCII letters and ignores the locale, returning |
---|
1629 | * all non-ASCII characters unchanged, even if they are lower case |
---|
1630 | * letters in a particular character set. Also unlike the standard |
---|
1631 | * library function, this takes and returns a char, not an int, so |
---|
1632 | * don't call it on %EOF but no need to worry about casting to #guchar |
---|
1633 | * before passing a possibly non-ASCII character in. |
---|
1634 | * |
---|
1635 | * Return value: the result of converting @c to lower case. |
---|
1636 | * If @c is not an ASCII upper case letter, |
---|
1637 | * @c is returned unchanged. |
---|
1638 | **/ |
---|
1639 | gchar |
---|
1640 | g_ascii_tolower (gchar c) |
---|
1641 | { |
---|
1642 | return g_ascii_isupper (c) ? c - 'A' + 'a' : c; |
---|
1643 | } |
---|
1644 | |
---|
1645 | /** |
---|
1646 | * g_ascii_toupper: |
---|
1647 | * @c: any character. |
---|
1648 | * |
---|
1649 | * Convert a character to ASCII upper case. |
---|
1650 | * |
---|
1651 | * Unlike the standard C library toupper() function, this only |
---|
1652 | * recognizes standard ASCII letters and ignores the locale, returning |
---|
1653 | * all non-ASCII characters unchanged, even if they are upper case |
---|
1654 | * letters in a particular character set. Also unlike the standard |
---|
1655 | * library function, this takes and returns a char, not an int, so |
---|
1656 | * don't call it on %EOF but no need to worry about casting to #guchar |
---|
1657 | * before passing a possibly non-ASCII character in. |
---|
1658 | * |
---|
1659 | * Return value: the result of converting @c to upper case. |
---|
1660 | * If @c is not an ASCII lower case letter, |
---|
1661 | * @c is returned unchanged. |
---|
1662 | **/ |
---|
1663 | gchar |
---|
1664 | g_ascii_toupper (gchar c) |
---|
1665 | { |
---|
1666 | return g_ascii_islower (c) ? c - 'a' + 'A' : c; |
---|
1667 | } |
---|
1668 | |
---|
1669 | /** |
---|
1670 | * g_ascii_digit_value: |
---|
1671 | * @c: an ASCII character. |
---|
1672 | * |
---|
1673 | * Determines the numeric value of a character as a decimal |
---|
1674 | * digit. Differs from g_unichar_digit_value() because it takes |
---|
1675 | * a char, so there's no worry about sign extension if characters |
---|
1676 | * are signed. |
---|
1677 | * |
---|
1678 | * Return value: If @c is a decimal digit (according to |
---|
1679 | * g_ascii_isdigit()), its numeric value. Otherwise, -1. |
---|
1680 | **/ |
---|
1681 | int |
---|
1682 | g_ascii_digit_value (gchar c) |
---|
1683 | { |
---|
1684 | if (g_ascii_isdigit (c)) |
---|
1685 | return c - '0'; |
---|
1686 | return -1; |
---|
1687 | } |
---|
1688 | |
---|
1689 | /** |
---|
1690 | * g_ascii_xdigit_value: |
---|
1691 | * @c: an ASCII character. |
---|
1692 | * |
---|
1693 | * Determines the numeric value of a character as a hexidecimal |
---|
1694 | * digit. Differs from g_unichar_xdigit_value() because it takes |
---|
1695 | * a char, so there's no worry about sign extension if characters |
---|
1696 | * are signed. |
---|
1697 | * |
---|
1698 | * Return value: If @c is a hex digit (according to |
---|
1699 | * g_ascii_isxdigit()), its numeric value. Otherwise, -1. |
---|
1700 | **/ |
---|
1701 | int |
---|
1702 | g_ascii_xdigit_value (gchar c) |
---|
1703 | { |
---|
1704 | if (c >= 'A' && c <= 'F') |
---|
1705 | return c - 'A' + 10; |
---|
1706 | if (c >= 'a' && c <= 'f') |
---|
1707 | return c - 'a' + 10; |
---|
1708 | return g_ascii_digit_value (c); |
---|
1709 | } |
---|
1710 | |
---|
1711 | /** |
---|
1712 | * g_ascii_strcasecmp: |
---|
1713 | * @s1: string to compare with @s2. |
---|
1714 | * @s2: string to compare with @s1. |
---|
1715 | * |
---|
1716 | * Compare two strings, ignoring the case of ASCII characters. |
---|
1717 | * |
---|
1718 | * Unlike the BSD strcasecmp() function, this only recognizes standard |
---|
1719 | * ASCII letters and ignores the locale, treating all non-ASCII |
---|
1720 | * characters as if they are not letters. |
---|
1721 | * |
---|
1722 | * Return value: an integer less than, equal to, or greater than |
---|
1723 | * zero if @s1 is found, respectively, to be less than, |
---|
1724 | * to match, or to be greater than @s2. |
---|
1725 | **/ |
---|
1726 | gint |
---|
1727 | g_ascii_strcasecmp (const gchar *s1, |
---|
1728 | const gchar *s2) |
---|
1729 | { |
---|
1730 | gint c1, c2; |
---|
1731 | |
---|
1732 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1733 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1734 | |
---|
1735 | while (*s1 && *s2) |
---|
1736 | { |
---|
1737 | c1 = (gint)(guchar) g_ascii_tolower (*s1); |
---|
1738 | c2 = (gint)(guchar) g_ascii_tolower (*s2); |
---|
1739 | if (c1 != c2) |
---|
1740 | return (c1 - c2); |
---|
1741 | s1++; s2++; |
---|
1742 | } |
---|
1743 | |
---|
1744 | return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); |
---|
1745 | } |
---|
1746 | |
---|
1747 | /** |
---|
1748 | * g_ascii_strncasecmp: |
---|
1749 | * @s1: string to compare with @s2. |
---|
1750 | * @s2: string to compare with @s1. |
---|
1751 | * @n: number of characters to compare. |
---|
1752 | * |
---|
1753 | * Compare @s1 and @s2, ignoring the case of ASCII characters and any |
---|
1754 | * characters after the first @n in each string. |
---|
1755 | * |
---|
1756 | * Unlike the BSD strcasecmp() function, this only recognizes standard |
---|
1757 | * ASCII letters and ignores the locale, treating all non-ASCII |
---|
1758 | * characters as if they are not letters. |
---|
1759 | * |
---|
1760 | * Return value: an integer less than, equal to, or greater than zero |
---|
1761 | * if the first @n bytes of @s1 is found, respectively, |
---|
1762 | * to be less than, to match, or to be greater than the |
---|
1763 | * first @n bytes of @s2. |
---|
1764 | **/ |
---|
1765 | gint |
---|
1766 | g_ascii_strncasecmp (const gchar *s1, |
---|
1767 | const gchar *s2, |
---|
1768 | gsize n) |
---|
1769 | { |
---|
1770 | gint c1, c2; |
---|
1771 | |
---|
1772 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1773 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1774 | |
---|
1775 | while (n && *s1 && *s2) |
---|
1776 | { |
---|
1777 | n -= 1; |
---|
1778 | c1 = (gint)(guchar) g_ascii_tolower (*s1); |
---|
1779 | c2 = (gint)(guchar) g_ascii_tolower (*s2); |
---|
1780 | if (c1 != c2) |
---|
1781 | return (c1 - c2); |
---|
1782 | s1++; s2++; |
---|
1783 | } |
---|
1784 | |
---|
1785 | if (n) |
---|
1786 | return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); |
---|
1787 | else |
---|
1788 | return 0; |
---|
1789 | } |
---|
1790 | |
---|
1791 | /** |
---|
1792 | * g_strcasecmp: |
---|
1793 | * @s1: a string. |
---|
1794 | * @s2: a string to compare with @s1. |
---|
1795 | * |
---|
1796 | * A case-insensitive string comparison, corresponding to the standard |
---|
1797 | * strcasecmp() function on platforms which support it. |
---|
1798 | * |
---|
1799 | * Return value: 0 if the strings match, a negative value if @s1 < @s2, |
---|
1800 | * or a positive value if @s1 > @s2. |
---|
1801 | * |
---|
1802 | * Deprecated: See g_strncasecmp() for a discussion of why this function is |
---|
1803 | * deprecated and how to replace it. |
---|
1804 | **/ |
---|
1805 | gint |
---|
1806 | g_strcasecmp (const gchar *s1, |
---|
1807 | const gchar *s2) |
---|
1808 | { |
---|
1809 | #ifdef HAVE_STRCASECMP |
---|
1810 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1811 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1812 | |
---|
1813 | return strcasecmp (s1, s2); |
---|
1814 | #else |
---|
1815 | gint c1, c2; |
---|
1816 | |
---|
1817 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1818 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1819 | |
---|
1820 | while (*s1 && *s2) |
---|
1821 | { |
---|
1822 | /* According to A. Cox, some platforms have islower's that |
---|
1823 | * don't work right on non-uppercase |
---|
1824 | */ |
---|
1825 | c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; |
---|
1826 | c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; |
---|
1827 | if (c1 != c2) |
---|
1828 | return (c1 - c2); |
---|
1829 | s1++; s2++; |
---|
1830 | } |
---|
1831 | |
---|
1832 | return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); |
---|
1833 | #endif |
---|
1834 | } |
---|
1835 | |
---|
1836 | /** |
---|
1837 | * g_strncasecmp: |
---|
1838 | * @s1: a string. |
---|
1839 | * @s2: a string to compare with @s1. |
---|
1840 | * @n: the maximum number of characters to compare. |
---|
1841 | * |
---|
1842 | * A case-insensitive string comparison, corresponding to the standard |
---|
1843 | * strncasecmp() function on platforms which support it. |
---|
1844 | * It is similar to g_strcasecmp() except it only compares the first @n |
---|
1845 | * characters of the strings. |
---|
1846 | * |
---|
1847 | * Return value: 0 if the strings match, a negative value if @s1 < @s2, |
---|
1848 | * or a positive value if @s1 > @s2. |
---|
1849 | * |
---|
1850 | * Deprecated: The problem with g_strncasecmp() is that it does the |
---|
1851 | * comparison by calling toupper()/tolower(). These functions are |
---|
1852 | * locale-specific and operate on single bytes. However, it is impossible |
---|
1853 | * to handle things correctly from an I18N standpoint by operating on |
---|
1854 | * bytes, since characters may be multibyte. Thus g_strncasecmp() is |
---|
1855 | * broken if your string is guaranteed to be ASCII, since it's |
---|
1856 | * locale-sensitive, and it's broken if your string is localized, since |
---|
1857 | * it doesn't work on many encodings at all, including UTF-8, EUC-JP, |
---|
1858 | * etc. |
---|
1859 | * |
---|
1860 | * There are therefore two replacement functions: g_ascii_strncasecmp(), |
---|
1861 | * which only works on ASCII and is not locale-sensitive, and |
---|
1862 | * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8. |
---|
1863 | **/ |
---|
1864 | gint |
---|
1865 | g_strncasecmp (const gchar *s1, |
---|
1866 | const gchar *s2, |
---|
1867 | gsize n) |
---|
1868 | { |
---|
1869 | #ifdef HAVE_STRNCASECMP |
---|
1870 | return strncasecmp (s1, s2, n); |
---|
1871 | #else |
---|
1872 | gint c1, c2; |
---|
1873 | |
---|
1874 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1875 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1876 | |
---|
1877 | while (n && *s1 && *s2) |
---|
1878 | { |
---|
1879 | n -= 1; |
---|
1880 | /* According to A. Cox, some platforms have islower's that |
---|
1881 | * don't work right on non-uppercase |
---|
1882 | */ |
---|
1883 | c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; |
---|
1884 | c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; |
---|
1885 | if (c1 != c2) |
---|
1886 | return (c1 - c2); |
---|
1887 | s1++; s2++; |
---|
1888 | } |
---|
1889 | |
---|
1890 | if (n) |
---|
1891 | return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); |
---|
1892 | else |
---|
1893 | return 0; |
---|
1894 | #endif |
---|
1895 | } |
---|
1896 | |
---|
1897 | gchar* |
---|
1898 | g_strdelimit (gchar *string, |
---|
1899 | const gchar *delimiters, |
---|
1900 | gchar new_delim) |
---|
1901 | { |
---|
1902 | register gchar *c; |
---|
1903 | |
---|
1904 | g_return_val_if_fail (string != NULL, NULL); |
---|
1905 | |
---|
1906 | if (!delimiters) |
---|
1907 | delimiters = G_STR_DELIMITERS; |
---|
1908 | |
---|
1909 | for (c = string; *c; c++) |
---|
1910 | { |
---|
1911 | if (strchr (delimiters, *c)) |
---|
1912 | *c = new_delim; |
---|
1913 | } |
---|
1914 | |
---|
1915 | return string; |
---|
1916 | } |
---|
1917 | |
---|
1918 | gchar* |
---|
1919 | g_strcanon (gchar *string, |
---|
1920 | const gchar *valid_chars, |
---|
1921 | gchar substitutor) |
---|
1922 | { |
---|
1923 | register gchar *c; |
---|
1924 | |
---|
1925 | g_return_val_if_fail (string != NULL, NULL); |
---|
1926 | g_return_val_if_fail (valid_chars != NULL, NULL); |
---|
1927 | |
---|
1928 | for (c = string; *c; c++) |
---|
1929 | { |
---|
1930 | if (!strchr (valid_chars, *c)) |
---|
1931 | *c = substitutor; |
---|
1932 | } |
---|
1933 | |
---|
1934 | return string; |
---|
1935 | } |
---|
1936 | |
---|
1937 | gchar* |
---|
1938 | g_strcompress (const gchar *source) |
---|
1939 | { |
---|
1940 | const gchar *p = source, *octal; |
---|
1941 | gchar *dest = g_malloc (strlen (source) + 1); |
---|
1942 | gchar *q = dest; |
---|
1943 | |
---|
1944 | while (*p) |
---|
1945 | { |
---|
1946 | if (*p == '\\') |
---|
1947 | { |
---|
1948 | p++; |
---|
1949 | switch (*p) |
---|
1950 | { |
---|
1951 | case '0': case '1': case '2': case '3': case '4': |
---|
1952 | case '5': case '6': case '7': |
---|
1953 | *q = 0; |
---|
1954 | octal = p; |
---|
1955 | while ((p < octal + 3) && (*p >= '0') && (*p <= '7')) |
---|
1956 | { |
---|
1957 | *q = (*q * 8) + (*p - '0'); |
---|
1958 | p++; |
---|
1959 | } |
---|
1960 | q++; |
---|
1961 | p--; |
---|
1962 | break; |
---|
1963 | case 'b': |
---|
1964 | *q++ = '\b'; |
---|
1965 | break; |
---|
1966 | case 'f': |
---|
1967 | *q++ = '\f'; |
---|
1968 | break; |
---|
1969 | case 'n': |
---|
1970 | *q++ = '\n'; |
---|
1971 | break; |
---|
1972 | case 'r': |
---|
1973 | *q++ = '\r'; |
---|
1974 | break; |
---|
1975 | case 't': |
---|
1976 | *q++ = '\t'; |
---|
1977 | break; |
---|
1978 | default: /* Also handles \" and \\ */ |
---|
1979 | *q++ = *p; |
---|
1980 | break; |
---|
1981 | } |
---|
1982 | } |
---|
1983 | else |
---|
1984 | *q++ = *p; |
---|
1985 | p++; |
---|
1986 | } |
---|
1987 | *q = 0; |
---|
1988 | |
---|
1989 | return dest; |
---|
1990 | } |
---|
1991 | |
---|
1992 | gchar * |
---|
1993 | g_strescape (const gchar *source, |
---|
1994 | const gchar *exceptions) |
---|
1995 | { |
---|
1996 | const guchar *p; |
---|
1997 | gchar *dest; |
---|
1998 | gchar *q; |
---|
1999 | guchar excmap[256]; |
---|
2000 | |
---|
2001 | g_return_val_if_fail (source != NULL, NULL); |
---|
2002 | |
---|
2003 | p = (guchar *) source; |
---|
2004 | /* Each source byte needs maximally four destination chars (\777) */ |
---|
2005 | q = dest = g_malloc (strlen (source) * 4 + 1); |
---|
2006 | |
---|
2007 | memset (excmap, 0, 256); |
---|
2008 | if (exceptions) |
---|
2009 | { |
---|
2010 | guchar *e = (guchar *) exceptions; |
---|
2011 | |
---|
2012 | while (*e) |
---|
2013 | { |
---|
2014 | excmap[*e] = 1; |
---|
2015 | e++; |
---|
2016 | } |
---|
2017 | } |
---|
2018 | |
---|
2019 | while (*p) |
---|
2020 | { |
---|
2021 | if (excmap[*p]) |
---|
2022 | *q++ = *p; |
---|
2023 | else |
---|
2024 | { |
---|
2025 | switch (*p) |
---|
2026 | { |
---|
2027 | case '\b': |
---|
2028 | *q++ = '\\'; |
---|
2029 | *q++ = 'b'; |
---|
2030 | break; |
---|
2031 | case '\f': |
---|
2032 | *q++ = '\\'; |
---|
2033 | *q++ = 'f'; |
---|
2034 | break; |
---|
2035 | case '\n': |
---|
2036 | *q++ = '\\'; |
---|
2037 | *q++ = 'n'; |
---|
2038 | break; |
---|
2039 | case '\r': |
---|
2040 | *q++ = '\\'; |
---|
2041 | *q++ = 'r'; |
---|
2042 | break; |
---|
2043 | case '\t': |
---|
2044 | *q++ = '\\'; |
---|
2045 | *q++ = 't'; |
---|
2046 | break; |
---|
2047 | case '\\': |
---|
2048 | *q++ = '\\'; |
---|
2049 | *q++ = '\\'; |
---|
2050 | break; |
---|
2051 | case '"': |
---|
2052 | *q++ = '\\'; |
---|
2053 | *q++ = '"'; |
---|
2054 | break; |
---|
2055 | default: |
---|
2056 | if ((*p < ' ') || (*p >= 0177)) |
---|
2057 | { |
---|
2058 | *q++ = '\\'; |
---|
2059 | *q++ = '0' + (((*p) >> 6) & 07); |
---|
2060 | *q++ = '0' + (((*p) >> 3) & 07); |
---|
2061 | *q++ = '0' + ((*p) & 07); |
---|
2062 | } |
---|
2063 | else |
---|
2064 | *q++ = *p; |
---|
2065 | break; |
---|
2066 | } |
---|
2067 | } |
---|
2068 | p++; |
---|
2069 | } |
---|
2070 | *q = 0; |
---|
2071 | return dest; |
---|
2072 | } |
---|
2073 | |
---|
2074 | gchar* |
---|
2075 | g_strchug (gchar *string) |
---|
2076 | { |
---|
2077 | guchar *start; |
---|
2078 | |
---|
2079 | g_return_val_if_fail (string != NULL, NULL); |
---|
2080 | |
---|
2081 | for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++) |
---|
2082 | ; |
---|
2083 | |
---|
2084 | g_memmove (string, start, strlen ((gchar *) start) + 1); |
---|
2085 | |
---|
2086 | return string; |
---|
2087 | } |
---|
2088 | |
---|
2089 | gchar* |
---|
2090 | g_strchomp (gchar *string) |
---|
2091 | { |
---|
2092 | gsize len; |
---|
2093 | |
---|
2094 | g_return_val_if_fail (string != NULL, NULL); |
---|
2095 | |
---|
2096 | len = strlen (string); |
---|
2097 | while (len--) |
---|
2098 | { |
---|
2099 | if (g_ascii_isspace ((guchar) string[len])) |
---|
2100 | string[len] = '\0'; |
---|
2101 | else |
---|
2102 | break; |
---|
2103 | } |
---|
2104 | |
---|
2105 | return string; |
---|
2106 | } |
---|
2107 | |
---|
2108 | /** |
---|
2109 | * g_strsplit: |
---|
2110 | * @string: a string to split. |
---|
2111 | * @delimiter: a string which specifies the places at which to split the string. |
---|
2112 | * The delimiter is not included in any of the resulting strings, unless |
---|
2113 | * @max_tokens is reached. |
---|
2114 | * @max_tokens: the maximum number of pieces to split @string into. If this is |
---|
2115 | * less than 1, the string is split completely. |
---|
2116 | * |
---|
2117 | * Splits a string into a maximum of @max_tokens pieces, using the given |
---|
2118 | * @delimiter. If @max_tokens is reached, the remainder of @string is appended |
---|
2119 | * to the last token. |
---|
2120 | * |
---|
2121 | * As a special case, the result of splitting the empty string "" is an empty |
---|
2122 | * vector, not a vector containing a single string. The reason for this |
---|
2123 | * special case is that being able to represent a empty vector is typically |
---|
2124 | * more useful than consistent handling of empty elements. If you do need |
---|
2125 | * to represent empty elements, you'll need to check for the empty string |
---|
2126 | * before calling g_strsplit(). |
---|
2127 | * |
---|
2128 | * Return value: a newly-allocated %NULL-terminated array of strings. Use |
---|
2129 | * g_strfreev() to free it. |
---|
2130 | **/ |
---|
2131 | gchar** |
---|
2132 | g_strsplit (const gchar *string, |
---|
2133 | const gchar *delimiter, |
---|
2134 | gint max_tokens) |
---|
2135 | { |
---|
2136 | GSList *string_list = NULL, *slist; |
---|
2137 | gchar **str_array, *s; |
---|
2138 | guint n = 0; |
---|
2139 | const gchar *remainder; |
---|
2140 | |
---|
2141 | g_return_val_if_fail (string != NULL, NULL); |
---|
2142 | g_return_val_if_fail (delimiter != NULL, NULL); |
---|
2143 | g_return_val_if_fail (delimiter[0] != '\0', NULL); |
---|
2144 | |
---|
2145 | if (max_tokens < 1) |
---|
2146 | max_tokens = G_MAXINT; |
---|
2147 | |
---|
2148 | remainder = string; |
---|
2149 | s = strstr (remainder, delimiter); |
---|
2150 | if (s) |
---|
2151 | { |
---|
2152 | gsize delimiter_len = strlen (delimiter); |
---|
2153 | |
---|
2154 | while (--max_tokens && s) |
---|
2155 | { |
---|
2156 | gsize len; |
---|
2157 | gchar *new_string; |
---|
2158 | |
---|
2159 | len = s - remainder; |
---|
2160 | new_string = g_new (gchar, len + 1); |
---|
2161 | strncpy (new_string, remainder, len); |
---|
2162 | new_string[len] = 0; |
---|
2163 | string_list = g_slist_prepend (string_list, new_string); |
---|
2164 | n++; |
---|
2165 | remainder = s + delimiter_len; |
---|
2166 | s = strstr (remainder, delimiter); |
---|
2167 | } |
---|
2168 | } |
---|
2169 | if (*string) |
---|
2170 | { |
---|
2171 | n++; |
---|
2172 | string_list = g_slist_prepend (string_list, g_strdup (remainder)); |
---|
2173 | } |
---|
2174 | |
---|
2175 | str_array = g_new (gchar*, n + 1); |
---|
2176 | |
---|
2177 | str_array[n--] = NULL; |
---|
2178 | for (slist = string_list; slist; slist = slist->next) |
---|
2179 | str_array[n--] = slist->data; |
---|
2180 | |
---|
2181 | g_slist_free (string_list); |
---|
2182 | |
---|
2183 | return str_array; |
---|
2184 | } |
---|
2185 | |
---|
2186 | void |
---|
2187 | g_strfreev (gchar **str_array) |
---|
2188 | { |
---|
2189 | if (str_array) |
---|
2190 | { |
---|
2191 | int i; |
---|
2192 | |
---|
2193 | for(i = 0; str_array[i] != NULL; i++) |
---|
2194 | g_free(str_array[i]); |
---|
2195 | |
---|
2196 | g_free (str_array); |
---|
2197 | } |
---|
2198 | } |
---|
2199 | |
---|
2200 | /** |
---|
2201 | * g_strdupv: |
---|
2202 | * @str_array: %NULL-terminated array of strings. |
---|
2203 | * |
---|
2204 | * Copies %NULL-terminated array of strings. The copy is a deep copy; |
---|
2205 | * the new array should be freed by first freeing each string, then |
---|
2206 | * the array itself. g_strfreev() does this for you. If called |
---|
2207 | * on a %NULL value, g_strdupv() simply returns %NULL. |
---|
2208 | * |
---|
2209 | * Return value: a new %NULL-terminated array of strings. |
---|
2210 | **/ |
---|
2211 | gchar** |
---|
2212 | g_strdupv (gchar **str_array) |
---|
2213 | { |
---|
2214 | if (str_array) |
---|
2215 | { |
---|
2216 | gint i; |
---|
2217 | gchar **retval; |
---|
2218 | |
---|
2219 | i = 0; |
---|
2220 | while (str_array[i]) |
---|
2221 | ++i; |
---|
2222 | |
---|
2223 | retval = g_new (gchar*, i + 1); |
---|
2224 | |
---|
2225 | i = 0; |
---|
2226 | while (str_array[i]) |
---|
2227 | { |
---|
2228 | retval[i] = g_strdup (str_array[i]); |
---|
2229 | ++i; |
---|
2230 | } |
---|
2231 | retval[i] = NULL; |
---|
2232 | |
---|
2233 | return retval; |
---|
2234 | } |
---|
2235 | else |
---|
2236 | return NULL; |
---|
2237 | } |
---|
2238 | |
---|
2239 | gchar* |
---|
2240 | g_strjoinv (const gchar *separator, |
---|
2241 | gchar **str_array) |
---|
2242 | { |
---|
2243 | gchar *string; |
---|
2244 | gchar *ptr; |
---|
2245 | |
---|
2246 | g_return_val_if_fail (str_array != NULL, NULL); |
---|
2247 | |
---|
2248 | if (separator == NULL) |
---|
2249 | separator = ""; |
---|
2250 | |
---|
2251 | if (*str_array) |
---|
2252 | { |
---|
2253 | gint i; |
---|
2254 | gsize len; |
---|
2255 | gsize separator_len; |
---|
2256 | |
---|
2257 | separator_len = strlen (separator); |
---|
2258 | /* First part, getting length */ |
---|
2259 | len = 1 + strlen (str_array[0]); |
---|
2260 | for (i = 1; str_array[i] != NULL; i++) |
---|
2261 | len += strlen (str_array[i]); |
---|
2262 | len += separator_len * (i - 1); |
---|
2263 | |
---|
2264 | /* Second part, building string */ |
---|
2265 | string = g_new (gchar, len); |
---|
2266 | ptr = g_stpcpy (string, *str_array); |
---|
2267 | for (i = 1; str_array[i] != NULL; i++) |
---|
2268 | { |
---|
2269 | ptr = g_stpcpy (ptr, separator); |
---|
2270 | ptr = g_stpcpy (ptr, str_array[i]); |
---|
2271 | } |
---|
2272 | } |
---|
2273 | else |
---|
2274 | string = g_strdup (""); |
---|
2275 | |
---|
2276 | return string; |
---|
2277 | } |
---|
2278 | |
---|
2279 | gchar* |
---|
2280 | g_strjoin (const gchar *separator, |
---|
2281 | ...) |
---|
2282 | { |
---|
2283 | gchar *string, *s; |
---|
2284 | va_list args; |
---|
2285 | gsize len; |
---|
2286 | gsize separator_len; |
---|
2287 | gchar *ptr; |
---|
2288 | |
---|
2289 | if (separator == NULL) |
---|
2290 | separator = ""; |
---|
2291 | |
---|
2292 | separator_len = strlen (separator); |
---|
2293 | |
---|
2294 | va_start (args, separator); |
---|
2295 | |
---|
2296 | s = va_arg (args, gchar*); |
---|
2297 | |
---|
2298 | if (s) |
---|
2299 | { |
---|
2300 | /* First part, getting length */ |
---|
2301 | len = 1 + strlen (s); |
---|
2302 | |
---|
2303 | s = va_arg (args, gchar*); |
---|
2304 | while (s) |
---|
2305 | { |
---|
2306 | len += separator_len + strlen (s); |
---|
2307 | s = va_arg (args, gchar*); |
---|
2308 | } |
---|
2309 | va_end (args); |
---|
2310 | |
---|
2311 | /* Second part, building string */ |
---|
2312 | string = g_new (gchar, len); |
---|
2313 | |
---|
2314 | va_start (args, separator); |
---|
2315 | |
---|
2316 | s = va_arg (args, gchar*); |
---|
2317 | ptr = g_stpcpy (string, s); |
---|
2318 | |
---|
2319 | s = va_arg (args, gchar*); |
---|
2320 | while (s) |
---|
2321 | { |
---|
2322 | ptr = g_stpcpy (ptr, separator); |
---|
2323 | ptr = g_stpcpy (ptr, s); |
---|
2324 | s = va_arg (args, gchar*); |
---|
2325 | } |
---|
2326 | } |
---|
2327 | else |
---|
2328 | string = g_strdup (""); |
---|
2329 | |
---|
2330 | va_end (args); |
---|
2331 | |
---|
2332 | return string; |
---|
2333 | } |
---|
2334 | |
---|
2335 | |
---|
2336 | /** |
---|
2337 | * g_strstr_len: |
---|
2338 | * @haystack: a string. |
---|
2339 | * @haystack_len: the maximum length of @haystack. |
---|
2340 | * @needle: the string to search for. |
---|
2341 | * |
---|
2342 | * Searches the string @haystack for the first occurrence |
---|
2343 | * of the string @needle, limiting the length of the search |
---|
2344 | * to @haystack_len. |
---|
2345 | * |
---|
2346 | * Return value: a pointer to the found occurrence, or |
---|
2347 | * %NULL if not found. |
---|
2348 | **/ |
---|
2349 | gchar * |
---|
2350 | g_strstr_len (const gchar *haystack, |
---|
2351 | gssize haystack_len, |
---|
2352 | const gchar *needle) |
---|
2353 | { |
---|
2354 | g_return_val_if_fail (haystack != NULL, NULL); |
---|
2355 | g_return_val_if_fail (needle != NULL, NULL); |
---|
2356 | |
---|
2357 | if (haystack_len < 0) |
---|
2358 | return strstr (haystack, needle); |
---|
2359 | else |
---|
2360 | { |
---|
2361 | const gchar *p = haystack; |
---|
2362 | gsize needle_len = strlen (needle); |
---|
2363 | const gchar *end; |
---|
2364 | gsize i; |
---|
2365 | |
---|
2366 | if (needle_len == 0) |
---|
2367 | return (gchar *)haystack; |
---|
2368 | |
---|
2369 | if (haystack_len < needle_len) |
---|
2370 | return NULL; |
---|
2371 | |
---|
2372 | end = haystack + haystack_len - needle_len; |
---|
2373 | |
---|
2374 | while (*p && p <= end) |
---|
2375 | { |
---|
2376 | for (i = 0; i < needle_len; i++) |
---|
2377 | if (p[i] != needle[i]) |
---|
2378 | goto next; |
---|
2379 | |
---|
2380 | return (gchar *)p; |
---|
2381 | |
---|
2382 | next: |
---|
2383 | p++; |
---|
2384 | } |
---|
2385 | |
---|
2386 | return NULL; |
---|
2387 | } |
---|
2388 | } |
---|
2389 | |
---|
2390 | /** |
---|
2391 | * g_strrstr: |
---|
2392 | * @haystack: a nul-terminated string. |
---|
2393 | * @needle: the nul-terminated string to search for. |
---|
2394 | * |
---|
2395 | * Searches the string @haystack for the last occurrence |
---|
2396 | * of the string @needle. |
---|
2397 | * |
---|
2398 | * Return value: a pointer to the found occurrence, or |
---|
2399 | * %NULL if not found. |
---|
2400 | **/ |
---|
2401 | gchar * |
---|
2402 | g_strrstr (const gchar *haystack, |
---|
2403 | const gchar *needle) |
---|
2404 | { |
---|
2405 | gsize i; |
---|
2406 | gsize needle_len; |
---|
2407 | gsize haystack_len; |
---|
2408 | const gchar *p; |
---|
2409 | |
---|
2410 | g_return_val_if_fail (haystack != NULL, NULL); |
---|
2411 | g_return_val_if_fail (needle != NULL, NULL); |
---|
2412 | |
---|
2413 | needle_len = strlen (needle); |
---|
2414 | haystack_len = strlen (haystack); |
---|
2415 | |
---|
2416 | if (needle_len == 0) |
---|
2417 | return (gchar *)haystack; |
---|
2418 | |
---|
2419 | if (haystack_len < needle_len) |
---|
2420 | return NULL; |
---|
2421 | |
---|
2422 | p = haystack + haystack_len - needle_len; |
---|
2423 | |
---|
2424 | while (p >= haystack) |
---|
2425 | { |
---|
2426 | for (i = 0; i < needle_len; i++) |
---|
2427 | if (p[i] != needle[i]) |
---|
2428 | goto next; |
---|
2429 | |
---|
2430 | return (gchar *)p; |
---|
2431 | |
---|
2432 | next: |
---|
2433 | p--; |
---|
2434 | } |
---|
2435 | |
---|
2436 | return NULL; |
---|
2437 | } |
---|
2438 | |
---|
2439 | /** |
---|
2440 | * g_strrstr_len: |
---|
2441 | * @haystack: a nul-terminated string. |
---|
2442 | * @haystack_len: the maximum length of @haystack. |
---|
2443 | * @needle: the nul-terminated string to search for. |
---|
2444 | * |
---|
2445 | * Searches the string @haystack for the last occurrence |
---|
2446 | * of the string @needle, limiting the length of the search |
---|
2447 | * to @haystack_len. |
---|
2448 | * |
---|
2449 | * Return value: a pointer to the found occurrence, or |
---|
2450 | * %NULL if not found. |
---|
2451 | **/ |
---|
2452 | gchar * |
---|
2453 | g_strrstr_len (const gchar *haystack, |
---|
2454 | gssize haystack_len, |
---|
2455 | const gchar *needle) |
---|
2456 | { |
---|
2457 | g_return_val_if_fail (haystack != NULL, NULL); |
---|
2458 | g_return_val_if_fail (needle != NULL, NULL); |
---|
2459 | |
---|
2460 | if (haystack_len < 0) |
---|
2461 | return g_strrstr (haystack, needle); |
---|
2462 | else |
---|
2463 | { |
---|
2464 | gsize needle_len = strlen (needle); |
---|
2465 | const gchar *haystack_max = haystack + haystack_len; |
---|
2466 | const gchar *p = haystack; |
---|
2467 | gsize i; |
---|
2468 | |
---|
2469 | while (p < haystack_max && *p) |
---|
2470 | p++; |
---|
2471 | |
---|
2472 | if (p < haystack + needle_len) |
---|
2473 | return NULL; |
---|
2474 | |
---|
2475 | p -= needle_len; |
---|
2476 | |
---|
2477 | while (p >= haystack) |
---|
2478 | { |
---|
2479 | for (i = 0; i < needle_len; i++) |
---|
2480 | if (p[i] != needle[i]) |
---|
2481 | goto next; |
---|
2482 | |
---|
2483 | return (gchar *)p; |
---|
2484 | |
---|
2485 | next: |
---|
2486 | p--; |
---|
2487 | } |
---|
2488 | |
---|
2489 | return NULL; |
---|
2490 | } |
---|
2491 | } |
---|
2492 | |
---|
2493 | |
---|
2494 | /** |
---|
2495 | * g_str_has_suffix: |
---|
2496 | * @str: a nul-terminated string. |
---|
2497 | * @suffix: the nul-terminated suffix to look for. |
---|
2498 | * |
---|
2499 | * Looks whether the string @str ends with @suffix. |
---|
2500 | * |
---|
2501 | * Return value: %TRUE if @str end with @suffix, %FALSE otherwise. |
---|
2502 | * |
---|
2503 | * Since: 2.2 |
---|
2504 | **/ |
---|
2505 | gboolean |
---|
2506 | g_str_has_suffix (const gchar *str, |
---|
2507 | const gchar *suffix) |
---|
2508 | { |
---|
2509 | int str_len; |
---|
2510 | int suffix_len; |
---|
2511 | |
---|
2512 | g_return_val_if_fail (str != NULL, FALSE); |
---|
2513 | g_return_val_if_fail (suffix != NULL, FALSE); |
---|
2514 | |
---|
2515 | str_len = strlen (str); |
---|
2516 | suffix_len = strlen (suffix); |
---|
2517 | |
---|
2518 | if (str_len < suffix_len) |
---|
2519 | return FALSE; |
---|
2520 | |
---|
2521 | return strcmp (str + str_len - suffix_len, suffix) == 0; |
---|
2522 | } |
---|
2523 | |
---|
2524 | /** |
---|
2525 | * g_str_has_prefix: |
---|
2526 | * @str: a nul-terminated string. |
---|
2527 | * @prefix: the nul-terminated prefix to look for. |
---|
2528 | * |
---|
2529 | * Looks whether the string @str begins with @prefix. |
---|
2530 | * |
---|
2531 | * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise. |
---|
2532 | * |
---|
2533 | * Since: 2.2 |
---|
2534 | **/ |
---|
2535 | gboolean |
---|
2536 | g_str_has_prefix (const gchar *str, |
---|
2537 | const gchar *prefix) |
---|
2538 | { |
---|
2539 | int str_len; |
---|
2540 | int prefix_len; |
---|
2541 | |
---|
2542 | g_return_val_if_fail (str != NULL, FALSE); |
---|
2543 | g_return_val_if_fail (prefix != NULL, FALSE); |
---|
2544 | |
---|
2545 | str_len = strlen (str); |
---|
2546 | prefix_len = strlen (prefix); |
---|
2547 | |
---|
2548 | if (str_len < prefix_len) |
---|
2549 | return FALSE; |
---|
2550 | |
---|
2551 | return strncmp (str, prefix, prefix_len) == 0; |
---|
2552 | } |
---|
2553 | |
---|