diff options
Diffstat (limited to 'Build/source/utils/dialog/dialog-1.1-20080819/inputstr.c')
-rw-r--r-- | Build/source/utils/dialog/dialog-1.1-20080819/inputstr.c | 745 |
1 files changed, 0 insertions, 745 deletions
diff --git a/Build/source/utils/dialog/dialog-1.1-20080819/inputstr.c b/Build/source/utils/dialog/dialog-1.1-20080819/inputstr.c deleted file mode 100644 index ca061b94cf9..00000000000 --- a/Build/source/utils/dialog/dialog-1.1-20080819/inputstr.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - * $Id: inputstr.c,v 1.64 2008/03/16 20:19:43 tom Exp $ - * - * inputstr.c -- functions for input/display of a string - * - * Copyright 2000-2007,2008 Thomas E. Dickey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License, version 2.1 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to - * Free Software Foundation, Inc. - * 51 Franklin St., Fifth Floor - * Boston, MA 02110, USA. - */ - -#include <dialog.h> -#include <dlg_keys.h> - -#include <errno.h> - -#ifdef HAVE_SETLOCALE -#include <locale.h> -#endif - -#if defined(HAVE_SEARCH_H) && defined(HAVE_TSEARCH) -#include <search.h> -#else -#undef HAVE_TSEARCH -#endif - -#ifdef NEED_WCHAR_H -#include <wchar.h> -#endif - -#if defined(USE_WIDE_CURSES) -#define USE_CACHING 1 -#elif defined(HAVE_XDIALOG) -#define USE_CACHING 1 /* editbox really needs caching! */ -#else -#define USE_CACHING 0 -#endif - -typedef struct _cache { - struct _cache *next; -#if USE_CACHING - struct _cache *cache_at; /* unique: associate caches by CACHE */ - const char *string_at; /* unique: associate caches by char* */ -#endif - unsigned s_len; /* strlen(string) - we add 1 for EOS */ - unsigned i_len; /* length(list) - we add 1 for EOS */ - char *string; /* a copy of the last-processed string */ - int *list; /* indices into the string */ -} CACHE; - -#if USE_CACHING -#define SAME_CACHE(c,s,l) (c->string != 0 && memcmp(c->string,s,l) == 0) - -static CACHE *cache_list; - -#ifdef HAVE_TSEARCH -static void *sorted_cache; -#endif - -#ifdef USE_WIDE_CURSES -static int -have_locale(void) -{ - static int result = -1; - if (result < 0) { - char *test = setlocale(LC_ALL, 0); - if (test == 0 || *test == 0) { - result = FALSE; - } else if (strcmp(test, "C") && strcmp(test, "POSIX")) { - result = TRUE; - } else { - result = FALSE; - } - } - return result; -} -#endif - -#ifdef HAVE_TSEARCH -static int -compare_cache(const void *a, const void *b) -{ - const CACHE *p = (const CACHE *) a; - const CACHE *q = (const CACHE *) b; - int result = 0; - result = p->cache_at - q->cache_at; - if (result == 0) - result = p->string_at - q->string_at; - return result; -} -#endif - -static CACHE * -find_cache(CACHE * cache, const char *string) -{ - CACHE *p; - -#ifdef HAVE_TSEARCH - void *pp; - CACHE find; - - memset(&find, 0, sizeof(find)); - find.cache_at = cache; - find.string_at = string; - - if ((pp = tfind(&find, &sorted_cache, compare_cache)) != 0) { - p = *(CACHE **) pp; - } else { - p = 0; - } -#else - for (p = cache_list; p != 0; p = p->next) { - if (p->cache_at == cache - && p->string_at == string) { - break; - } - } -#endif - return p; -} - -static void -make_cache(CACHE * cache, const char *string) -{ - CACHE *p; - - p = dlg_calloc(CACHE, 1); - assert_ptr(p, "load_cache"); - p->next = cache_list; - cache_list = p; - - p->cache_at = cache; - p->string_at = string; - - *cache = *p; -#ifdef HAVE_TSEARCH - (void) tsearch(p, &sorted_cache, compare_cache); -#endif -} - -static void -load_cache(CACHE * cache, const char *string) -{ - CACHE *p; - - if ((p = find_cache(cache, string)) != 0) { - *cache = *p; - } else { - make_cache(cache, string); - } -} - -static void -save_cache(CACHE * cache, const char *string) -{ - CACHE *p; - - if ((p = find_cache(cache, string)) != 0) { - CACHE *q = p->next; - *p = *cache; - p->next = q; - } -} -#else -#define SAME_CACHE(c,s,l) (c->string != 0) -#define load_cache(cache, string) /* nothing */ -#define save_cache(cache, string) /* nothing */ -#endif /* USE_WIDE_CURSES */ - -/* - * If the given string has not changed, we do not need to update the index. - * If we need to update the index, allocate enough memory for it. - */ -static bool -same_cache2(CACHE * cache, const char *string, unsigned i_len) -{ - unsigned need; - unsigned s_len = strlen(string); - - if (cache->s_len != 0 - && cache->s_len >= s_len - && cache->list != 0 - && SAME_CACHE(cache, string, s_len)) { - return TRUE; - } - - need = (i_len + 1); - if (cache->list == 0) { - cache->list = dlg_malloc(int, need); - } else if (cache->i_len < i_len) { - cache->list = dlg_realloc(int, need, cache->list); - } - cache->i_len = i_len; - - if (cache->s_len >= s_len && cache->string != 0) { - strcpy(cache->string, string); - } else { - if (cache->string != 0) - free(cache->string); - cache->string = dlg_strclone(string); - } - cache->s_len = s_len; - - return FALSE; -} - -#ifdef USE_WIDE_CURSES -/* - * Like same_cache2(), but we are only concerned about caching a copy of the - * string and its associated length. - */ -static bool -same_cache1(CACHE * cache, const char *string, unsigned i_len) -{ - unsigned s_len = strlen(string); - - if (cache->s_len == s_len - && SAME_CACHE(cache, string, s_len)) { - return TRUE; - } - - if (cache->s_len >= s_len && cache->string != 0) { - strcpy(cache->string, string); - } else { - if (cache->string != 0) - free(cache->string); - cache->string = dlg_strclone(string); - } - cache->s_len = s_len; - cache->i_len = i_len; - - return FALSE; -} -#endif /* USE_CACHING */ - -/* - * Counts the number of bytes that make up complete wide-characters, up to byte - * 'len'. If there is no locale set, simply return the original length. - */ -#ifdef USE_WIDE_CURSES -static int -dlg_count_wcbytes(const char *string, size_t len) -{ - int result; - - if (have_locale()) { - static CACHE cache; - - load_cache(&cache, string); - if (!same_cache1(&cache, string, len)) { - while (len != 0) { - int part = 0; - int code = 0; - const char *src = cache.string; - mbstate_t state; - int save = cache.string[len]; - - cache.string[len] = '\0'; - memset(&state, 0, sizeof(state)); - code = mbsrtowcs((wchar_t *) 0, &src, len, &state); - cache.string[len] = save; - if (code >= 0) { - break; - } - ++part; - --len; - } - cache.i_len = len; - save_cache(&cache, string); - } - result = cache.i_len; - } else { - result = len; - } - return result; -} -#endif /* USE_WIDE_CURSES */ - -/* - * Counts the number of wide-characters in the string. - */ -int -dlg_count_wchars(const char *string) -{ - int result; - -#ifdef USE_WIDE_CURSES - if (have_locale()) { - static CACHE cache; - size_t len = strlen(string); - - load_cache(&cache, string); - if (!same_cache1(&cache, string, len)) { - const char *src = cache.string; - mbstate_t state; - int part = dlg_count_wcbytes(cache.string, len); - int save = cache.string[part]; - int code; - wchar_t *temp = dlg_calloc(wchar_t, len + 1); - - cache.string[part] = '\0'; - memset(&state, 0, sizeof(state)); - code = mbsrtowcs(temp, &src, part, &state); - cache.i_len = (code >= 0) ? wcslen(temp) : 0; - cache.string[part] = save; - free(temp); - save_cache(&cache, string); - } - result = cache.i_len; - } else -#endif /* USE_WIDE_CURSES */ - { - result = strlen(string); - } - return result; -} - -/* - * Build an index of the wide-characters in the string, so we can easily tell - * which byte-offset begins a given wide-character. - */ -const int * -dlg_index_wchars(const char *string) -{ - static CACHE cache; - unsigned len = dlg_count_wchars(string); - unsigned inx; - - load_cache(&cache, string); - if (!same_cache2(&cache, string, len)) { - const char *current = string; - - cache.list[0] = 0; - for (inx = 1; inx <= len; ++inx) { -#ifdef USE_WIDE_CURSES - if (have_locale()) { - mbstate_t state; - int width; - memset(&state, 0, sizeof(state)); - width = mbrlen(current, strlen(current), &state); - if (width <= 0) - width = 1; /* FIXME: what if we have a control-char? */ - current += width; - cache.list[inx] = cache.list[inx - 1] + width; - } else -#endif /* USE_WIDE_CURSES */ - { - (void) current; - cache.list[inx] = inx; - } - } - save_cache(&cache, string); - } - return cache.list; -} - -/* - * Given the character-offset to find in the list, return the corresponding - * array index. - */ -int -dlg_find_index(const int *list, int limit, int to_find) -{ - int result; - for (result = 0; result <= limit; ++result) { - if (to_find == list[result] - || result == limit - || to_find < list[result + 1]) - break; - } - return result; -} - -/* - * Build a list of the display-columns for the given string's characters. - */ -const int * -dlg_index_columns(const char *string) -{ - static CACHE cache; - unsigned len = dlg_count_wchars(string); - unsigned inx; - - load_cache(&cache, string); - if (!same_cache2(&cache, string, len)) { - cache.list[0] = 0; -#ifdef USE_WIDE_CURSES - if (have_locale()) { - size_t num_bytes = strlen(string); - const int *inx_wchars = dlg_index_wchars(string); - mbstate_t state; - - for (inx = 0; inx < len; ++inx) { - wchar_t temp[2]; - int check; - int result; - - if (string[inx_wchars[inx]] == TAB) { - result = ((cache.list[inx] | 7) + 1) - cache.list[inx]; - } else { - memset(&state, 0, sizeof(state)); - memset(temp, 0, sizeof(temp)); - check = mbrtowc(temp, - string + inx_wchars[inx], - num_bytes - inx_wchars[inx], &state); - if (check <= 0) { - result = 1; - } else { - result = wcwidth(temp[0]); - } - if (result < 0) { - wchar_t *printable; - cchar_t temp2; - setcchar(&temp2, temp, 0, 0, 0); - printable = wunctrl(&temp2); - result = printable ? wcslen(printable) : 1; - } - } - cache.list[inx + 1] = result; - if (inx != 0) - cache.list[inx + 1] += cache.list[inx]; - } - } else -#endif /* USE_WIDE_CURSES */ - { - for (inx = 0; inx < len; ++inx) { - int ch = UCH(string[inx]); - - if (ch == TAB) - cache.list[inx + 1] = - ((cache.list[inx] | 7) + 1) - cache.list[inx]; - else if (isprint(ch)) - cache.list[inx + 1] = 1; - else { - const char *printable; - printable = unctrl(ch); - cache.list[inx + 1] = printable ? strlen(printable) : 1; - } - if (inx != 0) - cache.list[inx + 1] += cache.list[inx]; - } - } - save_cache(&cache, string); - } - return cache.list; -} - -/* - * Returns the number of columns used for a string. That happens to be the - * end-value of the cols[] array. - */ -int -dlg_count_columns(const char *string) -{ - int result = 0; - int limit = dlg_count_wchars(string); - if (limit > 0) { - const int *cols = dlg_index_columns(string); - result = cols[limit]; - } else { - result = strlen(string); - } - return result; -} - -/* - * Given a column limit, count the number of wide characters that can fit - * into that limit. The offset is used to skip over a leading character - * that was already written. - */ -int -dlg_limit_columns(const char *string, int limit, int offset) -{ - const int *cols = dlg_index_columns(string); - int result = dlg_count_wchars(string); - - while (result > 0 && (cols[result] - cols[offset]) > limit) - --result; - return result; -} - -/* - * Updates the string and character-offset, given various editing characters - * or literal characters which are inserted at the character-offset. - */ -bool -dlg_edit_string(char *string, int *chr_offset, int key, int fkey, bool force) -{ - int i; - int len = strlen(string); - int limit = dlg_count_wchars(string); - const int *indx = dlg_index_wchars(string); - int offset = dlg_find_index(indx, limit, *chr_offset); - int max_len = dlg_max_input(MAX_LEN); - bool edit = TRUE; - - /* transform editing characters into equivalent function-keys */ - if (!fkey) { - fkey = TRUE; /* assume we transform */ - switch (key) { - case 0: - break; - case ESC: - case TAB: - fkey = FALSE; /* this is used for navigation */ - break; - default: - fkey = FALSE; /* ...no, we did not transform */ - break; - } - } - - if (fkey) { - switch (key) { - case 0: /* special case for loop entry */ - edit = force; - break; - case DLGK_GRID_LEFT: - if (*chr_offset) - *chr_offset = indx[offset - 1]; - break; - case DLGK_GRID_RIGHT: - if (offset < limit) - *chr_offset = indx[offset + 1]; - break; - case DLGK_BEGIN: - if (*chr_offset) - *chr_offset = 0; - break; - case DLGK_FINAL: - if (offset < limit) - *chr_offset = indx[limit]; - break; - case DLGK_DELETE_LEFT: - if (offset) { - int gap = indx[offset] - indx[offset - 1]; - *chr_offset = indx[offset - 1]; - if (gap > 0) { - for (i = *chr_offset; - (string[i] = string[i + gap]) != '\0'; - i++) { - ; - } - } - } - break; - case DLGK_DELETE_RIGHT: - if (limit) { - if (--limit == 0) { - string[*chr_offset = 0] = '\0'; - } else { - int gap = ((offset <= limit) - ? (indx[offset + 1] - indx[offset]) - : 0); - if (gap > 0) { - for (i = indx[offset]; - (string[i] = string[i + gap]) != '\0'; - i++) { - ; - } - } else if (offset > 0) { - string[indx[offset - 1]] = '\0'; - } - if (*chr_offset > indx[limit]) - *chr_offset = indx[limit]; - } - } - break; - case DLGK_DELETE_ALL: - string[*chr_offset = 0] = '\0'; - break; - case DLGK_ENTER: - edit = 0; - break; -#ifdef KEY_RESIZE - case KEY_RESIZE: - edit = 0; - break; -#endif - case DLGK_GRID_UP: - case DLGK_GRID_DOWN: - case DLGK_FIELD_NEXT: - case DLGK_FIELD_PREV: - edit = 0; - break; - default: - beep(); - break; - } - } else { - if (key == ESC) { - edit = 0; - } else { - if (len < max_len) { - for (i = ++len; i > *chr_offset; i--) - string[i] = string[i - 1]; - string[*chr_offset] = key; - *chr_offset += 1; - } else { - (void) beep(); - } - } - } - return edit; -} - -static void -compute_edit_offset(const char *string, - int chr_offset, - int x_last, - int *p_dpy_column, - int *p_scroll_amt) -{ - const int *cols = dlg_index_columns(string); - const int *indx = dlg_index_wchars(string); - int limit = dlg_count_wchars(string); - int offset = dlg_find_index(indx, limit, chr_offset); - int offset2; - int dpy_column; - int n; - - for (n = offset2 = 0; n <= offset; ++n) { - if ((cols[offset] - cols[n]) < x_last - && (offset == limit || (cols[offset + 1] - cols[n]) < x_last)) { - offset2 = n; - break; - } - } - - dpy_column = cols[offset] - cols[offset2]; - - if (p_dpy_column != 0) - *p_dpy_column = dpy_column; - if (p_scroll_amt != 0) - *p_scroll_amt = offset2; -} - -/* - * Given the character-offset in the string, returns the display-offset where - * we will position the cursor. - */ -int -dlg_edit_offset(char *string, int chr_offset, int x_last) -{ - int result; - - compute_edit_offset(string, chr_offset, x_last, &result, 0); - - return result; -} - -/* - * Displays the string, shifted as necessary, to fit within the box and show - * the current character-offset. - */ -void -dlg_show_string(WINDOW *win, - const char *string, /* string to display (may be multibyte) */ - int chr_offset, /* character (not bytes) offset */ - chtype attr, /* window-attributes */ - int y_base, /* beginning row on screen */ - int x_base, /* beginning column on screen */ - int x_last, /* number of columns on screen */ - bool hidden, /* if true, do not echo */ - bool force) /* if true, force repaint */ -{ - x_last = MIN(x_last + x_base, getmaxx(win)) - x_base; - - if (hidden && !dialog_vars.insecure) { - if (force) { - (void) wmove(win, y_base, x_base); - wrefresh(win); - } - } else { - const int *cols = dlg_index_columns(string); - const int *indx = dlg_index_wchars(string); - int limit = dlg_count_wchars(string); - - int i, j, k; - int input_x; - int scrollamt; - - compute_edit_offset(string, chr_offset, x_last, &input_x, &scrollamt); - - wattrset(win, attr); - (void) wmove(win, y_base, x_base); - for (i = scrollamt, k = 0; i < limit && k < x_last; ++i) { - int check = cols[i + 1] - cols[scrollamt]; - if (check <= x_last) { - for (j = indx[i]; j < indx[i + 1]; ++j) { - int ch = UCH(string[j]); - if (hidden && dialog_vars.insecure) { - waddch(win, '*'); - } else if (ch == TAB) { - int count = cols[i + 1] - cols[i]; - while (--count >= 0) - waddch(win, ' '); - } else { - waddch(win, ch); - } - } - k = check; - } else { - break; - } - } - while (k++ < x_last) - waddch(win, ' '); - (void) wmove(win, y_base, x_base + input_x); - wrefresh(win); - } -} - -#ifdef NO_LEAKS -void -_dlg_inputstr_leaks(void) -{ -#if USE_CACHING - while (cache_list != 0) { - CACHE *next = cache_list->next; -#ifdef HAVE_TSEARCH - tdelete(cache_list, &sorted_cache, compare_cache); -#endif - if (cache_list->string != 0) - free(cache_list->string); - if (cache_list->list != 0) - free(cache_list->list); - free(cache_list); - cache_list = next; - } -#endif /* USE_CACHING */ -} -#endif /* NO_LEAKS */ |