-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathsetup.py
94 lines (78 loc) · 2.63 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""Build cython extensions and generated files."""
import sys
import numpy as np
from Cython.Build import cythonize
from setuptools import setup
from setuptools.command.build_py import build_py
from wcwidth import wcwidth
_CWIDTH_HEADER = """\
#ifndef _WIN32
#include <stddef.h>
#endif
#include "cwidth.h"
int cwidth(uint32_t wc) {
// Character widths as generated by wcwidth.
// Each item in `CHAR_WIDTHS` represents an interval of ords with common width,
// i.e., `{0u, 31u, 0u}` means ords 0 through 31 (inclusive) have width 0.
// Intervals with width 1 are omitted so if an ord doesn't belong to any interval
// we can assume it has width 1.
static const uint32_t CHAR_WIDTHS[][3] = {
"""
_CWIDTH_FOOTER = """\
};
static const size_t CHAR_WIDTHS_LEN = sizeof(CHAR_WIDTHS) / sizeof(int[3]);
size_t lo = 0, hi = CHAR_WIDTHS_LEN, mid;
while(lo < hi) {
mid = (lo + hi) / 2;
if(wc < CHAR_WIDTHS[mid][0]) hi = mid;
else if(wc > CHAR_WIDTHS[mid][1]) lo = mid + 1;
else return CHAR_WIDTHS[mid][2];
}
return 1;
}
"""
def _create_cwidth():
"""
Build ``cwidth.c``.
This function builds the table used in ``cwidth.c`` needed to determine displayed
width of a character in the terminal. The widths are taken directly from `wcwidth`,
but the ``cwidth`` function is a couple of magnitude times faster than
``wcwidth.wcwidth``.
"""
groups = []
start = 0
group_width = 1
for codepoint in range(sys.maxunicode + 1):
char_width = max(wcwidth(chr(codepoint)), 0)
if char_width != group_width:
if group_width != 1:
groups.append((start, codepoint - 1, group_width))
group_width = char_width
start = codepoint
if group_width != 1:
groups.append((start, codepoint, group_width))
with open("src/batgrl/cwidth.c", "w") as file:
file.write(_CWIDTH_HEADER)
for group in groups:
file.write(" {{{}u, {}u, {}u}},\n".format(*group))
file.write(_CWIDTH_FOOTER)
class build_py_with_cwidth(build_py):
"""Generate ``cwidth.c`` on build."""
def run(self):
"""Generate ``cwidth.c`` on build."""
super().run()
_create_cwidth()
setup(
ext_modules=cythonize(
[
"src/batgrl/_fbuf.pyx",
"src/batgrl/_rendering.pyx",
"src/batgrl/_sixel.pyx",
"src/batgrl/char_width.pyx",
"src/batgrl/gadgets/_raycasting.pyx",
"src/batgrl/geometry/regions.pyx",
]
),
include_dirs=[np.get_include()],
cmdclass={"build_py": build_py_with_cwidth},
)