| Commit | Line | Data |
|---|---|---|
| 92d0a6a6 | 1 | // -*- C++ -*- |
| 4d3e9548 | 2 | /* Copyright (C) 2002, 2009 |
| 92d0a6a6 JR |
3 | Free Software Foundation, Inc. |
| 4 | Written by Werner Lemberg <wl@gnu.org> | |
| 5 | ||
| 6 | This file is part of groff. | |
| 7 | ||
| 8 | groff is free software; you can redistribute it and/or modify it under | |
| 9 | the terms of the GNU General Public License as published by the Free | |
| 4d3e9548 JL |
10 | Software Foundation, either version 3 of the License, or |
| 11 | (at your option) any later version. | |
| 92d0a6a6 JR |
12 | |
| 13 | groff is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 16 | for more details. | |
| 17 | ||
| 4d3e9548 JL |
18 | You should have received a copy of the GNU General Public License |
| 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
| 92d0a6a6 JR |
20 | |
| 21 | #include "lib.h" | |
| 22 | #include "cset.h" | |
| 23 | #include "stringclass.h" | |
| 24 | ||
| 25 | #include "unicode.h" | |
| 26 | ||
| 27 | const char *check_unicode_name(const char *u) | |
| 28 | { | |
| 29 | if (*u != 'u') | |
| 30 | return 0; | |
| 31 | const char *p = ++u; | |
| 32 | for (;;) { | |
| 33 | int val = 0; | |
| 34 | const char *start = p; | |
| 35 | for (;;) { | |
| 36 | // only uppercase hex digits allowed | |
| 37 | if (!csxdigit(*p)) | |
| 38 | return 0; | |
| 39 | if (csdigit(*p)) | |
| 40 | val = val*0x10 + (*p-'0'); | |
| 41 | else if (csupper(*p)) | |
| 42 | val = val*0x10 + (*p-'A'+10); | |
| 43 | else | |
| 44 | return 0; | |
| 45 | // biggest Unicode value is U+10FFFF | |
| 46 | if (val > 0x10FFFF) | |
| 47 | return 0; | |
| 48 | p++; | |
| 49 | if (*p == '\0' || *p == '_') | |
| 50 | break; | |
| 51 | } | |
| 52 | // surrogates not allowed | |
| 53 | if ((val >= 0xD800 && val <= 0xDBFF) || (val >= 0xDC00 && val <= 0xDFFF)) | |
| 54 | return 0; | |
| 55 | if (val > 0xFFFF) { | |
| 56 | if (*start == '0') // no leading zeros allowed if > 0xFFFF | |
| 57 | return 0; | |
| 58 | } | |
| 59 | else if (p - start != 4) // otherwise, check for exactly 4 hex digits | |
| 60 | return 0; | |
| 61 | if (*p == '\0') | |
| 62 | break; | |
| 63 | p++; | |
| 64 | } | |
| 65 | return u; | |
| 66 | } |