~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/gnulib-lib/unistr/u8-mblen.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Look at first character in UTF-8 string.
 
2
   Copyright (C) 1999-2000, 2002, 2006-2007, 2009-2010 Free Software
 
3
   Foundation, Inc.
 
4
   Written by Bruno Haible <bruno@clisp.org>, 2002.
 
5
 
 
6
   This program is free software: you can redistribute it and/or modify it
 
7
   under the terms of the GNU General Public License as published
 
8
   by the Free Software Foundation; either version 3 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
18
 
 
19
#include <config.h>
 
20
 
 
21
/* Specification.  */
 
22
#include "unistr.h"
 
23
 
 
24
int
 
25
u8_mblen (const uint8_t *s, size_t n)
 
26
{
 
27
  if (n > 0)
 
28
    {
 
29
      /* Keep in sync with unistr.h and utf8-ucs4.c.  */
 
30
      uint8_t c = *s;
 
31
 
 
32
      if (c < 0x80)
 
33
        return (c != 0 ? 1 : 0);
 
34
      if (c >= 0xc2)
 
35
        {
 
36
          if (c < 0xe0)
 
37
            {
 
38
              if (n >= 2
 
39
#if CONFIG_UNICODE_SAFETY
 
40
                  && (s[1] ^ 0x80) < 0x40
 
41
#endif
 
42
                 )
 
43
                return 2;
 
44
            }
 
45
          else if (c < 0xf0)
 
46
            {
 
47
              if (n >= 3
 
48
#if CONFIG_UNICODE_SAFETY
 
49
                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
 
50
                  && (c >= 0xe1 || s[1] >= 0xa0)
 
51
                  && (c != 0xed || s[1] < 0xa0)
 
52
#endif
 
53
                 )
 
54
                return 3;
 
55
            }
 
56
          else if (c < 0xf8)
 
57
            {
 
58
              if (n >= 4
 
59
#if CONFIG_UNICODE_SAFETY
 
60
                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
 
61
                  && (s[3] ^ 0x80) < 0x40
 
62
                  && (c >= 0xf1 || s[1] >= 0x90)
 
63
#if 1
 
64
                  && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
 
65
#endif
 
66
#endif
 
67
                 )
 
68
                return 4;
 
69
            }
 
70
#if 0
 
71
          else if (c < 0xfc)
 
72
            {
 
73
              if (n >= 5
 
74
#if CONFIG_UNICODE_SAFETY
 
75
                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
 
76
                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
 
77
                  && (c >= 0xf9 || s[1] >= 0x88)
 
78
#endif
 
79
                 )
 
80
                return 5;
 
81
            }
 
82
          else if (c < 0xfe)
 
83
            {
 
84
              if (n >= 6
 
85
#if CONFIG_UNICODE_SAFETY
 
86
                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
 
87
                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
 
88
                  && (s[5] ^ 0x80) < 0x40
 
89
                  && (c >= 0xfd || s[1] >= 0x84)
 
90
#endif
 
91
                 )
 
92
                return 6;
 
93
            }
 
94
#endif
 
95
        }
 
96
    }
 
97
  /* invalid or incomplete multibyte character */
 
98
  return -1;
 
99
}