mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-01 09:49:24 +03:00
commit
6143508f7b
@ -1,13 +1,18 @@
|
||||
#include "idris_directory.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "idris_util.h"
|
||||
|
||||
char* idris2_currentDirectory() {
|
||||
char* cwd = malloc(1024); // probably ought to deal with the unlikely event of this being too small
|
||||
IDRIS2_VERIFY(cwd, "malloc failed");
|
||||
return getcwd(cwd, 1024); // Freed by RTS
|
||||
}
|
||||
|
||||
@ -34,6 +39,7 @@ void* idris2_openDir(char* dir) {
|
||||
return NULL;
|
||||
} else {
|
||||
DirInfo* di = malloc(sizeof(DirInfo));
|
||||
IDRIS2_VERIFY(di, "malloc failed");
|
||||
di->dirptr = d;
|
||||
di->error = 0;
|
||||
|
||||
@ -44,7 +50,7 @@ void* idris2_openDir(char* dir) {
|
||||
void idris2_closeDir(void* d) {
|
||||
DirInfo* di = (DirInfo*)d;
|
||||
|
||||
closedir(di->dirptr);
|
||||
IDRIS2_VERIFY(closedir(di->dirptr) == 0, "closedir failed: %s", strerror(errno));
|
||||
free(di);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include "getline.h"
|
||||
#include "idris_file.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -15,6 +16,8 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include "idris_util.h"
|
||||
|
||||
FILE* idris2_openFile(char* name, char* mode) {
|
||||
#ifdef _WIN32
|
||||
FILE *f = win32_u8fopen(name, mode);
|
||||
@ -25,7 +28,7 @@ FILE* idris2_openFile(char* name, char* mode) {
|
||||
}
|
||||
|
||||
void idris2_closeFile(FILE* f) {
|
||||
fclose(f);
|
||||
IDRIS2_VERIFY(fclose(f) == 0, "fclose failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
int idris2_fileError(FILE* f) {
|
||||
@ -90,10 +93,11 @@ void *idris2_popen(const char *cmd, const char *mode) {
|
||||
|
||||
void idris2_pclose(void *stream) {
|
||||
#ifdef _WIN32
|
||||
_pclose(stream);
|
||||
int r = _pclose(stream);
|
||||
#else
|
||||
pclose(stream);
|
||||
int r = pclose(stream);
|
||||
#endif
|
||||
IDRIS2_VERIFY(r != -1, "pclose failed");
|
||||
}
|
||||
|
||||
// seek through the next newline, consuming and
|
||||
|
@ -1,15 +1,13 @@
|
||||
#include "idris_memory.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "idris_util.h"
|
||||
|
||||
void* idris2_malloc(int size) {
|
||||
if (size < 0) {
|
||||
fprintf(stderr, "malloc negative argument: %d\n", size);
|
||||
abort();
|
||||
}
|
||||
IDRIS2_VERIFY(size >= 0, "malloc negative argument: %d", size);
|
||||
|
||||
if (size == 0) {
|
||||
// Do not depend on platform-speific behavior of malloc.
|
||||
@ -17,10 +15,7 @@ void* idris2_malloc(int size) {
|
||||
}
|
||||
|
||||
void* ptr = malloc(size);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "malloc failed: %s\n", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
IDRIS2_VERIFY(ptr, "malloc failed: %s", strerror(errno));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "idris_util.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
@ -1,11 +1,14 @@
|
||||
#include "idris_signal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "idris_util.h"
|
||||
|
||||
static_assert(ATOMIC_LONG_LOCK_FREE == 2,
|
||||
"when not lock free, atomic functions are not async-signal-safe");
|
||||
@ -14,20 +17,14 @@ static_assert(ATOMIC_LONG_LOCK_FREE == 2,
|
||||
static atomic_long signal_count[N_SIGNALS];
|
||||
|
||||
void _collect_signal(int signum) {
|
||||
if (signum < 0 || signum >= N_SIGNALS) {
|
||||
abort();
|
||||
}
|
||||
IDRIS2_VERIFY(signum >= 0 && signum < N_SIGNALS, "signal number out of range: %d", signum);
|
||||
|
||||
long prev = atomic_fetch_add(&signal_count[signum], 1);
|
||||
if (prev == LONG_MAX) {
|
||||
// Practically impossible, but better crash explicitly
|
||||
fprintf(stderr, "signal count overflow\n");
|
||||
abort();
|
||||
}
|
||||
IDRIS2_VERIFY(prev != LONG_MAX, "signal count overflow");
|
||||
|
||||
#ifdef _WIN32
|
||||
//re-instate signal handler
|
||||
signal(signum, _collect_signal);
|
||||
IDRIS2_VERIFY(signal(signum, _collect_signal) != SIG_ERR, "signal failed: %s", strerror(errno));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -77,11 +74,7 @@ int handle_next_collected_signal() {
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
if (count < 0) {
|
||||
// Practically impossible, but better crash explicitly
|
||||
fprintf(stderr, "signal count overflow\n");
|
||||
abort();
|
||||
}
|
||||
IDRIS2_VERIFY(count >= 0, "signal count overflow");
|
||||
if (atomic_compare_exchange_strong(&signal_count[signum], &count, count - 1)) {
|
||||
return signum;
|
||||
}
|
||||
|
@ -68,6 +68,8 @@ void idris2_sleep(int sec) {
|
||||
t.tv_sec = sec;
|
||||
t.tv_nsec = 0;
|
||||
|
||||
// TODO: `nanosleep` can fail
|
||||
// TODO: `nanosleep` can return early due to interrupt
|
||||
nanosleep(&t, NULL);
|
||||
#endif
|
||||
}
|
||||
|
16
support/c/idris_util.c
Normal file
16
support/c/idris_util.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "idris_util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void idris2_verify_failed(const char* file, int line, const char* cond, const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
char message[1000];
|
||||
snprintf(message, sizeof(message), fmt, ap);
|
||||
|
||||
fprintf(stderr, "assertion failed in %s:%d: %s: %s\n", file, line, cond, message);
|
||||
abort();
|
||||
}
|
20
support/c/idris_util.h
Normal file
20
support/c/idris_util.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdnoreturn.h>
|
||||
|
||||
// Utilities used by FFI code.
|
||||
|
||||
// Crash is the condition is false.
|
||||
#define IDRIS2_VERIFY(cond, ...) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
idris2_verify_failed(__FILE__, __LINE__, #cond, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Used by `IDRIS2_VERIFY`, do not use directly.
|
||||
noreturn void idris2_verify_failed(const char* file, int line, const char* cond, const char* fmt, ...)
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
__attribute__ ((format(printf, 4, 5)))
|
||||
#endif
|
||||
;
|
Loading…
Reference in New Issue
Block a user