mirror of git://git.sv.gnu.org/nano.git
start making multibyte equivalents of the string functions in utils.c
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2277 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
parent
721fe6704a
commit
3a1fc8f0ab
27
ChangeLog
27
ChangeLog
|
@ -96,17 +96,22 @@ CVS code -
|
|||
file chars.c; new functions is_alnum_char(),
|
||||
is_alnum_mbchar(), is_alnum_wchar(), is_blank_mbchar(),
|
||||
is_blank_wchar(), is_cntrl_mbchar(), is_cntrl_wchar(),
|
||||
mbstrnlen(), control_mbrep(), control_wrep(), mbwidth(),
|
||||
mb_cur_max(), and make_mbchar(); changes to is_blank_char()
|
||||
(moved to chars.c), is_cntrl_char() (moved to chars.c),
|
||||
nstrnlen() (moved to chars.c), parse_char() (renamed
|
||||
parse_mbchar() and moved to chars.c), move_left() (renamed
|
||||
move_mbleft() and moved to chars.c), move_right() (renamed
|
||||
move_mbright() and moved to chars.c), do_home(),
|
||||
do_verbatim_input(), do_delete(), do_tab(), do_next_word(),
|
||||
do_prev_word(), do_input(), do_output(), get_buffer(),
|
||||
unget_input(), unget_kbinput(), get_input(), parse_kbinput(),
|
||||
unparse_kbinput(), parse_verbatim_kbinput(),
|
||||
control_mbrep(), control_wrep(), mbwidth(), mb_cur_max(),
|
||||
make_mbchar(), mbstrnlen(), mbstrcasecmp(), and
|
||||
mbstrncasecmp(); changes to is_blank_char() (moved to
|
||||
chars.c), is_cntrl_char() (moved to chars.c), nstricmp()
|
||||
(renamed nstrcasecmp() and moved to chars.c), nstrnicmp()
|
||||
(renamed nstrncasecmp() and moved to chars.c), nstristr()
|
||||
(renamed nstrcasestr() and moved to chars.c), revstrstr()
|
||||
(moved to chars.c), revstristr() (renamed revstrcasestr() and
|
||||
moved to chars.c), nstrnlen() (moved to chars.c),
|
||||
parse_char() (renamed parse_mbchar() and moved to chars.c),
|
||||
move_left() (renamed move_mbleft() and moved to chars.c),
|
||||
move_right() (renamed move_mbright() and moved to chars.c),
|
||||
do_home(), do_verbatim_input(), do_delete(), do_tab(),
|
||||
do_next_word(), do_prev_word(), do_input(), do_output(),
|
||||
get_buffer(), unget_input(), unget_kbinput(), get_input(),
|
||||
parse_kbinput(), unparse_kbinput(), parse_verbatim_kbinput(),
|
||||
do_statusbar_input(), do_statusbar_home(),
|
||||
do_statusbar_verbatim_kbinput(), do_statusbar_output(), and
|
||||
display_string(); removal of buffer_to_keys() and
|
||||
|
|
315
src/chars.c
315
src/chars.c
|
@ -160,59 +160,6 @@ bool is_cntrl_wchar(wchar_t wc)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRNLEN
|
||||
/* This function is equivalent to strnlen(). */
|
||||
size_t nstrnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
|
||||
;
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function is equivalent to strnlen() for multibyte strings. */
|
||||
size_t mbstrnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
#ifdef NANO_WIDE
|
||||
if (!ISSET(NO_UTF8)) {
|
||||
size_t n = 0;
|
||||
char *s_mb = charalloc(mb_cur_max());
|
||||
int s_mb_len;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
while (*s != '\0') {
|
||||
s_mb_len = parse_mbchar(s + n, s_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (s_mb_len > maxlen)
|
||||
break;
|
||||
|
||||
maxlen -= s_mb_len;
|
||||
n += s_mb_len;
|
||||
}
|
||||
|
||||
free(s_mb);
|
||||
|
||||
return n;
|
||||
} else
|
||||
#endif
|
||||
return
|
||||
#ifdef HAVE_STRNLEN
|
||||
strnlen(s, maxlen);
|
||||
#else
|
||||
nstrnlen(s, maxlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* c is a control character. It displays as ^@, ^?, or ^[ch] where ch
|
||||
* is c + 64. We return that character. */
|
||||
unsigned char control_rep(unsigned char c)
|
||||
|
@ -475,3 +422,265 @@ size_t move_mbright(const char *buf, size_t pos)
|
|||
#endif
|
||||
, NULL);
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
/* This function is equivalent to strcasecmp(). */
|
||||
int nstrcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
|
||||
if (tolower(*s1) != tolower(*s2))
|
||||
break;
|
||||
}
|
||||
|
||||
return (tolower(*s1) - tolower(*s2));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function is equivalent to strcasecmp() for multibyte strings. */
|
||||
int mbstrcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
#ifdef NANO_WIDE
|
||||
if (!ISSET(NO_UTF8)) {
|
||||
char *s1_mb = charalloc(mb_cur_max());
|
||||
char *s2_mb = charalloc(mb_cur_max());
|
||||
int s1_mb_len, s2_mb_len;
|
||||
wchar_t ws1, ws2;
|
||||
|
||||
while (*s1 != '\0' && *s2 != '\0') {
|
||||
s1_mb_len = parse_mbchar(s1, s1_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (mbtowc(&ws1, s1_mb, s1_mb_len) <= 0) {
|
||||
mbtowc(NULL, NULL, 0);
|
||||
ws1 = (unsigned char)*s1_mb;
|
||||
}
|
||||
|
||||
|
||||
s2_mb_len = parse_mbchar(s2, s2_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (mbtowc(&ws2, s2_mb, s2_mb_len) <= 0) {
|
||||
mbtowc(NULL, NULL, 0);
|
||||
ws2 = (unsigned char)*s2_mb;
|
||||
}
|
||||
|
||||
|
||||
if (towlower(ws1) != towlower(ws2))
|
||||
break;
|
||||
|
||||
s1 += s1_mb_len;
|
||||
s2 += s2_mb_len;
|
||||
}
|
||||
|
||||
free(s1_mb);
|
||||
free(s2_mb);
|
||||
|
||||
return (towlower(ws1) - towlower(ws2));
|
||||
} else
|
||||
#endif
|
||||
return
|
||||
#ifdef HAVE_STRCASECMP
|
||||
strcasecmp(s1, s2);
|
||||
#else
|
||||
nstrcasecmp(s1, s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
/* This function is equivalent to strncasecmp(). */
|
||||
int nstrncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
|
||||
if (tolower(*s1) != tolower(*s2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
return (tolower(*s1) - tolower(*s2));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function is equivalent to strncasecmp() for multibyte
|
||||
* strings. */
|
||||
int mbstrncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
#ifdef NANO_WIDE
|
||||
if (!ISSET(NO_UTF8)) {
|
||||
char *s1_mb = charalloc(mb_cur_max());
|
||||
char *s2_mb = charalloc(mb_cur_max());
|
||||
int s1_mb_len, s2_mb_len;
|
||||
wchar_t ws1, ws2;
|
||||
|
||||
while (n > 0 && *s1 != '\0' && *s2 != '\0') {
|
||||
s1_mb_len = parse_mbchar(s1, s1_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (mbtowc(&ws1, s1_mb, s1_mb_len) <= 0) {
|
||||
mbtowc(NULL, NULL, 0);
|
||||
ws1 = (unsigned char)*s1_mb;
|
||||
}
|
||||
|
||||
s2_mb_len = parse_mbchar(s2, s2_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (mbtowc(&ws2, s2_mb, s2_mb_len) <= 0) {
|
||||
mbtowc(NULL, NULL, 0);
|
||||
ws2 = (unsigned char)*s2_mb;
|
||||
}
|
||||
|
||||
if (s1_mb_len > n || towlower(ws1) != towlower(ws2))
|
||||
break;
|
||||
|
||||
s1 += s1_mb_len;
|
||||
s2 += s2_mb_len;
|
||||
n -= s1_mb_len;
|
||||
}
|
||||
|
||||
free(s1_mb);
|
||||
free(s2_mb);
|
||||
|
||||
return (towlower(ws1) - towlower(ws2));
|
||||
} else
|
||||
#endif
|
||||
return
|
||||
#ifdef HAVE_STRNCASECMP
|
||||
strncasecmp(s1, s2, n);
|
||||
#else
|
||||
nstrncasecmp(s1, s2, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
/* This function is equivalent to strcasestr(). It was adapted from
|
||||
* mutt's mutt_stristr() function. */
|
||||
const char *nstrcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL);
|
||||
|
||||
for (; *haystack != '\0'; haystack++) {
|
||||
const char *p = haystack, *q = needle;
|
||||
|
||||
for (; tolower(*p) == tolower(*q) && *q != '\0'; p++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return haystack;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* None of this is needed if we're using NANO_SMALL! */
|
||||
#ifndef NANO_SMALL
|
||||
const char *revstrstr(const char *haystack, const char *needle, const
|
||||
char *rev_start)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL && rev_start != NULL);
|
||||
|
||||
for (; rev_start >= haystack; rev_start--) {
|
||||
const char *r, *q;
|
||||
|
||||
for (r = rev_start, q = needle; *q == *r && *q != '\0'; r++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return rev_start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *revstrcasestr(const char *haystack, const char *needle,
|
||||
const char *rev_start)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL && rev_start != NULL);
|
||||
|
||||
for (; rev_start >= haystack; rev_start--) {
|
||||
const char *r = rev_start, *q = needle;
|
||||
|
||||
for (; tolower(*q) == tolower(*r) && *q != '\0'; r++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return rev_start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
#ifndef HAVE_STRNLEN
|
||||
/* This function is equivalent to strnlen(). */
|
||||
size_t nstrnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
|
||||
;
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function is equivalent to strnlen() for multibyte strings. */
|
||||
size_t mbstrnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
assert(s != NULL);
|
||||
|
||||
#ifdef NANO_WIDE
|
||||
if (!ISSET(NO_UTF8)) {
|
||||
size_t n = 0;
|
||||
char *s_mb = charalloc(mb_cur_max());
|
||||
int s_mb_len;
|
||||
|
||||
while (*s != '\0') {
|
||||
s_mb_len = parse_mbchar(s + n, s_mb
|
||||
#ifdef NANO_WIDE
|
||||
, NULL
|
||||
#endif
|
||||
, NULL);
|
||||
|
||||
if (s_mb_len > maxlen)
|
||||
break;
|
||||
|
||||
maxlen -= s_mb_len;
|
||||
n += s_mb_len;
|
||||
}
|
||||
|
||||
free(s_mb);
|
||||
|
||||
return n;
|
||||
} else
|
||||
#endif
|
||||
return
|
||||
#ifdef HAVE_STRNLEN
|
||||
strnlen(s, maxlen);
|
||||
#else
|
||||
nstrnlen(s, maxlen);
|
||||
#endif
|
||||
}
|
||||
|
|
22
src/nano.h
22
src/nano.h
|
@ -89,23 +89,19 @@
|
|||
#include <sys/stat.h>
|
||||
#include "config.h"
|
||||
|
||||
/* If no snprintf()/vsnprintf(), use the versions from glib. */
|
||||
/* If no snprintf() or vsnprintf(), use the versions from glib. */
|
||||
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
|
||||
#include <glib.h>
|
||||
# ifndef HAVE_SNPRINTF
|
||||
# define snprintf g_snprintf
|
||||
# endif
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define vsnprintf g_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If no strcasecmp(), strncasecmp(), strcasestr(), getdelim(), or
|
||||
* getline(), use the versions we have. */
|
||||
#ifndef HAVE_STRCASECMP
|
||||
#define strcasecmp nstricmp
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#define snprintf g_snprintf
|
||||
#endif
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
#define vsnprintf g_vsnprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If no strcasestr(), getdelim(), or getline(), use the versions we
|
||||
* have. */
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
#define strncasecmp nstrnicmp
|
||||
#endif
|
||||
|
|
40
src/proto.h
40
src/proto.h
|
@ -166,10 +166,6 @@ bool is_cntrl_mbchar(const char *c);
|
|||
#ifdef NANO_WIDE
|
||||
bool is_cntrl_wchar(wchar_t wc);
|
||||
#endif
|
||||
#ifndef HAVE_STRNLEN
|
||||
size_t nstrnlen(const char *s, size_t maxlen);
|
||||
#endif
|
||||
size_t mbstrnlen(const char *s, size_t maxlen);
|
||||
unsigned char control_rep(unsigned char c);
|
||||
char *control_mbrep(const char *c, char *crep, int *crep_len);
|
||||
#ifdef NANO_WIDE
|
||||
|
@ -185,6 +181,27 @@ int parse_mbchar(const char *buf, char *chr
|
|||
, size_t *col);
|
||||
size_t move_mbleft(const char *buf, size_t pos);
|
||||
size_t move_mbright(const char *buf, size_t pos);
|
||||
#ifndef HAVE_STRCASECMP
|
||||
int nstrcasecmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
int mbstrcasecmp(const char *s1, const char *s2);
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
int nstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
int mbstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#ifndef HAVE_STRCASESTR
|
||||
const char *nstrcasestr(const char *haystack, const char *needle);
|
||||
#endif
|
||||
#ifndef NANO_SMALL
|
||||
const char *revstrstr(const char *haystack, const char *needle, const
|
||||
char *rev_start);
|
||||
const char *revstrcasestr(const char *haystack, const char *needle, const
|
||||
char *rev_start);
|
||||
#endif
|
||||
#ifndef HAVE_STRNLEN
|
||||
size_t nstrnlen(const char *s, size_t maxlen);
|
||||
#endif
|
||||
size_t mbstrnlen(const char *s, size_t maxlen);
|
||||
|
||||
/* Public functions in color.c. */
|
||||
#ifdef ENABLE_COLOR
|
||||
|
@ -513,21 +530,6 @@ void align(char **strp);
|
|||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
#ifndef HAVE_STRCASECMP
|
||||
int nstricmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
int nstrnicmp(const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
#ifndef HAVE_STRCASESTR
|
||||
const char *nstristr(const char *haystack, const char *needle);
|
||||
#endif
|
||||
#ifndef NANO_SMALL
|
||||
const char *revstrstr(const char *haystack, const char *needle, const
|
||||
char *rev_start);
|
||||
const char *revstristr(const char *haystack, const char *needle, const
|
||||
char *rev_start);
|
||||
#endif
|
||||
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
||||
#ifndef HAVE_GETLINE
|
||||
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream);
|
||||
|
|
95
src/utils.c
95
src/utils.c
|
@ -131,99 +131,6 @@ void sunder(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
/* This function is equivalent to strcasecmp(). */
|
||||
int nstricmp(const char *s1, const char *s2)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
|
||||
if (tolower(*s1) != tolower(*s2))
|
||||
break;
|
||||
}
|
||||
|
||||
return (tolower(*s1) - tolower(*s2));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
/* This function is equivalent to strncasecmp(). */
|
||||
int nstrnicmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
assert(s1 != NULL && s2 != NULL);
|
||||
|
||||
for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
|
||||
if (tolower(*s1) != tolower(*s2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
return (tolower(*s1) - tolower(*s2));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASESTR
|
||||
/* This function is equivalent to strcasestr(). It was adapted from
|
||||
* mutt's mutt_stristr() function. */
|
||||
const char *nstristr(const char *haystack, const char *needle)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL);
|
||||
|
||||
for (; *haystack != '\0'; haystack++) {
|
||||
const char *p = haystack, *q = needle;
|
||||
|
||||
for (; tolower(*p) == tolower(*q) && *q != '\0'; p++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return haystack;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* None of this is needed if we're using NANO_SMALL! */
|
||||
#ifndef NANO_SMALL
|
||||
const char *revstrstr(const char *haystack, const char *needle, const
|
||||
char *rev_start)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL && rev_start != NULL);
|
||||
|
||||
for (; rev_start >= haystack; rev_start--) {
|
||||
const char *r, *q;
|
||||
|
||||
for (r = rev_start, q = needle; *q == *r && *q != '\0'; r++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return rev_start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *revstristr(const char *haystack, const char *needle, const
|
||||
char *rev_start)
|
||||
{
|
||||
assert(haystack != NULL && needle != NULL && rev_start != NULL);
|
||||
|
||||
for (; rev_start >= haystack; rev_start--) {
|
||||
const char *r = rev_start, *q = needle;
|
||||
|
||||
for (; tolower(*q) == tolower(*r) && *q != '\0'; r++, q++)
|
||||
;
|
||||
|
||||
if (*q == '\0')
|
||||
return rev_start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !NANO_SMALL */
|
||||
|
||||
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
||||
#ifndef HAVE_GETLINE
|
||||
/* This function is equivalent to getline(). It was adapted from
|
||||
|
@ -341,7 +248,7 @@ const char *strstrwrapper(const char *haystack, const char *needle,
|
|||
#endif /* !DISABLE_SPELLER || !NANO_SMALL */
|
||||
#ifndef NANO_SMALL
|
||||
else if (ISSET(REVERSE_SEARCH))
|
||||
return revstristr(haystack, needle, start);
|
||||
return revstrcasestr(haystack, needle, start);
|
||||
#endif
|
||||
return strcasestr(start, needle);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue