1664 |
program_name, p, q); |
program_name, p, q); |
1665 |
} |
} |
1666 |
|
|
1667 |
|
/* mb_icase_keys() is called by main() to convert its "keys" string with |
1668 |
|
strlen() "len" to lowercase if match_icase is true. Pointers are used |
1669 |
|
to implement in-out call-by-reference parameters. */ |
1670 |
|
#ifdef MBS_SUPPORT |
1671 |
|
static void |
1672 |
|
mb_icase_keys (char **keys, size_t *len) |
1673 |
|
{ |
1674 |
|
wchar_t wc; |
1675 |
|
mbstate_t sti, stj; /* i for input/old, j for output/new. */ |
1676 |
|
size_t i, j, li, lj; /* l for total string length (minus '\0'). */ |
1677 |
|
char *ki, *kj; /* k for keys. */ |
1678 |
|
int mcm; |
1679 |
|
|
1680 |
|
if ((mcm = MB_CUR_MAX) == 1) |
1681 |
|
return; |
1682 |
|
|
1683 |
|
li = *len; |
1684 |
|
ki = *keys; |
1685 |
|
/* We use a new buffer because some multi-octet characters change |
1686 |
|
length through a lower-case conversion. For example: |
1687 |
|
len(U+0049)=1 --> len(U+0131)=2 under tr_TR.UTF-8 |
1688 |
|
len(U+0130)=2 --> len(U+0069)=1 under en_US.UTF-8 |
1689 |
|
len(U+2126)=3 --> len(U+03C9)=2 under en_US.UTF-8 |
1690 |
|
len(U+212A)=3 --> len(U+006B)=1 under en_US.UTF-8 |
1691 |
|
len(U+212B)=3 --> len(U+00E5)=2 under en_US.UTF-8 */ |
1692 |
|
lj = li + mcm; |
1693 |
|
kj = xmalloc(lj + 1); |
1694 |
|
|
1695 |
|
memset(&sti, 0, sizeof(mbstate_t)); |
1696 |
|
memset(&stj, 0, sizeof(mbstate_t)); |
1697 |
|
for (i = j = 0; i < li ;) |
1698 |
|
{ |
1699 |
|
size_t mbclen; |
1700 |
|
mbclen = mbrtowc(&wc, ki + i, li - i, &sti); |
1701 |
|
if (lj < j + mcm) |
1702 |
|
{ |
1703 |
|
lj += mcm; |
1704 |
|
kj = xrealloc(kj, lj + 1); |
1705 |
|
} |
1706 |
|
if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0) |
1707 |
|
{ |
1708 |
|
/* An invalid sequence, or a truncated multi-octet character. |
1709 |
|
We treat it as a single-octet character. */ |
1710 |
|
kj[j++] = ki[i++]; |
1711 |
|
} |
1712 |
|
else |
1713 |
|
{ |
1714 |
|
/* Doing towupper() before towlower() helps a few hairy cases and is |
1715 |
|
not too costly since this is the PATTERN and is done only once. */ |
1716 |
|
wc = towupper((wint_t)wc); |
1717 |
|
wc = towlower((wint_t)wc); |
1718 |
|
j += wcrtomb(kj + j, wc, &stj); |
1719 |
|
i += mbclen; |
1720 |
|
} |
1721 |
|
} |
1722 |
|
kj[j] = '\0'; |
1723 |
|
|
1724 |
|
free(ki); |
1725 |
|
*keys = kj; |
1726 |
|
*len = j; |
1727 |
|
} |
1728 |
|
#endif /* MBS_SUPPORT */ |
1729 |
|
|
1730 |
int |
int |
1731 |
main (int argc, char **argv) |
main (int argc, char **argv) |
1732 |
{ |
{ |
2163 |
abort (); |
abort (); |
2164 |
|
|
2165 |
#ifdef MBS_SUPPORT |
#ifdef MBS_SUPPORT |
2166 |
if (MB_CUR_MAX != 1 && match_icase) |
if (match_icase) |
2167 |
{ |
mb_icase_keys (&keys, &keycc); |
|
wchar_t wc; |
|
|
mbstate_t cur_state, prev_state; |
|
|
int i, len = strlen(keys); |
|
|
|
|
|
memset(&cur_state, 0, sizeof(mbstate_t)); |
|
|
for (i = 0; i <= len ;) |
|
|
{ |
|
|
size_t mbclen; |
|
|
mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state); |
|
|
if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0) |
|
|
{ |
|
|
/* An invalid sequence, or a truncated multibyte character. |
|
|
We treat it as a single byte character. */ |
|
|
mbclen = 1; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (iswupper((wint_t)wc)) |
|
|
{ |
|
|
wc = towlower((wint_t)wc); |
|
|
wcrtomb(keys + i, wc, &cur_state); |
|
|
} |
|
|
} |
|
|
i += mbclen; |
|
|
} |
|
|
} |
|
2168 |
#endif /* MBS_SUPPORT */ |
#endif /* MBS_SUPPORT */ |
2169 |
|
|
2170 |
(*compile)(keys, keycc); |
(*compile)(keys, keycc); |