Changeset 4363 for proto/charsetcompiler


Ignore:
Timestamp:
Dec 27, 2014, 11:08:11 AM (4 years ago)
Author:
cameron
Message:

Generate ScriptExtensions?.h

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/charsetcompiler/UCD/UCD_properties.py

    r4192 r4363  
    120120CodepointProperties = ['scf', 'slc', 'suc', 'stc']
    121121
    122 def generate_ScriptExtensions_h():
    123    (scx_sets, scx_map) = parse_UCD_codepoint_name_map('ScriptExtensions.txt')
    124    map2 = {}
    125    f = cformat.open_header_file_for_write('ScriptExtensions')
    126    cformat.write_imports(f, ["<vector>", '"PropertyAliases.h"', '"PropertyValueAliases.h"', '"unicode_set.h"'])
    127    f.write("\nusing namespace UCD;\n\n")
    128    for scx_list in scx_sets:
    129      scx_items = scx_list.split(" ")
    130      for scx in scx_items:
    131         if map2.has_key(scx):
    132            map2[scx] = uset_union(map2[scx], scx_map[scx_list])
    133         else: map2[scx] = scx_map[scx_list]
    134    print "%s bytes" % sum([map2[k].bytes() for k in map2.keys()])
    135    for k in sorted(map2.keys()):
    136      pass#f.write(map2[k].showC('value_sets[scx][SC::%s]' % k.lower()))
    137    cformat.close_header_file(f)
    138 
    139 
    140122class UCD_generator():
    141         def __init__(self, UCD_dir):
    142                 self.UCD_dir = UCD_dir
    143                 self.supported_props = []
    144                 self.property_data_headers = []
    145                 self.missing_specs = {}
    146 
    147         def parse_PropertyAlias_txt(self):
    148            self.property_enum_name_list = []
    149            self.full_name_map = {}
    150            self.property_lookup_map = {}
    151            self.property_kind_map = {}
    152            property_kind = "unspecified"
    153            f = open(self.UCD_dir + "/" + 'PropertyAliases.txt')
    154            lines = f.readlines()
    155            for t in lines:
    156               m = UCD_property_section_regexp.match(t)
    157               if m:
    158                 property_kind = m.group(1)
    159               if UCD_skip.match(t): continue  # skip comment and blank lines
    160               m = UCD_property_alias_regexp.match(t)
    161               if not m: raise Exception("Unknown property alias syntax: %s" % t)
    162               prop_enum = m.group(1).lower()
    163               prop_preferred_full_name = m.group(2)
    164               prop_extra = m.group(3)
    165               prop_aliases = re.findall("[-A-Za-z_0-9]+", prop_extra)
    166               self.property_enum_name_list.append(prop_enum)
    167               self.full_name_map[prop_enum] = prop_preferred_full_name
    168               self.property_lookup_map[canonicalize(prop_enum)] = prop_enum
    169               self.property_lookup_map[canonicalize(prop_preferred_full_name)] = prop_enum
    170               for a in prop_aliases: self.property_lookup_map[canonicalize(a)] = prop_enum
    171               self.property_kind_map[prop_enum] = property_kind
    172 
    173         def generate_PropertyAliases_h(self):
    174            f = cformat.open_header_file_for_write('PropertyAliases')
    175            cformat.write_imports(f, ["<string>", "<vector>", "<unordered_map>"])
    176            enum_text = cformat.multiline_fill(self.property_enum_name_list, ',')
    177            full_name_text = cformat.multiline_fill(['"%s"' % self.full_name_map[e] for e in self.property_enum_name_list], ',')
    178            map_text = cformat.multiline_fill(['{"%s", %s}' % (k, self.property_lookup_map[k]) for k in sorted(self.property_lookup_map.keys())], ',')
    179            f.write(PropertyAliases_template % (enum_text, full_name_text, map_text))
    180            cformat.close_header_file(f)
    181 
    182         def process_missing_spec_format_2(self, s):
    183           UCD_property_value_missing_regexp = re.compile("^#\s*@missing:\s*([0-9A-F]{4,6})[.][.]([0-9A-F]{4,6})\s*;\s*([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.<> ]+)\s*([^#]*)")
    184           m = UCD_property_value_missing_regexp.match(s)
    185           if m:
    186             if m.group(1) != '0000' or m.group(2) != '10FFFF': raise Exception("Bad missing spec: " + s)
    187             cname = canonicalize(m.group(3))
    188             if not self.property_lookup_map.has_key(cname): raise Exception("Bad missing property: " + s)
    189             self.missing_specs[self.property_lookup_map[cname]] = m.group(4)
     123    def __init__(self, UCD_dir):
     124            self.UCD_dir = UCD_dir
     125            self.supported_props = []
     126            self.property_data_headers = []
     127            self.missing_specs = {}
     128
     129    def parse_PropertyAlias_txt(self):
     130       self.property_enum_name_list = []
     131       self.full_name_map = {}
     132       self.property_lookup_map = {}
     133       self.property_kind_map = {}
     134       property_kind = "unspecified"
     135       f = open(self.UCD_dir + "/" + 'PropertyAliases.txt')
     136       lines = f.readlines()
     137       for t in lines:
     138          m = UCD_property_section_regexp.match(t)
     139          if m:
     140            property_kind = m.group(1)
     141          if UCD_skip.match(t): continue  # skip comment and blank lines
     142          m = UCD_property_alias_regexp.match(t)
     143          if not m: raise Exception("Unknown property alias syntax: %s" % t)
     144          prop_enum = m.group(1).lower()
     145          prop_preferred_full_name = m.group(2)
     146          prop_extra = m.group(3)
     147          prop_aliases = re.findall("[-A-Za-z_0-9]+", prop_extra)
     148          self.property_enum_name_list.append(prop_enum)
     149          self.full_name_map[prop_enum] = prop_preferred_full_name
     150          self.property_lookup_map[canonicalize(prop_enum)] = prop_enum
     151          self.property_lookup_map[canonicalize(prop_preferred_full_name)] = prop_enum
     152          for a in prop_aliases: self.property_lookup_map[canonicalize(a)] = prop_enum
     153          self.property_kind_map[prop_enum] = property_kind
     154
     155    def generate_PropertyAliases_h(self):
     156       f = cformat.open_header_file_for_write('PropertyAliases')
     157       cformat.write_imports(f, ["<string>", "<vector>", "<unordered_map>"])
     158       enum_text = cformat.multiline_fill(self.property_enum_name_list, ',')
     159       full_name_text = cformat.multiline_fill(['"%s"' % self.full_name_map[e] for e in self.property_enum_name_list], ',')
     160       map_text = cformat.multiline_fill(['{"%s", %s}' % (k, self.property_lookup_map[k]) for k in sorted(self.property_lookup_map.keys())], ',')
     161       f.write(PropertyAliases_template % (enum_text, full_name_text, map_text))
     162       cformat.close_header_file(f)
     163
     164    def process_missing_spec_format_2(self, s):
     165      UCD_property_value_missing_regexp = re.compile("^#\s*@missing:\s*([0-9A-F]{4,6})[.][.]([0-9A-F]{4,6})\s*;\s*([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.<> ]+)\s*([^#]*)")
     166      m = UCD_property_value_missing_regexp.match(s)
     167      if m:
     168        if m.group(1) != '0000' or m.group(2) != '10FFFF': raise Exception("Bad missing spec: " + s)
     169        cname = canonicalize(m.group(3))
     170        if not self.property_lookup_map.has_key(cname): raise Exception("Bad missing property: " + s)
     171        self.missing_specs[self.property_lookup_map[cname]] = m.group(4)
    190172#
    191173#  UCD Property File Format 2: property value aliases
     
    204186#      non-enumerated types
    205187
    206         def parse_PropertyValueAlias_txt(self):
    207             UCD_property_value_alias_regexp = re.compile("^([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.]+)([^#]*)")
    208             self.property_value_list = {}
    209             self.property_value_enum_integer = {}
    210             self.property_value_full_name_map = {}
    211             self.property_value_lookup_map = {}
    212             f = open(self.UCD_dir + "/" + 'PropertyValueAliases.txt')
    213             lines = f.readlines()
    214             for t in lines:
    215                 if UCD_skip.match(t):
    216                   self.process_missing_spec_format_2(t)
    217                   continue  # skip comment and blank lines
    218                 m = UCD_property_value_alias_regexp.match(t)
    219                 if not m: raise Exception("Unknown property value alias syntax: %s" % t)
    220                 prop_code = canonicalize(m.group(1))
    221                 if not self.property_lookup_map.has_key(prop_code): raise Exception("Property code: '%s' is unknown" % prop_code)
    222                 else: prop_code = self.property_lookup_map[prop_code]
    223                 if not self.property_value_list.has_key(prop_code):
    224                   self.property_value_list[prop_code] = []
    225                   self.property_value_enum_integer[prop_code] = {}
    226                   self.property_value_full_name_map[prop_code] = {}
    227                   self.property_value_lookup_map[prop_code] = {}
    228                   enum_integer = 0
    229                 # Special case for ccc: second field is enum integer value
    230                 if prop_code == 'ccc':
    231                   enum_integer = int(m.group(2))
    232                   value_enum = m.group(3)
    233                   extra = m.group(4)
    234                   extra_list = re.findall("[-A-Za-z_0-9.]+", extra)
    235                   value_preferred_full_name = extra_list[0]
    236                   value_aliases = extra_list[1:]
    237                 # Special case for age: second field is numeric, third field is enum
    238                 # treat numeric value as an alias string
    239                 elif prop_code == 'age':
    240                   value_enum = m.group(3)
    241                   value_preferred_full_name = m.group(3)
    242                   extra = m.group(4)
    243                   value_aliases = [m.group(2)] + re.findall("[-A-Za-z_0-9]+", extra)
    244                 else:
    245                   value_enum = m.group(2)
    246                   value_preferred_full_name = m.group(3)
    247                   extra = m.group(4)
    248                   value_aliases = re.findall("[-A-Za-z_0-9]+", extra)
    249                 self.property_value_list[prop_code].append(value_enum)
    250                 self.property_value_enum_integer[prop_code][value_enum] = enum_integer
    251                 enum_integer += 1
    252                 self.property_value_full_name_map[prop_code][value_enum] = value_preferred_full_name
    253                 self.property_value_lookup_map[prop_code][canonicalize(value_enum)] = value_enum
    254                 self.property_value_lookup_map[prop_code][canonicalize(value_preferred_full_name)] = value_enum
    255                 for a in value_aliases: self.property_value_lookup_map[prop_code][canonicalize(a)] = value_enum
    256 
    257 
    258         def generate_PropertyValueAliases_h(self):
    259            f = cformat.open_header_file_for_write('PropertyValueAliases')
    260            cformat.write_imports(f, ["<string>", "<unordered_map>", '"PropertyAliases.h"'])
    261            f.write("namespace UCD {\n")
    262            #  Generate the aliases for all Binary properties.
    263            enum_text = cformat.multiline_fill(['N', 'Y'], ',', 6)
    264            full_name_text = cformat.multiline_fill(['"No"', '"Yes"'], ',', 6)
    265            binary_map_text = cformat.multiline_fill(['{"n", N}', '{"y", Y}', '{"no", N}', '{"yes", Y}', '{"f", N}', '{"t", Y}', '{"false", N}', '{"true", Y}'], ',', 6)
    266            f.write(EnumeratedProperty_template % ('Binary', enum_text, full_name_text, binary_map_text))
    267            #
    268            for p in self.property_enum_name_list:
    269              if self.property_value_list.has_key(p):
    270                if not self.property_kind_map[p] == 'Binary':
    271                  enum_text = cformat.multiline_fill(self.property_value_list[p], ',', 6)
    272                  if p == 'ccc': # Special case: add numeric value information for ccc.
    273                    enum_text += r"""
    274             };
    275             const uint8_t enum_val[] = {
    276         """
    277                    enum_text += "      " + cformat.multiline_fill(["%s" % (self.property_value_enum_integer[p][e]) for e in self.property_value_list['ccc']], ',', 6)
    278                  full_names = [self.property_value_full_name_map[p][e] for e in self.property_value_list[p]]
    279                  full_name_text = cformat.multiline_fill(['"%s"' % name for name in full_names], ',', 6)
    280                  canon_full_names = [canonicalize(name) for name in full_names]
    281                  aliases_only = [k for k in self.property_value_lookup_map[p].keys() if not canonicalize(k) in canon_full_names]
    282                  map_text = cformat.multiline_fill(['{"%s", %s::%s}' % (k, p.upper(), self.property_value_lookup_map[p][k]) for k in sorted(aliases_only)], ',', 6)
    283                  f.write(EnumeratedProperty_template % (p.upper(), enum_text, full_name_text, map_text))
    284            f.write("}\n")
    285            cformat.close_header_file(f)
    286 
    287      
    288         def generate_property_value_file(self, filename_root, property_code):
    289            canonical_property_value_map = self.property_value_lookup_map[property_code]
    290            (prop_values, value_map) = parse_UCD_codepoint_name_map(filename_root + '.txt', canonical_property_value_map)
    291            for v in self.property_value_list[property_code]:
    292               if not v in prop_values:
    293                  #raise Exception("Property %s value %s missing" % (self.full_name_map[property_code], v))
    294                  print("Property %s value %s missing" % (self.full_name_map[property_code], v))
    295                  value_map[v] = empty_uset()
    296            basename = os.path.basename(filename_root)
    297            f = cformat.open_header_file_for_write(os.path.basename(filename_root))
    298            cformat.write_imports(f, ["<vector>", '"unicode_set.h"', '"PropertyAliases.h"', '"PropertyValueAliases.h"'])
    299            f.write("\nnamespace UCD {\n")
    300            f.write("  namespace %s {\n" % property_code.upper())
    301            all_explicit_values = union_of_all([value_map[v] for v in self.property_value_list[property_code]])
    302            missing_values = uset_complement(all_explicit_values)
    303            if self.missing_specs.has_key(property_code):
    304              default = canonicalize(self.missing_specs[property_code])
    305              if not self.property_value_lookup_map[property_code].has_key(default): raise Exception("Cannot process default specification '%s'" % default)
    306              default_key = self.property_value_lookup_map[property_code][default]
    307              value_map[default_key] = uset_union(value_map[default_key], missing_values) 
    308 #
    309 #
    310            if property_code == 'gc':
    311              value_map['LC'] = union_of_all([value_map[v] for v in ['Lu', 'Ll', 'Lt']])
    312              value_map['L'] = union_of_all([value_map[v] for v in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo']])
    313              value_map['M'] = union_of_all([value_map[v] for v in ['Mn', 'Mc', 'Me']])
    314              value_map['N'] = union_of_all([value_map[v] for v in ['Nd', 'Nl', 'No']])
    315              value_map['P'] = union_of_all([value_map[v] for v in ['Pc', 'Pd', 'Ps', 'Pe', 'Pi', 'Pf', 'Po']])
    316              value_map['S'] = union_of_all([value_map[v] for v in ['Sm', 'Sc', 'Sk', 'So']])
    317              value_map['Z'] = union_of_all([value_map[v] for v in ['Zs', 'Zl', 'Zp']])
    318              value_map['C'] = union_of_all([value_map[v] for v in ['Cc', 'Cf', 'Cs', 'Co', 'Cn']])
    319            for v in self.property_value_list[property_code]:
    320              f.write("    const UnicodeSet %s_Set \n" % v.lower())
    321              f.write(value_map[v].showC(6) + ";\n")
    322            print "%s: %s bytes" % (basename, sum([value_map[v].bytes() for v in value_map.keys()]))
    323            if not self.missing_specs.has_key(property_code):
    324              f.write("    const UnicodeSet Missing_Set \n")
    325              f.write(missing_values.showC(6) + ";\n")
    326            set_list = ['%s_Set' % v.lower() for v in self.property_value_list[property_code]]
    327            f.write("    const EnumeratedPropertyObject property_object\n")
    328            f.write("      {%s,\n" % property_code)
    329            f.write("       %s::value_names,\n" % property_code.upper())
    330            f.write("       %s::aliases_only_map,\n" % property_code.upper())
    331            f.write("       {")
    332            f.write(cformat.multiline_fill(set_list, ',', 8))
    333            f.write("\n       }};\n  }\n}\n")
    334            cformat.close_header_file(f)
    335            self.supported_props.append(property_code)
    336            self.property_data_headers.append(basename)
    337 
    338         def generate_binary_properties_file(self, filename_root):
    339            (props, prop_map) = parse_UCD_codepoint_name_map(filename_root + '.txt', self.property_lookup_map)
    340            basename = os.path.basename(filename_root)
    341            f = cformat.open_header_file_for_write(basename)
    342            cformat.write_imports(f, ["<vector>", '"unicode_set.h"', '"PropertyAliases.h"'])
    343            f.write("\nnamespace UCD {\n")
    344            print "%s: %s bytes" % (basename, sum([prop_map[p].bytes() for p in prop_map.keys()]))
    345            for p in sorted(props):
    346              f.write("  namespace %s {\n    const UnicodeSet codepoint_set \n" % p.upper())
    347              f.write(prop_map[p].showC(6) + ";\n")
    348              f.write("    const BinaryPropertyObject property_object{%s, codepoint_set};\n  }\n" % p)
    349            f.write("}\n\n")
    350            cformat.close_header_file(f)
    351            self.supported_props += props
    352            self.property_data_headers.append(basename)
    353 
    354         def generate_PropertyObjectTable_h(self):
    355            f = cformat.open_header_file_for_write('PropertyObjectTable')
    356            cformat.write_imports(f, ['"PropertyObjects.h"', '"PropertyAliases.h"'])
    357            cformat.write_imports(f, ['"%s.h"' % fname for fname in self.property_data_headers])
    358            f.write("\nnamespace UCD {\n")
    359            objlist = []
    360            for p in self.property_enum_name_list:
    361              k = self.property_kind_map[p]
    362              if (k == 'Enumerated' or k == 'Catalog') and p in self.supported_props:
    363                 objlist.append("&%s::property_object" % p.upper())
    364              elif k == 'String':
    365                 if p in CodepointProperties:
    366                   objlist.append("new UnsupportedPropertyObject(%s, CodepointProperty)" % p)
    367                 else:
    368                   objlist.append("new UnsupportedPropertyObject(%s, StringProperty)" % p)
    369              elif k == 'Binary' and p in self.supported_props:
    370                 objlist.append("&%s::property_object" % p.upper())
    371              else:
    372                 objlist.append("new UnsupportedPropertyObject(%s, %sProperty)" % (p, k))
    373            f.write("\n  const PropertyObject* property_object_table[] = {\n    ")
    374            f.write(",\n    ".join(objlist) + '  };\n}\n')
    375            cformat.close_header_file(f)
     188    def parse_PropertyValueAlias_txt(self):
     189        UCD_property_value_alias_regexp = re.compile("^([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.]+)\s*;\s*([-A-Za-z_0-9.]+)([^#]*)")
     190        self.property_value_list = {}
     191        self.property_value_enum_integer = {}
     192        self.property_value_full_name_map = {}
     193        self.property_value_lookup_map = {}
     194        f = open(self.UCD_dir + "/" + 'PropertyValueAliases.txt')
     195        lines = f.readlines()
     196        for t in lines:
     197            if UCD_skip.match(t):
     198              self.process_missing_spec_format_2(t)
     199              continue  # skip comment and blank lines
     200            m = UCD_property_value_alias_regexp.match(t)
     201            if not m: raise Exception("Unknown property value alias syntax: %s" % t)
     202            prop_code = canonicalize(m.group(1))
     203            if not self.property_lookup_map.has_key(prop_code): raise Exception("Property code: '%s' is unknown" % prop_code)
     204            else: prop_code = self.property_lookup_map[prop_code]
     205            if not self.property_value_list.has_key(prop_code):
     206              self.property_value_list[prop_code] = []
     207              self.property_value_enum_integer[prop_code] = {}
     208              self.property_value_full_name_map[prop_code] = {}
     209              self.property_value_lookup_map[prop_code] = {}
     210              enum_integer = 0
     211            # Special case for ccc: second field is enum integer value
     212            if prop_code == 'ccc':
     213              enum_integer = int(m.group(2))
     214              value_enum = m.group(3)
     215              extra = m.group(4)
     216              extra_list = re.findall("[-A-Za-z_0-9.]+", extra)
     217              value_preferred_full_name = extra_list[0]
     218              value_aliases = extra_list[1:]
     219            # Special case for age: second field is numeric, third field is enum
     220            # treat numeric value as an alias string
     221            elif prop_code == 'age':
     222              value_enum = m.group(3)
     223              value_preferred_full_name = m.group(3)
     224              extra = m.group(4)
     225              value_aliases = [m.group(2)] + re.findall("[-A-Za-z_0-9]+", extra)
     226            else:
     227              value_enum = m.group(2)
     228              value_preferred_full_name = m.group(3)
     229              extra = m.group(4)
     230              value_aliases = re.findall("[-A-Za-z_0-9]+", extra)
     231            self.property_value_list[prop_code].append(value_enum)
     232            self.property_value_enum_integer[prop_code][value_enum] = enum_integer
     233            enum_integer += 1
     234            self.property_value_full_name_map[prop_code][value_enum] = value_preferred_full_name
     235            self.property_value_lookup_map[prop_code][canonicalize(value_enum)] = value_enum
     236            self.property_value_lookup_map[prop_code][canonicalize(value_preferred_full_name)] = value_enum
     237            for a in value_aliases: self.property_value_lookup_map[prop_code][canonicalize(a)] = value_enum
     238
     239
     240    def generate_PropertyValueAliases_h(self):
     241       f = cformat.open_header_file_for_write('PropertyValueAliases')
     242       cformat.write_imports(f, ["<string>", "<unordered_map>", '"PropertyAliases.h"'])
     243       f.write("namespace UCD {\n")
     244       #  Generate the aliases for all Binary properties.
     245       enum_text = cformat.multiline_fill(['N', 'Y'], ',', 6)
     246       full_name_text = cformat.multiline_fill(['"No"', '"Yes"'], ',', 6)
     247       binary_map_text = cformat.multiline_fill(['{"n", N}', '{"y", Y}', '{"no", N}', '{"yes", Y}', '{"f", N}', '{"t", Y}', '{"false", N}', '{"true", Y}'], ',', 6)
     248       f.write(EnumeratedProperty_template % ('Binary', enum_text, full_name_text, binary_map_text))
     249       #
     250       for p in self.property_enum_name_list:
     251         if self.property_value_list.has_key(p):
     252           if not self.property_kind_map[p] == 'Binary':
     253             enum_text = cformat.multiline_fill(self.property_value_list[p], ',', 6)
     254             if p == 'ccc': # Special case: add numeric value information for ccc.
     255               enum_text += r"""
     256        };
     257        const uint8_t enum_val[] = {
     258    """
     259               enum_text += "      " + cformat.multiline_fill(["%s" % (self.property_value_enum_integer[p][e]) for e in self.property_value_list['ccc']], ',', 6)
     260             full_names = [self.property_value_full_name_map[p][e] for e in self.property_value_list[p]]
     261             full_name_text = cformat.multiline_fill(['"%s"' % name for name in full_names], ',', 6)
     262             canon_full_names = [canonicalize(name) for name in full_names]
     263             aliases_only = [k for k in self.property_value_lookup_map[p].keys() if not canonicalize(k) in canon_full_names]
     264             map_text = cformat.multiline_fill(['{"%s", %s::%s}' % (k, p.upper(), self.property_value_lookup_map[p][k]) for k in sorted(aliases_only)], ',', 6)
     265             f.write(EnumeratedProperty_template % (p.upper(), enum_text, full_name_text, map_text))
     266       f.write("}\n")
     267       cformat.close_header_file(f)
     268
     269 
     270    def generate_property_value_file(self, filename_root, property_code):
     271       canonical_property_value_map = self.property_value_lookup_map[property_code]
     272       (prop_values, value_map) = parse_UCD_codepoint_name_map(filename_root + '.txt', canonical_property_value_map)
     273       for v in self.property_value_list[property_code]:
     274          if not v in prop_values:
     275             #raise Exception("Property %s value %s missing" % (self.full_name_map[property_code], v))
     276             print("Property %s value %s missing" % (self.full_name_map[property_code], v))
     277             value_map[v] = empty_uset()
     278       basename = os.path.basename(filename_root)
     279       f = cformat.open_header_file_for_write(os.path.basename(filename_root))
     280       cformat.write_imports(f, ["<vector>", '"unicode_set.h"', '"PropertyAliases.h"', '"PropertyValueAliases.h"'])
     281       f.write("\nnamespace UCD {\n")
     282       f.write("  namespace %s {\n" % property_code.upper())
     283       all_explicit_values = union_of_all([value_map[v] for v in self.property_value_list[property_code]])
     284       missing_values = uset_complement(all_explicit_values)
     285       if self.missing_specs.has_key(property_code):
     286         default = canonicalize(self.missing_specs[property_code])
     287         if not self.property_value_lookup_map[property_code].has_key(default): raise Exception("Cannot process default specification '%s'" % default)
     288         default_key = self.property_value_lookup_map[property_code][default]
     289         value_map[default_key] = uset_union(value_map[default_key], missing_values)   
     290       if property_code == 'gc':
     291         # special logic for derived categories
     292         value_map['LC'] = union_of_all([value_map[v] for v in ['Lu', 'Ll', 'Lt']])
     293         value_map['L'] = union_of_all([value_map[v] for v in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo']])
     294         value_map['M'] = union_of_all([value_map[v] for v in ['Mn', 'Mc', 'Me']])
     295         value_map['N'] = union_of_all([value_map[v] for v in ['Nd', 'Nl', 'No']])
     296         value_map['P'] = union_of_all([value_map[v] for v in ['Pc', 'Pd', 'Ps', 'Pe', 'Pi', 'Pf', 'Po']])
     297         value_map['S'] = union_of_all([value_map[v] for v in ['Sm', 'Sc', 'Sk', 'So']])
     298         value_map['Z'] = union_of_all([value_map[v] for v in ['Zs', 'Zl', 'Zp']])
     299         value_map['C'] = union_of_all([value_map[v] for v in ['Cc', 'Cf', 'Cs', 'Co', 'Cn']])
     300       for v in self.property_value_list[property_code]:
     301         f.write("    const UnicodeSet %s_Set \n" % v.lower())
     302         f.write(value_map[v].showC(6) + ";\n")
     303       print "%s: %s bytes" % (basename, sum([value_map[v].bytes() for v in value_map.keys()]))
     304       if not self.missing_specs.has_key(property_code):
     305         f.write("    const UnicodeSet Missing_Set \n")
     306         f.write(missing_values.showC(6) + ";\n")
     307       set_list = ['%s_Set' % v.lower() for v in self.property_value_list[property_code]]
     308       f.write("    const EnumeratedPropertyObject property_object\n")
     309       f.write("      {%s,\n" % property_code)
     310       f.write("       %s::value_names,\n" % property_code.upper())
     311       f.write("       %s::aliases_only_map,\n" % property_code.upper())
     312       f.write("       {")
     313       f.write(cformat.multiline_fill(set_list, ',', 8))
     314       f.write("\n       }};\n  }\n}\n")
     315       cformat.close_header_file(f)
     316       self.supported_props.append(property_code)
     317       self.property_data_headers.append(basename)
     318
     319    def generate_ScriptExtensions_h(self):
     320       filename_root = 'ScriptExtensions'
     321       property_code = 'scx'
     322       canonical_property_value_map = self.property_value_lookup_map['sc']
     323       (scripts, script_map) = parse_UCD_codepoint_name_map('Scripts.txt', canonical_property_value_map)
     324       (scx_sets, scx_set_map) = parse_UCD_codepoint_name_map('ScriptExtensions.txt')
     325       value_map = {}
     326       basename = os.path.basename(filename_root)
     327       f = cformat.open_header_file_for_write(basename)
     328       cformat.write_imports(f, ["<vector>", '"PropertyAliases.h"', '"PropertyValueAliases.h"', '"unicode_set.h"'])
     329       f.write("\nusing namespace UCD;\n\n")
     330       explicitly_defined_set = empty_uset()
     331       for scx_list in scx_sets:
     332         scx_items = scx_list.split(" ")
     333         for scx in scx_items:
     334            #sc = canonical_property_value_map[canonicalize(scx)]
     335            sc = scx
     336            if value_map.has_key(sc):
     337               value_map[sc] = uset_union(value_map[sc], scx_set_map[scx_list])
     338            else: value_map[sc] = scx_set_map[scx_list]
     339         explicitly_defined_set = uset_union(explicitly_defined_set, scx_set_map[scx_list])
     340       for v in self.property_value_list['sc']:
     341          if value_map.has_key(v):
     342            value_map[v] = uset_union(value_map[v], uset_difference(script_map[v], explicitly_defined_set))
     343          elif script_map.has_key(v):
     344            value_map[v] = script_map[v]
     345          else: value_map[v] = empty_uset()
     346       for v in self.property_value_list['sc']:
     347         #v = canonical_property_value_map[canonicalize(v)]
     348         f.write("    const UnicodeSet %s_Ext \n" % v.lower())
     349         f.write(value_map[v].showC(6) + ";\n")
     350       print "%s: %s bytes" % (basename, sum([value_map[v].bytes() for v in value_map.keys()]))
     351       set_list = ['%s_Ext' % v.lower() for v in self.property_value_list['sc']]
     352       f.write("    const EnumeratedPropertyObject property_object\n")
     353       f.write("      {%s,\n" % property_code)
     354       f.write("       SC::value_names,\n")
     355       f.write("       SC:aliases_only_map,\n")
     356       f.write("       {")
     357       f.write(cformat.multiline_fill(set_list, ',', 8))
     358       f.write("\n       }};\n  }\n}\n")
     359       cformat.close_header_file(f)
     360       self.supported_props.append('property_code')
     361       self.property_data_headers.append(basename)
     362
     363
     364    def generate_binary_properties_file(self, filename_root):
     365       (props, prop_map) = parse_UCD_codepoint_name_map(filename_root + '.txt', self.property_lookup_map)
     366       basename = os.path.basename(filename_root)
     367       f = cformat.open_header_file_for_write(basename)
     368       cformat.write_imports(f, ["<vector>", '"unicode_set.h"', '"PropertyAliases.h"'])
     369       f.write("\nnamespace UCD {\n")
     370       print "%s: %s bytes" % (basename, sum([prop_map[p].bytes() for p in prop_map.keys()]))
     371       for p in sorted(props):
     372         f.write("  namespace %s {\n    const UnicodeSet codepoint_set \n" % p.upper())
     373         f.write(prop_map[p].showC(6) + ";\n")
     374         f.write("    const BinaryPropertyObject property_object{%s, codepoint_set};\n  }\n" % p)
     375       f.write("}\n\n")
     376       cformat.close_header_file(f)
     377       self.supported_props += props
     378       self.property_data_headers.append(basename)
     379
     380    def generate_PropertyObjectTable_h(self):
     381       f = cformat.open_header_file_for_write('PropertyObjectTable')
     382       cformat.write_imports(f, ['"PropertyObjects.h"', '"PropertyAliases.h"'])
     383       cformat.write_imports(f, ['"%s.h"' % fname for fname in self.property_data_headers])
     384       f.write("\nnamespace UCD {\n")
     385       objlist = []
     386       for p in self.property_enum_name_list:
     387         k = self.property_kind_map[p]
     388         if (k == 'Enumerated' or k == 'Catalog') and p in self.supported_props:
     389            objlist.append("&%s::property_object" % p.upper())
     390         elif k == 'String':
     391            if p in CodepointProperties:
     392              objlist.append("new UnsupportedPropertyObject(%s, CodepointProperty)" % p)
     393            else:
     394              objlist.append("new UnsupportedPropertyObject(%s, StringProperty)" % p)
     395         elif k == 'Binary' and p in self.supported_props:
     396            objlist.append("&%s::property_object" % p.upper())
     397         else:
     398            objlist.append("new UnsupportedPropertyObject(%s, %sProperty)" % (p, k))
     399       f.write("\n  const PropertyObject* property_object_table[] = {\n    ")
     400       f.write(",\n    ".join(objlist) + '  };\n}\n')
     401       cformat.close_header_file(f)
    376402
    377403
     
    398424   #
    399425   # Script Extensions
    400    #generate_ScriptExtensions_h()
     426   ucd.generate_ScriptExtensions_h()
    401427   #
    402428   # General Category
Note: See TracChangeset for help on using the changeset viewer.