mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Make Cosmopolitan ANSI C89 compatible
You can now use cosmopolitan.h with an ANSI C89 compiler like MSVC. The Cosmopolitan codebase itself won't support being compiled that way. But you can build objects that link against Cosmopolitan using any compiler and you can furthermore use tools like IntelliSense that can't even GNU See also #40
This commit is contained in:
parent
46085797b6
commit
a8d7195777
34 changed files with 262 additions and 9561 deletions
10
Makefile
10
Makefile
|
@ -135,7 +135,6 @@ include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
|||
include libc/dns/dns.mk # │ You can communicate with the network
|
||||
include libc/crypto/crypto.mk # │
|
||||
include net/http/http.mk #─┘
|
||||
include third_party/lemon/lemon.mk
|
||||
include third_party/duktape/duktape.mk
|
||||
include third_party/regex/regex.mk
|
||||
include third_party/third_party.mk
|
||||
|
@ -149,7 +148,6 @@ include third_party/chibicc/test/test.mk
|
|||
include tool/build/emucrt/emucrt.mk
|
||||
include tool/build/emubin/emubin.mk
|
||||
include tool/build/build.mk
|
||||
include tool/calc/calc.mk
|
||||
include tool/decode/lib/decodelib.mk
|
||||
include tool/decode/decode.mk
|
||||
include tool/hash/hash.mk
|
||||
|
@ -328,6 +326,14 @@ o/cosmopolitan.html: \
|
|||
-fno-common -include libc/integral/normalize.inc -o $@ \
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS)))
|
||||
|
||||
$(SRCS): \
|
||||
libc/integral/normalize.inc \
|
||||
libc/integral/c.inc \
|
||||
libc/integral/cxx.inc \
|
||||
libc/integral/cxxtypescompat.inc \
|
||||
libc/integral/lp64arg.inc \
|
||||
libc/integral/lp64.inc
|
||||
|
||||
# UNSPECIFIED PREREQUISITES TUTORIAL
|
||||
#
|
||||
# A build rule must exist for all files that make needs to consider in
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
||||
#define COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_
|
||||
#ifndef __STRICT_ANSI__
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
@ -83,5 +82,4 @@ uint64_t(unsignedsubtract)(uint64_t, uint64_t) pureconst;
|
|||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* !ANSI */
|
||||
#endif /* COSMOPOLITAN_LIBC_BITS_SAFEMACROS_H_ */
|
||||
|
|
262
libc/errno.h
262
libc/errno.h
|
@ -6,137 +6,137 @@
|
|||
* @see libc/sysv/consts.sh for numbers
|
||||
*/
|
||||
|
||||
#define EPERM EPERM // operation not permitted
|
||||
#define ENOENT ENOENT // no such file or directory
|
||||
#define ESRCH ESRCH // no such process
|
||||
#define EINTR EINTR // interrupted system call
|
||||
#define EIO EIO // input/output error
|
||||
#define ENXIO ENXIO // no such device or address
|
||||
#define E2BIG E2BIG // argument list too long
|
||||
#define ENOEXEC ENOEXEC // exec format error
|
||||
#define EBADF EBADF // bad file descriptor
|
||||
#define ECHILD ECHILD // no child processes
|
||||
#define EAGAIN EAGAIN // resource temporarily unavailable
|
||||
#define ENOMEM ENOMEM // not enough space
|
||||
#define EACCES EACCES // permission denied
|
||||
#define EFAULT EFAULT // bad address
|
||||
#define ENOTBLK ENOTBLK // block device required
|
||||
#define EBUSY EBUSY // device or resource busy
|
||||
#define EEXIST EEXIST // file exists
|
||||
#define EXDEV EXDEV // improper link
|
||||
#define ENODEV ENODEV // no such device
|
||||
#define ENOTDIR ENOTDIR // not a directory
|
||||
#define EISDIR EISDIR // is a directory
|
||||
#define EINVAL EINVAL // invalid argument
|
||||
#define ENFILE ENFILE // too many open files in system
|
||||
#define EMFILE EMFILE // too many open files
|
||||
#define ENOTTY ENOTTY // inappropriate I/O control op
|
||||
#define ETXTBSY ETXTBSY // text file busy
|
||||
#define EFBIG EFBIG // file too large
|
||||
#define ENOSPC ENOSPC // no space left on device
|
||||
#define ESPIPE ESPIPE // invalid seek
|
||||
#define EROFS EROFS // read-only filesystem
|
||||
#define EMLINK EMLINK // too many links
|
||||
#define EPIPE EPIPE // broken pipe
|
||||
#define EDOM EDOM // argument out of function domain
|
||||
#define ERANGE ERANGE // result too large
|
||||
#define EDEADLK EDEADLK // resource deadlock avoided
|
||||
#define ENAMETOOLONG ENAMETOOLONG // filename too long
|
||||
#define ENOLCK ENOLCK // no locks available
|
||||
#define ENOSYS ENOSYS // system call not implemented
|
||||
#define ENOTEMPTY ENOTEMPTY // directory not empty
|
||||
#define ELOOP ELOOP // too many levels of symbolic links
|
||||
#define ENOMSG ENOMSG // no message of the desired type
|
||||
#define EIDRM EIDRM // identifier removed
|
||||
#define ECHRNG ECHRNG // channel number out of range
|
||||
#define EL2NSYNC EL2NSYNC // level 2 not synchronized
|
||||
#define EL3HLT EL3HLT // level 3 halted
|
||||
#define EL3RST EL3RST // level 3 halted
|
||||
#define ELNRNG ELNRNG // link number out of range
|
||||
#define EUNATCH EUNATCH // protocol driver not attached
|
||||
#define ENOCSI ENOCSI // no csi structure available
|
||||
#define EL2HLT EL2HLT // level 2 halted
|
||||
#define EBADE EBADE // invalid exchange
|
||||
#define EBADR EBADR // invalid request descriptor
|
||||
#define EXFULL EXFULL // exchange full
|
||||
#define ENOANO ENOANO // no anode
|
||||
#define EBADRQC EBADRQC // invalid request code
|
||||
#define EBADSLT EBADSLT // invalid slot
|
||||
#define ENOSTR ENOSTR // no string
|
||||
#define ENODATA ENODATA // no data
|
||||
#define ETIME ETIME // timer expired
|
||||
#define ENOSR ENOSR // out of streams resources
|
||||
#define ENONET ENONET // no network
|
||||
#define ENOPKG ENOPKG // package not installed
|
||||
#define EREMOTE EREMOTE // object is remote
|
||||
#define ENOLINK ENOLINK // link severed
|
||||
#define EADV EADV // todo
|
||||
#define ESRMNT ESRMNT // todo
|
||||
#define ECOMM ECOMM // communication error on send
|
||||
#define EPROTO EPROTO // protocol error
|
||||
#define EMULTIHOP EMULTIHOP // multihop attempted
|
||||
#define EDOTDOT EDOTDOT // todo
|
||||
#define EBADMSG EBADMSG // bad message
|
||||
#define EOVERFLOW EOVERFLOW // value too large for type
|
||||
#define ENOTUNIQ ENOTUNIQ // name not unique on network
|
||||
#define EBADFD EBADFD // fd in bad *state* (cf. EBADF)
|
||||
#define EREMCHG EREMCHG // remote address changed
|
||||
#define ELIBACC ELIBACC // cannot access dso
|
||||
#define ELIBBAD ELIBBAD // corrupted shared library
|
||||
#define ELIBSCN ELIBSCN // a.out section corrupted
|
||||
#define ELIBMAX ELIBMAX // too many shared libraries
|
||||
#define ELIBEXEC ELIBEXEC // cannot exec a dso directly
|
||||
#define EILSEQ EILSEQ // invalid wide character
|
||||
#define ERESTART ERESTART // please restart syscall
|
||||
#define ESTRPIPE ESTRPIPE // streams pipe error
|
||||
#define EUSERS EUSERS // too many users
|
||||
#define ENOTSOCK ENOTSOCK // not a socket
|
||||
#define EDESTADDRREQ EDESTADDRREQ // dest address needed
|
||||
#define EMSGSIZE EMSGSIZE // message too long
|
||||
#define EPROTOTYPE EPROTOTYPE // protocol wrong for socket
|
||||
#define ENOPROTOOPT ENOPROTOOPT // protocol not available
|
||||
#define EPROTONOSUPPORT EPROTONOSUPPORT // protocol not supported
|
||||
#define ESOCKTNOSUPPORT ESOCKTNOSUPPORT // socket type not supported
|
||||
#define EOPNOTSUPP EOPNOTSUPP // operation not supported on socket
|
||||
#define EPFNOSUPPORT EPFNOSUPPORT // protocol family not supported
|
||||
#define EAFNOSUPPORT EAFNOSUPPORT // address family not supported
|
||||
#define EADDRINUSE EADDRINUSE // address already in use
|
||||
#define EADDRNOTAVAIL EADDRNOTAVAIL // address not available
|
||||
#define ENETDOWN ENETDOWN // network is down
|
||||
#define ENETUNREACH ENETUNREACH // network unreachable
|
||||
#define ENETRESET ENETRESET // connection aborted by network
|
||||
#define ECONNABORTED ECONNABORTED // connection aborted
|
||||
#define ECONNRESET ECONNRESET // connection reset
|
||||
#define ENOBUFS ENOBUFS // no buffer space available
|
||||
#define EISCONN EISCONN // socket is connected
|
||||
#define ENOTCONN ENOTCONN // the socket is not connected
|
||||
#define ESHUTDOWN ESHUTDOWN // no send after endpoint shutdown
|
||||
#define ETOOMANYREFS ETOOMANYREFS // too many refs
|
||||
#define ETIMEDOUT ETIMEDOUT // connection timed out
|
||||
#define ECONNREFUSED ECONNREFUSED // connection refused
|
||||
#define EHOSTDOWN EHOSTDOWN // host is down
|
||||
#define EHOSTUNREACH EHOSTUNREACH // host is unreachable
|
||||
#define EALREADY EALREADY // connection already in progress
|
||||
#define EINPROGRESS EINPROGRESS // operation in progress
|
||||
#define ESTALE ESTALE // stale file handle
|
||||
#define EUCLEAN EUCLEAN // structure needs cleaning
|
||||
#define ENOTNAM ENOTNAM // todo
|
||||
#define ENAVAIL ENAVAIL // todo
|
||||
#define EISNAM EISNAM // is a named type file
|
||||
#define EREMOTEIO EREMOTEIO // remote i/o error
|
||||
#define EDQUOT EDQUOT // disk quota exceeded
|
||||
#define ENOMEDIUM ENOMEDIUM // no medium found
|
||||
#define EMEDIUMTYPE EMEDIUMTYPE // wrong medium type
|
||||
#define ECANCELED ECANCELED // operation canceled
|
||||
#define ENOKEY ENOKEY // required key not available
|
||||
#define EKEYEXPIRED EKEYEXPIRED // key has expired
|
||||
#define EKEYREVOKED EKEYREVOKED // key has been revoked
|
||||
#define EKEYREJECTED EKEYREJECTED // key was rejected by service
|
||||
#define EOWNERDEAD EOWNERDEAD // owner died
|
||||
#define ENOTRECOVERABLE ENOTRECOVERABLE // state not recoverable
|
||||
#define ERFKILL ERFKILL // can't op b/c RF-kill
|
||||
#define EHWPOISON EHWPOISON // mempage has h/w error
|
||||
#define EWOULDBLOCK EAGAIN // poll fd and try again
|
||||
#define EPERM EPERM /* operation not permitted */
|
||||
#define ENOENT ENOENT /* no such file or directory */
|
||||
#define ESRCH ESRCH /* no such process */
|
||||
#define EINTR EINTR /* interrupted system call */
|
||||
#define EIO EIO /* input/output error */
|
||||
#define ENXIO ENXIO /* no such device or address */
|
||||
#define E2BIG E2BIG /* argument list too long */
|
||||
#define ENOEXEC ENOEXEC /* exec format error */
|
||||
#define EBADF EBADF /* bad file descriptor */
|
||||
#define ECHILD ECHILD /* no child processes */
|
||||
#define EAGAIN EAGAIN /* resource temporarily unavailable */
|
||||
#define ENOMEM ENOMEM /* not enough space */
|
||||
#define EACCES EACCES /* permission denied */
|
||||
#define EFAULT EFAULT /* bad address */
|
||||
#define ENOTBLK ENOTBLK /* block device required */
|
||||
#define EBUSY EBUSY /* device or resource busy */
|
||||
#define EEXIST EEXIST /* file exists */
|
||||
#define EXDEV EXDEV /* improper link */
|
||||
#define ENODEV ENODEV /* no such device */
|
||||
#define ENOTDIR ENOTDIR /* not a directory */
|
||||
#define EISDIR EISDIR /* is a directory */
|
||||
#define EINVAL EINVAL /* invalid argument */
|
||||
#define ENFILE ENFILE /* too many open files in system */
|
||||
#define EMFILE EMFILE /* too many open files */
|
||||
#define ENOTTY ENOTTY /* inappropriate I/O control op */
|
||||
#define ETXTBSY ETXTBSY /* text file busy */
|
||||
#define EFBIG EFBIG /* file too large */
|
||||
#define ENOSPC ENOSPC /* no space left on device */
|
||||
#define ESPIPE ESPIPE /* invalid seek */
|
||||
#define EROFS EROFS /* read-only filesystem */
|
||||
#define EMLINK EMLINK /* too many links */
|
||||
#define EPIPE EPIPE /* broken pipe */
|
||||
#define EDOM EDOM /* argument out of function domain */
|
||||
#define ERANGE ERANGE /* result too large */
|
||||
#define EDEADLK EDEADLK /* resource deadlock avoided */
|
||||
#define ENAMETOOLONG ENAMETOOLONG /* filename too long */
|
||||
#define ENOLCK ENOLCK /* no locks available */
|
||||
#define ENOSYS ENOSYS /* system call not implemented */
|
||||
#define ENOTEMPTY ENOTEMPTY /* directory not empty */
|
||||
#define ELOOP ELOOP /* too many levels of symbolic links */
|
||||
#define ENOMSG ENOMSG /* no message of the desired type */
|
||||
#define EIDRM EIDRM /* identifier removed */
|
||||
#define ECHRNG ECHRNG /* channel number out of range */
|
||||
#define EL2NSYNC EL2NSYNC /* level 2 not synchronized */
|
||||
#define EL3HLT EL3HLT /* level 3 halted */
|
||||
#define EL3RST EL3RST /* level 3 halted */
|
||||
#define ELNRNG ELNRNG /* link number out of range */
|
||||
#define EUNATCH EUNATCH /* protocol driver not attached */
|
||||
#define ENOCSI ENOCSI /* no csi structure available */
|
||||
#define EL2HLT EL2HLT /* level 2 halted */
|
||||
#define EBADE EBADE /* invalid exchange */
|
||||
#define EBADR EBADR /* invalid request descriptor */
|
||||
#define EXFULL EXFULL /* exchange full */
|
||||
#define ENOANO ENOANO /* no anode */
|
||||
#define EBADRQC EBADRQC /* invalid request code */
|
||||
#define EBADSLT EBADSLT /* invalid slot */
|
||||
#define ENOSTR ENOSTR /* no string */
|
||||
#define ENODATA ENODATA /* no data */
|
||||
#define ETIME ETIME /* timer expired */
|
||||
#define ENOSR ENOSR /* out of streams resources */
|
||||
#define ENONET ENONET /* no network */
|
||||
#define ENOPKG ENOPKG /* package not installed */
|
||||
#define EREMOTE EREMOTE /* object is remote */
|
||||
#define ENOLINK ENOLINK /* link severed */
|
||||
#define EADV EADV /* todo */
|
||||
#define ESRMNT ESRMNT /* todo */
|
||||
#define ECOMM ECOMM /* communication error on send */
|
||||
#define EPROTO EPROTO /* protocol error */
|
||||
#define EMULTIHOP EMULTIHOP /* multihop attempted */
|
||||
#define EDOTDOT EDOTDOT /* todo */
|
||||
#define EBADMSG EBADMSG /* bad message */
|
||||
#define EOVERFLOW EOVERFLOW /* value too large for type */
|
||||
#define ENOTUNIQ ENOTUNIQ /* name not unique on network */
|
||||
#define EBADFD EBADFD /* fd in bad *state* (cf. EBADF) */
|
||||
#define EREMCHG EREMCHG /* remote address changed */
|
||||
#define ELIBACC ELIBACC /* cannot access dso */
|
||||
#define ELIBBAD ELIBBAD /* corrupted shared library */
|
||||
#define ELIBSCN ELIBSCN /* a.out section corrupted */
|
||||
#define ELIBMAX ELIBMAX /* too many shared libraries */
|
||||
#define ELIBEXEC ELIBEXEC /* cannot exec a dso directly */
|
||||
#define EILSEQ EILSEQ /* invalid wide character */
|
||||
#define ERESTART ERESTART /* please restart syscall */
|
||||
#define ESTRPIPE ESTRPIPE /* streams pipe error */
|
||||
#define EUSERS EUSERS /* too many users */
|
||||
#define ENOTSOCK ENOTSOCK /* not a socket */
|
||||
#define EDESTADDRREQ EDESTADDRREQ /* dest address needed */
|
||||
#define EMSGSIZE EMSGSIZE /* message too long */
|
||||
#define EPROTOTYPE EPROTOTYPE /* protocol wrong for socket */
|
||||
#define ENOPROTOOPT ENOPROTOOPT /* protocol not available */
|
||||
#define EPROTONOSUPPORT EPROTONOSUPPORT /* protocol not supported */
|
||||
#define ESOCKTNOSUPPORT ESOCKTNOSUPPORT /* socket type not supported */
|
||||
#define EOPNOTSUPP EOPNOTSUPP /* operation not supported on socket */
|
||||
#define EPFNOSUPPORT EPFNOSUPPORT /* protocol family not supported */
|
||||
#define EAFNOSUPPORT EAFNOSUPPORT /* address family not supported */
|
||||
#define EADDRINUSE EADDRINUSE /* address already in use */
|
||||
#define EADDRNOTAVAIL EADDRNOTAVAIL /* address not available */
|
||||
#define ENETDOWN ENETDOWN /* network is down */
|
||||
#define ENETUNREACH ENETUNREACH /* network unreachable */
|
||||
#define ENETRESET ENETRESET /* connection aborted by network */
|
||||
#define ECONNABORTED ECONNABORTED /* connection aborted */
|
||||
#define ECONNRESET ECONNRESET /* connection reset */
|
||||
#define ENOBUFS ENOBUFS /* no buffer space available */
|
||||
#define EISCONN EISCONN /* socket is connected */
|
||||
#define ENOTCONN ENOTCONN /* the socket is not connected */
|
||||
#define ESHUTDOWN ESHUTDOWN /* no send after endpoint shutdown */
|
||||
#define ETOOMANYREFS ETOOMANYREFS /* too many refs */
|
||||
#define ETIMEDOUT ETIMEDOUT /* connection timed out */
|
||||
#define ECONNREFUSED ECONNREFUSED /* connection refused */
|
||||
#define EHOSTDOWN EHOSTDOWN /* host is down */
|
||||
#define EHOSTUNREACH EHOSTUNREACH /* host is unreachable */
|
||||
#define EALREADY EALREADY /* connection already in progress */
|
||||
#define EINPROGRESS EINPROGRESS /* operation in progress */
|
||||
#define ESTALE ESTALE /* stale file handle */
|
||||
#define EUCLEAN EUCLEAN /* structure needs cleaning */
|
||||
#define ENOTNAM ENOTNAM /* todo */
|
||||
#define ENAVAIL ENAVAIL /* todo */
|
||||
#define EISNAM EISNAM /* is a named type file */
|
||||
#define EREMOTEIO EREMOTEIO /* remote i/o error */
|
||||
#define EDQUOT EDQUOT /* disk quota exceeded */
|
||||
#define ENOMEDIUM ENOMEDIUM /* no medium found */
|
||||
#define EMEDIUMTYPE EMEDIUMTYPE /* wrong medium type */
|
||||
#define ECANCELED ECANCELED /* operation canceled */
|
||||
#define ENOKEY ENOKEY /* required key not available */
|
||||
#define EKEYEXPIRED EKEYEXPIRED /* key has expired */
|
||||
#define EKEYREVOKED EKEYREVOKED /* key has been revoked */
|
||||
#define EKEYREJECTED EKEYREJECTED /* key was rejected by service */
|
||||
#define EOWNERDEAD EOWNERDEAD /* owner died */
|
||||
#define ENOTRECOVERABLE ENOTRECOVERABLE /* state not recoverable */
|
||||
#define ERFKILL ERFKILL /* can't op b/c RF-kill */
|
||||
#define EHWPOISON EHWPOISON /* mempage has h/w error */
|
||||
#define EWOULDBLOCK EAGAIN /* poll fd and try again */
|
||||
#define ENOTSUP ENOTSUP
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
|
|
@ -26,7 +26,6 @@ int sscanf(const char *, const char *, ...) scanfesque(2);
|
|||
int vsscanf(const char *, const char *, va_list);
|
||||
int vcscanf(int (*)(void *), int (*)(int, void *), void *, const char *,
|
||||
va_list);
|
||||
char *strerror(int) returnsnonnull nothrow nocallback;
|
||||
int strerror_r(int, char *, size_t) nothrow nocallback;
|
||||
int palandprintf(void *, void *, const char *, va_list) hidden;
|
||||
char *itoa(int, char *, int) compatfn;
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
int sleb128(const void *, size_t, int128_t);
|
||||
int unsleb128(const void *, size_t, int128_t *);
|
||||
#endif /* ANSI */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -61,23 +61,44 @@
|
|||
*/
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif /* __GNUC__ + 0 < 6 */
|
||||
|
||||
#else
|
||||
#define PFLINK(FMT) FMT
|
||||
#define SFLINK(FMT) FMT
|
||||
asm(".section .yoink\n\t"
|
||||
"nop\tntoa(%rip)\n\t"
|
||||
"nop\tftoa(%rip)\n\t"
|
||||
"nop\tkCp437(%rip)\n\t"
|
||||
"nop\tstrerror(%rip)\n\t"
|
||||
"nop\tstrnwidth(%rip)\n\t"
|
||||
"nop\tstrnwidth16(%rip)\n\t"
|
||||
"nop\twcsnwidth(%rip)\n\t"
|
||||
"nop\tmalloc(%rip)\n\t"
|
||||
"nop\tcalloc(%rip)\n\t"
|
||||
"nop\tfree_s(%rip)\n\t"
|
||||
"nop\t__grow(%rip)\n\t"
|
||||
".previous");
|
||||
#ifdef __GNUC__
|
||||
__asm__(".section .yoink\n\t"
|
||||
"nop\tntoa(%rip)\n\t"
|
||||
"nop\tftoa(%rip)\n\t"
|
||||
"nop\tkCp437(%rip)\n\t"
|
||||
"nop\tstrerror(%rip)\n\t"
|
||||
"nop\tstrnwidth(%rip)\n\t"
|
||||
"nop\tstrnwidth16(%rip)\n\t"
|
||||
"nop\twcsnwidth(%rip)\n\t"
|
||||
"nop\tmalloc(%rip)\n\t"
|
||||
"nop\tcalloc(%rip)\n\t"
|
||||
"nop\tfree_s(%rip)\n\t"
|
||||
"nop\t__grow(%rip)\n\t"
|
||||
".previous");
|
||||
#else
|
||||
#include "libc/fmt/palandprintf.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/unicode/unicode.h"
|
||||
static long __pflink(long x) {
|
||||
x |= kCp437[0];
|
||||
x |= ntoa(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
x |= ftoa(0, 0, 0, 0, 0, 0);
|
||||
x |= strnwidth(0, 0);
|
||||
x |= strnwidth16(0, 0);
|
||||
x |= wcsnwidth(0, 0);
|
||||
x |= malloc(0);
|
||||
x |= __grow(0, 0, 0, 0);
|
||||
x |= (intptr_t)strerror(0);
|
||||
x |= (intptr_t)calloc(0, 0);
|
||||
free_s(0);
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
#endif /* __STRICT_ANSI__ */
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_FMT_PFLINK_H_ */
|
||||
|
|
|
@ -601,7 +601,13 @@ typedef uint64_t uintmax_t;
|
|||
#endif
|
||||
|
||||
#ifndef unreachable
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI)
|
||||
#define unreachable __builtin_unreachable()
|
||||
#else
|
||||
#define unreachable \
|
||||
do { \
|
||||
} while (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define donothing \
|
||||
|
@ -754,13 +760,13 @@ typedef uint64_t uintmax_t;
|
|||
#endif /* ANSI */
|
||||
#endif /* -w */
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define DebugBreak() asm("int3")
|
||||
#else
|
||||
#define DebugBreak() (void)0
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define VEIL(CONSTRAINT, EXPRESSION) \
|
||||
({ \
|
||||
autotype(EXPRESSION) VeiledValue = (EXPRESSION); \
|
||||
|
@ -771,7 +777,7 @@ typedef uint64_t uintmax_t;
|
|||
#define VEIL(CONSTRAINT, EXPRESSION) (EXPRESSION)
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define CONCEAL(CONSTRAINT, EXPRESSION) \
|
||||
({ \
|
||||
autotype(EXPRESSION) VeiledValue = (EXPRESSION); \
|
||||
|
@ -782,7 +788,7 @@ typedef uint64_t uintmax_t;
|
|||
#define CONCEAL(CONSTRAINT, EXPRESSION) (EXPRESSION)
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define EXPROPRIATE(EXPRESSION) \
|
||||
({ \
|
||||
asm volatile("" ::"g"(EXPRESSION) : "memory"); \
|
||||
|
@ -792,7 +798,7 @@ typedef uint64_t uintmax_t;
|
|||
#define EXPROPRIATE(EXPRESSION) (EXPRESSION)
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define YOINK(SYMBOL) \
|
||||
do { \
|
||||
_Static_assert(!__builtin_types_compatible_p(typeof(SYMBOL), char[]), \
|
||||
|
@ -807,7 +813,7 @@ typedef uint64_t uintmax_t;
|
|||
#define YOINK(SYMBOL) (void)0
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define STATIC_YOINK(SYMBOLSTR) \
|
||||
asm(".section .yoink\n\tnopl\t\"" SYMBOLSTR "\"\n\t.previous")
|
||||
#else
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
void __logerrno(const char *file, int line, const char *form) {
|
||||
flogf(kLogWarn, file, line, NULL, PFLINK("%s → %s"), form, strerror(errno));
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Writes error messages to standard error.
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/fmt.h"
|
||||
|
||||
/**
|
||||
* Formats string, allocating needed memory.
|
||||
|
|
18
libc/mem/fmt.h
Normal file
18
libc/mem/fmt.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MEM_FMT_H_
|
||||
#define COSMOPOLITAN_LIBC_MEM_FMT_H_
|
||||
#include "libc/fmt/pflink.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int asprintf(char **, const char *, ...) printfesque(2)
|
||||
paramsnonnull((1, 2)) libcesque;
|
||||
int vasprintf(char **, const char *, va_list) paramsnonnull() libcesque;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define asprintf(SP, FMT, ...) (asprintf)(SP, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vasprintf(SP, FMT, VA) (vasprintf)(SP, PFLINK(FMT), VA)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_MEM_FMT_H_ */
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MEM_MEM_H_
|
||||
#define COSMOPOLITAN_LIBC_MEM_MEM_H_
|
||||
#include "libc/fmt/pflink.h"
|
||||
|
||||
#define M_TRIM_THRESHOLD (-1)
|
||||
#define M_GRANULARITY (-2)
|
||||
|
@ -34,10 +33,6 @@ size_t malloc_usable_size(const void *);
|
|||
void **independent_calloc(size_t, size_t, void **);
|
||||
void **independent_comalloc(size_t, size_t *, void **);
|
||||
|
||||
int asprintf(char **, const char *, ...) printfesque(2)
|
||||
paramsnonnull((1, 2)) libcesque;
|
||||
int vasprintf(char **, const char *, va_list) paramsnonnull() libcesque;
|
||||
|
||||
wchar_t *wcsdup(const wchar_t *) strlenesque nodiscard;
|
||||
|
||||
struct mallinfo {
|
||||
|
@ -63,15 +58,6 @@ size_t malloc_set_footprint_limit(size_t);
|
|||
void malloc_inspect_all(void (*handler)(void *, void *, size_t, void *),
|
||||
void *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § dynamic memory » optimizations ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define asprintf(SP, FMT, ...) (asprintf)(SP, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vasprintf(SP, FMT, VA) (vasprintf)(SP, PFLINK(FMT), VA)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_MEM_MEM_H_ */
|
||||
|
|
|
@ -59,8 +59,8 @@ uint32_t SleepEx(uint32_t dwMilliseconds, bool32 bAlertable);
|
|||
void GetSystemTime(struct NtSystemTime *lpSystemTime);
|
||||
bool32 SystemTimeToFileTime(const struct NtSystemTime *lpSystemTime,
|
||||
struct NtFileTime *lpFileTime);
|
||||
void GetSystemTimeAsFileTime(struct NtFileTime *); // win8+
|
||||
void GetSystemTimePreciseAsFileTime(struct NtFileTime *); // win8+
|
||||
void GetSystemTimeAsFileTime(struct NtFileTime *); /* win8+ */
|
||||
void GetSystemTimePreciseAsFileTime(struct NtFileTime *); /* win8+ */
|
||||
|
||||
uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds);
|
||||
uint32_t WaitForMultipleObjects(uint32_t nCount, const int64_t *lpHandles,
|
||||
|
|
|
@ -25,6 +25,7 @@ LIBC_RAND_A_CHECKS = \
|
|||
|
||||
LIBC_RAND_A_DIRECTDEPS = \
|
||||
LIBC_CALLS \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_STR \
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define _kAutomapStart 0x0000100080000000 // asan can't spread its poison here
|
||||
#define _kAutomapSize 0x00000fff80000000
|
||||
#define _kAutomapStart 0x0000100080000000 /* asan can't spread its poison */
|
||||
#define _kAutomapSize 0x00000fff80000000 /* beyond the above mem address */
|
||||
#define _kFixedmapStart 0x0000200000000000
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,19 +10,19 @@ COSMOPOLITAN_C_START_
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
typedef struct FILE {
|
||||
uint8_t bufmode; // 0x00 _IOFBF, etc. (ignored if fd=-1)
|
||||
bool noclose; // 0x01 for fake dup()
|
||||
uint32_t iomode; // 0x04 O_RDONLY, etc. (ignored if fd=-1)
|
||||
int32_t state; // 0x08 0=OK, -1=EOF, >0=errno
|
||||
int fd; // 0x0c ≥0=fd, -1=closed|buffer
|
||||
uint32_t beg; // 0x10
|
||||
uint32_t end; // 0x14
|
||||
uint8_t *buf; // 0x18
|
||||
uint32_t size; // 0x20
|
||||
uint32_t nofree; // 0x24
|
||||
int (*reader)(struct FILE *); // 0x28
|
||||
int (*writer)(struct FILE *); // 0x30
|
||||
int pid; // 0x34
|
||||
uint8_t bufmode; /* 0x00 _IOFBF, etc. (ignored if fd=-1) */
|
||||
bool noclose; /* 0x01 for fake dup() */
|
||||
uint32_t iomode; /* 0x04 O_RDONLY, etc. (ignored if fd=-1) */
|
||||
int32_t state; /* 0x08 0=OK, -1=EOF, >0=errno */
|
||||
int fd; /* 0x0c ≥0=fd, -1=closed|buffer */
|
||||
uint32_t beg; /* 0x10 */
|
||||
uint32_t end; /* 0x14 */
|
||||
uint8_t *buf; /* 0x18 */
|
||||
uint32_t size; /* 0x20 */
|
||||
uint32_t nofree; /* 0x24 */
|
||||
int (*reader)(struct FILE *); /* 0x28 */
|
||||
int (*writer)(struct FILE *); /* 0x30 */
|
||||
int pid; /* 0x34 */
|
||||
} FILE;
|
||||
|
||||
extern FILE *stdin;
|
||||
|
|
|
@ -181,6 +181,7 @@ compatfn wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t) memcpyesque;
|
|||
int timingsafe_memcmp(const void *, const void *, size_t);
|
||||
void *memmem(const void *, size_t, const void *, size_t)
|
||||
paramsnonnull() nothrow nocallback nosideeffect;
|
||||
char *strerror(int) returnsnonnull nothrow nocallback;
|
||||
|
||||
char *tinystrstr(const char *, const char *) strlenesque;
|
||||
char16_t *tinystrstr16(const char16_t *, const char16_t *) strlenesque;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
testonly void testlib_showerror(const char *file, int line, const char *func,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
|
|
@ -67,9 +67,37 @@ o/$(MODE)/test/libc/release/smokecxx.com.dbg: \
|
|||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
|
||||
o/$(MODE)/test/libc/release/smokeansi.com.dbg: \
|
||||
test/libc/release/smoke.c \
|
||||
o/cosmopolitan.h \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
@ACTION=ANSI build/compile $(CC) \
|
||||
-o $@ \
|
||||
-Os \
|
||||
-ansi \
|
||||
-static \
|
||||
-no-pie \
|
||||
-fno-pie \
|
||||
-nostdlib \
|
||||
-nostdinc \
|
||||
-mno-red-zone \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,-z,max-page-size=0x1000 \
|
||||
-Wl,-T,o/$(MODE)/ape/ape.lds \
|
||||
-include o/cosmopolitan.h \
|
||||
test/libc/release/smoke.c \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/cosmopolitan.a
|
||||
|
||||
.PHONY: o/$(MODE)/test/libc/release
|
||||
o/$(MODE)/test/libc/release: \
|
||||
o/$(MODE)/test/libc/release/smoke.com \
|
||||
o/$(MODE)/test/libc/release/smoke.com.runs \
|
||||
o/$(MODE)/test/libc/release/smokecxx.com \
|
||||
o/$(MODE)/test/libc/release/smokecxx.com.runs
|
||||
o/$(MODE)/test/libc/release/smokecxx.com.runs \
|
||||
o/$(MODE)/test/libc/release/smokeansi.com \
|
||||
o/$(MODE)/test/libc/release/smokeansi.com.runs
|
||||
|
|
1022
third_party/lemon/README
vendored
1022
third_party/lemon/README
vendored
File diff suppressed because it is too large
Load diff
5968
third_party/lemon/lemon.c
vendored
5968
third_party/lemon/lemon.c
vendored
File diff suppressed because it is too large
Load diff
61
third_party/lemon/lemon.mk
vendored
61
third_party/lemon/lemon.mk
vendored
|
@ -1,61 +0,0 @@
|
|||
#-*-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───────────────────────┘
|
||||
|
||||
PKGS += THIRD_PARTY_LEMON
|
||||
THIRD_PARTY_LEMON_FILES := $(wildcard third_party/lemon/*)
|
||||
THIRD_PARTY_LEMON_HDRS = $(filter %.h,$(THIRD_PARTY_LEMON_FILES))
|
||||
THIRD_PARTY_LEMON_INCS = $(filter %.inc,$(THIRD_PARTY_LEMON_FILES))
|
||||
THIRD_PARTY_LEMON_SRCS = $(filter %.c,$(THIRD_PARTY_LEMON_FILES))
|
||||
|
||||
LEMON = $(MKDIR) $(@D) && ACTION="LEMON $@" build/do $(THIRD_PARTY_LEMON)
|
||||
|
||||
THIRD_PARTY_LEMON = o/$(MODE)/third_party/lemon/lemon.com.dbg
|
||||
|
||||
THIRD_PARTY_LEMON_OBJS = \
|
||||
o/$(MODE)/third_party/lemon/lemon.o \
|
||||
o/$(MODE)/third_party/lemon/lempar.c.txt.zip.o
|
||||
|
||||
THIRD_PARTY_LEMON_COMS = \
|
||||
o/$(MODE)/third_party/lemon/lemon.com
|
||||
|
||||
THIRD_PARTY_LEMON_LINK = \
|
||||
$(THIRD_PARTY_LEMON_DEPS) \
|
||||
o/$(MODE)/third_party/lemon/%.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
|
||||
THIRD_PARTY_LEMON_DIRECTDEPS = \
|
||||
LIBC_ALG \
|
||||
LIBC_CALLS \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_GDTOA
|
||||
|
||||
THIRD_PARTY_LEMON_DEPS := \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_LEMON_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/third_party/lemon/lemon.pkg: \
|
||||
$(THIRD_PARTY_LEMON_OBJS) \
|
||||
$(foreach x,$(THIRD_PARTY_LEMON_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/third_party/lemon/lemon.com.dbg: \
|
||||
$(THIRD_PARTY_LEMON_DEPS) \
|
||||
o/$(MODE)/third_party/lemon/lemon.pkg \
|
||||
o/$(MODE)/third_party/lemon/lemon.o \
|
||||
o/$(MODE)/third_party/lemon/lempar.c.txt.zip.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/lemon
|
||||
o/$(MODE)/third_party/lemon: \
|
||||
o/$(MODE)/third_party/lemon/lemon.com
|
1083
third_party/lemon/lempar.c.txt
vendored
1083
third_party/lemon/lempar.c.txt
vendored
File diff suppressed because it is too large
Load diff
1
third_party/third_party.mk
vendored
1
third_party/third_party.mk
vendored
|
@ -11,7 +11,6 @@ o/$(MODE)/third_party: \
|
|||
o/$(MODE)/third_party/duktape \
|
||||
o/$(MODE)/third_party/f2c \
|
||||
o/$(MODE)/third_party/getopt \
|
||||
o/$(MODE)/third_party/lemon \
|
||||
o/$(MODE)/third_party/lz4cli \
|
||||
o/$(MODE)/third_party/musl \
|
||||
o/$(MODE)/third_party/regex \
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/memtrack.h"
|
||||
|
|
961
tool/calc/calc.c
961
tool/calc/calc.c
|
@ -1,961 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ 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/bits/bits.h"
|
||||
#include "libc/bits/bswap.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/nexgen32e/ffs.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "o/tool/calc/calc.c.inc"
|
||||
#include "o/tool/calc/calc.h.inc"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
#include "tool/calc/calc.h"
|
||||
|
||||
/**
|
||||
* make -j8 o//tool/calc
|
||||
* rlwrap -A -H ~/.calc -f tool/calc/calc.lst -e\( o//tool/calc/calc.com
|
||||
* @see https://github.com/hanslub42/rlwrap
|
||||
*/
|
||||
|
||||
static jmp_buf jb;
|
||||
static int g_line;
|
||||
static int g_column;
|
||||
static const char *g_file;
|
||||
static yyParser g_parser[1];
|
||||
|
||||
wontreturn static void Error(const char *msg) {
|
||||
fprintf(stderr, "%s:%d:%d: %s\n", g_file, g_line, g_column, msg);
|
||||
longjmp(jb, 1);
|
||||
}
|
||||
|
||||
wontreturn static void SyntaxError(void) {
|
||||
Error("SYNTAX ERROR");
|
||||
}
|
||||
|
||||
wontreturn static void LexError(void) {
|
||||
Error("LEX ERROR");
|
||||
}
|
||||
|
||||
wontreturn static void MissingArgumentError(void) {
|
||||
Error("MISSING ARGUMENT");
|
||||
}
|
||||
|
||||
wontreturn static void MissingFunctionError(void) {
|
||||
Error("MISSING FUNCTION");
|
||||
}
|
||||
|
||||
wontreturn static void SyscallError(const char *name) {
|
||||
fprintf(stderr, "ERROR: %s[%s]: %d\n", name, g_file, errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void NumbersFree(struct Numbers *n) {
|
||||
if (n) {
|
||||
NumbersFree(n->n);
|
||||
free(n);
|
||||
}
|
||||
}
|
||||
|
||||
static struct Numbers *NumbersAppend(struct Numbers *n, long double x) {
|
||||
struct Numbers *a;
|
||||
a = malloc(sizeof(struct Numbers));
|
||||
a->n = n;
|
||||
a->x = x;
|
||||
return a;
|
||||
}
|
||||
|
||||
static long double ParseNumber(struct Token t) {
|
||||
char *ep;
|
||||
ep = t.s + t.n;
|
||||
if (t.s[0] == '0') {
|
||||
return strtoumax(t.s, &ep, 0);
|
||||
} else {
|
||||
return strtod(t.s, &ep);
|
||||
}
|
||||
}
|
||||
|
||||
static long double FnRand(struct Numbers *a) {
|
||||
return rand();
|
||||
}
|
||||
|
||||
static long double FnRand32(struct Numbers *a) {
|
||||
return rand32();
|
||||
}
|
||||
|
||||
static long double FnRand64(struct Numbers *a) {
|
||||
return rand64();
|
||||
}
|
||||
|
||||
static long double FnRdrand(struct Numbers *a) {
|
||||
if (X86_HAVE(RDRND)) {
|
||||
return rdrand();
|
||||
} else {
|
||||
return NAN;
|
||||
}
|
||||
}
|
||||
|
||||
static long double FnRdseed(struct Numbers *a) {
|
||||
if (X86_HAVE(RDSEED)) {
|
||||
return rdseed();
|
||||
} else {
|
||||
return NAN;
|
||||
}
|
||||
}
|
||||
|
||||
static long double FnAtan2(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return atan2l(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnLdexp(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return ldexpl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnCopysign(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return copysignl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnFmax(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return fmaxl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnFmin(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return fminl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnFmod(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return fmodl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnHypot(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return hypotl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnPowi(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return powil(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnPow(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return powl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnScalb(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return scalbl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIsgreater(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return isgreater(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRemainder(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return remainderl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIsgreaterequal(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return isgreaterequal(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIsless(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return isless(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIslessequal(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return islessequal(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIslessgreater(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return islessgreater(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnIsunordered(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return isunordered(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRounddown(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return ROUNDDOWN((int128_t)a->n->x, (int128_t)a->x);
|
||||
}
|
||||
|
||||
static long double FnRoundup(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return ROUNDUP((int128_t)a->n->x, (int128_t)a->x);
|
||||
}
|
||||
|
||||
static long double FnAcos(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return acosl(a->x);
|
||||
}
|
||||
|
||||
static long double FnAsin(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return asinl(a->x);
|
||||
}
|
||||
|
||||
static long double FnAtan(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return atanl(a->x);
|
||||
}
|
||||
|
||||
static long double FnCbrt(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return cbrtl(a->x);
|
||||
}
|
||||
|
||||
static long double FnCeil(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return ceill(a->x);
|
||||
}
|
||||
|
||||
static long double FnCos(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return cosl(a->x);
|
||||
}
|
||||
|
||||
static long double FnExp10(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return exp10l(a->x);
|
||||
}
|
||||
|
||||
static long double FnExp2(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return exp2l(a->x);
|
||||
}
|
||||
|
||||
static long double FnExp(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return expl(a->x);
|
||||
}
|
||||
|
||||
static long double FnExpm1(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return expm1l(a->x);
|
||||
}
|
||||
|
||||
static long double FnFabs(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return fabsl(a->x);
|
||||
}
|
||||
|
||||
static long double FnFloor(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return floorl(a->x);
|
||||
}
|
||||
|
||||
static long double FnIlogb(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return ilogbl(a->x);
|
||||
}
|
||||
|
||||
static long double FnLog10(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return log10l(a->x);
|
||||
}
|
||||
|
||||
static long double FnLog1p(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return log1pl(a->x);
|
||||
}
|
||||
|
||||
static long double FnLog2(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return log2l(a->x);
|
||||
}
|
||||
|
||||
static long double FnLogb(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return logbl(a->x);
|
||||
}
|
||||
|
||||
static long double FnLog(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return logl(a->x);
|
||||
}
|
||||
|
||||
static long double FnLrint(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return lrintl(a->x);
|
||||
}
|
||||
|
||||
static long double FnLround(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return lroundl(a->x);
|
||||
}
|
||||
|
||||
static long double FnNearbyint(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return nearbyintl(a->x);
|
||||
}
|
||||
|
||||
static long double FnRint(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return rintl(a->x);
|
||||
}
|
||||
|
||||
static long double FnRound(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return roundl(a->x);
|
||||
}
|
||||
|
||||
static long double FnSignificand(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return significandl(a->x);
|
||||
}
|
||||
|
||||
static long double FnSin(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return sinl(a->x);
|
||||
}
|
||||
|
||||
static long double FnSqrt(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return sqrtl(a->x);
|
||||
}
|
||||
|
||||
static long double FnTan(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return tanl(a->x);
|
||||
}
|
||||
|
||||
static long double FnTrunc(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return truncl(a->x);
|
||||
}
|
||||
|
||||
static long double FnIsinf(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return isinf(a->x);
|
||||
}
|
||||
|
||||
static long double FnIsnan(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return isnan(a->x);
|
||||
}
|
||||
|
||||
static long double FnIsfinite(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return isfinite(a->x);
|
||||
}
|
||||
|
||||
static long double FnIsnormal(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return isnormal(a->x);
|
||||
}
|
||||
|
||||
static long double FnSignbit(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return signbit(a->x);
|
||||
}
|
||||
|
||||
static long double FnFpclassify(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return fpclassify(a->x);
|
||||
}
|
||||
|
||||
static long double FnBswap16(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bswap_16((uint16_t)a->x);
|
||||
}
|
||||
|
||||
static long double FnBswap32(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bswap_32((uint32_t)a->x);
|
||||
}
|
||||
|
||||
static long double FnBswap64(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bswap_64((uint64_t)a->x);
|
||||
}
|
||||
|
||||
static long double FnBsr(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bsr(a->x);
|
||||
}
|
||||
|
||||
static long double FnBsrl(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bsrl(a->x);
|
||||
}
|
||||
|
||||
static long double FnBsfl(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bsfl(a->x);
|
||||
}
|
||||
|
||||
static long double FnFfs(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return ffs(a->x);
|
||||
}
|
||||
|
||||
static long double FnFfsl(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return ffsl(a->x);
|
||||
}
|
||||
|
||||
static long double FnGray(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return gray(a->x);
|
||||
}
|
||||
|
||||
static long double FnUngray(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return ungray(a->x);
|
||||
}
|
||||
|
||||
static long double FnRounddown2pow(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return rounddown2pow(a->x);
|
||||
}
|
||||
|
||||
static long double FnRoundup2pow(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return roundup2pow(a->x);
|
||||
}
|
||||
|
||||
static long double FnRoundup2log(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return roundup2log(a->x);
|
||||
}
|
||||
|
||||
static long double FnBitreverse8(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bitreverse8(a->x);
|
||||
}
|
||||
|
||||
static long double FnBitreverse16(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bitreverse16(a->x);
|
||||
}
|
||||
|
||||
static long double FnBitreverse32(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bitreverse32(a->x);
|
||||
}
|
||||
|
||||
static long double FnBitreverse64(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
return bitreverse64(a->x);
|
||||
}
|
||||
|
||||
static int8_t sarb(int8_t x, uint8_t y) {
|
||||
return x >> (y & 7);
|
||||
}
|
||||
|
||||
static int16_t sarw(int16_t x, uint8_t y) {
|
||||
return x >> (y & 15);
|
||||
}
|
||||
|
||||
static int32_t sarl(int32_t x, uint8_t y) {
|
||||
return x >> (y & 31);
|
||||
}
|
||||
|
||||
static int64_t sarq(int64_t x, uint8_t y) {
|
||||
return x >> (y & 63);
|
||||
}
|
||||
|
||||
static long double FnSarb(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return sarb(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnSarw(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return sarw(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnSarl(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return sarl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnSarq(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return sarq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnSar(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return sarq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static uint8_t rorb(uint8_t x, uint8_t y) {
|
||||
return x >> (y & 7) | x << (8 - (y & 7));
|
||||
}
|
||||
|
||||
static uint16_t rorw(uint16_t x, uint8_t y) {
|
||||
return x >> (y & 15) | x << (16 - (y & 15));
|
||||
}
|
||||
|
||||
static uint32_t rorl(uint32_t x, uint8_t y) {
|
||||
return x >> (y & 31) | x << (32 - (y & 31));
|
||||
}
|
||||
|
||||
static uint64_t rorq(uint64_t x, uint8_t y) {
|
||||
return x >> (y & 63) | x << (64 - (y & 63));
|
||||
}
|
||||
|
||||
static long double FnRorb(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rorb(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRorw(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rorw(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRorl(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rorl(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRorq(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rorq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRor(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rorq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static uint8_t rolb(uint8_t x, uint8_t y) {
|
||||
return x << (y & 7) | x >> (8 - (y & 7));
|
||||
}
|
||||
|
||||
static uint16_t rolw(uint16_t x, uint8_t y) {
|
||||
return x << (y & 15) | x >> (16 - (y & 15));
|
||||
}
|
||||
|
||||
static uint32_t roll(uint32_t x, uint8_t y) {
|
||||
return x << (y & 31) | x >> (32 - (y & 31));
|
||||
}
|
||||
|
||||
static uint64_t rolq(uint64_t x, uint8_t y) {
|
||||
return x << (y & 63) | x >> (64 - (y & 63));
|
||||
}
|
||||
|
||||
static long double FnRolb(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rolb(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRolw(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rolw(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRoll(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return roll(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRolq(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rolq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnRol(struct Numbers *a) {
|
||||
if (!a || !a->n) MissingArgumentError();
|
||||
return rolq(a->n->x, a->x);
|
||||
}
|
||||
|
||||
static long double FnTime(struct Numbers *a) {
|
||||
return nowl();
|
||||
}
|
||||
|
||||
static long double FnBin(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
printf("0b%jb\n", (uint128_t)a->x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long double FnOct(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
printf("0%jo\n", (uint128_t)a->x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long double FnHex(struct Numbers *a) {
|
||||
if (!a) MissingArgumentError();
|
||||
printf("0x%jx\n", (uint128_t)a->x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PrintNumber(long double x) {
|
||||
char buf[32];
|
||||
g_xfmt_p(buf, &x, 15, sizeof(buf), 0);
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
|
||||
static void Print(struct Numbers *a) {
|
||||
if (a) {
|
||||
Print(a->n);
|
||||
if (a->n) fputc(' ', stdout);
|
||||
PrintNumber(a->x);
|
||||
}
|
||||
}
|
||||
|
||||
static long double FnPrint(struct Numbers *a) {
|
||||
Print(a);
|
||||
fputc('\n', stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct Fn {
|
||||
const char *s;
|
||||
long double (*f)(struct Numbers *);
|
||||
} kFunctions[] = {
|
||||
{"abs", FnFabs},
|
||||
{"acos", FnAcos},
|
||||
{"asin", FnAsin},
|
||||
{"atan", FnAtan},
|
||||
{"atan2", FnAtan2},
|
||||
{"bin", FnBin},
|
||||
{"bitreverse16", FnBitreverse16},
|
||||
{"bitreverse32", FnBitreverse32},
|
||||
{"bitreverse64", FnBitreverse64},
|
||||
{"bitreverse8", FnBitreverse8},
|
||||
{"bsfl", FnBsfl},
|
||||
{"bsfl", FnBsfl},
|
||||
{"bsr", FnBsr},
|
||||
{"bsrl", FnBsrl},
|
||||
{"bswap16", FnBswap16},
|
||||
{"bswap32", FnBswap32},
|
||||
{"bswap64", FnBswap64},
|
||||
{"cbrt", FnCbrt},
|
||||
{"ceil", FnCeil},
|
||||
{"copysign", FnCopysign},
|
||||
{"cos", FnCos},
|
||||
{"exp", FnExp},
|
||||
{"exp10", FnExp10},
|
||||
{"exp2", FnExp2},
|
||||
{"expm1", FnExpm1},
|
||||
{"fabs", FnFabs},
|
||||
{"ffs", FnFfs},
|
||||
{"ffsl", FnFfsl},
|
||||
{"floor", FnFloor},
|
||||
{"fmax", FnFmax},
|
||||
{"fmin", FnFmin},
|
||||
{"fmod", FnFmod},
|
||||
{"fpclassify", FnFpclassify},
|
||||
{"gray", FnGray},
|
||||
{"hex", FnHex},
|
||||
{"hypot", FnHypot},
|
||||
{"ilogb", FnIlogb},
|
||||
{"isfinite", FnIsfinite},
|
||||
{"isgreater", FnIsgreater},
|
||||
{"isgreaterequal", FnIsgreaterequal},
|
||||
{"isinf", FnIsinf},
|
||||
{"isless", FnIsless},
|
||||
{"islessequal", FnIslessequal},
|
||||
{"islessgreater", FnIslessgreater},
|
||||
{"isnan", FnIsnan},
|
||||
{"isnormal", FnIsnormal},
|
||||
{"isunordered", FnIsunordered},
|
||||
{"ldexp", FnLdexp},
|
||||
{"ldexp", FnLdexp},
|
||||
{"log", FnLog},
|
||||
{"log10", FnLog10},
|
||||
{"log1p", FnLog1p},
|
||||
{"log2", FnLog2},
|
||||
{"logb", FnLogb},
|
||||
{"lrint", FnLrint},
|
||||
{"lround", FnLround},
|
||||
{"max", FnFmax},
|
||||
{"min", FnFmin},
|
||||
{"nearbyint", FnNearbyint},
|
||||
{"oct", FnOct},
|
||||
{"pow", FnPow},
|
||||
{"powi", FnPowi},
|
||||
{"print", FnPrint},
|
||||
{"rand", FnRand},
|
||||
{"rand32", FnRand32},
|
||||
{"rand64", FnRand64},
|
||||
{"rdrand", FnRdrand},
|
||||
{"rdseed", FnRdseed},
|
||||
{"remainder", FnRemainder},
|
||||
{"rint", FnRint},
|
||||
{"rol", FnRol},
|
||||
{"rolb", FnRolb},
|
||||
{"roll", FnRoll},
|
||||
{"rolq", FnRolq},
|
||||
{"rolw", FnRolw},
|
||||
{"ror", FnRor},
|
||||
{"rorb", FnRorb},
|
||||
{"rorl", FnRorl},
|
||||
{"rorq", FnRorq},
|
||||
{"rorw", FnRorw},
|
||||
{"round", FnRound},
|
||||
{"rounddown", FnRounddown},
|
||||
{"rounddown2pow", FnRounddown2pow},
|
||||
{"roundup", FnRoundup},
|
||||
{"roundup2log", FnRoundup2log},
|
||||
{"roundup2pow", FnRoundup2pow},
|
||||
{"sar", FnSar},
|
||||
{"sarb", FnSarb},
|
||||
{"sarl", FnSarl},
|
||||
{"sarq", FnSarq},
|
||||
{"sarw", FnSarw},
|
||||
{"scalb", FnScalb},
|
||||
{"signbit", FnSignbit},
|
||||
{"signbit", FnSignbit},
|
||||
{"significand", FnSignificand},
|
||||
{"sin", FnSin},
|
||||
{"sqrt", FnSqrt},
|
||||
{"tan", FnTan},
|
||||
{"time", FnTime},
|
||||
{"trunc", FnTrunc},
|
||||
{"ungray", FnUngray},
|
||||
};
|
||||
|
||||
static long double CallFunction(struct Token fn, struct Numbers *args) {
|
||||
int l, r, m, p;
|
||||
l = 0;
|
||||
r = ARRAYLEN(kFunctions) - 1;
|
||||
while (l <= r) {
|
||||
m = (l + r) >> 1;
|
||||
p = strncmp(kFunctions[m].s, fn.s, fn.n);
|
||||
if (p < 0) {
|
||||
l = m + 1;
|
||||
} else if (p > 0) {
|
||||
r = m - 1;
|
||||
} else {
|
||||
return kFunctions[m].f(args);
|
||||
}
|
||||
}
|
||||
MissingFunctionError();
|
||||
}
|
||||
|
||||
static void Tokenize(const char *s, size_t size) {
|
||||
size_t n;
|
||||
char *se;
|
||||
for (se = s + size; s < se; s += n, ++g_column) {
|
||||
n = 1;
|
||||
switch (*s & 0xff) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\v':
|
||||
case '\r':
|
||||
break;
|
||||
case '\n':
|
||||
++g_line;
|
||||
g_column = 0;
|
||||
break;
|
||||
case 'A' ... 'Z':
|
||||
case 'a' ... 'z':
|
||||
n = strspn(s, "0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz");
|
||||
Parse(g_parser, SYMBOL, (struct Token){s, n});
|
||||
break;
|
||||
case '0':
|
||||
n = strspn(s, "xXbB0123456789abcdefABCDEF");
|
||||
Parse(g_parser, NUMBER, (struct Token){s, n});
|
||||
n += strspn(s + n, "LUlu");
|
||||
break;
|
||||
case '1' ... '9':
|
||||
n = strspn(s, "0123456789.");
|
||||
if (s[n] == 'e' || s[n] == 'E') {
|
||||
++n;
|
||||
if (s[n] == '+' || s[n] == '-') ++n;
|
||||
n += strspn(s + n, "0123456789");
|
||||
}
|
||||
Parse(g_parser, NUMBER, (struct Token){s, n});
|
||||
n += strspn(s + n, "LUlu");
|
||||
break;
|
||||
case '(':
|
||||
Parse(g_parser, LP, (struct Token){0, 0});
|
||||
break;
|
||||
case ')':
|
||||
Parse(g_parser, RP, (struct Token){0, 0});
|
||||
break;
|
||||
case ',':
|
||||
Parse(g_parser, COMMA, (struct Token){0, 0});
|
||||
break;
|
||||
case '^':
|
||||
Parse(g_parser, XOR, (struct Token){0, 0});
|
||||
break;
|
||||
case '%':
|
||||
Parse(g_parser, REM, (struct Token){0, 0});
|
||||
break;
|
||||
case '+':
|
||||
Parse(g_parser, PLUS, (struct Token){0, 0});
|
||||
break;
|
||||
case '-':
|
||||
Parse(g_parser, MINUS, (struct Token){0, 0});
|
||||
break;
|
||||
case '~':
|
||||
Parse(g_parser, NOT, (struct Token){0, 0});
|
||||
break;
|
||||
case '/':
|
||||
if (s[1] == '/') {
|
||||
Parse(g_parser, DDIV, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, DIV, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
if (s[1] == '*') {
|
||||
Parse(g_parser, EXP, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, MUL, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
if (s[1] == '|') {
|
||||
Parse(g_parser, LOR, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, OR, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '&':
|
||||
if (s[1] == '&') {
|
||||
Parse(g_parser, LAND, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, AND, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
if (s[1] == '=') {
|
||||
Parse(g_parser, NE, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, LNOT, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
if (s[1] == '=') {
|
||||
Parse(g_parser, EQ, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
LexError();
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (s[1] == '=') {
|
||||
Parse(g_parser, GE, (struct Token){0, 0});
|
||||
++n;
|
||||
} else if (s[1] == '>') {
|
||||
Parse(g_parser, SHR, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, GT, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
case '<':
|
||||
if (s[1] == '=') {
|
||||
Parse(g_parser, LE, (struct Token){0, 0});
|
||||
++n;
|
||||
} else if (s[1] == '<') {
|
||||
Parse(g_parser, SHL, (struct Token){0, 0});
|
||||
++n;
|
||||
} else {
|
||||
Parse(g_parser, LT, (struct Token){0, 0});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LexError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
int ec;
|
||||
int fd;
|
||||
size_t n;
|
||||
char *buf;
|
||||
ssize_t rc;
|
||||
size_t bufcap;
|
||||
if (!(ec = setjmp(jb))) {
|
||||
if (argc > 1) {
|
||||
ParseInit(g_parser);
|
||||
bufcap = BIGPAGESIZE;
|
||||
buf = malloc(bufcap);
|
||||
for (i = 1; i < argc; ++i) {
|
||||
g_file = argv[i];
|
||||
g_line = 0;
|
||||
g_column = 0;
|
||||
n = 0; /* wut */
|
||||
if ((fd = open(g_file, O_RDONLY)) == -1) SyscallError("open");
|
||||
for (;;) {
|
||||
if ((rc = read(fd, buf, bufcap)) == -1) SyscallError("read");
|
||||
if (!(n = rc)) break;
|
||||
Tokenize(buf, n);
|
||||
}
|
||||
close(fd);
|
||||
Parse(g_parser, 0, (struct Token){0, 0});
|
||||
}
|
||||
ParseFinalize(g_parser);
|
||||
} else {
|
||||
g_file = "/dev/stdin";
|
||||
g_line = 0;
|
||||
g_column = 0;
|
||||
buf = NULL;
|
||||
bufcap = 0;
|
||||
while (getline(&buf, &bufcap, stdin) != -1) {
|
||||
if ((n = strlen(buf))) {
|
||||
ParseInit(g_parser);
|
||||
if (!setjmp(jb)) {
|
||||
Tokenize("print(", 6);
|
||||
Tokenize(buf, n);
|
||||
Tokenize(")", 1);
|
||||
Parse(g_parser, 0, (struct Token){0, 0});
|
||||
}
|
||||
ParseFinalize(g_parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return ec;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_CALC_CALC_H_
|
||||
#define COSMOPOLITAN_TOOL_CALC_CALC_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct Token {
|
||||
const char *s;
|
||||
size_t n;
|
||||
};
|
||||
|
||||
struct Numbers {
|
||||
struct Numbers *n;
|
||||
long double x;
|
||||
};
|
||||
|
||||
static void SyntaxError(void) wontreturn;
|
||||
static long double ParseNumber(struct Token);
|
||||
static void NumbersFree(struct Numbers *);
|
||||
static struct Numbers *NumbersAppend(struct Numbers *, long double);
|
||||
static long double CallFunction(struct Token, struct Numbers *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_CALC_CALC_H_ */
|
|
@ -1,93 +0,0 @@
|
|||
abs
|
||||
acos
|
||||
asin
|
||||
atan
|
||||
atan2
|
||||
bin
|
||||
bitreverse16
|
||||
bitreverse32
|
||||
bitreverse64
|
||||
bitreverse8
|
||||
bsfl
|
||||
bsfl
|
||||
bsr
|
||||
bsr
|
||||
cbrt
|
||||
ceil
|
||||
copysign
|
||||
cos
|
||||
exp
|
||||
exp10
|
||||
exp2
|
||||
expm1
|
||||
fabs
|
||||
ffs
|
||||
ffsl
|
||||
floor
|
||||
fmax
|
||||
fmin
|
||||
fmod
|
||||
fpclassify
|
||||
gray
|
||||
hex
|
||||
hypot
|
||||
ilogb
|
||||
isfinite
|
||||
isgreater
|
||||
isgreaterequal
|
||||
isinf
|
||||
isless
|
||||
islessequal
|
||||
islessgreater
|
||||
isnan
|
||||
isnormal
|
||||
isunordered
|
||||
ldexp
|
||||
ldexp
|
||||
log
|
||||
log10
|
||||
log1p
|
||||
log2
|
||||
logb
|
||||
lrint
|
||||
lround
|
||||
max
|
||||
min
|
||||
nearbyint
|
||||
oct
|
||||
pow
|
||||
powi
|
||||
print
|
||||
remainder
|
||||
rint
|
||||
rol
|
||||
rolb
|
||||
roll
|
||||
rolq
|
||||
rolw
|
||||
ror
|
||||
rorb
|
||||
rorl
|
||||
rorq
|
||||
rorw
|
||||
round
|
||||
rounddown
|
||||
rounddown2pow
|
||||
roundup
|
||||
roundup2log
|
||||
roundup2pow
|
||||
sar
|
||||
sarb
|
||||
sarl
|
||||
sarq
|
||||
sarw
|
||||
scalb
|
||||
signbit
|
||||
signbit
|
||||
significand
|
||||
sin
|
||||
sqrt
|
||||
tan
|
||||
time
|
||||
trunc
|
||||
ungray
|
|
@ -1,79 +0,0 @@
|
|||
#-*-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───────────────────────┘
|
||||
|
||||
PKGS += TOOL_CALC
|
||||
|
||||
TOOL_CALC = $(TOOL_LIB_A_DEPS) $(TOOL_LIB_A)
|
||||
TOOL_CALC_A = o/$(MODE)/tool/calc/calc.a
|
||||
TOOL_CALC_FILES := $(wildcard tool/calc/*)
|
||||
TOOL_CALC_COMS = $(TOOL_CALC_OBJS:%.o=%.com)
|
||||
TOOL_CALC_SRCS = $(filter %.c,$(TOOL_CALC_FILES))
|
||||
TOOL_CALC_HDRS = $(filter %.h,$(TOOL_CALC_FILES))
|
||||
|
||||
TOOL_CALC_OBJS = \
|
||||
$(TOOL_CALC_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TOOL_CALC_COMS = \
|
||||
$(TOOL_CALC_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TOOL_CALC_BINS = \
|
||||
$(TOOL_CALC_COMS) \
|
||||
$(TOOL_CALC_COMS:%=%.dbg)
|
||||
|
||||
TOOL_CALC_CHECKS = \
|
||||
$(TOOL_CALC_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
TOOL_CALC_DIRECTDEPS = \
|
||||
LIBC_BITS \
|
||||
LIBC_CALLS \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_X \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_GDTOA
|
||||
|
||||
TOOL_CALC_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TOOL_CALC_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(TOOL_CALC_A): \
|
||||
tool/calc/ \
|
||||
$(TOOL_CALC_A).pkg \
|
||||
$(TOOL_CALC_OBJS)
|
||||
|
||||
$(TOOL_CALC_A).pkg: \
|
||||
$(TOOL_CALC_OBJS) \
|
||||
$(foreach x,$(TOOL_CALC_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/tool/calc/calc.h.inc: o/tool/calc/calc.c.inc
|
||||
o/tool/calc/calc.c.inc: \
|
||||
tool/calc/calc.y \
|
||||
$(THIRD_PARTY_LEMON)
|
||||
@$(LEMON) -l -d$(@D) $<
|
||||
|
||||
o/$(MODE)/tool/calc/%.com.dbg: \
|
||||
$(TOOL_CALC_DEPS) \
|
||||
$(TOOL_CALC_A) \
|
||||
o/$(MODE)/tool/calc/%.o \
|
||||
$(TOOL_CALC_A).pkg \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
tool/calc/calc.c: \
|
||||
o/tool/calc/calc.c.inc \
|
||||
o/tool/calc/calc.h.inc
|
||||
|
||||
.PHONY: o/$(MODE)/tool/calc
|
||||
o/$(MODE)/tool/calc: \
|
||||
$(TOOL_CALC_BINS) \
|
||||
$(TOOL_CALC_CHECKS)
|
|
@ -1,79 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ 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 {
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "tool/calc/calc.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/math.h"
|
||||
}
|
||||
|
||||
%token_type {struct Token}
|
||||
%type number {long double}
|
||||
%syntax_error { SyntaxError(); }
|
||||
|
||||
%left LOR.
|
||||
%left LAND.
|
||||
%left OR.
|
||||
%left XOR.
|
||||
%left AND.
|
||||
%left EQ NE.
|
||||
%left LT LE GT GE.
|
||||
%left SHL SHR.
|
||||
%left PLUS MINUS.
|
||||
%left MUL DIV DDIV REM.
|
||||
%right NOT LNOT.
|
||||
%right EXP.
|
||||
|
||||
program ::= number.
|
||||
number(A) ::= NUMBER(B). { A = ParseNumber(B); }
|
||||
number(A) ::= LP number(B) RP. { A = B; }
|
||||
number(A) ::= LNOT number(B). { A = !B; }
|
||||
number(A) ::= NOT number(B). { A = ~(long)B; }
|
||||
number(A) ::= PLUS number(B). { A = +B; } [NOT]
|
||||
number(A) ::= MINUS number(B). { A = -B; } [NOT]
|
||||
number(A) ::= SYMBOL(F) LP numbers(N) RP. { A = CallFunction(F, N); }
|
||||
number(A) ::= number(B) EQ number(C). { A = B == C; }
|
||||
number(A) ::= number(B) NE number(C). { A = B != C; }
|
||||
number(A) ::= number(B) LT number(C). { A = B < C; }
|
||||
number(A) ::= number(B) LE number(C). { A = B <= C; }
|
||||
number(A) ::= number(B) GT number(C). { A = B > C; }
|
||||
number(A) ::= number(B) GE number(C). { A = B >= C; }
|
||||
number(A) ::= number(B) LOR number(C). { A = B || C; }
|
||||
number(A) ::= number(B) LAND number(C). { A = B && C; }
|
||||
number(A) ::= number(B) PLUS number(C). { A = B + C; }
|
||||
number(A) ::= number(B) MINUS number(C). { A = B - C; }
|
||||
number(A) ::= number(B) MUL number(C). { A = B * C; }
|
||||
number(A) ::= number(B) DIV number(C). { A = B / C; }
|
||||
number(A) ::= number(B) REM number(C). { A = remainderl(B, C); }
|
||||
number(A) ::= number(B) EXP number(C). { A = powl(B, C); }
|
||||
number(A) ::= number(B) DDIV number(C). { A = truncl(B / C); }
|
||||
number(A) ::= number(B) OR number(C). { A = (long)B | (long)C; }
|
||||
number(A) ::= number(B) XOR number(C). { A = (long)B ^ (long)C; }
|
||||
number(A) ::= number(B) AND number(C). { A = (long)B & (long)C; }
|
||||
number(A) ::= number(B) SHL number(C). { A = (long)B << (long)C; }
|
||||
number(A) ::= number(B) SHR number(C). { A = (long)B >> (long)C; }
|
||||
|
||||
%type numbers {struct Numbers *}
|
||||
%destructor numbers { NumbersFree($$); }
|
||||
numbers(A) ::= . { A = 0; }
|
||||
numbers(A) ::= number(B). { A = NumbersAppend(0, B); }
|
||||
numbers(A) ::= numbers(A) COMMA number(B). { A = NumbersAppend(A, B); }
|
|
@ -4,7 +4,6 @@
|
|||
.PHONY: o/$(MODE)/tool
|
||||
o/$(MODE)/tool: \
|
||||
o/$(MODE)/tool/build \
|
||||
o/$(MODE)/tool/calc \
|
||||
o/$(MODE)/tool/decode \
|
||||
o/$(MODE)/tool/hash \
|
||||
o/$(MODE)/tool/net \
|
||||
|
|
Loading…
Reference in a new issue