make_uts46_mapping_table.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # Copyright 2013-2014 The rust-url developers.
  2. #
  3. # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  4. # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  5. # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  6. # option. This file may not be copied, modified, or distributed
  7. # except according to those terms.
  8. # Run as: python make_uts46_mapping_table.py IdnaMappingTable.txt > uts46_mapping_table.rs
  9. # You can get the latest idna table from
  10. # http://www.unicode.org/Public/idna/latest/IdnaMappingTable.txt
  11. import collections
  12. import itertools
  13. print('''\
  14. // Copyright 2013-2014 The rust-url developers.
  15. //
  16. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  17. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  18. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  19. // option. This file may not be copied, modified, or distributed
  20. // except according to those terms.
  21. // Generated by make_idna_table.py
  22. static TABLE: &'static [Range] = &[
  23. ''')
  24. txt = open("IdnaMappingTable.txt")
  25. def escape_char(c):
  26. return "\\u{%x}" % ord(c[0])
  27. def char(s):
  28. return unichr(int(s, 16))
  29. strtab = collections.OrderedDict()
  30. strtab_offset = 0
  31. def strtab_slice(s):
  32. global strtab, strtab_offset
  33. if s in strtab:
  34. return strtab[s]
  35. else:
  36. utf8_len = len(s.encode('utf8'))
  37. c = (strtab_offset, utf8_len)
  38. strtab[s] = c
  39. strtab_offset += utf8_len
  40. return c
  41. def rust_slice(s):
  42. return "(StringTableSlice { byte_start: %d, byte_len: %d })" % s
  43. for line in txt:
  44. # remove comments
  45. line, _, _ = line.partition('#')
  46. # skip empty lines
  47. if len(line.strip()) == 0:
  48. continue
  49. fields = line.split(';')
  50. if fields[0].strip() == 'D800..DFFF':
  51. continue # Surrogates don't occur in Rust strings.
  52. first, _, last = fields[0].strip().partition('..')
  53. if not last:
  54. last = first
  55. mapping = fields[1].strip().replace('_', ' ').title().replace(' ', '')
  56. if len(fields) > 2:
  57. if fields[2].strip():
  58. unicode_str = u''.join(char(c) for c in fields[2].strip().split(' '))
  59. mapping += rust_slice(strtab_slice(unicode_str))
  60. elif mapping == "Deviation":
  61. mapping += rust_slice(strtab_slice(''))
  62. print(" Range { from: '%s', to: '%s', mapping: %s }," % (escape_char(char(first)),
  63. escape_char(char(last)),
  64. mapping))
  65. print("];\n")
  66. def escape_str(s):
  67. return [escape_char(c) for c in s]
  68. print("static STRING_TABLE: &'static str = \"%s\";"
  69. % '\\\n '.join(itertools.chain(*[escape_str(s) for s in strtab.iterkeys()])))