Rework strutils for usage GString instread of self-made buffers.

This commit is contained in:
Slava Zanko 2009-04-14 13:29:01 +03:00
parent 21c88729a4
commit dbf8dd1bc2
11 changed files with 1806 additions and 1715 deletions

View File

@ -1068,8 +1068,8 @@ get_random_hint (int force)
int start; int start;
static int last_sec; static int last_sec;
static struct timeval tv; static struct timeval tv;
str_conv_t conv; GIConv conv;
struct str_buffer *buffer; GString *buffer;
/* Do not change hints more often than one minute */ /* Do not change hints more often than one minute */
gettimeofday (&tv, NULL); gettimeofday (&tv, NULL);
@ -1095,20 +1095,19 @@ get_random_hint (int force)
eol = strchr (&data[start], '\n'); eol = strchr (&data[start], '\n');
if (eol) if (eol)
*eol = 0; *eol = 0;
/* hint files are stored in utf-8 */ /* hint files are stored in utf-8 */
/* try convert hint file from utf-8 to terminal encoding */ /* try convert hint file from utf-8 to terminal encoding */
conv = str_crt_conv_from ("UTF-8"); conv = str_crt_conv_from ("UTF-8");
if (conv != INVALID_CONV) { if (conv != INVALID_CONV) {
buffer = str_get_buffer (); buffer = g_string_new ("");
if (str_convert (conv, &data[start], buffer) != ESTR_FAILURE) { if (str_convert (conv, &data[start], buffer) != ESTR_FAILURE) {
result = g_strdup (buffer->data); result = g_strdup (buffer->str);
} }
g_string_free (buffer, TRUE);
str_release_buffer (buffer);
str_close_conv (conv); str_close_conv (conv);
} }
g_free (data); g_free (data);
return result; return result;
} }

View File

@ -69,12 +69,6 @@
#define STRING_LINK_END "\03" #define STRING_LINK_END "\03"
#define STRING_NODE_END "\04" #define STRING_NODE_END "\04"
/* every help file is supposed to be in utf-8 and is translated to terminal
* encoding */
/* buffer for translation */
static struct str_buffer *translated_data = NULL;
/* point into translated_data->data or in NULL,
* if help file could not be converted */
static char *data; static char *data;
static int help_lines; /* Lines in help viewer */ static int help_lines; /* Lines in help viewer */
static int history_ptr; /* For the history queue */ static int history_ptr; /* For the history queue */
@ -775,26 +769,26 @@ interactive_display_finish (void)
clear_link_areas (); clear_link_areas ();
} }
/* translate help file into terminal encoding /* translate help file into terminal encoding */
* translated_data is initialized */
static void static void
translate_file (char *filedata) translate_file (char *filedata)
{ {
str_conv_t conv; GIConv conv;
GString *translated_data;
if (translated_data == NULL) translated_data = str_get_buffer ();
translated_data = g_string_new ("");
str_reset_buffer (translated_data);
conv = str_crt_conv_from ("UTF-8"); conv = str_crt_conv_from ("UTF-8");
if (conv != INVALID_CONV) { if (conv != INVALID_CONV) {
if (str_convert (conv, filedata, translated_data) != ESTR_FAILURE) { if (str_convert (conv, filedata, translated_data) != ESTR_FAILURE) {
data = translated_data->data; data = translated_data->str;
} else { } else {
data = NULL; data = NULL;
} }
str_close_conv (conv); str_close_conv (conv);
} }
g_string_free (translated_data, TRUE);
} }
void void

View File

@ -218,20 +218,18 @@ do { \
static void fill_listbox (void) static void fill_listbox (void)
{ {
struct hotlist *current = current_group->head; struct hotlist *current = current_group->head;
struct str_buffer *buff; GString *buff = g_string_new ("");
buff = str_get_buffer ();
while (current){ while (current){
switch (current->type) { switch (current->type) {
case HL_TYPE_GROUP: case HL_TYPE_GROUP:
{ {
str_insert_string ("->", buff); g_string_append(buff,"->");
str_insert_string (current->label, buff); g_string_append(buff,current->label);
if (hotlist_state.moving) if (hotlist_state.moving)
listbox_add_item (l_movelist, 0, 0, buff->data, current); listbox_add_item (l_movelist, 0, 0, buff->str, current);
else else
listbox_add_item (l_hotlist, 0, 0, buff->data, current); listbox_add_item (l_hotlist, 0, 0, buff->str, current);
} }
break; break;
case HL_TYPE_DOTDOT: case HL_TYPE_DOTDOT:
@ -246,8 +244,7 @@ static void fill_listbox (void)
} }
current = current->next; current = current->next;
} }
g_string_free (buff, TRUE);
str_release_buffer (buff);
} }
static void static void
@ -1203,7 +1200,7 @@ load_group (struct hotlist *grp)
#define TKN_EOF 126 #define TKN_EOF 126
#define TKN_UNKNOWN 127 #define TKN_UNKNOWN 127
static struct str_buffer *tkn_buf = NULL; static GString *tkn_buf = NULL;
static char *hotlist_file_name; static char *hotlist_file_name;
static FILE *hotlist_file; static FILE *hotlist_file;
@ -1221,41 +1218,47 @@ static int hot_skip_blanks (void)
static int hot_next_token (void) static int hot_next_token (void)
{ {
int c; int c, ret=0;
size_t l; size_t l;
if (tkn_buf == NULL) tkn_buf = str_get_buffer ();
str_reset_buffer (tkn_buf); if (tkn_buf == NULL) tkn_buf = g_string_new ("");
g_string_set_size(tkn_buf,0);
again: again:
c = hot_skip_blanks (); c = hot_skip_blanks ();
switch (c) { switch (c) {
case EOF: case EOF:
return TKN_EOF; ret = TKN_EOF;
break; break;
case '\n': case '\n':
return TKN_EOL; ret = TKN_EOL;
break; break;
case '#': case '#':
while ((c = getc (hotlist_file)) != EOF && c != '\n') { while ((c = getc (hotlist_file)) != EOF && c != '\n') {
str_insert_char (c, tkn_buf); g_string_append_c (tkn_buf, c);
} }
return TKN_COMMENT; ret = TKN_COMMENT;
break; break;
case '"': case '"':
while ((c = getc (hotlist_file)) != EOF && c != '"') { while ((c = getc (hotlist_file)) != EOF && c != '"') {
if (c == '\\') if (c == '\\')
if ((c = getc (hotlist_file)) == EOF) if ((c = getc (hotlist_file)) == EOF){
g_string_free (tkn_buf, TRUE);
return TKN_EOF; return TKN_EOF;
str_insert_char (c == '\n' ? ' ' : c, tkn_buf); }
g_string_append_c (tkn_buf, c == '\n' ? ' ' : c);
} }
if (c == EOF) if (c == EOF)
return TKN_EOF; ret = TKN_EOF;
return TKN_STRING; else
ret = TKN_STRING;
break; break;
case '\\': case '\\':
if ((c = getc (hotlist_file)) == EOF) if ((c = getc (hotlist_file)) == EOF){
g_string_free (tkn_buf, TRUE);
return TKN_EOF; return TKN_EOF;
}
if (c == '\n') if (c == '\n')
goto again; goto again;
@ -1263,24 +1266,25 @@ again:
default: default:
do { do {
str_insert_char (g_ascii_toupper (c), tkn_buf); g_string_append_c (tkn_buf, g_ascii_toupper (c));
} while ((c = fgetc (hotlist_file)) != EOF && } while ((c = fgetc (hotlist_file)) != EOF &&
(g_ascii_isalnum (c) || !isascii (c))); (g_ascii_isalnum (c) || !isascii (c)));
if (c != EOF) if (c != EOF)
ungetc (c, hotlist_file); ungetc (c, hotlist_file);
l = tkn_buf->size - tkn_buf->remain; l = tkn_buf->len;
if (strncmp (tkn_buf->data, "GROUP", l) == 0) if (strncmp (tkn_buf->str, "GROUP", l) == 0)
return TKN_GROUP; ret = TKN_GROUP;
else if (strncmp (tkn_buf->data, "ENTRY", l) == 0) else if (strncmp (tkn_buf->str, "ENTRY", l) == 0)
return TKN_ENTRY; ret = TKN_ENTRY;
else if (strncmp (tkn_buf->data, "ENDGROUP", l) == 0) else if (strncmp (tkn_buf->str, "ENDGROUP", l) == 0)
return TKN_ENDGROUP; ret = TKN_ENDGROUP;
else if (strncmp (tkn_buf->data, "URL", l) == 0) else if (strncmp (tkn_buf->str, "URL", l) == 0)
return TKN_URL; ret = TKN_URL;
else else
return TKN_UNKNOWN; ret = TKN_UNKNOWN;
break; break;
} }
return ret;
} }
#define SKIP_TO_EOL { \ #define SKIP_TO_EOL { \
@ -1310,22 +1314,22 @@ hot_load_group (struct hotlist * grp)
switch (tkn) { switch (tkn) {
case TKN_GROUP: case TKN_GROUP:
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
new_grp = add2hotlist (g_strdup (tkn_buf->data), 0, HL_TYPE_GROUP, 0); new_grp = add2hotlist (g_strdup (tkn_buf->str), 0, HL_TYPE_GROUP, 0);
SKIP_TO_EOL; SKIP_TO_EOL;
hot_load_group (new_grp); hot_load_group (new_grp);
current_group = grp; current_group = grp;
break; break;
case TKN_ENTRY: case TKN_ENTRY:
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
label = g_strdup (tkn_buf->data); label = g_strdup (tkn_buf->str);
CHECK_TOKEN(TKN_URL); CHECK_TOKEN(TKN_URL);
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
url = g_strdup (tkn_buf->data); url = g_strdup (tkn_buf->str);
add2hotlist (label, url, HL_TYPE_ENTRY, 0); add2hotlist (label, url, HL_TYPE_ENTRY, 0);
SKIP_TO_EOL; SKIP_TO_EOL;
break; break;
case TKN_COMMENT: case TKN_COMMENT:
label = g_strdup (tkn_buf->data); label = g_strdup (tkn_buf->str);
add2hotlist (label, 0, HL_TYPE_COMMENT, 0); add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
break; break;
case TKN_EOF: case TKN_EOF:
@ -1358,22 +1362,22 @@ hot_load_file (struct hotlist * grp)
switch (tkn) { switch (tkn) {
case TKN_GROUP: case TKN_GROUP:
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
new_grp = add2hotlist (g_strdup (tkn_buf->data), 0, HL_TYPE_GROUP, 0); new_grp = add2hotlist (g_strdup (tkn_buf->str), 0, HL_TYPE_GROUP, 0);
SKIP_TO_EOL; SKIP_TO_EOL;
hot_load_group (new_grp); hot_load_group (new_grp);
current_group = grp; current_group = grp;
break; break;
case TKN_ENTRY: case TKN_ENTRY:
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
label = g_strdup (tkn_buf->data); label = g_strdup (tkn_buf->str);
CHECK_TOKEN(TKN_URL); CHECK_TOKEN(TKN_URL);
CHECK_TOKEN(TKN_STRING); CHECK_TOKEN(TKN_STRING);
url = g_strdup (tkn_buf->data); url = g_strdup (tkn_buf->str);
add2hotlist (label, url, HL_TYPE_ENTRY, 0); add2hotlist (label, url, HL_TYPE_ENTRY, 0);
SKIP_TO_EOL; SKIP_TO_EOL;
break; break;
case TKN_COMMENT: case TKN_COMMENT:
label = g_strdup (tkn_buf->data); label = g_strdup (tkn_buf->str);
add2hotlist (label, 0, HL_TYPE_COMMENT, 0); add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
break; break;
case TKN_EOL: case TKN_EOL:
@ -1570,7 +1574,7 @@ void done_hotlist (void)
g_free (hotlist); g_free (hotlist);
hotlist = 0; hotlist = 0;
} }
hotlist_state.loaded = 0; hotlist_state.loaded = 0;
g_free (hotlist_file_name); g_free (hotlist_file_name);
@ -1579,7 +1583,7 @@ void done_hotlist (void)
current_group = 0; current_group = 0;
if (tkn_buf){ if (tkn_buf){
str_release_buffer (tkn_buf); g_string_free (tkn_buf, TRUE);
tkn_buf = NULL; tkn_buf = NULL;
} }
} }

View File

@ -63,8 +63,7 @@ info_show_info (struct WInfo *info)
{ {
static int i18n_adjust=0; static int i18n_adjust=0;
static const char *file_label; static const char *file_label;
struct str_buffer *buff; GString *buff;
struct stat st; struct stat st;
if (!is_idle ()) if (!is_idle ())
@ -82,23 +81,23 @@ info_show_info (struct WInfo *info)
if (!info->ready) if (!info->ready)
return; return;
my_statfs (&myfs_stats, current_panel->cwd); my_statfs (&myfs_stats, current_panel->cwd);
st = current_panel->dir.list [current_panel->selected].st; st = current_panel->dir.list [current_panel->selected].st;
/* Print only lines which fit */ /* Print only lines which fit */
if(!i18n_adjust) { if(!i18n_adjust) {
/* This printf pattern string is used as a reference for size */ /* This printf pattern string is used as a reference for size */
file_label=_("File: %s"); file_label=_("File: %s");
i18n_adjust = str_term_width1(file_label) + 2; i18n_adjust = str_term_width1(file_label) + 2;
} }
buff = str_get_buffer (); buff = g_string_new ("");
switch (info->widget.lines-2){ switch (info->widget.lines-2){
/* Note: all cases are fall-throughs */ /* Note: all cases are fall-throughs */
default: default:
case 16: case 16:
@ -135,24 +134,21 @@ info_show_info (struct WInfo *info)
widget_move (&info->widget, 13, 3); widget_move (&info->widget, 13, 3);
str_printf (buff, _("Device: %s"), str_printf (buff, _("Device: %s"),
str_trunc (myfs_stats.device, info->widget.cols - i18n_adjust)); str_trunc (myfs_stats.device, info->widget.cols - i18n_adjust));
addstr (str_term_form (buff->data)); addstr (str_term_form (buff->str));
str_reset_buffer (buff); g_string_set_size(buff,0);
case 12: case 12:
widget_move (&info->widget, 12, 3); widget_move (&info->widget, 12, 3);
str_printf (buff, _("Filesystem: %s"), str_printf (buff, _("Filesystem: %s"),
str_trunc (myfs_stats.mpoint, info->widget.cols - i18n_adjust)); str_trunc (myfs_stats.mpoint, info->widget.cols - i18n_adjust));
addstr (str_term_form (buff->data)); addstr (str_term_form (buff->str));
str_reset_buffer (buff);
case 11: case 11:
widget_move (&info->widget, 11, 3); widget_move (&info->widget, 11, 3);
str_printf (buff, _("Accessed: %s"), file_date (st.st_atime)); str_printf (buff, _("Accessed: %s"), file_date (st.st_atime));
addstr (str_term_form (buff->data)); addstr (str_term_form (buff->str));
str_reset_buffer (buff);
case 10: case 10:
widget_move (&info->widget, 10, 3); widget_move (&info->widget, 10, 3);
str_printf (buff, _("Modified: %s"), file_date (st.st_mtime)); str_printf (buff, _("Modified: %s"), file_date (st.st_mtime));
addstr (str_term_form (buff->data)); addstr (str_term_form (buff->str));
str_reset_buffer (buff);
case 9: case 9:
widget_move (&info->widget, 9, 3); widget_move (&info->widget, 9, 3);
/* TRANSLATORS: "Status changed", like in the stat(2) man page */ /* TRANSLATORS: "Status changed", like in the stat(2) man page */
@ -204,8 +200,7 @@ info_show_info (struct WInfo *info)
str_printf (buff, file_label, str_printf (buff, file_label,
str_trunc (current_panel->dir.list [current_panel->selected].fname, str_trunc (current_panel->dir.list [current_panel->selected].fname,
info->widget.cols - i18n_adjust)); info->widget.cols - i18n_adjust));
addstr (str_term_form (buff->data)); addstr (str_term_form (buff->str));
str_reset_buffer (buff);
} else } else
addstr (_("File: None")); addstr (_("File: None"));
@ -214,8 +209,7 @@ info_show_info (struct WInfo *info)
case 0: case 0:
; ;
} /* switch */ } /* switch */
g_string_free (buff, TRUE);
str_release_buffer (buff);
} }
static void info_hook (void *data) static void info_hook (void *data)

View File

@ -37,331 +37,256 @@
//names, that are used for utf-8 //names, that are used for utf-8
static const char *str_utf8_encodings[] = { static const char *str_utf8_encodings[] = {
"utf-8", "utf-8",
"utf8", "utf8",
NULL}; NULL
};
// standard 8bit encodings, no wide or multibytes characters // standard 8bit encodings, no wide or multibytes characters
static const char *str_8bit_encodings[] = { static const char *str_8bit_encodings[] = {
"cp-1251", "cp-1251",
"cp1251", "cp1251",
"cp-1250", "cp-1250",
"cp1250", "cp1250",
"cp-866", "cp-866",
"cp866", "cp866",
"cp-850", "cp-850",
"cp850", "cp850",
"cp-852", "cp-852",
"cp852", "cp852",
"iso-8859", "iso-8859",
"iso8859", "iso8859",
"koi8", "koi8",
NULL NULL
}; };
// terminal encoding // terminal encoding
static char *codeset; static char *codeset;
// function for encoding specific operations // function for encoding specific operations
static struct str_class used_class; static struct str_class used_class;
// linked list of string buffers
static struct str_buffer *buffer_list = NULL;
iconv_t str_cnv_to_term; iconv_t str_cnv_to_term;
iconv_t str_cnv_from_term; iconv_t str_cnv_from_term;
iconv_t str_cnv_not_convert; iconv_t str_cnv_not_convert;
// if enc is same encoding like on terminal // if enc is same encoding like on terminal
static int static int
str_test_not_convert (const char *enc) str_test_not_convert (const char *enc)
{ {
return g_ascii_strcasecmp (enc, codeset) == 0; return g_ascii_strcasecmp (enc, codeset) == 0;
} }
str_conv_t GIConv
str_crt_conv_to (const char *to_enc) str_crt_conv_to (const char *to_enc)
{ {
return (!str_test_not_convert (to_enc)) ? iconv_open (to_enc, codeset) : return (!str_test_not_convert (to_enc))
str_cnv_not_convert; ? g_iconv_open (to_enc, codeset) : str_cnv_not_convert;
} }
str_conv_t GIConv
str_crt_conv_from (const char *from_enc) str_crt_conv_from (const char *from_enc)
{ {
return (!str_test_not_convert (from_enc)) ? iconv_open (codeset, from_enc) : return (!str_test_not_convert (from_enc))
str_cnv_not_convert; ? g_iconv_open (codeset, from_enc) : str_cnv_not_convert;
} }
void void
str_close_conv (str_conv_t conv) str_close_conv (GIConv conv)
{ {
if (conv != str_cnv_not_convert) if (conv != str_cnv_not_convert)
iconv_close (conv); g_iconv_close (conv);
}
struct str_buffer *
str_get_buffer ()
{
struct str_buffer *result;
result = buffer_list;
while (result != NULL) {
if (!result->used) {
str_reset_buffer (result);
result->used = 1;
return result;
}
result = result->next;
}
result = g_new (struct str_buffer, 1);
result->size = BUF_TINY;
result->data = g_new0 (char, result->size);
result->data[0] = '\0';
result->actual = result->data;
result->remain = result->size;
result->next = buffer_list;
buffer_list = result;
result->used = 1;
return result;
}
void
str_release_buffer (struct str_buffer *buffer)
{
buffer->used = 0;
}
void
str_incrase_buffer (struct str_buffer *buffer)
{
size_t offset;
offset = buffer->actual - buffer->data;
buffer->remain+= buffer->size;
buffer->size*= 2;
buffer->data = g_renew (char, buffer->data, buffer->size);
buffer->actual = buffer->data + offset;
}
void
str_reset_buffer (struct str_buffer *buffer)
{
buffer->data[0] = '\0';
buffer->actual = buffer->data;
buffer->remain = buffer->size;
} }
static int static int
_str_convert (str_conv_t coder, char *string, struct str_buffer *buffer) _str_convert (GIConv coder, char *string, int size, GString * buffer)
{ {
int state; int state;
gchar *tmp_buff;
size_t left; gssize left;
size_t nconv; gsize bytes_read, bytes_written;
GError *error = NULL;
errno = 0; errno = 0;
if (used_class.is_valid_string (string)) { if (used_class.is_valid_string (string))
state = 0; {
state = 0;
if (size < 0)
{
size = strlen (string);
}
else
{
left = strlen (string);
if (left < size)
size = left;
}
left = size;
left = strlen (string); if (coder == (GIConv) (-1))
return ESTR_FAILURE;
if (coder == (iconv_t) (-1)) return ESTR_FAILURE; g_iconv (coder, NULL, NULL, NULL, NULL);
iconv(coder, NULL, NULL, NULL, NULL); while (left)
{
tmp_buff = g_convert_with_iconv ((const gchar *) string,
left,
coder,
&bytes_read,
&bytes_written, &error);
while (((int)left) > 0) { if (error)
nconv = iconv(coder, &string, &left, {
&(buffer->actual), &(buffer->remain)); switch (error->code)
if (nconv == (size_t) (-1)) { {
switch (errno) { case G_CONVERT_ERROR_NO_CONVERSION:
case EINVAL: /* Conversion between the requested character sets is not supported. */
return ESTR_FAILURE; tmp_buff = g_strnfill (strlen (string), '?');
case EILSEQ: g_string_append (buffer, tmp_buff);
string++; g_free (tmp_buff);
left--; g_error_free (error);
if (buffer->remain <= 0) { return ESTR_PROBLEM;
str_incrase_buffer (buffer); break;
} case G_CONVERT_ERROR_ILLEGAL_SEQUENCE:
buffer->actual[0] = '?'; /* Invalid byte sequence in conversion input. */
buffer->actual++; g_string_append (buffer, tmp_buff);
buffer->remain--; g_string_append (buffer, "?");
state = ESTR_PROBLEM; g_free (tmp_buff);
break; if (bytes_read < left)
case E2BIG: {
str_incrase_buffer (buffer); string += bytes_read + 1;
break; size -= (bytes_read + 1);
} left -= (bytes_read + 1);
} }
}; else
{
g_error_free (error);
return ESTR_PROBLEM;
}
state = ESTR_PROBLEM;
break;
case G_CONVERT_ERROR_PARTIAL_INPUT:
/* Partial character sequence at end of input. */
g_error_free (error);
g_string_append (buffer, tmp_buff);
g_free (tmp_buff);
if (bytes_read < left)
{
left = left - bytes_read;
tmp_buff = g_strnfill (left, '?');
g_string_append (buffer, tmp_buff);
g_free (tmp_buff);
}
return ESTR_PROBLEM;
break;
case G_CONVERT_ERROR_BAD_URI: /* Don't know how handle this error :( */
case G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: /* Don't know how handle this error :( */
case G_CONVERT_ERROR_FAILED: /* Conversion failed for some reason. */
default:
g_error_free (error);
if (tmp_buff)
g_free (tmp_buff);
return state; return ESTR_FAILURE;
} else return ESTR_FAILURE; }
g_error_free (error);
}
else
{
g_string_append (buffer, tmp_buff);
g_free (tmp_buff);
string += bytes_read;
left -= bytes_read;
}
}
return state;
}
else
return ESTR_FAILURE;
} }
int int
str_convert (str_conv_t coder, char *string, struct str_buffer *buffer) str_convert (GIConv coder, char *string, GString * buffer)
{
int result;
result = _str_convert (coder, string, buffer);
buffer->actual[0] = '\0';
return result;
}
static int
_str_vfs_convert_from (str_conv_t coder, char *string,
struct str_buffer *buffer)
{
size_t left;
size_t nconv;
left = strlen (string);
if (coder == (iconv_t) (-1)) return ESTR_FAILURE;
iconv(coder, NULL, NULL, NULL, NULL);
do {
nconv = iconv(coder, &string, &left,
&(buffer->actual), &(buffer->remain));
if (nconv == (size_t) (-1)) {
switch (errno) {
case EINVAL:
return ESTR_FAILURE;
case EILSEQ:
return ESTR_FAILURE;
case E2BIG:
str_incrase_buffer (buffer);
break;
}
}
} while (left > 0);
return 0;
}
int
str_vfs_convert_from (str_conv_t coder, char *string, struct str_buffer *buffer)
{ {
int result; int result;
if (coder == str_cnv_not_convert) { result = _str_convert (coder, string, -1, buffer);
str_insert_string (string, buffer);
result = 0;
} else result = _str_vfs_convert_from (coder, string, buffer);
buffer->actual[0] = '\0';
return result; return result;
} }
int int
str_vfs_convert_to (str_conv_t coder, const char *string, str_nconvert (GIConv coder, char *string, int size, GString * buffer)
int size, struct str_buffer *buffer) {
int result;
result = _str_convert (coder, string, size, buffer);
return result;
}
int
str_vfs_convert_from (GIConv coder, char *string, GString * buffer)
{
int result;
if (coder == str_cnv_not_convert)
{
g_string_append (buffer, string);
result = 0;
}
else
result = _str_convert (coder, string, -1, buffer);
return result;
}
int
str_vfs_convert_to (GIConv coder, const char *string, int size,
GString * buffer)
{ {
return used_class.vfs_convert_to (coder, string, size, buffer); return used_class.vfs_convert_to (coder, string, size, buffer);
} }
void void
str_insert_string (const char *string, struct str_buffer *buffer) str_printf (GString * buffer, const char *format, ...)
{ {
size_t s;
s = strlen (string);
while (buffer->remain < s) str_incrase_buffer (buffer);
memcpy (buffer->actual, string, s);
buffer->actual+= s;
buffer->remain-= s;
buffer->actual[0] = '\0';
}
void
str_insert_string2 (const char *string, int size, struct str_buffer *buffer)
{
size_t s;
s = (size >= 0) ? size : strlen (string);
while (buffer->remain < s) str_incrase_buffer (buffer);
memcpy (buffer->actual, string, s);
buffer->actual+= s;
buffer->remain-= s;
buffer->actual[0] = '\0';
}
void
str_printf (struct str_buffer *buffer, const char *format, ...)
{
int size;
va_list ap; va_list ap;
va_start (ap, format); va_start (ap, format);
size = vsnprintf (buffer->actual, buffer->remain, format, ap); g_string_append_vprintf (buffer, format, ap);
while (buffer->remain <= size) {
str_incrase_buffer (buffer);
size = vsnprintf (buffer->actual, buffer->remain, format, ap);
}
buffer->actual+= size;
buffer->remain-= size;
va_end (ap); va_end (ap);
} }
void void
str_insert_char (char ch, struct str_buffer *buffer) str_insert_replace_char (GString * buffer)
{
if (buffer->remain <= 1) str_incrase_buffer (buffer);
buffer->actual[0] = ch;
buffer->actual++;
buffer->remain--;
buffer->actual[0] = '\0';
}
void
str_insert_replace_char (struct str_buffer *buffer)
{ {
used_class.insert_replace_char (buffer); used_class.insert_replace_char (buffer);
} }
void
str_backward_buffer (struct str_buffer *buffer, int count)
{
char *prev;
while ((count > 0) && (buffer->actual > buffer->data)) {
prev = str_get_prev_char (buffer->actual);
buffer->remain+= buffer->actual - prev;
buffer->actual = prev;
buffer->actual[0] = '\0';
count--;
}
}
int int
str_translate_char (str_conv_t conv, char *keys, size_t ch_size, str_translate_char (str_conv_t conv, char *keys, size_t ch_size,
char *output, size_t out_size) char *output, size_t out_size)
{ {
size_t left; size_t left;
size_t cnv; size_t cnv;
iconv (conv, NULL, NULL, NULL, NULL); iconv (conv, NULL, NULL, NULL, NULL);
left = (ch_size == (size_t)(-1)) ? strlen (keys) : ch_size; left = (ch_size == (size_t) (-1)) ? strlen (keys) : ch_size;
cnv = iconv (conv, &keys, &left, &output, &out_size); cnv = iconv (conv, &keys, &left, &output, &out_size);
if (cnv == (size_t)(-1)) { if (cnv == (size_t) (-1))
if (errno == EINVAL) return ESTR_PROBLEM; else return ESTR_FAILURE; {
} else { if (errno == EINVAL)
output[0] = '\0'; return ESTR_PROBLEM;
return 0; else
return ESTR_FAILURE;
}
else
{
output[0] = '\0';
return 0;
} }
} }
@ -369,7 +294,7 @@ str_translate_char (str_conv_t conv, char *keys, size_t ch_size,
static const char * static const char *
str_detect_termencoding () str_detect_termencoding ()
{ {
return (nl_langinfo(CODESET)); return (nl_langinfo (CODESET));
} }
static int static int
@ -378,9 +303,10 @@ str_test_encoding_class (const char *encoding, const char **table)
int t; int t;
int result = 0; int result = 0;
for (t = 0; table[t] != NULL; t++) { for (t = 0; table[t] != NULL; t++)
result+= (g_ascii_strncasecmp (encoding, table[t], {
strlen (table[t])) == 0); result += (g_ascii_strncasecmp (encoding, table[t],
strlen (table[t])) == 0);
} }
return result; return result;
@ -389,12 +315,17 @@ str_test_encoding_class (const char *encoding, const char **table)
static void static void
str_choose_str_functions () str_choose_str_functions ()
{ {
if (str_test_encoding_class (codeset, str_utf8_encodings)) { if (str_test_encoding_class (codeset, str_utf8_encodings))
used_class = str_utf8_init (); {
} else if (str_test_encoding_class (codeset, str_8bit_encodings)) { used_class = str_utf8_init ();
used_class = str_8bit_init (); }
} else { else if (str_test_encoding_class (codeset, str_8bit_encodings))
used_class = str_ascii_init (); {
used_class = str_8bit_init ();
}
else
{
used_class = str_ascii_init ();
} }
} }
@ -402,8 +333,9 @@ int
str_isutf8 (char *codeset_name) str_isutf8 (char *codeset_name)
{ {
int result = 0; int result = 0;
if (str_test_encoding_class (codeset_name, str_utf8_encodings)) { if (str_test_encoding_class (codeset_name, str_utf8_encodings))
result = 1; {
result = 1;
} }
return result; return result;
} }
@ -411,23 +343,25 @@ str_isutf8 (char *codeset_name)
void void
str_init_strings (const char *termenc) str_init_strings (const char *termenc)
{ {
codeset = g_strdup ((termenc != NULL) codeset = g_strdup ((termenc != NULL)
? termenc ? termenc : str_detect_termencoding ());
: str_detect_termencoding ());
str_cnv_not_convert = iconv_open (codeset, codeset); str_cnv_not_convert = iconv_open (codeset, codeset);
if (str_cnv_not_convert == INVALID_CONV) { if (str_cnv_not_convert == INVALID_CONV)
if (termenc != NULL) { {
g_free (codeset); if (termenc != NULL)
codeset = g_strdup (str_detect_termencoding ()); {
str_cnv_not_convert = iconv_open (codeset, codeset); g_free (codeset);
} codeset = g_strdup (str_detect_termencoding ());
str_cnv_not_convert = iconv_open (codeset, codeset);
}
if (str_cnv_not_convert == INVALID_CONV) { if (str_cnv_not_convert == INVALID_CONV)
g_free (codeset); {
codeset = g_strdup ("ascii"); g_free (codeset);
str_cnv_not_convert = iconv_open (codeset, codeset); codeset = g_strdup ("ascii");
} str_cnv_not_convert = iconv_open (codeset, codeset);
}
} }
str_cnv_to_term = str_cnv_not_convert; str_cnv_to_term = str_cnv_not_convert;
@ -436,26 +370,9 @@ str_init_strings (const char *termenc)
str_choose_str_functions (); str_choose_str_functions ();
} }
static void
str_release_buffer_list ()
{
struct str_buffer *buffer;
struct str_buffer *next;
buffer = buffer_list;
while (buffer != NULL) {
next = buffer->next;
g_free (buffer->data);
g_free (buffer);
buffer = next;
}
}
void void
str_uninit_strings () str_uninit_strings ()
{ {
str_release_buffer_list ();
iconv_close (str_cnv_not_convert); iconv_close (str_cnv_not_convert);
} }
@ -477,7 +394,7 @@ str_term_trim (const char *text, int width)
return used_class.term_trim (text, width); return used_class.term_trim (text, width);
} }
void void
str_msg_term_size (const char *text, int *lines, int *columns) str_msg_term_size (const char *text, int *lines, int *columns)
{ {
return used_class.msg_term_size (text, lines, columns); return used_class.msg_term_size (text, lines, columns);
@ -493,7 +410,7 @@ char *
str_get_next_char (char *text) str_get_next_char (char *text)
{ {
used_class.cnext_char ((const char **)&text); used_class.cnext_char ((const char **) &text);
return text; return text;
} }
@ -643,25 +560,25 @@ str_term_char_width (const char *text)
} }
int int
str_offset_to_pos (const char* text, size_t length) str_offset_to_pos (const char *text, size_t length)
{ {
return used_class.offset_to_pos (text, length); return used_class.offset_to_pos (text, length);
} }
int int
str_length (const char* text) str_length (const char *text)
{ {
return used_class.length (text); return used_class.length (text);
} }
int int
str_length2 (const char* text, int size) str_length2 (const char *text, int size)
{ {
return used_class.length2 (text, size); return used_class.length2 (text, size);
} }
int int
str_length_noncomb (const char* text) str_length_noncomb (const char *text)
{ {
return used_class.length_noncomb (text); return used_class.length_noncomb (text);
} }
@ -679,7 +596,7 @@ str_isspace (const char *ch)
} }
int int
str_ispunct (const char *ch) str_ispunct (const char *ch)
{ {
return used_class.ispunct (ch); return used_class.ispunct (ch);
} }
@ -697,13 +614,13 @@ str_isdigit (const char *ch)
} }
int int
str_toupper (const char *ch, char **out, size_t *remain) str_toupper (const char *ch, char **out, size_t * remain)
{ {
return used_class.toupper (ch, out, remain); return used_class.toupper (ch, out, remain);
} }
int int
str_tolower (const char *ch, char **out, size_t *remain) str_tolower (const char *ch, char **out, size_t * remain)
{ {
return used_class.tolower (ch, out, remain); return used_class.tolower (ch, out, remain);
} }
@ -800,13 +717,13 @@ str_fix_string (char *text)
} }
char * char *
str_create_key (const char *text, int case_sen) str_create_key (const char *text, int case_sen)
{ {
return used_class.create_key (text, case_sen); return used_class.create_key (text, case_sen);
} }
char * char *
str_create_key_for_filename (const char *text, int case_sen) str_create_key_for_filename (const char *text, int case_sen)
{ {
return used_class.create_key_for_filename (text, case_sen); return used_class.create_key_for_filename (text, case_sen);
} }
@ -822,4 +739,3 @@ str_release_key (char *key, int case_sen)
{ {
used_class.release_key (key, case_sen); used_class.release_key (key, case_sen);
} }

View File

@ -74,29 +74,11 @@ extern str_conv_t str_cnv_from_term;
// from terminal encoding to terminal encoding // from terminal encoding to terminal encoding
extern str_conv_t str_cnv_not_convert; extern str_conv_t str_cnv_not_convert;
/* structure for growing strings
* try to avoid set any members manually
*/
struct str_buffer {
// all buffers are stored in linked list
struct str_buffer *next;
// if is buffer in use or not
int used;
// whole string
char *data;
// size of string
size_t size;
// end of string, actual[0] is always '\0'
char *actual;
// how many (chars)bytes remain after actual
size_t remain;
};
// all functions in str_class must be defined for every encoding // all functions in str_class must be defined for every encoding
struct str_class { struct str_class {
int (*vfs_convert_to) (str_conv_t coder, const char *string, int (*vfs_convert_to) (str_conv_t coder, const char *string,
int size, struct str_buffer *buffer); //I int size, GString *buffer); //I
void (*insert_replace_char) (struct str_buffer *buffer); void (*insert_replace_char) (GString *buffer);
int (*is_valid_string) (const char *); //I int (*is_valid_string) (const char *); //I
int (*is_valid_char) (const char *, size_t); //I int (*is_valid_char) (const char *, size_t); //I
void (*cnext_char) (const char **); void (*cnext_char) (const char **);
@ -151,85 +133,52 @@ struct str_class str_ascii_init ();
/* create convertor from "from_enc" to terminal encoding /* create convertor from "from_enc" to terminal encoding
* if "from_enc" is not supported return INVALID_CONV * if "from_enc" is not supported return INVALID_CONV
*/ */
str_conv_t str_crt_conv_from (const char *from_enc); GIConv str_crt_conv_from (const char *);
/* create convertor from terminal encoding to "to_enc" /* create convertor from terminal encoding to "to_enc"
* if "to_enc" is not supported return INVALID_CONV * if "to_enc" is not supported return INVALID_CONV
*/ */
str_conv_t str_crt_conv_to (const char *to_enc); GIConv str_crt_conv_to (const char *);
/* close convertor, do not close str_cnv_to_term, str_cnv_from_term, /* close convertor, do not close str_cnv_to_term, str_cnv_from_term,
* str_cnv_not_convert * str_cnv_not_convert
*/ */
void str_close_conv (str_conv_t conv); void str_close_conv (GIConv);
/* return on of not used buffers (.used == 0) or create new /* return on of not used buffers (.used == 0) or create new
* returned buffer has set .used to 1 * returned buffer has set .used to 1
*/ */
struct str_buffer *str_get_buffer ();
/* clear buffer, in .data is empty string, .actual = .data, .remain = .size
* do not set .used
*/
void str_reset_buffer (struct str_buffer *buffer);
/* set .used of buffer to 0, so can be returned by str_get_buffer again
* data in buffer may stay valid after function return
*/
void str_release_buffer (struct str_buffer *buffer);
/* incrase capacity of buffer
*/
void str_incrase_buffer (struct str_buffer *buffer);
/* convert string using coder, result of conversion is appended at end of buffer /* convert string using coder, result of conversion is appended at end of buffer
* return 0 if there was no problem. * return 0 if there was no problem.
* otherwise return ESTR_PROBLEM or ESTR_FAILURE * otherwise return ESTR_PROBLEM or ESTR_FAILURE
*/ */
int str_convert (str_conv_t coder, char *string, int str_convert (GIConv, char *, GString *);
struct str_buffer *buffer);
int str_nconvert (GIConv, char *, int, GString *);
/* return only 0 or ESTR_FAILURE, because vfs must be able to convert result to /* return only 0 or ESTR_FAILURE, because vfs must be able to convert result to
* original string. (so no replace with questionmark) * original string. (so no replace with questionmark)
* if coder is str_cnv_from_term or str_cnv_not_convert, string is only copied, * if coder is str_cnv_from_term or str_cnv_not_convert, string is only copied,
* so is possible to show file, that is not valid in terminal encoding * so is possible to show file, that is not valid in terminal encoding
*/ */
int str_vfs_convert_from (str_conv_t coder, char *string, int str_vfs_convert_from (GIConv, char *, GString *);
struct str_buffer *buffer);
/* if coder is str_cnv_to_term or str_cnv_not_convert, string is only copied, /* if coder is str_cnv_to_term or str_cnv_not_convert, string is only copied,
* does replace with questionmark * does replace with questionmark
* I * I
*/ */
int str_vfs_convert_to (str_conv_t coder, const char *string, int str_vfs_convert_to (GIConv, const char *, int, GString *);
int size, struct str_buffer *buffer);
/* append string at the end of buffer
*/
void str_insert_string (const char *string, struct str_buffer *buffer);
/* append string at the end of buffer, limit to size
*/
void
str_insert_string2 (const char *string, int size, struct str_buffer *buffer);
/* printf functin for str_buffer, append result of printf at the end of buffer /* printf functin for str_buffer, append result of printf at the end of buffer
*/ */
void void
str_printf (struct str_buffer *buffer, const char *format, ...); str_printf (GString *, const char *, ...);
/* append char at the end of buffer
*/
void str_insert_char (char ch, struct str_buffer *buffer);
/* add standard replacement character in terminal encoding /* add standard replacement character in terminal encoding
*/ */
void str_insert_replace_char (struct str_buffer *buffer); void str_insert_replace_char (GString *);
/* rewind "count" characters buffer back
*/
void str_backward_buffer (struct str_buffer *buffer, int count);
/* init strings and set terminal encoding, /* init strings and set terminal encoding,
* if is termenc NULL, detect terminal encoding * if is termenc NULL, detect terminal encoding
* create all str_cnv_* and set functions for terminal encoding * create all str_cnv_* and set functions for terminal encoding

View File

@ -1,6 +1,6 @@
/* 8bit strings utilities /* 8bit strings utilities
Copyright (C) 2007 Free Software Foundation, Inc. Copyright (C) 2007 Free Software Foundation, Inc.
Written 2007 by: Written 2007 by:
Rostislav Benes Rostislav Benes
@ -11,7 +11,7 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -40,18 +40,18 @@
static const char replch = '?'; static const char replch = '?';
static void static void
str_8bit_insert_replace_char (struct str_buffer *buffer) str_8bit_insert_replace_char (GString * buffer)
{ {
str_insert_char (replch, buffer); g_string_append_c (buffer, replch);
} }
static int static int
str_8bit_is_valid_string (const char *text) str_8bit_is_valid_string (const char *text)
{ {
return 1; return 1;
} }
static int static int
str_8bit_is_valid_char (const char *ch, size_t size) str_8bit_is_valid_char (const char *ch, size_t size)
{ {
return 1; return 1;
@ -69,64 +69,71 @@ str_8bit_cprev_char (const char **text)
(*text)--; (*text)--;
} }
static int static int
str_8bit_cnext_noncomb_char (const char **text) str_8bit_cnext_noncomb_char (const char **text)
{ {
if (*text[0] != '\0') { if (*text[0] != '\0')
(*text)++; {
return 1; (*text)++;
} else return 0; return 1;
}
else
return 0;
} }
static int static int
str_8bit_cprev_noncomb_char (const char **text, const char *begin) str_8bit_cprev_noncomb_char (const char **text, const char *begin)
{ {
if ((*text) != begin) { if ((*text) != begin)
(*text)--; {
return 1; (*text)--;
} else return 0; return 1;
}
else
return 0;
} }
static int static int
str_8bit_isspace (const char *text) str_8bit_isspace (const char *text)
{ {
return isspace (text[0]); return isspace (text[0]);
} }
static int static int
str_8bit_ispunct (const char *text) str_8bit_ispunct (const char *text)
{ {
return ispunct (text[0]); return ispunct (text[0]);
} }
static int static int
str_8bit_isalnum (const char *text) str_8bit_isalnum (const char *text)
{ {
return isalnum (text[0]); return isalnum (text[0]);
} }
static int static int
str_8bit_isdigit (const char *text) str_8bit_isdigit (const char *text)
{ {
return isdigit (text[0]); return isdigit (text[0]);
} }
static int static int
str_8bit_isprint (const char *text) str_8bit_isprint (const char *text)
{ {
return isprint (text[0]); return isprint (text[0]);
} }
static int static int
str_8bit_iscombiningmark (const char *text) str_8bit_iscombiningmark (const char *text)
{ {
return 0; return 0;
} }
static int static int
str_8bit_toupper (const char *text, char **out, size_t *remain) str_8bit_toupper (const char *text, char **out, size_t * remain)
{ {
if (*remain <= 1) return 0; if (*remain <= 1)
return 0;
(*out)[0] = toupper ((unsigned char) text[0]); (*out)[0] = toupper ((unsigned char) text[0]);
(*out)++; (*out)++;
(*remain)--; (*remain)--;
@ -134,9 +141,10 @@ str_8bit_toupper (const char *text, char **out, size_t *remain)
} }
static int static int
str_8bit_tolower (const char *text, char **out, size_t *remain) str_8bit_tolower (const char *text, char **out, size_t * remain)
{ {
if (*remain <= 1) return 0; if (*remain <= 1)
return 0;
(*out)[0] = tolower ((unsigned char) text[0]); (*out)[0] = tolower ((unsigned char) text[0]);
(*out)++; (*out)++;
(*remain)--; (*remain)--;
@ -155,58 +163,20 @@ str_8bit_length2 (const char *text, int size)
return (size >= 0) ? min (strlen (text), size) : strlen (text); return (size >= 0) ? min (strlen (text), size) : strlen (text);
} }
static int
_str_8bit_vfs_convert_to (str_conv_t coder, char *string,
int size, struct str_buffer *buffer)
{
int state;
size_t left;
size_t nconv;
errno = 0;
state = 0;
left = (size >= 0) ? size : strlen (string);
if (coder == (iconv_t) (-1)) return ESTR_FAILURE;
iconv(coder, NULL, NULL, NULL, NULL);
while (((int)left) > 0) {
nconv = iconv(coder, &string, &left,
&(buffer->actual), &(buffer->remain));
if (nconv == (size_t) (-1)) {
switch (errno) {
case EINVAL:
return ESTR_FAILURE;
case EILSEQ:
string++;
left--;
str_insert_char ('?', buffer);
state = ESTR_PROBLEM;
break;
case E2BIG:
str_incrase_buffer (buffer);
break;
}
}
}
return state;
}
int int
str_8bit_vfs_convert_to (str_conv_t coder, const char *string, str_8bit_vfs_convert_to (str_conv_t coder, const char *string,
int size, struct str_buffer *buffer) int size, GString * buffer)
{ {
int result; int result;
if (coder == str_cnv_not_convert) { if (coder == str_cnv_not_convert)
str_insert_string2 (string, size, buffer); {
result = 0; g_string_append_len (buffer, string, size);
} else result = _str_8bit_vfs_convert_to (coder, (char*)string, size, buffer); result = 0;
buffer->actual[0] = '\0'; }
else
result = str_nconvert (coder, (char *) string, size, buffer);
return result; return result;
} }
@ -219,21 +189,22 @@ str_8bit_term_form (const char *text)
size_t remain; size_t remain;
size_t length; size_t length;
size_t pos = 0; size_t pos = 0;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
for (; pos < length && remain > 1; pos++, actual++, remain--) { for (; pos < length && remain > 1; pos++, actual++, remain--)
actual[0] = isprint (text[pos]) ? text[pos] : '.'; {
actual[0] = isprint (text[pos]) ? text[pos] : '.';
} }
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
static const char * static const char *
str_8bit_fit_to_term (const char *text, int width, int just_mode) str_8bit_fit_to_term (const char *text, int width, int just_mode)
{ {
static char result[BUF_MEDIUM]; static char result[BUF_MEDIUM];
char *actual; char *actual;
@ -241,74 +212,90 @@ str_8bit_fit_to_term (const char *text, int width, int just_mode)
int ident; int ident;
size_t length; size_t length;
size_t pos = 0; size_t pos = 0;
length = strlen (text); length = strlen (text);
actual = result; actual = result;
remain = sizeof(result); remain = sizeof (result);
if (length <= width) { if (length <= width)
ident = 0; {
switch (HIDE_FIT (just_mode)) { ident = 0;
case J_CENTER_LEFT: switch (HIDE_FIT (just_mode))
case J_CENTER: {
ident = (width - length) / 2; case J_CENTER_LEFT:
break; case J_CENTER:
case J_RIGHT: ident = (width - length) / 2;
ident = width - length; break;
break; case J_RIGHT:
} ident = width - length;
break;
if (remain <= ident) goto finally; }
memset (actual, ' ', ident);
actual+= ident; if (remain <= ident)
remain-= ident; goto finally;
memset (actual, ' ', ident);
for (; pos < length && remain > 1; pos++, actual++, remain--) { actual += ident;
actual[0] = isprint (text[pos]) ? text[pos] : '.'; remain -= ident;
}
if (width - length - ident > 0) { for (; pos < length && remain > 1; pos++, actual++, remain--)
if (remain <= width - length - ident) goto finally; {
memset (actual, ' ', width - length - ident); actual[0] = isprint (text[pos]) ? text[pos] : '.';
actual+= width - length - ident; }
remain-= width - length - ident; if (width - length - ident > 0)
} {
} else { if (remain <= width - length - ident)
if (IS_FIT (just_mode)) { goto finally;
for (; pos + 1 <= width / 2 && remain > 1; memset (actual, ' ', width - length - ident);
actual++, pos++, remain--) { actual += width - length - ident;
remain -= width - length - ident;
actual[0] = isprint (text[pos]) ? text[pos] : '.'; }
} }
else
if (remain <= 1) goto finally; {
actual[0] = '~'; if (IS_FIT (just_mode))
actual++; {
remain--; for (; pos + 1 <= width / 2 && remain > 1;
actual++, pos++, remain--)
pos+= length - width + 1; {
for (; pos < length && remain > 1; pos++, actual++, remain--) { actual[0] = isprint (text[pos]) ? text[pos] : '.';
actual[0] = isprint (text[pos]) ? text[pos] : '.'; }
}
} else { if (remain <= 1)
ident = 0; goto finally;
switch (HIDE_FIT (just_mode)) { actual[0] = '~';
case J_CENTER: actual++;
ident = (length - width) / 2; remain--;
break;
case J_RIGHT: pos += length - width + 1;
ident = length - width;
break; for (; pos < length && remain > 1; pos++, actual++, remain--)
} {
actual[0] = isprint (text[pos]) ? text[pos] : '.';
pos+= ident; }
for (; pos < ident + width && remain > 1; }
pos++, actual++, remain--) { else
{
actual[0] = isprint (text[pos]) ? text[pos] : '.'; ident = 0;
} switch (HIDE_FIT (just_mode))
{
} case J_CENTER:
ident = (length - width) / 2;
break;
case J_RIGHT:
ident = length - width;
break;
}
pos += ident;
for (; pos < ident + width && remain > 1;
pos++, actual++, remain--)
{
actual[0] = isprint (text[pos]) ? text[pos] : '.';
}
}
} }
finally: finally:
actual[0] = '\0'; actual[0] = '\0';
@ -316,40 +303,48 @@ str_8bit_fit_to_term (const char *text, int width, int just_mode)
} }
static const char * static const char *
str_8bit_term_trim (const char *text, int width) str_8bit_term_trim (const char *text, int width)
{ {
static char result[BUF_MEDIUM]; static char result[BUF_MEDIUM];
size_t remain; size_t remain;
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
length = strlen (text); length = strlen (text);
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
if (width < length) { if (width < length)
if (width <= 3) { {
memset (actual, '.', width); if (width <= 3)
actual+= width; {
remain-= width; memset (actual, '.', width);
} else { actual += width;
memset (actual, '.', 3); remain -= width;
actual+= 3; }
remain-= 3; else
{
pos+= length - width + 3; memset (actual, '.', 3);
actual += 3;
for (; pos < length && remain > 1; pos++, actual++, remain--) { remain -= 3;
actual[0] = isprint (text[pos]) ? text[pos] : '.';
} pos += length - width + 3;
}
} else { for (; pos < length && remain > 1; pos++, actual++, remain--)
for (; pos < length && remain > 1; pos++, actual++, remain--) { {
actual[0] = isprint (text[pos]) ? text[pos] : '.'; actual[0] = isprint (text[pos]) ? text[pos] : '.';
} }
} }
}
else
{
for (; pos < length && remain > 1; pos++, actual++, remain--)
{
actual[0] = isprint (text[pos]) ? text[pos] : '.';
}
}
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
@ -357,50 +352,52 @@ str_8bit_term_trim (const char *text, int width)
static int static int
str_8bit_term_width2 (const char *text, size_t length) str_8bit_term_width2 (const char *text, size_t length)
{ {
return (length != (size_t)(-1)) return (length != (size_t) (-1))
? min (strlen (text), length) ? min (strlen (text), length) : strlen (text);
: strlen (text); }
}
static int static int
str_8bit_term_width1 (const char *text) str_8bit_term_width1 (const char *text)
{ {
return str_8bit_term_width2 (text, (size_t)(-1)); return str_8bit_term_width2 (text, (size_t) (-1));
} }
static int static int
str_8bit_term_char_width (const char *text) str_8bit_term_char_width (const char *text)
{ {
return 1; return 1;
} }
static void static void
str_8bit_msg_term_size (const char *text, int *lines, int *columns) str_8bit_msg_term_size (const char *text, int *lines, int *columns)
{ {
(*lines) = 1; (*lines) = 1;
(*columns) = 0; (*columns) = 0;
char *p, *tmp = g_strdup (text); char *p, *tmp = g_strdup (text);
char *q; char *q;
char c = '\0'; char c = '\0';
int width; int width;
p = tmp; p = tmp;
for (;;) { for (;;)
q = strchr (p, '\n'); {
if (q != NULL) { q = strchr (p, '\n');
c = q[0]; if (q != NULL)
q[0] = '\0'; {
} c = q[0];
q[0] = '\0';
width = str_8bit_term_width1 (p); }
if (width > (*columns)) (*columns) = width;
width = str_8bit_term_width1 (p);
if (q == NULL) if (width > (*columns))
break; (*columns) = width;
q[0] = c;
p = q + 1; if (q == NULL)
(*lines)++; break;
q[0] = c;
p = q + 1;
(*lines)++;
} }
g_free (tmp); g_free (tmp);
} }
@ -413,27 +410,30 @@ str_8bit_term_substring (const char *text, int start, int width)
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
if (start < length) { if (start < length)
pos+= start; {
for (; pos < length && width > 0 && remain > 1; pos += start;
pos++, width--, actual++, remain--) { for (; pos < length && width > 0 && remain > 1;
pos++, width--, actual++, remain--)
actual[0] = isprint (text[pos]) ? text[pos] : '.'; {
}
actual[0] = isprint (text[pos]) ? text[pos] : '.';
}
} }
for (; width > 0 && remain > 1; actual++, remain--, width--) { for (; width > 0 && remain > 1; actual++, remain--, width--)
actual[0] = ' '; {
actual[0] = ' ';
} }
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
static const char * static const char *
str_8bit_trunc (const char *text, int width) str_8bit_trunc (const char *text, int width)
@ -443,30 +443,37 @@ str_8bit_trunc (const char *text, int width)
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
if (length > width) { if (length > width)
for (; pos + 1 <= width / 2 && remain > 1; actual++, pos++, remain--) { {
actual[0] = isprint (text[pos]) ? text[pos] : '.'; for (; pos + 1 <= width / 2 && remain > 1; actual++, pos++, remain--)
} {
actual[0] = isprint (text[pos]) ? text[pos] : '.';
if (remain <= 1) goto finally; }
actual[0] = '~';
actual++; if (remain <= 1)
remain--; goto finally;
actual[0] = '~';
pos+= length - width + 1; actual++;
remain--;
for (; pos < length && remain > 1; pos++, actual++, remain--) {
actual[0] = isprint (text[pos]) ? text[pos] : '.'; pos += length - width + 1;
}
} else { for (; pos < length && remain > 1; pos++, actual++, remain--)
for (; pos < length && remain > 1; pos++, actual++, remain--) { {
actual[0] = isprint (text[pos]) ? text[pos] : '.'; actual[0] = isprint (text[pos]) ? text[pos] : '.';
} }
}
else
{
for (; pos < length && remain > 1; pos++, actual++, remain--)
{
actual[0] = isprint (text[pos]) ? text[pos] : '.';
}
} }
finally: finally:
@ -477,22 +484,22 @@ str_8bit_trunc (const char *text, int width)
static int static int
str_8bit_offset_to_pos (const char *text, size_t length) str_8bit_offset_to_pos (const char *text, size_t length)
{ {
return (int)length; return (int) length;
} }
static int static int
str_8bit_column_to_pos (const char *text, size_t pos) str_8bit_column_to_pos (const char *text, size_t pos)
{ {
return (int)pos; return (int) pos;
} }
static char * static char *
str_8bit_create_search_needle (const char *needle, int case_sen) str_8bit_create_search_needle (const char *needle, int case_sen)
{ {
return (char*) needle; return (char *) needle;
} }
static void static void
str_8bit_release_search_needle (char *needle, int case_sen) str_8bit_release_search_needle (char *needle, int case_sen)
{ {
} }
@ -504,21 +511,23 @@ str_8bit_search_first (const char *text, const char *search, int case_sen)
char *fold_search; char *fold_search;
const char *match; const char *match;
size_t offsset; size_t offsset;
fold_text = (case_sen) ? (char*) text : g_strdown (g_strdup (text)); fold_text = (case_sen) ? (char *) text : g_strdown (g_strdup (text));
fold_search = (case_sen) ? (char*) text : g_strdown (g_strdup (search)); fold_search = (case_sen) ? (char *) text : g_strdown (g_strdup (search));
match = g_strstr_len (fold_text, -1, fold_search); match = g_strstr_len (fold_text, -1, fold_search);
if (match != NULL) { if (match != NULL)
offsset = match - fold_text; {
match = text + offsset; offsset = match - fold_text;
match = text + offsset;
} }
if (!case_sen) { if (!case_sen)
g_free (fold_text); {
g_free (fold_search); g_free (fold_text);
g_free (fold_search);
} }
return match; return match;
} }
@ -529,21 +538,23 @@ str_8bit_search_last (const char *text, const char *search, int case_sen)
char *fold_search; char *fold_search;
const char *match; const char *match;
size_t offsset; size_t offsset;
fold_text = (case_sen) ? (char*) text : g_strdown (g_strdup (text)); fold_text = (case_sen) ? (char *) text : g_strdown (g_strdup (text));
fold_search = (case_sen) ? (char*) text : g_strdown (g_strdup (search)); fold_search = (case_sen) ? (char *) text : g_strdown (g_strdup (search));
match = g_strrstr_len (fold_text, -1, fold_search); match = g_strrstr_len (fold_text, -1, fold_search);
if (match != NULL) { if (match != NULL)
offsset = match - fold_text; {
match = text + offsset; offsset = match - fold_text;
match = text + offsset;
} }
if (!case_sen) { if (!case_sen)
g_free (fold_text); {
g_free (fold_search); g_free (fold_text);
g_free (fold_search);
} }
return match; return match;
} }
@ -551,42 +562,41 @@ static int
str_8bit_compare (const char *t1, const char *t2) str_8bit_compare (const char *t1, const char *t2)
{ {
return strcmp (t1, t2); return strcmp (t1, t2);
} }
static int static int
str_8bit_ncompare (const char *t1, const char *t2) str_8bit_ncompare (const char *t1, const char *t2)
{ {
return strncmp (t1, t2, min (strlen (t1), strlen (t2))); return strncmp (t1, t2, min (strlen (t1), strlen (t2)));
} }
static int static int
str_8bit_casecmp (const char *t1, const char *t2) str_8bit_casecmp (const char *t1, const char *t2)
{ {
return g_strcasecmp (t1, t2); return g_strcasecmp (t1, t2);
} }
static int static int
str_8bit_ncasecmp (const char *t1, const char *t2) str_8bit_ncasecmp (const char *t1, const char *t2)
{ {
return g_strncasecmp (t1, t2, min (strlen (t1), strlen (t2))); return g_strncasecmp (t1, t2, min (strlen (t1), strlen (t2)));
} }
static int static int
str_8bit_prefix (const char *text, const char *prefix) str_8bit_prefix (const char *text, const char *prefix)
{ {
int result; int result;
for (result = 0; text[result] != '\0' && prefix[result] != '\0' for (result = 0; text[result] != '\0' && prefix[result] != '\0'
&& text[result] == prefix[result]; result++); && text[result] == prefix[result]; result++);
return result; return result;
} }
static int static int
str_8bit_caseprefix (const char *text, const char *prefix) str_8bit_caseprefix (const char *text, const char *prefix)
{ {
int result; int result;
for (result = 0; text[result] != '\0' && prefix[result] != '\0' for (result = 0; text[result] != '\0' && prefix[result] != '\0'
&& toupper (text[result]) == toupper (prefix[result]); && toupper (text[result]) == toupper (prefix[result]); result++);
result++);
return result; return result;
} }
@ -595,36 +605,39 @@ str_8bit_caseprefix (const char *text, const char *prefix)
static void static void
str_8bit_fix_string (char *text) str_8bit_fix_string (char *text)
{ {
} }
static char * static char *
str_8bit_create_key (const char *text, int case_sen) str_8bit_create_key (const char *text, int case_sen)
{ {
return (case_sen) ? (char*)text : g_strdown (g_strdup (text)); return (case_sen) ? (char *) text : g_strdown (g_strdup (text));
} }
static int static int
str_8bit_key_collate (const char *t1, const char *t2, int case_sen) str_8bit_key_collate (const char *t1, const char *t2, int case_sen)
{ {
if (case_sen) return strcmp (t1, t2); if (case_sen)
else return strcoll (t1, t2); return strcmp (t1, t2);
} else
return strcoll (t1, t2);
}
static void static void
str_8bit_release_key (char *key, int case_sen) str_8bit_release_key (char *key, int case_sen)
{ {
if (!case_sen) g_free (key); if (!case_sen)
} g_free (key);
}
struct str_class struct str_class
str_8bit_init () str_8bit_init ()
{ {
struct str_class result; struct str_class result;
result.vfs_convert_to = str_8bit_vfs_convert_to; result.vfs_convert_to = str_8bit_vfs_convert_to;
result.insert_replace_char = str_8bit_insert_replace_char; result.insert_replace_char = str_8bit_insert_replace_char;
result.is_valid_string = str_8bit_is_valid_string; result.is_valid_string = str_8bit_is_valid_string;
result.is_valid_char = str_8bit_is_valid_char; result.is_valid_char = str_8bit_is_valid_char;
result.cnext_char = str_8bit_cnext_char; result.cnext_char = str_8bit_cnext_char;
result.cprev_char = str_8bit_cprev_char; result.cprev_char = str_8bit_cprev_char;
result.cnext_char_safe = str_8bit_cnext_char; result.cnext_char_safe = str_8bit_cnext_char;
@ -668,6 +681,6 @@ str_8bit_init ()
result.create_key_for_filename = str_8bit_create_key; result.create_key_for_filename = str_8bit_create_key;
result.key_collate = str_8bit_key_collate; result.key_collate = str_8bit_key_collate;
result.release_key = str_8bit_release_key; result.release_key = str_8bit_release_key;
return result; return result;
} }

View File

@ -1,6 +1,6 @@
/* ASCII strings utilities /* ASCII strings utilities
Copyright (C) 2007 Free Software Foundation, Inc. Copyright (C) 2007 Free Software Foundation, Inc.
Written 2007 by: Written 2007 by:
Rostislav Benes Rostislav Benes
@ -11,7 +11,7 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -30,26 +30,26 @@
#include "global.h" #include "global.h"
#include "strutil.h" #include "strutil.h"
/* using g_ascii function from glib /* using g_ascii function from glib
* on terminal are showed only ascii characters (lower then 0x80) * on terminal are showed only ascii characters (lower then 0x80)
*/ */
static const char replch = '?'; static const char replch = '?';
static void static void
str_ascii_insert_replace_char (struct str_buffer *buffer) str_ascii_insert_replace_char (GString * buffer)
{ {
str_insert_char (replch, buffer); g_string_append_c (buffer, replch);
} }
static int static int
str_ascii_is_valid_string (const char *text) str_ascii_is_valid_string (const char *text)
{ {
return 1; return 1;
} }
static int static int
str_ascii_is_valid_char (const char *ch, size_t size) str_ascii_is_valid_char (const char *ch, size_t size)
{ {
return 1; return 1;
@ -67,64 +67,71 @@ str_ascii_cprev_char (const char **text)
(*text)--; (*text)--;
} }
static int static int
str_ascii_cnext_noncomb_char (const char **text) str_ascii_cnext_noncomb_char (const char **text)
{ {
if (*text[0] != '\0') { if (*text[0] != '\0')
(*text)++; {
return 1; (*text)++;
} else return 0; return 1;
}
else
return 0;
} }
static int static int
str_ascii_cprev_noncomb_char (const char **text, const char *begin) str_ascii_cprev_noncomb_char (const char **text, const char *begin)
{ {
if ((*text) != begin) { if ((*text) != begin)
(*text)--; {
return 1; (*text)--;
} else return 0; return 1;
}
else
return 0;
} }
static int static int
str_ascii_isspace (const char *text) str_ascii_isspace (const char *text)
{ {
return g_ascii_isspace ((gchar) text[0]); return g_ascii_isspace ((gchar) text[0]);
} }
static int static int
str_ascii_ispunct (const char *text) str_ascii_ispunct (const char *text)
{ {
return g_ascii_ispunct ((gchar) text[0]); return g_ascii_ispunct ((gchar) text[0]);
} }
static int static int
str_ascii_isalnum (const char *text) str_ascii_isalnum (const char *text)
{ {
return g_ascii_isalnum ((gchar) text[0]); return g_ascii_isalnum ((gchar) text[0]);
} }
static int static int
str_ascii_isdigit (const char *text) str_ascii_isdigit (const char *text)
{ {
return g_ascii_isdigit ((gchar) text[0]); return g_ascii_isdigit ((gchar) text[0]);
} }
static int static int
str_ascii_isprint (const char *text) str_ascii_isprint (const char *text)
{ {
return g_ascii_isprint ((gchar) text[0]); return g_ascii_isprint ((gchar) text[0]);
} }
static int static int
str_ascii_iscombiningmark (const char *text) str_ascii_iscombiningmark (const char *text)
{ {
return 0; return 0;
} }
static int static int
str_ascii_toupper (const char *text, char **out, size_t *remain) str_ascii_toupper (const char *text, char **out, size_t * remain)
{ {
if (*remain <= 1) return 0; if (*remain <= 1)
return 0;
(*out)[0] = (char) g_ascii_toupper ((gchar) text[0]); (*out)[0] = (char) g_ascii_toupper ((gchar) text[0]);
(*out)++; (*out)++;
(*remain)--; (*remain)--;
@ -132,9 +139,10 @@ str_ascii_toupper (const char *text, char **out, size_t *remain)
} }
static int static int
str_ascii_tolower (const char *text, char **out, size_t *remain) str_ascii_tolower (const char *text, char **out, size_t * remain)
{ {
if (*remain <= 1) return 0; if (*remain <= 1)
return 0;
(*out)[0] = (char) g_ascii_tolower ((gchar) text[0]); (*out)[0] = (char) g_ascii_tolower ((gchar) text[0]);
(*out)++; (*out)++;
(*remain)--; (*remain)--;
@ -154,10 +162,10 @@ str_ascii_length2 (const char *text, int size)
} }
int int
str_ascii_vfs_convert_to (str_conv_t coder, const char *string, str_ascii_vfs_convert_to (GIConv coder, const char *string,
int size, struct str_buffer *buffer) int size, GString * buffer)
{ {
str_insert_string2 (string, size, buffer); g_string_append_len (buffer, string, size);
return 0; return 0;
} }
@ -170,23 +178,24 @@ str_ascii_term_form (const char *text)
size_t remain; size_t remain;
size_t length; size_t length;
size_t pos = 0; size_t pos = 0;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
/* go throw all characters and check, if they are ascii and printable */ /* go throw all characters and check, if they are ascii and printable */
for (; pos < length && remain > 1; pos++, actual++, remain--) { for (; pos < length && remain > 1; pos++, actual++, remain--)
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?'; {
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
} }
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
static const char * static const char *
str_ascii_fit_to_term (const char *text, int width, int just_mode) str_ascii_fit_to_term (const char *text, int width, int just_mode)
{ {
static char result[BUF_MEDIUM]; static char result[BUF_MEDIUM];
char *actual; char *actual;
@ -194,90 +203,106 @@ str_ascii_fit_to_term (const char *text, int width, int just_mode)
int ident; int ident;
size_t length; size_t length;
size_t pos = 0; size_t pos = 0;
length = strlen (text); length = strlen (text);
actual = result; actual = result;
remain = sizeof(result); remain = sizeof (result);
if (length <= width) { if (length <= width)
ident = 0; {
switch (HIDE_FIT (just_mode)) { ident = 0;
case J_CENTER_LEFT: switch (HIDE_FIT (just_mode))
case J_CENTER: {
ident = (width - length) / 2; case J_CENTER_LEFT:
break; case J_CENTER:
case J_RIGHT: ident = (width - length) / 2;
ident = width - length; break;
break; case J_RIGHT:
} ident = width - length;
break;
/* add space before text */ }
if (remain <= ident) goto finally;
memset (actual, ' ', ident); /* add space before text */
actual+= ident; if (remain <= ident)
remain-= ident; goto finally;
memset (actual, ' ', ident);
/* copy all characters */ actual += ident;
for (; pos < length && remain > 1; pos++, actual++, remain--) { remain -= ident;
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; /* copy all characters */
} for (; pos < length && remain > 1; pos++, actual++, remain--)
{
/* add space after text */ actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
if (width - length - ident > 0) { actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
if (remain <= width - length - ident) goto finally; }
memset (actual, ' ', width - length - ident);
actual+= width - length - ident; /* add space after text */
remain-= width - length - ident; if (width - length - ident > 0)
} {
} else { if (remain <= width - length - ident)
if (IS_FIT (just_mode)) { goto finally;
/* copy prefix of text, that is not wider than width / 2 */ memset (actual, ' ', width - length - ident);
for (; pos + 1 <= width / 2 && remain > 1; actual += width - length - ident;
actual++, pos++, remain--) { remain -= width - length - ident;
actual[0] = isascii((unsigned char)text[pos]) }
? text[pos] : '?'; }
actual[0] = g_ascii_isprint ((gchar) actual[0]) else
? actual[0] : '.'; {
} if (IS_FIT (just_mode))
{
if (remain <= 1) goto finally; /* copy prefix of text, that is not wider than width / 2 */
actual[0] = '~'; for (; pos + 1 <= width / 2 && remain > 1;
actual++; actual++, pos++, remain--)
remain--; {
actual[0] = isascii ((unsigned char) text[pos])
pos+= length - width + 1; ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0])
/* copy suffix of text */ ? actual[0] : '.';
for (; pos < length && remain > 1; pos++, actual++, remain--) { }
actual[0] = isascii((unsigned char)text[pos])
? text[pos] : '?'; if (remain <= 1)
actual[0] = g_ascii_isprint ((gchar) actual[0]) goto finally;
? actual[0] : '.'; actual[0] = '~';
} actual++;
} else { remain--;
ident = 0;
switch (HIDE_FIT (just_mode)) { pos += length - width + 1;
case J_CENTER:
ident = (length - width) / 2; /* copy suffix of text */
break; for (; pos < length && remain > 1; pos++, actual++, remain--)
case J_RIGHT: {
ident = length - width; actual[0] = isascii ((unsigned char) text[pos])
break; ? text[pos] : '?';
} actual[0] = g_ascii_isprint ((gchar) actual[0])
? actual[0] : '.';
/* copy substring text, substring start from ident and take width }
* characters from text */ }
pos+= ident; else
for (; pos < ident + width && remain > 1; {
pos++, actual++, remain--) { ident = 0;
actual[0] = isascii((unsigned char)text[pos]) switch (HIDE_FIT (just_mode))
? text[pos] : '?'; {
actual[0] = g_ascii_isprint ((gchar) actual[0]) case J_CENTER:
? actual[0] : '.'; ident = (length - width) / 2;
} break;
case J_RIGHT:
} ident = length - width;
break;
}
/* copy substring text, substring start from ident and take width
* characters from text */
pos += ident;
for (; pos < ident + width && remain > 1;
pos++, actual++, remain--)
{
actual[0] = isascii ((unsigned char) text[pos])
? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0])
? actual[0] : '.';
}
}
} }
finally: finally:
actual[0] = '\0'; actual[0] = '\0';
@ -285,46 +310,54 @@ str_ascii_fit_to_term (const char *text, int width, int just_mode)
} }
static const char * static const char *
str_ascii_term_trim (const char *text, int width) str_ascii_term_trim (const char *text, int width)
{ {
static char result[BUF_MEDIUM]; static char result[BUF_MEDIUM];
size_t remain; size_t remain;
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
length = strlen (text); length = strlen (text);
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
if (width < length) { if (width < length)
if (width <= 3) { {
memset (actual, '.', width); if (width <= 3)
actual+= width; {
remain-= width; memset (actual, '.', width);
} else { actual += width;
memset (actual, '.', 3); remain -= width;
actual+= 3; }
remain-= 3; else
{
pos+= length - width + 3; memset (actual, '.', 3);
actual += 3;
/* copy suffix of text*/ remain -= 3;
for (; pos < length && remain > 1; pos++, actual++, remain--) {
actual[0] = isascii((unsigned char)text[pos]) pos += length - width + 3;
? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) /* copy suffix of text */
? actual[0] : '.'; for (; pos < length && remain > 1; pos++, actual++, remain--)
} {
} actual[0] = isascii ((unsigned char) text[pos])
} else { ? text[pos] : '?';
/* copy all characters */ actual[0] = g_ascii_isprint ((gchar) actual[0])
for (; pos < length && remain > 1; pos++, actual++, remain--) { ? actual[0] : '.';
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?'; }
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; }
} }
} else
{
/* copy all characters */
for (; pos < length && remain > 1; pos++, actual++, remain--)
{
actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
}
}
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
@ -332,50 +365,52 @@ str_ascii_term_trim (const char *text, int width)
static int static int
str_ascii_term_width2 (const char *text, size_t length) str_ascii_term_width2 (const char *text, size_t length)
{ {
return (length != (size_t)(-1)) return (length != (size_t) (-1))
? min (strlen (text), length) ? min (strlen (text), length) : strlen (text);
: strlen (text); }
}
static int static int
str_ascii_term_width1 (const char *text) str_ascii_term_width1 (const char *text)
{ {
return str_ascii_term_width2 (text, (size_t)(-1)); return str_ascii_term_width2 (text, (size_t) (-1));
} }
static int static int
str_ascii_term_char_width (const char *text) str_ascii_term_char_width (const char *text)
{ {
return 1; return 1;
} }
static void static void
str_ascii_msg_term_size (const char *text, int *lines, int *columns) str_ascii_msg_term_size (const char *text, int *lines, int *columns)
{ {
(*lines) = 1; (*lines) = 1;
(*columns) = 0; (*columns) = 0;
char *p, *tmp = g_strdup (text); char *p, *tmp = g_strdup (text);
char *q; char *q;
char c = '\0'; char c = '\0';
int width; int width;
p = tmp; p = tmp;
for (;;) { for (;;)
q = strchr (p, '\n'); {
if (q != NULL) { q = strchr (p, '\n');
c = q[0]; if (q != NULL)
q[0] = '\0'; {
} c = q[0];
q[0] = '\0';
width = str_ascii_term_width1 (p); }
if (width > (*columns)) (*columns) = width;
width = str_ascii_term_width1 (p);
if (q == NULL) if (width > (*columns))
break; (*columns) = width;
q[0] = c;
p = q + 1; if (q == NULL)
(*lines)++; break;
q[0] = c;
p = q + 1;
(*lines)++;
} }
g_free (tmp); g_free (tmp);
} }
@ -388,30 +423,33 @@ str_ascii_term_substring (const char *text, int start, int width)
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
if (start < length) { if (start < length)
pos+= start; {
/* copy at most width characters from text from start */ pos += start;
for (; pos < length && width > 0 && remain > 1; /* copy at most width characters from text from start */
pos++, width--, actual++, remain--) { for (; pos < length && width > 0 && remain > 1;
pos++, width--, actual++, remain--)
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?'; {
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
} actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
}
} }
/* if text is shorter then width, add space to the end */ /* if text is shorter then width, add space to the end */
for (; width > 0 && remain > 1; actual++, remain--, width--) { for (; width > 0 && remain > 1; actual++, remain--, width--)
actual[0] = ' '; {
actual[0] = ' ';
} }
actual[0] = '\0'; actual[0] = '\0';
return result; return result;
} }
static const char * static const char *
str_ascii_trunc (const char *text, int width) str_ascii_trunc (const char *text, int width)
@ -421,36 +459,43 @@ str_ascii_trunc (const char *text, int width)
char *actual; char *actual;
size_t pos = 0; size_t pos = 0;
size_t length; size_t length;
actual = result; actual = result;
remain = sizeof (result); remain = sizeof (result);
length = strlen (text); length = strlen (text);
if (length > width) { if (length > width)
/* copy prefix of text */ {
for (; pos + 1 <= width / 2 && remain > 1; actual++, pos++, remain--) { /* copy prefix of text */
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?'; for (; pos + 1 <= width / 2 && remain > 1; actual++, pos++, remain--)
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; {
} actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
if (remain <= 1) goto finally; }
actual[0] = '~';
actual++; if (remain <= 1)
remain--; goto finally;
actual[0] = '~';
pos+= length - width + 1; actual++;
remain--;
/* copy suffix of text */
for (; pos < length && remain > 1; pos++, actual++, remain--) { pos += length - width + 1;
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; /* copy suffix of text */
} for (; pos < length && remain > 1; pos++, actual++, remain--)
} else { {
/* copy all characters */ actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
for (; pos < length && remain > 1; pos++, actual++, remain--) { actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
actual[0] = isascii((unsigned char)text[pos]) ? text[pos] : '?'; }
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.'; }
} else
{
/* copy all characters */
for (; pos < length && remain > 1; pos++, actual++, remain--)
{
actual[0] = isascii ((unsigned char) text[pos]) ? text[pos] : '?';
actual[0] = g_ascii_isprint ((gchar) actual[0]) ? actual[0] : '.';
}
} }
finally: finally:
@ -461,22 +506,22 @@ str_ascii_trunc (const char *text, int width)
static int static int
str_ascii_offset_to_pos (const char *text, size_t length) str_ascii_offset_to_pos (const char *text, size_t length)
{ {
return (int)length; return (int) length;
} }
static int static int
str_ascii_column_to_pos (const char *text, size_t pos) str_ascii_column_to_pos (const char *text, size_t pos)
{ {
return (int)pos; return (int) pos;
} }
static char * static char *
str_ascii_create_search_needle (const char *needle, int case_sen) str_ascii_create_search_needle (const char *needle, int case_sen)
{ {
return (char*) needle; return (char *) needle;
} }
static void static void
str_ascii_release_search_needle (char *needle, int case_sen) str_ascii_release_search_needle (char *needle, int case_sen)
{ {
} }
@ -488,21 +533,23 @@ str_ascii_search_first (const char *text, const char *search, int case_sen)
char *fold_search; char *fold_search;
const char *match; const char *match;
size_t offset; size_t offset;
fold_text = (case_sen) ? (char*) text : g_ascii_strdown (text, -1); fold_text = (case_sen) ? (char *) text : g_ascii_strdown (text, -1);
fold_search = (case_sen) ? (char*) search : g_ascii_strdown (search, -1); fold_search = (case_sen) ? (char *) search : g_ascii_strdown (search, -1);
match = g_strstr_len (fold_text, -1, fold_search); match = g_strstr_len (fold_text, -1, fold_search);
if (match != NULL) { if (match != NULL)
offset = match - fold_text; {
match = text + offset; offset = match - fold_text;
match = text + offset;
} }
if (!case_sen) { if (!case_sen)
g_free (fold_text); {
g_free (fold_search); g_free (fold_text);
g_free (fold_search);
} }
return match; return match;
} }
@ -513,21 +560,23 @@ str_ascii_search_last (const char *text, const char *search, int case_sen)
char *fold_search; char *fold_search;
const char *match; const char *match;
size_t offset; size_t offset;
fold_text = (case_sen) ? (char*) text : g_ascii_strdown (text, -1); fold_text = (case_sen) ? (char *) text : g_ascii_strdown (text, -1);
fold_search = (case_sen) ? (char*) search : g_ascii_strdown (search, -1); fold_search = (case_sen) ? (char *) search : g_ascii_strdown (search, -1);
match = g_strrstr_len (fold_text, -1, fold_search); match = g_strrstr_len (fold_text, -1, fold_search);
if (match != NULL) { if (match != NULL)
offset = match - fold_text; {
match = text + offset; offset = match - fold_text;
match = text + offset;
} }
if (!case_sen) { if (!case_sen)
g_free (fold_text); {
g_free (fold_search); g_free (fold_text);
g_free (fold_search);
} }
return match; return match;
} }
@ -535,80 +584,81 @@ static int
str_ascii_compare (const char *t1, const char *t2) str_ascii_compare (const char *t1, const char *t2)
{ {
return strcmp (t1, t2); return strcmp (t1, t2);
} }
static int static int
str_ascii_ncompare (const char *t1, const char *t2) str_ascii_ncompare (const char *t1, const char *t2)
{ {
return strncmp (t1, t2, min (strlen (t1), strlen(t2))); return strncmp (t1, t2, min (strlen (t1), strlen (t2)));
} }
static int static int
str_ascii_casecmp (const char *t1, const char *t2) str_ascii_casecmp (const char *t1, const char *t2)
{ {
return g_ascii_strcasecmp (t1, t2); return g_ascii_strcasecmp (t1, t2);
} }
static int static int
str_ascii_ncasecmp (const char *t1, const char *t2) str_ascii_ncasecmp (const char *t1, const char *t2)
{ {
return g_ascii_strncasecmp (t1, t2, min (strlen (t1), strlen (t2))); return g_ascii_strncasecmp (t1, t2, min (strlen (t1), strlen (t2)));
} }
static void static void
str_ascii_fix_string (char *text) str_ascii_fix_string (char *text)
{ {
for (; text[0] != '\0'; text++) { for (; text[0] != '\0'; text++)
text[0] = ((unsigned char)text[0] < 128) ? text[0] : '?'; {
text[0] = ((unsigned char) text[0] < 128) ? text[0] : '?';
} }
} }
static char * static char *
str_ascii_create_key (const char *text, int case_sen) str_ascii_create_key (const char *text, int case_sen)
{ {
return (char*)text; return (char *) text;
} }
static int static int
str_ascii_key_collate (const char *t1, const char *t2, int case_sen) str_ascii_key_collate (const char *t1, const char *t2, int case_sen)
{ {
return (case_sen) ? strcmp (t1, t2) : g_ascii_strcasecmp (t1, t2); return (case_sen) ? strcmp (t1, t2) : g_ascii_strcasecmp (t1, t2);
} }
static void static void
str_ascii_release_key (char *key, int case_sen) str_ascii_release_key (char *key, int case_sen)
{ {
} }
static int static int
str_ascii_prefix (const char *text, const char *prefix) str_ascii_prefix (const char *text, const char *prefix)
{ {
int result; int result;
for (result = 0; text[result] != '\0' && prefix[result] != '\0' for (result = 0; text[result] != '\0' && prefix[result] != '\0'
&& text[result] == prefix[result]; result++); && text[result] == prefix[result]; result++);
return result; return result;
} }
static int static int
str_ascii_caseprefix (const char *text, const char *prefix) str_ascii_caseprefix (const char *text, const char *prefix)
{ {
int result; int result;
for (result = 0; text[result] != '\0' && prefix[result] != '\0' for (result = 0; text[result] != '\0' && prefix[result] != '\0'
&& g_ascii_toupper (text[result]) == g_ascii_toupper (prefix[result]); && g_ascii_toupper (text[result]) ==
result++); g_ascii_toupper (prefix[result]); result++);
return result; return result;
} }
struct str_class struct str_class
str_ascii_init () str_ascii_init ()
{ {
struct str_class result; struct str_class result;
result.vfs_convert_to = str_ascii_vfs_convert_to; result.vfs_convert_to = str_ascii_vfs_convert_to;
result.insert_replace_char = str_ascii_insert_replace_char; result.insert_replace_char = str_ascii_insert_replace_char;
result.is_valid_string = str_ascii_is_valid_string; result.is_valid_string = str_ascii_is_valid_string;
result.is_valid_char = str_ascii_is_valid_char; result.is_valid_char = str_ascii_is_valid_char;
result.cnext_char = str_ascii_cnext_char; result.cnext_char = str_ascii_cnext_char;
result.cprev_char = str_ascii_cprev_char; result.cprev_char = str_ascii_cprev_char;
result.cnext_char_safe = str_ascii_cnext_char; result.cnext_char_safe = str_ascii_cnext_char;
@ -652,6 +702,6 @@ str_ascii_init ()
result.create_key_for_filename = str_ascii_create_key; result.create_key_for_filename = str_ascii_create_key;
result.key_collate = str_ascii_key_collate; result.key_collate = str_ascii_key_collate;
result.release_key = str_ascii_release_key; result.release_key = str_ascii_release_key;
return result; return result;
} }

File diff suppressed because it is too large Load Diff

View File

@ -235,7 +235,7 @@ struct WView {
* used for both normal adn nroff mode */ * used for both normal adn nroff mode */
struct cache_line *first_showed_line; struct cache_line *first_showed_line;
/* converter for translation of text */ /* converter for translation of text */
str_conv_t converter; GIConv converter;
}; };
@ -2450,34 +2450,34 @@ view_display_text (WView * view)
if (col >= view->dpy_text_column if (col >= view->dpy_text_column
&& col + w - view->dpy_text_column <= width) { && col + w - view->dpy_text_column <= width) {
widget_move (view, top + row, left + (col - view->dpy_text_column)); widget_move (view, top + row, left + (col - view->dpy_text_column));
if (!str_iscombiningmark (info.cnxt)) { if (!str_iscombiningmark (info.cnxt)) {
if (str_isprint (info.cact)) { if (str_isprint (info.cact)) {
addstr (str_term_form (info.cact)); addstr (str_term_form (info.cact));
} else { } else {
addch ('.'); addch ('.');
} }
} else { } else {
struct str_buffer *comb = str_get_buffer (); GString *comb = g_string_new ("");
if (str_isprint (info.cact)) { if (str_isprint (info.cact)) {
str_insert_string (info.cact, comb); g_string_append(comb,info.cact);
} else { } else {
str_insert_string (".", comb); g_string_append(comb,".");
} }
while (str_iscombiningmark (info.cnxt)) { while (str_iscombiningmark (info.cnxt)) {
view_read_continue (view, &info); view_read_continue (view, &info);
str_insert_string (info.cact, comb); g_string_append(comb,info.cact);
} }
addstr (str_term_form (comb->data)); addstr (str_term_form (comb->str));
str_release_buffer (comb); g_string_free (comb, TRUE);
} }
} else { } else {
while (str_iscombiningmark (info.cnxt)) { while (str_iscombiningmark (info.cnxt)) {
view_read_continue (view, &info); view_read_continue (view, &info);
} }
} }
col+= w; col+= w;
tty_setcolor (NORMAL_COLOR); tty_setcolor (NORMAL_COLOR);
} }
view->dpy_end = info.next; view->dpy_end = info.next;
@ -2731,7 +2731,7 @@ icase_search_p (WView *view, char *text, char *data, int nothing,
/* read one whole line into buffer, return where line start and end */ /* read one whole line into buffer, return where line start and end */
static int static int
view_get_line_at (WView *view, offset_type from, struct str_buffer * buffer, view_get_line_at (WView *view, offset_type from, GString * buffer,
offset_type *buff_start, offset_type *buff_end) offset_type *buff_start, offset_type *buff_end)
{ {
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0) #define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
@ -2756,7 +2756,7 @@ view_get_line_at (WView *view, offset_type from, struct str_buffer * buffer,
(*buff_start) = start; (*buff_start) = start;
(*buff_end) = end; (*buff_end) = end;
str_reset_buffer (buffer); g_string_set_size(buffer,0);
view_read_start (view, &info, start); view_read_start (view, &info, start);
while ((info.result != -1) && (info.next < end)) { while ((info.result != -1) && (info.next < end)) {
@ -2766,29 +2766,30 @@ view_get_line_at (WView *view, offset_type from, struct str_buffer * buffer,
if (cmp (info.cact, "")) { if (cmp (info.cact, "")) {
if (info.actual < from) { if (info.actual < from) {
/* '\0' before start offset, continue */ /* '\0' before start offset, continue */
str_reset_buffer (buffer); g_string_set_size(buffer,0);
(*buff_start) = info.next; (*buff_start) = info.next;
continue; continue;
} else { } else {
/* '\0' after start offset, end */ /* '\0' after start offset, end */
(*buff_end) = info.next; (*buff_end) = info.next;
return 1; return 1;
} }
} }
if (view_read_test_new_line (view, &info)) if (view_read_test_new_line (view, &info))
continue; continue;
if (view_read_test_nroff_back (view, &info)) { if (view_read_test_nroff_back (view, &info)) {
str_backward_buffer (buffer, 1); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
g_string_truncate (buffer, buffer->len-1);
continue; continue;
}
str_insert_string (info.cact, buffer);
} }
g_string_append(buffer,info.cact);
}
return 1; return 1;
} }
/* map search result positions to offsets in text */ /* map search result positions to offsets in text */
void void
@ -2803,7 +2804,7 @@ view_matchs_to_offsets (WView *view, offset_type start, offset_type end,
(*search_end) = INVALID_OFFSET; (*search_end) = INVALID_OFFSET;
view_read_start (view, &info, start); view_read_start (view, &info, start);
while ((info.result != -1) && (info.next < end)) { while ((info.result != -1) && (info.next < end)) {
view_read_continue (view, &info); view_read_continue (view, &info);
@ -2981,7 +2982,7 @@ static void
view_search (WView *view, char *text, view_search (WView *view, char *text,
int (*search) (WView *, char *, char *, int, size_t *, size_t *)) int (*search) (WView *, char *, char *, int, size_t *, size_t *))
{ {
struct str_buffer *buffer; GString *buffer;
offset_type search_start; offset_type search_start;
int search_status; int search_status;
Dlg_head *d = 0; Dlg_head *d = 0;
@ -2996,7 +2997,7 @@ view_search (WView *view, char *text,
mc_refresh (); mc_refresh ();
} }
buffer = str_get_buffer (); buffer = g_string_new ("");
search_start = (view->direction != 1) ? view->search_start : search_start = (view->direction != 1) ? view->search_start :
view->search_end; view->search_end;
@ -3007,12 +3008,12 @@ view_search (WView *view, char *text,
enable_interrupt_key (); enable_interrupt_key ();
search_status = -1; search_status = -1;
while (1) { while (1) {
if (search_start >= view->update_activate) { if (search_start >= view->update_activate) {
view->update_activate += view->update_steps; view->update_activate += view->update_steps;
if (verbose) { if (verbose) {
view_percent (view, search_start); view_percent (view, search_start);
mc_refresh (); mc_refresh ();
} }
if (got_interrupt ()) if (got_interrupt ())
@ -3022,9 +3023,9 @@ view_search (WView *view, char *text,
if (!view_get_line_at (view, search_start, buffer, &line_start, &line_end)) if (!view_get_line_at (view, search_start, buffer, &line_start, &line_end))
break; break;
search_status = (*search) (view, text, buffer->data, match_normal, search_status = (*search) (view, text, buffer->str, match_normal,
&match_start, &match_end); &match_start, &match_end);
if (search_status < 0) { if (search_status < 0) {
break; break;
} }
@ -3041,11 +3042,11 @@ view_search (WView *view, char *text,
/* We found the string */ /* We found the string */
view_matchs_to_offsets (view, line_start, line_end, view_matchs_to_offsets (view, line_start, line_end,
match_start, match_end, match_start, match_end,
&(view->search_start), &(view->search_end)); &(view->search_start), &(view->search_end));
view_moveto_match (view); view_moveto_match (view);
break; break;
} }
@ -3058,7 +3059,7 @@ view_search (WView *view, char *text,
message (D_NORMAL, _("Search"), _(" Search string not found ")); message (D_NORMAL, _("Search"), _(" Search string not found "));
view->search_end = view->search_start; view->search_end = view->search_start;
} }
str_release_buffer (buffer); g_string_free (buffer, TRUE);
} }
/* Search buffer (its size is len) in the complete buffer /* Search buffer (its size is len) in the complete buffer

View File

@ -75,7 +75,7 @@ static GSList *vfs_openfiles;
#define VFS_FIRST_HANDLE 100 #define VFS_FIRST_HANDLE 100
static struct vfs_class *localfs_class; static struct vfs_class *localfs_class;
static struct str_buffer *vfs_str_buffer; static GString *vfs_str_buffer;
static const char *supported_encodings[] = { static const char *supported_encodings[] = {
"UTF8", "UTF8",
@ -382,8 +382,8 @@ vfs_supported_enconding (const char *encoding) {
* buffer - used to store result of translation * buffer - used to store result of translation
*/ */
static int static int
_vfs_translate_path (const char *path, int size, _vfs_translate_path (const char *path, int size,
str_conv_t defcnv, struct str_buffer *buffer) str_conv_t defcnv, GString *buffer)
{ {
const char *semi; const char *semi;
const char *ps; const char *ps;
@ -392,37 +392,37 @@ _vfs_translate_path (const char *path, int size,
static char encoding[16]; static char encoding[16];
str_conv_t coder; str_conv_t coder;
int ms; int ms;
if (size == 0) return 0; if (size == 0) return 0;
size = (size > 0) ? size : strlen (path); size = (size > 0) ? size : strlen (path);
/* try found #end: */ /* try found #end: */
semi = g_strrstr_len (path, size, "#enc:"); semi = g_strrstr_len (path, size, "#enc:");
if (semi != NULL) { if (semi != NULL) {
/* first must be translated part before #enc: */ /* first must be translated part before #enc: */
ms = semi - path; ms = semi - path;
/* remove '/' before #enc */ /* remove '/' before #enc */
ps = str_cget_prev_char (semi); ps = str_cget_prev_char (semi);
if (ps[0] == PATH_SEP) ms = ps - path; if (ps[0] == PATH_SEP) ms = ps - path;
state = _vfs_translate_path (path, ms, defcnv, buffer); state = _vfs_translate_path (path, ms, defcnv, buffer);
if (state != 0) return state; if (state != 0) return state;
/* now can be translated part after #enc: */ /* now can be translated part after #enc: */
semi+= 5; semi+= 5;
slash = strchr (semi, PATH_SEP); slash = strchr (semi, PATH_SEP);
// ignore slashes after size; // ignore slashes after size;
if (slash - path >= size) slash = NULL; if (slash - path >= size) slash = NULL;
ms = (slash != NULL) ? slash - semi : strlen (semi); ms = (slash != NULL) ? slash - semi : strlen (semi);
ms = min (ms, sizeof (encoding) - 1); ms = min (ms, sizeof (encoding) - 1);
// limit encoding size (ms) to path size (size) // limit encoding size (ms) to path size (size)
if (semi + ms > path + size) ms = path + size - semi; if (semi + ms > path + size) ms = path + size - semi;
memcpy (encoding, semi, ms); memcpy (encoding, semi, ms);
encoding[ms] = '\0'; encoding[ms] = '\0';
switch (vfs_supported_enconding (encoding)) { switch (vfs_supported_enconding (encoding)) {
case 1: case 1:
coder = str_crt_conv_to (encoding); coder = str_crt_conv_to (encoding);
@ -430,9 +430,9 @@ _vfs_translate_path (const char *path, int size,
if (slash != NULL) { if (slash != NULL) {
state = str_vfs_convert_to (coder, slash, state = str_vfs_convert_to (coder, slash,
path + size - slash, buffer); path + size - slash, buffer);
} else if (buffer->data[0] == '\0') { } else if (buffer->str[0] == '\0') {
/* exmaple "/#enc:utf-8" */ /* exmaple "/#enc:utf-8" */
str_insert_char (PATH_SEP, buffer); g_string_append_c(buffer, PATH_SEP);
} }
str_close_conv (coder); str_close_conv (coder);
return state; return state;
@ -459,12 +459,12 @@ char *
vfs_translate_path (const char *path) vfs_translate_path (const char *path)
{ {
int state; int state;
str_reset_buffer (vfs_str_buffer); g_string_set_size(vfs_str_buffer,0);
state = _vfs_translate_path (path, -1, str_cnv_from_term, vfs_str_buffer); state = _vfs_translate_path (path, -1, str_cnv_from_term, vfs_str_buffer);
// strict version // strict version
//return (state == 0) ? vfs_str_buffer->data : NULL; //return (state == 0) ? vfs_str_buffer->data : NULL;
return (state != ESTR_FAILURE) ? vfs_str_buffer->data : NULL; return (state != ESTR_FAILURE) ? vfs_str_buffer->str : NULL;
} }
char * char *
@ -753,12 +753,12 @@ mc_readdir (DIR *dirp)
do { do {
entry = (*vfs->readdir) (dirinfo->info); entry = (*vfs->readdir) (dirinfo->info);
if (entry == NULL) return NULL; if (entry == NULL) return NULL;
str_reset_buffer (vfs_str_buffer); g_string_set_size(vfs_str_buffer,0);
state = str_vfs_convert_from (dirinfo->converter, state = str_vfs_convert_from (dirinfo->converter,
entry->d_name, vfs_str_buffer); entry->d_name, vfs_str_buffer);
} while (state != 0); } while (state != 0);
memcpy (&result, entry, sizeof (struct dirent)); memcpy (&result, entry, sizeof (struct dirent));
g_strlcpy (result.d_name, vfs_str_buffer->data, NAME_MAX + 1); g_strlcpy (result.d_name, vfs_str_buffer->str, NAME_MAX + 1);
result.d_reclen = strlen (result.d_name); result.d_reclen = strlen (result.d_name);
} }
if (entry == NULL) errno = vfs->readdir ? ferrno (vfs) : E_NOTSUPP; if (entry == NULL) errno = vfs->readdir ? ferrno (vfs) : E_NOTSUPP;
@ -854,10 +854,10 @@ _vfs_get_cwd (void)
if (encoding == NULL) { if (encoding == NULL) {
tmp = g_get_current_dir (); tmp = g_get_current_dir ();
if (tmp != NULL) { /* One of the directories in the path is not readable */ if (tmp != NULL) { /* One of the directories in the path is not readable */
str_reset_buffer (vfs_str_buffer); g_string_set_size(vfs_str_buffer,0);
state = str_vfs_convert_from (str_cnv_from_term, tmp, vfs_str_buffer); state = str_vfs_convert_from (str_cnv_from_term, tmp, vfs_str_buffer);
g_free (tmp); g_free (tmp);
sys_cwd = (state == 0) ? g_strdup (vfs_str_buffer->data) : NULL; sys_cwd = (state == 0) ? g_strdup (vfs_str_buffer->str) : NULL;
if (!sys_cwd) if (!sys_cwd)
return current_dir; return current_dir;
@ -1174,7 +1174,7 @@ mc_ungetlocalcopy (const char *pathname, const char *local, int has_changed)
void void
vfs_init (void) vfs_init (void)
{ {
vfs_str_buffer = str_get_buffer (); vfs_str_buffer = g_string_new("");
/* localfs needs to be the first one */ /* localfs needs to be the first one */
init_localfs(); init_localfs();
/* fallback value for vfs_get_class() */ /* fallback value for vfs_get_class() */
@ -1218,8 +1218,8 @@ vfs_shut (void)
(*vfs->done) (vfs); (*vfs->done) (vfs);
g_slist_free (vfs_openfiles); g_slist_free (vfs_openfiles);
str_release_buffer (vfs_str_buffer); g_string_free (vfs_str_buffer, TRUE);
} }
/* /*