File: fficurses.py

package info (click to toggle)
pypy3 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 111,848 kB
  • sloc: python: 1,291,746; ansic: 74,281; asm: 5,187; cpp: 3,017; sh: 2,533; makefile: 544; xml: 243; lisp: 45; csh: 21; awk: 4
file content (127 lines) | stat: -rw-r--r-- 4,164 bytes parent folder | download | duplicates (2)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
""" The ffi for rpython
"""

from rpython.rtyper.lltypesystem import rffi
from rpython.rtyper.tool import rffi_platform
from rpython.translator.tool.cbuild import ExternalCompilationInfo

# We cannot trust ncurses5-config, it's broken in various ways in
# various versions.  For example it might not list -ltinfo even though
# it's needed, or --cflags might be completely empty.  On Ubuntu 10.04
# it gives -I/usr/include/ncurses, which doesn't exist at all.  Crap.

def try_cflags():
    yield ExternalCompilationInfo(includes=['curses.h', 'term.h'])
    yield ExternalCompilationInfo(includes=['curses.h', 'term.h'],
                                  include_dirs=['/usr/include/ncurses'])
    yield ExternalCompilationInfo(includes=['ncurses/curses.h',
                                            'ncurses/term.h'])

def try_ldflags():
    yield ExternalCompilationInfo(libraries=['curses'])
    yield ExternalCompilationInfo(libraries=['curses', 'tinfo'])
    yield ExternalCompilationInfo(libraries=['ncurses'])
    yield ExternalCompilationInfo(libraries=['ncurses'],
                                  library_dirs=['/usr/lib64'])

def try_tools():
    try:
        yield ExternalCompilationInfo.from_pkg_config("ncurses")
    except Exception:
        pass
    try:
        yield ExternalCompilationInfo.from_config_tool("ncurses5-config")
    except Exception:
        pass

def try_eci():
    for eci in try_tools():
        yield eci.merge(ExternalCompilationInfo(includes=['curses.h',
                                                          'term.h']))
    for eci1 in try_cflags():
        for eci2 in try_ldflags():
            yield eci1.merge(eci2)

def guess_eci():
    for eci in try_eci():
        class CConfig:
            _compilation_info_ = eci
            HAS = rffi_platform.Has("setupterm")
        if rffi_platform.configure(CConfig)['HAS']:
            return eci
    raise ImportError("failed to guess where ncurses is installed. "
                      "You might need to install libncurses5-dev or similar.")

eci = guess_eci()


# We should not use this 'eci' directly because it causes the #include
# of term.h to appear in all generated C sources, and term.h contains a
# poisonous quantity of #defines for common lower-case names like
# 'buttons' or 'lines' (!!!).  It is basically dangerous to include
# term.h in any C source file that may contain unrelated source code.

include_lines = '\n'.join(['#include <%s>' % _incl for _incl in eci.includes])
eci = eci.copy_without('includes')


eci = eci.merge(ExternalCompilationInfo(
   post_include_bits=[
        "RPY_EXTERN char *rpy_curses_setupterm(char *, int);\n"
        "RPY_EXTERN char *rpy_curses_tigetstr(char *);\n"
        "RPY_EXTERN char *rpy_curses_tparm(char *, int, int, int, int,"
        " int, int, int, int, int);"
        ],
    separate_module_sources=["""

%(include_lines)s

RPY_EXTERN
char *rpy_curses_setupterm(char *term, int fd)
{
    int errret = -42;
    if (setupterm(term, fd, &errret) == ERR) {
        switch (errret) {
        case 0:
            return "setupterm: could not find terminal";
        case -1:
            return "setupterm: could not find terminfo database";
        default:
            return "setupterm: unknown error";
        }
    }
    return NULL;
}

RPY_EXTERN
char *rpy_curses_tigetstr(char *capname)
{
    char *res = tigetstr(capname);
    if (res == (char *)-1)
        res = NULL;
    return res;
}

RPY_EXTERN
char *rpy_curses_tparm(char *str, int x0, int x1, int x2, int x3,
                       int x4, int x5, int x6, int x7, int x8)
{
    return tparm(str, x0, x1, x2, x3, x4, x5, x6, x7, x8);
}

""" % globals()]))


rpy_curses_setupterm = rffi.llexternal(
    "rpy_curses_setupterm", [rffi.CCHARP, rffi.INT], rffi.CCHARP,
    compilation_info=eci)

rpy_curses_tigetstr = rffi.llexternal(
    "rpy_curses_tigetstr", [rffi.CCHARP], rffi.CCHARP,
    compilation_info=eci)

rpy_curses_tparm = rffi.llexternal(
    "rpy_curses_tparm", [rffi.CCHARP, rffi.INT, rffi.INT, rffi.INT, rffi.INT,
                         rffi.INT, rffi.INT, rffi.INT, rffi.INT, rffi.INT],
    rffi.CCHARP,
    compilation_info=eci)