Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/utils.c @ 551:c71699efa5cc
Add split_arg() / free_arg_lst()
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Tue, 29 Nov 2005 00:03:04 +0100 |
parents | 05c0e55c4bb1 |
children | b1d71f5107a1 |
comparison
equal
deleted
inserted
replaced
550:89cc86940f09 | 551:c71699efa5cc |
---|---|
28 #include <time.h> | 28 #include <time.h> |
29 #include <unistd.h> | 29 #include <unistd.h> |
30 #include <sys/types.h> | 30 #include <sys/types.h> |
31 #include <sys/stat.h> | 31 #include <sys/stat.h> |
32 #include <ctype.h> | 32 #include <ctype.h> |
33 #include <glib.h> | |
33 | 34 |
34 #include <config.h> | 35 #include <config.h> |
35 #include "logprint.h" | 36 #include "logprint.h" |
36 | 37 |
37 static int DebugEnabled; | 38 static int DebugEnabled; |
48 FName = NULL; | 49 FName = NULL; |
49 return; | 50 return; |
50 } | 51 } |
51 | 52 |
52 if (filename) | 53 if (filename) |
53 FName = strdup(filename); | 54 FName = g_strdup(filename); |
54 else { | 55 else { |
55 FName = getenv("HOME"); | 56 FName = getenv("HOME"); |
56 if (!FName) | 57 if (!FName) |
57 FName = "/tmp/mcabberlog"; | 58 FName = "/tmp/mcabberlog"; |
58 else { | 59 else { |
59 char *tmpname = malloc(strlen(FName) + 12); | 60 char *tmpname = g_new(char, strlen(FName) + 12); |
60 strcpy(tmpname, FName); | 61 strcpy(tmpname, FName); |
61 strcat(tmpname, "/mcabberlog"); | 62 strcat(tmpname, "/mcabberlog"); |
62 FName = tmpname; | 63 FName = tmpname; |
63 } | 64 } |
64 } | 65 } |
339 | 340 |
340 /* it's okay as far as we can tell without LIBIDN */ | 341 /* it's okay as far as we can tell without LIBIDN */ |
341 return 0; | 342 return 0; |
342 } | 343 } |
343 | 344 |
345 | |
344 void mc_strtolower(char *str) | 346 void mc_strtolower(char *str) |
345 { | 347 { |
346 if (!str) return; | 348 if (!str) return; |
347 for ( ; *str; str++) | 349 for ( ; *str; str++) |
348 *str = tolower(*str); | 350 *str = tolower(*str); |
349 } | 351 } |
352 | |
353 // strip_arg_special_chars(string) | |
354 // Remove quotes and backslashes before an escaped quote | |
355 // Only quotes need a backslash | |
356 // Ex.: ["a b"] -> [a b]; [a\"b] -> [a"b] | |
357 static void strip_arg_special_chars(char *s) | |
358 { | |
359 int instring = FALSE; | |
360 int escape = FALSE; | |
361 char *p; | |
362 | |
363 for (p = s; *p; p++) { | |
364 if (*p == '"') { | |
365 if (!escape) { | |
366 instring = !instring; | |
367 strcpy(p, p+1); | |
368 p--; | |
369 } else { | |
370 escape = FALSE; | |
371 } | |
372 } else if (*p == '\\') { | |
373 if (!escape) { | |
374 if (*(p+1) == '"') { | |
375 strcpy(p, p+1); | |
376 p--; | |
377 } | |
378 escape = TRUE; | |
379 } else { | |
380 escape = FALSE; | |
381 } | |
382 } | |
383 } | |
384 } | |
385 | |
386 // split_arg(arg, n) | |
387 // Split the string arg into a maximum of n pieces, taking care of | |
388 // double quotes. | |
389 // Return a null-terminated array of strings. This array should be freed | |
390 // be the caller after use, for example with free_arg_lst(). | |
391 char **split_arg(const char *arg, unsigned int n) | |
392 { | |
393 char **arglst; | |
394 const char *p, *start, *end; | |
395 int i = 0; | |
396 int instring = FALSE; | |
397 int escape = FALSE; | |
398 | |
399 arglst = g_new0(char*, n+1); | |
400 | |
401 if (!arg || !n) return arglst; | |
402 | |
403 // Skip leading space | |
404 for (start = arg; *start && *start == ' '; start++) ; | |
405 // End of string pointer | |
406 for (end = start; *end; end++) ; | |
407 // Skip trailing space | |
408 while (end > start+1 && *(end-1) == ' ') | |
409 end--; | |
410 printf("start=|%s|\n", start); | |
411 | |
412 for (p = start; p < end; p++) { | |
413 if (*p == '"' && !escape) | |
414 instring = !instring; | |
415 if (*p == '\\' && !escape) | |
416 escape = TRUE; | |
417 else if (escape) | |
418 escape = FALSE; | |
419 if (*p == ' ' && !instring && i+1 < n) { | |
420 // end of parameter | |
421 *(arglst+i) = g_strndup(start, p-start); | |
422 strip_arg_special_chars(*(arglst+i)); | |
423 start = p+1; | |
424 i++; | |
425 } | |
426 } | |
427 | |
428 if (start < end) { | |
429 *(arglst+i) = g_strndup(start, end-start); | |
430 strip_arg_special_chars(*(arglst+i)); | |
431 } | |
432 | |
433 return arglst; | |
434 } | |
435 | |
436 // free_arg_lst(arglst) | |
437 // Free an array allocated by split_arg() | |
438 void free_arg_lst(char **arglst) | |
439 { | |
440 char **arg_elt; | |
441 | |
442 for (arg_elt = arglst; *arg_elt; arg_elt++) | |
443 g_free(*arg_elt); | |
444 g_free(arglst); | |
445 } |