FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
fetch_language_identifiers.py
1#!/bin/env python3
2#
3# This is a helper script that fetches the current language and keyboard tables
4# and writes the result to a C compatible struct.
5#
6import os
7import sys
8import requests
9import numpy as np
10import traceback
11from bs4 import BeautifulSoup
12from bs4 import element
13
14intro = '''/* This file is auto generated from
15 *
16 * https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings
17 *
18 * please do not edit but use ./scripts/fetch_language_identifiers.py to regenerate!
19 */
20
21'''
22
23def parse_html(text):
24 soup = BeautifulSoup(text, 'html.parser')
25 table = soup.find("table")
26 head = table.find('thead').find('tr')
27 headers = []
28 for th in head:
29 if type(th) == element.Tag:
30 headers += th
31
32 body = table.find('tbody')
33 languages = []
34
35 for tr in body:
36 if type(tr) == element.Tag:
37 entry = []
38 for th in tr:
39 if type(th) == element.Tag:
40 if th.string:
41 entry += [th.string]
42 else:
43 entry += ['']
44 languages += [entry]
45 return [headers, languages]
46
47def is_base(num, base):
48 try:
49 v = int(num, base)
50 return True
51 except ValueError:
52 return False
53
54def padhexa(v):
55 s = hex(v)
56 return '0x' + s[2:].zfill(8)
57
58def write_struct(fp, struct, name, url, base, inv = False, typemap = None):
59 li = requests.get(url)
60 if li.status_code != requests.codes.ok:
61 print('Could not fetch ' + str(url) + ', response code ' + str(li.status_code))
62 sys.exit(1)
63 headers, languages = parse_html(li.text)
64
65 fp.write('const ' + str(struct) + ' ' + str(name) + '[] =\n')
66 fp.write('{\n')
67 fp.write('/* ')
68 for h in headers:
69 fp.write('\t[')
70 fp.write(h)
71 fp.write(']\t')
72 fp.write('*/\n')
73 last = [None] * 32
74 for language in languages:
75 fp.write('\t{ ')
76 line = ''
77 pos = 0
78 for e in language:
79 try:
80 v = int(e, base=base)
81 switcher = {
82 0: padhexa(v),
83 2: bin(v),
84 8: oct(v),
85 10: str(v),
86 16: padhexa(v)
87 }
88 h = str(switcher.get(base))
89 if h != "None":
90 last[pos] = h
91 if inv:
92 line = h + ', ' + line
93 else:
94 line += h + ', '
95 except ValueError:
96 if typemap and typemap[pos] != str:
97 line += str(last[pos]) + ',\t'
98 else:
99 if e == "":
100 line += '"' + str(last[pos]) + '",\t'
101 else:
102 line += '"' + e + '",\t'
103 if e != "None":
104 last[pos] = str(e)
105 pos = pos + 1
106 fp.write(line[:-2] + '},\n')
107 fp.write('};\n')
108 fp.write('\n')
109
110def update_lang_identifiers(fp):
111# [Language identifier] [Primary language] [Prim. lang. identifier] [Prim. lang. symbol] [Sublanguage] [Sublang. identifier] [Sublang. symbol]
112 write_struct(fp, 'LanguageIdentifier', 'language_identifiers', 'https://docs.microsoft.com/en-us/windows/win32/intl/language-identifier-constants-and-strings', 16, False, [int, str, int, str, str, int, str])
113
114def update_code_pages(fp):
115 write_struct(fp, 'CodePage', 'code_pages', 'https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers', 10)
116
117def update_input_locales(fp):
118 write_struct(fp, 'KeyboardIdentifier', 'keyboard_identifiers', 'https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc766503(v=ws.10)', 0)
119 write_struct(fp, 'RDP_KEYBOARD_LAYOUT', 'RDP_KEYBOARD_LAYOUT_TABLE', 'https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values', 16, True)
120
121try:
122 with open('language_identifiers.c', 'w') as fp:
123 fp.write(intro)
124 update_lang_identifiers(fp)
125 update_code_pages(fp)
126 update_input_locales(fp)
127except:
128 print('exception cought')
129 traceback.print_exc()