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 Library 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 | * Library General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU Library 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-1999. 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 | #ifdef HAVE_CONFIG_H |
---|
32 | #include <config.h> |
---|
33 | #endif |
---|
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 | #include "glib.h" |
---|
46 | /* do not include <unistd.h> in this place since it |
---|
47 | * inteferes with g_strsignal() on some OSes |
---|
48 | */ |
---|
49 | |
---|
50 | typedef union _GDoubleIEEE754 GDoubleIEEE754; |
---|
51 | #define G_IEEE754_DOUBLE_BIAS (1023) |
---|
52 | /* multiply with base2 exponent to get base10 exponent (nomal numbers) */ |
---|
53 | #define G_LOG_2_BASE_10 (0.30102999566398119521) |
---|
54 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN |
---|
55 | union _GDoubleIEEE754 |
---|
56 | { |
---|
57 | gdouble v_double; |
---|
58 | struct { |
---|
59 | guint mantissa_low : 32; |
---|
60 | guint mantissa_high : 20; |
---|
61 | guint biased_exponent : 11; |
---|
62 | guint sign : 1; |
---|
63 | } mpn; |
---|
64 | }; |
---|
65 | #elif G_BYTE_ORDER == G_BIG_ENDIAN |
---|
66 | union _GDoubleIEEE754 |
---|
67 | { |
---|
68 | gdouble v_double; |
---|
69 | struct { |
---|
70 | guint sign : 1; |
---|
71 | guint biased_exponent : 11; |
---|
72 | guint mantissa_high : 20; |
---|
73 | guint mantissa_low : 32; |
---|
74 | } mpn; |
---|
75 | }; |
---|
76 | #else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ |
---|
77 | #error unknown ENDIAN type |
---|
78 | #endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ |
---|
79 | |
---|
80 | gchar* |
---|
81 | g_strdup (const gchar *str) |
---|
82 | { |
---|
83 | gchar *new_str; |
---|
84 | |
---|
85 | if (str) |
---|
86 | { |
---|
87 | new_str = g_new (char, strlen (str) + 1); |
---|
88 | strcpy (new_str, str); |
---|
89 | } |
---|
90 | else |
---|
91 | new_str = NULL; |
---|
92 | |
---|
93 | return new_str; |
---|
94 | } |
---|
95 | |
---|
96 | gpointer |
---|
97 | g_memdup (gconstpointer mem, |
---|
98 | guint byte_size) |
---|
99 | { |
---|
100 | gpointer new_mem; |
---|
101 | |
---|
102 | if (mem) |
---|
103 | { |
---|
104 | new_mem = g_malloc (byte_size); |
---|
105 | memcpy (new_mem, mem, byte_size); |
---|
106 | } |
---|
107 | else |
---|
108 | new_mem = NULL; |
---|
109 | |
---|
110 | return new_mem; |
---|
111 | } |
---|
112 | |
---|
113 | gchar* |
---|
114 | g_strndup (const gchar *str, |
---|
115 | guint n) |
---|
116 | { |
---|
117 | gchar *new_str; |
---|
118 | |
---|
119 | if (str) |
---|
120 | { |
---|
121 | new_str = g_new (gchar, n + 1); |
---|
122 | strncpy (new_str, str, n); |
---|
123 | new_str[n] = '\0'; |
---|
124 | } |
---|
125 | else |
---|
126 | new_str = NULL; |
---|
127 | |
---|
128 | return new_str; |
---|
129 | } |
---|
130 | |
---|
131 | gchar* |
---|
132 | g_strnfill (guint length, |
---|
133 | gchar fill_char) |
---|
134 | { |
---|
135 | register gchar *str, *s, *end; |
---|
136 | |
---|
137 | str = g_new (gchar, length + 1); |
---|
138 | s = str; |
---|
139 | end = str + length; |
---|
140 | while (s < end) |
---|
141 | *(s++) = fill_char; |
---|
142 | *s = 0; |
---|
143 | |
---|
144 | return str; |
---|
145 | } |
---|
146 | |
---|
147 | gchar* |
---|
148 | g_strdup_vprintf (const gchar *format, |
---|
149 | va_list args1) |
---|
150 | { |
---|
151 | gchar *buffer; |
---|
152 | va_list args2; |
---|
153 | |
---|
154 | G_VA_COPY (args2, args1); |
---|
155 | |
---|
156 | buffer = g_new (gchar, g_printf_string_upper_bound (format, args1)); |
---|
157 | |
---|
158 | vsprintf (buffer, format, args2); |
---|
159 | va_end (args2); |
---|
160 | |
---|
161 | return buffer; |
---|
162 | } |
---|
163 | |
---|
164 | gchar* |
---|
165 | g_strdup_printf (const gchar *format, |
---|
166 | ...) |
---|
167 | { |
---|
168 | gchar *buffer; |
---|
169 | va_list args; |
---|
170 | |
---|
171 | va_start (args, format); |
---|
172 | buffer = g_strdup_vprintf (format, args); |
---|
173 | va_end (args); |
---|
174 | |
---|
175 | return buffer; |
---|
176 | } |
---|
177 | |
---|
178 | gchar* |
---|
179 | g_strconcat (const gchar *string1, ...) |
---|
180 | { |
---|
181 | guint l; |
---|
182 | va_list args; |
---|
183 | gchar *s; |
---|
184 | gchar *concat; |
---|
185 | |
---|
186 | g_return_val_if_fail (string1 != NULL, NULL); |
---|
187 | |
---|
188 | l = 1 + strlen (string1); |
---|
189 | va_start (args, string1); |
---|
190 | s = va_arg (args, gchar*); |
---|
191 | while (s) |
---|
192 | { |
---|
193 | l += strlen (s); |
---|
194 | s = va_arg (args, gchar*); |
---|
195 | } |
---|
196 | va_end (args); |
---|
197 | |
---|
198 | concat = g_new (gchar, l); |
---|
199 | concat[0] = 0; |
---|
200 | |
---|
201 | strcat (concat, string1); |
---|
202 | va_start (args, string1); |
---|
203 | s = va_arg (args, gchar*); |
---|
204 | while (s) |
---|
205 | { |
---|
206 | strcat (concat, s); |
---|
207 | s = va_arg (args, gchar*); |
---|
208 | } |
---|
209 | va_end (args); |
---|
210 | |
---|
211 | return concat; |
---|
212 | } |
---|
213 | |
---|
214 | gdouble |
---|
215 | g_strtod (const gchar *nptr, |
---|
216 | gchar **endptr) |
---|
217 | { |
---|
218 | gchar *fail_pos_1; |
---|
219 | gchar *fail_pos_2; |
---|
220 | gdouble val_1; |
---|
221 | gdouble val_2 = 0; |
---|
222 | |
---|
223 | g_return_val_if_fail (nptr != NULL, 0); |
---|
224 | |
---|
225 | fail_pos_1 = NULL; |
---|
226 | fail_pos_2 = NULL; |
---|
227 | |
---|
228 | val_1 = strtod (nptr, &fail_pos_1); |
---|
229 | |
---|
230 | if (fail_pos_1 && fail_pos_1[0] != 0) |
---|
231 | { |
---|
232 | gchar *old_locale; |
---|
233 | |
---|
234 | old_locale = g_strdup (setlocale (LC_NUMERIC, NULL)); |
---|
235 | setlocale (LC_NUMERIC, "C"); |
---|
236 | val_2 = strtod (nptr, &fail_pos_2); |
---|
237 | setlocale (LC_NUMERIC, old_locale); |
---|
238 | g_free (old_locale); |
---|
239 | } |
---|
240 | |
---|
241 | if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2) |
---|
242 | { |
---|
243 | if (endptr) |
---|
244 | *endptr = fail_pos_1; |
---|
245 | return val_1; |
---|
246 | } |
---|
247 | else |
---|
248 | { |
---|
249 | if (endptr) |
---|
250 | *endptr = fail_pos_2; |
---|
251 | return val_2; |
---|
252 | } |
---|
253 | } |
---|
254 | |
---|
255 | gchar* |
---|
256 | g_strerror (gint errnum) |
---|
257 | { |
---|
258 | static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; |
---|
259 | char *msg; |
---|
260 | |
---|
261 | #ifdef HAVE_STRERROR |
---|
262 | return strerror (errnum); |
---|
263 | #elif NO_SYS_ERRLIST |
---|
264 | switch (errnum) |
---|
265 | { |
---|
266 | #ifdef E2BIG |
---|
267 | case E2BIG: return "argument list too long"; |
---|
268 | #endif |
---|
269 | #ifdef EACCES |
---|
270 | case EACCES: return "permission denied"; |
---|
271 | #endif |
---|
272 | #ifdef EADDRINUSE |
---|
273 | case EADDRINUSE: return "address already in use"; |
---|
274 | #endif |
---|
275 | #ifdef EADDRNOTAVAIL |
---|
276 | case EADDRNOTAVAIL: return "can't assign requested address"; |
---|
277 | #endif |
---|
278 | #ifdef EADV |
---|
279 | case EADV: return "advertise error"; |
---|
280 | #endif |
---|
281 | #ifdef EAFNOSUPPORT |
---|
282 | case EAFNOSUPPORT: return "address family not supported by protocol family"; |
---|
283 | #endif |
---|
284 | #ifdef EAGAIN |
---|
285 | case EAGAIN: return "try again"; |
---|
286 | #endif |
---|
287 | #ifdef EALIGN |
---|
288 | case EALIGN: return "EALIGN"; |
---|
289 | #endif |
---|
290 | #ifdef EALREADY |
---|
291 | case EALREADY: return "operation already in progress"; |
---|
292 | #endif |
---|
293 | #ifdef EBADE |
---|
294 | case EBADE: return "bad exchange descriptor"; |
---|
295 | #endif |
---|
296 | #ifdef EBADF |
---|
297 | case EBADF: return "bad file number"; |
---|
298 | #endif |
---|
299 | #ifdef EBADFD |
---|
300 | case EBADFD: return "file descriptor in bad state"; |
---|
301 | #endif |
---|
302 | #ifdef EBADMSG |
---|
303 | case EBADMSG: return "not a data message"; |
---|
304 | #endif |
---|
305 | #ifdef EBADR |
---|
306 | case EBADR: return "bad request descriptor"; |
---|
307 | #endif |
---|
308 | #ifdef EBADRPC |
---|
309 | case EBADRPC: return "RPC structure is bad"; |
---|
310 | #endif |
---|
311 | #ifdef EBADRQC |
---|
312 | case EBADRQC: return "bad request code"; |
---|
313 | #endif |
---|
314 | #ifdef EBADSLT |
---|
315 | case EBADSLT: return "invalid slot"; |
---|
316 | #endif |
---|
317 | #ifdef EBFONT |
---|
318 | case EBFONT: return "bad font file format"; |
---|
319 | #endif |
---|
320 | #ifdef EBUSY |
---|
321 | case EBUSY: return "mount device busy"; |
---|
322 | #endif |
---|
323 | #ifdef ECHILD |
---|
324 | case ECHILD: return "no children"; |
---|
325 | #endif |
---|
326 | #ifdef ECHRNG |
---|
327 | case ECHRNG: return "channel number out of range"; |
---|
328 | #endif |
---|
329 | #ifdef ECOMM |
---|
330 | case ECOMM: return "communication error on send"; |
---|
331 | #endif |
---|
332 | #ifdef ECONNABORTED |
---|
333 | case ECONNABORTED: return "software caused connection abort"; |
---|
334 | #endif |
---|
335 | #ifdef ECONNREFUSED |
---|
336 | case ECONNREFUSED: return "connection refused"; |
---|
337 | #endif |
---|
338 | #ifdef ECONNRESET |
---|
339 | case ECONNRESET: return "connection reset by peer"; |
---|
340 | #endif |
---|
341 | #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK)) |
---|
342 | case EDEADLK: return "resource deadlock avoided"; |
---|
343 | #endif |
---|
344 | #ifdef EDEADLOCK |
---|
345 | case EDEADLOCK: return "resource deadlock avoided"; |
---|
346 | #endif |
---|
347 | #ifdef EDESTADDRREQ |
---|
348 | case EDESTADDRREQ: return "destination address required"; |
---|
349 | #endif |
---|
350 | #ifdef EDIRTY |
---|
351 | case EDIRTY: return "mounting a dirty fs w/o force"; |
---|
352 | #endif |
---|
353 | #ifdef EDOM |
---|
354 | case EDOM: return "math argument out of range"; |
---|
355 | #endif |
---|
356 | #ifdef EDOTDOT |
---|
357 | case EDOTDOT: return "cross mount point"; |
---|
358 | #endif |
---|
359 | #ifdef EDQUOT |
---|
360 | case EDQUOT: return "disk quota exceeded"; |
---|
361 | #endif |
---|
362 | #ifdef EDUPPKG |
---|
363 | case EDUPPKG: return "duplicate package name"; |
---|
364 | #endif |
---|
365 | #ifdef EEXIST |
---|
366 | case EEXIST: return "file already exists"; |
---|
367 | #endif |
---|
368 | #ifdef EFAULT |
---|
369 | case EFAULT: return "bad address in system call argument"; |
---|
370 | #endif |
---|
371 | #ifdef EFBIG |
---|
372 | case EFBIG: return "file too large"; |
---|
373 | #endif |
---|
374 | #ifdef EHOSTDOWN |
---|
375 | case EHOSTDOWN: return "host is down"; |
---|
376 | #endif |
---|
377 | #ifdef EHOSTUNREACH |
---|
378 | case EHOSTUNREACH: return "host is unreachable"; |
---|
379 | #endif |
---|
380 | #ifdef EIDRM |
---|
381 | case EIDRM: return "identifier removed"; |
---|
382 | #endif |
---|
383 | #ifdef EINIT |
---|
384 | case EINIT: return "initialization error"; |
---|
385 | #endif |
---|
386 | #ifdef EINPROGRESS |
---|
387 | case EINPROGRESS: return "operation now in progress"; |
---|
388 | #endif |
---|
389 | #ifdef EINTR |
---|
390 | case EINTR: return "interrupted system call"; |
---|
391 | #endif |
---|
392 | #ifdef EINVAL |
---|
393 | case EINVAL: return "invalid argument"; |
---|
394 | #endif |
---|
395 | #ifdef EIO |
---|
396 | case EIO: return "I/O error"; |
---|
397 | #endif |
---|
398 | #ifdef EISCONN |
---|
399 | case EISCONN: return "socket is already connected"; |
---|
400 | #endif |
---|
401 | #ifdef EISDIR |
---|
402 | case EISDIR: return "illegal operation on a directory"; |
---|
403 | #endif |
---|
404 | #ifdef EISNAME |
---|
405 | case EISNAM: return "is a name file"; |
---|
406 | #endif |
---|
407 | #ifdef ELBIN |
---|
408 | case ELBIN: return "ELBIN"; |
---|
409 | #endif |
---|
410 | #ifdef EL2HLT |
---|
411 | case EL2HLT: return "level 2 halted"; |
---|
412 | #endif |
---|
413 | #ifdef EL2NSYNC |
---|
414 | case EL2NSYNC: return "level 2 not synchronized"; |
---|
415 | #endif |
---|
416 | #ifdef EL3HLT |
---|
417 | case EL3HLT: return "level 3 halted"; |
---|
418 | #endif |
---|
419 | #ifdef EL3RST |
---|
420 | case EL3RST: return "level 3 reset"; |
---|
421 | #endif |
---|
422 | #ifdef ELIBACC |
---|
423 | case ELIBACC: return "can not access a needed shared library"; |
---|
424 | #endif |
---|
425 | #ifdef ELIBBAD |
---|
426 | case ELIBBAD: return "accessing a corrupted shared library"; |
---|
427 | #endif |
---|
428 | #ifdef ELIBEXEC |
---|
429 | case ELIBEXEC: return "can not exec a shared library directly"; |
---|
430 | #endif |
---|
431 | #ifdef ELIBMAX |
---|
432 | case ELIBMAX: return "attempting to link in more shared libraries than system limit"; |
---|
433 | #endif |
---|
434 | #ifdef ELIBSCN |
---|
435 | case ELIBSCN: return ".lib section in a.out corrupted"; |
---|
436 | #endif |
---|
437 | #ifdef ELNRNG |
---|
438 | case ELNRNG: return "link number out of range"; |
---|
439 | #endif |
---|
440 | #ifdef ELOOP |
---|
441 | case ELOOP: return "too many levels of symbolic links"; |
---|
442 | #endif |
---|
443 | #ifdef EMFILE |
---|
444 | case EMFILE: return "too many open files"; |
---|
445 | #endif |
---|
446 | #ifdef EMLINK |
---|
447 | case EMLINK: return "too many links"; |
---|
448 | #endif |
---|
449 | #ifdef EMSGSIZE |
---|
450 | case EMSGSIZE: return "message too long"; |
---|
451 | #endif |
---|
452 | #ifdef EMULTIHOP |
---|
453 | case EMULTIHOP: return "multihop attempted"; |
---|
454 | #endif |
---|
455 | #ifdef ENAMETOOLONG |
---|
456 | case ENAMETOOLONG: return "file name too long"; |
---|
457 | #endif |
---|
458 | #ifdef ENAVAIL |
---|
459 | case ENAVAIL: return "not available"; |
---|
460 | #endif |
---|
461 | #ifdef ENET |
---|
462 | case ENET: return "ENET"; |
---|
463 | #endif |
---|
464 | #ifdef ENETDOWN |
---|
465 | case ENETDOWN: return "network is down"; |
---|
466 | #endif |
---|
467 | #ifdef ENETRESET |
---|
468 | case ENETRESET: return "network dropped connection on reset"; |
---|
469 | #endif |
---|
470 | #ifdef ENETUNREACH |
---|
471 | case ENETUNREACH: return "network is unreachable"; |
---|
472 | #endif |
---|
473 | #ifdef ENFILE |
---|
474 | case ENFILE: return "file table overflow"; |
---|
475 | #endif |
---|
476 | #ifdef ENOANO |
---|
477 | case ENOANO: return "anode table overflow"; |
---|
478 | #endif |
---|
479 | #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR)) |
---|
480 | case ENOBUFS: return "no buffer space available"; |
---|
481 | #endif |
---|
482 | #ifdef ENOCSI |
---|
483 | case ENOCSI: return "no CSI structure available"; |
---|
484 | #endif |
---|
485 | #ifdef ENODATA |
---|
486 | case ENODATA: return "no data available"; |
---|
487 | #endif |
---|
488 | #ifdef ENODEV |
---|
489 | case ENODEV: return "no such device"; |
---|
490 | #endif |
---|
491 | #ifdef ENOENT |
---|
492 | case ENOENT: return "no such file or directory"; |
---|
493 | #endif |
---|
494 | #ifdef ENOEXEC |
---|
495 | case ENOEXEC: return "exec format error"; |
---|
496 | #endif |
---|
497 | #ifdef ENOLCK |
---|
498 | case ENOLCK: return "no locks available"; |
---|
499 | #endif |
---|
500 | #ifdef ENOLINK |
---|
501 | case ENOLINK: return "link has be severed"; |
---|
502 | #endif |
---|
503 | #ifdef ENOMEM |
---|
504 | case ENOMEM: return "not enough memory"; |
---|
505 | #endif |
---|
506 | #ifdef ENOMSG |
---|
507 | case ENOMSG: return "no message of desired type"; |
---|
508 | #endif |
---|
509 | #ifdef ENONET |
---|
510 | case ENONET: return "machine is not on the network"; |
---|
511 | #endif |
---|
512 | #ifdef ENOPKG |
---|
513 | case ENOPKG: return "package not installed"; |
---|
514 | #endif |
---|
515 | #ifdef ENOPROTOOPT |
---|
516 | case ENOPROTOOPT: return "bad proocol option"; |
---|
517 | #endif |
---|
518 | #ifdef ENOSPC |
---|
519 | case ENOSPC: return "no space left on device"; |
---|
520 | #endif |
---|
521 | #ifdef ENOSR |
---|
522 | case ENOSR: return "out of stream resources"; |
---|
523 | #endif |
---|
524 | #ifdef ENOSTR |
---|
525 | case ENOSTR: return "not a stream device"; |
---|
526 | #endif |
---|
527 | #ifdef ENOSYM |
---|
528 | case ENOSYM: return "unresolved symbol name"; |
---|
529 | #endif |
---|
530 | #ifdef ENOSYS |
---|
531 | case ENOSYS: return "function not implemented"; |
---|
532 | #endif |
---|
533 | #ifdef ENOTBLK |
---|
534 | case ENOTBLK: return "block device required"; |
---|
535 | #endif |
---|
536 | #ifdef ENOTCONN |
---|
537 | case ENOTCONN: return "socket is not connected"; |
---|
538 | #endif |
---|
539 | #ifdef ENOTDIR |
---|
540 | case ENOTDIR: return "not a directory"; |
---|
541 | #endif |
---|
542 | #ifdef ENOTEMPTY |
---|
543 | case ENOTEMPTY: return "directory not empty"; |
---|
544 | #endif |
---|
545 | #ifdef ENOTNAM |
---|
546 | case ENOTNAM: return "not a name file"; |
---|
547 | #endif |
---|
548 | #ifdef ENOTSOCK |
---|
549 | case ENOTSOCK: return "socket operation on non-socket"; |
---|
550 | #endif |
---|
551 | #ifdef ENOTTY |
---|
552 | case ENOTTY: return "inappropriate device for ioctl"; |
---|
553 | #endif |
---|
554 | #ifdef ENOTUNIQ |
---|
555 | case ENOTUNIQ: return "name not unique on network"; |
---|
556 | #endif |
---|
557 | #ifdef ENXIO |
---|
558 | case ENXIO: return "no such device or address"; |
---|
559 | #endif |
---|
560 | #ifdef EOPNOTSUPP |
---|
561 | case EOPNOTSUPP: return "operation not supported on socket"; |
---|
562 | #endif |
---|
563 | #ifdef EPERM |
---|
564 | case EPERM: return "not owner"; |
---|
565 | #endif |
---|
566 | #ifdef EPFNOSUPPORT |
---|
567 | case EPFNOSUPPORT: return "protocol family not supported"; |
---|
568 | #endif |
---|
569 | #ifdef EPIPE |
---|
570 | case EPIPE: return "broken pipe"; |
---|
571 | #endif |
---|
572 | #ifdef EPROCLIM |
---|
573 | case EPROCLIM: return "too many processes"; |
---|
574 | #endif |
---|
575 | #ifdef EPROCUNAVAIL |
---|
576 | case EPROCUNAVAIL: return "bad procedure for program"; |
---|
577 | #endif |
---|
578 | #ifdef EPROGMISMATCH |
---|
579 | case EPROGMISMATCH: return "program version wrong"; |
---|
580 | #endif |
---|
581 | #ifdef EPROGUNAVAIL |
---|
582 | case EPROGUNAVAIL: return "RPC program not available"; |
---|
583 | #endif |
---|
584 | #ifdef EPROTO |
---|
585 | case EPROTO: return "protocol error"; |
---|
586 | #endif |
---|
587 | #ifdef EPROTONOSUPPORT |
---|
588 | case EPROTONOSUPPORT: return "protocol not suppored"; |
---|
589 | #endif |
---|
590 | #ifdef EPROTOTYPE |
---|
591 | case EPROTOTYPE: return "protocol wrong type for socket"; |
---|
592 | #endif |
---|
593 | #ifdef ERANGE |
---|
594 | case ERANGE: return "math result unrepresentable"; |
---|
595 | #endif |
---|
596 | #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED)) |
---|
597 | case EREFUSED: return "EREFUSED"; |
---|
598 | #endif |
---|
599 | #ifdef EREMCHG |
---|
600 | case EREMCHG: return "remote address changed"; |
---|
601 | #endif |
---|
602 | #ifdef EREMDEV |
---|
603 | case EREMDEV: return "remote device"; |
---|
604 | #endif |
---|
605 | #ifdef EREMOTE |
---|
606 | case EREMOTE: return "pathname hit remote file system"; |
---|
607 | #endif |
---|
608 | #ifdef EREMOTEIO |
---|
609 | case EREMOTEIO: return "remote i/o error"; |
---|
610 | #endif |
---|
611 | #ifdef EREMOTERELEASE |
---|
612 | case EREMOTERELEASE: return "EREMOTERELEASE"; |
---|
613 | #endif |
---|
614 | #ifdef EROFS |
---|
615 | case EROFS: return "read-only file system"; |
---|
616 | #endif |
---|
617 | #ifdef ERPCMISMATCH |
---|
618 | case ERPCMISMATCH: return "RPC version is wrong"; |
---|
619 | #endif |
---|
620 | #ifdef ERREMOTE |
---|
621 | case ERREMOTE: return "object is remote"; |
---|
622 | #endif |
---|
623 | #ifdef ESHUTDOWN |
---|
624 | case ESHUTDOWN: return "can't send afer socket shutdown"; |
---|
625 | #endif |
---|
626 | #ifdef ESOCKTNOSUPPORT |
---|
627 | case ESOCKTNOSUPPORT: return "socket type not supported"; |
---|
628 | #endif |
---|
629 | #ifdef ESPIPE |
---|
630 | case ESPIPE: return "invalid seek"; |
---|
631 | #endif |
---|
632 | #ifdef ESRCH |
---|
633 | case ESRCH: return "no such process"; |
---|
634 | #endif |
---|
635 | #ifdef ESRMNT |
---|
636 | case ESRMNT: return "srmount error"; |
---|
637 | #endif |
---|
638 | #ifdef ESTALE |
---|
639 | case ESTALE: return "stale remote file handle"; |
---|
640 | #endif |
---|
641 | #ifdef ESUCCESS |
---|
642 | case ESUCCESS: return "Error 0"; |
---|
643 | #endif |
---|
644 | #ifdef ETIME |
---|
645 | case ETIME: return "timer expired"; |
---|
646 | #endif |
---|
647 | #ifdef ETIMEDOUT |
---|
648 | case ETIMEDOUT: return "connection timed out"; |
---|
649 | #endif |
---|
650 | #ifdef ETOOMANYREFS |
---|
651 | case ETOOMANYREFS: return "too many references: can't splice"; |
---|
652 | #endif |
---|
653 | #ifdef ETXTBSY |
---|
654 | case ETXTBSY: return "text file or pseudo-device busy"; |
---|
655 | #endif |
---|
656 | #ifdef EUCLEAN |
---|
657 | case EUCLEAN: return "structure needs cleaning"; |
---|
658 | #endif |
---|
659 | #ifdef EUNATCH |
---|
660 | case EUNATCH: return "protocol driver not attached"; |
---|
661 | #endif |
---|
662 | #ifdef EUSERS |
---|
663 | case EUSERS: return "too many users"; |
---|
664 | #endif |
---|
665 | #ifdef EVERSION |
---|
666 | case EVERSION: return "version mismatch"; |
---|
667 | #endif |
---|
668 | #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) |
---|
669 | case EWOULDBLOCK: return "operation would block"; |
---|
670 | #endif |
---|
671 | #ifdef EXDEV |
---|
672 | case EXDEV: return "cross-domain link"; |
---|
673 | #endif |
---|
674 | #ifdef EXFULL |
---|
675 | case EXFULL: return "message tables full"; |
---|
676 | #endif |
---|
677 | } |
---|
678 | #else /* NO_SYS_ERRLIST */ |
---|
679 | extern int sys_nerr; |
---|
680 | extern char *sys_errlist[]; |
---|
681 | |
---|
682 | if ((errnum > 0) && (errnum <= sys_nerr)) |
---|
683 | return sys_errlist [errnum]; |
---|
684 | #endif /* NO_SYS_ERRLIST */ |
---|
685 | |
---|
686 | msg = g_static_private_get (&msg_private); |
---|
687 | if (!msg) |
---|
688 | { |
---|
689 | msg = g_new (gchar, 64); |
---|
690 | g_static_private_set (&msg_private, msg, g_free); |
---|
691 | } |
---|
692 | |
---|
693 | sprintf (msg, "unknown error (%d)", errnum); |
---|
694 | |
---|
695 | return msg; |
---|
696 | } |
---|
697 | |
---|
698 | gchar* |
---|
699 | g_strsignal (gint signum) |
---|
700 | { |
---|
701 | static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; |
---|
702 | char *msg; |
---|
703 | |
---|
704 | #ifdef HAVE_STRSIGNAL |
---|
705 | extern char *strsignal (int sig); |
---|
706 | return strsignal (signum); |
---|
707 | #elif NO_SYS_SIGLIST |
---|
708 | switch (signum) |
---|
709 | { |
---|
710 | #ifdef SIGHUP |
---|
711 | case SIGHUP: return "Hangup"; |
---|
712 | #endif |
---|
713 | #ifdef SIGINT |
---|
714 | case SIGINT: return "Interrupt"; |
---|
715 | #endif |
---|
716 | #ifdef SIGQUIT |
---|
717 | case SIGQUIT: return "Quit"; |
---|
718 | #endif |
---|
719 | #ifdef SIGILL |
---|
720 | case SIGILL: return "Illegal instruction"; |
---|
721 | #endif |
---|
722 | #ifdef SIGTRAP |
---|
723 | case SIGTRAP: return "Trace/breakpoint trap"; |
---|
724 | #endif |
---|
725 | #ifdef SIGABRT |
---|
726 | case SIGABRT: return "IOT trap/Abort"; |
---|
727 | #endif |
---|
728 | #ifdef SIGBUS |
---|
729 | case SIGBUS: return "Bus error"; |
---|
730 | #endif |
---|
731 | #ifdef SIGFPE |
---|
732 | case SIGFPE: return "Floating point exception"; |
---|
733 | #endif |
---|
734 | #ifdef SIGKILL |
---|
735 | case SIGKILL: return "Killed"; |
---|
736 | #endif |
---|
737 | #ifdef SIGUSR1 |
---|
738 | case SIGUSR1: return "User defined signal 1"; |
---|
739 | #endif |
---|
740 | #ifdef SIGSEGV |
---|
741 | case SIGSEGV: return "Segmentation fault"; |
---|
742 | #endif |
---|
743 | #ifdef SIGUSR2 |
---|
744 | case SIGUSR2: return "User defined signal 2"; |
---|
745 | #endif |
---|
746 | #ifdef SIGPIPE |
---|
747 | case SIGPIPE: return "Broken pipe"; |
---|
748 | #endif |
---|
749 | #ifdef SIGALRM |
---|
750 | case SIGALRM: return "Alarm clock"; |
---|
751 | #endif |
---|
752 | #ifdef SIGTERM |
---|
753 | case SIGTERM: return "Terminated"; |
---|
754 | #endif |
---|
755 | #ifdef SIGSTKFLT |
---|
756 | case SIGSTKFLT: return "Stack fault"; |
---|
757 | #endif |
---|
758 | #ifdef SIGCHLD |
---|
759 | case SIGCHLD: return "Child exited"; |
---|
760 | #endif |
---|
761 | #ifdef SIGCONT |
---|
762 | case SIGCONT: return "Continued"; |
---|
763 | #endif |
---|
764 | #ifdef SIGSTOP |
---|
765 | case SIGSTOP: return "Stopped (signal)"; |
---|
766 | #endif |
---|
767 | #ifdef SIGTSTP |
---|
768 | case SIGTSTP: return "Stopped"; |
---|
769 | #endif |
---|
770 | #ifdef SIGTTIN |
---|
771 | case SIGTTIN: return "Stopped (tty input)"; |
---|
772 | #endif |
---|
773 | #ifdef SIGTTOU |
---|
774 | case SIGTTOU: return "Stopped (tty output)"; |
---|
775 | #endif |
---|
776 | #ifdef SIGURG |
---|
777 | case SIGURG: return "Urgent condition"; |
---|
778 | #endif |
---|
779 | #ifdef SIGXCPU |
---|
780 | case SIGXCPU: return "CPU time limit exceeded"; |
---|
781 | #endif |
---|
782 | #ifdef SIGXFSZ |
---|
783 | case SIGXFSZ: return "File size limit exceeded"; |
---|
784 | #endif |
---|
785 | #ifdef SIGVTALRM |
---|
786 | case SIGVTALRM: return "Virtual time alarm"; |
---|
787 | #endif |
---|
788 | #ifdef SIGPROF |
---|
789 | case SIGPROF: return "Profile signal"; |
---|
790 | #endif |
---|
791 | #ifdef SIGWINCH |
---|
792 | case SIGWINCH: return "Window size changed"; |
---|
793 | #endif |
---|
794 | #ifdef SIGIO |
---|
795 | case SIGIO: return "Possible I/O"; |
---|
796 | #endif |
---|
797 | #ifdef SIGPWR |
---|
798 | case SIGPWR: return "Power failure"; |
---|
799 | #endif |
---|
800 | #ifdef SIGUNUSED |
---|
801 | case SIGUNUSED: return "Unused signal"; |
---|
802 | #endif |
---|
803 | } |
---|
804 | #else /* NO_SYS_SIGLIST */ |
---|
805 | |
---|
806 | #ifdef NO_SYS_SIGLIST_DECL |
---|
807 | extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/ |
---|
808 | #endif |
---|
809 | |
---|
810 | return (char*) /* this function should return const --josh */ sys_siglist [signum]; |
---|
811 | #endif /* NO_SYS_SIGLIST */ |
---|
812 | |
---|
813 | msg = g_static_private_get (&msg_private); |
---|
814 | if (!msg) |
---|
815 | { |
---|
816 | msg = g_new (gchar, 64); |
---|
817 | g_static_private_set (&msg_private, msg, g_free); |
---|
818 | } |
---|
819 | |
---|
820 | sprintf (msg, "unknown signal (%d)", signum); |
---|
821 | |
---|
822 | return msg; |
---|
823 | } |
---|
824 | |
---|
825 | typedef struct |
---|
826 | { |
---|
827 | guint min_width; |
---|
828 | guint precision; |
---|
829 | gboolean alternate_format, zero_padding, adjust_left, locale_grouping; |
---|
830 | gboolean add_space, add_sign, possible_sign, seen_precision; |
---|
831 | gboolean mod_half, mod_long, mod_extra_long; |
---|
832 | } PrintfArgSpec; |
---|
833 | |
---|
834 | guint |
---|
835 | g_printf_string_upper_bound (const gchar* format, |
---|
836 | va_list args) |
---|
837 | { |
---|
838 | static const gboolean honour_longs = SIZEOF_LONG > 4 || SIZEOF_VOID_P > 4; |
---|
839 | guint len = 1; |
---|
840 | |
---|
841 | if (!format) |
---|
842 | return len; |
---|
843 | |
---|
844 | while (*format) |
---|
845 | { |
---|
846 | register gchar c = *format++; |
---|
847 | |
---|
848 | if (c != '%') |
---|
849 | len += 1; |
---|
850 | else /* (c == '%') */ |
---|
851 | { |
---|
852 | PrintfArgSpec spec = { 0, }; |
---|
853 | gboolean seen_l = FALSE, conv_done = FALSE; |
---|
854 | guint conv_len = 0; |
---|
855 | const gchar *spec_start = format; |
---|
856 | |
---|
857 | do |
---|
858 | { |
---|
859 | c = *format++; |
---|
860 | switch (c) |
---|
861 | { |
---|
862 | GDoubleIEEE754 u_double; |
---|
863 | guint v_uint; |
---|
864 | gint v_int; |
---|
865 | const gchar *v_string; |
---|
866 | |
---|
867 | /* beware of positional parameters |
---|
868 | */ |
---|
869 | case '$': |
---|
870 | g_warning (G_GNUC_PRETTY_FUNCTION |
---|
871 | "(): unable to handle positional parameters (%%n$)"); |
---|
872 | len += 1024; /* try adding some safety padding */ |
---|
873 | break; |
---|
874 | |
---|
875 | /* parse flags |
---|
876 | */ |
---|
877 | case '#': |
---|
878 | spec.alternate_format = TRUE; |
---|
879 | break; |
---|
880 | case '0': |
---|
881 | spec.zero_padding = TRUE; |
---|
882 | break; |
---|
883 | case '-': |
---|
884 | spec.adjust_left = TRUE; |
---|
885 | break; |
---|
886 | case ' ': |
---|
887 | spec.add_space = TRUE; |
---|
888 | break; |
---|
889 | case '+': |
---|
890 | spec.add_sign = TRUE; |
---|
891 | break; |
---|
892 | case '\'': |
---|
893 | spec.locale_grouping = TRUE; |
---|
894 | break; |
---|
895 | |
---|
896 | /* parse output size specifications |
---|
897 | */ |
---|
898 | case '.': |
---|
899 | spec.seen_precision = TRUE; |
---|
900 | break; |
---|
901 | case '1': |
---|
902 | case '2': |
---|
903 | case '3': |
---|
904 | case '4': |
---|
905 | case '5': |
---|
906 | case '6': |
---|
907 | case '7': |
---|
908 | case '8': |
---|
909 | case '9': |
---|
910 | v_uint = c - '0'; |
---|
911 | c = *format; |
---|
912 | while (c >= '0' && c <= '9') |
---|
913 | { |
---|
914 | format++; |
---|
915 | v_uint = v_uint * 10 + c - '0'; |
---|
916 | c = *format; |
---|
917 | } |
---|
918 | if (spec.seen_precision) |
---|
919 | spec.precision = MAX (spec.precision, v_uint); |
---|
920 | else |
---|
921 | spec.min_width = MAX (spec.min_width, v_uint); |
---|
922 | break; |
---|
923 | case '*': |
---|
924 | v_int = va_arg (args, int); |
---|
925 | if (spec.seen_precision) |
---|
926 | { |
---|
927 | /* forget about negative precision */ |
---|
928 | if (v_int >= 0) |
---|
929 | spec.precision = MAX (spec.precision, v_int); |
---|
930 | } |
---|
931 | else |
---|
932 | { |
---|
933 | if (v_int < 0) |
---|
934 | { |
---|
935 | v_int = - v_int; |
---|
936 | spec.adjust_left = TRUE; |
---|
937 | } |
---|
938 | spec.min_width = MAX (spec.min_width, v_int); |
---|
939 | } |
---|
940 | break; |
---|
941 | |
---|
942 | /* parse type modifiers |
---|
943 | */ |
---|
944 | case 'h': |
---|
945 | spec.mod_half = TRUE; |
---|
946 | break; |
---|
947 | case 'l': |
---|
948 | if (!seen_l) |
---|
949 | { |
---|
950 | spec.mod_long = TRUE; |
---|
951 | seen_l = TRUE; |
---|
952 | break; |
---|
953 | } |
---|
954 | /* else, fall through */ |
---|
955 | case 'L': |
---|
956 | case 'q': |
---|
957 | spec.mod_long = TRUE; |
---|
958 | spec.mod_extra_long = TRUE; |
---|
959 | break; |
---|
960 | case 'z': |
---|
961 | case 'Z': |
---|
962 | #if GLIB_SIZEOF_SIZE_T > 4 |
---|
963 | spec.mod_long = TRUE; |
---|
964 | spec.mod_extra_long = TRUE; |
---|
965 | #endif /* GLIB_SIZEOF_SIZE_T > 4 */ |
---|
966 | break; |
---|
967 | case 't': |
---|
968 | #if GLIB_SIZEOF_PTRDIFF_T > 4 |
---|
969 | spec.mod_long = TRUE; |
---|
970 | spec.mod_extra_long = TRUE; |
---|
971 | #endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */ |
---|
972 | break; |
---|
973 | case 'j': |
---|
974 | #if GLIB_SIZEOF_INTMAX_T > 4 |
---|
975 | spec.mod_long = TRUE; |
---|
976 | spec.mod_extra_long = TRUE; |
---|
977 | #endif /* GLIB_SIZEOF_INTMAX_T > 4 */ |
---|
978 | break; |
---|
979 | |
---|
980 | /* parse output conversions |
---|
981 | */ |
---|
982 | case '%': |
---|
983 | conv_len += 1; |
---|
984 | break; |
---|
985 | case 'O': |
---|
986 | case 'D': |
---|
987 | case 'I': |
---|
988 | case 'U': |
---|
989 | /* some C libraries feature long variants for these as well? */ |
---|
990 | spec.mod_long = TRUE; |
---|
991 | /* fall through */ |
---|
992 | case 'o': |
---|
993 | conv_len += 2; |
---|
994 | /* fall through */ |
---|
995 | case 'd': |
---|
996 | case 'i': |
---|
997 | conv_len += 1; /* sign */ |
---|
998 | /* fall through */ |
---|
999 | case 'u': |
---|
1000 | conv_len += 4; |
---|
1001 | /* fall through */ |
---|
1002 | case 'x': |
---|
1003 | case 'X': |
---|
1004 | spec.possible_sign = TRUE; |
---|
1005 | conv_len += 10; |
---|
1006 | if (spec.mod_long && honour_longs) |
---|
1007 | conv_len *= 2; |
---|
1008 | if (spec.mod_extra_long) |
---|
1009 | conv_len *= 2; |
---|
1010 | if (spec.mod_extra_long) |
---|
1011 | { |
---|
1012 | #ifdef G_HAVE_GINT64 |
---|
1013 | (void) va_arg (args, gint64); |
---|
1014 | #else /* !G_HAVE_GINT64 */ |
---|
1015 | (void) va_arg (args, long); |
---|
1016 | #endif /* !G_HAVE_GINT64 */ |
---|
1017 | } |
---|
1018 | else if (spec.mod_long) |
---|
1019 | (void) va_arg (args, long); |
---|
1020 | else |
---|
1021 | (void) va_arg (args, int); |
---|
1022 | break; |
---|
1023 | case 'A': |
---|
1024 | case 'a': |
---|
1025 | /* 0x */ |
---|
1026 | conv_len += 2; |
---|
1027 | /* fall through */ |
---|
1028 | case 'g': |
---|
1029 | case 'G': |
---|
1030 | case 'e': |
---|
1031 | case 'E': |
---|
1032 | case 'f': |
---|
1033 | spec.possible_sign = TRUE; |
---|
1034 | /* n . dddddddddddddddddddddddd E +- eeee */ |
---|
1035 | conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4; |
---|
1036 | if (spec.mod_extra_long) |
---|
1037 | g_warning (G_GNUC_PRETTY_FUNCTION |
---|
1038 | "(): unable to handle long double, collecting double only"); |
---|
1039 | #ifdef HAVE_LONG_DOUBLE |
---|
1040 | #error need to implement special handling for long double |
---|
1041 | #endif |
---|
1042 | u_double.v_double = va_arg (args, double); |
---|
1043 | /* %f can expand up to all significant digits before '.' (308) */ |
---|
1044 | if (c == 'f' && |
---|
1045 | u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047) |
---|
1046 | { |
---|
1047 | gint exp = u_double.mpn.biased_exponent; |
---|
1048 | |
---|
1049 | exp -= G_IEEE754_DOUBLE_BIAS; |
---|
1050 | exp = exp * G_LOG_2_BASE_10 + 1; |
---|
1051 | conv_len += exp; |
---|
1052 | } |
---|
1053 | /* some printf() implementations require extra padding for rounding */ |
---|
1054 | conv_len += 2; |
---|
1055 | /* we can't really handle locale specific grouping here */ |
---|
1056 | if (spec.locale_grouping) |
---|
1057 | conv_len *= 2; |
---|
1058 | break; |
---|
1059 | case 'C': |
---|
1060 | spec.mod_long = TRUE; |
---|
1061 | /* fall through */ |
---|
1062 | case 'c': |
---|
1063 | conv_len += spec.mod_long ? MB_LEN_MAX : 1; |
---|
1064 | (void) va_arg (args, int); |
---|
1065 | break; |
---|
1066 | case 'S': |
---|
1067 | spec.mod_long = TRUE; |
---|
1068 | /* fall through */ |
---|
1069 | case 's': |
---|
1070 | v_string = va_arg (args, char*); |
---|
1071 | if (!v_string) |
---|
1072 | conv_len += 8; /* hold "(null)" */ |
---|
1073 | else if (spec.seen_precision) |
---|
1074 | conv_len += spec.precision; |
---|
1075 | else |
---|
1076 | conv_len += strlen (v_string); |
---|
1077 | conv_done = TRUE; |
---|
1078 | if (spec.mod_long) |
---|
1079 | { |
---|
1080 | g_warning (G_GNUC_PRETTY_FUNCTION |
---|
1081 | "(): unable to handle wide char strings"); |
---|
1082 | len += 1024; /* try adding some safety padding */ |
---|
1083 | } |
---|
1084 | break; |
---|
1085 | case 'P': /* do we actually need this? */ |
---|
1086 | /* fall through */ |
---|
1087 | case 'p': |
---|
1088 | spec.alternate_format = TRUE; |
---|
1089 | conv_len += 10; |
---|
1090 | if (honour_longs) |
---|
1091 | conv_len *= 2; |
---|
1092 | /* fall through */ |
---|
1093 | case 'n': |
---|
1094 | conv_done = TRUE; |
---|
1095 | (void) va_arg (args, void*); |
---|
1096 | break; |
---|
1097 | case 'm': |
---|
1098 | /* there's not much we can do to be clever */ |
---|
1099 | v_string = g_strerror (errno); |
---|
1100 | v_uint = v_string ? strlen (v_string) : 0; |
---|
1101 | conv_len += MAX (256, v_uint); |
---|
1102 | break; |
---|
1103 | |
---|
1104 | /* handle invalid cases |
---|
1105 | */ |
---|
1106 | case '\000': |
---|
1107 | /* no conversion specification, bad bad */ |
---|
1108 | conv_len += format - spec_start; |
---|
1109 | break; |
---|
1110 | default: |
---|
1111 | g_warning (G_GNUC_PRETTY_FUNCTION |
---|
1112 | "(): unable to handle `%c' while parsing format", |
---|
1113 | c); |
---|
1114 | break; |
---|
1115 | } |
---|
1116 | conv_done |= conv_len > 0; |
---|
1117 | } |
---|
1118 | while (!conv_done); |
---|
1119 | /* handle width specifications */ |
---|
1120 | conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width)); |
---|
1121 | /* handle flags */ |
---|
1122 | conv_len += spec.alternate_format ? 2 : 0; |
---|
1123 | conv_len += (spec.add_space || spec.add_sign || spec.possible_sign); |
---|
1124 | /* finally done */ |
---|
1125 | len += conv_len; |
---|
1126 | } /* else (c == '%') */ |
---|
1127 | } /* while (*format) */ |
---|
1128 | |
---|
1129 | return len; |
---|
1130 | } |
---|
1131 | |
---|
1132 | void |
---|
1133 | g_strdown (gchar *string) |
---|
1134 | { |
---|
1135 | register guchar *s; |
---|
1136 | |
---|
1137 | g_return_if_fail (string != NULL); |
---|
1138 | |
---|
1139 | s = string; |
---|
1140 | |
---|
1141 | while (*s) |
---|
1142 | { |
---|
1143 | *s = tolower (*s); |
---|
1144 | s++; |
---|
1145 | } |
---|
1146 | } |
---|
1147 | |
---|
1148 | void |
---|
1149 | g_strup (gchar *string) |
---|
1150 | { |
---|
1151 | register guchar *s; |
---|
1152 | |
---|
1153 | g_return_if_fail (string != NULL); |
---|
1154 | |
---|
1155 | s = string; |
---|
1156 | |
---|
1157 | while (*s) |
---|
1158 | { |
---|
1159 | *s = toupper (*s); |
---|
1160 | s++; |
---|
1161 | } |
---|
1162 | } |
---|
1163 | |
---|
1164 | void |
---|
1165 | g_strreverse (gchar *string) |
---|
1166 | { |
---|
1167 | g_return_if_fail (string != NULL); |
---|
1168 | |
---|
1169 | if (*string) |
---|
1170 | { |
---|
1171 | register gchar *h, *t; |
---|
1172 | |
---|
1173 | h = string; |
---|
1174 | t = string + strlen (string) - 1; |
---|
1175 | |
---|
1176 | while (h < t) |
---|
1177 | { |
---|
1178 | register gchar c; |
---|
1179 | |
---|
1180 | c = *h; |
---|
1181 | *h = *t; |
---|
1182 | h++; |
---|
1183 | *t = c; |
---|
1184 | t--; |
---|
1185 | } |
---|
1186 | } |
---|
1187 | } |
---|
1188 | |
---|
1189 | gint |
---|
1190 | g_strcasecmp (const gchar *s1, |
---|
1191 | const gchar *s2) |
---|
1192 | { |
---|
1193 | #ifdef HAVE_STRCASECMP |
---|
1194 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1195 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1196 | |
---|
1197 | return strcasecmp (s1, s2); |
---|
1198 | #else |
---|
1199 | gint c1, c2; |
---|
1200 | |
---|
1201 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1202 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1203 | |
---|
1204 | while (*s1 && *s2) |
---|
1205 | { |
---|
1206 | /* According to A. Cox, some platforms have islower's that |
---|
1207 | * don't work right on non-uppercase |
---|
1208 | */ |
---|
1209 | c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; |
---|
1210 | c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; |
---|
1211 | if (c1 != c2) |
---|
1212 | return (c1 - c2); |
---|
1213 | s1++; s2++; |
---|
1214 | } |
---|
1215 | |
---|
1216 | return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); |
---|
1217 | #endif |
---|
1218 | } |
---|
1219 | |
---|
1220 | gint |
---|
1221 | g_strncasecmp (const gchar *s1, |
---|
1222 | const gchar *s2, |
---|
1223 | guint n) |
---|
1224 | { |
---|
1225 | #ifdef HAVE_STRNCASECMP |
---|
1226 | return strncasecmp (s1, s2, n); |
---|
1227 | #else |
---|
1228 | gint c1, c2; |
---|
1229 | |
---|
1230 | g_return_val_if_fail (s1 != NULL, 0); |
---|
1231 | g_return_val_if_fail (s2 != NULL, 0); |
---|
1232 | |
---|
1233 | while (n && *s1 && *s2) |
---|
1234 | { |
---|
1235 | n -= 1; |
---|
1236 | /* According to A. Cox, some platforms have islower's that |
---|
1237 | * don't work right on non-uppercase |
---|
1238 | */ |
---|
1239 | c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; |
---|
1240 | c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; |
---|
1241 | if (c1 != c2) |
---|
1242 | return (c1 - c2); |
---|
1243 | s1++; s2++; |
---|
1244 | } |
---|
1245 | |
---|
1246 | if (n) |
---|
1247 | return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); |
---|
1248 | else |
---|
1249 | return 0; |
---|
1250 | #endif |
---|
1251 | } |
---|
1252 | |
---|
1253 | gchar* |
---|
1254 | g_strdelimit (gchar *string, |
---|
1255 | const gchar *delimiters, |
---|
1256 | gchar new_delim) |
---|
1257 | { |
---|
1258 | register gchar *c; |
---|
1259 | |
---|
1260 | g_return_val_if_fail (string != NULL, NULL); |
---|
1261 | |
---|
1262 | if (!delimiters) |
---|
1263 | delimiters = G_STR_DELIMITERS; |
---|
1264 | |
---|
1265 | for (c = string; *c; c++) |
---|
1266 | { |
---|
1267 | if (strchr (delimiters, *c)) |
---|
1268 | *c = new_delim; |
---|
1269 | } |
---|
1270 | |
---|
1271 | return string; |
---|
1272 | } |
---|
1273 | |
---|
1274 | gchar* |
---|
1275 | g_strescape (gchar *string) |
---|
1276 | { |
---|
1277 | gchar *q; |
---|
1278 | gchar *escaped; |
---|
1279 | guint backslashes = 0; |
---|
1280 | gchar *p = string; |
---|
1281 | |
---|
1282 | g_return_val_if_fail (string != NULL, NULL); |
---|
1283 | |
---|
1284 | while (*p != '\000') |
---|
1285 | backslashes += (*p++ == '\\'); |
---|
1286 | |
---|
1287 | if (!backslashes) |
---|
1288 | return g_strdup (string); |
---|
1289 | |
---|
1290 | escaped = g_new (gchar, strlen (string) + backslashes + 1); |
---|
1291 | |
---|
1292 | p = string; |
---|
1293 | q = escaped; |
---|
1294 | |
---|
1295 | while (*p != '\000') |
---|
1296 | { |
---|
1297 | if (*p == '\\') |
---|
1298 | *q++ = '\\'; |
---|
1299 | *q++ = *p++; |
---|
1300 | } |
---|
1301 | *q = '\000'; |
---|
1302 | |
---|
1303 | return escaped; |
---|
1304 | } |
---|
1305 | |
---|
1306 | /* blame Elliot for these next five routines */ |
---|
1307 | gchar* |
---|
1308 | g_strchug (gchar *string) |
---|
1309 | { |
---|
1310 | guchar *start; |
---|
1311 | |
---|
1312 | g_return_val_if_fail (string != NULL, NULL); |
---|
1313 | |
---|
1314 | for (start = string; *start && isspace (*start); start++) |
---|
1315 | ; |
---|
1316 | |
---|
1317 | g_memmove(string, start, strlen(start) + 1); |
---|
1318 | |
---|
1319 | return string; |
---|
1320 | } |
---|
1321 | |
---|
1322 | gchar* |
---|
1323 | g_strchomp (gchar *string) |
---|
1324 | { |
---|
1325 | gchar *s; |
---|
1326 | |
---|
1327 | g_return_val_if_fail (string != NULL, NULL); |
---|
1328 | |
---|
1329 | if (!*string) |
---|
1330 | return string; |
---|
1331 | |
---|
1332 | for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s); |
---|
1333 | s--) |
---|
1334 | *s = '\0'; |
---|
1335 | |
---|
1336 | return string; |
---|
1337 | } |
---|
1338 | |
---|
1339 | gchar** |
---|
1340 | g_strsplit (const gchar *string, |
---|
1341 | const gchar *delimiter, |
---|
1342 | gint max_tokens) |
---|
1343 | { |
---|
1344 | GSList *string_list = NULL, *slist; |
---|
1345 | gchar **str_array, *s; |
---|
1346 | guint i, n = 1; |
---|
1347 | |
---|
1348 | g_return_val_if_fail (string != NULL, NULL); |
---|
1349 | g_return_val_if_fail (delimiter != NULL, NULL); |
---|
1350 | |
---|
1351 | if (max_tokens < 1) |
---|
1352 | max_tokens = G_MAXINT; |
---|
1353 | |
---|
1354 | s = strstr (string, delimiter); |
---|
1355 | if (s) |
---|
1356 | { |
---|
1357 | guint delimiter_len = strlen (delimiter); |
---|
1358 | |
---|
1359 | do |
---|
1360 | { |
---|
1361 | guint len; |
---|
1362 | gchar *new_string; |
---|
1363 | |
---|
1364 | len = s - string; |
---|
1365 | new_string = g_new (gchar, len + 1); |
---|
1366 | strncpy (new_string, string, len); |
---|
1367 | new_string[len] = 0; |
---|
1368 | string_list = g_slist_prepend (string_list, new_string); |
---|
1369 | n++; |
---|
1370 | string = s + delimiter_len; |
---|
1371 | s = strstr (string, delimiter); |
---|
1372 | } |
---|
1373 | while (--max_tokens && s); |
---|
1374 | } |
---|
1375 | if (*string) |
---|
1376 | { |
---|
1377 | n++; |
---|
1378 | string_list = g_slist_prepend (string_list, g_strdup (string)); |
---|
1379 | } |
---|
1380 | |
---|
1381 | str_array = g_new (gchar*, n); |
---|
1382 | |
---|
1383 | i = n - 1; |
---|
1384 | |
---|
1385 | str_array[i--] = NULL; |
---|
1386 | for (slist = string_list; slist; slist = slist->next) |
---|
1387 | str_array[i--] = slist->data; |
---|
1388 | |
---|
1389 | g_slist_free (string_list); |
---|
1390 | |
---|
1391 | return str_array; |
---|
1392 | } |
---|
1393 | |
---|
1394 | void |
---|
1395 | g_strfreev (gchar **str_array) |
---|
1396 | { |
---|
1397 | if (str_array) |
---|
1398 | { |
---|
1399 | int i; |
---|
1400 | |
---|
1401 | for(i = 0; str_array[i] != NULL; i++) |
---|
1402 | g_free(str_array[i]); |
---|
1403 | |
---|
1404 | g_free (str_array); |
---|
1405 | } |
---|
1406 | } |
---|
1407 | |
---|
1408 | gchar* |
---|
1409 | g_strjoinv (const gchar *separator, |
---|
1410 | gchar **str_array) |
---|
1411 | { |
---|
1412 | gchar *string; |
---|
1413 | |
---|
1414 | g_return_val_if_fail (str_array != NULL, NULL); |
---|
1415 | |
---|
1416 | if (separator == NULL) |
---|
1417 | separator = ""; |
---|
1418 | |
---|
1419 | if (*str_array) |
---|
1420 | { |
---|
1421 | guint i, len; |
---|
1422 | guint separator_len; |
---|
1423 | |
---|
1424 | separator_len = strlen (separator); |
---|
1425 | len = 1 + strlen (str_array[0]); |
---|
1426 | for(i = 1; str_array[i] != NULL; i++) |
---|
1427 | len += separator_len + strlen(str_array[i]); |
---|
1428 | |
---|
1429 | string = g_new (gchar, len); |
---|
1430 | *string = 0; |
---|
1431 | strcat (string, *str_array); |
---|
1432 | for (i = 1; str_array[i] != NULL; i++) |
---|
1433 | { |
---|
1434 | strcat (string, separator); |
---|
1435 | strcat (string, str_array[i]); |
---|
1436 | } |
---|
1437 | } |
---|
1438 | else |
---|
1439 | string = g_strdup (""); |
---|
1440 | |
---|
1441 | return string; |
---|
1442 | } |
---|
1443 | |
---|
1444 | gchar* |
---|
1445 | g_strjoin (const gchar *separator, |
---|
1446 | ...) |
---|
1447 | { |
---|
1448 | gchar *string, *s; |
---|
1449 | va_list args; |
---|
1450 | guint len; |
---|
1451 | guint separator_len; |
---|
1452 | |
---|
1453 | if (separator == NULL) |
---|
1454 | separator = ""; |
---|
1455 | |
---|
1456 | separator_len = strlen (separator); |
---|
1457 | |
---|
1458 | va_start (args, separator); |
---|
1459 | |
---|
1460 | s = va_arg (args, gchar*); |
---|
1461 | |
---|
1462 | if (s) |
---|
1463 | { |
---|
1464 | len = strlen (s); |
---|
1465 | |
---|
1466 | s = va_arg (args, gchar*); |
---|
1467 | while (s) |
---|
1468 | { |
---|
1469 | len += separator_len + strlen (s); |
---|
1470 | s = va_arg (args, gchar*); |
---|
1471 | } |
---|
1472 | va_end (args); |
---|
1473 | |
---|
1474 | string = g_new (gchar, len + 1); |
---|
1475 | *string = 0; |
---|
1476 | |
---|
1477 | va_start (args, separator); |
---|
1478 | |
---|
1479 | s = va_arg (args, gchar*); |
---|
1480 | strcat (string, s); |
---|
1481 | |
---|
1482 | s = va_arg (args, gchar*); |
---|
1483 | while (s) |
---|
1484 | { |
---|
1485 | strcat (string, separator); |
---|
1486 | strcat (string, s); |
---|
1487 | s = va_arg (args, gchar*); |
---|
1488 | } |
---|
1489 | } |
---|
1490 | else |
---|
1491 | string = g_strdup (""); |
---|
1492 | |
---|
1493 | va_end (args); |
---|
1494 | |
---|
1495 | return string; |
---|
1496 | } |
---|