This allows us to set `fetch-version-from` for the `early-to-late-beta` merge action. Differential Revision: https://phabricator.services.mozilla.com/D253859
174 lines
3.7 KiB
Python
Executable File
174 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import io
|
|
import pathlib
|
|
from collections import defaultdict
|
|
|
|
import multidict
|
|
|
|
ROOT = pathlib.Path.cwd()
|
|
while ROOT.parent != ROOT and not (ROOT / "pyproject.toml").exists():
|
|
ROOT = ROOT.parent
|
|
|
|
|
|
def calc_headers(root):
|
|
hdrs_file = root / "aiohttp/hdrs.py"
|
|
code = compile(hdrs_file.read_text(), str(hdrs_file), "exec")
|
|
globs = {}
|
|
exec(code, globs)
|
|
headers = [val for val in globs.values() if isinstance(val, multidict.istr)]
|
|
return sorted(headers)
|
|
|
|
|
|
headers = calc_headers(ROOT)
|
|
|
|
|
|
def factory():
|
|
return defaultdict(factory)
|
|
|
|
|
|
TERMINAL = object()
|
|
|
|
|
|
def build(headers):
|
|
dct = defaultdict(factory)
|
|
for hdr in headers:
|
|
d = dct
|
|
for ch in hdr:
|
|
d = d[ch]
|
|
d[TERMINAL] = hdr
|
|
return dct
|
|
|
|
|
|
dct = build(headers)
|
|
|
|
|
|
HEADER = """\
|
|
/* The file is autogenerated from aiohttp/hdrs.py
|
|
Run ./tools/gen.py to update it after the origin changing. */
|
|
|
|
#include "_find_header.h"
|
|
|
|
#define NEXT_CHAR() \\
|
|
{ \\
|
|
count++; \\
|
|
if (count == size) { \\
|
|
/* end of search */ \\
|
|
return -1; \\
|
|
} \\
|
|
pchar++; \\
|
|
ch = *pchar; \\
|
|
last = (count == size -1); \\
|
|
} while(0);
|
|
|
|
int
|
|
find_header(const char *str, int size)
|
|
{
|
|
char *pchar = str;
|
|
int last;
|
|
char ch;
|
|
int count = -1;
|
|
pchar--;
|
|
"""
|
|
|
|
BLOCK = """
|
|
{label}
|
|
NEXT_CHAR();
|
|
switch (ch) {{
|
|
{cases}
|
|
default:
|
|
return -1;
|
|
}}
|
|
"""
|
|
|
|
CASE = """\
|
|
case '{char}':
|
|
if (last) {{
|
|
return {index};
|
|
}}
|
|
goto {next};"""
|
|
|
|
FOOTER = """
|
|
{missing}
|
|
missing:
|
|
/* nothing found */
|
|
return -1;
|
|
}}
|
|
"""
|
|
|
|
|
|
def gen_prefix(prefix, k):
|
|
if k == "-":
|
|
return prefix + "_"
|
|
else:
|
|
return prefix + k.upper()
|
|
|
|
|
|
def gen_block(dct, prefix, used_blocks, missing, out):
|
|
cases = {}
|
|
for k, v in dct.items():
|
|
if k is TERMINAL:
|
|
continue
|
|
next_prefix = gen_prefix(prefix, k)
|
|
term = v.get(TERMINAL)
|
|
if term is not None:
|
|
index = headers.index(term)
|
|
else:
|
|
index = -1
|
|
hi = k.upper()
|
|
lo = k.lower()
|
|
case = CASE.format(char=hi, index=index, next=next_prefix)
|
|
cases[hi] = case
|
|
if lo != hi:
|
|
case = CASE.format(char=lo, index=index, next=next_prefix)
|
|
cases[lo] = case
|
|
label = prefix + ":" if prefix else ""
|
|
if cases:
|
|
block = BLOCK.format(label=label, cases="\n".join(cases.values()))
|
|
out.write(block)
|
|
else:
|
|
missing.add(label)
|
|
for k, v in dct.items():
|
|
if not isinstance(v, defaultdict):
|
|
continue
|
|
block_name = gen_prefix(prefix, k)
|
|
if block_name in used_blocks:
|
|
continue
|
|
used_blocks.add(block_name)
|
|
gen_block(v, block_name, used_blocks, missing, out)
|
|
|
|
|
|
def gen(dct):
|
|
out = io.StringIO()
|
|
out.write(HEADER)
|
|
missing = set()
|
|
gen_block(dct, "", set(), missing, out)
|
|
missing_labels = "\n".join(m for m in sorted(missing))
|
|
out.write(FOOTER.format(missing=missing_labels))
|
|
return out
|
|
|
|
|
|
def gen_headers(headers):
|
|
out = io.StringIO()
|
|
out.write("# The file is autogenerated from aiohttp/hdrs.py\n")
|
|
out.write("# Run ./tools/gen.py to update it after the origin changing.")
|
|
out.write("\n\n")
|
|
out.write("from . import hdrs\n")
|
|
out.write("cdef tuple headers = (\n")
|
|
for hdr in headers:
|
|
out.write(" hdrs.{},\n".format(hdr.upper().replace("-", "_")))
|
|
out.write(")\n")
|
|
return out
|
|
|
|
|
|
# print(gen(dct).getvalue())
|
|
# print(gen_headers(headers).getvalue())
|
|
|
|
folder = ROOT / "aiohttp"
|
|
|
|
with (folder / "_find_header.c").open("w") as f:
|
|
f.write(gen(dct).getvalue())
|
|
|
|
with (folder / "_headers.pxi").open("w") as f:
|
|
f.write(gen_headers(headers).getvalue())
|