busybox对arm终端中文的支持

本文通过配置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 == '\0') {

                                          do

                                                   *d++= ' ';

                                          while((int)--width >= 0);

                                          break;

                                 }

                                 *d++= (c >= ' ' && c < 0x7f) ? c : '?';

                                 src++;

                       }

                       *d ='\0';

              } 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'\0')

                        * written to dest is returned.

                        * If len (here: 1) non-L'\0' 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] = '\0';

     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中文需要宽字的支持。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值