more bpmpfw shenanigans

This commit is contained in:
souldbminersmwc committed 2026-08-25 13:37:05 -04:00
1 parent 7660650129
commit b20d20edff
54 files changed
+1275 -30

No files matched your search

@@ -0,0 +1,12 @@
#include "fslc_stdlib.h"
#include "stdlibx.h"
void *fslc_bsearch(const void *key, const void *base, size_t num, size_t size, int (*cmp_proc)(const void *, const void *))
{
int sidx = fslc_bsearch_i(key, base, num, size, cmp_proc);
if (sidx < 0)
return NULL;
return (char *)base + (sidx * size);
}
@@ -0,0 +1,31 @@
#include <stddef.h>
int fslc_bsearch_i(const void *key, const void *base, size_t num, size_t size, int (*cmp_proc)(const void *, const void *))
{
int lo = 0;
int hi = num - 1;
char *cbase = (char *)base;
while (lo <= hi)
{
int i = lo + ((hi - lo) >> 1);
char *ptr = cbase + (i * size);
int cmp = cmp_proc(key, ptr);
if (cmp == 0)
return i;
if (cmp > 0)
{
lo = i + 1;
}
else
{
hi = i - 1;
}
}
return ~lo;
}
@@ -0,0 +1,10 @@
#include "fslc_stdio.h"
int fslc_fprintf(FSLC_FILE *stream, const char *format, ...)
{
va_list args;
va_start(args, format);
int r = fslc_vfprintf(stream, format, args);
va_end(args);
return r;
}
@@ -0,0 +1,12 @@
#include "fslc_stdio.h"
int fslc_fputc(int c, FSLC_FILE *stream)
{
if (stream->pre_output) stream->pre_output(stream);
int r = stream->putc(c, stream);
if (stream->post_output) stream->post_output(stream);
return r;
}
@@ -0,0 +1,15 @@
#include "fslc_stdio.h"
int _fslc_fputs_impl(const char *str, FSLC_FILE *stream);
int fslc_fputs(const char *str, FSLC_FILE *stream)
{
if (stream->pre_output) stream->pre_output(stream);
int r = _fslc_fputs_impl(str, stream);
if (stream->post_output) stream->post_output(stream);
return r;
}
@@ -0,0 +1,13 @@
#include "fslc_stdio.h"
int _fslc_fputs_impl(const char *str, FSLC_FILE *stream)
{
int res = 0;
for (;*str; ++str)
{
int pr = stream->putc(*str, stream);
if (pr < 0) return pr;
++res;
}
return res;
}
@@ -0,0 +1,38 @@
#include "fslc_string.h"
#include <stdint.h>
int fslc_memcmp(const void *ptr1, const void *ptr2, size_t num)
{
unsigned char *b_p1 = (unsigned char *)ptr1;
unsigned char *b_p2 = (unsigned char *)ptr2;
for (;((uintptr_t)b_p1 & (sizeof(long)-1)) && num > 0; ++b_p1, ++b_p2, --num)
{
if (*b_p1 != *b_p2)
{
return *b_p1 > *b_p2 ? 1 : -1;
}
}
unsigned long *w_p1 = (unsigned long *)b_p1;
unsigned long *w_p2 = (unsigned long *)b_p2;
for (;num >= sizeof(unsigned long); ++w_p1, ++w_p2, num -= sizeof(unsigned long))
{
if (*w_p1 != *w_p2)
{
return *w_p1 > *w_p2 ? 1 : -1;
}
}
b_p1 = (unsigned char *)w_p1;
b_p2 = (unsigned char *)w_p2;
for (; num > 0; ++b_p1, ++b_p2, --num)
{
if (*b_p1 != *b_p2)
{
return *b_p1 > *b_p2 ? 1 : -1;
}
}
return 0;
}
@@ -0,0 +1,40 @@
#include "fslc_string.h"
#include <stdint.h>
void *fslc_memcpy(void *dest, const void *src, size_t len)
{
/* Copy byte-by-byte up to word-aligned.
*
* There's a possibility, that src and dest have different offsets
* to word boundary and can not both be used efficiently.
*
* In this case we use align to dest argument, because it then can be
* written in one operation, instead of read-modify-write of 2 words.
*
* Most of the time both parameters should be word-aligned, however.
*/
unsigned char *b_src = (unsigned char *)src;
unsigned char *b_dst = (unsigned char *)dest;
for (;((uintptr_t)b_dst & (sizeof(unsigned long)-1)) && len > 0; b_src++, b_dst++, len--)
{
*b_dst = *b_src;
}
/* Then all word-aligned */
unsigned long *w_src = (unsigned long*)b_src;
unsigned long *w_dst = (unsigned long*)b_dst;
for (;len >= sizeof(unsigned long); w_src++, w_dst++, len -= sizeof(unsigned long))
{
*w_dst = *w_src;
}
/* And byte-by-byte the rest */
b_src = (unsigned char *)w_src;
b_dst = (unsigned char *)w_dst;
for (; len > 0; b_src++, b_dst++, len--)
{
*b_dst = *b_src;
}
return dest;
}
@@ -0,0 +1,69 @@
#include "fslc_string.h"
#include <stdint.h>
void *fslc_memmove(void *dest, const void *src, size_t len)
{
unsigned char *b_dst = (unsigned char *)dest;
unsigned char *b_src = (unsigned char *)src;
/* Need to check if memory regions overlaps. Then if the dest address is
* larger than source, we need to copy backwards (or else source regions
* ending will be overwritten by writes to dest, before they are read).
*
* In other cases it works identically as memcpy(). Same considerations
* about address alignment applies here.
*/
if ( b_dst < b_src + len && b_dst > b_src)
{
b_src += len;
b_dst += len;
/* Byte-by-byte down to word-aligned. */
for (;((uintptr_t)b_dst & (sizeof(unsigned long)-1)) && len > 0; )
{
b_src--, b_dst--, len--;
*b_dst = *b_src;
}
/* Then all word-aligned */
unsigned long *w_src = (unsigned long*)b_src;
unsigned long *w_dst = (unsigned long*)b_dst;
for (;len >= sizeof(unsigned long); )
{
w_src--, w_dst--, len -= sizeof(unsigned long);
*w_dst = *w_src;
}
/* And byte-by-byte the rest */
b_src = (unsigned char *)w_src;
b_dst = (unsigned char *)w_dst;
for (; len > 0; )
{
b_src--, b_dst--, len--;
*b_dst = *b_src;
}
} else {
/* Byte-by-byte up to word-aligned. */
for (;((uintptr_t)b_dst & (sizeof(unsigned long)-1)) && len > 0; b_src++, b_dst++, len--)
{
*b_dst = *b_src;
}
/* Then all word-aligned */
unsigned long *w_src = (unsigned long *)b_src;
unsigned long *w_dst = (unsigned long *)b_dst;
for (;len >= sizeof(unsigned long); w_src++, w_dst++, len -= sizeof(unsigned long))
{
*w_dst = *w_src;
}
/* And byte-by-byte the rest */
b_src = (unsigned char *)w_src;
b_dst = (unsigned char *)w_dst;
for (; len > 0; b_src++, b_dst++, len--)
{
*b_dst = *b_src;
}
}
return dest;
}
@@ -0,0 +1,22 @@
#include "fslc_string.h"
#include "stringx.h"
void *fslc_memset(void *ptr, int value, size_t num)
{
/* Will use memset_l() to actually fill the memory region. If value is non-zero, we need
* to replicate lowest byte to all the long's bytes.
*/
if (value)
{
unsigned char c_val = value;
unsigned long l_val = (c_val << 0) | (c_val << 8) | (c_val << 16) | (c_val << 24);
#if __SIZEOF_LONG__ == 8
l_val |= l_val << 32;
#endif
return fslc_memset_l(ptr, l_val, num);
}
else
return fslc_memset_l(ptr, value, num);
}
@@ -0,0 +1,31 @@
#include "stringx.h"
#include <stdint.h>
void *fslc_memset_l(void *ptr, unsigned long value, size_t num)
{
unsigned char *b_src = (unsigned char *)&value;
unsigned char *b_dst = (unsigned char *)ptr;
/* Byte by byte - to aligned word address */
b_src += ((uintptr_t)b_dst & (sizeof(unsigned long)-1));
for (;((uintptr_t)b_dst & (sizeof(unsigned long)-1)) && num > 0; b_dst++,b_src++,num--)
{
*b_dst = *b_src;
}
/* All aligned */
unsigned long *w_dst = (unsigned long *)b_dst;
for (;num >= sizeof(unsigned long); w_dst++,num -= sizeof(unsigned long))
{
*w_dst= value;
}
/* Unaligned ending */
b_src = (unsigned char *)&value;
b_dst = (unsigned char *)w_dst;
for (; num > 0; b_dst++,b_src++,num--)
{
*b_dst = *b_src;
}
return ptr;
}
@@ -0,0 +1,10 @@
#include "fslc_stdio.h"
int fslc_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
int r = fslc_vfprintf(fslc_stdout, format, args);
va_end(args);
return r;
}
@@ -0,0 +1,6 @@
#include "fslc_stdio.h"
int fslc_putchar(int c)
{
return fslc_fputc(c, fslc_stdout);
}
@@ -0,0 +1,21 @@
#include "fslc_stdio.h"
int _fslc_fputs_impl(const char *str, FSLC_FILE *stream);
int fslc_puts(const char *str)
{
if (fslc_stdout->pre_output) fslc_stdout->pre_output(fslc_stdout);
int r = _fslc_fputs_impl(str, fslc_stdout);
if (r >= 0)
{
int nlr = fslc_stdout->putc('\n', fslc_stdout);
if (nlr < 0)
r = nlr;
}
if (fslc_stdout->post_output) fslc_stdout->post_output(fslc_stdout);
return r;
}
@@ -0,0 +1,3 @@
#include "fslc_stdio.h"
FSLC_FILE *fslc_stdout;
@@ -0,0 +1,10 @@
#include "fslc_string.h"
char *fslc_strchr(const char *str, int c)
{
for (;*str; ++str)
if (*str == c)
return (char *)str;
return NULL;
}
@@ -0,0 +1,8 @@
#include "fslc_string.h"
int fslc_strcmp(const char *str1, const char *str2)
{
for( ; *str1 && *str1 == *str2; ++str1, ++str2);
return *((unsigned char *)str1) - *((unsigned char *)str2);
}
@@ -0,0 +1,8 @@
#include "fslc_string.h"
#include "stringx.h"
char *fslc_strcpy(char *dest, const char *src)
{
fslc_strcpy_e(dest, src);
return dest;
}
@@ -0,0 +1,10 @@
#include "stringx.h"
char *fslc_strcpy_e(char *dest, const char *src)
{
for(; *src; ++src, ++dest)
*dest = *src;
*dest = 0;
return dest;
}
@@ -0,0 +1,9 @@
#include "fslc_string.h"
size_t fslc_strlen(const char *str)
{
size_t res = 0;
for(; *str; ++str) ++res;
return res;
}
@@ -0,0 +1,8 @@
#include "fslc_string.h"
int fslc_strncmp(const char *str1, const char *str2, size_t num)
{
for( ; *str1 && *str1 == *str2 && num > 1; ++str1, ++str2, --num);
return *((unsigned char *)str1) - *((unsigned char *)str2);
}
@@ -0,0 +1,9 @@
#include "fslc_string.h"
char *_fslc_strncpy_impl(char *dest, const char *src, size_t len);
char *fslc_strncpy(char *dest, const char *src, size_t len)
{
_fslc_strncpy_impl(dest, src, len);
return dest;
}
@@ -0,0 +1,9 @@
#include "stringx.h"
char *_fslc_strncpy_impl(char *dest, const char *src, size_t len);
char *fslc_strncpy_e(char *dest, const char *src, size_t len)
{
char *r = _fslc_strncpy_impl(dest, src, len);
return *r ? r + 1: r;
}
@@ -0,0 +1,10 @@
#include <stddef.h>
char *_fslc_strncpy_impl(char *dest, const char *src, size_t len)
{
for(; *src && len > 1; ++src, ++dest, --len)
*dest = *src;
*dest = *src;
return dest;
}
@@ -0,0 +1,14 @@
#include "fslc_string.h"
char *fslc_strpbrk(const char *str, const char *delim)
{
for (; *str; ++str)
{
const char *d;
for (d = delim; *d; ++d)
if (*str == *d)
return (char *)str;
}
return NULL;
}
@@ -0,0 +1,18 @@
#include "fslc_string.h"
size_t fslc_strspn(const char *str, const char *delim)
{
size_t r;
for (r = 0; *str; ++str, ++r)
{
const char *d;
for (d = delim; *d; ++d)
if (*str == *d) // skip to next if found
break;
if (*d == 0) // inner loop exited on \0 - char was not there
break;
}
return r;
}
@@ -0,0 +1,23 @@
#include "fslc_string.h"
char *fslc_strstr(const char *search_in, const char *search_for)
{
while (*search_in)
{
char *rc = fslc_strchr(search_in, search_for[0]); // find first char
if (rc)
{
const char *si = rc + 1, *sf = search_for + 1; // search strcmp-style from second char
for( ; *si && *si == *sf; ++si, ++sf);
if (*sf == 0) return rc; // end of search-for - found result
search_in = rc + 1; // not this one, continue from next char
}
else
return NULL; // did not find first char - exit
}
return NULL; // reached end of source - did not find
}
@@ -0,0 +1,27 @@
#include "fslc_string.h"
char *fslc_strtok_r(char *str, const char *delim, char **save_p)
{
if (str)
*save_p = str;
if (*save_p == NULL)
return NULL;
char *r = *save_p + fslc_strspn(*save_p, delim);
char *p = fslc_strpbrk(r, delim);
if (p)
{
*(p++) = 0;
*save_p = p;
}
else
{
if (*r == 0) r = NULL;
*save_p = NULL;
}
return r;
}
@@ -0,0 +1,347 @@
#include "fslc_stdio.h"
/* There'a a funny behaviour of va_list and va_arg() macros:
* - on x86_64 compiler generates a branch of some sort for each va_arg() macro. Normally it is not a problem,
* however it kinda screws up branch coverage analysis. Therefore I decided to move va_arg() accesses into
* dedicated functions, minimizing the issue to one untaken branch per access function.
* - passing va_list by value works fine on x86_64, but makes some tests to fail on i386. It seems that modifications
* done by va_arg() is not passed back to caller. Subsequent calls to va_arg() or access functions returns wrong
* values on that platform.
* - OK, then. Let's pass pointer to va_list instead. Not so fast. Works fine on i386, but fails to compile on
* x86_64. Fine! Wrapping va_list into a dedicated struct and passing around pointer to it.
*
* Why such a fuss about a few untaken branches in tests? Well, just because! Also, if I ever decide to refactor
* _fslc_vfprintf_impl() - the case statement is getting a bit long and messy, it should make things easier if
* argument list can be passed around freely (as opposed to using it from single function).
*/
struct va_list_w
{
va_list arg;
};
/* Prototype for printf's internal implementation */
static int _fslc_vfprintf_impl(FSLC_FILE *stream, const char *format, struct va_list_w *args);
/* Main exported function */
int fslc_vfprintf(FSLC_FILE *stream, const char *format, va_list arg)
{
if (stream->pre_output) stream->pre_output(stream);
struct va_list_w argw;
va_copy(argw.arg, arg); // can not assign directly, should make a copy
int res = _fslc_vfprintf_impl(stream, format, &argw);
va_end(argw.arg); // and free it after use
if (stream->post_output) stream->post_output(stream);
return res;
}
/* Prototype to private FSLIBC function - implemented elsewhere */
int _fslc_fputs_impl(const char *str, FSLC_FILE *stream);
/* Prototypes for internal functions */
static int _fslc_put_sint_l(signed long v, FSLC_FILE *stream);
static int _fslc_put_uint_l(unsigned long v, FSLC_FILE *stream);
static int _fslc_put_hex_l(unsigned long v, FSLC_FILE *stream, char alpha);
static int _get_sint_arg(struct va_list_w *arg);
static unsigned _get_uint_arg(struct va_list_w *arg);
static long long _get_slonglong_arg(struct va_list_w *arg);
static unsigned long long _get_ulonglong_arg(struct va_list_w *arg);
static void *_get_ptr_arg(struct va_list_w *arg);
/* There are some considerations when formatting Integers for output:
* - on 32-bit systems integers will mostly be 32 bits long, except when one REALLY
* wants to print long long. It should be more optimal to use 32-bit calculations
* when possible and invoke 64-bit only when needed. To support that we provide 2
* separate implementations.
* - on 64-bit systems may be 32 or 64 bits, but there is no real benefit from
* using shorter bit size. Hence common implementation.
* - this library does not aim to support systems with shorter integer sizes (like 16-bit)
* but it it did, it would probably make sense to provide optimized ports for these cases
* as well.
*
* Buffer size calculations:
* Max UInt32 fits in 10 bytes (+1 for zero terminator) decimal
* 2**32 - 1 == 4294967295z
* FFFFFFFFz
* 01234567890
*
* Max UInt64 fits in 10 bytes (and +1 for \0)
* 2**64 -1 == 18446744073709551615z
* FFFFFFFFFFFFFFFFz
* 012345678901234567890
*/
#define BUFSIZE_LONG_LONG_DECIMAL 20
#define BUFSIZE_LONG_HEX (__SIZEOF_LONG__ * 2)
#define BUFSIZE_LONG_LONG_HEX (__SIZEOF_LONG_LONG__ * 2)
#if __SIZEOF_LONG__ == 4
#define BUFSIZE_LONG_DECIMAL 10
static int _fslc_put_sint_ll(signed long long v, FSLC_FILE *stream);
static int _fslc_put_uint_ll(unsigned long long v, FSLC_FILE *stream);
static int _fslc_put_hex_ll(unsigned long long v, FSLC_FILE *stream, char alpha);
#define _get_slong_arg _get_sint_arg
#define _get_ulong_arg _get_uint_arg
#elif __SIZEOF_LONG__ == 8
#define BUFSIZE_LONG_DECIMAL BUFSIZE_LONG_LONG_DECIMAL
#define _fslc_put_sint_ll _fslc_put_sint_l
#define _fslc_put_uint_ll _fslc_put_uint_l
#define _fslc_put_hex_ll _fslc_put_hex_l
#define _get_slong_arg _get_slonglong_arg
#define _get_ulong_arg _get_ulonglong_arg
#endif
#define FLAG_LONG 1
#define FLAG_VERYLONG 3
static int _fslc_vfprintf_impl(FSLC_FILE *stream, const char *format, struct va_list_w *arg)
{
int res = 0;
int pr;
const char *c;
for (c = format; *c; ++c)
{
if (*c == '%')
{
int flags = 0;
for (;;)
{
++c;
switch (*c)
{
case 's':
pr = _fslc_fputs_impl((const char *)_get_ptr_arg(arg), stream);
if (pr < 0) return pr;
res += pr;
break;
case 'c':
pr = stream->putc(_get_sint_arg(arg), stream);
if (pr < 0) return pr;
++res;
break;
case '%':
pr = stream->putc('%', stream);
if (pr < 0) return pr;
++res;
break;
case 'i':
case 'd':
if ((flags & FLAG_VERYLONG) == FLAG_VERYLONG)
pr = _fslc_put_sint_ll(_get_slonglong_arg(arg), stream);
else if (flags & FLAG_LONG)
pr = _fslc_put_sint_l(_get_slong_arg(arg), stream);
else
pr = _fslc_put_sint_l(_get_sint_arg(arg), stream);
if (pr < 0) return pr;
res += pr;
break;
case 'u':
if ((flags & FLAG_VERYLONG) == FLAG_VERYLONG)
pr = _fslc_put_uint_ll(_get_ulonglong_arg(arg), stream);
else if (flags & FLAG_LONG)
pr = _fslc_put_uint_l(_get_ulong_arg(arg), stream);
else
pr = _fslc_put_uint_l(_get_uint_arg(arg), stream);
if (pr < 0) return pr;
res += pr;
break;
case 'x':
if ((flags & FLAG_VERYLONG) == FLAG_VERYLONG)
pr = _fslc_put_hex_ll(_get_ulonglong_arg(arg), stream, 'a');
else if (flags & FLAG_LONG)
pr = _fslc_put_hex_l(_get_ulong_arg(arg), stream, 'a');
else
pr = _fslc_put_hex_l(_get_uint_arg(arg), stream, 'a');
if (pr < 0) return pr;
res += pr;
break;
case 'X':
if ((flags & FLAG_VERYLONG) == FLAG_VERYLONG)
pr = _fslc_put_hex_ll(_get_ulonglong_arg(arg), stream, 'A');
else if (flags & FLAG_LONG)
pr = _fslc_put_hex_l(_get_ulong_arg(arg), stream, 'A');
else
pr = _fslc_put_hex_l(_get_uint_arg(arg), stream, 'A');
if (pr < 0) return pr;
res += pr;
break;
case 'p':
pr = _fslc_fputs_impl("0x", stream);
if (pr < 0) return pr;
res += pr;
pr = _fslc_put_hex_l(_get_ulong_arg(arg), stream, 'a');
if (pr < 0) return pr;
res += pr;
break;
case 'l':
if (flags & FLAG_LONG)
flags |= FLAG_VERYLONG;
else
flags |= FLAG_LONG;
continue;
}
break;
}
} else {
pr = stream->putc(*c, stream);
if (pr < 0) return pr;
++res;
}
}
return res;
}
static int _get_sint_arg(struct va_list_w *arg)
{
return va_arg(arg->arg, signed int);
}
static unsigned _get_uint_arg(struct va_list_w *arg)
{
return va_arg(arg->arg, unsigned int);
}
static long long _get_slonglong_arg(struct va_list_w *arg)
{
return va_arg(arg->arg, signed long long);
}
static unsigned long long _get_ulonglong_arg(struct va_list_w *arg)
{
return va_arg(arg->arg, unsigned long long);
}
static void *_get_ptr_arg(struct va_list_w *arg)
{
return va_arg(arg->arg, void *);
}
static int _fslc_put_sint_l(signed long v, FSLC_FILE *stream)
{
if (v < 0)
{
int pr = stream->putc('-', stream);
if (pr < 0) return pr;
pr = _fslc_put_uint_l(-v, stream);
if (pr < 0) return pr;
return pr+1;
} else
return _fslc_put_uint_l(v, stream);
}
static int _fslc_put_uint_l(unsigned long v, FSLC_FILE *stream)
{
char dbuff[BUFSIZE_LONG_DECIMAL+1], *p;
dbuff[BUFSIZE_LONG_DECIMAL] = 0;
for (p = dbuff + BUFSIZE_LONG_DECIMAL; v ; v /= 10)
{
*(--p) = (v % 10) + '0';
}
if (*p == 0) *(--p) = '0';
return _fslc_fputs_impl(p, stream);
}
static int _fslc_put_hex_l(unsigned long v, FSLC_FILE *stream, char alpha)
{
char dbuff[BUFSIZE_LONG_HEX+1], *p;
dbuff[BUFSIZE_LONG_HEX] = 0;
for (p = dbuff + BUFSIZE_LONG_HEX; v ; v >>= 4)
{
char digit = (v & 0xF);
*(--p) = digit < 10 ? digit + '0' : digit - 10 + alpha;
}
if (*p == 0) *(--p) = '0';
return _fslc_fputs_impl(p, stream);
}
#if __SIZEOF_LONG__ == 4
static int _fslc_put_sint_ll(signed long long v, FSLC_FILE *stream)
{
if (v < 0)
{
int pr = stream->putc('-', stream);
if (pr < 0) return pr;
pr = _fslc_put_uint_ll(-v, stream);
if (pr < 0) return pr;
return pr+1;
} else
return _fslc_put_uint_ll(v, stream);
}
static int _fslc_put_uint_ll(unsigned long long v, FSLC_FILE *stream)
{
char dbuff[BUFSIZE_LONG_LONG_DECIMAL+1], *p;
dbuff[BUFSIZE_LONG_LONG_DECIMAL] = 0;
for (p = dbuff + BUFSIZE_LONG_LONG_DECIMAL; v ; v /= 10)
{
*(--p) = (v % 10) + '0';
}
if (*p == 0) *(--p) = '0';
return _fslc_fputs_impl(p, stream);
}
static int _fslc_put_hex_ll(unsigned long long v, FSLC_FILE *stream, char alpha)
{
char dbuff[BUFSIZE_LONG_LONG_HEX+1], *p;
dbuff[BUFSIZE_LONG_LONG_HEX] = 0;
for (p = dbuff + BUFSIZE_LONG_LONG_HEX; v ; v >>= 4)
{
char digit = (v & 0xF);
*(--p) = digit < 10 ? digit + '0' : digit - 10 + alpha;
}
if (*p == 0) *(--p) = '0';
return _fslc_fputs_impl(p, stream);
}
#endif
@@ -0,0 +1,6 @@
#include "fslc_stdio.h"
int fslc_vprintf(const char *format, va_list arg)
{
return fslc_vfprintf(fslc_stdout, format, arg);
}