mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
(intl) Pair every packed translation row with the enum ids[] names for it
intl/msg_hash_<lang>.h pairs its blob against its ids[] by position and by nothing else: msg_hash_strtab_index_build() walks the blob once and gives row N to ids[N]. Two rows sitting in twenty-nine blobs with no ids[] entry of their own shift every row that follows them, so each of those languages shows real translated strings belonging to other menu entries from the audio device row onward. The rows go, and the contiguity constants come down with them. tools/msg_hash_packed_check.py holds the invariant from here on. Member names are the djb2 hash of the key their row was emitted for, so it re-derives the pairing and compares it against ids[] row for row under the guards, together with each member's width, embedded NULs, and the sizeof() constant that tells a padding compiler to fail the build. Reading the headers rather than building them means one run covers every language and every #ifdef configuration, which no build job can do and which an English-only test cannot see at all, msg_hash_us.c being a switch rather than a packed table. intl/json2h.py runs the check on its own output before writing, and Msg-Hash-Packed-Check.yml runs it on the tree.
This commit is contained in:
1 parent
1666330910
commit
ae4d627adb
32 files changed
+501
-170
No files matched your search
@@ -0,0 +1,79 @@
|
||||
name: CI msg_hash packed tables
|
||||
|
||||
# intl/msg_hash_<lang>.h is generated as two objects that are paired by
|
||||
# position: the blob struct holds every row as one run of NUL-terminated
|
||||
# strings, and ids[] names the enum each row belongs to.
|
||||
# msg_hash_strtab_index_build() walks the blob once and hands row N to
|
||||
# ids[N].
|
||||
#
|
||||
# Nothing in the C ties them together. Both objects are well formed on
|
||||
# their own, and the sizeof() contiguity check inside the header only
|
||||
# measures the blob against itself, so a row removed from one side and
|
||||
# left on the other compiles clean everywhere and renames every row
|
||||
# after it at runtime. The menu then shows real translated strings
|
||||
# belonging to other entries - which is what #19534 reported, in every
|
||||
# language at once. English is unaffected, because msg_hash_us.c is a
|
||||
# switch rather than a packed table, so no English-language test, manual
|
||||
# or automated, can see it either.
|
||||
#
|
||||
# 5d0f721 did exactly that: retiring audio_block_frames took
|
||||
# MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES and its sublabel out of ids[]
|
||||
# in twenty-nine headers and left the two blob members behind. From the
|
||||
# audio device row onward every language was off by one or two.
|
||||
#
|
||||
# The check re-derives the pairing from the member names - json2h.py
|
||||
# names each member after the djb2 hash of the key its row was emitted
|
||||
# for - and compares it against ids[] row for row, under the guards. It
|
||||
# reads the files rather than building them, so it covers every
|
||||
# language and every #ifdef configuration at once, which no build job
|
||||
# does. intl/json2h.py runs the same check on its own output before
|
||||
# writing, so this is the lane that catches a header edited by hand.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
msg-hash-packed-check:
|
||||
name: blob and ids[] pairing
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Checker self-test
|
||||
shell: bash
|
||||
run: |
|
||||
set -eu
|
||||
# Fixture pass: a consistent table is clean, 5d0f721's shape
|
||||
# (a row dropped from ids[] only) is caught, so is its mirror,
|
||||
# a member one byte wider than its string, a guard present on
|
||||
# one side only, and a contiguity constant left stale.
|
||||
#
|
||||
# The fixtures are built by the checker rather than lifted
|
||||
# from intl/, so this reports the same thing whether or not
|
||||
# the shipped headers currently pass - it is measuring the
|
||||
# checker, not the tree.
|
||||
python3 tools/msg_hash_packed_check.py --selftest
|
||||
|
||||
- name: Tree check
|
||||
shell: bash
|
||||
run: |
|
||||
set -eu
|
||||
# Every packed header: row N's member name must be what the
|
||||
# key in ids[N] hashes to and carry the same guard, each
|
||||
# member must be exactly its string plus the NUL (or exactly
|
||||
# the chunk, for a non-final chunk of a split row), no row may
|
||||
# hold an embedded NUL, and the sizeof() check must still add
|
||||
# up to the members it guards.
|
||||
python3 tools/msg_hash_packed_check.py
|
||||
+22
-2
@@ -572,6 +572,25 @@ def pack(text, lang, source=None):
|
||||
out.append('')
|
||||
return '\n'.join(out)
|
||||
|
||||
def verify(text, lang, name):
|
||||
"""Refuse to write a header whose blob and ids[] disagree.
|
||||
|
||||
The two are paired by position at runtime and by nothing the
|
||||
compiler can check, so tools/msg_hash_packed_check.py re-derives the
|
||||
pairing from the member names and the guards. Running it here means
|
||||
a header in the tree has passed it whatever route it arrived by.
|
||||
"""
|
||||
sys.path.insert(0, os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), '..', 'tools'))
|
||||
import msg_hash_packed_check
|
||||
errors = msg_hash_packed_check.check_text(text, lang, name)
|
||||
if errors:
|
||||
for e in errors:
|
||||
print(e, file=sys.stderr)
|
||||
raise SystemExit('packed emitter: %s failed verification' % name)
|
||||
return text
|
||||
|
||||
|
||||
LANG = h_basename.replace('msg_hash_', '').replace('.h', '')
|
||||
|
||||
if repack_mode:
|
||||
@@ -587,7 +606,7 @@ if repack_mode:
|
||||
sys.exit(0)
|
||||
raise SystemExit('packed emitter: no MSG_HASH rows in ' + h_filename)
|
||||
with open(h_filename, 'w', encoding='utf-8') as f:
|
||||
f.write(pack(text, LANG))
|
||||
f.write(verify(pack(text, LANG), LANG, h_filename))
|
||||
sys.exit(0)
|
||||
|
||||
with open('msg_hash_us.h', 'r', encoding='utf-8') as template_file:
|
||||
@@ -601,5 +620,6 @@ with open('msg_hash_us.h', 'r', encoding='utf-8') as template_file:
|
||||
h_file.seek(0)
|
||||
_src_bytes = dict((k, v.encode('utf-8'))
|
||||
for k, v in source_messages.items())
|
||||
h_file.write(pack(new_translation, LANG, _src_bytes))
|
||||
h_file.write(verify(pack(new_translation, LANG, _src_bytes),
|
||||
LANG, h_filename))
|
||||
h_file.truncate()
|
||||
+1
-3
@@ -138,7 +138,6 @@ static const struct
|
||||
char s_e011fe61[79];
|
||||
#endif
|
||||
char s_12e77e8f[13];
|
||||
char s_af6007a1[24];
|
||||
char s_da068369[13];
|
||||
char s_daead8a5[31];
|
||||
char s_48c208ee[15];
|
||||
@@ -2767,7 +2766,6 @@ static const struct
|
||||
"\210\331\211",
|
||||
#endif
|
||||
"\330\247\331\204\330\243\330\265\331\210\331\204",
|
||||
"\330\255\330\270\330\261 \330\247\331\204\330\245\330\267\330\247\330\261\330\247\330\252",
|
||||
"\330\247\331\204\330\254\331\207\330\247\330\262",
|
||||
"\331\206\330\270\330\247\331\205 \330\252\330\264\330\272\331\212\331\204 \330\247\331\204\330"
|
||||
"\265\331\210\330\252",
|
||||
@@ -7925,7 +7923,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ar_blob_check[
|
||||
(sizeof(msg_hash_ar_blob) == (107560u
|
||||
(sizeof(msg_hash_ar_blob) == (107536u
|
||||
#ifdef HAVE_LAKKA
|
||||
+ 287u
|
||||
#endif
|
||||
|
||||
+1
-4
@@ -267,7 +267,6 @@ static const struct
|
||||
char s_4e447c6c[57];
|
||||
char s_d9a51d02[30];
|
||||
char s_12e77e8f[15];
|
||||
char s_af6007a1[29];
|
||||
char s_da068369[15];
|
||||
char s_daead8a5[11];
|
||||
char s_48c208ee[19];
|
||||
@@ -5455,8 +5454,6 @@ static const struct
|
||||
"\320\227\320\275\320\260\321\207\320\276\320\272 \320\277\321\200\320\260\320\263\321\200\320"
|
||||
"\260\320\274\321\213",
|
||||
"\320\240\321\215\321\201\321\203\321\200\321\201\321\213",
|
||||
"\320\244\321\200\321\215\320\271\320\274\320\260\321\236 \321\203 \320\261\320\273\320\276\320"
|
||||
"\272\321\203",
|
||||
"\320\237\321\200\321\213\320\273\320\260\320\264\320\260",
|
||||
"\320\220\321\236\320\264\321\213\321\217",
|
||||
"\320\243\320\261\321\203\320\264\320\276\320\262\320\260 DSP",
|
||||
@@ -16577,7 +16574,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_be_blob_check[
|
||||
(sizeof(msg_hash_be_blob) == (261629u
|
||||
(sizeof(msg_hash_be_blob) == (261600u
|
||||
#ifdef ANDROID
|
||||
+ 531u
|
||||
#endif
|
||||
|
||||
+1
-7
@@ -265,7 +265,6 @@ static const struct
|
||||
char s_12e77e8f[9];
|
||||
char s_98760b94[40];
|
||||
char s_b81eb68d[23];
|
||||
char s_af6007a1[22];
|
||||
char s_da068369[11];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[14];
|
||||
@@ -2414,7 +2413,6 @@ static const struct
|
||||
char s_310ec7bd[72];
|
||||
char s_5832a2c2[111];
|
||||
char s_6f6e337b[402];
|
||||
char s_f47e544f[243];
|
||||
char s_20cc6597[92];
|
||||
char s_21b0bad3[57];
|
||||
char s_66e9521c[80];
|
||||
@@ -4647,7 +4645,6 @@ static const struct
|
||||
"Recursos",
|
||||
"Obre el panell de configuraci\303\263 de ASIO",
|
||||
"Canals de sortida ASIO",
|
||||
"Bloquejant fotogrames",
|
||||
"Dispositiu",
|
||||
"\303\200udio",
|
||||
"Connector DSP",
|
||||
@@ -6836,9 +6833,6 @@ static const struct
|
||||
"imera parella no sempre \303\251s la que tenen els altaveus o auriculars. Trieu la parella que c"
|
||||
"oincideixi amb els jacks que esteu escoltant, tal com els anomena el dispositiu. Els dispositius"
|
||||
" de dues sortides nom\303\251s tenen 1-2.",
|
||||
"Nombre de fotogrames que el controlador d'\303\240udio mou per bloc. L'opci\303\263 0 pregunta a"
|
||||
"l controlador pel seu propi valor, el qual \303\251s el millor valor per moltes configuracions; "
|
||||
"un valor alt augmenta la lat\303\250ncia a canvi de reduir les estrebades.",
|
||||
"For\303\247a el dispositiu que fa servir el controlador d\342\200\231\303\240udio. Aix\303\262 d"
|
||||
"ep\303\250n del controlador.",
|
||||
"Controlador d'\303\240udio que es far\303\240 servir (cal reiniciar)",
|
||||
@@ -9344,7 +9338,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ca_blob_check[
|
||||
(sizeof(msg_hash_ca_blob) == (203358u
|
||||
(sizeof(msg_hash_ca_blob) == (203093u
|
||||
#ifdef ANDROID
|
||||
+ 281u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -258,7 +258,6 @@ static const struct
|
||||
char s_4e447c6c[31];
|
||||
char s_d9a51d02[11];
|
||||
char s_12e77e8f[7];
|
||||
char s_af6007a1[7];
|
||||
char s_da068369[7];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[11];
|
||||
@@ -4834,7 +4833,6 @@ static const struct
|
||||
"\346\226\271\346\263\225",
|
||||
"App \345\233\276\346\240\207",
|
||||
"\347\264\240\346\235\220",
|
||||
"\345\235\227\345\270\247",
|
||||
"\350\256\276\345\244\207",
|
||||
"\351\237\263\351\242\221",
|
||||
"DSP \346\217\222\344\273\266",
|
||||
@@ -11144,7 +11142,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_chs_blob_check[
|
||||
(sizeof(msg_hash_chs_blob) == (128254u
|
||||
(sizeof(msg_hash_chs_blob) == (128247u
|
||||
#ifdef ANDROID
|
||||
+ 220u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -243,7 +243,6 @@ static const struct
|
||||
#endif
|
||||
char s_4e447c6c[38];
|
||||
char s_12e77e8f[13];
|
||||
char s_af6007a1[13];
|
||||
char s_da068369[7];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[13];
|
||||
@@ -4494,7 +4493,6 @@ static const struct
|
||||
"\346\216\247\345\210\266\345\231\250\346\226\267\351\226\213\350\247\243\346\261\272\346\226\271"
|
||||
"\346\263\225 (Android)",
|
||||
"\351\201\270\345\226\256\344\270\273\351\241\214",
|
||||
"\345\215\200\345\241\212\345\271\200\346\225\270",
|
||||
"\350\243\235\347\275\256",
|
||||
"\351\237\263\346\225\210",
|
||||
"\351\237\263\350\250\212\346\217\222\344\273\266",
|
||||
@@ -10470,7 +10468,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_cht_blob_check[
|
||||
(sizeof(msg_hash_cht_blob) == (121375u
|
||||
(sizeof(msg_hash_cht_blob) == (121362u
|
||||
#ifdef ANDROID
|
||||
+ 157u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -256,7 +256,6 @@ static const struct
|
||||
char s_4e447c6c[29];
|
||||
char s_d9a51d02[15];
|
||||
char s_12e77e8f[12];
|
||||
char s_af6007a1[17];
|
||||
char s_da068369[12];
|
||||
char s_daead8a5[5];
|
||||
char s_a38cafbb[21];
|
||||
@@ -4300,7 +4299,6 @@ static const struct
|
||||
"\305\230e\305\241en\303\255 odpojen\303\255 Androidu",
|
||||
"Ikona aplikace",
|
||||
"Prost\305\231edky",
|
||||
"Blokov\303\251 sn\303\255mky",
|
||||
"Za\305\231\303\255zen\303\255",
|
||||
"Zvuk",
|
||||
"Odstranit DSP Plugin",
|
||||
@@ -8807,7 +8805,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_cs_blob_check[
|
||||
(sizeof(msg_hash_cs_blob) == (163095u
|
||||
(sizeof(msg_hash_cs_blob) == (163078u
|
||||
#ifdef ANDROID
|
||||
+ 390u
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -263,7 +263,6 @@ static const struct
|
||||
char s_d9a51d02[10];
|
||||
char s_98760b94[27];
|
||||
char s_b81eb68d[20];
|
||||
char s_af6007a1[23];
|
||||
char s_da068369[12];
|
||||
char s_daead8a5[13];
|
||||
char s_48c208ee[11];
|
||||
@@ -2381,7 +2380,6 @@ static const struct
|
||||
char s_310ec7bd[80];
|
||||
char s_5832a2c2[108];
|
||||
char s_6f6e337b[441];
|
||||
char s_f47e544f[294];
|
||||
char s_20cc6597[110];
|
||||
char s_21b0bad3[54];
|
||||
char s_66e9521c[96];
|
||||
@@ -4628,7 +4626,6 @@ static const struct
|
||||
"Appsymbol",
|
||||
"ASIO Control Panel \303\266ffnen",
|
||||
"ASIO-Ausgabekan\303\244le",
|
||||
"Warte auf Audio-Frames",
|
||||
"Audioger\303\244t",
|
||||
"Audiotreiber",
|
||||
"DSP-Plugin",
|
||||
@@ -6777,10 +6774,6 @@ static const struct
|
||||
"e Lautsprecher oder Kopfh\303\266rer angeschlossen sind. Bitte das Paar ausw\303\244hlen, \303"
|
||||
"\274ber das geh\303\266rt wird \342\200\223 so wie vom Ger\303\244t benannt. Ger\303\244te mit z"
|
||||
"wei Ausg\303\244ngen haben nur die Paare 1 und 2.",
|
||||
"Anzahl der Frames, die der Audiotreiber pro Block verschiebt. Bei 0 wird der Treiber nach dem ge"
|
||||
"r\303\244tespezifischen Wert gefragt, was in den meisten Konfigurationen gew\303\274nscht ist; e"
|
||||
"in gr\303\266\303\237erer Block geht zu Lasten der Latenz, bietet daf\303\274r aber eine h\303"
|
||||
"\266here Ausfallsicherheit gegen Aussetzer.",
|
||||
"Das Standard-Audioger\303\244t, welches vom Audiotreiber verwendet wird, \303\274berschreiben. D"
|
||||
"ies ist treiberabh\303\244ngig.",
|
||||
"Zu verwendender Audiotreiber. (Neustart erforderlich)",
|
||||
@@ -9266,7 +9259,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_de_blob_check[
|
||||
(sizeof(msg_hash_de_blob) == (201319u
|
||||
(sizeof(msg_hash_de_blob) == (201002u
|
||||
#ifdef ANDROID
|
||||
+ 358u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -92,7 +92,6 @@ static const struct
|
||||
char s_826b2d88[60];
|
||||
char s_2e5078b2[55];
|
||||
char s_12e77e8f[17];
|
||||
char s_af6007a1[20];
|
||||
char s_da068369[24];
|
||||
char s_daead8a5[22];
|
||||
char s_48c208ee[30];
|
||||
@@ -1764,7 +1763,6 @@ static const struct
|
||||
"\275\316\267\317\204\316\256\317\202 \316\235\316\277\316\267\316\274\316\277\317\203\317\215"
|
||||
"\316\275\316\267\317\202",
|
||||
"\316\225\317\201\316\263\316\261\316\273\316\265\316\257\316\261",
|
||||
"\316\246\317\201\316\261\316\263\316\256 \316\232\316\261\317\201\316\255",
|
||||
"\316\243\317\205\317\203\316\272\316\265\317\205\316\256 \316\211\317\207\316\277\317\205",
|
||||
"\316\237\316\264\316\267\316\263\317\214\317\202 \316\211\317\207\316\277\317\205",
|
||||
"\316\240\317\201\317\214\317\203\316\270\316\265\317\204\316\277 \316\211\317\207\316\277\317"
|
||||
@@ -4745,7 +4743,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_el_blob_check[
|
||||
(sizeof(msg_hash_el_blob) == (68809u
|
||||
(sizeof(msg_hash_el_blob) == (68789u
|
||||
#ifdef HAVE_LAKKA
|
||||
+ 35u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -265,7 +265,6 @@ static const struct
|
||||
char s_d9a51d02[21];
|
||||
char s_12e77e8f[9];
|
||||
char s_98760b94[29];
|
||||
char s_af6007a1[17];
|
||||
char s_da068369[8];
|
||||
char s_daead8a5[5];
|
||||
char s_48c208ee[16];
|
||||
@@ -4612,7 +4611,6 @@ static const struct
|
||||
"Aplika\304\265a piktogramo",
|
||||
"Hava\304\265oj",
|
||||
"Malfermi stirpanelon de ASIO",
|
||||
"Baritaj filmeroj",
|
||||
"Aparato",
|
||||
"Sono",
|
||||
"Kroma\304\265o de DSP",
|
||||
@@ -9058,7 +9056,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_eo_blob_check[
|
||||
(sizeof(msg_hash_eo_blob) == (172566u
|
||||
(sizeof(msg_hash_eo_blob) == (172549u
|
||||
#ifdef ANDROID
|
||||
+ 312u
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -267,7 +267,6 @@ static const struct
|
||||
char s_12e77e8f[9];
|
||||
char s_98760b94[31];
|
||||
char s_b81eb68d[26];
|
||||
char s_af6007a1[30];
|
||||
char s_da068369[12];
|
||||
char s_48c208ee[11];
|
||||
char s_a38cafbb[18];
|
||||
@@ -2466,7 +2465,6 @@ static const struct
|
||||
char s_310ec7bd[74];
|
||||
char s_5832a2c2[106];
|
||||
char s_6f6e337b[484];
|
||||
char s_f47e544f[283];
|
||||
char s_20cc6597[99];
|
||||
char s_21b0bad3[79];
|
||||
char s_66e9521c[75];
|
||||
@@ -4735,7 +4733,6 @@ static const struct
|
||||
"Recursos",
|
||||
"Abrir panel de control de ASIO",
|
||||
"Canales de salida de ASIO",
|
||||
"Fotogramas por trama de audio",
|
||||
"Dispositivo",
|
||||
"Plugin DSP",
|
||||
"Quitar plugin DSP",
|
||||
@@ -6973,10 +6970,6 @@ static const struct
|
||||
"us altavoces o auriculares. Selecciona la pareja que coincida con las clavijas que est\303\251s "
|
||||
"escuchando seg\303\272n est\303\251n nombradas por el dispositivo. Los dispositivos con solo dos"
|
||||
" salidas solo tendr\303\241n las salidas 1-2.",
|
||||
"Indica la cantidad de fotogramas que mover\303\241 el controlador de audio por bloque. Un valor "
|
||||
"de 0 pedir\303\241 al controlador el valor del dispositivo, que es lo que esperan la mayor\303"
|
||||
"\255a de configuraciones; un valor m\303\241s grande compensa la resistencia contra p\303\251rdi"
|
||||
"das de audio con latencia.",
|
||||
"Fuerza el dispositivo que utilizar\303\241 el controlador de audio. Este ajuste depende del cont"
|
||||
"rolador.",
|
||||
"Selecciona el controlador de audio que se utilizar\303\241 (es necesario reiniciar).",
|
||||
@@ -9598,7 +9591,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_es_blob_check[
|
||||
(sizeof(msg_hash_es_blob) == (218493u
|
||||
(sizeof(msg_hash_es_blob) == (218180u
|
||||
#ifdef ANDROID
|
||||
+ 329u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -178,7 +178,6 @@ static const struct
|
||||
char s_4e447c6c[38];
|
||||
char s_d9a51d02[19];
|
||||
char s_12e77e8f[10];
|
||||
char s_af6007a1[14];
|
||||
char s_da068369[6];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[19];
|
||||
@@ -3661,7 +3660,6 @@ static const struct
|
||||
"Android-yhteyden katkaisun kiertotapa",
|
||||
"Sovelluksen kuvake",
|
||||
"Resurssit",
|
||||
"Est\303\244 kuvissa",
|
||||
"Laite",
|
||||
"\303\204\303\244ni",
|
||||
"DSP-liit\303\244nn\303\244inen",
|
||||
@@ -7457,7 +7455,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_fi_blob_check[
|
||||
(sizeof(msg_hash_fi_blob) == (124130u
|
||||
(sizeof(msg_hash_fi_blob) == (124116u
|
||||
#ifdef HAVE_LAKKA
|
||||
+ 257u
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -269,7 +269,6 @@ static const struct
|
||||
char s_12e77e8f[12];
|
||||
char s_98760b94[40];
|
||||
char s_b81eb68d[22];
|
||||
char s_af6007a1[17];
|
||||
char s_da068369[16];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[12];
|
||||
@@ -2456,7 +2455,6 @@ static const struct
|
||||
char s_310ec7bd[80];
|
||||
char s_5832a2c2[132];
|
||||
char s_6f6e337b[468];
|
||||
char s_f47e544f[288];
|
||||
char s_20cc6597[108];
|
||||
char s_21b0bad3[48];
|
||||
char s_66e9521c[77];
|
||||
@@ -4762,7 +4760,6 @@ static const struct
|
||||
"Ressources ",
|
||||
"Ouvrir le panneau de configuration ASIO",
|
||||
"Canaux de sortie ASIO",
|
||||
"Taille des blocs",
|
||||
"P\303\251riph\303\251rique ",
|
||||
"Audio ",
|
||||
"Module DSP ",
|
||||
@@ -6998,10 +6995,6 @@ static const struct
|
||||
"ant aux prises utilis\303\251es pour l'\303\251coute, telles qu'indiqu\303\251es par le p\303"
|
||||
"\251riph\303\251rique. Les p\303\251riph\303\251riques \303\240 deux sorties n'affichent que les"
|
||||
" sorties 1 et 2.",
|
||||
"Nombre d'images que le pilote audio traite par bloc. 0 demande au pilote d'utiliser la valeur pr"
|
||||
"opre au p\303\251riph\303\251rique, ce qui convient \303\240 la plupart des configurations ; une"
|
||||
" taille de bloc plus importante privil\303\251gie la stabilit\303\251 (en \303\251vitant les cou"
|
||||
"pures) au d\303\251triment de la latence.",
|
||||
"Remplacer le p\303\251riph\303\251rique audio utilis\303\251 par d\303\251faut par le pilote aud"
|
||||
"io. Cette option d\303\251pend du pilote.",
|
||||
"Pilote audio \303\240 utiliser. (Red\303\251marrage requis)",
|
||||
@@ -9747,7 +9740,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_fr_blob_check[
|
||||
(sizeof(msg_hash_fr_blob) == (226416u
|
||||
(sizeof(msg_hash_fr_blob) == (226111u
|
||||
#ifdef ANDROID
|
||||
+ 373u
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -268,7 +268,6 @@ static const struct
|
||||
char s_12e77e8f[13];
|
||||
char s_98760b94[31];
|
||||
char s_b81eb68d[22];
|
||||
char s_af6007a1[14];
|
||||
char s_da068369[7];
|
||||
char s_daead8a5[6];
|
||||
char s_48c208ee[14];
|
||||
@@ -2479,7 +2478,6 @@ static const struct
|
||||
char s_310ec7bd[83];
|
||||
char s_5832a2c2[103];
|
||||
char s_6f6e337b[422];
|
||||
char s_f47e544f[266];
|
||||
char s_20cc6597[116];
|
||||
char s_21b0bad3[53];
|
||||
char s_66e9521c[81];
|
||||
@@ -4842,7 +4840,6 @@ static const struct
|
||||
"S\303\263cmhainn\303\255",
|
||||
"Oscail Pain\303\251al Rialaithe ASIO",
|
||||
"Cain\303\251il Aschuir ASIO",
|
||||
"Fr\303\241ma\303\255 Bloc",
|
||||
"Gl\303\251as",
|
||||
"Fuaim",
|
||||
"Breise\303\241n DSP",
|
||||
@@ -7118,10 +7115,6 @@ static const struct
|
||||
"\303\255. Roghnaigh an p\303\251ire a mheaitse\303\241lann na seacanna at\303\241 \303\241 n-"
|
||||
"\303\251isteacht agat leo, mar a ainmn\303\255onn an gl\303\251as. N\303\255l ach 1-2 ag gl\303"
|
||||
"\251asanna dh\303\241 aschur.",
|
||||
"L\303\255on na bhfr\303\241ma\303\255 a bhogann an tiom\303\241na\303\255 fuaime in aghaidh an b"
|
||||
"hloic. Iarrann 0 luach an fheiste f\303\251in ar an tiom\303\241na\303\255, agus is \303\251 sin"
|
||||
" at\303\241 uathu i bhformh\303\263r na socruithe; d\303\251anann bloc n\303\255os m\303\263 moi"
|
||||
"ll a thr\303\241d\303\241il ar son athl\303\251imneachta i gcoinne titim amach.",
|
||||
"S\303\241raigh an gl\303\251as fuaime r\303\251amhshocraithe a \303\272s\303\241ideann an tiom"
|
||||
"\303\241na\303\255 fuaime. Braitheann s\303\251 seo ar an tiom\303\241na\303\255.",
|
||||
"Tiom\303\241na\303\255 fuaime le h\303\272s\303\241id. (Atos\303\272 ag teast\303\241il)",
|
||||
@@ -10104,7 +10097,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ga_blob_check[
|
||||
(sizeof(msg_hash_ga_blob) == (213095u
|
||||
(sizeof(msg_hash_ga_blob) == (212815u
|
||||
#ifdef ANDROID
|
||||
+ 390u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -265,7 +265,6 @@ static const struct
|
||||
char s_d9a51d02[21];
|
||||
char s_12e77e8f[8];
|
||||
char s_98760b94[28];
|
||||
char s_af6007a1[18];
|
||||
char s_da068369[12];
|
||||
char s_daead8a5[4];
|
||||
char s_48c208ee[16];
|
||||
@@ -4576,7 +4575,6 @@ static const struct
|
||||
"Icona da aplicaci\303\263n",
|
||||
"Activos",
|
||||
"Abrir panel de control ASIO",
|
||||
"Bloque fotogramas",
|
||||
"Dispositivo",
|
||||
"Son",
|
||||
"Complemento DSP",
|
||||
@@ -9092,7 +9090,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_gl_blob_check[
|
||||
(sizeof(msg_hash_gl_blob) == (193900u
|
||||
(sizeof(msg_hash_gl_blob) == (193882u
|
||||
#ifdef ANDROID
|
||||
+ 365u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -262,7 +262,6 @@ static const struct
|
||||
char s_d9a51d02[22];
|
||||
char s_12e77e8f[26];
|
||||
char s_98760b94[31];
|
||||
char s_af6007a1[21];
|
||||
char s_da068369[8];
|
||||
char s_daead8a5[5];
|
||||
char s_48c208ee[17];
|
||||
@@ -4644,7 +4643,6 @@ static const struct
|
||||
"Az alkalmaz\303\241s ikonja",
|
||||
"Be\303\251p\303\255tett m\303\251diaf\303\241jlok",
|
||||
"ASIO vez\303\251rl\305\221pult megnyit\303\241sa",
|
||||
"Keretek blokkonk\303\251nt",
|
||||
"Eszk\303\266z",
|
||||
"Hang",
|
||||
"DSP b\305\221v\303\255tm\303\251ny",
|
||||
@@ -9718,7 +9716,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_hu_blob_check[
|
||||
(sizeof(msg_hash_hu_blob) == (188989u
|
||||
(sizeof(msg_hash_hu_blob) == (188968u
|
||||
#ifdef ANDROID
|
||||
+ 316u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -261,7 +261,6 @@ static const struct
|
||||
char s_4e447c6c[31];
|
||||
char s_d9a51d02[10];
|
||||
char s_12e77e8f[14];
|
||||
char s_af6007a1[14];
|
||||
char s_da068369[18];
|
||||
char s_48c208ee[17];
|
||||
char s_a38cafbb[19];
|
||||
@@ -4436,7 +4435,6 @@ static const struct
|
||||
"Disconnetti Android workaround",
|
||||
"Icona App",
|
||||
"Risorse/Asset",
|
||||
"Blocchi Frame",
|
||||
"Dispositivo audio",
|
||||
"Plugin Audio DSP",
|
||||
"Rimuovi plugin DSP",
|
||||
@@ -8694,7 +8692,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_it_blob_check[
|
||||
(sizeof(msg_hash_it_blob) == (183539u
|
||||
(sizeof(msg_hash_it_blob) == (183525u
|
||||
#ifdef ANDROID
|
||||
+ 376u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -250,7 +250,6 @@ static const struct
|
||||
char s_4e447c6c[21];
|
||||
char s_d9a51d02[22];
|
||||
char s_12e77e8f[13];
|
||||
char s_af6007a1[25];
|
||||
char s_da068369[13];
|
||||
char s_daead8a5[16];
|
||||
char s_48c208ee[20];
|
||||
@@ -4963,7 +4962,6 @@ static const struct
|
||||
"Android \345\210\207\346\226\255\345\257\276\347\255\226",
|
||||
"\343\202\242\343\203\227\343\203\252\343\202\242\343\202\244\343\202\263\343\203\263",
|
||||
"\343\202\242\343\202\273\343\203\203\343\203\210",
|
||||
"\343\203\226\343\203\255\343\203\203\343\202\257\343\203\225\343\203\254\343\203\274\343\203\240",
|
||||
"\343\203\207\343\203\220\343\202\244\343\202\271",
|
||||
"\343\202\252\343\203\274\343\203\207\343\202\243\343\202\252",
|
||||
"DSP \343\203\227\343\203\251\343\202\260\343\202\244\343\203\263",
|
||||
@@ -13982,7 +13980,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ja_blob_check[
|
||||
(sizeof(msg_hash_ja_blob) == (201384u
|
||||
(sizeof(msg_hash_ja_blob) == (201359u
|
||||
#ifdef ANDROID
|
||||
+ 484u
|
||||
#endif
|
||||
|
||||
+1
-16
@@ -265,7 +265,6 @@ static const struct
|
||||
char s_d9a51d02[14];
|
||||
char s_12e77e8f[7];
|
||||
char s_98760b94[22];
|
||||
char s_af6007a1[17];
|
||||
char s_da068369[17];
|
||||
char s_daead8a5[23];
|
||||
char s_48c208ee[27];
|
||||
@@ -2464,7 +2463,6 @@ static const struct
|
||||
char s_f7cc6630[31];
|
||||
char s_310ec7bd[79];
|
||||
char s_5832a2c2[103];
|
||||
char s_f47e544f[304];
|
||||
char s_20cc6597[127];
|
||||
char s_21b0bad3[62];
|
||||
char s_66e9521c[106];
|
||||
@@ -5462,7 +5460,6 @@ static const struct
|
||||
"\354\225\261 \354\225\204\354\235\264\354\275\230",
|
||||
"\354\225\240\354\205\213",
|
||||
"ASIO \354\240\234\354\226\264\355\214\220 \354\227\264\352\270\260",
|
||||
"\353\270\224\353\241\235 \355\224\204\353\240\210\354\236\204",
|
||||
"\354\230\244\353\224\224\354\230\244 \354\236\245\354\271\230",
|
||||
"\354\230\244\353\224\224\354\230\244 \353\223\234\353\235\274\354\235\264\353\262\204",
|
||||
"\354\230\244\353\224\224\354\230\244 DSP \355\224\214\353\237\254\352\267\270\354\235\270",
|
||||
@@ -8427,18 +8424,6 @@ static const struct
|
||||
"\353\262\204\355\215\274 \354\204\244\354\240\225 \353\223\261\354\235\204 \353\263\200\352\262"
|
||||
"\275\355\225\240 \354\210\230 \354\236\210\354\212\265\353\213\210\353\213\244.",
|
||||
"\354\230\244\353\224\224\354\230\244 \353\223\234\353\235\274\354\235\264\353\262\204\352\260"
|
||||
"\200 \353\270\224\353\241\235\353\213\271 \354\230\256\352\270\270 \355\224\204\353\240\210\354"
|
||||
"\236\204 \354\210\230\354\236\205\353\213\210\353\213\244. 0\354\234\274\353\241\234 \354\204"
|
||||
"\244\354\240\225\355\225\240 \352\262\275\354\232\260 \353\223\234\353\235\274\354\235\264\353"
|
||||
"\262\204\354\235\230 \354\236\220\354\262\264 \352\260\222\354\235\204 \354\202\254\354\232\251"
|
||||
"\355\225\230\353\251\260, \353\214\200\353\266\200\353\266\204\354\235\230 \352\262\275\354\232"
|
||||
"\260 0\354\234\274\353\241\234 \354\204\244\354\240\225\355\225\230\353\212\224 \352\262\203\354"
|
||||
"\235\264 \352\266\214\354\236\245\353\220\251\353\213\210\353\213\244. \353\270\224\353\241\235"
|
||||
"\354\235\264 \354\273\244\354\247\200\353\251\264 \354\247\200\354\227\260\354\213\234\352\260"
|
||||
"\204\354\235\264 \353\202\256\354\225\204\354\247\200\354\247\200\353\247\214 \354\230\244\353"
|
||||
"\224\224\354\230\244\354\227\220 \353\201\212\352\271\200\354\235\264 \353\260\234\354\203\235"
|
||||
"\355\225\240 \354\210\230 \354\236\210\354\212\265\353\213\210\353\213\244.",
|
||||
"\354\230\244\353\224\224\354\230\244 \353\223\234\353\235\274\354\235\264\353\262\204\352\260"
|
||||
"\200 \354\202\254\354\232\251\355\225\240 \352\270\260\353\263\270 \354\230\244\353\224\224\354"
|
||||
"\230\244 \354\236\245\354\271\230\353\245\274 \354\204\244\354\240\225\355\225\251\353\213\210"
|
||||
"\353\213\244. \354\235\264 \354\230\265\354\205\230\354\235\200 \353\223\234\353\235\274\354\235"
|
||||
@@ -14520,7 +14505,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ko_blob_check[
|
||||
(sizeof(msg_hash_ko_blob) == (203093u
|
||||
(sizeof(msg_hash_ko_blob) == (202772u
|
||||
#ifdef ANDROID
|
||||
+ 436u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -255,7 +255,6 @@ static const struct
|
||||
char s_4e447c6c[54];
|
||||
char s_d9a51d02[14];
|
||||
char s_98760b94[29];
|
||||
char s_af6007a1[12];
|
||||
char s_da068369[15];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[17];
|
||||
@@ -4385,7 +4384,6 @@ static const struct
|
||||
"Tijdelijke oplossing voor het loskoppelen van Android",
|
||||
"App-pictogram",
|
||||
"Open het ASIO Controlepaneel",
|
||||
"Blok Frames",
|
||||
"Audio Apparaat",
|
||||
"Geluid",
|
||||
"Audio DSP Plugin",
|
||||
@@ -8572,7 +8570,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_nl_blob_check[
|
||||
(sizeof(msg_hash_nl_blob) == (174351u
|
||||
(sizeof(msg_hash_nl_blob) == (174339u
|
||||
#ifdef ANDROID
|
||||
+ 375u
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -267,7 +267,6 @@ static const struct
|
||||
char s_12e77e8f[7];
|
||||
char s_98760b94[30];
|
||||
char s_b81eb68d[24];
|
||||
char s_af6007a1[16];
|
||||
char s_da068369[12];
|
||||
char s_48c208ee[11];
|
||||
char s_a38cafbb[19];
|
||||
@@ -2448,7 +2447,6 @@ static const struct
|
||||
char s_f7cc6630[25];
|
||||
char s_310ec7bd[71];
|
||||
char s_5832a2c2[103];
|
||||
char s_f47e544f[242];
|
||||
char s_20cc6597[86];
|
||||
char s_21b0bad3[47];
|
||||
char s_66e9521c[82];
|
||||
@@ -4731,7 +4729,6 @@ static const struct
|
||||
"Assety",
|
||||
"Otw\303\263rz panel sterowania ASIO",
|
||||
"Kana\305\202y wyj\305\233ciowe ASIO",
|
||||
"Zablokuj klatki",
|
||||
"Urz\304\205dzenie",
|
||||
"Plugin DSP",
|
||||
"Usu\305\204 wtyczk\304\231 DSP",
|
||||
@@ -6954,10 +6951,6 @@ static const struct
|
||||
"Zasoby menu u\305\274ywane przez RetroArch s\304\205 przechowywane w tym katalogu.",
|
||||
"Otw\303\263rz panel sterowania sterownika ASIO, aby skonfigurowa\304\207 ustawienia routingu i b"
|
||||
"uforu urz\304\205dzenia.",
|
||||
"Liczba klatek, kt\303\263r\304\205 przesuwa sterownik audio na blok. 0 pyta sterownik o w\305"
|
||||
"\202asn\304\205 warto\305\233\304\207 urz\304\205dzenia, co jest chciane w wi\304\231kszo\305"
|
||||
"\233ci konfiguracji; wi\304\231kszy blok ma wi\304\231ksze op\303\263\305\272nienie, ale ma wi"
|
||||
"\304\231ksz\304\205 odporno\305\233\304\207 na braki d\305\272wi\304\231ku.",
|
||||
"Zast\304\205p domy\305\233lne urz\304\205dzenie audio u\305\274ywane przez sterownik. Zale\305"
|
||||
"\274ne od sterownika.",
|
||||
"Sterownik audio do u\305\274ycia. (Wymagany restart)",
|
||||
@@ -9612,7 +9605,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_pl_blob_check[
|
||||
(sizeof(msg_hash_pl_blob) == (191859u
|
||||
(sizeof(msg_hash_pl_blob) == (191601u
|
||||
#ifdef ANDROID
|
||||
+ 385u
|
||||
#endif
|
||||
|
||||
@@ -267,7 +267,6 @@ static const struct
|
||||
char s_12e77e8f[9];
|
||||
char s_98760b94[30];
|
||||
char s_b81eb68d[22];
|
||||
char s_af6007a1[18];
|
||||
char s_da068369[12];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[21];
|
||||
@@ -2399,7 +2398,6 @@ static const struct
|
||||
char s_310ec7bd[75];
|
||||
char s_5832a2c2[118];
|
||||
char s_6f6e337b[274];
|
||||
char s_f47e544f[244];
|
||||
char s_20cc6597[99];
|
||||
char s_21b0bad3[57];
|
||||
char s_66e9521c[79];
|
||||
@@ -4624,7 +4622,6 @@ static const struct
|
||||
"Recursos",
|
||||
"Abrir Painel de Controle ASIO",
|
||||
"Canais de sa\303\255da ASIO",
|
||||
"Quadros por bloco",
|
||||
"Dispositivo",
|
||||
"\303\201udio",
|
||||
"Plugin DSP de \303\241udio",
|
||||
@@ -6795,10 +6792,6 @@ static const struct
|
||||
"\247\303\243o. Um dispositivo ASIO enumera suas sa\303\255das em pares numerados; em um disposit"
|
||||
"ivo com mais de duas sa\303\255das, o primeiro par n\303\243o \303\251 necessariamente das suas "
|
||||
"caixas de som ou fones de ouvido.",
|
||||
"Define a quantidade de quadros que o driver de \303\241udio percorre por bloco. \"0\" pergunta a"
|
||||
"o driver pelo valor do pr\303\263prio dispositivo, que \303\251 o que a maioria das configura"
|
||||
"\303\247\303\265es quer; um bloco maior troca lat\303\252ncia pela prote\303\247\303\243o contra"
|
||||
" falhas.",
|
||||
"Substitui o dispositivo de \303\241udio padr\303\243o utilizado pelo driver de \303\241udio. Ist"
|
||||
"o depende do driver.",
|
||||
"Driver de \303\241udio a ser usado. (Requer reinicializa\303\247\303\243o)",
|
||||
@@ -9285,7 +9278,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_pt_br_blob_check[
|
||||
(sizeof(msg_hash_pt_br_blob) == (195061u
|
||||
(sizeof(msg_hash_pt_br_blob) == (194799u
|
||||
#ifdef ANDROID
|
||||
+ 352u
|
||||
#endif
|
||||
|
||||
@@ -120,7 +120,6 @@ static const struct
|
||||
char s_29398124[35];
|
||||
char s_2e5078b2[12];
|
||||
char s_12e77e8f[9];
|
||||
char s_af6007a1[20];
|
||||
char s_da068369[19];
|
||||
char s_daead8a5[7];
|
||||
char s_48c208ee[18];
|
||||
@@ -1558,7 +1557,6 @@ static const struct
|
||||
"Adicionar \303\240 lista de reprodu\303\247\303\243o",
|
||||
"Servi\303\247o IA",
|
||||
"Recursos",
|
||||
"Bloquear fotogramas",
|
||||
"Dispositivo de som",
|
||||
"\303\201udio",
|
||||
"Plugin de som DSP",
|
||||
@@ -2985,7 +2983,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_pt_pt_blob_check[
|
||||
(sizeof(msg_hash_pt_pt_blob) == (54869u
|
||||
(sizeof(msg_hash_pt_pt_blob) == (54849u
|
||||
#ifdef HAVE_LAKKA
|
||||
+ 17u
|
||||
#endif
|
||||
|
||||
+1
-4
@@ -274,7 +274,6 @@ static const struct
|
||||
char s_d9a51d02[34];
|
||||
char s_12e77e8f[24];
|
||||
char s_98760b94[54];
|
||||
char s_af6007a1[50];
|
||||
char s_da068369[21];
|
||||
char s_daead8a5[11];
|
||||
char s_48c208ee[17];
|
||||
@@ -5897,8 +5896,6 @@ static const struct
|
||||
"\320\236\321\202\320\272\321\200\321\213\321\202\321\214 \320\277\320\260\320\275\320\265\320"
|
||||
"\273\321\214 \321\203\320\277\321\200\320\260\320\262\320\273\320\265\320\275\320\270\321\217 AS"
|
||||
"IO",
|
||||
"\320\232\320\276\320\273\320\270\321\207\320\265\321\201\321\202\320\262\320\276 \321\204\321"
|
||||
"\200\320\265\320\271\320\274\320\276\320\262 \320\262 \320\261\320\273\320\276\320\272\320\265",
|
||||
"\320\243\321\201\321\202\321\200\320\276\320\271\321\201\321\202\320\262\320\276",
|
||||
"\320\220\321\203\320\264\320\270\320\276",
|
||||
"DSP-\320\277\320\273\320\260\320\263\320\270\320\275",
|
||||
@@ -18735,7 +18732,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_ru_blob_check[
|
||||
(sizeof(msg_hash_ru_blob) == (300319u
|
||||
(sizeof(msg_hash_ru_blob) == (300269u
|
||||
#ifdef ANDROID
|
||||
+ 547u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -262,7 +262,6 @@ static const struct
|
||||
char s_d9a51d02[17];
|
||||
char s_12e77e8f[7];
|
||||
char s_98760b94[31];
|
||||
char s_af6007a1[18];
|
||||
char s_da068369[11];
|
||||
char s_daead8a5[5];
|
||||
char s_48c208ee[20];
|
||||
@@ -4592,7 +4591,6 @@ static const struct
|
||||
"Ikona aplik\303\241cie",
|
||||
"Assety",
|
||||
"Otvori\305\245 ovl\303\241dac\303\255 panel ASIO",
|
||||
"Blokova\305\245 sn\303\255mky",
|
||||
"Zariadenie",
|
||||
"Zvuk",
|
||||
"DPS z\303\241suvn\303\275 modul",
|
||||
@@ -9416,7 +9414,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_sk_blob_check[
|
||||
(sizeof(msg_hash_sk_blob) == (179358u
|
||||
(sizeof(msg_hash_sk_blob) == (179340u
|
||||
#ifdef ANDROID
|
||||
+ 389u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -259,7 +259,6 @@ static const struct
|
||||
char s_d9a51d02[12];
|
||||
char s_12e77e8f[9];
|
||||
char s_98760b94[26];
|
||||
char s_af6007a1[19];
|
||||
char s_da068369[6];
|
||||
char s_daead8a5[5];
|
||||
char s_48c208ee[18];
|
||||
@@ -4455,7 +4454,6 @@ static const struct
|
||||
"Programikon",
|
||||
"Resurser",
|
||||
"\303\226ppna ASIO-kontrollpanel",
|
||||
"Blockera bildrutor",
|
||||
"Enhet",
|
||||
"Ljud",
|
||||
"DSP-insticksmodul",
|
||||
@@ -8897,7 +8895,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_sv_blob_check[
|
||||
(sizeof(msg_hash_sv_blob) == (170667u
|
||||
(sizeof(msg_hash_sv_blob) == (170648u
|
||||
#ifdef ANDROID
|
||||
+ 361u
|
||||
#endif
|
||||
|
||||
+1
-4
@@ -302,7 +302,6 @@ static const struct
|
||||
char s_d9a51d02[25];
|
||||
char s_12e77e8f[25];
|
||||
char s_98760b94[45];
|
||||
char s_af6007a1[34];
|
||||
char s_da068369[22];
|
||||
char s_daead8a5[16];
|
||||
char s_a38cafbb[35];
|
||||
@@ -6494,8 +6493,6 @@ static const struct
|
||||
"\340\270\227\340\270\243\340\270\261\340\270\236\340\270\242\340\270\262\340\270\201\340\270\243",
|
||||
"\340\271\200\340\270\233\340\270\264\340\270\224\340\271\201\340\270\234\340\270\207\340\270\204"
|
||||
"\340\270\247\340\270\232\340\270\204\340\270\270\340\270\241 ASIO",
|
||||
"\340\270\233\340\270\264\340\270\224\340\270\201\340\270\261\340\271\211\340\270\231\340\271\200"
|
||||
"\340\270\237\340\270\243\340\270\241",
|
||||
"\340\270\255\340\270\270\340\270\233\340\270\201\340\270\243\340\270\223\340\271\214",
|
||||
"\340\271\200\340\270\252\340\270\265\340\270\242\340\270\207",
|
||||
"\340\270\245\340\270\232\340\270\233\340\270\245\340\270\261\340\271\212\340\270\201\340\270\255"
|
||||
@@ -23099,7 +23096,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_th_blob_check[
|
||||
(sizeof(msg_hash_th_blob) == (402910u
|
||||
(sizeof(msg_hash_th_blob) == (402876u
|
||||
#ifdef ANDROID
|
||||
+ 757u
|
||||
#endif
|
||||
|
||||
+1
-3
@@ -258,7 +258,6 @@ static const struct
|
||||
char s_4e447c6c[48];
|
||||
char s_d9a51d02[17];
|
||||
char s_12e77e8f[12];
|
||||
char s_af6007a1[17];
|
||||
char s_da068369[7];
|
||||
char s_daead8a5[4];
|
||||
char s_48c208ee[14];
|
||||
@@ -4483,7 +4482,6 @@ static const struct
|
||||
"Android ba\304\237lant\304\261 kesilmesi ge\303\247ici \303\247\303\266z\303\274m\303\274",
|
||||
"Uygulama Simgesi",
|
||||
"\304\260\303\247erikler",
|
||||
"Kareleri Engelle",
|
||||
"Ayg\304\261t",
|
||||
"Ses",
|
||||
"DSP Eklentisi",
|
||||
@@ -9180,7 +9178,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_tr_blob_check[
|
||||
(sizeof(msg_hash_tr_blob) == (170931u
|
||||
(sizeof(msg_hash_tr_blob) == (170914u
|
||||
#ifdef ANDROID
|
||||
+ 340u
|
||||
#endif
|
||||
|
||||
+1
-24
@@ -291,7 +291,6 @@ static const struct
|
||||
char s_12e77e8f[15];
|
||||
char s_98760b94[54];
|
||||
char s_b81eb68d[31];
|
||||
char s_af6007a1[30];
|
||||
char s_da068369[17];
|
||||
char s_daead8a5[9];
|
||||
char s_48c208ee[17];
|
||||
@@ -2478,7 +2477,6 @@ static const struct
|
||||
char s_5832a2c2[190];
|
||||
char s_6f6e337b_0[500];
|
||||
char s_6f6e337b_1[224];
|
||||
char s_f47e544f[460];
|
||||
char s_20cc6597[185];
|
||||
char s_21b0bad3[110];
|
||||
char s_66e9521c[125];
|
||||
@@ -6175,8 +6173,6 @@ static const struct
|
||||
"IO",
|
||||
"\320\232\320\260\320\275\320\260\320\273\320\270 \320\262\320\270\321\205\320\276\320\264\321"
|
||||
"\203 ASIO",
|
||||
"\320\221\320\273\320\276\320\272\321\203\320\262\320\260\321\202\320\270 \320\272\320\260\320"
|
||||
"\264\321\200\320\270",
|
||||
"\320\237\321\200\320\270\321\201\321\202\321\200\321\226\320\271",
|
||||
"\320\227\320\262\321\203\320\272",
|
||||
"DSP \320\277\320\273\320\260\320\263\321\226\320\275",
|
||||
@@ -10685,25 +10681,6 @@ static const struct
|
||||
"\200\320\276\321\227 \320\267 \320\264\320\262\320\276\320\274\320\260 \320\262\320\270\321\205"
|
||||
"\320\276\320\264\320\260\320\274\320\270 \320\274\320\260\321\216\321\202\321\214 \320\273\320"
|
||||
"\270\321\210\320\265 \320\277\320\260\321\200\320\270 1-2.",
|
||||
"\320\232\321\226\320\273\321\214\320\272\321\226\321\201\321\202\321\214 \320\272\320\260\320"
|
||||
"\264\321\200\321\226\320\262, \321\217\320\272\321\226 \320\260\321\203\320\264\321\226\320\276"
|
||||
"\320\264\321\200\320\260\320\271\320\262\320\265\321\200 \320\277\320\265\321\200\320\265\320"
|
||||
"\274\321\226\321\211\321\203\321\224 \320\267\320\260 \320\276\320\264\320\270\320\275 \320\261"
|
||||
"\320\273\320\276\320\272. \320\227\320\275\320\260\321\207\320\265\320\275\320\275\321\217 0 "
|
||||
"\320\267\320\260\320\277\320\270\321\202\321\203\321\224 \321\203 \320\264\321\200\320\260\320"
|
||||
"\271\320\262\320\265\321\200\320\260 \320\262\320\273\320\260\321\201\320\275\320\265 \320\267"
|
||||
"\320\275\320\260\321\207\320\265\320\275\320\275\321\217 \320\277\321\200\320\270\321\201\321"
|
||||
"\202\321\200\320\276\321\216, \321\211\320\276 \320\262\321\226\320\264\320\277\320\276\320\262"
|
||||
"\321\226\320\264\320\260\321\224 \320\262\320\270\320\274\320\276\320\263\320\260\320\274 \320"
|
||||
"\261\321\226\320\273\321\214\321\210\320\276\321\201\321\202\321\226 \320\272\320\276\320\275"
|
||||
"\321\204\321\226\320\263\321\203\321\200\320\260\321\206\321\226\320\271; \320\261\321\226\320"
|
||||
"\273\321\214\321\210\320\270\320\271 \320\261\320\273\320\276\320\272 \320\267\320\260\320\261"
|
||||
"\320\265\320\267\320\277\320\265\321\207\321\203\321\224 \320\262\320\270\321\211\321\203 \321"
|
||||
"\201\321\202\321\226\320\271\320\272\321\226\321\201\321\202\321\214 \320\264\320\276 \320\277"
|
||||
"\321\200\320\276\320\277\321\203\321\201\320\272\321\226\320\262 \321\201\320\270\320\263\320"
|
||||
"\275\320\260\320\273\321\203 \321\210\320\273\321\217\321\205\320\276\320\274 \320\267\320\261"
|
||||
"\321\226\320\273\321\214\321\210\320\265\320\275\320\275\321\217 \320\267\320\260\321\202\321"
|
||||
"\200\320\270\320\274\320\272\320\270.",
|
||||
"\320\237\320\265\321\200\320\265\320\262\320\270\320\267\320\275\320\260\321\207\320\270\321\202"
|
||||
"\320\270 \321\202\320\270\320\277\320\276\320\262\320\270\320\271 \320\260\321\203\320\264\321"
|
||||
"\226\320\276 \320\277\321\200\320\270\321\201\321\202\321\200\321\226\320\271, \321\217\320\272"
|
||||
@@ -20017,7 +19994,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_uk_blob_check[
|
||||
(sizeof(msg_hash_uk_blob) == (326579u
|
||||
(sizeof(msg_hash_uk_blob) == (326089u
|
||||
#ifdef ANDROID
|
||||
+ 610u
|
||||
#endif
|
||||
|
||||
+1
-13
@@ -276,7 +276,6 @@ static const struct
|
||||
char s_12e77e8f[13];
|
||||
char s_98760b94[33];
|
||||
char s_b81eb68d[21];
|
||||
char s_af6007a1[24];
|
||||
char s_da068369[13];
|
||||
char s_daead8a5[10];
|
||||
char s_48c208ee[33];
|
||||
@@ -2497,7 +2496,6 @@ static const struct
|
||||
char s_5832a2c2[123];
|
||||
char s_6f6e337b_0[500];
|
||||
char s_6f6e337b_1[11];
|
||||
char s_f47e544f[364];
|
||||
char s_20cc6597[152];
|
||||
char s_21b0bad3[80];
|
||||
char s_66e9521c[92];
|
||||
@@ -5219,7 +5217,6 @@ static const struct
|
||||
"T\303\240i nguy\303\252n",
|
||||
"M\341\273\237 b\341\272\243ng \304\221i\341\273\201u khi\341\273\203n ASIO",
|
||||
"K\303\252nh \304\221\341\272\247u ra ASIO",
|
||||
"Khung h\303\254nh b\341\273\213 ch\341\272\267n",
|
||||
"Thi\341\272\277t b\341\273\213",
|
||||
"\303\202m thanh",
|
||||
"M\303\264-\304\221un x\341\273\255 l\303\275 \303\242m thanh s\341\273\221",
|
||||
@@ -7857,15 +7854,6 @@ static const struct
|
||||
"\213 \304\221\341\272\267t cho ch\303\272ng. Thi\341\272\277t b\341\273\213 ch\341\273\211 c\303"
|
||||
"\263 hai \304\221\341\272\247u ra ch\341\273\211 c\303\263 ",
|
||||
"c\341\272\267p 1-2.",
|
||||
"S\341\273\221 khung h\303\254nh \303\242m thanh m\303\240 tr\303\254nh \304\221i\341\273\201u kh"
|
||||
"i\341\273\203n \303\242m thanh x\341\273\255 l\303\275 trong m\341\273\227i kh\341\273\221i. 0 y"
|
||||
"\303\252u c\341\272\247u tr\303\254nh \304\221i\341\273\201u khi\341\273\203n s\341\273\255 d"
|
||||
"\341\273\245ng gi\303\241 tr\341\273\213 ri\303\252ng c\341\273\247a thi\341\272\277t b\341\273"
|
||||
"\213, \304\221\303\242y l\303\240 l\341\273\261a ch\341\273\215n ph\303\271 h\341\273\243p v\341"
|
||||
"\273\233i h\341\272\247u h\341\272\277t c\303\241c thi\341\272\277t l\341\272\255p; gi\303\241 t"
|
||||
"r\341\273\213 kh\341\273\221i l\341\273\233n h\306\241n s\341\272\275 t\304\203ng \304\221\341"
|
||||
"\273\231 \341\273\225n \304\221\341\273\213nh nh\306\260ng \304\221\341\273\225i l\341\272\241i "
|
||||
"l\303\240m t\304\203ng \304\221\341\273\231 tr\341\273\205 \303\242m thanh.",
|
||||
"Ghi \304\221\303\250 thi\341\272\277t b\341\273\213 \303\242m thanh m\341\272\267c \304\221\341"
|
||||
"\273\213nh m\303\240 tr\303\254nh \304\221i\341\273\201u khi\341\273\203n \303\242m thanh s\341"
|
||||
"\273\255 d\341\273\245ng. \304\220i\341\273\201u n\303\240y ph\341\273\245 thu\341\273\231c v"
|
||||
@@ -12502,7 +12490,7 @@ static const struct
|
||||
* compiler that pads this struct fails here instead of
|
||||
* misindexing at runtime. */
|
||||
typedef char msg_hash_vn_blob_check[
|
||||
(sizeof(msg_hash_vn_blob) == (240514u
|
||||
(sizeof(msg_hash_vn_blob) == (240126u
|
||||
#ifdef ANDROID
|
||||
+ 373u
|
||||
#endif
|
||||
|
||||
Executable
+371
@@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Packed translation table consistency check.
|
||||
|
||||
Usage, from the repository root:
|
||||
python3 tools/msg_hash_packed_check.py [intl/msg_hash_xx.h ...]
|
||||
python3 tools/msg_hash_packed_check.py --selftest
|
||||
|
||||
Every intl/msg_hash_<lang>.h that intl/json2h.py emits carries two
|
||||
objects paired by position and by nothing else: the blob struct holds
|
||||
the rows as one run of NUL-terminated strings, and ids[] names the enum
|
||||
each row belongs to. msg_hash_strtab_index_build() walks the blob once
|
||||
and gives row N to ids[N], so a row present on one side and absent on
|
||||
the other hands every row after it to the wrong enum, and the menu
|
||||
fills with real strings belonging to other entries. A C compiler cannot
|
||||
see that: both objects are well formed on their own, and the sizeof()
|
||||
contiguity check in the header measures the blob against itself.
|
||||
|
||||
The pairing is recoverable because json2h.py names each struct member
|
||||
after the djb2 hash of the key its row was emitted for, so this checks
|
||||
it directly: row N's member name must be the name the key in ids[N]
|
||||
hashes to, under the same preprocessor guards. The row sizes the walk
|
||||
depends on are checked with it - a member one byte wider than its
|
||||
string leaves a stray NUL that ends the walk's row early and shifts
|
||||
everything after it just as surely.
|
||||
|
||||
Both checks read the whole file and follow the guards, so this sees
|
||||
configurations no single build job compiles.
|
||||
"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def djb2(s):
|
||||
h = 5381
|
||||
for ch in s:
|
||||
h = ((h * 33) + ord(ch)) & 0xffffffff
|
||||
return h
|
||||
|
||||
|
||||
def decode_c_literal(src):
|
||||
"""Decode the text between the quotes of a C string literal to bytes."""
|
||||
out = bytearray()
|
||||
data = src.encode('utf-8')
|
||||
i = 0
|
||||
n = len(data)
|
||||
while i < n:
|
||||
c = data[i]
|
||||
if c != 0x5c:
|
||||
out.append(c)
|
||||
i += 1
|
||||
continue
|
||||
i += 1
|
||||
e = data[i:i + 1].decode('latin1')
|
||||
if e == 'n': out.append(0x0a); i += 1
|
||||
elif e == 't': out.append(0x09); i += 1
|
||||
elif e == 'r': out.append(0x0d); i += 1
|
||||
elif e == 'x':
|
||||
j = i + 1
|
||||
while j < n and chr(data[j]) in '0123456789abcdefABCDEF':
|
||||
j += 1
|
||||
out.append(int(data[i + 1:j], 16) & 0xff)
|
||||
i = j
|
||||
elif e in '01234567':
|
||||
j = i
|
||||
while j < n and j < i + 3 and chr(data[j]) in '01234567':
|
||||
j += 1
|
||||
out.append(int(data[i:j], 8) & 0xff)
|
||||
i = j
|
||||
else:
|
||||
out.append(data[i])
|
||||
i += 1
|
||||
return bytes(out)
|
||||
|
||||
|
||||
LIT = re.compile(r'"((?:[^"\\]|\\.)*)"')
|
||||
MEMBER = re.compile(r'\s*char (\w+)\[(\d+)\];')
|
||||
IDENT = re.compile(r'\s*\(uint32_t\)(\w+),')
|
||||
CHUNK = re.compile(r'^s_[0-9a-f]{8}(?:_c\d+)?_\d+$')
|
||||
|
||||
|
||||
def scan_guarded(lines):
|
||||
"""Yield (line, guard) for every non-directive line, where guard is the
|
||||
enclosing #if stack in the form json2h.py records it."""
|
||||
stack = []
|
||||
for line in lines:
|
||||
s = line.strip()
|
||||
if s.startswith('#if'):
|
||||
stack.append([s, False])
|
||||
elif s.startswith('#else'):
|
||||
if stack:
|
||||
stack[-1][1] = True
|
||||
elif s.startswith('#endif'):
|
||||
if stack:
|
||||
stack.pop()
|
||||
elif s:
|
||||
yield line, tuple((g[0], g[1]) for g in stack)
|
||||
|
||||
|
||||
def row_name(member):
|
||||
"""Strip the chunk suffix json2h.py appends to a split row."""
|
||||
if CHUNK.match(member):
|
||||
return member.rsplit('_', 1)[0]
|
||||
return member
|
||||
|
||||
|
||||
def expected_names(keys):
|
||||
"""Reproduce json2h.py's member_base_names() from the ids[] order."""
|
||||
by_hash = {}
|
||||
for key in keys:
|
||||
by_hash.setdefault(djb2(key), []).append(key)
|
||||
names = {}
|
||||
for h, ks in by_hash.items():
|
||||
uniq = sorted(set(ks))
|
||||
if len(uniq) == 1:
|
||||
names[uniq[0]] = 's_%08x' % h
|
||||
else:
|
||||
for n, key in enumerate(uniq):
|
||||
names[key] = 's_%08x_c%u' % (h, n)
|
||||
return names
|
||||
|
||||
|
||||
def split_sections(text, lang):
|
||||
"""Return the four generated regions of a packed header as line lists."""
|
||||
def between(start, end, after=0):
|
||||
i = text.index(start, after) + len(start)
|
||||
j = text.index(end, i)
|
||||
return text[i:j].split('\n'), j
|
||||
|
||||
members, at = between('static const struct\n{\n',
|
||||
'\n} msg_hash_%s_blob =' % lang)
|
||||
inits, at = between('_blob =\n{\n', '\n};', at)
|
||||
check, at = between('_blob_check[\n', '\n )) ? 1 : -1];', at)
|
||||
ids, at = between('_ids[] =\n{\n', '\n};', at)
|
||||
return members, inits, check, ids
|
||||
|
||||
|
||||
def check_text(text, lang, name):
|
||||
"""Check one packed header's text; return a list of error strings."""
|
||||
errors = []
|
||||
if ('static const uint32_t msg_hash_%s_ids[] =' % lang) not in text:
|
||||
return errors
|
||||
try:
|
||||
member_l, init_l, check_l, id_l = split_sections(text, lang)
|
||||
except ValueError:
|
||||
return ['%s: generated regions not found' % name]
|
||||
|
||||
members = []
|
||||
for line, guard in scan_guarded(member_l):
|
||||
m = MEMBER.match(line)
|
||||
if not m:
|
||||
errors.append('%s: unparsed struct member: %s' % (name, line))
|
||||
continue
|
||||
members.append((m.group(1), int(m.group(2)), guard))
|
||||
|
||||
inits = []
|
||||
cur = None
|
||||
for line, guard in scan_guarded(init_l):
|
||||
if cur is None:
|
||||
cur = [b'', guard]
|
||||
cur[0] += b''.join(decode_c_literal(p) for p in LIT.findall(line))
|
||||
if line.rstrip().endswith(','):
|
||||
inits.append((cur[0], cur[1]))
|
||||
cur = None
|
||||
if cur is not None:
|
||||
errors.append('%s: unterminated initializer' % name)
|
||||
|
||||
ids = []
|
||||
for line, guard in scan_guarded(id_l):
|
||||
m = IDENT.match(line)
|
||||
if not m:
|
||||
errors.append('%s: unparsed ids entry: %s' % (name, line))
|
||||
continue
|
||||
ids.append((m.group(1), guard))
|
||||
|
||||
if len(members) != len(inits):
|
||||
errors.append('%s: %u struct members but %u initializers'
|
||||
% (name, len(members), len(inits)))
|
||||
return errors
|
||||
|
||||
# Each member is exactly its decoded row plus the NUL, or exactly the
|
||||
# chunk for a non-final chunk of a split row. Anything wider leaves a
|
||||
# NUL the walk stops on; anything narrower runs two rows together.
|
||||
rows = []
|
||||
for i, ((mname, size, mg), (data, ig)) in enumerate(zip(members, inits)):
|
||||
if mg != ig:
|
||||
errors.append('%s: member %s is guarded %r and its initializer %r'
|
||||
% (name, mname, mg, ig))
|
||||
if b'\x00' in data:
|
||||
errors.append('%s: member %s holds an embedded NUL'
|
||||
% (name, mname))
|
||||
last = size == len(data) + 1
|
||||
if not last and size != len(data):
|
||||
errors.append('%s: member %s declared [%u] holds %u bytes'
|
||||
% (name, mname, size, len(data)))
|
||||
base = row_name(mname)
|
||||
if rows and rows[-1][2] and rows[-1][0] == base:
|
||||
rows[-1][1] += size
|
||||
rows[-1][2] = not last
|
||||
else:
|
||||
if rows and rows[-1][2]:
|
||||
errors.append('%s: member %s has no NUL and no continuation'
|
||||
% (name, members[i - 1][0]))
|
||||
rows.append([base, size, not last, mg])
|
||||
if rows and rows[-1][2]:
|
||||
errors.append('%s: the last row is unterminated' % name)
|
||||
|
||||
# The pairing the menu depends on.
|
||||
if len(rows) != len(ids):
|
||||
errors.append('%s: the blob holds %u rows but ids[] names %u'
|
||||
% (name, len(rows), len(ids)))
|
||||
names = expected_names([k for k, _g in ids])
|
||||
for i in range(min(len(rows), len(ids))):
|
||||
key, ig = ids[i]
|
||||
if rows[i][0] != names[key]:
|
||||
errors.append('%s: row %u is %s but ids[] pairs it with %s (%s)'
|
||||
% (name, i, rows[i][0], names[key], key))
|
||||
break
|
||||
if rows[i][3] != ig:
|
||||
errors.append('%s: row %u (%s) is guarded %r in the blob and %r '
|
||||
'in ids[]' % (name, i, key, rows[i][3], ig))
|
||||
break
|
||||
|
||||
# The sizeof() check is what makes a padding compiler fail the build
|
||||
# instead of misindexing, and it does that only while it still adds up
|
||||
# to the members above it.
|
||||
sums = {}
|
||||
m = re.match(r'\s*\(sizeof\(msg_hash_\w+_blob\) == \((\d+)u',
|
||||
check_l[0] if check_l else '')
|
||||
if not m:
|
||||
errors.append('%s: size check preamble not found' % name)
|
||||
else:
|
||||
sums[()] = int(m.group(1))
|
||||
for line, guard in scan_guarded(check_l[1:]):
|
||||
v = re.match(r'\s*\+ (\d+)u', line)
|
||||
if not v:
|
||||
errors.append('%s: unparsed size check term: %s'
|
||||
% (name, line))
|
||||
continue
|
||||
sums[guard] = sums.get(guard, 0) + int(v.group(1))
|
||||
want = {}
|
||||
for _base, size, _open, guard in rows:
|
||||
want[guard] = want.get(guard, 0) + size
|
||||
for guard in sorted(set(sums) | set(want), key=repr):
|
||||
if sums.get(guard, 0) != want.get(guard, 0):
|
||||
errors.append('%s: the size check counts %u bytes under %r, '
|
||||
'the blob has %u' % (name, sums.get(guard, 0),
|
||||
guard, want.get(guard, 0)))
|
||||
return errors
|
||||
|
||||
|
||||
def check_file(path):
|
||||
lang = os.path.basename(path)[len('msg_hash_'):-len('.h')]
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
return check_text(f.read(), lang, path)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Self-test. The fixtures are built here rather than lifted from the tree, so
|
||||
# the result says the same thing whether or not the shipped headers currently
|
||||
# pass: it measures the checker.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _fixture():
|
||||
rows = [('MENU_ENUM_LABEL_VALUE_A', b'alpha', ()),
|
||||
('MENU_ENUM_LABEL_VALUE_B', b'beta', (('#ifdef HAVE_X', False),)),
|
||||
('MENU_ENUM_LABEL_VALUE_C', b'gamma', ()),
|
||||
('MENU_ENUM_LABEL_VALUE_D', b'delta', ())]
|
||||
names = expected_names([r[0] for r in rows])
|
||||
members, inits, ids = [], [], []
|
||||
base, guarded = 0, {}
|
||||
for key, data, guard in rows:
|
||||
pre = [g[0] for g in guard]
|
||||
post = ['#endif' for _g in guard]
|
||||
members += pre + [' char %s[%u];' % (names[key], len(data) + 1)] + post
|
||||
inits += pre + [' "%s",' % data.decode('ascii')] + post
|
||||
ids += pre + [' (uint32_t)%s,' % key] + post
|
||||
if guard:
|
||||
guarded[guard] = guarded.get(guard, 0) + len(data) + 1
|
||||
else:
|
||||
base += len(data) + 1
|
||||
check = [' (sizeof(msg_hash_zz_blob) == (%uu' % base]
|
||||
for guard, size in guarded.items():
|
||||
check += [g[0] for g in guard] + [' + %uu' % size, '#endif']
|
||||
return ('static const struct\n{\n' + '\n'.join(members)
|
||||
+ '\n} msg_hash_zz_blob =\n{\n' + '\n'.join(inits)
|
||||
+ '\n};\n\ntypedef char msg_hash_zz_blob_check[\n'
|
||||
+ '\n'.join(check) + '\n )) ? 1 : -1];\n\n'
|
||||
+ 'static const uint32_t msg_hash_zz_ids[] =\n{\n'
|
||||
+ '\n'.join(ids) + '\n};\n')
|
||||
|
||||
|
||||
def selftest():
|
||||
failures = [0]
|
||||
|
||||
def expect(label, text, want):
|
||||
errors = check_text(text, 'zz', label)
|
||||
ok = (not errors) if want is None else any(want in e
|
||||
for e in errors)
|
||||
print('%-30s %s' % (label, 'ok' if ok else 'FAILED'))
|
||||
if not ok:
|
||||
failures[0] += 1
|
||||
for e in errors:
|
||||
print(' %s' % e)
|
||||
|
||||
good = _fixture()
|
||||
named = expected_names(['MENU_ENUM_LABEL_VALUE_A',
|
||||
'MENU_ENUM_LABEL_VALUE_C'])
|
||||
|
||||
expect('clean fixture', good, None)
|
||||
|
||||
# A retired setting's row taken out of ids[] and left in the blob,
|
||||
# which is what renamed every row after it in 5d0f721.
|
||||
expect('ids[] row dropped',
|
||||
good.replace(' (uint32_t)MENU_ENUM_LABEL_VALUE_C,\n', ''),
|
||||
'ids[] pairs it with')
|
||||
|
||||
# The mirror of it: the row taken out of the blob and left in ids[].
|
||||
lost = good.replace(' char %s[6];\n'
|
||||
% named['MENU_ENUM_LABEL_VALUE_C'], '')
|
||||
expect('blob row dropped', lost.replace(' "gamma",\n', ''),
|
||||
'ids[] pairs it with')
|
||||
|
||||
# A member one byte too wide: the walk stops on the padding NUL and
|
||||
# every row after it shifts by one.
|
||||
expect('member wider than its row',
|
||||
good.replace(' char %s[6];\n' % named['MENU_ENUM_LABEL_VALUE_A'],
|
||||
' char %s[7];\n' % named['MENU_ENUM_LABEL_VALUE_A']),
|
||||
'holds 5 bytes')
|
||||
|
||||
# A guard on one side only: the pairing holds for the build that
|
||||
# defines it and breaks for the one that does not.
|
||||
expect('guard on the blob only',
|
||||
good.replace('#ifdef HAVE_X\n (uint32_t)MENU_ENUM_LABEL_VALUE_B,'
|
||||
'\n#endif\n',
|
||||
' (uint32_t)MENU_ENUM_LABEL_VALUE_B,\n'),
|
||||
'is guarded')
|
||||
|
||||
# A contiguity constant that no longer describes the blob it guards.
|
||||
expect('stale size check', good.replace('== (18u', '== (17u'),
|
||||
'the size check counts')
|
||||
|
||||
return 1 if failures[0] else 0
|
||||
|
||||
|
||||
def main(argv):
|
||||
args = argv[1:]
|
||||
if '--selftest' in args:
|
||||
return selftest()
|
||||
paths = args
|
||||
if not paths:
|
||||
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
paths = sorted(glob.glob(os.path.join(here, 'intl', 'msg_hash_*.h')))
|
||||
failed = 0
|
||||
for path in paths:
|
||||
errors = check_file(path)
|
||||
for e in errors:
|
||||
print(e)
|
||||
if errors:
|
||||
failed += 1
|
||||
if failed:
|
||||
print('%u packed header(s) failed verification' % failed)
|
||||
return 1
|
||||
print('%u packed header(s) verified' % len(paths))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
Reference in new issue
Block a user