2 parted - a frontend to libparted
3 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <parted/debug.h>
41 #else /* ENABLE_NLS */
49 #endif /* !ENABLE_NLS */
53 #define MIN(a,b) ( (a<b)? a : b )
56 wchar_strlen (const wchar_t* str)
66 wchar_strchr (const wchar_t* str, char ch)
69 return wcschr (str, ch);
71 return strchr (str, ch);
76 wchar_strcasecmp (const wchar_t* a, const wchar_t* b)
79 return wcscasecmp (a, b);
81 return strcasecmp (a, b);
86 wchar_strncasecmp (const wchar_t* a, const wchar_t* b, size_t n)
89 return wcsncasecmp (a, b, n);
91 return strncasecmp (a, b, n);
96 wchar_strdup (const wchar_t* str)
101 return xstrdup (str);
105 /* converts a string from the encoding in the gettext catalogues to wide
106 * character strings (of type wchar_t*).
110 gettext_to_wchar (const char* str)
117 count = strlen (str) + 1;
118 result = malloc (count * sizeof (wchar_t));
122 memset(&ps, 0, sizeof (ps));
123 status = mbsrtowcs(result, &str, count, &ps);
124 if (status == (size_t) -1)
127 result = realloc (result, (wcslen (result) + 1) * sizeof (wchar_t));
131 printf ("Error during translation: %s\n", strerror (errno));
135 #else /* ENABLE_NLS */
138 gettext_to_wchar (const char* str)
140 return xstrdup (str);
143 #endif /* !ENABLE_NLS */
148 wchar_to_str (const wchar_t* str, size_t count)
156 if (count == 0 || wcslen(str) < count)
157 count = wcslen (str);
159 out_buf = result = malloc ((count + 1) * MB_LEN_MAX);
163 memset(&ps, 0, sizeof(ps));
165 for (i = 0; i < count; i++) {
166 status = wcrtomb (out_buf, str[i], &ps);
167 if (status == (size_t) -1)
172 status = wcrtomb (out_buf, 0, &ps);
173 if (status == (size_t) -1)
176 result = realloc (result, strlen (result) + 1);
180 printf ("Error during translation: %s\n", strerror (errno));
184 #else /* ENABLE_NLS */
187 wchar_to_str (const wchar_t* str, size_t count)
191 result = xstrdup (str);
192 if (count && count < strlen (result))
197 #endif /* !ENABLE_NLS */
200 print_wchar (const wchar_t* str, size_t count)
202 char* tmp = wchar_to_str (str, count);
212 list = (StrList*) xmalloc (sizeof (StrList));
219 str_list_destroy (StrList* list)
222 str_list_destroy (list->next);
223 str_list_destroy_node (list);
228 str_list_destroy_node (StrList* list)
230 free ((wchar_t*) list->str);
235 str_list_duplicate_node (const StrList* node)
237 StrList* result = str_list_alloc ();
238 result->str = wchar_strdup (node->str);
243 str_list_duplicate (const StrList* list)
246 return str_list_join (str_list_duplicate_node (list),
247 str_list_duplicate (list->next));
253 str_list_join (StrList* a, StrList* b)
257 for (walk = a; walk && walk->next; walk = walk->next);
268 _str_list_append (StrList* list, const wchar_t* str)
273 for (walk = list; walk->next; walk = walk->next);
274 walk->next = str_list_alloc ();
277 walk = list = str_list_alloc ();
285 str_list_append (StrList* list, const char* str)
287 return _str_list_append (list, gettext_to_wchar (str));
291 str_list_append_unique (StrList* list, const char* str)
294 wchar_t* new_str = gettext_to_wchar (str);
296 for (walk=list; walk; walk=walk->next) {
298 if (wchar_strcasecmp (new_str, walk->str) == 0) {
305 return _str_list_append (list, new_str);
309 str_list_insert (StrList* list, const char* str)
311 return str_list_join (str_list_create (str, NULL), list);
315 str_list_create (const char* first, ...)
321 list = str_list_append (NULL, first);
324 va_start (args, first);
325 while ( (str = va_arg (args, char*)) )
326 str_list_append (list, str);
334 str_list_create_unique (const char* first, ...)
340 list = str_list_append (NULL, first);
343 va_start (args, first);
344 while ( (str = va_arg (args, char*)) )
345 str_list_append_unique (list, str);
353 str_list_convert_node (const StrList* list)
355 return wchar_to_str (list->str, 0);
359 str_list_convert (const StrList* list)
364 char* str = xstrdup ("");
366 for (walk = list; walk; walk = walk->next) {
368 char* tmp = wchar_to_str (walk->str, 0);
370 length += strlen (tmp);
372 str = realloc (str, length);
373 strcpy (str + pos, tmp);
384 str_list_print (const StrList* list)
388 for (walk=list; walk; walk=walk->next) {
390 print_wchar (walk->str, 0);
395 str_search (const wchar_t* str, int n, wchar_t c)
406 /* Japanese don't leave spaces between words, so ALL Japanese characters
407 * are treated as delimiters. Note: since the translations should already
408 * be properly formatted (eg: spaces after commas), there should be no
409 * need to include them. Best not to avoid side effects, like 3.
411 * FIXME: how do we exclude "." and "(" ?
412 * FIXME: glibc doesn't like umlaute. i.e. \"o (TeX notation), which should
417 is_break_point (wchar_t c)
420 return !iswalnum (c) && !iswpunct (c);
422 return !isalnum (c) && !ispunct (c);
426 /* NOTE: this should not return '\n' as a space, because explicit '\n' may
427 * be placed inside strings.
433 return c == (wchar_t) btowc(' ');
440 str_list_print_wrap (const StrList* list, int line_length, int offset,
452 PED_ASSERT (line_length - indent > 10, return);
454 line_left = line_length - offset;
456 for (walk=list; walk; walk=walk->next) {
460 str_len = wchar_strlen (str);
462 while (line_left < str_len || wchar_strchr (str, '\n')) {
465 cut_left = MIN (line_left - 1, str_len - 1);
467 /* we can have a space "over", but not a comma */
468 if (cut_left < str_len
469 && is_space (str [cut_left + 1]))
472 while (cut_left && !is_break_point (str [cut_left]))
474 while (cut_left && is_space (str [cut_left]))
477 /* str [cut_left] is either the end of a word, or a
478 * Japanese character, or the start of a blank line.
481 search_result = str_search (str, cut_left + 1, '\n');
482 if (search_result != -1) {
483 cut_left = search_result - 1;
487 for (cut_right = cut_left + (line_break ? 2 : 1);
488 cut_right < str_len && is_space (str [cut_right]);
492 print_wchar (str, cut_left + 1);
495 str_len -= cut_right;
496 line_left = line_length - indent;
498 if (walk->next || *str)
499 printf ("\n%*s", indent, "");
504 print_wchar (str, 0);
505 line_left -= wchar_strlen (str);
510 _str_list_match_node (const StrList* list, const wchar_t* str)
512 if (wchar_strcasecmp (list->str, str) == 0)
514 if (wchar_strncasecmp (list->str, str, wchar_strlen (str)) == 0)
520 str_list_match_node (const StrList* list, const char* str)
522 wchar_t* wc_str = gettext_to_wchar (str); /* FIXME */
525 status = _str_list_match_node (list, wc_str);
531 /* returns: 2 for full match
536 str_list_match_any (const StrList* list, const char* str)
540 wchar_t* wc_str = gettext_to_wchar (str);
542 for (walk = list; walk; walk = walk->next) {
543 int this_status = _str_list_match_node (walk, wc_str);
544 if (this_status > best_status)
545 best_status = this_status;
553 str_list_match (const StrList* list, const char* str)
556 const StrList* partial_match = NULL;
558 wchar_t* wc_str = gettext_to_wchar (str);
560 for (walk = list; walk; walk = walk->next) {
561 switch (_str_list_match_node (walk, wc_str)) {
564 return (StrList*) walk;
569 partial_match = walk;
574 return ambiguous ? NULL : (StrList*) partial_match;
578 str_list_length (const StrList* list)
583 for (walk = list; walk; walk = walk->next)