/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/******************************************************************************
This file provides a finite state machine to support Irish Gaelic uppercasing
rules .
The caller will need to iterate through a string , passing a State variable
along with the current character to each UpperCase call and checking the flags
that are returned :
If aMarkPos is true , caller must remember the current index in the string as
a possible target for a future action .
If aAction is non - zero , then one or more characters from the marked index are
to be modified :
1 lowercase the marked letter
2 lowercase the marked letter and its successor
3 lowercase the marked letter , and delete its successor
# # # Rules from https : //bugzilla.mozilla.org/show_bug.cgi?id=1014639,
# # # comments 1 and 4 :
v = [ a , á , e , é , i , í , o , ó , u , ú ]
V = [ A , Á , E , É , I , Í , O , Ó , U , Ú ]
bhf - > bhF
bhF - > bhF
bp - > bP
bP - > bP
dt - > dT
dT - > dT
gc - > gC
gC - > gC
h { V } - > h { V }
mb - > mB
mB - > mB
n - { v } - > n { V }
n { V } - > n { V }
nd - > nD
nD - > nD
ng - > nG
nG - > nG
t - { v } - > t { V }
t { V } - > t { V }
ts { v } - > tS { V }
tS { v } - > tS { V }
tS { V } - > tS { V }
tsl - > tSL
tSl - > tSL
tSL - > tSL
tsn - > tSN
tSn - > tSN
tSN - > tSN
tsr - > tSR
tSr - > tSR
tSR - > tSR
# # # Create table of states and actions for each input class .
Start ( non - word ) state is # ; generic in - word state is _ , once we know there ' s
no special action to do in this word .
# _ b bh d g h m n n - t t - ts
input \ state
b b ' _ _ _ _ _ _ 1 _ _ _ _ _
B _ _ _ _ _ _ _ 1 _ _ _ _ _
c _ _ _ _ _ 1 _ _ _ _ _ _ _
C _ _ _ _ _ 1 _ _ _ _ _ _ _
d d ' _ _ _ _ _ _ _ 1 _ _ _ _
D _ _ _ _ _ _ _ _ 1 _ _ _ _
f _ _ _ 2 _ _ _ _ _ _ _ _ _
F _ _ _ 2 _ _ _ _ _ _ _ _ _
g g ' _ _ _ _ _ _ _ 1 _ _ _ _
G _ _ _ _ _ _ _ _ 1 _ _ _ _
h h ' _ bh _ _ _ _ _ _ _ _ _ _
l _ _ _ _ _ _ _ _ _ _ _ _ 1
L _ _ _ _ _ _ _ _ _ _ _ _ 1
m m ' _ _ _ _ _ _ _ _ _ _ _ _
n n ' _ _ _ _ _ _ _ _ _ _ _ 1
N _ _ _ _ _ _ _ _ _ _ _ _ 1
p _ _ 1 _ _ _ _ _ _ _ _ _ _
P _ _ 1 _ _ _ _ _ _ _ _ _ _
r _ _ _ _ _ _ _ _ _ _ _ _ 1
R _ _ _ _ _ _ _ _ _ _ _ _ 1
s _ _ _ _ _ _ _ _ _ _ ts _ _
S _ _ _ _ _ _ _ _ _ _ ts _ _
t t ' _ _ _ 1 _ _ _ _ _ _ _ _
T _ _ _ _ 1 _ _ _ _ _ _ _ _
vowel _ _ _ _ _ _ _ _ _ 1 d _ 1 d 1
Vowel _ _ _ _ _ _ 1 _ 1 _ 1 _ 1
hyph _ _ _ _ _ _ _ _ n - _ t - _ _
letter _ _ _ _ _ _ _ _ _ _ _ _ _
other # # # # # # # # # # # # #
Actions :
1 lowercase one letter at start of word
2 lowercase two letters at start of word
1 d lowercase one letter at start of word , and delete next
( and then go to state _ , nothing further to do in this word )
else just go to the given state ; suffix ' indicates mark start - of - word .
# # # Consolidate identical states and classes :
0 1 2 3 4 5 6 7 8 9 A B
# _ b bh d g h m n [ nt ] - t ts
input \ state
b b ' _ _ _ _ _ _ 1 _ _ _ _
B _ _ _ _ _ _ _ 1 _ _ _ _
[ cC ] _ _ _ _ _ 1 _ _ _ _ _ _
d d ' _ _ _ _ _ _ _ 1 _ _ _
[ DG ] _ _ _ _ _ _ _ _ 1 _ _ _
[ fF ] _ _ _ 2 _ _ _ _ _ _ _ _
g g ' _ _ _ _ _ _ _ 1 _ _ _
h h ' _ bh _ _ _ _ _ _ _ _ _
[ lLNrR ] _ _ _ _ _ _ _ _ _ _ _ 1
m m ' _ _ _ _ _ _ _ _ _ _ _
n n ' _ _ _ _ _ _ _ _ _ _ 1
[ pP ] _ _ 1 _ _ _ _ _ _ _ _ _
[ sS ] _ _ _ _ _ _ _ _ _ _ ts _
t t ' _ _ _ 1 _ _ _ _ _ _ _
T _ _ _ _ 1 _ _ _ _ _ _ _
vowel _ _ _ _ _ _ _ _ _ 1 d _ 1
Vowel _ _ _ _ _ _ 1 _ 1 _ 1 1
hyph _ _ _ _ _ _ _ _ [ nt - ] _ [ nt - ] _
letter _ _ _ _ _ _ _ _ _ _ _ _
other # # # # # # # # # # # #
So we have 20 input classes , and 12 states .
State table array will contain bytes that encode action and new state :
0 x80 - bit flag : mark start - of - word position
0 x40 - currently unused
0 x30 - action mask : 4 values
0 x00 - do nothing
0 x10 - lowercase one letter
0 x20 - lowercase two letters
0 x30 - lowercase one , delete one
0 x0F - next - state mask
******************************************************************************/
#include "IrishCasing.h"
#include "nsUnicodeProperties.h"
#include "nsUnicharUtils.h"
namespace mozilla {
const uint8_t IrishCasing::sUppercaseStateTable[kNumClasses][kNumStates] = {
// # _ b bh d g h m n [nt]- t ts
{
0 x82,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01,
0 x01},
// b
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01,
0 x01},
// B
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x10,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// [cC]
{
0 x84,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01},
// d
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01},
// [DG]
{
0 x01,
0 x01,
0 x01,
0 x21,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// [fF]
{
0 x85,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01},
// g
{
0 x86,
0 x01,
0 x03,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// h
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11},
// [lLNrR]
{
0 x87,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// m
{
0 x88,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11},
// n
{
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// [pP]
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x0B,
0 x01},
// [sS]
{
0 x8A,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// t
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// T
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x31,
0 x01,
0 x11},
// vowel
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x11,
0 x01,
0 x11,
0 x01,
0 x11,
0 x11},
// Vowel
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x09,
0 x01,
0 x09,
0 x01},
// hyph
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01},
// letter
{
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
// other
};
#define HYPHEN
0 x2010
#define NO_BREAK_HYPHEN
0 x2011
#define a_ACUTE
0 x00e1
#define e_ACUTE
0 x00e9
#define i_ACUTE
0 x00ed
#define o_ACUTE
0 x00f3
#define u_ACUTE
0 x00fa
#define A_ACUTE
0 x00c1
#define E_ACUTE
0 x00c9
#define I_ACUTE
0 x00cd
#define O_ACUTE
0 x00d3
#define U_ACUTE
0 x00da
const uint8_t IrishCasing::sLcClasses[
26 ] = {
kClass_vowel, kClass_b, kClass_cC, kClass_d, kClass_vowel,
kClass_fF, kClass_g, kClass_h, kClass_vowel, kClass_letter,
kClass_letter, kClass_lLNrR, kClass_m, kClass_n, kClass_vowel,
kClass_pP, kClass_letter, kClass_lLNrR, kClass_sS, kClass_t,
kClass_vowel, kClass_letter, kClass_letter, kClass_letter, kClass_letter,
kClass_letter};
const uint8_t IrishCasing::sUcClasses[
26 ] = {
kClass_Vowel, kClass_B, kClass_cC, kClass_DG, kClass_Vowel,
kClass_fF, kClass_DG, kClass_letter, kClass_Vowel, kClass_letter,
kClass_letter, kClass_lLNrR, kClass_letter, kClass_lLNrR, kClass_Vowel,
kClass_pP, kClass_letter, kClass_lLNrR, kClass_sS, kClass_T,
kClass_Vowel, kClass_letter, kClass_letter, kClass_letter, kClass_letter,
kClass_letter};
uint8_t IrishCasing::GetClass(uint32_t aCh) {
using mozilla::unicode::GetGenCategory;
if (aCh >=
'a' && aCh <=
'z' ) {
return sLcClasses[aCh -
'a' ];
}
if (aCh >=
'A' && aCh <=
'Z' ) {
return sUcClasses[aCh -
'A' ];
}
if (GetGenCategory(aCh) == nsUGenCategory::kLetter) {
if (aCh == a_ACUTE || aCh == e_ACUTE || aCh == i_ACUTE || aCh == o_ACUTE ||
aCh == u_ACUTE) {
return kClass_vowel;
}
if (aCh == A_ACUTE || aCh == E_ACUTE || aCh == I_ACUTE || aCh == O_ACUTE ||
aCh == U_ACUTE) {
return kClass_Vowel;
}
return kClass_letter;
}
if (aCh ==
'-' || aCh == HYPHEN || aCh == NO_BREAK_HYPHEN) {
return kClass_hyph;
}
return kClass_other;
}
uint32_t IrishCasing::UpperCase(uint32_t aCh, State& aState,
bool & aMarkPos,
uint8_t& aAction) {
uint8_t cls = GetClass(aCh);
uint8_t stateEntry = sUppercaseStateTable[cls][aState];
aMarkPos = !!(stateEntry & kMarkPositionFlag);
aAction = (stateEntry & kActionMask) >> kActionShift;
aState = State(stateEntry & kNextStateMask);
return ToUpperCase(aCh);
}
}
// namespace mozilla
Messung V0.5 in Prozent C=91 H=100 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*© Formatika GbR, Deutschland