#include "system.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include "pmath.h"
#ifndef M_PI
// some math.h do not have M_PI macros
# define M_PI 3.14159265358979323846 /* pi */
# define M_PI_2 1.57079632679489661923 /* pi/2 */
# define M_PI_4 0.78539816339744830962 /* pi/4 */
# define M_PIl 3.1415926535897932384626433832795029L /* pi */
# define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */
# define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */
#endif
double pi = M_PI;
int paramCount;
string255 params[MAX_PARAMS];
string255 fpcrtl_copy(string255 s, Integer index, Integer count) {
string255 result = STRINIT("");
if (count < 1) {
return result;
}
if (index < 1) {
index = 1;
}
if (index > s.len) {
return result;
}
if (index + count > s.len + 1) {
count = s.len + 1 - index;
}
memcpy(result.str, s.str + index - 1, count);
result.len = count;
return result;
}
astring fpcrtl_copyA(astring s, Integer index, Integer count) {
astring result;
result.len = 0;
if (count < 1) {
return result;
}
if (index < 1) {
index = 1;
}
if (index > s.len) {
return result;
}
if (index + count > s.len + 1) {
count = s.len + 1 - index;
}
memcpy(result.s + 1, s.s + index, count);
result.len = count;
return result;
}
void __attribute__((overloadable)) fpcrtl_insert__vars(string255 *src, string255 *dst, SizeInt index) {
int num_insert;
int num_shift;
int num_preshift;
// nothing to do if empty string is inserted or index invalid
if ((src->len == 0) || (index < 1) || (index > 255)) {
return;
}
num_insert = src->len;
// number of chars from start of destination string to end of insertion
num_preshift = index - 1 + num_insert;
// don't overflow on insert
if (num_preshift > 255) {
num_preshift = 255;
num_insert = 255 - (index - 1);
num_shift = 0;
}
// shift trailing chars
else {
// number of bytes to be shifted
num_shift = dst->len - (index - 1);
if (num_shift > 0) {
// don't overflow when shifting
if (num_shift + num_preshift > 255)
num_shift = 255 - num_preshift;
// time to move some bytes!
memmove(dst->str + num_preshift, dst->str + index - 1, num_shift);
}
}
// actual byte insertion
memmove(dst->str + index - 1, src->str, num_insert);
// store new length
dst->len = num_shift + num_preshift;
}
void __attribute__((overloadable)) fpcrtl_insert__vars(astring *src, astring *dst, SizeInt index) {
int num_insert;
int num_shift;
int num_preshift;
// nothing to do if empty string is inserted or index invalid
if ((src->len == 0) || (index < 1) || (index > MAX_ANSISTRING_LENGTH)) {
return;
}
num_insert = src->len;
// number of chars from start of destination string to end of insertion
num_preshift = index - 1 + num_insert;
// don't overflow on insert
if (num_preshift > MAX_ANSISTRING_LENGTH) {
num_preshift = MAX_ANSISTRING_LENGTH;
num_insert = MAX_ANSISTRING_LENGTH - (index - 1);
num_shift = 0;
}
// shift trailing chars
else {
// number of bytes to be shifted
num_shift = dst->len - (index - 1);
if (num_shift > 0) {
// don't overflow when shifting
if (num_shift + num_preshift > MAX_ANSISTRING_LENGTH)
num_shift = MAX_ANSISTRING_LENGTH - num_preshift;
// time to move some bytes!
memmove(dst->str + num_preshift, dst->str + index - 1, num_shift);
}
}
// actual byte insertion
memmove(dst->str + index - 1, src->str, num_insert);
// store new length
dst->len = num_shift + num_preshift;
}
void __attribute__((overloadable)) fpcrtl_delete__vars(string255 *s, SizeInt index, SizeInt count) {
// number of chars to be move
int num_move;
int new_length;
if (index < 1) {
// in fpc, if index < 1, the string won't be modified
return;
}
if(index > s->len){
return;
}
if (count > s->len - index + 1) {
s->len = index - 1;
return;
}
num_move = s->len - index + 1 - count;
new_length = s->len - count;
memmove(s->str + index - 1, s->str + index - 1 + count, num_move);
s->str[new_length] = 0;
s->len = new_length;
}
void __attribute__((overloadable)) fpcrtl_delete__vars(astring *s, SizeInt index, SizeInt count) {
// number of chars to be move
int num_move;
int new_length;
if (index < 1) {
// in fpc, if index < 1, the string won't be modified
return;
}
if(index > s->len){
return;
}
if (count > s->len - index + 1) {
s->len = index - 1;
return;
}
num_move = s->len - index + 1 - count;
new_length = s->len - count;
memmove(s->s + index, s->s + index + count, num_move);
s->len = new_length;
}
string255 fpcrtl_floatToStr(double n) {
string255 t;
t.len = sprintf(t.str, "%f", n);
return t;
}
void fpcrtl_move__vars(void *src, void *dst, SizeInt count) {
memmove(dst, src, count);
}
Integer __attribute__((overloadable)) fpcrtl_pos(Char c, string255 str) {
unsigned char* p;
if (str.len == 0) {
return 0;
}
FIX_STRING(str);
p = strchr(str.str, c);
if (p == NULL) {
return 0;
}
return p - (unsigned char*)&str.s;
}
Integer __attribute__((overloadable)) fpcrtl_pos(string255 substr, string255 str) {
unsigned char* p;
if (str.len == 0) {
return 0;
}
if (substr.len == 0) {
return 0;
}
FIX_STRING(substr);
FIX_STRING(str);
p = strstr(str.str, substr.str);
if (p == NULL) {
return 0;
}
return p - (unsigned char*)&str.s;
}
Integer __attribute__((overloadable)) fpcrtl_pos(Char c, astring str) {
unsigned char* p;
if (str.len == 0) {
return 0;
}
FIX_STRINGA(str);
p = strchr(str.str, c);
if (p == NULL) {
return 0;
}
return p - (unsigned char*)&str.s;
}
Integer __attribute__((overloadable)) fpcrtl_pos(string255 substr, astring str) {
unsigned char* p;
if (str.len == 0) {
return 0;
}
if (substr.len == 0) {
return 0;
}
FIX_STRING(substr);
FIX_STRINGA(str);
p = strstr(str.str, substr.str);
if (p == NULL) {
return 0;
}
return p - (unsigned char *)&str.s;
}
Integer fpcrtl_length(string255 s) {
return s.len;
}
Integer fpcrtl_lengthA(astring s)
{
return s.len;
}
string255 fpcrtl_lowerCase(string255 s) {
int i;
for (i = 0; i < s.len; i++) {
if (s.str[i] >= 'A' && s.str[i] <= 'Z') {
s.str[i] += 'a' - 'A';
}
}
return s;
}
void fpcrtl_fillChar__vars(void *x, SizeInt count, Byte value) {
memset(x, value, count);
}
void fpcrtl_new__vars(void **p, int size) {
*p = malloc(size);
}
Int64 fpcrtl_trunc(extended n) {
return (Int64) n;
}
Integer fpcrtl_ceil(extended n) {
return (Integer) (ceil(n));
}
LongInt str_to_int(char *src)
{
int i;
char *end;
for(i = 0; src[i]; i++)
{
if(src[i] == '$'){
// hex
return strtol(src + i + 1, &end, 16);
}
}
// decimal
return atoi(src);
}
void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, LongInt *a)
{
FIX_STRING(s);
*a = str_to_int(s.str);
}
void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, Byte *a)
{
FIX_STRING(s);
*a = str_to_int(s.str);
}
void __attribute__((overloadable)) fpcrtl_val__vars(string255 s, LongWord *a)
{
FIX_STRING(s);
*a = str_to_int(s.str);
}
LongInt fpcrtl_random(LongInt l) {
// random(0) is undefined in docs but effectively returns 0 in free pascal
if (l == 0) {
//printf("WARNING: random(0) called!\n");
return 0;
}
return (LongInt) (rand() / (double) RAND_MAX * l);
}
void __attribute__((overloadable)) fpcrtl_str__vars(float x, string255 *s) {
s->len = sprintf(s->str, "%f", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(double x, string255 *s) {
s->len = sprintf(s->str, "%f", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(uint8_t x, string255 *s) {
s->len = sprintf(s->str, "%u", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(int8_t x, string255 *s) {
s->len = sprintf(s->str, "%d", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(uint16_t x, string255 *s) {
s->len = sprintf(s->str, "%u", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(int16_t x, string255 *s) {
s->len = sprintf(s->str, "%d", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(uint32_t x, string255 *s) {
s->len = sprintf(s->str, "%u", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(int32_t x, string255 *s) {
s->len = sprintf(s->str, "%d", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(uint64_t x, string255 *s) {
s->len = sprintf(s->str, "%llu", x);
}
void __attribute__((overloadable)) fpcrtl_str__vars(int64_t x, string255 *s) {
s->len = sprintf(s->str, "%lld", x);
}
/*
* XXX No protection currently!
*/
void fpcrtl_interlockedIncrement__vars(int *i) {
(*i)++;
}
void fpcrtl_interlockedDecrement__vars(int *i) {
(*i)--;
}
/*
* This function should be called when entering main
*/
void fpcrtl_init(int argc, char** argv) {
int i;
paramCount = argc;
printf("ARGC = %d\n", paramCount);
for (i = 0; i < argc; i++) {
if (strlen(argv[i]) > 255) {
assert(0);
}
strcpy(params[i].str, argv[i]);
params[i].len = strlen(params[i].str);
}
}
int fpcrtl_paramCount() {
return paramCount - 1; // ignore the first one
}
string255 fpcrtl_paramStr(int i) {
return params[i];
}
int fpcrtl_UTF8ToUnicode(PWideChar dest, PChar src, SizeInt maxLen) {
//return swprintf(dest, maxLen, L"%hs", "src"); //doesn't work in emscripten
return 0;
}
uint32_t __attribute__((overloadable)) fpcrtl_lo(uint64_t i) {
return (i & 0xFFFFFFFF);
}