source: trunk/sys/dietlibc/mbrtowc.c @ 21

Last change on this file since 21 was 1, checked in by alain, 8 years ago

First import

File size: 1.2 KB
Line 
1#include "dietlocale.h"
2#include <wchar.h>
3#include <errno.h>
4
5static mbstate_t internal;
6
7size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) {
8  size_t i;
9  if (!ps) ps=&internal;
10  if (!s) {
11    if (ps->count) {
12      errno=EILSEQ;
13      return (size_t)-1;
14    } else {
15      ps->count=0;
16      ps->sofar=0;
17      return 0;
18    }
19  }
20  for (i=0; i<n; ++i) {
21    unsigned char c=s[i];
22    switch (lc_ctype) {
23    case CT_8BIT:
24      if (pwc) { *pwc=c; ++pwc; }
25      return (!!c);
26    case CT_UTF8:
27      if (ps->count) {
28        /* we have an unfinished multibyte sequence */
29        if ((c&0xc0)!=0x80) {
30          /* expected a continuation, didn't get one */
31kaputt:
32          errno=EILSEQ;
33          ps->count=0;
34          return (size_t)-1;
35        }
36        ps->sofar=(ps->sofar << 6) + (c & 0x3f);
37        if (!--ps->count) {
38complete:
39          if (pwc) { *pwc=ps->sofar; ++pwc; }
40          if (ps->sofar) {
41            ps->sofar=0;
42            return i+1;
43          } else {
44            ps->count=0; ps->sofar=0;
45            return 0;
46          }
47        }
48      } else {
49        if (c&0x80) {   /* start of multibyte sequence? */
50          unsigned char x=c<<1;
51          unsigned char cnt=0;
52          while (x&0x80) {
53            x<<=1;
54            ++cnt;
55          }
56          if (!cnt || cnt>5) goto kaputt;
57          ps->sofar=x>>(cnt+1);
58          ps->count=cnt;
59        } else {
60          ps->sofar=c;
61          goto complete;
62        }
63      }
64    }
65  }
66  return n;
67}
Note: See TracBrowser for help on using the repository browser.