2005-07-28 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / Mono.Globalization.Unicode / create-combining-class-source.cs
1 //
2 //
3 // create-combining-class-source.cs
4 //
5 // Author:
6 //      Atsushi Enomoto  <atsushi@ximian.com>
7 //
8 // Copyright 2005 Novell, Inc
9 //
10 // It creates combining class information table.
11 //
12
13 using System;
14 using System.Globalization;
15 using System.IO;
16
17 using Util = Mono.Globalization.Unicode.NormalizationTableUtil;
18
19 namespace Mono.Globalization.Unicode
20 {
21         internal class CombiningClassCodeGenerator
22         {
23                 private int lineCount = 0;
24
25                 TextWriter CSCodeOut = TextWriter.Null;//Console.Out;
26                 TextWriter CSTableOut = Console.Out;//TextWriter.Null;
27
28                 public static void Main ()
29                 {
30                         new CombiningClassCodeGenerator ().Run ();
31                 }
32
33                 private void Run ()
34                 {
35                         try {
36                                 Process ();
37                         } catch (Exception ex) {
38                                 throw new InvalidOperationException ("Internal error at line " + lineCount + " : " + ex);
39                         }
40                 }
41
42                 private void Process ()
43                 {
44                         CSCodeOut.WriteLine ("public static byte GetCombiningClass (int c)");
45                         CSCodeOut.WriteLine ("{");
46                         CSCodeOut.WriteLine ("  switch (c) {");
47
48                         TextReader reader = Console.In;
49                         while (reader.Peek () != -1) {
50                                 string line = reader.ReadLine ();
51                                 lineCount++;
52                                 int idx = line.IndexOf ('#');
53                                 if (idx >= 0)
54                                         line = line.Substring (0, idx).Trim ();
55                                 if (line.Length == 0)
56                                         continue;
57                                 int n = 0;
58                                 while (Char.IsDigit (line [n]) || Char.IsLetter (line [n]))
59                                         n++;
60                                 int cp = int.Parse (line.Substring (0, n), NumberStyles.HexNumber);
61
62                                 int cpEnd = -1;
63                                 if (line [n] == '.' && line [n + 1] == '.')
64                                         cpEnd = int.Parse (line.Substring (n + 2, n), NumberStyles.HexNumber);
65                                 int nameStart = line.IndexOf (';') + 1;
66                                 int valueStart = line.IndexOf (';', nameStart) + 1;
67                                 string val = valueStart == 0 ? line.Substring (nameStart) :
68                                         line.Substring (nameStart, valueStart - nameStart - 1);
69                                 SetProp (cp, cpEnd, short.Parse (val));
70                         }
71
72                         CSCodeOut.WriteLine ("          return {0};", prevVal);
73                         CSCodeOut.WriteLine ("  default:");
74                         CSCodeOut.WriteLine ("          return 0;");
75                         CSCodeOut.WriteLine ("  }");
76                         CSCodeOut.WriteLine ("}");
77
78                         reader.Close ();
79
80                         byte [] ret = CodePointIndexer.CompressArray (
81                                 values, typeof (byte), Util.Combining) as byte [];
82
83                         CSTableOut.WriteLine ("public static byte [] combiningClass = new byte [] {");
84                         for (int i = 0; i < ret.Length; i++) {
85                                 byte value = ret [i];
86                                 if (value < 10)
87                                         CSTableOut.Write ("{0},", value);
88                                 else
89                                         CSTableOut.Write ("0x{0:X02},", value);
90                                 if (i % 16 == 15)
91                                         CSTableOut.WriteLine (" // {0:X04}", Util.Combining.ToCodePoint (i - 15));
92                         }
93                         CSTableOut.WriteLine ("};");
94                 }
95
96                 private short prevVal;
97
98                 byte [] values = new byte [0x20000];
99
100                 private void SetProp (int cp, int cpEnd, short val)
101                 {
102                         if (val == 0)
103                                 return;
104
105                         if (prevVal != val && prevVal != 0)
106                                 CSCodeOut.WriteLine ("\t\treturn {0};", prevVal);
107                         prevVal = val;
108
109                         if (cpEnd < 0) {
110                                 CSCodeOut.WriteLine ("\tcase 0x{0:X}:", cp);
111                                 values [cp] = (byte) val;
112                         }
113                         else
114                                 for (int i = cp; i <= cpEnd; i++) {
115                                         CSCodeOut.WriteLine ("\tcase 0x{0:X}:", i);
116                                         values [i] = (byte) val;
117                                 }
118                 }
119         }
120 }
121