1151497Sru// -*- C++ -*- 2151497Sru/* Copyright (C) 2002 3151497Sru Free Software Foundation, Inc. 4151497Sru Written by Werner Lemberg <wl@gnu.org> 5151497Sru 6151497SruThis file is part of groff. 7151497Sru 8151497Srugroff is free software; you can redistribute it and/or modify it under 9151497Sruthe terms of the GNU General Public License as published by the Free 10151497SruSoftware Foundation; either version 2, or (at your option) any later 11151497Sruversion. 12151497Sru 13151497Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY 14151497SruWARRANTY; without even the implied warranty of MERCHANTABILITY or 15151497SruFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16151497Srufor more details. 17151497Sru 18151497SruYou should have received a copy of the GNU General Public License along 19151497Sruwith groff; see the file COPYING. If not, write to the Free Software 20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 21151497Sru 22151497Sru#include "lib.h" 23151497Sru#include "cset.h" 24151497Sru#include "stringclass.h" 25151497Sru 26151497Sru#include "unicode.h" 27151497Sru 28151497Sruconst char *check_unicode_name(const char *u) 29151497Sru{ 30151497Sru if (*u != 'u') 31151497Sru return 0; 32151497Sru const char *p = ++u; 33151497Sru for (;;) { 34151497Sru int val = 0; 35151497Sru const char *start = p; 36151497Sru for (;;) { 37151497Sru // only uppercase hex digits allowed 38151497Sru if (!csxdigit(*p)) 39151497Sru return 0; 40151497Sru if (csdigit(*p)) 41151497Sru val = val*0x10 + (*p-'0'); 42151497Sru else if (csupper(*p)) 43151497Sru val = val*0x10 + (*p-'A'+10); 44151497Sru else 45151497Sru return 0; 46151497Sru // biggest Unicode value is U+10FFFF 47151497Sru if (val > 0x10FFFF) 48151497Sru return 0; 49151497Sru p++; 50151497Sru if (*p == '\0' || *p == '_') 51151497Sru break; 52151497Sru } 53151497Sru // surrogates not allowed 54151497Sru if ((val >= 0xD800 && val <= 0xDBFF) || (val >= 0xDC00 && val <= 0xDFFF)) 55151497Sru return 0; 56151497Sru if (val > 0xFFFF) { 57151497Sru if (*start == '0') // no leading zeros allowed if > 0xFFFF 58151497Sru return 0; 59151497Sru } 60151497Sru else if (p - start != 4) // otherwise, check for exactly 4 hex digits 61151497Sru return 0; 62151497Sru if (*p == '\0') 63151497Sru break; 64151497Sru p++; 65151497Sru } 66151497Sru return u; 67151497Sru} 68