2 // create-normalization-source.cs - creates normalization information table.
6 using System.Globalization;
9 namespace Mono.Globalization.Unicode
11 internal class NormalizationCodeGenerator
13 private int lineCount = 0;
14 int singleCount = 1, multiCount = 1, propValueCount = 1;
15 int [] singleNorm = new int [550];
16 int [] multiNorm = new int [280];
17 int [] prop = new int [char.MaxValue]; // maybe it will be enough when we use CodePointIndexer
18 int [] propValues = new int [1024];
20 public const int NoNfd = 1;
21 public const int NoNfkd = 2;
22 public const int NoNfc = 4;
23 public const int MaybeNfc = 8;
24 public const int NoNfkc = 16;
25 public const int MaybeNfkc = 32;
26 public const int ExpandOnNfd = 64;
27 public const int ExpandOnNfc = 128;
28 public const int ExpandOnNfkd = 256;
29 public const int ExpandOnNfkc = 512;
30 public const int FullCompositionExclusion = 1024;
32 public static void Main ()
34 new NormalizationCodeGenerator ().Run ();
43 } catch (Exception ex) {
44 throw new InvalidOperationException ("Internal error at line " + lineCount + " : " + ex);
48 private void MakeIndex ()
50 for (int i = 0; i < prop.Length; i++) {
52 for (int v = 0; v < propValueCount; v++)
53 if (propValues [v] == prop [i]) {
60 if (propValueCount == propValues.Length) {
61 int [] tmp = new int [propValueCount * 2];
62 Array.Copy (propValues, tmp, propValueCount);
65 propValues [propValueCount] = prop [i];
66 prop [i] = propValueCount++;
70 private void Serialize ()
72 Console.WriteLine ("static readonly int [] singleNorm = new int [] {");
73 DumpArray (singleNorm, singleCount, false);
74 Console.WriteLine ("};");
75 Console.WriteLine ("static readonly int [] multiNorm = new int [] {");
76 DumpArray (multiNorm, multiCount, false);
77 Console.WriteLine ("};");
78 Console.WriteLine ("static readonly byte [] propIdx = new byte [] {");
79 DumpArray (prop, NormalizationTableUtil.PropCount, true);
80 Console.WriteLine ("};");
81 Console.WriteLine ("static readonly uint [] propValue = new uint [] {");
82 DumpArray (propValues, propValueCount, false);
83 Console.WriteLine ("};");
86 private void DumpArray (int [] array, int count, bool getCP)
88 if (array.Length < count)
89 throw new ArgumentOutOfRangeException ("count");
90 for (int i = 0; i < count; i++) {
91 uint value = (uint) array [i];
93 Console.Write ("{0}, ", value);
95 Console.Write ("0x{0:X}, ", value);
97 int l = getCP ? NormalizationTableUtil.PropCP (i) : i;
98 Console.WriteLine ("// {0:X04}-{1:X04}", l - 15, l);
103 private void Parse ()
105 TextReader reader = Console.In;
106 while (reader.Peek () != -1) {
107 string line = reader.ReadLine ();
109 int idx = line.IndexOf ('#');
111 line = line.Substring (0, idx);
112 if (line.Length == 0)
115 while (Char.IsDigit (line [n]) || Char.IsLetter (line [n]))
117 int cp = int.Parse (line.Substring (0, n), NumberStyles.HexNumber);
120 if (line [n] == '.' && line [n + 1] == '.')
121 cpEnd = int.Parse (line.Substring (n + 2, n), NumberStyles.HexNumber);
122 int nameStart = line.IndexOf (';') + 1;
123 int valueStart = line.IndexOf (';', nameStart) + 1;
124 string name = valueStart == 0 ? line.Substring (nameStart) :
125 line.Substring (nameStart, valueStart - nameStart - 1);
127 string values = valueStart > 0 ?
128 line.Substring (valueStart).Trim () : "";
130 case "Full_Composition_Exclusion":
131 SetProp (cp, cpEnd, FullCompositionExclusion);
134 SetProp (cp, cpEnd, NoNfd);
137 SetProp (cp, cpEnd, (values == "M") ?
141 SetProp (cp, cpEnd, NoNfkd);
144 SetProp (cp, cpEnd, (values == "M") ?
147 case "Expands_On_NFD":
148 SetProp (cp, cpEnd, ExpandOnNfd);
150 case "Expands_On_NFC":
151 SetProp (cp, cpEnd, ExpandOnNfc);
153 case "Expands_On_NFKD":
154 SetProp (cp, cpEnd, ExpandOnNfkd);
156 case "Expands_On_NFKC":
157 SetProp (cp, cpEnd, ExpandOnNfkc);
160 int v1 = 0, v2 = 0, v3 = 0, v4 = 0;
161 foreach (string s in values.Split (' ')) {
162 if (s.Trim ().Length == 0)
164 int v = int.Parse (s, NumberStyles.HexNumber);
174 throw new NotSupportedException (String.Format ("more than 4 values in FC_NFKC: {0:x}", cp));
176 SetNFKC (cp, cpEnd, v1, v2, v3, v4);
183 private void SetProp (int cp, int cpEnd, int flag)
185 int idx = NormalizationTableUtil.PropIdx (cp);
189 int idxEnd = NormalizationTableUtil.PropIdx (cpEnd);
190 for (int i = idx; i <= idxEnd; i++)
195 private void SetNFKC (int cp, int cpEnd, int v1, int v2, int v3, int v4)
199 for (int i = 0; i < singleCount; i++)
200 if (singleNorm [i] == v1) {
205 if (singleNorm.Length == singleCount) {
206 int [] tmp = new int [singleCount << 1];
207 Array.Copy (singleNorm, tmp, singleCount);
211 singleNorm [singleCount++] = v1;
213 SetProp (cp, cpEnd, idx << 16);
215 if (multiNorm.Length == multiCount) {
216 int [] tmp = new int [multiCount << 1];
217 Array.Copy (multiNorm, tmp, multiCount);
221 (int) ((multiCount << 16) | 0xF0000000));
222 multiNorm [multiCount++] = v1;
223 multiNorm [multiCount++] = v2;
224 multiNorm [multiCount++] = v3;
225 multiNorm [multiCount++] = v4;