2 parted - a frontend to libparted
3 Copyright (C) 1999-2001, 2007, 2009-2010 Free Software Foundation,
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <parted/debug.h>
41 #endif /* !ENABLE_NLS */
45 #define MIN(a,b) ( (a<b)? a : b )
48 wchar_strlen (const wchar_t* str)
58 wchar_strchr (const wchar_t* str, char ch)
61 return wcschr (str, ch);
63 return strchr (str, ch);
68 wchar_strcasecmp (const wchar_t* a, const wchar_t* b)
71 return wcscasecmp (a, b);
73 return strcasecmp (a, b);
78 wchar_strncasecmp (const wchar_t* a, const wchar_t* b, size_t n)
81 return wcsncasecmp (a, b, n);
83 return strncasecmp (a, b, n);
88 wchar_strdup (const wchar_t* str)
97 /* converts a string from the encoding in the gettext catalogues to wide
98 * character strings (of type wchar_t*).
102 gettext_to_wchar (const char* str)
109 count = strlen (str) + 1;
110 result = malloc (count * sizeof (wchar_t));
114 memset(&ps, 0, sizeof (ps));
115 status = mbsrtowcs(result, &str, count, &ps);
116 if (status == (size_t) -1)
119 result = xrealloc (result, (wcslen (result) + 1) * sizeof (wchar_t));
123 printf ("Error during translation: %s\n", strerror (errno));
127 #else /* ENABLE_NLS */
130 gettext_to_wchar (const char* str)
132 return xstrdup (str);
135 #endif /* !ENABLE_NLS */
140 wchar_to_str (const wchar_t* str, size_t count)
148 if (count == 0 || wcslen(str) < count)
149 count = wcslen (str);
151 out_buf = result = malloc ((count + 1) * MB_LEN_MAX);
155 memset(&ps, 0, sizeof(ps));
157 for (i = 0; i < count; i++) {
158 status = wcrtomb (out_buf, str[i], &ps);
159 if (status == (size_t) -1)
164 status = wcrtomb (out_buf, 0, &ps);
165 if (status == (size_t) -1)
168 result = realloc (result, strlen (result) + 1);
172 printf ("Error during translation: %s\n", strerror (errno));
176 #else /* ENABLE_NLS */
179 wchar_to_str (const wchar_t* str, size_t count)
183 result = xstrdup (str);
184 if (count && count < strlen (result))
189 #endif /* !ENABLE_NLS */
192 print_wchar (const wchar_t* str, size_t count)
194 char* tmp = wchar_to_str (str, count);
204 list = xmalloc (sizeof (StrList));
211 str_list_destroy (StrList* list)
214 str_list_destroy (list->next);
215 str_list_destroy_node (list);
220 str_list_destroy_node (StrList* list)
222 void *p = (char *) (list->str); /* discard const */
228 str_list_duplicate_node (const StrList* node)
230 StrList* result = str_list_alloc ();
231 result->str = wchar_strdup (node->str);
236 str_list_duplicate (const StrList* list)
239 return str_list_join (str_list_duplicate_node (list),
240 str_list_duplicate (list->next));
246 str_list_join (StrList* a, StrList* b)
250 for (walk = a; walk && walk->next; walk = walk->next);
261 _str_list_append (StrList* list, const wchar_t* str)
266 for (walk = list; walk->next; walk = walk->next);
267 walk->next = str_list_alloc ();
270 walk = list = str_list_alloc ();
278 str_list_append (StrList* list, const char* str)
280 return _str_list_append (list, gettext_to_wchar (str));
284 str_list_append_unique (StrList* list, const char* str)
287 wchar_t* new_str = gettext_to_wchar (str);
289 for (walk=list; walk; walk=walk->next) {
291 if (wchar_strcasecmp (new_str, walk->str) == 0) {
298 return _str_list_append (list, new_str);
302 str_list_insert (StrList* list, const char* str)
304 return str_list_join (str_list_create (str, NULL), list);
308 str_list_create (const char* first, ...)
314 list = str_list_append (NULL, first);
317 va_start (args, first);
318 while ( (str = va_arg (args, char*)) )
319 str_list_append (list, str);
327 str_list_create_unique (const char* first, ...)
333 list = str_list_append (NULL, first);
336 va_start (args, first);
337 while ( (str = va_arg (args, char*)) )
338 str_list_append_unique (list, str);
346 str_list_convert_node (const StrList* list)
348 return wchar_to_str (list->str, 0);
352 str_list_convert (const StrList* list)
357 char* str = xstrdup ("");
359 for (walk = list; walk; walk = walk->next) {
361 char* tmp = wchar_to_str (walk->str, 0);
363 length += strlen (tmp);
365 str = realloc (str, length);
366 strcpy (str + pos, tmp);
377 str_list_print (const StrList* list)
381 for (walk=list; walk; walk=walk->next) {
383 print_wchar (walk->str, 0);
388 str_search (const wchar_t* str, int n, wchar_t c)
399 /* Japanese don't leave spaces between words, so ALL Japanese characters
400 * are treated as delimiters. Note: since the translations should already
401 * be properly formatted (eg: spaces after commas), there should be no
402 * need to include them. Best not to avoid side effects, like 3.
404 * FIXME: how do we exclude "." and "(" ?
405 * FIXME: glibc doesn't like umlaute. i.e. \"o (TeX notation), which should
410 is_break_point (wchar_t c)
413 return !iswalnum (c) && !iswpunct (c);
415 return !isalnum (c) && !ispunct (c);
419 /* NOTE: this should not return '\n' as a space, because explicit '\n' may
420 * be placed inside strings.
426 return c == (wchar_t) btowc(' ');
433 str_list_print_wrap (const StrList* list, int line_length, int offset,
445 PED_ASSERT (line_length - indent > 10, return);
447 line_left = line_length - offset;
449 for (walk=list; walk; walk=walk->next) {
453 str_len = wchar_strlen (str);
455 while (line_left < str_len || wchar_strchr (str, '\n')) {
458 cut_left = MIN (line_left - 1, str_len - 1);
460 /* we can have a space "over", but not a comma */
461 if (cut_left < str_len
462 && is_space (str [cut_left + 1]))
465 while (cut_left && !is_break_point (str [cut_left]))
467 while (cut_left && is_space (str [cut_left]))
470 /* str [cut_left] is either the end of a word, or a
471 * Japanese character, or the start of a blank line.
474 search_result = str_search (str, cut_left + 1, '\n');
475 if (search_result != -1) {
476 cut_left = search_result - 1;
480 for (cut_right = cut_left + (line_break ? 2 : 1);
481 cut_right < str_len && is_space (str [cut_right]);
485 print_wchar (str, cut_left + 1);
488 str_len -= cut_right;
489 line_left = line_length - indent;
491 if (walk->next || *str)
492 printf ("\n%*s", indent, "");
497 print_wchar (str, 0);
498 line_left -= wchar_strlen (str);
503 _str_list_match_node (const StrList* list, const wchar_t* str)
505 if (wchar_strcasecmp (list->str, str) == 0)
507 if (wchar_strncasecmp (list->str, str, wchar_strlen (str)) == 0)
513 str_list_match_node (const StrList* list, const char* str)
515 wchar_t* wc_str = gettext_to_wchar (str); /* FIXME */
518 status = _str_list_match_node (list, wc_str);
524 /* returns: 2 for full match
529 str_list_match_any (const StrList* list, const char* str)
533 wchar_t* wc_str = gettext_to_wchar (str);
535 for (walk = list; walk; walk = walk->next) {
536 int this_status = _str_list_match_node (walk, wc_str);
537 if (this_status > best_status)
538 best_status = this_status;
546 str_list_match (const StrList* list, const char* str)
549 const StrList* partial_match = NULL;
551 wchar_t* wc_str = gettext_to_wchar (str);
553 for (walk = list; walk; walk = walk->next) {
554 switch (_str_list_match_node (walk, wc_str)) {
557 return (StrList*) walk;
562 partial_match = walk;
567 return ambiguous ? NULL : (StrList*) partial_match;
571 str_list_length (const StrList* list)
576 for (walk = list; walk; walk = walk->next)