mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
Add chibicc
This program popped up on Hacker News recently. It's the only modern compiler I've ever seen that doesn't have dependencies and is easily modified. So I added all of the missing GNU extensions I like to use which means it might be possible soon to build on non-Linux and have third party not vendor gcc binaries.
This commit is contained in:
parent
e44a0cf6f8
commit
8da931a7f6
298 changed files with 19493 additions and 11950 deletions
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef endswith
|
||||
#undef strlen
|
||||
#undef strnlen
|
||||
|
||||
#define char char16_t
|
||||
#define endswith endswith16
|
||||
#define strlen strlen16
|
||||
#define strnlen strnlen16
|
||||
|
||||
#include "libc/str/endswith.c"
|
||||
/**
|
||||
* Returns true if s has suffix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool endswith16(const char16_t *s, const char16_t *suffix) {
|
||||
size_t n, m;
|
||||
n = strlen16(s);
|
||||
m = strlen16(suffix);
|
||||
if (m > n) return false;
|
||||
return memcmp(s + n - m, suffix, m * sizeof(char16_t)) == 0;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef startswith
|
||||
#undef strlen
|
||||
#undef strncmp
|
||||
|
||||
#define char char16_t
|
||||
#define startswith startswith16
|
||||
#define strlen strlen16
|
||||
#define strncmp strncmp16
|
||||
|
||||
#include "libc/str/startswith.c"
|
||||
/**
|
||||
* Returns true if s has prefix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool startswith16(const char16_t *s, const char16_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (*s++ != *prefix++) return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,8 +238,8 @@ char *strsignal(int) returnsnonnull libcesque;
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
||||
#define strncpy(DEST, SRC, N) _strncpy(DEST, SRC, N) /* pacify bad warning */
|
||||
char *__strncpy(char *, const char *, size_t) memcpyesque;
|
||||
#define strncpy(DEST, SRC, N) __strncpy(DEST, SRC, N) /* pacify bad warning */
|
||||
|
||||
#define explicit_bzero(STR, BYTES) \
|
||||
do { \
|
||||
|
@ -318,7 +318,7 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
|||
size_t SiZe = (SIZE); \
|
||||
size_t Rcx; \
|
||||
asm("rep movsb" \
|
||||
: "=D"(Rdi), "=S"(Rsi), "=D"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \
|
||||
: "=D"(Rdi), "=S"(Rsi), "=c"(Rcx), "=m"(*(char(*)[SiZe])(Dest)) \
|
||||
: "0"(Dest), "1"(Src), "2"(SiZe), "m"(*(const char(*)[SiZe])(Src)) \
|
||||
: "cc"); \
|
||||
Rdi; \
|
||||
|
@ -351,9 +351,6 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
|
|||
|
||||
#endif /* hosted/sse2/unbloat */
|
||||
|
||||
size_t _strlen(const char *s) asm("strlen") strlenesque;
|
||||
void *_memchr(const void *, int, size_t) asm("memchr") strlenesque;
|
||||
|
||||
#endif /* __GNUC__ && !__STRICT_ANSI__ */
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
24
libc/str/strncpy.thunk.S
Normal file
24
libc/str/strncpy.thunk.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 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/macros.h"
|
||||
|
||||
__strncpy:
|
||||
jmp strncpy
|
||||
.endfn __strncpy,globl
|
|
@ -24,7 +24,7 @@
|
|||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
char *(strpbrk)(const char *s, const char *accept) {
|
||||
char *strpbrk(const char *s, const char *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
|
|
|
@ -20,10 +20,22 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strpbrk
|
||||
#define char char16_t
|
||||
#define HasCharacter HasCharacter16
|
||||
#define strpbrk strpbrk16
|
||||
#define strchr(x, y) strchr16(x, y)
|
||||
|
||||
#include "libc/str/strpbrk.c"
|
||||
/**
|
||||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
char16_t *strpbrk16(const char16_t *s, const char16_t *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
return strchr16(s, accept[0]);
|
||||
} else {
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (HasCharacter16(s[i], accept)) {
|
||||
return (/*unconst*/ char16_t *)&s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t(strspn)(const char *s, const char *accept) {
|
||||
size_t strspn(const char *s, const char *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacter(s[i], accept)) {
|
||||
|
|
|
@ -20,9 +20,19 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strspn
|
||||
#define char char16_t
|
||||
#define HasCharacter HasCharacter16
|
||||
#define strspn strspn16
|
||||
|
||||
#include "libc/str/strspn.c"
|
||||
/**
|
||||
* Returns prefix length, consisting of chars in accept.
|
||||
*
|
||||
* @param accept is nul-terminated character set
|
||||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t strspn16(const char16_t *s, const char16_t *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacter16(s[i], accept)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -32,22 +31,26 @@
|
|||
* @asyncsignalsafe
|
||||
* @see memmem()
|
||||
*/
|
||||
char *(strstr)(const char *haystack, const char *needle) {
|
||||
char *strstr(const char *haystack, const char *needle) {
|
||||
size_t i;
|
||||
if (needle[0]) {
|
||||
if (needle[1]) {
|
||||
if (!((intptr_t)needle & 0xf) && X86_HAVE(SSE4_2)) {
|
||||
return strstr$sse42(haystack, needle);
|
||||
} else {
|
||||
size_t needlelen;
|
||||
alignas(16) char needle2[64];
|
||||
needlelen = strlen(needle);
|
||||
if (needlelen < 64 && X86_HAVE(SSE4_2)) {
|
||||
memcpy(needle2, needle, (needlelen + 1) * sizeof(char));
|
||||
return strstr$sse42(haystack, needle2);
|
||||
} else {
|
||||
return tinystrstr(haystack, needle);
|
||||
for (;;) {
|
||||
#if 0 /* todo: fix me */
|
||||
if (!((uintptr_t)haystack & 15) && X86_HAVE(SSE4_2) &&
|
||||
(((uintptr_t)needle + strlen(needle)) & 0xfff) <= 0xff0) {
|
||||
return strstr$sse42(haystack, needle);
|
||||
}
|
||||
#endif
|
||||
for (i = 0;;) {
|
||||
if (!needle[i]) return haystack;
|
||||
if (!haystack[i]) break;
|
||||
if (needle[i] != haystack[i]) break;
|
||||
++i;
|
||||
}
|
||||
if (!*haystack++) break;
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
return strchr(haystack, needle[0]);
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef endswith
|
||||
#undef strlen
|
||||
#undef strnlen
|
||||
|
||||
#define char wchar_t
|
||||
#define endswith wcsendswith
|
||||
#define strlen wcslen
|
||||
#define strnlen wcsnlen
|
||||
|
||||
#include "libc/str/endswith.c"
|
||||
/**
|
||||
* Returns true if s has suffix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool wcsendswith(const wchar_t *s, const wchar_t *suffix) {
|
||||
size_t n, m;
|
||||
n = wcslen(s);
|
||||
m = wcslen(suffix);
|
||||
if (m > n) return false;
|
||||
return memcmp(s + n - m, suffix, m * sizeof(wchar_t)) == 0;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,22 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strpbrk
|
||||
#define char wchar_t
|
||||
#define HasCharacter HasCharacterWide
|
||||
#define strpbrk wcspbrk
|
||||
#define strchr(x, y) wcschr(x, y)
|
||||
|
||||
#include "libc/str/strpbrk.c"
|
||||
/**
|
||||
* Returns pointer to first byte matching any in accept, or NULL.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
wchar_t *wcspbrk(const wchar_t *s, const wchar_t *accept) {
|
||||
size_t i;
|
||||
if (accept[0]) {
|
||||
if (!accept[1]) {
|
||||
return wcschr(s, accept[0]);
|
||||
} else {
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (HasCharacterWide(s[i], accept)) {
|
||||
return (/*unconst*/ wchar_t *)&s[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,19 @@
|
|||
#include "libc/nexgen32e/hascharacter.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef strspn
|
||||
#define char wchar_t
|
||||
#define HasCharacter HasCharacterWide
|
||||
#define strspn wcsspn
|
||||
|
||||
#include "libc/str/strspn.c"
|
||||
/**
|
||||
* Returns prefix length, consisting of chars in accept.
|
||||
*
|
||||
* @param accept is nul-terminated character set
|
||||
* @see strcspn(), strtok_r()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t wcsspn(const wchar_t *s, const wchar_t *accept) {
|
||||
size_t i;
|
||||
for (i = 0; s[i]; ++i) {
|
||||
if (!HasCharacterWide(s[i], accept)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#undef char
|
||||
#undef startswith
|
||||
#undef strlen
|
||||
#undef strncmp
|
||||
|
||||
#define char wchar_t
|
||||
#define startswith wcsstartswith
|
||||
#define strlen wcslen
|
||||
#define strncmp wcsncmp
|
||||
|
||||
#include "libc/str/startswith.c"
|
||||
/**
|
||||
* Returns true if s has prefix.
|
||||
*
|
||||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool wcsstartswith(const wchar_t *s, const wchar_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
if (*s++ != *prefix++) return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue