Make terminal ui binaries work well everywhere

Here's some screenshots of an emulator tui program that was compiled on
Linux, then scp'd it to Windows, Mac, and FreeBSD.

https://justine.storage.googleapis.com/blinkenlights-cmdexe.png
https://justine.storage.googleapis.com/blinkenlights-imac.png
https://justine.storage.googleapis.com/blinkenlights-freebsd.png
https://justine.storage.googleapis.com/blinkenlights-lisp.png

How is this even possible that we have a nontrivial ui binary that just
works on Mac, Windows, Linux, and BSD? Surely a first ever achievement.

Fixed many bugs. Bootstrapped John McCarthy's metacircular evaluator on
bare metal in half the size of Altair BASIC (about 2.5kb) and ran it in
emulator for fun and profit.
This commit is contained in:
Justine Tunney 2020-10-10 21:18:53 -07:00
parent 680daf1210
commit 9e3e985ae5
276 changed files with 7026 additions and 3790 deletions

33
libc/str/decodentsutf16.c Normal file
View file

@ -0,0 +1,33 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
#include "libc/str/utf16.h"
wint_t DecodeNtsUtf16(const char16_t **s) {
wint_t x, y;
if (!IsUcs2((x = *(*s)++))) {
if ((y = *(*s)++)) {
x = MergeUtf16(x, y);
} else {
x = 0;
}
}
return x;
}

32
libc/str/hextoint.c Normal file
View file

@ -0,0 +1,32 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int hextoint(int c) {
if ('0' <= c && c <= '9') {
return c - '0';
} else if ('a' <= c && c <= 'f') {
return c - 'a' + 10;
} else if ('A' <= c && c <= 'F') {
return c - 'A' + 10;
} else {
return 0;
}
}

25
libc/str/isalnum.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isalnum(int c) {
return ('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') ||
('a' <= c && c <= 'z');
}

24
libc/str/isalpha.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isalpha(int c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
}

23
libc/str/isascii.c Normal file
View file

@ -0,0 +1,23 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
int isascii(int c) {
return 0x00 <= c && c <= 0x7F;
}

24
libc/str/isblank.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isblank(int c) {
return c == ' ' || c == '\t';
}

24
libc/str/iscntrl.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iscntrl(int c) {
return (0x00 <= c && c <= 0x1F) || c == 0x7F;
}

24
libc/str/isdigit.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isdigit(int c) {
return '0' <= c && c <= '9';
}

24
libc/str/isgraph.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isgraph(int c) {
return 0x21 <= c && c <= 0x7E;
}

24
libc/str/islower.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int islower(int c) {
return 'a' <= c && c <= 'z';
}

24
libc/str/isprint.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isprint(int c) {
return 0x20 <= c && c <= 0x7E;
}

25
libc/str/ispunct.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int ispunct(int c) {
return (0x21 <= c && c <= 0x7E) && !('0' <= c && c <= '9') &&
!('A' <= c && c <= 'Z') && !('a' <= c && c <= 'z');
}

25
libc/str/isspace.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isspace(int c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' ||
c == '\v';
}

24
libc/str/isupper.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isupper(int c) {
return 'A' <= c && c <= 'Z';
}

24
libc/str/iswalnum.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswalnum(wint_t wc) {
return isalnum(wc);
}

24
libc/str/iswalpha.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswalpha(wint_t wc) {
return isalpha(wc);
}

24
libc/str/iswblank.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswblank(wint_t wc) {
return isblank(wc);
}

24
libc/str/iswcntrl.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswcntrl(wint_t wc) {
return (0x00 <= wc && wc <= 0x1F) || (0x7F <= wc && wc <= 0x9F);
}

View file

@ -20,33 +20,71 @@
#include "libc/macros.h"
#include "libc/str/str.h"
static const struct WcTypes {
char name[8];
wctype_t type;
} wctypes[] = {{"alnum", 0x006}, {"alpha", 0x002}, {"blank", 0x080},
{"cntrl", 0x100}, {"digit", 0x004}, {"graph", 0x200},
{"lower", 0x020}, {"print", 0x010}, {"punct", 0x300},
{"space", 0x001}, {"upper", 0x040}, {"xdigit", 0x008}};
#define ALNUM 1
#define ALPHA 2
#define BLANK 3
#define CNTRL 4
#define DIGIT 5
#define GRAPH 6
#define LOWER 7
#define PRINT 8
#define PUNCT 9
#define SPACE 10
#define UPPER 11
#define XDIGIT 12
wctype_t wctype(const char *s) {
char name[8];
strncpy(name, s, sizeof(name));
for (unsigned i = 0; i < ARRAYLEN(wctypes); ++i) {
if (memcmp(name, wctypes[i].name, sizeof(name)) == 0) {
return wctypes[i].type;
static const struct {
char name[7];
char type;
} kWcTypes[] = {
{"alnum", ALNUM}, {"alpha", ALPHA}, {"blank", BLANK}, {"cntrl", CNTRL},
{"digit", DIGIT}, {"graph", GRAPH}, {"lower", LOWER}, {"print", PRINT},
{"punct", PUNCT}, {"space", SPACE}, {"upper", UPPER}, {"xdigit", XDIGIT},
};
static int CompareStrings(const char *l, const char *r) {
size_t i = 0;
while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 0xff) - (r[i] & 0xff);
}
wctype_t wctype(const char *name) {
unsigned i;
for (i = 0; i < ARRAYLEN(kWcTypes); ++i) {
if (CompareStrings(name, kWcTypes[i].name) == 0) {
return kWcTypes[i].type;
}
}
return 0;
}
int iswctype(wint_t c, wctype_t type) {
if (c < 128) {
if (!(type & ~0xff)) {
return kCtype[(unsigned char)type];
}
if (type == 0x100) return iscntrl((unsigned char)c);
if (type == 0x200) return isgraph((unsigned char)c);
if (type == 0x300) return ispunct((unsigned char)c);
int iswctype(wint_t wc, wctype_t type) {
switch (type) {
case ALNUM:
return iswalnum(wc);
case ALPHA:
return iswalpha(wc);
case BLANK:
return iswblank(wc);
case CNTRL:
return iswcntrl(wc);
case DIGIT:
return iswdigit(wc);
case GRAPH:
return iswgraph(wc);
case LOWER:
return iswlower(wc);
case PRINT:
return iswprint(wc);
case PUNCT:
return iswpunct(wc);
case SPACE:
return iswspace(wc);
case UPPER:
return iswupper(wc);
case XDIGIT:
return iswxdigit(wc);
default:
return 0;
}
return 0;
}

24
libc/str/iswdigit.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswdigit(wint_t wc) {
return isdigit(wc);
}

24
libc/str/iswgraph.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswgraph(wint_t wc) {
return isgraph(wc);
}

24
libc/str/iswlower.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswlower(wint_t wc) {
return islower(wc);
}

24
libc/str/iswprint.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswprint(wint_t wc) {
return !iswcntrl(wc);
}

24
libc/str/iswpunct.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswpunct(wint_t wc) {
return ispunct(wc);
}

24
libc/str/iswspace.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswspace(wint_t wc) {
return isspace(wc);
}

24
libc/str/iswupper.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswupper(wint_t wc) {
return isupper(wc);
}

24
libc/str/iswxdigit.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int iswxdigit(wint_t wc) {
return isxdigit(wc);
}

25
libc/str/isxdigit.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int isxdigit(int c) {
return ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') ||
('a' <= c && c <= 'f');
}

View file

@ -8,7 +8,6 @@ COSMOPOLITAN_C_START_
fourth age telecommunications */
extern const uint8_t gperf_downcase[256];
extern const uint8_t kCtype[256];
extern const uint8_t kToLower[256];
extern const uint8_t kToUpper[256];
extern const uint16_t kToLower16[256];
@ -64,6 +63,7 @@ void *isnotplaintext(const void *, size_t) nothrow nocallback nosideeffect;
#define INVALID_CODEPOINT 0xfffd
wint_t DecodeNtsUtf16(const char16_t **);
unsigned getutf16(const char16_t *, wint_t *);
int pututf16(char16_t *, size_t, wint_t, bool);
int iswalnum(wint_t);
@ -78,8 +78,8 @@ int iswupper(wint_t);
int iswxdigit(wint_t);
int iswpunct(wint_t);
int iswprint(wint_t);
unsigned towlower(unsigned);
unsigned towupper(unsigned);
wint_t towlower(wint_t);
wint_t towupper(wint_t);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § strings

View file

@ -5,7 +5,7 @@
#define ThomPikeCont(x) (((x)&0b11000000) == 0b10000000)
#define ThomPikeByte(x) ((x) & (((1 << ThomPikeMsb(x)) - 1) | 3))
#define ThomPikeLen(x) (7 - ThomPikeMsb(x))
#define ThomPikeMsb(x) ((x) < 252 ? bsr(~(x)&0xff) : 1)
#define ThomPikeMsb(x) (((x)&0xff) < 252 ? bsr(~(x)&0xff) : 1)
#define ThomPikeMerge(x, y) ((x) << 6 | (y)&0b00111111)
#endif /* COSMOPOLITAN_LIBC_STR_THOMPIKE_H_ */

24
libc/str/tolower.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int tolower(int c) {
return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c;
}

24
libc/str/toupper.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
int toupper(int c) {
return 'a' <= c && c <= 'z' ? c - ('a' - 'A') : c;
}

24
libc/str/towlower.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
wint_t towlower(wint_t wc) {
return tolower(wc);
}

24
libc/str/towupper.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
wint_t towupper(wint_t wc) {
return toupper(wc);
}

View file

@ -24,19 +24,15 @@
/
/ @param edi is int to encode
/ @return rax is word-encoded byte buffer
/ @clob edi,rax,flags
/ @note invented on a napkin in a new jersey diner
tpenc: .leafprologue
.profilable
push %rcx
push %rdx
mov %edi,%edi
xor %eax,%eax
cmp $127,%edi
jbe 3f
bsr %edi,%ecx
ezlea kTpenc,dx
mov -7*(1+1)(%rdx,%rcx,2),%ecx
mov kTpenc-7*(1+1)(,%rcx,2),%ecx
1: mov %edi,%edx
shr $6,%edi
and $0b00111111,%dl
@ -47,12 +43,11 @@ tpenc: .leafprologue
jnz 1b
2: or %ch,%al
3: or %rdi,%rax
pop %rdx
pop %rcx
.leafepilogue
.endfn tpenc,globl
.rodata
.align 4
kTpenc: .rept 4 # MSB10 (0x7FF)
.byte 1,0b11000000 # len,mark
.endr
@ -68,4 +63,5 @@ kTpenc: .rept 4 # MSB≤10 (0x7FF)
.rept 6 # MSB31 (0xffffffff)
.byte 5,0b11111100 # len,mark
.endr
.zero 2
.endobj kTpenc

View file

@ -16,7 +16,7 @@ uint64_t tpenc(int32_t) pureconst;
asm("call\ttpenc" \
: "=a"(Buf), "+D"(Code) \
: /* inputs */ \
: "cc"); \
: "rcx", "rdx", "cc"); \
} \
Buf; \
})

View file

@ -19,7 +19,8 @@
*/
#include "libc/conv/conv.h"
#include "libc/str/str.h"
#include "libc/str/tpencode.h"
#include "libc/str/tpenc.h"
#include "libc/str/utf16.h"
/**
* Transcodes UTF-16 to UTF-8.
@ -30,19 +31,25 @@
* @return number of bytes written excluding NUL
*/
size_t tprecode16to8(char *dst, size_t dstsize, const char16_t *src) {
size_t i = 0;
size_t i;
uint64_t w;
wint_t x, y;
i = 0;
if (dstsize) {
for (;;) {
wint_t wc;
src += abs(getutf16(src, &wc));
if (!wc || dstsize == 1) {
dst[i] = '\0';
break;
if (!(x = *src++)) break;
if (IsUtf16Cont(x)) continue;
if (!IsUcs2(x)) {
if (!(y = *src++)) break;
x = MergeUtf16(x, y);
}
w = tpenc(x);
while (w && i + 1 < dstsize) {
dst[i++] = w & 0xFF;
w >>= 8;
}
size_t got = abs(tpencode(&dst[i], dstsize, wc, false));
dstsize -= got;
i += got;
}
dst[i] = 0;
}
return i;
}

View file

@ -17,9 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/conv/conv.h"
#include "libc/str/str.h"
#include "libc/str/tpdecode.h"
#include "libc/str/thompike.h"
#include "libc/str/utf16.h"
/**
* Transcodes UTF-8 to UTF-16.
@ -30,19 +30,31 @@
* @return number of shorts written excluding NUL
*/
size_t tprecode8to16(char16_t *dst, size_t dstsize, const char *src) {
size_t i = 0;
size_t i;
unsigned n;
uint64_t w;
wint_t x, y;
i = 0;
if (dstsize) {
for (;;) {
wint_t wc;
src += abs(tpdecode(src, &wc));
if (!wc || dstsize == 1) {
dst[i] = u'\0';
break;
if (!(x = *src++ & 0xff)) break;
if (ThomPikeCont(x)) continue;
if (!isascii(x)) {
n = ThomPikeLen(x);
x = ThomPikeByte(x);
while (--n) {
if (!(y = *src++ & 0xff)) goto stop;
x = ThomPikeMerge(x, y);
}
}
w = EncodeUtf16(x);
while (w && i + 1 < dstsize) {
dst[i++] = w & 0xFFFF;
w >>= 16;
}
size_t got = abs(pututf16(&dst[i], dstsize, wc, false));
dstsize -= got;
i += got;
}
stop:
dst[i] = 0;
}
return i;
}

View file

@ -8,5 +8,13 @@
#define IsUcs2(wc) (((wc)&UTF16_MASK) != UTF16_MOAR)
#define IsUtf16Cont(wc) (((wc)&UTF16_MASK) == UTF16_CONT)
#define MergeUtf16(lo, hi) ((((lo)-0xD800) << 10) + ((hi)-0xDC00) + 0x10000)
#define EncodeUtf16(wc) \
(likely((0x0000 <= (wc) && (wc) <= 0xFFFF) || \
(0xE000 <= (wc) && (wc) <= 0xFFFF)) \
? (wc) \
: 0x10000 <= (wc) && (wc) <= 0x10FFFF \
? (((((wc)-0x10000) >> 10) + 0xD800) | \
((((wc)-0x10000) & 1023) + 0xDC00) << 16) \
: 0xFFFD)
#endif /* COSMOPOLITAN_LIBC_STR_UTF16_H_ */