Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <newlib.h>
  2. #include <stdlib.h>
  3. #include <locale.h>
  4. #include "mbctype.h"
  5. #include <wchar.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include "local.h"
  9.  
  10. int (*__mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
  11.                  const char *, mbstate_t *)
  12. #ifdef __CYGWIN__
  13.    /* Cygwin starts up in UTF-8 mode. */
  14.    = __utf8_mbtowc;
  15. #else
  16.    = __ascii_mbtowc;
  17. #endif
  18.  
  19. int
  20. _DEFUN (_mbtowc_r, (r, pwc, s, n, state),
  21.         struct _reent *r   _AND
  22.         wchar_t       *pwc _AND
  23.         const char    *s   _AND        
  24.         size_t         n   _AND
  25.         mbstate_t      *state)
  26. {
  27.   return __mbtowc (r, pwc, s, n, __locale_charset (), state);
  28. }
  29.  
  30. int
  31. _DEFUN (__ascii_mbtowc, (r, pwc, s, n, charset, state),
  32.         struct _reent *r       _AND
  33.         wchar_t       *pwc     _AND
  34.         const char    *s       _AND        
  35.         size_t         n       _AND
  36.         const char    *charset _AND
  37.         mbstate_t      *state)
  38. {
  39.   wchar_t dummy;
  40.   unsigned char *t = (unsigned char *)s;
  41.  
  42.   if (pwc == NULL)
  43.     pwc = &dummy;
  44.  
  45.   if (s == NULL)
  46.     return 0;
  47.  
  48.   if (n == 0)
  49.     return -2;
  50.  
  51. #ifdef __CYGWIN__
  52.   if ((wchar_t)*t >= 0x80)
  53.     {
  54.       r->_errno = EILSEQ;
  55.       return -1;
  56.     }
  57. #endif
  58.  
  59.   *pwc = (wchar_t)*t;
  60.  
  61.   if (*t == '\0')
  62.     return 0;
  63.  
  64.   return 1;
  65. }
  66.  
  67. #ifdef _MB_CAPABLE
  68. typedef enum { ESCAPE, DOLLAR, BRACKET, AT, B, J,
  69.                NUL, JIS_CHAR, OTHER, JIS_C_NUM } JIS_CHAR_TYPE;
  70. typedef enum { ASCII, JIS, A_ESC, A_ESC_DL, JIS_1, J_ESC, J_ESC_BR,
  71.                INV, JIS_S_NUM } JIS_STATE;
  72. typedef enum { COPY_A, COPY_J1, COPY_J2, MAKE_A, NOOP, EMPTY, ERROR } JIS_ACTION;
  73.  
  74. /**************************************************************************************
  75.  * state/action tables for processing JIS encoding
  76.  * Where possible, switches to JIS are grouped with proceding JIS characters and switches
  77.  * to ASCII are grouped with preceding JIS characters.  Thus, maximum returned length
  78.  * is 2 (switch to JIS) + 2 (JIS characters) + 2 (switch back to ASCII) = 6.
  79.  *************************************************************************************/
  80.  
  81. static JIS_STATE JIS_state_table[JIS_S_NUM][JIS_C_NUM] = {
  82. /*              ESCAPE   DOLLAR    BRACKET   AT       B       J        NUL      JIS_CHAR  OTHER */
  83. /* ASCII */   { A_ESC,   ASCII,    ASCII,    ASCII,   ASCII,  ASCII,   ASCII,   ASCII,    ASCII },
  84. /* JIS */     { J_ESC,   JIS_1,    JIS_1,    JIS_1,   JIS_1,  JIS_1,   INV,     JIS_1,    INV },
  85. /* A_ESC */   { ASCII,   A_ESC_DL, ASCII,    ASCII,   ASCII,  ASCII,   ASCII,   ASCII,    ASCII },
  86. /* A_ESC_DL */{ ASCII,   ASCII,    ASCII,    JIS,     JIS,    ASCII,   ASCII,   ASCII,    ASCII },
  87. /* JIS_1 */   { INV,     JIS,      JIS,      JIS,     JIS,    JIS,     INV,     JIS,      INV },
  88. /* J_ESC */   { INV,     INV,      J_ESC_BR, INV,     INV,    INV,     INV,     INV,      INV },
  89. /* J_ESC_BR */{ INV,     INV,      INV,      INV,     ASCII,  ASCII,   INV,     INV,      INV },
  90. };
  91.  
  92. static JIS_ACTION JIS_action_table[JIS_S_NUM][JIS_C_NUM] = {
  93. /*              ESCAPE   DOLLAR    BRACKET   AT       B        J        NUL      JIS_CHAR  OTHER */
  94. /* ASCII */   { NOOP,    COPY_A,   COPY_A,   COPY_A,  COPY_A,  COPY_A,  EMPTY,   COPY_A,  COPY_A},
  95. /* JIS */     { NOOP,    COPY_J1,  COPY_J1,  COPY_J1, COPY_J1, COPY_J1, ERROR,   COPY_J1, ERROR },
  96. /* A_ESC */   { COPY_A,  NOOP,     COPY_A,   COPY_A,  COPY_A,  COPY_A,  COPY_A,  COPY_A,  COPY_A},
  97. /* A_ESC_DL */{ COPY_A,  COPY_A,   COPY_A,   NOOP,    NOOP,    COPY_A,  COPY_A,  COPY_A,  COPY_A},
  98. /* JIS_1 */   { ERROR,   COPY_J2,  COPY_J2,  COPY_J2, COPY_J2, COPY_J2, ERROR,   COPY_J2, ERROR },
  99. /* J_ESC */   { ERROR,   ERROR,    NOOP,     ERROR,   ERROR,   ERROR,   ERROR,   ERROR,   ERROR },
  100. /* J_ESC_BR */{ ERROR,   ERROR,    ERROR,    ERROR,   MAKE_A,  MAKE_A,  ERROR,   ERROR,   ERROR },
  101. };
  102.  
  103. /* we override the mbstate_t __count field for more complex encodings and use it store a state value */
  104. #define __state __count
  105.  
  106. #ifdef _MB_EXTENDED_CHARSETS_ISO
  107. int
  108. _DEFUN (__iso_mbtowc, (r, pwc, s, n, charset, state),
  109.         struct _reent *r       _AND
  110.         wchar_t       *pwc     _AND
  111.         const char    *s       _AND        
  112.         size_t         n       _AND
  113.         const char    *charset _AND
  114.         mbstate_t      *state)
  115. {
  116.   wchar_t dummy;
  117.   unsigned char *t = (unsigned char *)s;
  118.  
  119.   if (pwc == NULL)
  120.     pwc = &dummy;
  121.  
  122.   if (s == NULL)
  123.     return 0;
  124.  
  125.   if (n == 0)
  126.     return -2;
  127.  
  128.   if (*t >= 0xa0)
  129.     {
  130.       int iso_idx = __iso_8859_index (charset + 9);
  131.       if (iso_idx >= 0)
  132.         {
  133.           *pwc = __iso_8859_conv[iso_idx][*t - 0xa0];
  134.           if (*pwc == 0) /* Invalid character */
  135.             {
  136.               r->_errno = EILSEQ;
  137.               return -1;
  138.             }
  139.           return 1;
  140.         }
  141.     }
  142.  
  143.   *pwc = (wchar_t) *t;
  144.  
  145.   if (*t == '\0')
  146.     return 0;
  147.  
  148.   return 1;
  149. }
  150. #endif /* _MB_EXTENDED_CHARSETS_ISO */
  151.  
  152. #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
  153. int
  154. _DEFUN (__cp_mbtowc, (r, pwc, s, n, charset, state),
  155.         struct _reent *r       _AND
  156.         wchar_t       *pwc     _AND
  157.         const char    *s       _AND        
  158.         size_t         n       _AND
  159.         const char    *charset _AND
  160.         mbstate_t      *state)
  161. {
  162.   wchar_t dummy;
  163.   unsigned char *t = (unsigned char *)s;
  164.  
  165.   if (pwc == NULL)
  166.     pwc = &dummy;
  167.  
  168.   if (s == NULL)
  169.     return 0;
  170.  
  171.   if (n == 0)
  172.     return -2;
  173.  
  174.   if (*t >= 0x80)
  175.     {
  176.       int cp_idx = __cp_index (charset + 2);
  177.       if (cp_idx >= 0)
  178.         {
  179.           *pwc = __cp_conv[cp_idx][*t - 0x80];
  180.           if (*pwc == 0) /* Invalid character */
  181.             {
  182.               r->_errno = EILSEQ;
  183.               return -1;
  184.             }
  185.           return 1;
  186.         }
  187.     }
  188.  
  189.   *pwc = (wchar_t)*t;
  190.  
  191.   if (*t == '\0')
  192.     return 0;
  193.  
  194.   return 1;
  195. }
  196. #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
  197.  
  198. int
  199. _DEFUN (__utf8_mbtowc, (r, pwc, s, n, charset, state),
  200.         struct _reent *r       _AND
  201.         wchar_t       *pwc     _AND
  202.         const char    *s       _AND        
  203.         size_t         n       _AND
  204.         const char    *charset _AND
  205.         mbstate_t      *state)
  206. {
  207.   wchar_t dummy;
  208.   unsigned char *t = (unsigned char *)s;
  209.   int ch;
  210.   int i = 0;
  211.  
  212.   if (pwc == NULL)
  213.     pwc = &dummy;
  214.  
  215.   if (s == NULL)
  216.     return 0;
  217.  
  218.   if (n == 0)
  219.     return -2;
  220.  
  221.   if (state->__count == 0)
  222.     ch = t[i++];
  223.   else
  224.     ch = state->__value.__wchb[0];
  225.  
  226.   if (ch == '\0')
  227.     {
  228.       *pwc = 0;
  229.       state->__count = 0;
  230.       return 0; /* s points to the null character */
  231.     }
  232.  
  233.   if (ch <= 0x7f)
  234.     {
  235.       /* single-byte sequence */
  236.       state->__count = 0;
  237.       *pwc = ch;
  238.       return 1;
  239.     }
  240.   if (ch >= 0xc0 && ch <= 0xdf)
  241.     {
  242.       /* two-byte sequence */
  243.       state->__value.__wchb[0] = ch;
  244.       if (state->__count == 0)
  245.         state->__count = 1;
  246.       else if (n < (size_t)-1)
  247.         ++n;
  248.       if (n < 2)
  249.         return -2;
  250.       ch = t[i++];
  251.       if (ch < 0x80 || ch > 0xbf)
  252.         {
  253.           r->_errno = EILSEQ;
  254.           return -1;
  255.         }
  256.       if (state->__value.__wchb[0] < 0xc2)
  257.         {
  258.           /* overlong UTF-8 sequence */
  259.           r->_errno = EILSEQ;
  260.           return -1;
  261.         }
  262.       state->__count = 0;
  263.       *pwc = (wchar_t)((state->__value.__wchb[0] & 0x1f) << 6)
  264.         |    (wchar_t)(ch & 0x3f);
  265.       return i;
  266.     }
  267.   if (ch >= 0xe0 && ch <= 0xef)
  268.     {
  269.       /* three-byte sequence */
  270.       wchar_t tmp;
  271.       state->__value.__wchb[0] = ch;
  272.       if (state->__count == 0)
  273.         state->__count = 1;
  274.       else if (n < (size_t)-1)
  275.         ++n;
  276.       if (n < 2)
  277.         return -2;
  278.       ch = (state->__count == 1) ? t[i++] : state->__value.__wchb[1];
  279.       if (state->__value.__wchb[0] == 0xe0 && ch < 0xa0)
  280.         {
  281.           /* overlong UTF-8 sequence */
  282.           r->_errno = EILSEQ;
  283.           return -1;
  284.         }
  285.       if (ch < 0x80 || ch > 0xbf)
  286.         {
  287.           r->_errno = EILSEQ;
  288.           return -1;
  289.         }
  290.       state->__value.__wchb[1] = ch;
  291.       if (state->__count == 1)
  292.         state->__count = 2;
  293.       else if (n < (size_t)-1)
  294.         ++n;
  295.       if (n < 3)
  296.         return -2;
  297.       ch = t[i++];
  298.       if (ch < 0x80 || ch > 0xbf)
  299.         {
  300.           r->_errno = EILSEQ;
  301.           return -1;
  302.         }
  303.       state->__count = 0;
  304.       tmp = (wchar_t)((state->__value.__wchb[0] & 0x0f) << 12)
  305.         |    (wchar_t)((state->__value.__wchb[1] & 0x3f) << 6)
  306.         |     (wchar_t)(ch & 0x3f);
  307.       *pwc = tmp;
  308.       return i;
  309.     }
  310.   if (ch >= 0xf0 && ch <= 0xf4)
  311.     {
  312.       /* four-byte sequence */
  313.       wint_t tmp;
  314.       state->__value.__wchb[0] = ch;
  315.       if (state->__count == 0)
  316.         state->__count = 1;
  317.       else if (n < (size_t)-1)
  318.         ++n;
  319.       if (n < 2)
  320.         return -2;
  321.       ch = (state->__count == 1) ? t[i++] : state->__value.__wchb[1];
  322.       if ((state->__value.__wchb[0] == 0xf0 && ch < 0x90)
  323.           || (state->__value.__wchb[0] == 0xf4 && ch >= 0x90))
  324.         {
  325.           /* overlong UTF-8 sequence or result is > 0x10ffff */
  326.           r->_errno = EILSEQ;
  327.           return -1;
  328.         }
  329.       if (ch < 0x80 || ch > 0xbf)
  330.         {
  331.           r->_errno = EILSEQ;
  332.           return -1;
  333.         }
  334.       state->__value.__wchb[1] = ch;
  335.       if (state->__count == 1)
  336.         state->__count = 2;
  337.       else if (n < (size_t)-1)
  338.         ++n;
  339.       if (n < 3)
  340.         return -2;
  341.       ch = (state->__count == 2) ? t[i++] : state->__value.__wchb[2];
  342.       if (ch < 0x80 || ch > 0xbf)
  343.         {
  344.           r->_errno = EILSEQ;
  345.           return -1;
  346.         }
  347.       state->__value.__wchb[2] = ch;
  348.       if (state->__count == 2)
  349.         state->__count = 3;
  350.       else if (n < (size_t)-1)
  351.         ++n;
  352.       if (state->__count == 3 && sizeof(wchar_t) == 2)
  353.         {
  354.           /* On systems which have wchar_t being UTF-16 values, the value
  355.              doesn't fit into a single wchar_t in this case.  So what we
  356.              do here is to store the state with a special value of __count
  357.              and return the first half of a surrogate pair.  The first
  358.              three bytes of a UTF-8 sequence are enough to generate the
  359.              first half of a UTF-16 surrogate pair.  As return value we
  360.              choose to return the number of bytes actually read up to
  361.              here.
  362.              The second half of the surrogate pair is returned in case we
  363.              recognize the special __count value of four, and the next
  364.              byte is actually a valid value.  See below. */
  365.           tmp = (wint_t)((state->__value.__wchb[0] & 0x07) << 18)
  366.             |   (wint_t)((state->__value.__wchb[1] & 0x3f) << 12)
  367.             |   (wint_t)((state->__value.__wchb[2] & 0x3f) << 6);
  368.           state->__count = 4;
  369.           *pwc = 0xd800 | ((tmp - 0x10000) >> 10);
  370.           return i;
  371.         }
  372.       if (n < 4)
  373.         return -2;
  374.       ch = t[i++];
  375.       if (ch < 0x80 || ch > 0xbf)
  376.         {
  377.           r->_errno = EILSEQ;
  378.           return -1;
  379.         }
  380.       tmp = (wint_t)((state->__value.__wchb[0] & 0x07) << 18)
  381.         |   (wint_t)((state->__value.__wchb[1] & 0x3f) << 12)
  382.         |   (wint_t)((state->__value.__wchb[2] & 0x3f) << 6)
  383.         |   (wint_t)(ch & 0x3f);
  384.       if (state->__count == 4 && sizeof(wchar_t) == 2)
  385.         /* Create the second half of the surrogate pair for systems with
  386.            wchar_t == UTF-16 . */
  387.         *pwc = 0xdc00 | (tmp & 0x3ff);
  388.       else
  389.         *pwc = tmp;
  390.       state->__count = 0;
  391.       return i;
  392.     }
  393.  
  394.   r->_errno = EILSEQ;
  395.   return -1;
  396. }
  397.  
  398. /* Cygwin defines its own doublebyte charset conversion functions
  399.    because the underlying OS requires wchar_t == UTF-16. */
  400. #ifndef  __CYGWIN__
  401. int
  402. _DEFUN (__sjis_mbtowc, (r, pwc, s, n, charset, state),
  403.         struct _reent *r       _AND
  404.         wchar_t       *pwc     _AND
  405.         const char    *s       _AND        
  406.         size_t         n       _AND
  407.         const char    *charset _AND
  408.         mbstate_t      *state)
  409. {
  410.   wchar_t dummy;
  411.   unsigned char *t = (unsigned char *)s;
  412.   int ch;
  413.   int i = 0;
  414.  
  415.   if (pwc == NULL)
  416.     pwc = &dummy;
  417.  
  418.   if (s == NULL)
  419.     return 0;  /* not state-dependent */
  420.  
  421.   if (n == 0)
  422.     return -2;
  423.  
  424.   ch = t[i++];
  425.   if (state->__count == 0)
  426.     {
  427.       if (_issjis1 (ch))
  428.         {
  429.           state->__value.__wchb[0] = ch;
  430.           state->__count = 1;
  431.           if (n <= 1)
  432.             return -2;
  433.           ch = t[i++];
  434.         }
  435.     }
  436.   if (state->__count == 1)
  437.     {
  438.       if (_issjis2 (ch))
  439.         {
  440.           *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)ch;
  441.           state->__count = 0;
  442.           return i;
  443.         }
  444.       else  
  445.         {
  446.           r->_errno = EILSEQ;
  447.           return -1;
  448.         }
  449.     }
  450.  
  451.   *pwc = (wchar_t)*t;
  452.  
  453.   if (*t == '\0')
  454.     return 0;
  455.  
  456.   return 1;
  457. }
  458.  
  459. int
  460. _DEFUN (__eucjp_mbtowc, (r, pwc, s, n, charset, state),
  461.         struct _reent *r       _AND
  462.         wchar_t       *pwc     _AND
  463.         const char    *s       _AND        
  464.         size_t         n       _AND
  465.         const char    *charset _AND
  466.         mbstate_t      *state)
  467. {
  468.   wchar_t dummy;
  469.   unsigned char *t = (unsigned char *)s;
  470.   int ch;
  471.   int i = 0;
  472.  
  473.   if (pwc == NULL)
  474.     pwc = &dummy;
  475.  
  476.   if (s == NULL)
  477.     return 0;
  478.  
  479.   if (n == 0)
  480.     return -2;
  481.  
  482.   ch = t[i++];
  483.   if (state->__count == 0)
  484.     {
  485.       if (_iseucjp1 (ch))
  486.         {
  487.           state->__value.__wchb[0] = ch;
  488.           state->__count = 1;
  489.           if (n <= 1)
  490.             return -2;
  491.           ch = t[i++];
  492.         }
  493.     }
  494.   if (state->__count == 1)
  495.     {
  496.       if (_iseucjp2 (ch))
  497.         {
  498.           if (state->__value.__wchb[0] == 0x8f)
  499.             {
  500.               state->__value.__wchb[1] = ch;
  501.               state->__count = 2;
  502.               if (n <= i)
  503.                 return -2;
  504.               ch = t[i++];
  505.             }
  506.           else
  507.             {
  508.               *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)ch;
  509.               state->__count = 0;
  510.               return i;
  511.             }
  512.         }
  513.       else
  514.         {
  515.           r->_errno = EILSEQ;
  516.           return -1;
  517.         }
  518.     }
  519.   if (state->__count == 2)
  520.     {
  521.       if (_iseucjp2 (ch))
  522.         {
  523.           *pwc = (((wchar_t)state->__value.__wchb[1]) << 8)
  524.                  + (wchar_t)(ch & 0x7f);
  525.           state->__count = 0;
  526.           return i;
  527.         }
  528.       else
  529.         {
  530.           r->_errno = EILSEQ;
  531.           return -1;
  532.         }
  533.     }
  534.  
  535.   *pwc = (wchar_t)*t;
  536.  
  537.   if (*t == '\0')
  538.     return 0;
  539.  
  540.   return 1;
  541. }
  542.  
  543. int
  544. _DEFUN (__jis_mbtowc, (r, pwc, s, n, charset, state),
  545.         struct _reent *r       _AND
  546.         wchar_t       *pwc     _AND
  547.         const char    *s       _AND        
  548.         size_t         n       _AND
  549.         const char    *charset _AND
  550.         mbstate_t      *state)
  551. {
  552.   wchar_t dummy;
  553.   unsigned char *t = (unsigned char *)s;
  554.   JIS_STATE curr_state;
  555.   JIS_ACTION action;
  556.   JIS_CHAR_TYPE ch;
  557.   unsigned char *ptr;
  558.   unsigned int i;
  559.   int curr_ch;
  560.  
  561.   if (pwc == NULL)
  562.     pwc = &dummy;
  563.  
  564.   if (s == NULL)
  565.     {
  566.       state->__state = ASCII;
  567.       return 1;  /* state-dependent */
  568.     }
  569.  
  570.   if (n == 0)
  571.     return -2;
  572.  
  573.   curr_state = state->__state;
  574.   ptr = t;
  575.  
  576.   for (i = 0; i < n; ++i)
  577.     {
  578.       curr_ch = t[i];
  579.       switch (curr_ch)
  580.         {
  581.         case ESC_CHAR:
  582.           ch = ESCAPE;
  583.           break;
  584.         case '$':
  585.           ch = DOLLAR;
  586.           break;
  587.         case '@':
  588.           ch = AT;
  589.           break;
  590.         case '(':
  591.           ch = BRACKET;
  592.           break;
  593.         case 'B':
  594.           ch = B;
  595.           break;
  596.         case 'J':
  597.           ch = J;
  598.           break;
  599.         case '\0':
  600.           ch = NUL;
  601.           break;
  602.         default:
  603.           if (_isjis (curr_ch))
  604.             ch = JIS_CHAR;
  605.           else
  606.             ch = OTHER;
  607.         }
  608.  
  609.       action = JIS_action_table[curr_state][ch];
  610.       curr_state = JIS_state_table[curr_state][ch];
  611.    
  612.       switch (action)
  613.         {
  614.         case NOOP:
  615.           break;
  616.         case EMPTY:
  617.           state->__state = ASCII;
  618.           *pwc = (wchar_t)0;
  619.           return 0;
  620.         case COPY_A:
  621.           state->__state = ASCII;
  622.           *pwc = (wchar_t)*ptr;
  623.           return (i + 1);
  624.         case COPY_J1:
  625.           state->__value.__wchb[0] = t[i];
  626.           break;
  627.         case COPY_J2:
  628.           state->__state = JIS;
  629.           *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)(t[i]);
  630.           return (i + 1);
  631.         case MAKE_A:
  632.           ptr = (unsigned char *)(t + i + 1);
  633.           break;
  634.         case ERROR:
  635.         default:
  636.           r->_errno = EILSEQ;
  637.           return -1;
  638.         }
  639.  
  640.     }
  641.  
  642.   state->__state = curr_state;
  643.   return -2;  /* n < bytes needed */
  644. }
  645. #endif /* !__CYGWIN__*/
  646. #endif /* _MB_CAPABLE */
  647.