mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-24 14:22:28 +00:00
Improve linenoise and get it working on Windows
Some progress has been made on introducing completion but there's been difficulties using the Python C API to get local shell variables.
This commit is contained in:
parent
968474d291
commit
5029e20bef
23 changed files with 408 additions and 209 deletions
13
third_party/python/Modules/getbuildinfo.c
vendored
13
third_party/python/Modules/getbuildinfo.c
vendored
|
@ -38,18 +38,7 @@
|
|||
const char *
|
||||
Py_GetBuildInfo(void)
|
||||
{
|
||||
static char buildinfo[50 + sizeof(GITVERSION) +
|
||||
((sizeof(GITTAG) > sizeof(GITBRANCH)) ?
|
||||
sizeof(GITTAG) : sizeof(GITBRANCH))];
|
||||
const char *revision = _Py_gitversion();
|
||||
const char *sep = *revision ? ":" : "";
|
||||
const char *gitid = _Py_gitidentifier();
|
||||
if (!(*gitid))
|
||||
gitid = "default";
|
||||
PyOS_snprintf(buildinfo, sizeof(buildinfo),
|
||||
"%s%s%s, %.20s, %.9s", gitid, sep, revision,
|
||||
DATE, TIME);
|
||||
return buildinfo;
|
||||
return "cosmopolitan";
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
1
third_party/python/Modules/getpath.c
vendored
1
third_party/python/Modules/getpath.c
vendored
|
@ -492,7 +492,6 @@ calculate_path(void)
|
|||
|
||||
if(IsWindows())
|
||||
{
|
||||
fprintf(stderr, "python APE on Windows\n");
|
||||
delimiter[0] = L';';
|
||||
separator[0] = L'\\';
|
||||
}
|
||||
|
|
80
third_party/python/Programs/python.c
vendored
80
third_party/python/Programs/python.c
vendored
|
@ -7,17 +7,24 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
#include "third_party/linenoise/linenoise.h"
|
||||
#include "third_party/python/Include/ceval.h"
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/fileutils.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Include/pyport.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
/* clang-format off */
|
||||
|
||||
static jmp_buf jbuf;
|
||||
|
@ -28,6 +35,77 @@ OnKeyboardInterrupt(int sig)
|
|||
longjmp(jbuf, 1);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
GetMember(const char *s, Py_ssize_t n, PyObject *o)
|
||||
{
|
||||
const char *t;
|
||||
PyObject *k, *v;
|
||||
Py_ssize_t i, m;
|
||||
if (!o) return 0;
|
||||
for (i = 0; PyDict_Next(o, &i, &k, &v);) {
|
||||
if (v != Py_None && PyUnicode_Check(k)) {
|
||||
t = PyUnicode_AsUTF8AndSize(k, &m);
|
||||
printf("\r%`'.*s vs. %`'.*s\n", n, s, m, t);
|
||||
if (n == m && !memcmp(s, t, n)) {
|
||||
Py_INCREF(v);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
GetVar(const char *s, Py_ssize_t n)
|
||||
{
|
||||
PyObject *o;
|
||||
/*
|
||||
* TODO: Why doesn't PyEval_GetLocals() work?
|
||||
*/
|
||||
if ((o = GetMember(s, n, PyEval_GetLocals()))) return o;
|
||||
if ((o = GetMember(s, n, PyEval_GetGlobals()))) return o;
|
||||
if ((o = GetMember(s, n, PyEval_GetBuiltins()))) return o;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
TerminalComplete(const char *s, linenoiseCompletions *c, PyObject *o)
|
||||
{
|
||||
const char *t;
|
||||
PyObject *k, *v;
|
||||
Py_ssize_t i, n, m;
|
||||
if (!o) return;
|
||||
for (n = strlen(s), i = 0; PyDict_Next(o, &i, &k, &v);) {
|
||||
if (v != Py_None && PyUnicode_Check(k)) {
|
||||
t = PyUnicode_AsUTF8AndSize(k, &m);
|
||||
if (m > n && !memcmp(t, s, n)) {
|
||||
c->cvec = realloc(c->cvec, ++c->len * sizeof(*c->cvec));
|
||||
c->cvec[c->len - 1] = strdup(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TerminalCompletion(const char *s, linenoiseCompletions *c)
|
||||
{
|
||||
const char *p;
|
||||
PyObject *o, *q;
|
||||
if ((p = strchr(s, '.'))) {
|
||||
if (!(o = GetVar(s, p - s))) return;
|
||||
for (s = p + 1; (p = strchr(s, '.')); o = q) {
|
||||
if ((q = GetMember(s, p - s, o))) return;
|
||||
Py_DECREF(o);
|
||||
}
|
||||
TerminalComplete(s, c, o);
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
TerminalComplete(s, c, PyEval_GetLocals());
|
||||
TerminalComplete(s, c, PyEval_GetGlobals());
|
||||
TerminalComplete(s, c, PyEval_GetBuiltins());
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
TerminalReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
|
||||
{
|
||||
|
@ -66,6 +144,8 @@ main(int argc, char **argv)
|
|||
int i, res;
|
||||
char *oldloc;
|
||||
|
||||
showcrashreports();
|
||||
linenoiseSetCompletionCallback(TerminalCompletion);
|
||||
PyOS_ReadlineFunctionPointer = TerminalReadline;
|
||||
|
||||
/* Force malloc() allocator to bootstrap Python */
|
||||
|
|
1
third_party/python/Python/pylifecycle.c
vendored
1
third_party/python/Python/pylifecycle.c
vendored
|
@ -14,6 +14,7 @@
|
|||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
#include "third_party/python/Include/Python-ast.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue