#include #include #ifdef _WIN32 #include #include #else #include #include #endif #if !defined(_WIN32) && !defined(__wasm__) #define VM_TLS _Thread_local #else #define VM_TLS #endif VM_TLS int J; #ifdef _WIN32 static int pk(void){int c=getchar();ungetc(c,stdin);return c==EOF;} char Q(void){int c=getchar();J=pk();return c;} #else /* input is read here, not through stdio, so the end-of-input flag J never blocks. a client that keeps the pipe open (an editor talking to the language server) sends one message and waits for the answer: peeking for the next byte after the last one would wait for a message that comes only after the answer. so J is 1 only when the end is known, and 0 when more may come. the output is flushed before any read that can wait, for the same reason. */ static VM_TLS unsigned char ib[65536]; static VM_TLS int ip, in, ieof; /* make a byte available. wait is 0 to look without waiting. returns 1 when one is ready */ static int fill(int wait) { int n; if (ip < in) return 1; if (ieof) return 0; if (!wait) { struct pollfd f; f.fd = 0; f.events = POLLIN; f.revents = 0; if (poll(&f, 1, 0) <= 0) return 0; /* nothing yet: not the end, not a byte */ } else fflush(stdout); n = (int)read(0, ib, sizeof ib); if (n <= 0) { ieof = 1; return 0; } ip = 0; in = n; return 1; } static int pk(void) { if (ip < in) return 0; if (ieof) return 1; fill(0); return ieof; } char Q(void) { int c; if (!fill(1)) { J = 1; return (char)-1; } c = ib[ip++]; J = pk(); return (char)c; } #endif /* 1 when a byte can be read without waiting: buffered, or already on the pipe */ int input_pending(void) { #ifdef _WIN32 return 0; #else return fill(0); #endif } #ifndef _WIN32 struct IoSnapshot { unsigned char bytes[65536]; int position, count, ended, flag; }; size_t io_context_size(void) { return sizeof(struct IoSnapshot); } void io_context_snapshot(void *destination) { struct IoSnapshot *snapshot = destination; memcpy(snapshot->bytes, ib, sizeof ib); snapshot->position = ip; snapshot->count = in; snapshot->ended = ieof; snapshot->flag = J; } void io_context_restore(const void *source) { const struct IoSnapshot *snapshot = source; memcpy(ib, snapshot->bytes, sizeof ib); ip = snapshot->position; in = snapshot->count; ieof = snapshot->ended; J = snapshot->flag; } #endif void G(char c){putchar(c);} static void init_io(void) { #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY); J = pk(); #else J = pk(); #endif } #if defined(__GNUC__) || defined(__clang__) __attribute__((constructor)) static void init(void) { init_io(); } #elif defined(_MSC_VER) #pragma section(".CRT$XCU", read) static void __cdecl msc_init(void) { init_io(); } __declspec(allocate(".CRT$XCU")) static void (__cdecl *msc_init_fn)(void) = msc_init; #else static void init(void) { init_io(); } #endif