Idris2/support/c/idris_support.c

182 lines
3.7 KiB
C
Raw Normal View History

2020-05-18 16:51:10 +03:00
#include "idris_support.h"
#include "idris_file.h"
#include <errno.h>
#include <stdio.h>
2020-06-16 13:53:36 +03:00
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <termios.h>
#endif
2022-09-21 13:13:15 +03:00
#include <time.h>
#include <unistd.h>
2020-05-18 16:51:10 +03:00
2024-03-21 15:32:37 +03:00
#if !defined(_SC_NPROCESSORS_ONLN) && defined(_DARWIN_C_SOURCE)
#include <sys/sysctl.h>
#include <sys/types.h>
#endif
2021-05-17 16:07:53 +03:00
int _argc;
char **_argv;
2020-05-19 14:11:07 +03:00
#ifdef _WIN32
extern char **_environ;
#include "windows/win_utils.h"
2020-05-19 14:11:07 +03:00
#define environ _environ
#elif defined(__APPLE__)
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
2020-05-19 14:11:07 +03:00
#else
2022-09-21 13:13:15 +03:00
extern char **environ;
2020-05-19 14:11:07 +03:00
#endif
2020-05-18 16:51:10 +03:00
2022-09-21 13:13:15 +03:00
int idris2_isNull(void *ptr) { return (ptr == NULL); }
2020-05-18 16:51:10 +03:00
2022-09-21 13:13:15 +03:00
void *idris2_getNull() { return NULL; }
2022-09-21 13:13:15 +03:00
char *idris2_getString(void *p) { return (char *)p; }
2020-05-18 16:51:10 +03:00
int idris2_getErrno() {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
return win32_getErrno();
#else
2022-09-21 13:13:15 +03:00
return errno;
#endif
2020-05-18 16:51:10 +03:00
}
2022-09-21 13:13:15 +03:00
char *idris2_strerror(int errnum) { return strerror(errnum); }
2022-09-21 13:13:15 +03:00
char *idris2_getStr() {
char *inp = idris2_readLine(stdin);
// Remove trailing newline; easier to do this than in PrimIO which
// doesn't have the relevant functions available yet
for (char *c = inp; *c != '\0'; ++c) {
if (*c == '\n' || *c == '\r') {
*c = '\0';
2020-05-18 16:51:10 +03:00
}
2022-09-21 13:13:15 +03:00
}
return inp;
2020-05-18 16:51:10 +03:00
}
2022-09-21 13:13:15 +03:00
void idris2_putStr(char *f) { idris2_writeLine(stdout, f); }
2020-05-18 16:51:10 +03:00
void idris2_sleep(int sec) {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
win32_sleep(sec * 1000);
#else
2022-09-21 13:13:15 +03:00
struct timespec t;
t.tv_sec = sec;
t.tv_nsec = 0;
2020-05-18 16:51:10 +03:00
2022-09-21 13:13:15 +03:00
// TODO: `nanosleep` can fail
// TODO: `nanosleep` can return early due to interrupt
nanosleep(&t, NULL);
#endif
2020-05-18 16:51:10 +03:00
}
void idris2_usleep(int usec) {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
win32_sleep(usec / 1000);
#else
2022-09-21 13:13:15 +03:00
struct timespec t;
t.tv_sec = usec / 1000000;
t.tv_nsec = (usec % 1000000) * 1000;
2020-05-18 16:51:10 +03:00
2022-09-21 13:13:15 +03:00
nanosleep(&t, NULL);
#endif
2020-05-18 16:51:10 +03:00
}
int idris2_time() {
2022-09-21 13:13:15 +03:00
return time(NULL); // RTS needs to have 32 bit integers at least
2020-05-18 16:51:10 +03:00
}
2021-05-17 16:07:53 +03:00
void idris2_setArgs(int argc, char *argv[]) {
2022-09-21 13:13:15 +03:00
_argc = argc;
_argv = argv;
2021-05-17 16:07:53 +03:00
}
2022-09-21 13:13:15 +03:00
int idris2_getArgCount() { return _argc; }
2021-05-17 16:07:53 +03:00
2022-09-21 13:13:15 +03:00
char *idris2_getArg(int n) { return _argv[n]; }
2021-05-17 16:07:53 +03:00
2022-09-21 13:13:15 +03:00
char *idris2_getEnvPair(int i) { return *(environ + i); }
2020-06-16 13:09:22 +03:00
int idris2_setenv(const char *name, const char *value, int overwrite) {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
return win32_modenv(name, value, overwrite);
2020-06-16 13:09:22 +03:00
#else
2022-09-21 13:13:15 +03:00
return setenv(name, value, overwrite);
2020-06-16 13:09:22 +03:00
#endif
}
#ifndef _WIN32
// The initial state of stdin is stored here if enableRawMode is called.
struct termios *initial_termios = NULL;
#endif
int idris2_enableRawMode() {
#ifndef _WIN32
struct termios ti;
int rval = tcgetattr(STDIN_FILENO, &ti);
if (rval != 0)
return rval;
if (!initial_termios) {
initial_termios = malloc(sizeof(struct termios));
*initial_termios = ti;
}
ti.c_lflag &= ~(ECHO | ICANON);
return tcsetattr(STDIN_FILENO, TCSAFLUSH, &ti);
#else
return -1;
#endif
}
void idris2_resetRawMode() {
#ifndef _WIN32
if (initial_termios != NULL) {
tcsetattr(STDIN_FILENO, TCSAFLUSH, initial_termios);
}
#endif
}
2020-06-16 13:09:22 +03:00
int idris2_unsetenv(const char *name) {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
return win32_modenv(name, "", 1);
2020-06-16 13:09:22 +03:00
#else
2022-09-21 13:13:15 +03:00
return unsetenv(name);
2020-06-16 13:09:22 +03:00
#endif
}
2021-05-25 18:45:46 +03:00
int idris2_getPID() {
#ifdef _WIN32
2022-09-21 13:13:15 +03:00
return win32_getPID();
2021-05-25 18:45:46 +03:00
#else
2022-09-21 13:13:15 +03:00
return getpid();
2021-05-25 18:45:46 +03:00
#endif
}
// get the number of processors configured
long idris2_getNProcessors() {
2024-03-21 15:32:37 +03:00
#if defined(_WIN32)
2022-09-21 13:13:15 +03:00
return win32_getNProcessors();
2024-03-21 15:32:37 +03:00
#elif defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L && \
defined(_SC_NPROCESSORS_ONLN)
// Note: Under MacOS with _POSIX_C_SOURCE, _SC_NPROCESSORS_ONLN never defined.
return sysconf(_SC_NPROCESSORS_ONLN);
2024-03-21 15:32:37 +03:00
#elif defined(_DARWIN_C_SOURCE) || defined(_BSD_SOURCE)
// Generic way for BSD style system.
#if defined(_DARWIN_C_SOURCE)
int xs[] = {CTL_HW, HW_LOGICALCPU};
#else
int xs[] = {CTL_HW, HW_NCPU};
#endif
int numcpus = 1;
size_t n = sizeof(numcpus);
return sysctll(xs, 2, &numcpus, &len, NULL, 0) < 0 ? 1 : numcpus;
#else
return 1
#endif
}