Improve Python and Linenoise

This change reinvents all the GNU Readline features I discovered that I
couldn't live without, e.g. UTF-8, CTRL-R search and CTRL-Y yanking. It
now feels just as good in terms of user interface from the subconscious
workflow perspective. It's real nice to finally have an embeddable line
reader that's actually good with a 30 kb footprint and a bsd-2 license.

This change adds a directory to the examples folder, explaining how the
new Python compiler may be used.  Some of the bugs with Python binaries
have been addressed but overall it's still a work in progress.
This commit is contained in:
Justine Tunney 2021-09-11 22:30:37 -07:00
parent ad52387b74
commit 51904e2687
35 changed files with 3541 additions and 8587 deletions

View file

@ -152,6 +152,7 @@ include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include examples/examples.mk
include examples/pyapp/pyapp.mk
include tool/decode/lib/decodelib.mk
include tool/decode/decode.mk
include tool/hash/hash.mk

View file

@ -168,7 +168,7 @@ DEFAULT_LDFLAGS = \
--gc-sections \
--build-id=none \
--no-dynamic-linker \
-z max-page-size=0x1000 --cref -Map=$@.map
-z max-page-size=0x1000
ZIPOBJ_FLAGS = \
-b$(IMAGE_BASE_VIRTUAL)

View file

@ -63,6 +63,7 @@ o/$(MODE)/%.o: o/$(MODE)/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx
o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -x c -g0 -o $@ $<
o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -x c++ -g0 -o $@ $<
o/$(MODE)/%.cxx.o: %.c ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) -x c++ $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.ansi.o: %.ansi.c ; @$(COMPILE) -AOBJECTIFY.ansi $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $<

116
examples/pyapp/pyapp.mk Normal file
View file

@ -0,0 +1,116 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
#
# SYNOPSIS
#
# Actually Portable Python Tutorial
#
# DESCRIPTION
#
# This tutorial demonstrates how to compile Python apps as tiny
# static multiplatform APE executables as small as 1.9m in size
# using Cosmopolitan, which is a BSD-style multitenant codebase
#
# GETTING STARTED
#
# # run these commands after cloning the cosmo repo on linux
# $ make -j8 o//examples/pyapp/pyapp.com
# $ o//examples/pyapp/pyapp.com
# cosmopolitan is cool!
#
# HOW IT WORKS
#
# $ pyobj.com -m -o pyapp.o pyapp.py
# $ ld -static -nostdlib -T o//ape/ape.lds ape.o crt.o \
# pyapp.o \
# cosmopolitan-python-stage2.a \
# cosmopolitan-sqlite3.a \
# cosmopolitan-linenoise.a \
# cosmopolitan-bzip2.a \
# cosmopolitan-python-stage1.a \
# cosmopolitan.a
# $ ./pyapp.com
# cosmopolitan is cool!
#
# NOTES
#
# If you enjoy this tutorial, let us know jtunney@gmail.com. If
# you're building something cool, then we can we can add you to
# our .gitowners file which grants you commit access so you can
# indepnedently maintain your package, as part of the mono-repo
PKGS += PYAPP
PYAPP = $(PYAPP_DEPS) o/$(MODE)/examples/pyapp/pyapp.a
PYAPP_COMS = o/$(MODE)/examples/pyapp/pyapp.com
PYAPP_BINS = $(PYAPP_COMS) $(PYAPP_COMS:%=%.dbg)
# Specify our Cosmopolitan library dependencies
#
# - THIRD_PARTY_PYTHON_STAGE1 plus THIRD_PARTY_PYTHON_STAGE2 will
# define the Python CAPI and supported standard library modules
#
PYAPP_DIRECTDEPS = \
THIRD_PARTY_PYTHON_STAGE2
# Compute the transitive closure of dependencies. There's dozens of
# other static libraries we need, in order to build a static binary
# such as fmt.a, runtime.a, str.a etc. This magic statement figures
# them all out and arranges them in the correct order.
PYAPP_DEPS := $(call uniq,$(foreach x,$(PYAPP_DIRECTDEPS),$($(x))))
# # Asks PYOBJ.COM to turn our Python source into an ELF object which
# # contains (a) embedded zip file artifacts of our .py file and .pyc
# # which it it compiled; and (b) statically analyzed listings of our
# # python namespaces and imports that GNU ld will use for tree shake
# # NOTE: This code can be commented out since it's in build/rules.mk
# o/$(MODE)/examples/pyapp/pyapp.o: examples/pyapp/pyapp.py o/$(MODE)/third_party/python/pyobj
# o/$(MODE)/third_party/python/pyobj $(PYFLAGS) -o $@ $<
# We need to define how the repository source code path gets mapped
# into an APE ZIP file path. By convention, we place Python modules
# in `.python/` (which is accessible via open() system calls, using
# the synthetic path `"/zip/.python/"`) which means that if we want
# to turn `pyapp/pyapp.py` into `.python/pyapp.py` so it's imported
# using `import pyapp` then we can simply append to PYOBJ.COM flags
# flags above asking it to strip one directory component and prefix
# Lastly be sure that whenever you use this variable override trick
# you only do it to .o files, since otherwise it'll ruin everything
# Passing -m to PYOBJ.COM causes a C main() function to get yoinked
# and it means our Python module can no longer be used as a library
o/$(MODE)/examples/pyapp/pyapp.o: PYFLAGS += -m -C2 -P.python
# Asks PACKAGE.COM to sanity check our DIRECTDEPS and symbol graph.
# This program functions as an incremental linker. It also provides
# enhancements to the object code that GCC generated similar to LTO
# so be certain that your .com.dbg rule depends on the .pkg output!
o/$(MODE)/examples/pyapp/pyapp.pkg: \
o/$(MODE)/examples/pyapp/pyapp.o \
$(foreach x,$(PYAPP_DIRECTDEPS),$($(x)_A).pkg)
# Ask GNU LD to link our APE executable within an ELF binary shell.
# The CRT and APE dependencies are special dependencies that define
# your _start() / WinMain() entrpoints as well as APE linker script
o/$(MODE)/examples/pyapp/pyapp.com.dbg: \
$(PYAPP_DEPS) \
o/$(MODE)/examples/pyapp/pyapp.pkg \
o/$(MODE)/examples/pyapp/pyapp.o \
$(CRT) \
$(APE)
$(LINK) $(LINKARGS) -o $@
# # Unwrap the APE .COM binary, that's embedded within the linked file
# # NOTE: This line can be commented out, since it's in build/rules.mk
# o/$(MODE)/examples/pyapp/pyapp.com: \
# o/$(MODE)/examples/pyapp/pyapp.com.dbg
# $(OBJCOPY) -S -O binary $< $@
# Ensure that build config changes will invalidate build artifacts.
o/$(MODE)/examples/pyapp/pyapp.o: \
examples/pyapp/pyapp.mk
# By convention we want to be able to say `make -j8 o//examples/pyapp`
# and have it build all targets the package defines.
.PHONY: o/$(MODE)/examples/pyapp
o/$(MODE)/examples/pyapp: \
o/$(MODE)/examples/pyapp/pyapp.com \
o/$(MODE)/examples/pyapp/pyapp.com.dbg

4
examples/pyapp/pyapp.py Normal file
View file

@ -0,0 +1,4 @@
def main():
print('cosmopolitan is cool!')
if __name__ == '__main__':
main()

View file

@ -5745,7 +5745,7 @@ retry:
linenoiseSetFreeHintsCallback(free);
linenoiseSetHintsCallback(ShellHint);
linenoiseSetCompletionCallback(ShellCompletion);
if ((p = ezlinenoise(getprompt(NULL), "unbourne"))) {
if ((p = ezlinenoise("$ ", "unbourne"))) {
nr = min(strlen(p), IBUFSIZ - 2);
memcpy(buf, p, nr);
buf[nr++] = '\n';

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/log/backtrace.internal.h"
#include "libc/zipos/zipos.internal.h"
/**

View file

@ -31,9 +31,16 @@
*
* "a" ALFA
* "\316\261" ALPHA
* "\033[A" CURSOR UP
* "\033[38;5;202m" ORANGERED
* "\e[38;5;202m" ORANGERED
* "\e[A" UP
* "\e\e[A" ALT-UP
* "\001" CTRL-ALFA
* "\e\001" ALT-CTRL-ALFA
* "\eOP" PF1
* "\000" NUL
* "\e]rm -rf /\e\\" OSC
* "\302\233A" UP
* "\300\200" NUL
*
* This routine generalizes to ascii, utf-8, chorded modifier keys,
* function keys, color codes, c0/c1 control codes, cursor movement,
@ -44,15 +51,7 @@
* can cause the stream to go out of sync. This function recovers such
* events by ignoring continuation bytes at the beginning of each read.
*
* String control sequences, e.g. "\e_hello\e\\" currently are not
* tokenized as a single read. Lastly note, this function has limited
* support for UNICODE representations of C0/C1 control codes, e.g.
*
* "\000" NUL
* "\300\200" NUL
* "\302\233A" CURSOR UP
*
* @param buf is guaranteed to receive a NUL terminator if size>0
* @param p is guaranteed to receive a NUL terminator if n>0
* @return number of bytes read (helps differentiate "\0" vs. "")
* @see examples/ttyinfo.c
* @see ANSI X3.64-1979
@ -60,81 +59,198 @@
* @see FIPS-86
* @see ECMA-48
*/
ssize_t readansi(int fd, char *buf, size_t size) {
ssize_t readansi(int fd, char *p, size_t n) {
wint_t x;
uint8_t c;
int i, j, rc;
enum { kAscii, kUtf8, kEsc, kCsi, kSs } t;
if (size) buf[0] = 0;
for (j = i = 0, t = kAscii;;) {
if (i + 2 >= size) return enomem();
if ((rc = read(fd, &c, 1)) != 1) return rc;
buf[i++] = c;
buf[i] = 0;
ssize_t rc;
int e, i, j;
unsigned char c;
enum { kAscii, kUtf8, kEsc, kCsi1, kCsi2, kSs, kNf, kStr, kStr2, kDone } t;
e = errno;
t = kAscii;
x = i = j = 0;
if (n) p[0] = 0;
do {
for (;;) {
if (n) {
rc = read(fd, &c, 1);
} else {
rc = read(fd, 0, 0);
}
if (rc == -1 && errno == EINTR) {
if (!i) {
return -1;
}
} else if (rc == -1) {
return -1;
} else if (!rc) {
if (!i) {
errno = e;
return 0;
} else {
return eilseq();
}
} else {
break;
}
}
if (i + 1 < n) {
p[i] = c;
p[i + 1] = 0;
} else if (i < n) {
p[i] = 0;
}
++i;
switch (t) {
Whoopsie:
if (n) p[0] = c;
t = kAscii;
i = 1;
/* fallthrough */
case kAscii:
if (c < 0200) {
if (c == '\e') {
t = kEsc;
} else {
return i;
t = kDone;
}
} else if (c >= 0300) {
t = kUtf8;
x = ThomPikeByte(c);
j = ThomPikeLen(c) - 1;
} else {
/* ignore overlong sequences */
}
break;
case kUtf8:
x = ThomPikeMerge(x, c);
if (!--j) {
switch (x) {
case '\e':
t = kEsc;
break;
case 0x9b:
t = kCsi;
break;
default:
return i;
if ((c & 0300) == 0200) {
x = ThomPikeMerge(x, c);
if (!--j) {
switch (x) {
case '\e':
t = kEsc; /* parsed but not canonicalized */
break;
case 0x9b:
t = kCsi1; /* unusual but legal */
break;
case 0x8e:
case 0x8f:
t = kSs; /* unusual but legal */
break;
case 0x90: /* DCS (Device Control String) */
case 0x98: /* SOS (Start of String) */
case 0x9d: /* OSC (Operating System Command) */
case 0x9e: /* PM (Privacy Message) */
case 0x9f: /* APC (Application Program Command) */
t = kStr;
break;
default:
t = kDone;
break;
}
}
} else {
goto Whoopsie; /* ignore underlong sequences if not eof */
}
break;
case kEsc:
switch (c) {
case '[':
t = kCsi;
break;
case 'N':
case 'O':
t = kSs;
break;
case '\e':
case 0x20 ... 0x2F:
break;
default:
return i;
}
break;
case kCsi:
switch (c) {
case '[':
case ':':
case ';':
case '<':
case '=':
case '>':
case '?':
case '0' ... '9':
break;
default:
return i;
if (0x20 <= c && c <= 0x2f) {
t = kNf;
} else if (0x30 <= c && c <= 0x3f) { /* Fp */
t = kDone;
} else if (0x20 <= c && c <= 0x5F) { /* Fe */
switch (c) {
case '[':
t = kCsi1;
break;
case 'N': /* SS2 */
case 'O': /* SS3 */
t = kSs;
break;
case 'P': /* DCS (Device Control String) */
case 'X': /* SOS (Start of String) */
case ']': /* DCS (Operating System Command) */
case '^': /* PM (Privacy Message) */
case '_': /* DCS (Application Program Command) */
t = kStr;
break;
case '\\':
goto Whoopsie;
default:
t = kDone;
break;
}
} else if (0x60 <= c && c <= 0x7e) { /* Fs */
t = kDone;
} else if (c == '\e') {
if (i < 3) {
t = kEsc; /* alt chording */
} else {
t = kDone; /* esc mashing */
i = 1;
}
} else {
t = kDone;
}
break;
case kSs:
return i;
t = kDone;
break;
case kNf:
if (0x30 <= c && c <= 0x7e) {
t = kDone;
} else if (!(0x20 <= c && c <= 0x2f)) {
goto Whoopsie;
}
break;
case kCsi1:
if (0x20 <= c && c <= 0x2f) {
t = kCsi2;
} else if (c == '[' && i == 3) {
/* linux function keys */
} else if (0x40 <= c && c <= 0x7e) {
t = kDone;
} else if (!(0x30 <= c && c <= 0x3f)) {
goto Whoopsie;
}
break;
case kCsi2:
if (0x40 <= c && c <= 0x7e) {
t = kDone;
} else if (!(0x20 <= c && c <= 0x2f)) {
goto Whoopsie;
}
break;
case kStr:
switch (c) {
case '\a':
t = kDone;
break;
case '\e': /* ESC */
case 0302: /* C1 (UTF-8) */
t = kStr2;
break;
default:
break;
}
break;
case kStr2:
switch (c) {
case '\a':
t = kDone;
break;
case '\\': /* ST (ASCII) */
case 0234: /* ST (UTF-8) */
t = kDone;
break;
default:
t = kStr;
break;
}
break;
default:
unreachable;
}
}
} while (t != kDone);
errno = e;
return i;
}

View file

@ -104,6 +104,7 @@ privileged noasan void ftracer(void) {
p = mempcpy(p, symbol, symbolsize);
*p++ = ' ';
p += uint64toarray_radix10((stamp - laststamp) / 3.3, p);
*p++ = '\r';
*p++ = '\n';
write(2, g_buf, p - g_buf);
}

View file

@ -46,7 +46,7 @@ ssize_t getdelim(char **s, size_t *n, int delim, FILE *f) {
f->state = errno = EBADF;
return -1;
}
if (f->beg > f->end || f->bufmode == _IONBF) {
if (f->beg > f->end) {
f->state = errno = EINVAL;
return -1;
}

File diff suppressed because it is too large Load diff

423
libc/str/iswseparator.c Normal file
View file

@ -0,0 +1,423 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/str/str.h"
static const unsigned short kCodes[][2] = {
{0x00aa, 0x00aa}, /* 1x English */
{0x00b2, 0x00b3}, /* 2x English Arabic */
{0x00b5, 0x00b5}, /* 1x Greek */
{0x00b9, 0x00ba}, /* 2x English Arabic */
{0x00bc, 0x00be}, /* 3x Vulgar English Arabic */
{0x00c0, 0x00d6}, /* 23x Watin */
{0x00d8, 0x00f6}, /* 31x Watin */
{0x0100, 0x02c1}, /* 450x Watin-AB,IPA,Spacemod */
{0x02c6, 0x02d1}, /* 12x Spacemod */
{0x02e0, 0x02e4}, /* 5x Spacemod */
{0x02ec, 0x02ec}, /* 1x Spacemod */
{0x02ee, 0x02ee}, /* 1x Spacemod */
{0x0370, 0x0374}, /* 5x Greek */
{0x0376, 0x0377}, /* 2x Greek */
{0x037a, 0x037d}, /* 4x Greek */
{0x037f, 0x037f}, /* 1x Greek */
{0x0386, 0x0386}, /* 1x Greek */
{0x0388, 0x038a}, /* 3x Greek */
{0x038c, 0x038c}, /* 1x Greek */
{0x038e, 0x03a1}, /* 20x Greek */
{0x03a3, 0x03f5}, /* 83x Greek */
{0x03f7, 0x0481}, /* 139x Greek */
{0x048a, 0x052f}, /* 166x Cyrillic */
{0x0531, 0x0556}, /* 38x Armenian */
{0x0560, 0x0588}, /* 41x Armenian */
{0x05d0, 0x05ea}, /* 27x Hebrew */
{0x0620, 0x064a}, /* 43x Arabic */
{0x0660, 0x0669}, /* 10x Arabic */
{0x0671, 0x06d3}, /* 99x Arabic */
{0x06ee, 0x06fc}, /* 15x Arabic */
{0x0712, 0x072f}, /* 30x Syriac */
{0x074d, 0x07a5}, /* 89x Syriac,Arabic2,Thaana */
{0x07c0, 0x07ea}, /* 43x NKo */
{0x0800, 0x0815}, /* 22x Samaritan */
{0x0840, 0x0858}, /* 25x Mandaic */
{0x0904, 0x0939}, /* 54x Devanagari */
{0x0993, 0x09a8}, /* 22x Bengali */
{0x09e6, 0x09f1}, /* 12x Bengali */
{0x0a13, 0x0a28}, /* 22x Gurmukhi */
{0x0a66, 0x0a6f}, /* 10x Gurmukhi */
{0x0a93, 0x0aa8}, /* 22x Gujarati */
{0x0b13, 0x0b28}, /* 22x Oriya */
{0x0c92, 0x0ca8}, /* 23x Kannada */
{0x0caa, 0x0cb3}, /* 10x Kannada */
{0x0ce6, 0x0cef}, /* 10x Kannada */
{0x0d12, 0x0d3a}, /* 41x Malayalam */
{0x0d85, 0x0d96}, /* 18x Sinhala */
{0x0d9a, 0x0db1}, /* 24x Sinhala */
{0x0de6, 0x0def}, /* 10x Sinhala */
{0x0e01, 0x0e30}, /* 48x Thai */
{0x0e8c, 0x0ea3}, /* 24x Lao */
{0x0f20, 0x0f33}, /* 20x Tibetan */
{0x0f49, 0x0f6c}, /* 36x Tibetan */
{0x109e, 0x10c5}, /* 40x Myanmar,Georgian */
{0x10d0, 0x10fa}, /* 43x Georgian */
{0x10fc, 0x1248}, /* 333x Georgian,Hangul,Ethiopic */
{0x13a0, 0x13f5}, /* 86x Cherokee */
{0x1401, 0x166d}, /* 621x Aboriginal */
{0x16a0, 0x16ea}, /* 75x Runic */
{0x1700, 0x170c}, /* 13x Tagalog */
{0x1780, 0x17b3}, /* 52x Khmer */
{0x1820, 0x1878}, /* 89x Mongolian */
{0x1a00, 0x1a16}, /* 23x Buginese */
{0x1a20, 0x1a54}, /* 53x Tai Tham */
{0x1a80, 0x1a89}, /* 10x Tai Tham */
{0x1a90, 0x1a99}, /* 10x Tai Tham */
{0x1b05, 0x1b33}, /* 47x Balinese */
{0x1b50, 0x1b59}, /* 10x Balinese */
{0x1b83, 0x1ba0}, /* 30x Sundanese */
{0x1bae, 0x1be5}, /* 56x Sundanese */
{0x1c90, 0x1cba}, /* 43x Georgian2 */
{0x1cbd, 0x1cbf}, /* 3x Georgian2 */
{0x1e00, 0x1f15}, /* 278x Watin-C,Greek2 */
{0x2070, 0x2071}, /* 2x Supersub */
{0x2074, 0x2079}, /* 6x Supersub */
{0x207f, 0x2089}, /* 11x Supersub */
{0x2090, 0x209c}, /* 13x Supersub */
{0x2100, 0x2117}, /* 24x Letterlike */
{0x2119, 0x213f}, /* 39x Letterlike */
{0x2145, 0x214a}, /* 6x Letterlike */
{0x214c, 0x218b}, /* 64x Letterlike,Numbery */
{0x21af, 0x21cd}, /* 31x Arrows */
{0x21d5, 0x21f3}, /* 31x Arrows */
{0x230c, 0x231f}, /* 20x Technical */
{0x232b, 0x237b}, /* 81x Technical */
{0x237d, 0x239a}, /* 30x Technical */
{0x23b4, 0x23db}, /* 40x Technical */
{0x23e2, 0x2426}, /* 69x Technical,ControlPictures */
{0x2460, 0x25b6}, /* 343x Enclosed,Boxes,Blocks,Shapes */
{0x25c2, 0x25f7}, /* 54x Shapes */
{0x2600, 0x266e}, /* 111x Symbols */
{0x2670, 0x2767}, /* 248x Symbols,Dingbats */
{0x2776, 0x27bf}, /* 74x Dingbats */
{0x2800, 0x28ff}, /* 256x Braille */
{0x2c00, 0x2c2e}, /* 47x Glagolitic */
{0x2c30, 0x2c5e}, /* 47x Glagolitic */
{0x2c60, 0x2ce4}, /* 133x Watin-D */
{0x2d00, 0x2d25}, /* 38x Georgian2 */
{0x2d30, 0x2d67}, /* 56x Tifinagh */
{0x2d80, 0x2d96}, /* 23x Ethiopic2 */
{0x2e2f, 0x2e2f}, /* 1x Punctuation2 */
{0x3005, 0x3007}, /* 3x CJK Symbols & Punctuation */
{0x3021, 0x3029}, /* 9x CJK Symbols & Punctuation */
{0x3031, 0x3035}, /* 5x CJK Symbols & Punctuation */
{0x3038, 0x303c}, /* 5x CJK Symbols & Punctuation */
{0x3041, 0x3096}, /* 86x Hiragana */
{0x30a1, 0x30fa}, /* 90x Katakana */
{0x3105, 0x312f}, /* 43x Bopomofo */
{0x3131, 0x318e}, /* 94x Hangul Compatibility Jamo */
{0x31a0, 0x31ba}, /* 27x Bopomofo Extended */
{0x31f0, 0x31ff}, /* 16x Katakana Phonetic Extensions */
{0x3220, 0x3229}, /* 10x Enclosed CJK Letters & Months */
{0x3248, 0x324f}, /* 8x Enclosed CJK Letters & Months */
{0x3251, 0x325f}, /* 15x Enclosed CJK Letters & Months */
{0x3280, 0x3289}, /* 10x Enclosed CJK Letters & Months */
{0x32b1, 0x32bf}, /* 15x Enclosed CJK Letters & Months */
{0x3400, 0x4db5}, /* 6582x CJK Unified Ideographs Extension A */
{0x4dc0, 0x9fef}, /* 21040x Yijing Hexagram, CJK Unified Ideographs */
{0xa000, 0xa48c}, /* 1165x Yi Syllables */
{0xa4d0, 0xa4fd}, /* 46x Lisu */
{0xa500, 0xa60c}, /* 269x Vai */
{0xa610, 0xa62b}, /* 28x Vai */
{0xa6a0, 0xa6ef}, /* 80x Bamum */
{0xa80c, 0xa822}, /* 23x Syloti Nagri */
{0xa840, 0xa873}, /* 52x Phags-pa */
{0xa882, 0xa8b3}, /* 50x Saurashtra */
{0xa8d0, 0xa8d9}, /* 10x Saurashtra */
{0xa900, 0xa925}, /* 38x Kayah Li */
{0xa930, 0xa946}, /* 23x Rejang */
{0xa960, 0xa97c}, /* 29x Hangul Jamo Extended-A */
{0xa984, 0xa9b2}, /* 47x Javanese */
{0xa9cf, 0xa9d9}, /* 11x Javanese */
{0xaa00, 0xaa28}, /* 41x Cham */
{0xaa50, 0xaa59}, /* 10x Cham */
{0xabf0, 0xabf9}, /* 10x Meetei Mayek */
{0xac00, 0xd7a3}, /* 11172x Hangul Syllables */
{0xf900, 0xfa6d}, /* 366x CJK Compatibility Ideographs */
{0xfa70, 0xfad9}, /* 106x CJK Compatibility Ideographs */
{0xfb1f, 0xfb28}, /* 10x Alphabetic Presentation Forms */
{0xfb2a, 0xfb36}, /* 13x Alphabetic Presentation Forms */
{0xfb46, 0xfbb1}, /* 108x Alphabetic Presentation Forms */
{0xfbd3, 0xfd3d}, /* 363x Arabic Presentation Forms-A */
{0xfe76, 0xfefc}, /* 135x Arabic Presentation Forms-B */
{0xff10, 0xff19}, /* 10x Dubs */
{0xff21, 0xff3a}, /* 26x Dubs */
{0xff41, 0xff5a}, /* 26x Dubs */
{0xff66, 0xffbe}, /* 89x Dubs */
{0xffc2, 0xffc7}, /* 6x Dubs */
{0xffca, 0xffcf}, /* 6x Dubs */
{0xffd2, 0xffd7}, /* 6x Dubs */
{0xffda, 0xffdc}, /* 3x Dubs */
};
static const unsigned kAstralCodes[][2] = {
{0x10107, 0x10133}, /* 45x Aegean */
{0x10140, 0x10178}, /* 57x Ancient Greek Numbers */
{0x1018a, 0x1018b}, /* 2x Ancient Greek Numbers */
{0x10280, 0x1029c}, /* 29x Lycian */
{0x102a0, 0x102d0}, /* 49x Carian */
{0x102e1, 0x102fb}, /* 27x Coptic Epact Numbers */
{0x10300, 0x10323}, /* 36x Old Italic */
{0x1032d, 0x1034a}, /* 30x Old Italic, Gothic */
{0x10350, 0x10375}, /* 38x Old Permic */
{0x10380, 0x1039d}, /* 30x Ugaritic */
{0x103a0, 0x103c3}, /* 36x Old Persian */
{0x103c8, 0x103cf}, /* 8x Old Persian */
{0x103d1, 0x103d5}, /* 5x Old Persian */
{0x10400, 0x1049d}, /* 158x Deseret, Shavian, Osmanya */
{0x104b0, 0x104d3}, /* 36x Osage */
{0x104d8, 0x104fb}, /* 36x Osage */
{0x10500, 0x10527}, /* 40x Elbasan */
{0x10530, 0x10563}, /* 52x Caucasian Albanian */
{0x10600, 0x10736}, /* 311x Linear A */
{0x10800, 0x10805}, /* 6x Cypriot Syllabary */
{0x1080a, 0x10835}, /* 44x Cypriot Syllabary */
{0x10837, 0x10838}, /* 2x Cypriot Syllabary */
{0x1083f, 0x1089e}, /* 86x Cypriot,ImperialAramaic,Palmyrene,Nabataean */
{0x108e0, 0x108f2}, /* 19x Hatran */
{0x108f4, 0x108f5}, /* 2x Hatran */
{0x108fb, 0x1091b}, /* 33x Hatran */
{0x10920, 0x10939}, /* 26x Lydian */
{0x10980, 0x109b7}, /* 56x Meroitic Hieromarks */
{0x109bc, 0x109cf}, /* 20x Meroitic Cursive */
{0x109d2, 0x10a00}, /* 47x Meroitic Cursive */
{0x10a10, 0x10a13}, /* 4x Kharoshthi */
{0x10a15, 0x10a17}, /* 3x Kharoshthi */
{0x10a19, 0x10a35}, /* 29x Kharoshthi */
{0x10a40, 0x10a48}, /* 9x Kharoshthi */
{0x10a60, 0x10a7e}, /* 31x Old South Arabian */
{0x10a80, 0x10a9f}, /* 32x Old North Arabian */
{0x10ac0, 0x10ac7}, /* 8x Manichaean */
{0x10ac9, 0x10ae4}, /* 28x Manichaean */
{0x10aeb, 0x10aef}, /* 5x Manichaean */
{0x10b00, 0x10b35}, /* 54x Avestan */
{0x10b40, 0x10b55}, /* 22x Inscriptional Parthian */
{0x10b58, 0x10b72}, /* 27x Inscriptional Parthian and Pahlavi */
{0x10b78, 0x10b91}, /* 26x Inscriptional Pahlavi, Psalter Pahlavi */
{0x10c00, 0x10c48}, /* 73x Old Turkic */
{0x10c80, 0x10cb2}, /* 51x Old Hungarian */
{0x10cc0, 0x10cf2}, /* 51x Old Hungarian */
{0x10cfa, 0x10d23}, /* 42x Old Hungarian, Hanifi Rohingya */
{0x10d30, 0x10d39}, /* 10x Hanifi Rohingya */
{0x10e60, 0x10e7e}, /* 31x Rumi Numeral Symbols */
{0x10f00, 0x10f27}, /* 40x Old Sogdian */
{0x10f30, 0x10f45}, /* 22x Sogdian */
{0x10f51, 0x10f54}, /* 4x Sogdian */
{0x10fe0, 0x10ff6}, /* 23x Elymaic */
{0x11003, 0x11037}, /* 53x Brahmi */
{0x11052, 0x1106f}, /* 30x Brahmi */
{0x11083, 0x110af}, /* 45x Kaithi */
{0x110d0, 0x110e8}, /* 25x Sora Sompeng */
{0x110f0, 0x110f9}, /* 10x Sora Sompeng */
{0x11103, 0x11126}, /* 36x Chakma */
{0x11136, 0x1113f}, /* 10x Chakma */
{0x11144, 0x11144}, /* 1x Chakma */
{0x11150, 0x11172}, /* 35x Mahajani */
{0x11176, 0x11176}, /* 1x Mahajani */
{0x11183, 0x111b2}, /* 48x Sharada */
{0x111c1, 0x111c4}, /* 4x Sharada */
{0x111d0, 0x111da}, /* 11x Sharada */
{0x111dc, 0x111dc}, /* 1x Sharada */
{0x111e1, 0x111f4}, /* 20x Sinhala Archaic Numbers */
{0x11200, 0x11211}, /* 18x Khojki */
{0x11213, 0x1122b}, /* 25x Khojki */
{0x11280, 0x11286}, /* 7x Multani */
{0x11288, 0x11288}, /* 1x Multani */
{0x1128a, 0x1128d}, /* 4x Multani */
{0x1128f, 0x1129d}, /* 15x Multani */
{0x1129f, 0x112a8}, /* 10x Multani */
{0x112b0, 0x112de}, /* 47x Khudawadi */
{0x112f0, 0x112f9}, /* 10x Khudawadi */
{0x11305, 0x1130c}, /* 8x Grantha */
{0x1130f, 0x11310}, /* 2x Grantha */
{0x11313, 0x11328}, /* 22x Grantha */
{0x1132a, 0x11330}, /* 7x Grantha */
{0x11332, 0x11333}, /* 2x Grantha */
{0x11335, 0x11339}, /* 5x Grantha */
{0x1133d, 0x1133d}, /* 1x Grantha */
{0x11350, 0x11350}, /* 1x Grantha */
{0x1135d, 0x11361}, /* 5x Grantha */
{0x11400, 0x11434}, /* 53x Newa */
{0x11447, 0x1144a}, /* 4x Newa */
{0x11450, 0x11459}, /* 10x Newa */
{0x1145f, 0x1145f}, /* 1x Newa */
{0x11480, 0x114af}, /* 48x Tirhuta */
{0x114c4, 0x114c5}, /* 2x Tirhuta */
{0x114c7, 0x114c7}, /* 1x Tirhuta */
{0x114d0, 0x114d9}, /* 10x Tirhuta */
{0x11580, 0x115ae}, /* 47x Siddham */
{0x115d8, 0x115db}, /* 4x Siddham */
{0x11600, 0x1162f}, /* 48x Modi */
{0x11644, 0x11644}, /* 1x Modi */
{0x11650, 0x11659}, /* 10x Modi */
{0x11680, 0x116aa}, /* 43x Takri */
{0x116b8, 0x116b8}, /* 1x Takri */
{0x116c0, 0x116c9}, /* 10x Takri */
{0x11700, 0x1171a}, /* 27x Ahom */
{0x11730, 0x1173b}, /* 12x Ahom */
{0x11800, 0x1182b}, /* 44x Dogra */
{0x118a0, 0x118f2}, /* 83x Warang Citi */
{0x118ff, 0x118ff}, /* 1x Warang Citi */
{0x119a0, 0x119a7}, /* 8x Nandinagari */
{0x119aa, 0x119d0}, /* 39x Nandinagari */
{0x119e1, 0x119e1}, /* 1x Nandinagari */
{0x119e3, 0x119e3}, /* 1x Nandinagari */
{0x11a00, 0x11a00}, /* 1x Zanabazar Square */
{0x11a0b, 0x11a32}, /* 40x Zanabazar Square */
{0x11a3a, 0x11a3a}, /* 1x Zanabazar Square */
{0x11a50, 0x11a50}, /* 1x Soyombo */
{0x11a5c, 0x11a89}, /* 46x Soyombo */
{0x11a9d, 0x11a9d}, /* 1x Soyombo */
{0x11ac0, 0x11af8}, /* 57x Pau Cin Hau */
{0x11c00, 0x11c08}, /* 9x Bhaiksuki */
{0x11c0a, 0x11c2e}, /* 37x Bhaiksuki */
{0x11c40, 0x11c40}, /* 1x Bhaiksuki */
{0x11c50, 0x11c6c}, /* 29x Bhaiksuki */
{0x11c72, 0x11c8f}, /* 30x Marchen */
{0x11d00, 0x11d06}, /* 7x Masaram Gondi */
{0x11d08, 0x11d09}, /* 2x Masaram Gondi */
{0x11d0b, 0x11d30}, /* 38x Masaram Gondi */
{0x11d46, 0x11d46}, /* 1x Masaram Gondi */
{0x11d50, 0x11d59}, /* 10x Masaram Gondi */
{0x11d60, 0x11d65}, /* 6x Gunjala Gondi */
{0x11d67, 0x11d68}, /* 2x Gunjala Gondi */
{0x11d6a, 0x11d89}, /* 32x Gunjala Gondi */
{0x11d98, 0x11d98}, /* 1x Gunjala Gondi */
{0x11da0, 0x11da9}, /* 10x Gunjala Gondi */
{0x11ee0, 0x11ef2}, /* 19x Makasar */
{0x11fc0, 0x11fd4}, /* 21x Tamil Supplement */
{0x12000, 0x12399}, /* 922x Cuneiform */
{0x12400, 0x1246e}, /* 111x Cuneiform Numbers & Punctuation */
{0x12480, 0x12543}, /* 196x Early Dynastic Cuneiform */
{0x13000, 0x1342e}, /* 1071x Egyptian Hieromarks */
{0x14400, 0x14646}, /* 583x Anatolian Hieromarks */
{0x16800, 0x16a38}, /* 569x Bamum Supplement */
{0x16a40, 0x16a5e}, /* 31x Mro */
{0x16a60, 0x16a69}, /* 10x Mro */
{0x16ad0, 0x16aed}, /* 30x Bassa Vah */
{0x16b00, 0x16b2f}, /* 48x Pahawh Hmong */
{0x16b40, 0x16b43}, /* 4x Pahawh Hmong */
{0x16b50, 0x16b59}, /* 10x Pahawh Hmong */
{0x16b5b, 0x16b61}, /* 7x Pahawh Hmong */
{0x16b63, 0x16b77}, /* 21x Pahawh Hmong */
{0x16b7d, 0x16b8f}, /* 19x Pahawh Hmong */
{0x16e40, 0x16e96}, /* 87x Medefaidrin */
{0x16f00, 0x16f4a}, /* 75x Miao */
{0x16f50, 0x16f50}, /* 1x Miao */
{0x16f93, 0x16f9f}, /* 13x Miao */
{0x16fe0, 0x16fe1}, /* 2x Ideographic Symbols & Punctuation */
{0x16fe3, 0x16fe3}, /* 1x Ideographic Symbols & Punctuation */
{0x17000, 0x187f7}, /* 6136x Tangut */
{0x18800, 0x18af2}, /* 755x Tangut Components */
{0x1b000, 0x1b11e}, /* 287x Kana Supplement */
{0x1b150, 0x1b152}, /* 3x Small Kana Extension */
{0x1b164, 0x1b167}, /* 4x Small Kana Extension */
{0x1b170, 0x1b2fb}, /* 396x Nushu */
{0x1bc00, 0x1bc6a}, /* 107x Duployan */
{0x1bc70, 0x1bc7c}, /* 13x Duployan */
{0x1bc80, 0x1bc88}, /* 9x Duployan */
{0x1bc90, 0x1bc99}, /* 10x Duployan */
{0x1d2e0, 0x1d2f3}, /* 20x Mayan Numerals */
{0x1d360, 0x1d378}, /* 25x Counting Rod Numerals */
{0x1d400, 0x1d454}, /* 85x 𝐀..𝑔 Math */
{0x1d456, 0x1d49c}, /* 71x 𝑖..𝒜 Math */
{0x1d49e, 0x1d49f}, /* 2x 𝒞..𝒟 Math */
{0x1d4a2, 0x1d4a2}, /* 1x 𝒢..𝒢 Math */
{0x1d4a5, 0x1d4a6}, /* 2x 𝒥..𝒦 Math */
{0x1d4a9, 0x1d4ac}, /* 4x 𝒩..𝒬 Math */
{0x1d4ae, 0x1d4b9}, /* 12x 𝒮..𝒹 Math */
{0x1d4bb, 0x1d4bb}, /* 1x 𝒻..𝒻 Math */
{0x1d4bd, 0x1d4c3}, /* 7x 𝒽..𝓃 Math */
{0x1d4c5, 0x1d505}, /* 65x 𝓅..𝔅 Math */
{0x1d507, 0x1d50a}, /* 4x 𝔇..𝔊 Math */
{0x1d50d, 0x1d514}, /* 8x 𝔍..𝔔 Math */
{0x1d516, 0x1d51c}, /* 7x 𝔖..𝔜 Math */
{0x1d51e, 0x1d539}, /* 28x 𝔞..𝔹 Math */
{0x1d53b, 0x1d53e}, /* 4x 𝔻..𝔾 Math */
{0x1d540, 0x1d544}, /* 5x 𝕀..𝕄 Math */
{0x1d546, 0x1d546}, /* 1x 𝕆..𝕆 Math */
{0x1d54a, 0x1d550}, /* 7x 𝕊..𝕐 Math */
{0x1d552, 0x1d6a5}, /* 340x 𝕒..𝚥 Math */
{0x1d6a8, 0x1d6c0}, /* 25x 𝚨..𝛀 Math */
{0x1d6c2, 0x1d6da}, /* 25x 𝛂..𝛚 Math */
{0x1d6dc, 0x1d6fa}, /* 31x 𝛜..𝛺 Math */
{0x1d6fc, 0x1d714}, /* 25x 𝛼..𝜔 Math */
{0x1d716, 0x1d734}, /* 31x 𝜖..𝜴 Math */
{0x1d736, 0x1d74e}, /* 25x 𝜶..𝝎 Math */
{0x1d750, 0x1d76e}, /* 31x 𝝐..𝝮 Math */
{0x1d770, 0x1d788}, /* 25x 𝝰..𝞈 Math */
{0x1d78a, 0x1d7a8}, /* 31x 𝞊..𝞨 Math */
{0x1d7aa, 0x1d7c2}, /* 25x 𝞪..𝟂 Math */
{0x1d7c4, 0x1d7cb}, /* 8x 𝟄..𝟋 Math */
{0x1d7ce, 0x1d9ff}, /* 562x Math, Sutton SignWriting */
{0x1f100, 0x1f10c}, /* 13x Enclosed Alphanumeric Supplement */
{0x20000, 0x2a6d6}, /* 42711x CJK Unified Ideographs Extension B */
{0x2a700, 0x2b734}, /* 4149x CJK Unified Ideographs Extension C */
{0x2b740, 0x2b81d}, /* 222x CJK Unified Ideographs Extension D */
{0x2b820, 0x2cea1}, /* 5762x CJK Unified Ideographs Extension E */
{0x2ceb0, 0x2ebe0}, /* 7473x CJK Unified Ideographs Extension F */
{0x2f800, 0x2fa1d}, /* 542x CJK Compatibility Ideographs Supplement */
};
/**
* Returns nonzero if 𝑐 isn't alphanumeric.
*
* Line reading interfaces generally define this operation as UNICODE
* characters that aren't in the letter category (Lu, Ll, Lt, Lm, Lo)
* and aren't in the number categorie (Nd, Nl, No). We also add a few
* other things like blocks and emoji (So).
*/
int iswseparator(wint_t c) {
int m, l, r;
if (c < 0200) {
return !(('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') ||
('a' <= c && c <= 'z'));
}
if (c <= 0xffff) {
l = 0;
r = sizeof(kCodes) / sizeof(kCodes[0]);
while (l < r) {
m = (l + r) >> 1;
if (kCodes[m][1] < c) {
l = m + 1;
} else {
r = m;
}
}
return !(kCodes[l][0] <= c && c <= kCodes[l][1]);
} else {
l = 0;
r = sizeof(kAstralCodes) / sizeof(kAstralCodes[0]);
while (l < r) {
m = (l + r) >> 1;
if (kAstralCodes[m][1] < c) {
l = m + 1;
} else {
r = m;
}
}
return !(kAstralCodes[l][0] <= c && c <= kAstralCodes[l][1]);
}
}

File diff suppressed because it is too large Load diff

View file

@ -73,6 +73,7 @@ int iswupper(wint_t);
int iswxdigit(wint_t);
int iswpunct(wint_t);
int iswprint(wint_t);
int iswseparator(wint_t);
wint_t towlower(wint_t);
wint_t towupper(wint_t);

View file

@ -52,8 +52,6 @@ o//libc/str/bzero.o: \
OVERRIDE_CFLAGS += \
-O2
o/$(MODE)/libc/str/fun3.o \
o/$(MODE)/libc/str/sha3.o \
o/$(MODE)/libc/str/dosdatetimetounix.o: \
OVERRIDE_CFLAGS += \
-O3
@ -76,7 +74,8 @@ o/$(MODE)/libc/str/getzipcfiletimestamps.o: \
o/$(MODE)/libc/str/iswpunct.o \
o/$(MODE)/libc/str/iswupper.o \
o/$(MODE)/libc/str/iswlower.o: \
o/$(MODE)/libc/str/iswlower.o \
o/$(MODE)/libc/str/iswseparator.o: \
OVERRIDE_CFLAGS += \
-fno-jump-tables

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -34,23 +34,44 @@ TEST(readansi, test) {
_exit(0);
}
close(fds[1]);
EXPECT_EQ(1, readansi(fds[0], b, 16));
EXPECT_EQ(1, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("a", b);
EXPECT_EQ(2, readansi(fds[0], b, 16));
EXPECT_EQ(2, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\eM", b);
EXPECT_EQ(3, readansi(fds[0], b, 16));
EXPECT_EQ(3, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\e[A", b);
EXPECT_EQ(3, readansi(fds[0], b, 16));
EXPECT_EQ(3, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("", b);
EXPECT_EQ(10, readansi(fds[0], b, 16));
EXPECT_EQ(10, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\e[123;456R", b);
EXPECT_EQ(4, readansi(fds[0], b, 16));
EXPECT_EQ(4, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\e[>c", b);
EXPECT_EQ(3, readansi(fds[0], b, 16));
EXPECT_EQ(3, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\eOz", b);
EXPECT_EQ(3, readansi(fds[0], b, 16));
EXPECT_EQ(3, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("\xc2\x9bM", b);
EXPECT_EQ(0, readansi(fds[0], b, 16));
EXPECT_EQ(0, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("", b);
ASSERT_NE(-1, wait(&ws));
ASSERT_TRUE(WIFEXITED(ws));
ASSERT_EQ(0, WEXITSTATUS(ws));
}
TEST(readansi, testOperatingSystemCommand) {
char b[32];
const char *s;
int ws, pid, fds[2];
s = "\e]rm -rf /\e\\";
ASSERT_NE(-1, pipe(fds));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
write(fds[1], s, strlen(s));
_exit(0);
}
close(fds[1]);
EXPECT_EQ(strlen(s), readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ(s, b);
EXPECT_EQ(0, readansi(fds[0], b, sizeof(b)));
EXPECT_STREQ("", b);
ASSERT_NE(-1, wait(&ws));
ASSERT_TRUE(WIFEXITED(ws));

View file

@ -16,22 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/runtime/gc.internal.h"
#include "libc/x/x.h"
#include "third_party/linenoise/linenoise.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
/**
* Reads line of input from terminal w/ history file.
*/
char *ezlinenoise(const char *prompt, const char *prog) {
char *p, *h;
h = gc(xasprintf("%s/.%s_history", gc(xhomedir()), prog));
linenoiseHistoryLoad(h);
p = linenoise(prompt);
if (p && *p) {
linenoiseHistoryLoad(h);
linenoiseHistoryAdd(p);
linenoiseHistorySave(h);
}
return p;
TEST(strclen, test) {
EXPECT_EQ(0, strclen(""));
EXPECT_EQ(5, strclen("hello"));
EXPECT_EQ(7, strclen("☺☻♥♦♣♠•"));
EXPECT_EQ(9, strclen("e☺e☻♥♦♣♠•"));
}

View file

@ -21,29 +21,35 @@
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(iswupper, test) {
EXPECT_TRUE(iswupper(L'𝐵'));
}
TEST(towupper, test) {
EXPECT_EQ(u'!', towupper(u'!'));
EXPECT_EQ(u'A', towupper(u'a'));
EXPECT_EQ(u'À', towupper(u'à'));
if (IsTiny()) return;
EXPECT_EQ(L'𝛥', towupper(L'𝛿'));
EXPECT_EQ(L'', towupper(L''));
EXPECT_EQ(u'', towupper(u''));
}
TEST(towlower, test) {
EXPECT_EQ(u'!', towlower(u'!'));
EXPECT_EQ(u'a', towlower(u'A'));
EXPECT_EQ(u'à', towlower(u'À'));
if (IsTiny()) return;
EXPECT_EQ(L'𝛿', towlower(L'𝛥'));
EXPECT_EQ(L'', towlower(L''));
EXPECT_EQ(u'', towlower(u''));
}
BENCH(towupper, bench) {
EZBENCH2("towupper ascii", donothing, EXPROPRIATE(towupper(VEIL("r", L'a'))));
EZBENCH2("towupper latin1", donothing,
EXPROPRIATE(towupper(VEIL("r", u'A'))));
if (IsTiny()) return;
EZBENCH2("towupper watinc", donothing,
EXPROPRIATE(towupper(VEIL("r", u''))));
EZBENCH2("towupper greek", donothing, EXPROPRIATE(towupper(VEIL("r", u'α'))));
EZBENCH2("towupper astral", donothing,
EXPROPRIATE(towupper(VEIL("r", L'𝛿'))));
}
@ -52,7 +58,9 @@ BENCH(towlower, bench) {
EZBENCH2("towlower ascii", donothing, EXPROPRIATE(towlower(VEIL("r", L'a'))));
EZBENCH2("towlower latin1", donothing,
EXPROPRIATE(towlower(VEIL("r", u'A'))));
if (IsTiny()) return;
EZBENCH2("towlower watinc", donothing,
EXPROPRIATE(towlower(VEIL("r", u''))));
EZBENCH2("towlower greek", donothing, EXPROPRIATE(towupper(VEIL("r", u'α'))));
EZBENCH2("towlower astral", donothing,
EXPROPRIATE(towlower(VEIL("r", L'𝛿'))));
}

View file

@ -1,7 +1,7 @@
DESCRIPTION
linenoise is a library for interactive pseudoteletypewriter command
sessions using ANSI Standard X3.64 control sequences.
Cosmopolitan Linenoise is a library for interactive pseudoteletypewriter
command sessions using ANSI Standard X3.64 control sequences.
ORIGIN
@ -10,3 +10,11 @@ ORIGIN
Author: antirez <antirez@gmail.com>
Date: Thu Mar 12 15:51:45 2020 +0100
Use unsigned int instead of uint like rest of code base.
DOCUMENTATION
See linenoise.c
LOCAL CHANGES
See linenoise.c

File diff suppressed because it is too large Load diff

View file

@ -19,18 +19,17 @@ void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
void linenoiseAddCompletion(linenoiseCompletions *, const char *);
char *linenoise(const char *) nodiscard;
char *linenoiseRaw(const char *, int, int) nodiscard;
char *ezlinenoise(const char *, const char *) nodiscard;
int linenoiseHistoryAdd(const char *);
int linenoiseHistorySetMaxLen(int);
int linenoiseHistorySave(const char *);
int linenoiseHistoryLoad(const char *);
void linenoiseFreeCompletions(linenoiseCompletions *);
void linenoiseHistoryFree(void);
void linenoiseClearScreen(void);
void linenoiseSetMultiLine(int);
void linenoiseClearScreen(int);
void linenoiseMaskModeEnable(void);
void linenoiseMaskModeDisable(void);
void linenoiseDisableRawMode(int);
void linenoiseDisableRawMode(void);
void linenoiseFree(void *);
COSMOPOLITAN_C_END_

View file

@ -25,7 +25,6 @@ THIRD_PARTY_LINENOISE_A_DIRECTDEPS = \
LIBC_STDIO \
LIBC_RUNTIME \
LIBC_SYSV_CALLS \
LIBC_X \
LIBC_STR \
LIBC_UNICODE \
LIBC_STUBS
@ -44,6 +43,7 @@ $(THIRD_PARTY_LINENOISE_A).pkg: \
$(THIRD_PARTY_LINENOISE_A_OBJS): \
OVERRIDE_CFLAGS += \
-fno-jump-tables \
-ffunction-sections \
-fdata-sections

View file

@ -1,21 +1,2 @@
"""A minimal subset of the locale module used at interpreter startup
(imported by the _io module), in order to reduce startup time.
Don't import directly from third-party code; use the `locale` module instead!
"""
import sys
import _locale
def getpreferredencoding(do_setlocale=True):
assert not do_setlocale
result = _locale.nl_langinfo(_locale.CODESET)
if not result and sys.platform in ('darwin', 'cosmo'):
# nl_langinfo can return an empty string
# when the setting has an invalid value.
# Default to UTF-8 in that case because
# UTF-8 is the default charset on OSX and
# returning nothing will crash the
# interpreter.
result = 'UTF-8'
return result
return 'UTF-8'

View file

@ -123,10 +123,7 @@ import enum
import sre_compile
import sre_parse
import functools
try:
import _locale
except ImportError:
_locale = None
import _locale
# public symbols
__all__ = [

View file

@ -1,2 +0,0 @@
#define LAUNCH "hello"
#include "third_party/python/Programs/launch.c"

View file

@ -1,2 +0,0 @@
#define LAUNCH "http.server"
#include "third_party/python/Programs/launch.c"

View file

@ -1,143 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/runtime/gc.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.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 "libc/x/x.h"
#include "libc/zip.h"
#include "third_party/linenoise/linenoise.h"
#include "third_party/python/Include/abstract.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/funcobject.h"
#include "third_party/python/Include/import.h"
#include "third_party/python/Include/listobject.h"
#include "third_party/python/Include/modsupport.h"
#include "third_party/python/Include/moduleobject.h"
#include "third_party/python/Include/object.h"
#include "third_party/python/Include/pydebug.h"
#include "third_party/python/Include/pyerrors.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/sysmodule.h"
#include "third_party/python/Include/unicodeobject.h"
#include "third_party/python/Include/yoink.h"
/* clang-format off */
#define _L(x) L##x
#define L(x) _L(x)
PYTHON_YOINK(LAUNCH);
PYTHON_YOINK("_bootlocale");
PYTHON_YOINK("_locale");
PYTHON_YOINK("encodings.aliases");
PYTHON_YOINK("encodings.latin_1");
PYTHON_YOINK("encodings.utf_8");
PYTHON_YOINK("launchpy");
const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
static int LaunchModule(wchar_t *modname)
{
PyObject *module, *runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("launchpy");
if (runpy == NULL) {
fprintf(stderr, "Could not import launchpy module\n");
PyErr_Print();
return -1;
}
runmodule = PyObject_GetAttrString(runpy, "run_module_as_main");
if (runmodule == NULL) {
fprintf(stderr, "Could not access launchpy.run_module_as_main\n");
PyErr_Print();
Py_DECREF(runpy);
return -1;
}
module = PyUnicode_FromWideChar(modname, wcslen(modname));
if (module == NULL) {
fprintf(stderr, "Could not convert module name to unicode\n");
PyErr_Print();
Py_DECREF(runpy);
Py_DECREF(runmodule);
return -1;
}
runargs = Py_BuildValue("(O)", module);
if (runargs == NULL) {
fprintf(stderr,
"Could not create arguments for runpy._run_module_as_main\n");
PyErr_Print();
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(module);
return -1;
}
result = PyObject_Call(runmodule, runargs, NULL);
if (result == NULL) {
PyErr_Print();
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(module);
Py_DECREF(runargs);
if (result == NULL) {
return -1;
}
Py_DECREF(result);
return 0;
}
int
main(int argc, char **argv)
{
int i, res;
char *oldloc;
wchar_t **argv_copy;
wchar_t **argv_copy2;
_PyMem_SetupAllocators("malloc");
argv_copy = gc(malloc(sizeof(wchar_t*) * (argc+1)));
argv_copy2 = gc(malloc(sizeof(wchar_t*) * (argc+1)));
oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "");
for (i = 0; i < argc; i++) {
argv_copy2[i] = argv_copy[i] = gc(utf8toutf32(argv[i], -1, 0));
}
argv_copy2[argc] = argv_copy[argc] = NULL;
setlocale(LC_ALL, oldloc);
PyMem_RawFree(oldloc);
_PyRandom_Init();
Py_FrozenFlag++;
Py_NoSiteFlag++;
/* Py_VerboseFlag++; */
Py_NoUserSiteDirectory++;
Py_IgnoreEnvironmentFlag++;
Py_DontWriteBytecodeFlag++;
Py_Initialize();
Py_LimitedPath();
PySys_SetArgvEx(argc, argv_copy, 0);
res = LaunchModule(L(LAUNCH)) != 0;
_PyMem_SetupAllocators("malloc");
return res;
}

View file

@ -153,7 +153,7 @@ TerminalReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
PyOS_sighandler_t saint;
saint = PyOS_setsig(SIGINT, OnKeyboardInterrupt);
if (setjmp(jbuf)) {
linenoiseDisableRawMode(STDIN_FILENO);
linenoiseDisableRawMode();
PyOS_setsig(SIGINT, saint);
return NULL;
}

103
third_party/python/launch.c vendored Normal file
View file

@ -0,0 +1,103 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Python 3
https://docs.python.org/3/license.html │
*/
#include "libc/x/x.h"
#include "third_party/python/Include/abstract.h"
#include "third_party/python/Include/import.h"
#include "third_party/python/Include/modsupport.h"
#include "third_party/python/Include/object.h"
#include "third_party/python/Include/pydebug.h"
#include "third_party/python/Include/pylifecycle.h"
#include "third_party/python/Include/pymem.h"
#include "third_party/python/Include/pythonrun.h"
#include "third_party/python/Include/sysmodule.h"
#include "third_party/python/Include/unicodeobject.h"
#include "third_party/python/Include/yoink.h"
/* clang-format off */
STATIC_YOINK("zip_uri_support");
PYTHON_YOINK("_bootlocale");
PYTHON_YOINK("_locale");
PYTHON_YOINK("encodings.aliases");
PYTHON_YOINK("encodings.latin_1");
PYTHON_YOINK("encodings.utf_8");
PYTHON_YOINK("launchpy");
extern char kLaunchPythonModuleName[]; /* generated by pyobj.com */
const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
int
LaunchPythonModule(const char *name)
{
PyObject *mod, *runpy, *runmodule, *runargs, *result;
if (!(runpy = PyImport_ImportModule("launchpy"))) {
PyErr_Print();
return 123;
}
if (!(runmodule = PyObject_GetAttrString(runpy, "run_module_as_main"))) {
PyErr_Print();
Py_DECREF(runpy);
return 122;
}
if (!(mod = PyUnicode_DecodeUTF8Stateful(name, strlen(name), 0, 0))) {
PyErr_Print();
Py_DECREF(runpy);
Py_DECREF(runmodule);
return 121;
}
if (!(runargs = Py_BuildValue("(O)", mod))) {
PyErr_Print();
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(mod);
return 119;
}
if (!(result = PyObject_Call(runmodule, runargs, NULL))) {
PyErr_Print();
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(mod);
Py_DECREF(runargs);
if (!result) return 118;
Py_DECREF(result);
return 0;
}
int
main(int argc, char *argv[])
{
size_t n;
int i, sts;
wchar_t *w;
PyObject *a, *s;
Py_FrozenFlag++;
Py_NoSiteFlag++;
/* Py_VerboseFlag++; */
Py_NoUserSiteDirectory++;
Py_IgnoreEnvironmentFlag++;
Py_DontWriteBytecodeFlag++;
#if defined(Py_DEBUG) || defined(USE_TRACEMALLOC)
_PyMem_SetupAllocators(Py_GETENV("PYTHONMALLOC"));
#else
_PyMem_SetupAllocators(0);
#endif
_PyRandom_Init();
Py_Initialize();
Py_LimitedPath();
if (!(a = PyList_New(argc))) return 127;
for (i = 0; i < argc; ++i) {
if (!(w = utf8toutf32(argv[i], -1, &n))) return 126;
if (!(s = PyUnicode_FromWideChar(w, n))) return 125;
PyList_SetItem(a, i, s);
free(w);
}
if (PySys_SetObject("argv", a)) return 124;
sts = LaunchPythonModule(kLaunchPythonModuleName);
if (Py_FinalizeEx() < 0) sts = 120;
return sts;
}

View file

@ -985,8 +985,10 @@
/* Define to printf format modifier for Py_ssize_t */
#define PY_FORMAT_SIZE_T "z"
/* Define if you want to build an interpreter with many run-time checks. */
/* #define Py_DEBUG 1 */
#ifdef MODE_DBG
#define Py_DEBUG 1
#define USE_TRACEMALLOC 1
#endif
/* Defined if Python is built as a shared library. */
/* #undef Py_ENABLE_SHARED */

View file

@ -64,12 +64,13 @@ OVERVIEW\n\
FLAGS\n\
\n\
-o PATH output elf object file\n\
-P STR prefix fake directory in zip\n\
-P STR prefix fake zip directory (default .python)\n\
-C INT strip directory components from src in zip\n\
-O0 don't optimize [default]\n\
-O1 remove debug statements\n\
-O2 remove debug statements and docstrings\n\
-B binary only (don't include .py file)\n\
-m insert executable launch.c yoink\n\
-0 zip uncompressed\n\
-n do nothing\n\
-h help\n\
@ -212,6 +213,7 @@ static struct stat st;
static PyObject *code;
static PyObject *marsh;
static bool nocompress;
static bool insertlauncher;
static uint64_t image_base;
static int strip_components;
static struct ElfWriter *elf;
@ -224,7 +226,8 @@ GetOpts(int argc, char *argv[])
{
int opt;
image_base = IMAGE_BASE_VIRTUAL;
while ((opt = getopt(argc, argv, "hn0Bb:O:o:C:P:")) != -1) {
path_prefix = ".python";
while ((opt = getopt(argc, argv, "hnm0Bb:O:o:C:P:")) != -1) {
switch (opt) {
case 'B':
binonly = true;
@ -232,6 +235,9 @@ GetOpts(int argc, char *argv[])
case '0':
nocompress = true;
break;
case 'm':
insertlauncher = true;
break;
case 'o':
outpath = optarg;
break;
@ -289,7 +295,7 @@ GetZipFile(void)
const char *zipfile;
zipfile = pyfile;
zipfile = StripComponents(zipfile, strip_components);
if (path_prefix) {
if (*path_prefix) {
zipfile = gc(xjoinpaths(path_prefix, zipfile));
}
return strdup(zipfile);
@ -418,9 +424,10 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
PyObject *co_code, *co_names, *co_consts, *name, *cnst, *iter, *item;
mod = 0;
istry = rel = 0;
co_code = PyObject_GetAttrString(code, "co_code");
co_names = PyObject_GetAttrString(code, "co_names");
co_consts = PyObject_GetAttrString(code, "co_consts");
assert(PyCode_Check(code));
co_code = ((PyCodeObject *)code)->co_code;
co_names = ((PyCodeObject *)code)->co_names;
co_consts = ((PyCodeObject *)code)->co_consts;
n = PyBytes_GET_SIZE(co_code);
p = PyBytes_AS_STRING(co_code);
for (a = i = 0; i + 2 <= n; i += 2) {
@ -490,8 +497,6 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
}
a = 0;
}
Py_DECREF(co_names);
Py_DECREF(co_code);
free(mod);
iter = PyObject_GetIter(co_consts);
while ((item = PyIter_Next(iter))) {
@ -501,7 +506,6 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
Py_DECREF(item);
}
Py_DECREF(iter);
Py_DECREF(co_consts);
}
static void
@ -521,6 +525,7 @@ AnalyzeModule(const char *modname)
static int
Objectify(void)
{
size_t n;
bool ispkg;
char header[12];
size_t pysize, pycsize, marsize;
@ -568,14 +573,28 @@ Objectify(void)
elfwriter_startsection(elf, ".yoink", SHT_PROGBITS,
SHF_ALLOC | SHF_EXECINSTR);
AnalyzeModule(modname);
if (path_prefix && !IsDot()) {
if (*path_prefix && !IsDot()) {
elfwriter_yoink(elf, gc(xstrcat(path_prefix, "/")), STB_GLOBAL);
}
if (strchr(modname, '.')) {
Yoink(gc(GetParent()), STB_GLOBAL);
}
elfwriter_yoink(elf, "__zip_start", STB_GLOBAL);
if (insertlauncher) {
elfwriter_yoink(elf, "LaunchPythonModule", STB_GLOBAL);
}
elfwriter_finishsection(elf);
if (insertlauncher) {
n = strlen(modname) + 1;
elfwriter_align(elf, 1, 0);
elfwriter_startsection(elf, ".rodata.str1.1", SHT_PROGBITS,
SHF_ALLOC | SHF_MERGE | SHF_STRINGS);
memcpy(elfwriter_reserve(elf, n), modname, n);
elfwriter_appendsym(elf, "kLaunchPythonModuleName",
ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT),
STV_DEFAULT, 0, n);
elfwriter_commit(elf, n);
elfwriter_finishsection(elf);
}
elfwriter_close(elf);
freeinterner(yoinked);
return 0;

View file

@ -27,8 +27,7 @@ THIRD_PARTY_PYTHON_COMS = \
o/$(MODE)/third_party/python/pyobj.com \
o/$(MODE)/third_party/python/pycomp.com \
o/$(MODE)/third_party/python/repl.com \
o/$(MODE)/third_party/python/hello.com \
o/$(MODE)/third_party/python/httpserver.com \
o/$(MODE)/third_party/python/Lib/hello.com \
o/$(MODE)/third_party/python/pythontester.com
THIRD_PARTY_PYTHON_CHECKS = \
@ -408,6 +407,7 @@ THIRD_PARTY_PYTHON_STAGE1_A_SRCS = \
third_party/python/Python/traceback.c
THIRD_PARTY_PYTHON_STAGE2_A_SRCS = \
third_party/python/launch.c \
third_party/python/Modules/_hashmbedtls.c \
third_party/python/Objects/fromfd.c \
third_party/python/Modules/_bisectmodule.c \
@ -1874,7 +1874,6 @@ THIRD_PARTY_PYTHON_STAGE2_A_DEPS = \
o/$(MODE)/third_party/python/pyobj.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
o/$(MODE)/third_party/python/pyobj.o \
$(CRT) \
$(APE)
@ -1882,7 +1881,6 @@ o/$(MODE)/third_party/python/pyobj.com.dbg: \
o/$(MODE)/third_party/python/pycomp.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
o/$(MODE)/third_party/python/pycomp.o \
$(CRT) \
$(APE)
@ -1890,7 +1888,6 @@ o/$(MODE)/third_party/python/pycomp.com.dbg: \
o/$(MODE)/third_party/python/freeze.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
o/$(MODE)/third_party/python/Programs/freeze.o \
$(CRT) \
$(APE)
@ -1898,9 +1895,7 @@ o/$(MODE)/third_party/python/freeze.com.dbg: \
o/$(MODE)/third_party/python/python.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
$(THIRD_PARTY_PYTHON_STAGE2) \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
o/$(MODE)/third_party/python/Programs/python.o \
$(CRT) \
$(APE)
@ -1908,39 +1903,23 @@ o/$(MODE)/third_party/python/python.com.dbg: \
o/$(MODE)/third_party/python/repl.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
$(THIRD_PARTY_PYTHON_STAGE2) \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
o/$(MODE)/third_party/python/Programs/repl.o \
$(CRT) \
$(APE)
@$(APELINK)
o/$(MODE)/third_party/python/httpserver.com.dbg: \
o/$(MODE)/third_party/python/Lib/hello.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
$(THIRD_PARTY_PYTHON_STAGE2) \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
o/$(MODE)/third_party/python/Programs/httpserver.o \
$(CRT) \
$(APE)
@$(APELINK)
o/$(MODE)/third_party/python/hello.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
$(THIRD_PARTY_PYTHON_STAGE2) \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
o/$(MODE)/third_party/python/Programs/hello.o \
o/$(MODE)/third_party/python/Lib/hello.o \
$(CRT) \
$(APE)
@$(APELINK)
o/$(MODE)/third_party/python/pythontester.com.dbg: \
$(THIRD_PARTY_PYTHON_STAGE1) \
$(THIRD_PARTY_PYTHON_STAGE1_A).pkg \
$(THIRD_PARTY_PYTHON_STAGE2) \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
o/$(MODE)/third_party/python/Programs/pythontester.o \
$(CRT) \
$(APE)
@ -2025,6 +2004,7 @@ o/$(MODE)/third_party/python/Modules/faulthandler.o: \
$(THIRD_PARTY_PYTHON_STDLIB_PYS_OBJS): PYFLAGS += -P.python -C3
$(THIRD_PARTY_PYTHON_STDLIB_DATA_OBJS): ZIPOBJ_FLAGS += -P.python -C3
o/$(MODE)/third_party/python/Lib/hello.o: PYFLAGS += -m
o/$(MODE)/third_party/python/Python/ceval.o: QUOTA = -M512m
o/$(MODE)/third_party/python/Objects/unicodeobject.o: QUOTA += -C16
@ -2050,11 +2030,8 @@ THIRD_PARTY_PYTHON_SRCS = \
third_party/python/pyobj.c \
third_party/python/pycomp.c \
third_party/python/Programs/repl.c \
third_party/python/Programs/hello.c \
third_party/python/Programs/launch.c \
third_party/python/Programs/freeze.c \
third_party/python/Programs/python.c \
third_party/python/Programs/httpserver.c \
third_party/python/Programs/pythontester.c
#$(THIRD_PARTY_PYTHON_OBJS): \

View file

@ -146,7 +146,7 @@ typedef unsigned char u8;
#define shell_add_history(X) linenoiseHistoryAdd(X)
#define shell_read_history(X) linenoiseHistoryLoad(X)
#define shell_write_history(X) linenoiseHistorySave(X)
#define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
#define shell_stifle_history(X)
#define shell_readline(X) linenoise(X)
#else