本文通过配置busybox来实现arm终端(debug serial)对中文的支持,无需修内核,无需修改busybox源码。
1. ls函数调用过程
main->lbb_main->parse_config_file->find_applet_by_name->applet_main->ls_main->showdirs->list_dir->showfiles->list_single->print_name->printable_string->unicode_conv_to_printable->unicode_conv_to_printable2
由以上过程的分析可知,对中文的支持是通过unicode_conv_to_printable2。
2. unicode_conv_to_printable2
static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats,const char *src, unsigned width, int flags)
{
char *dst;
unsigned dst_len;
unsigned uni_count;
unsigned uni_width;
if(unicode_status != UNICODE_ON) {
char *d;
if (flags &UNI_FLAG_PAD) {
d = dst= xmalloc(width + 1);
while((int)--width >= 0) {
unsignedchar c = *src;
if(c == '') {
do
*d++= ' ';
while((int)--width >= 0);
break;
}
*d++= (c >= ' ' && c < 0x7f) ? c : '?';
src++;
}
*d ='';
} else {
d = dst= xstrndup(src, width);
while(*d) {
unsignedchar c = *d;
if(c < ' ' || c >= 0x7f)
*d = '?';
d++;
}
}
if (stats) {
stats->byte_count= (d - dst);
stats->unicode_count= (d - dst);
stats->unicode_width= (d - dst);
}
return dst;
}
dst = NULL;
uni_count = uni_width = 0;
dst_len = 0;
while (1) {
int w;
wchar_t wc;
#if ENABLE_UNICODE_USING_LOCALE
{
mbstate_t mbst = { 0 };
ssize_trc = mbsrtowcs(&wc, &src, 1, &mbst);
/* Ifinvalid sequence is seen: -1 is returned,
* src points to the invalid sequence, errno =EILSEQ.
* Else number of wchars (excluding terminatingL'')
* written to dest is returned.
* If len (here: 1) non-L'' wchars stored atdest,
* src points to the next char to be converted.
* If string is completely converted: src =NULL.
*/
if (rc== 0) /* end-of-string */
break;
if (rc <0) { /* error */
src++;
gotosubst;
}
if(!iswprint(wc))
gotosubst;
}
#else
src =mbstowc_internal(&wc, src);
/* src isadvanced to next mb char
* wc == ERROR_WCHAR: invalid sequence is seen
* else: wc is set
*/
if (wc ==ERROR_WCHAR) /* error */
gotosubst;
if (wc == 0) /*end-of-string */
break;
#endif
if(CONFIG_LAST_SUPPORTED_WCHAR && wc >CONFIG_LAST_SUPPORTED_WCHAR)
gotosubst;
w = wcwidth(wc);
if((ENABLE_UNICODE_COMBINING_WCHARS && w < 0) /* non-printable wchar*/
|| (!ENABLE_UNICODE_COMBINING_WCHARS&& w <= 0)
|| (!ENABLE_UNICODE_WIDE_WCHARS&& w > 1)
) {
subst:
wc =CONFIG_SUBST_WCHAR;
w = 1;
}
width -= w;
/* Note: if width== 0, we still may add more chars,
* they may be zero-width or combining ones */
if ((int)width< 0) {
/* can'tadd this wc, string would become longer than width */
width +=w;
break;
}
uni_count++;
uni_width += w;
dst =xrealloc(dst, dst_len + MB_CUR_MAX);
#if ENABLE_UNICODE_USING_LOCALE
{
mbstate_tmbst = { 0 };
dst_len+= wcrtomb(&dst[dst_len], wc, &mbst);
}
#else
dst_len +=wcrtomb_internal(&dst[dst_len], wc);
#endif
}
/* Pad to remaining width*/
if (flags &UNI_FLAG_PAD) {
dst =xrealloc(dst, dst_len + width + 1);
uni_count +=width;
uni_width +=width;
while((int)--width >= 0) {
dst[dst_len++]= ' ';
}
}
dst[dst_len] = '';
if (stats) {
stats->byte_count= dst_len;
stats->unicode_count= uni_count;
stats->unicode_width= uni_width;
}
return dst;
}
需要支持中文,则unicode_status必须为UNICODE_ON。
实现中文有两种方式,ENABLE_UNICODE_USING_LOCALE,则通过内核本地化实现支持。
!ENABLE_UNICODE_USING_LOCALE,则通过busybox实现对中文的支持。
3. unicode_status
#ifENABLE_UNICODE_USING_LOCALE
/* Unicode support using libc localesupport. */
void FAST_FUNC init_unicode(void)
{
staticconst char unicode_0x394[] = { 0xce, 0x94, 0 };
size_twidth;
if(unicode_status != UNICODE_UNKNOWN)
return;
/*In unicode, this is a one character string */
// can use unicode_strlen(string) too, butotherwise unicode_strlen() is unused
width= mbstowcs(NULL, unicode_0x394, INT_MAX);
unicode_status= (width == 1 ? UNICODE_ON : UNICODE_OFF);
}
#else
/* Homegrown Unicode support. It knows onlyC and Unicode locales. */
# if ENABLE_FEATURE_CHECK_UNICODE_IN_ENV
void FAST_FUNC init_unicode(void)
{
char*lang;
if(unicode_status != UNICODE_UNKNOWN)
return;
unicode_status= UNICODE_OFF;
lang= getenv("LANG");
if(!lang || !(strstr(lang, ".utf") || strstr(lang, ".UTF")))
return;
unicode_status= UNICODE_ON;
}
# endif
………..
#endif
本由于我的内核不支持中文,因此采用rootfs实现。即!ENABLE_UNICODE_USING_LOCALE
和ENABLE_FEATURE_CHECK_UNICODE_IN_ENV,同时设置环境变量export LANG=zh_CN.UTF-8
4 配置
Busybox Settings --->
GeneralConfiguration --->
[] Enable locale support (system needs locale for this to work)
[*] SupportUnicode
[*] Check $LANG environment variable
(63) Character code to substitute unprintablecharacters with
(40907) Range of supported Unicode characters
[] Allow zero-width Unicode characterson output
[*] Allow wide Unicode characters on output
[] Bidirectional character-aware lineinput
Support Unicode:中文是通过unicode实现的。
Check $LANG environmentvariable:检查环境变量LANG选择unicode_status = UNICODE_ON。
Range of supportedUnicode characters默认767,汉字unicode编码范围到2FA1D,需要修改。
Allow wide Unicodecharacters on output:中文需要宽字的支持。
最后
以上就是幸福紫菜最近收集整理的关于busybox对arm终端中文的支持的全部内容,更多相关busybox对arm终端中文内容请搜索靠谱客的其他文章。
发表评论 取消回复