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

« back to all changes in this revision

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