Quantum/lib/hack.c

351 lines
8.9 KiB
C
Raw Permalink Normal View History

2023-12-16 16:17:02 +01:00
#include "libwasm.h"
size_t strlen (const char *s) {
size_t l = 0;
while (*s++) l++;
return l;
}
char *strncpy (char *dst0, const char *src0, size_t count) {
char *dscan;
const char *sscan;
dscan = dst0;
sscan = src0;
while (count > 0) {
--count;
if ((*dscan++ = *sscan++) == '\0')
break;
}
while (count-- > 0)
*dscan++ = '\0';
return dst0;
}
int strncmp (const char *s1, const char *s2, size_t n) {
if (n == 0) return 0;
while (n-- != 0 && *s1 == *s2) {
if (n == 0 || *s1 == '\0') break;
s1++;
s2++;
}
return (* (unsigned char *) s1) - (* (unsigned char *) s2);
}
int strcmp (const char *s1, const char *s2) {
while (*s1 != '\0' && *s1 == *s2) {
s1++;
s2++;
}
return (* (unsigned char *) s1) - (* (unsigned char *) s2);
}
void *memcpy (void *dest, const void *src, size_t n) {
const char *s = (const char *) src;
char *d = (char *) dest;
int i;
for (i=0; i<n; i++) d[i] = s[i];
return dest;
}
void *memset (void *s, int c, size_t n) {
char *p = (char *) s;
int i;
for (i=0; i<n; i++) p[i] = c;
return s;
}
char *strtok (char *s, const char *delim) {
static char *lasts[1];
register char *spanp;
register int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *) delim; (sc = *spanp++) != 0;) {
if (c == sc) {
if (/*skip_leading_delim*/ 1) {
goto cont;
} else {
*lasts = s;
s[-1] = 0;
return (s - 1);
}
}
}
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *) delim;
do {
if ( (sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
/* *************************************************************/
//------------------------------------------------------------------------------
/// Writes a character inside the given string. Returns 1.
/// \param pStr Storage string.
/// \param c Character to write.
//------------------------------------------------------------------------------
static signed int PutChar (char *pStr, char c) {
*pStr = c;
return 1;
}
//------------------------------------------------------------------------------
/// Writes a string inside the given string.
/// Returns the size of the written
/// string.
/// \param pStr Storage string.
/// \param pSource Source string.
//------------------------------------------------------------------------------
static signed int PutString (char *pStr, const char *pSource) {
signed int num = 0;
while (*pSource != 0) {
*pStr++ = *pSource++;
num++;
}
return num;
}
//------------------------------------------------------------------------------
/// Writes an unsigned int inside the given string, using the provided fill &
/// width parameters.
/// Returns the size in characters of the written integer.
/// \param pStr Storage string.
/// \param fill Fill character.
/// \param width Minimum integer width.
/// \param value Integer value.
//------------------------------------------------------------------------------
static signed int PutUnsignedInt (
char *pStr,
char fill,
signed int width,
unsigned int value) {
signed int num = 0;
// Take current digit into account when calculating width
width--;
// Recursively write upper digits
if ( (value / 10) > 0) {
num = PutUnsignedInt (pStr, fill, width, value / 10);
pStr += num;
}
// Write filler characters
else {
while (width > 0) {
PutChar (pStr, fill);
pStr++;
num++;
width--;
}
}
// Write lower digit
num += PutChar (pStr, (value % 10) + '0');
return num;
}
////------------------------------------------------------------------------------
/// Writes a signed int inside the given string, using the provided fill & width
/// parameters.
/// Returns the size of the written integer.
/// \param pStr Storage string.
/// \param fill Fill character.
/// \param width Minimum integer width.
/// \param value Signed integer value.
////------------------------------------------------------------------------------
static signed int PutSignedInt (
char *pStr,
char fill,
signed int width,
signed int value) {
signed int num = 0;
unsigned int absolute;
// Compute absolute value
if (value < 0) {
absolute = -value;
} else {
absolute = value;
}
// Take current digit into account when calculating width
width--;
// Recursively write upper digits
if ( (absolute / 10) > 0) {
if (value < 0) {
num = PutSignedInt (pStr, fill, width, - (absolute / 10));
} else {
num = PutSignedInt (pStr, fill, width, absolute / 10);
}
pStr += num;
} else {
// Reserve space for sign
if (value < 0) {
width--;
}
// Write filler characters
while (width > 0) {
PutChar (pStr, fill);
pStr++;
num++;
width--;
}
// Write sign
if (value < 0) {
num += PutChar (pStr, '-');
pStr++;
}
}
// Write lower digit
num += PutChar (pStr, (absolute % 10) + '0');
return num;
}
//------------------------------------------------------------------------------
/// Writes an hexadecimal value into a string, using the given fill, width &
/// capital parameters.
/// Returns the number of char written.
/// \param pStr Storage string.
/// \param fill Fill character.
/// \param width Minimum integer width.
/// \param maj Indicates if the letters must be printed in lower- or upper-case.
/// \param value Hexadecimal value.
//------------------------------------------------------------------------------
static signed int PutHexa (
char *pStr,
char fill,
signed int width,
unsigned char maj,
unsigned int value) {
signed int num = 0;
// Decrement width
width--;
// Recursively output upper digits
if ( (value >> 4) > 0) {
num += PutHexa (pStr, fill, width, maj, value >> 4);
pStr += num;
}
// Write filler chars
else {
while (width > 0) {
PutChar (pStr, fill);
pStr++;
num++;
width--;
}
}
// Write current digit
if ( (value & 0xF) < 10) {
PutChar (pStr, (value & 0xF) + '0');
} else if (maj) {
PutChar (pStr, (value & 0xF) - 10 + 'A');
} else {
PutChar (pStr, (value & 0xF) - 10 + 'a');
}
num++;
return num;
}
static signed int PutPointer (char * pStr, void * ptr) {
int num = PutString(pStr, "0x");
pStr += num;
num += PutHexa(pStr, '0', 8, 0, (unsigned int) ptr);
return num;
}
signed int vsnprintf (char *pStr, size_t length, const char *pFormat, va_list ap) {
char fill;
unsigned char width;
signed int num = 0;
signed int size = 0;
// Clear the string
if (pStr) { * pStr = 0; }
// Phase string
while (*pFormat != 0 && size < length) {
// Normal character
if (*pFormat != '%') {
*pStr++ = *pFormat++;
size++;
} else if (* (pFormat + 1) == '%') { // Escaped '%'
*pStr++ = '%';
pFormat += 2;
size++;
} else { // Token delimiter
fill = ' ';
width = 0;
pFormat++;
if (*pFormat == '0') { // Parse filler
fill = '0';
pFormat++;
}
while ((*pFormat >= '0') && (*pFormat <= '9')) { // Parse width
width = (width * 10) + *pFormat - '0';
pFormat++;
}
// Check if there is enough space
if (size + width > length) {
width = length - size;
}
// Parse type
type_spec:
switch (*pFormat) {
case 'z': // modifikatory z,l jsou zbytečné - size long a int jsou stejne
case 'l':
pFormat++;
goto type_spec;
case 'd':
case 'i':
num = PutSignedInt (pStr, fill, width, va_arg (ap, signed int));
break;
case 'u':
num = PutUnsignedInt (pStr, fill, width, va_arg (ap, unsigned int));
break;
case 'x':
num = PutHexa (pStr, fill, width, 0, va_arg (ap, unsigned int));
break;
case 'X':
num = PutHexa (pStr, fill, width, 1, va_arg (ap, unsigned int));
break;
case 's':
num = PutString (pStr, va_arg (ap, char *));
break;
case 'c':
num = PutChar (pStr, va_arg (ap, unsigned int));
break;
case 'p':
num = PutPointer (pStr, va_arg (ap, void *));
break;
default:
return 0;
}
pFormat++;
pStr += num;
size += num;
}
}
// NULL-terminated (final \0 is not counted)
if (size < length) {
*pStr = 0;
} else {
* (--pStr) = 0;
size--;
}
return size;
}