/*
parted - a frontend to libparted
Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "xalloc.h"
#ifdef ENABLE_NLS
#undef __USE_GNU
#define __USE_GNU
#include
#include
#else /* ENABLE_NLS */
#ifdef wchar_t
#undef wchar_t
#endif
#define wchar_t char
#endif /* !ENABLE_NLS */
#include "strlist.h"
#define MIN(a,b) ( (anext = NULL;
return list;
}
void
str_list_destroy (StrList* list)
{
if (list) {
str_list_destroy (list->next);
str_list_destroy_node (list);
}
}
void
str_list_destroy_node (StrList* list)
{
free ((wchar_t*) list->str);
free (list);
}
StrList*
str_list_duplicate_node (const StrList* node)
{
StrList* result = str_list_alloc ();
result->str = wchar_strdup (node->str);
return result;
}
StrList*
str_list_duplicate (const StrList* list)
{
if (list)
return str_list_join (str_list_duplicate_node (list),
str_list_duplicate (list->next));
else
return NULL;
}
StrList*
str_list_join (StrList* a, StrList* b)
{
StrList* walk;
for (walk = a; walk && walk->next; walk = walk->next);
if (walk) {
walk->next = b;
return a;
} else {
return b;
}
}
static StrList*
_str_list_append (StrList* list, const wchar_t* str)
{
StrList* walk;
if (list) {
for (walk = list; walk->next; walk = walk->next);
walk->next = str_list_alloc ();
walk = walk->next;
} else {
walk = list = str_list_alloc ();
}
walk->str = str;
return list;
}
StrList*
str_list_append (StrList* list, const char* str)
{
return _str_list_append (list, gettext_to_wchar (str));
}
StrList*
str_list_append_unique (StrList* list, const char* str)
{
StrList* walk;
wchar_t* new_str = gettext_to_wchar (str);
for (walk=list; walk; walk=walk->next) {
if (walk->str) {
if (wchar_strcasecmp (new_str, walk->str) == 0) {
free (new_str);
return list;
}
}
}
return _str_list_append (list, new_str);
}
StrList*
str_list_insert (StrList* list, const char* str)
{
return str_list_join (str_list_create (str, NULL), list);
}
StrList*
str_list_create (const char* first, ...)
{
va_list args;
char* str;
StrList* list;
list = str_list_append (NULL, first);
if (first) {
va_start (args, first);
while ( (str = va_arg (args, char*)) )
str_list_append (list, str);
va_end (args);
}
return list;
}
StrList*
str_list_create_unique (const char* first, ...)
{
va_list args;
char* str;
StrList* list;
list = str_list_append (NULL, first);
if (first) {
va_start (args, first);
while ( (str = va_arg (args, char*)) )
str_list_append_unique (list, str);
va_end (args);
}
return list;
}
char*
str_list_convert_node (const StrList* list)
{
return wchar_to_str (list->str, 0);
}
char*
str_list_convert (const StrList* list)
{
const StrList* walk;
int pos = 0;
int length = 1;
char* str = xstrdup ("");
for (walk = list; walk; walk = walk->next) {
if (walk->str) {
char* tmp = wchar_to_str (walk->str, 0);
length += strlen (tmp);
str = realloc (str, length);
strcpy (str + pos, tmp);
pos = length - 1;
free (tmp);
}
}
return str;
}
void
str_list_print (const StrList* list)
{
const StrList* walk;
for (walk=list; walk; walk=walk->next) {
if (walk->str)
print_wchar (walk->str, 0);
}
}
static int
str_search (const wchar_t* str, int n, wchar_t c)
{
int i;
for (i=0; i 10, return);
line_left = line_length - offset;
for (walk=list; walk; walk=walk->next) {
if (!walk->str)
continue;
str = walk->str;
str_len = wchar_strlen (str);
while (line_left < str_len || wchar_strchr (str, '\n')) {
line_break = 0;
cut_left = MIN (line_left - 1, str_len - 1);
/* we can have a space "over", but not a comma */
if (cut_left < str_len
&& is_space (str [cut_left + 1]))
cut_left++;
while (cut_left && !is_break_point (str [cut_left]))
cut_left--;
while (cut_left && is_space (str [cut_left]))
cut_left--;
/* str [cut_left] is either the end of a word, or a
* Japanese character, or the start of a blank line.
*/
search_result = str_search (str, cut_left + 1, '\n');
if (search_result != -1) {
cut_left = search_result - 1;
line_break = 1;
}
for (cut_right = cut_left + (line_break ? 2 : 1);
cut_right < str_len && is_space (str [cut_right]);
cut_right++);
if (cut_left > 0)
print_wchar (str, cut_left + 1);
str += cut_right;
str_len -= cut_right;
line_left = line_length - indent;
if (walk->next || *str)
printf ("\n%*s", indent, "");
else if (line_break)
putchar ('\n');
}
print_wchar (str, 0);
line_left -= wchar_strlen (str);
}
}
static int
_str_list_match_node (const StrList* list, const wchar_t* str)
{
if (wchar_strcasecmp (list->str, str) == 0)
return 2;
if (wchar_strncasecmp (list->str, str, wchar_strlen (str)) == 0)
return 1;
return 0;
}
int
str_list_match_node (const StrList* list, const char* str)
{
wchar_t* wc_str = gettext_to_wchar (str); /* FIXME */
int status;
status = _str_list_match_node (list, wc_str);
free (wc_str);
return status;
}
/* returns: 2 for full match
1 for partial match
0 for no match
*/
int
str_list_match_any (const StrList* list, const char* str)
{
const StrList* walk;
int best_status = 0;
wchar_t* wc_str = gettext_to_wchar (str);
for (walk = list; walk; walk = walk->next) {
int this_status = _str_list_match_node (walk, wc_str);
if (this_status > best_status)
best_status = this_status;
}
free (wc_str);
return best_status;
}
StrList*
str_list_match (const StrList* list, const char* str)
{
const StrList* walk;
const StrList* partial_match = NULL;
int ambiguous = 0;
wchar_t* wc_str = gettext_to_wchar (str);
for (walk = list; walk; walk = walk->next) {
switch (_str_list_match_node (walk, wc_str)) {
case 2:
free (wc_str);
return (StrList*) walk;
case 1:
if (partial_match)
ambiguous = 1;
partial_match = walk;
}
}
free (wc_str);
return ambiguous ? NULL : (StrList*) partial_match;
}
int
str_list_length (const StrList* list)
{
int length = 0;
const StrList* walk;
for (walk = list; walk; walk = walk->next)
length++;
return length;
}