spdxl/src/osic.c

552 wiersze
8.9 KiB
C

/*
* dxlAPRS toolchain
*
* Copyright (C) Hannes Schmelzer <oe5hpm@oevsv.at>
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include <errno.h>
#include "osic.h"
#undef DEBUG
#ifdef DEBUG
# define DBG(...) printf(__VA_ARGS__)
#else
# define DBG(...) do { } while (0)
#endif
#define FNLENCHECK 1
/* Does not exist - and is not necessary - on MacOS */
#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
static int osic_argc, argc_delivered;
static char **osic_argv;
void osic_flush(void)
{
fflush(stdout);
fflush(stderr);
}
void osic_WrLn(void)
{
fprintf(stdout, "\n");
fflush(stdout);
}
void osic_WerrLn(void)
{
fprintf(stderr, "\n");
fflush(stderr);
}
void osic_WrStr(char s[], uint32_t s_len)
{
size_t len;
len = strnlen(s, s_len);
fprintf(stdout, "%.*s", len, s);
}
void osic_WrStrLn(char s[], uint32_t s_len)
{
size_t len;
len = strnlen(s, s_len);
fprintf(stdout, "%.*s", len, s);
osic_WrLn();
}
void osic_WerrStr(char s[], uint32_t s_len)
{
size_t len;
len = strnlen(s, s_len);
fprintf(stderr, "%.*s", len, s);
}
void osic_WerrStrLn(char s[], uint32_t s_len)
{
size_t len;
len = strnlen(s, s_len);
fprintf(stderr, "%.*s", len, s);
osic_WrLn();
}
void osic_WrUINT32(uint32_t x, uint32_t witdh)
{
fprintf(stdout, "%*d", (int)witdh, x);
}
void osic_WrINT32(int32_t x, uint32_t witdh)
{
fprintf(stdout, "%*d", (int)witdh, x);
}
void osic_WrFixed(float x, int32_t place, uint32_t witdh)
{
fprintf(stdout, "%*.*f", (int)witdh, (int)place, x);
}
void osic_WrHex(uint32_t n, uint32_t f)
{
fprintf(stdout, "%*X", (int)f, (uint32_t)n);
fflush(stdout);
}
int osic_getptsname(int fd, char *name, int len)
{
#ifndef MACOS
return ptsname_r(fd, name, len);
#else
{
/* MacOS does not have ptsname_r, emulate it with ptsname */
if (name == NULL)
return -EINVAL;
char *n = ptsname(fd);
if (n == NULL)
return -ENOTTY;
if (len < strlen(n))
return -ERANGE;
strncpy(name, n, len);
return 0;
}
#endif
}
int osic_grantpts(int fd)
{
return grantpt(fd);
}
int osic_unlockpts(int fd)
{
return unlockpt(fd);
}
int32_t osic_OpenAppendLong(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_WRONLY | O_APPEND | O_LARGEFILE);
}
int32_t osic_OpenAppend(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_WRONLY | O_APPEND);
}
int32_t osic_OpenWrite(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return creat(fn, 0664);
}
int32_t osic_OpenReadLong(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_RDONLY | O_LARGEFILE);
}
int32_t osic_OpenRead(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_RDONLY);
}
int32_t osic_OpenRW(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_RDWR);
}
int32_t osic_OpenNONBLOCK(char fn[], uint32_t fn_len)
{
if (FNLENCHECK && strnlen(fn, fn_len) > fn_len)
return -1;
return open(fn, O_RDWR | O_NONBLOCK);
}
char osic_FdValid(int32_t fd)
{
return (fd >= 0);
}
void osic_Close(int32_t fd)
{
close(fd);
}
void osic_CloseSock(int32_t fd)
{
close(fd);
}
int32_t osic_RdBin(int32_t fd, char buf[], uint32_t buf_len, uint32_t size)
{
if (size > buf_len)
size = buf_len;
return read(fd, (char *)buf, size);
}
void osic_WrBin(int32_t fd, char buf[], uint32_t buf_len, uint32_t size)
{
int rc;
if (size > buf_len)
size = buf_len;
rc = write(fd, (char *)buf, size);
(void)rc;
}
void osic_Rename(char fname[], uint32_t fname_len,
char newname[], uint32_t newname_len)
{
if (FNLENCHECK && strnlen(fname, fname_len) >= fname_len)
return;
if (FNLENCHECK && strnlen(newname, newname_len) >= newname_len)
return;
rename(fname, newname);
}
int osic_Size(int fd)
{
struct stat st = { };
fstat(fd, &st);
return st.st_size;
}
void osic_Seek(int32_t fd, uint32_t pos)
{
lseek(fd, (int32_t)pos, SEEK_SET);
}
void osic_Seekcur(int32_t fd, int32_t rel)
{
#ifndef MACOS
if (lseek64(fd, rel, (uint32_t)SEEK_CUR) < 0)
lseek(fd, 0, SEEK_SET);
#else
/* MacOS has no lseek64 */
if (lseek(fd, rel, (uint32_t)SEEK_CUR) < 0)
lseek(fd, 0, SEEK_SET);
#endif
}
void osic_Remove(char fname[], uint32_t fname_len, char *done)
{
int rc;
rc = remove(fname);
if (rc == 0)
*done = 1;
else
*done = 0;
}
char osic_Exists(char fname[], uint32_t fname_len)
{
if (access(fname, F_OK) != -1)
return 1;
return 0;
}
int osic_symblink(char *existing, char *newname)
{
return symlink(existing, newname);
}
void osic_NextArg(char s[], uint32_t s_len)
{
if (argc_delivered >= osic_argc-1) {
s[0] = 0;
return;
}
strncpy(s, osic_argv[argc_delivered+1], s_len);
argc_delivered++;
}
void osic_Fill(char *buf, uint32_t len, char byte)
{
memset(buf, byte, len);
}
double osic_Random(void)
{
return (rand() / (double)RAND_MAX);
}
void X2C_BEGIN(int *argc, char *argv[],
int gc_auto, int32_t gc_threshold, int32_t heap_limit)
{
if (osic_argc != 0)
return;
osic_argc = *argc;
osic_argv = argv;
}
void X2C_PCOPY(void **ppcpy, size_t size)
{
void *pnew;
pnew = malloc(size);
if (pnew == NULL)
return;
memcpy(pnew, *ppcpy, size);
*ppcpy = pnew;
}
int32_t X2C_TRUNCI(double x, int32_t min0, int32_t max0)
{
int32_t i;
if (x < (double)min0 || x > (double)max0)
assert(0);
i = (int32_t)x;
if (x > 0.0) {
if ((double)i > x)
--i;
} else if ((double)i < x) {
++i;
}
return i;
}
uint32_t X2C_TRUNCC(double x, uint32_t min0, uint32_t max0)
{
uint32_t i;
if (x < (double)min0)
i = (uint32_t)min0;
if (x > (double)max0)
i = (uint32_t)max0;
i = (uint32_t)x;
if ((double)i > x)
--i;
return i;
}
float osic_cos(float x)
{
return cos(x);
}
float osic_ln(float x)
{
if (x <= 0.0)
assert(0);
return log(x);
}
float osic_sqrt(float x)
{
if (x < 0.0)
assert(0);
return sqrt(x);
}
float osic_sin(float x)
{
return sin(x);
}
float osic_arctan(float x)
{
return atan(x);
}
float osic_tan(float x)
{
return tan(x);
}
float osic_exp(float x)
{
return exp(x);
}
float osic_power(float base, float exponent)
{
if (base <= 0.0)
assert(0);
return pow(base, exponent);
}
float osic_arccos(float x)
{
return acos(x);
}
float osic_floor(float x)
{
return floorf(x);
}
void osic_alloc(X2C_ADDRESS *p, uint32_t size)
{
void *pmem;
pmem = malloc(size);
if (pmem == NULL)
return;
*p = pmem;
}
void osic_free(X2C_ADDRESS *a, uint32_t size)
{
assert(*a);
free(*a);
}
uint32_t osic_time(void)
{
return time(NULL);
}
uint32_t X2C_LSH(uint32_t a, int32_t length, int32_t n)
{
uint32_t m;
m = 0;
m = (length == 32) ? 0xFFFFFFFFl : (1 << length) - 1;
if (n > 0) {
if (n >= (int32_t)length)
return 0;
return (a << n) & m;
}
if (n <= (int32_t)-length)
return 0;
return (a >> -n) & m;
}
char X2C_IN(uint32_t i, uint32_t bits, uint32_t set)
{
if (i < bits)
return (((1 << (int)i) & set) != 0);
return 0;
}
char X2C_INL(uint32_t i, uint32_t bits, uint32_t *set)
{
if (i < bits)
return (set[(int)i / X2C_LSET_SIZE] & (1 << ((int)i % X2C_LSET_SIZE))) != 0;
return 0;
}
void X2C_INCL(uint32_t *set, uint32_t i, uint32_t bits)
{
if (i >= bits)
assert(0);
set[(int)i / X2C_LSET_SIZE] |= 1L << ((int)i % X2C_LSET_SIZE);
}
void X2C_EXCL(uint32_t *set, uint32_t i, uint32_t bits)
{
if (i >= bits)
assert(0);
set[(int)i / X2C_LSET_SIZE] &= ~(1L << ((int)i % X2C_LSET_SIZE));
}
uint32_t *X2C_COMPLEMENT(uint32_t *res, uint32_t *a, uint32_t length)
{
uint32_t *pres = res;
while (length--)
*res++ = ~(*a++);
return pres;
}
struct xrMM_Dynarr {
char *a;
size_t n[15];
};
size_t xrMM_DynarrDescSize(size_t i)
{
return (sizeof(char *) + i * sizeof(size_t) * 2);
}
void X2C_InitDesc(struct xrMM_Dynarr *d, size_t *size, size_t lens[], size_t dims)
{
uint32_t i;
uint32_t tmp;
d->n[(dims - 1) * 2] = lens[0];
tmp = dims - 1;
i = 1;
if (i <= tmp) {
for (;; i++) {
*size = *size * lens[dims-i];
d->n[i * 2 - 1] = *size;
d->n[(dims - i) * 2 - 2] = lens[i];
if (i == tmp)
break;
}
}
*size = *size*lens[0];
}
void X2C_DYNALLOCATE(char **a, size_t size, size_t lens[], size_t dims)
{
struct xrMM_Dynarr *desc;
*a = 0;
desc = malloc(xrMM_DynarrDescSize(dims));
if (desc) {
X2C_InitDesc(desc, &size, lens, dims);
desc->a = malloc(size);
if (desc->a == 0) {
free(desc);
} else {
DBG("%s: %p (%d bytes) with child %p (%d bytes)\n",
__func__, desc, xrMM_DynarrDescSize(dims),
desc->a, size);
*a = (char *)desc;
}
}
}
void X2C_DYNDEALLOCATE(char **a)
{
struct xrMM_Dynarr *d;
if (*a) {
d = (struct xrMM_Dynarr *)*a;
DBG("%s: have %p with child %p\n", __func__, d, d->a);
free(d->a);
free(d);
}
}
void *osic_chkptr(void *p)
{
assert(p);
return p;
}