two-split switch
[m6w6/ext-http] / scripts / gen_switch_utf8.php
1 #!/usr/bin/env php
2 <?php
3
4 error_reporting(E_ALL);
5 set_error_handler(function($c, $e, $f, $l) {
6 throw new Exception("$e in $f on line $l");
7 });
8
9 $i18n = $argc >= 2 ? $argv[1] : "/usr/share/i18n/locales/i18n";
10
11 $b = 10;
12 $m = 0xfffff000 >> $b;
13 $b2 = 8;
14 $x = $m >> $b2;
15
16 $f = fopen($i18n, "r");
17 $c = false;
18 $a = false;
19
20 ob_start(null, 0xfffff);
21
22 printf("/* generated on %s with\n b = %d\n m = 0x%08x\n b2= %d\n*/",
23 strftime("%x %X"), $b, $m, $b2);
24
25 while (!feof($f)) {
26 $line = fgets($f);
27 if (!$c && $line !== "LC_CTYPE\n") {
28 continue;
29 }
30 $c = true;
31 if ($line === "END LC_CTYPE\n") {
32 break;
33 }
34 switch($line{0}) {
35 case "%":
36 break;
37 case "\n":
38 if ($a) {
39 break 2;
40 }
41 break;
42 case " ":
43 if ($a) {
44 foreach (explode(";", trim($line, "\n/ ;")) as $ranges) {
45 $range = explode("..", $ranges);
46 $step = 0;
47 $end = 0;
48 switch (count($range)) {
49 case 3:
50 list($sstart, $sstep, $send) = $range;
51 sscanf($sstart, "<U%X>", $start);
52 sscanf($sstep, "(%d)", $step);
53 sscanf($send, "<U%X>", $end);
54
55 break;
56 case 2:
57 list($sstart, $send) = $range;
58 $step = 1;
59 sscanf($sstart, "<U%X>", $start);
60 sscanf($send, "<U%X>", $end);
61 break;
62 case 1:
63 list($sstart) = $range;
64 sscanf($sstart, "<U%X>", $start);
65 break;
66 }
67 $r[$start >> $b][($start & $m) >> $b2][]=[$start,$end,$step];
68 }
69 }
70 break;
71 default:
72 if ($a) {
73 break 2;
74 } elseif ($line === "alpha /\n") {
75 $a = true;
76 }
77 break;
78 }
79 }
80
81 function sp($sp, $ch = " ") { return str_repeat($ch, $sp); }
82 printf("switch (ch >> %d) {\n", $b);
83 foreach ($r as $sw => $sws) {
84 printf("case 0x%08X:\n", $sw);
85 printf(" switch((ch & 0x%08X) >> %d) {\n", $m, $b2);
86 foreach ($sws as $sw2 => $specs) {
87 printf(" case 0x%08X:\n", $sw2);
88 $sp = 2;
89 foreach ($specs as list($start, $end, $step)) {
90 if ($end) {
91 if ($step > 1) {
92 die("\nUNEXPECTED: step>1\n");
93 printf("\tfor (i=0x%08X; i <= 0x%08X; i+= %d) { if (i == ch) return 1; }\n", $start, $end, $step);
94 } else {
95 //printf(" if (ch >= 0x%08X && ch <= 0x%08X) return 1;\n", $start, $end);
96 printf("%sif (ch >= 0x%08X) {\n", sp($sp), $start);
97 printf("%sif (ch <= 0x%08X) return 1;\n", sp(++$sp), $end);
98 }
99 } else {
100 printf("%sif (ch == 0x%08X) return 1;\n", sp($sp), $start);
101 }
102 }
103 printf(" %s\n break;\n", sp($sp-2, "}"));
104 }
105 printf(" }\n break;\n");
106 }
107 printf("}\n");
108
109 file_put_contents("php_http_utf8.h",
110 preg_replace('/(\/\* BEGIN::UTF8SWITCH \*\/\n).*(\n\s*\/\* END::UTF8SWITCH \*\/)/s', '$1'. ob_get_contents() .'$2',
111 file_get_contents("php_http_utf8.h")));