📄 strlist.c
字号:
/* GNU fdisk - a clone of Linux fdisk. This file originally from GNU Parted. Copyright (C) 1999, 2000, 2001, 2002, 2006 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, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA*/#include "config.h"#include <parted/debug.h>#include <ctype.h>#include <errno.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#ifdef ENABLE_NLS#undef __USE_GNU#define __USE_GNU#include <wchar.h>#include <wctype.h>#else /* ENABLE_NLS */#ifdef wchar_t#undef wchar_t#endif#define wchar_t char#endif /* !ENABLE_NLS */#include "strlist.h"#define MIN(a,b) ( (a<b)? a : b )intwchar_strlen (const wchar_t* str){#ifdef ENABLE_NLS return wcslen (str);#else return strlen (str);#endif}wchar_t*wchar_strchr (const wchar_t* str, char ch){#ifdef ENABLE_NLS return wcschr (str, ch);#else return strchr (str, ch);#endif}intwchar_strcasecmp (const wchar_t* a, const wchar_t* b){#ifdef ENABLE_NLS return wcscasecmp (a, b);#else return strcasecmp (a, b);#endif}intwchar_strncasecmp (const wchar_t* a, const wchar_t* b, size_t n){#ifdef ENABLE_NLS return wcsncasecmp (a, b, n);#else return strncasecmp (a, b, n);#endif}wchar_t*wchar_strdup (const wchar_t* str){#ifdef ENABLE_NLS return wcsdup (str);#else return strdup (str);#endif}/* converts a string from the encoding in the gettext catalogues to wide * character strings (of type wchar_t*). */#ifdef ENABLE_NLSstatic wchar_t*gettext_to_wchar (const char* str){ int count; wchar_t* result; size_t status; mbstate_t ps; count = strlen (str) + 1; result = malloc (count * sizeof (wchar_t)); if (!result) goto error; memset(&ps, 0, sizeof (ps)); status = mbsrtowcs(result, &str, count, &ps); if (status == (size_t) -1) goto error; result = realloc (result, (wcslen (result) + 1) * sizeof (wchar_t)); return result;error: printf ("Error during translation: %s\n", strerror (errno)); exit (1);}#else /* ENABLE_NLS */static wchar_t*gettext_to_wchar (const char* str){ return strdup (str);}#endif /* !ENABLE_NLS */#ifdef ENABLE_NLSstatic char*wchar_to_str (const wchar_t* str, size_t count){ char* result; char* out_buf; size_t status; mbstate_t ps; size_t i; if (count == 0 || wcslen(str) < count) count = wcslen (str); out_buf = result = malloc ((count + 1) * MB_LEN_MAX); if (!result) goto error; memset(&ps, 0, sizeof(ps)); for (i = 0; i < count; i++) { status = wcrtomb (out_buf, str[i], &ps); if (status == (size_t) -1) goto error; out_buf += status; } status = wcrtomb (out_buf, 0, &ps); if (status == (size_t) -1) goto error; result = realloc (result, strlen (result) + 1); return result;error: printf ("Error during translation: %s\n", strerror (errno)); exit (1);}#else /* ENABLE_NLS */static char*wchar_to_str (const wchar_t* str, size_t count){ char* result; result = strdup (str); if (count && count < strlen (result)) result [count] = 0; return result;}#endif /* !ENABLE_NLS */static voidprint_wchar (const wchar_t* str, size_t count){ char* tmp = wchar_to_str (str, count); printf ("%s", tmp); free (tmp);}static StrList* str_list_alloc (){ StrList* list; list = (StrList*) malloc (sizeof (StrList)); list->next = NULL; return list;}voidstr_list_destroy (StrList* list){ if (list) { str_list_destroy (list->next); str_list_destroy_node (list); }}voidstr_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 = strdup (""); 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;}voidstr_list_print (const StrList* list){ const StrList* walk; for (walk=list; walk; walk=walk->next) { if (walk->str) print_wchar (walk->str, 0); }}static char*get_spaces (int space_count){ char* str; int i; str = malloc (space_count + 1); for (i = 0; i < space_count; i++) str [i] = ' '; str [i] = 0; return str;}static intstr_search (const wchar_t* str, int n, wchar_t c){ int i; for (i=0; i<n; i++) if (str [i] == c) return i; return -1;}/* Japanese don't leave spaces between words, so ALL Japanese characters * are treated as delimiters. Note: since the translations should already * be properly formatted (eg: spaces after commas), there should be no * need to include them. Best not to avoid side effects, like 3.14159 :-) * FIXME: how do we exclude "." and "(" ? * FIXME: glibc doesn't like umlaute. i.e. \"o (TeX notation), which should * look like:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -