/******************************************************************************\
* Copyright (c) 2016, Robert van Engelen, Genivia Inc. All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions are met: *
* *
* (1) Redistributions of source code must retain the above copyright notice, *
* this list of conditions and the following disclaimer. *
* *
* (2) Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* *
* (3) The name of the author may not be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO *
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR *
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
\******************************************************************************/
/**
@file unicode.cpp
@brief Get Unicode character class ranges and UTF-8 regex translations
@author Robert van Engelen - engelen@genivia.com
@copyright (c) 2016-2025, Robert van Engelen, Genivia Inc. All rights reserved.
@copyright (c) BSD-3 License - see LICENSE.txt
*/
#include <reflex/unicode.h>
#include <reflex/utf8.h>
namespace reflex {
namespace Unicode {
Tables::Tables()
{
block_scripts();
language_scripts();
letter_scripts();
composer();
range["Other"] = range["C"];
range["Letter"] = range["L"];
range["Mark"] = range["M"];
range["Number"] = range["N"];
range["Punctuation"] = range["P"];
range["Symbol"] = range["S"];
range["Separator"] = range["Z"];
range["Lowercase_Letter"] = range["Ll"];
range["Uppercase_Letter"] = range["Lu"];
range["Titlecase_Letter"] = range["Lt"];
range["Modifier_Letter"] = range["Lm"];
range["Other_Letter"] = range["Lo"];
range["Non_Spacing_Mark"] = range["Mn"];
range["Spacing_Combining_Mark"] = range["Mc"];
range["Enclosing_Mark"] = range["Me"];
range["Space_Separator"] = range["Zs"];
range["Line_Separator"] = range["Zl"];
range["Paragraph_Separator"] = range["Zp"];
range["Math_Symbol"] = range["Sm"];
range["Currency_Symbol"] = range["Sc"];
range["Modifier_Symbol"] = range["Sk"];
range["Other_Symbol"] = range["So"];
range["Decimal_Digit_Number"] = range["Nd"];
range["Letter_Number"] = range["Nl"];
range["Other_Number"] = range["No"];
range["Dash_Punctuation"] = range["Pd"];
range["Open_Punctuation"] = range["Ps"];
range["Close_Punctuation"] = range["Pe"];
range["Initial_Punctuation"] = range["Pi"];
range["Final_Punctuation"] = range["Pf"];
range["Connector_Punctuation"] = range["Pc"];
range["Other_Punctuation"] = range["Po"];
range["Control"] = range["Cc"];
range["Format"] = range["Cf"];
range["Cntrl"] = range["C"];
range["Digit"] = range["Nd"];
range["Lower"] = range["Ll"];
range["Punct"] = range["P"];
range["Upper"] = range["Lu"];
range["d"] = range["Digit"];
range["l"] = range["Lower"];
range["u"] = range["Upper"];
range["s"] = range["Space"];
range["w"] = range["Word"];
}
static const Tables tables;
const int * range(const char *s)
{
Tables::Range::const_iterator i = tables.range.find(s);
if (i != tables.range.end())
return i->second;
return NULL;
}
int compose(int prev, int next)
{
Tables::Compose::const_iterator i = tables.compose.find(next);
if (i != tables.compose.end())
for (const int *p = i->second; p[0] != 0; p += 2)
if (p[0] == prev)
return p[1];
return -1;
}
int toupper(int c)
{
return Tables::toupper(c);
}
int tolower(int c)
{
return Tables::tolower(c);
}
int invcase(int c)
{
int a = toupper(c);
if (a == c)
a = tolower(c);
return a;
}
} // namespace Unicode
} // namespace reflex