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 #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 = xrealloc (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 = 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 void *p = (char *) (list->str); /* discard const */
236 str_list_duplicate_node (const StrList* node)
238 StrList* result = str_list_alloc ();
239 result->str = wchar_strdup (node->str);
244 str_list_duplicate (const StrList* list)
247 return str_list_join (str_list_duplicate_node (list),
248 str_list_duplicate (list->next));
254 str_list_join (StrList* a, StrList* b)
258 for (walk = a; walk && walk->next; walk = walk->next);
269 _str_list_append (StrList* list, const wchar_t* str)
274 for (walk = list; walk->next; walk = walk->next);
275 walk->next = str_list_alloc ();
278 walk = list = str_list_alloc ();
286 str_list_append (StrList* list, const char* str)
288 return _str_list_append (list, gettext_to_wchar (str));
292 str_list_append_unique (StrList* list, const char* str)
295 wchar_t* new_str = gettext_to_wchar (str);
297 for (walk=list; walk; walk=walk->next) {
299 if (wchar_strcasecmp (new_str, walk->str) == 0) {
306 return _str_list_append (list, new_str);
310 str_list_insert (StrList* list, const char* str)
312 return str_list_join (str_list_create (str, NULL), list);
316 str_list_create (const char* first, ...)
322 list = str_list_append (NULL, first);
325 va_start (args, first);
326 while ( (str = va_arg (args, char*)) )
327 str_list_append (list, str);
335 str_list_create_unique (const char* first, ...)
341 list = str_list_append (NULL, first);
344 va_start (args, first);
345 while ( (str = va_arg (args, char*)) )
346 str_list_append_unique (list, str);
354 str_list_convert_node (const StrList* list)
356 return wchar_to_str (list->str, 0);
360 str_list_convert (const StrList* list)
365 char* str = xstrdup ("");
367 for (walk = list; walk; walk = walk->next) {
369 char* tmp = wchar_to_str (walk->str, 0);
371 length += strlen (tmp);
373 str = realloc (str, length);
374 strcpy (str + pos, tmp);
385 str_list_print (const StrList* list)
389 for (walk=list; walk; walk=walk->next) {
391 print_wchar (walk->str, 0);
396 str_search (const wchar_t* str, int n, wchar_t c)
407 /* Japanese don't leave spaces between words, so ALL Japanese characters
408 * are treated as delimiters. Note: since the translations should already
409 * be properly formatted (eg: spaces after commas), there should be no
410 * need to include them. Best not to avoid side effects, like 3.
412 * FIXME: how do we exclude "." and "(" ?
413 * FIXME: glibc doesn't like umlaute. i.e. \"o (TeX notation), which should
418 is_break_point (wchar_t c)
421 return !iswalnum (c) && !iswpunct (c);
423 return !isalnum (c) && !ispunct (c);
427 /* NOTE: this should not return '\n' as a space, because explicit '\n' may
428 * be placed inside strings.
434 return c == (wchar_t) btowc(' ');
441 str_list_print_wrap (const StrList* list, int line_length, int offset,
453 PED_ASSERT (line_length - indent > 10, return);
455 line_left = line_length - offset;
457 for (walk=list; walk; walk=walk->next) {
461 str_len = wchar_strlen (str);
463 while (line_left < str_len || wchar_strchr (str, '\n')) {
466 cut_left = MIN (line_left - 1, str_len - 1);
468 /* we can have a space "over", but not a comma */
469 if (cut_left < str_len
470 && is_space (str [cut_left + 1]))
473 while (cut_left && !is_break_point (str [cut_left]))
475 while (cut_left && is_space (str [cut_left]))
478 /* str [cut_left] is either the end of a word, or a
479 * Japanese character, or the start of a blank line.
482 search_result = str_search (str, cut_left + 1, '\n');
483 if (search_result != -1) {
484 cut_left = search_result - 1;
488 for (cut_right = cut_left + (line_break ? 2 : 1);
489 cut_right < str_len && is_space (str [cut_right]);
493 print_wchar (str, cut_left + 1);
496 str_len -= cut_right;
497 line_left = line_length - indent;
499 if (walk->next || *str)
500 printf ("\n%*s", indent, "");
505 print_wchar (str, 0);
506 line_left -= wchar_strlen (str);
511 _str_list_match_node (const StrList* list, const wchar_t* str)
513 if (wchar_strcasecmp (list->str, str) == 0)
515 if (wchar_strncasecmp (list->str, str, wchar_strlen (str)) == 0)
521 str_list_match_node (const StrList* list, const char* str)
523 wchar_t* wc_str = gettext_to_wchar (str); /* FIXME */
526 status = _str_list_match_node (list, wc_str);
532 /* returns: 2 for full match
537 str_list_match_any (const StrList* list, const char* str)
541 wchar_t* wc_str = gettext_to_wchar (str);
543 for (walk = list; walk; walk = walk->next) {
544 int this_status = _str_list_match_node (walk, wc_str);
545 if (this_status > best_status)
546 best_status = this_status;
554 str_list_match (const StrList* list, const char* str)
557 const StrList* partial_match = NULL;
559 wchar_t* wc_str = gettext_to_wchar (str);
561 for (walk = list; walk; walk = walk->next) {
562 switch (_str_list_match_node (walk, wc_str)) {
565 return (StrList*) walk;
570 partial_match = walk;
575 return ambiguous ? NULL : (StrList*) partial_match;
579 str_list_length (const StrList* list)
584 for (walk = list; walk; walk = walk->next)