3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-26 22:09:26 +01:00
pbot/modules/compiler_vm/misc/prelude.h

97 lines
3.5 KiB
C

#include <limits.h>
#include <wchar.h>
#include <stdio.h>
#include <printf.h>
#include <locale.h>
static int printf_binary_handler(FILE *s, const struct printf_info *info, const void *const *args)
{
const char *g = 0;
struct lconv *loc = 0;
int group = 0, arr = 0, total = 0, len, digits;
unsigned long long value = info->is_long_double ? *(const unsigned long long *)args[0] :
info->is_long ? *(const unsigned long *) args[0] :
info->is_char ? *(const unsigned char *) args[0] :
info->is_short ? *(const unsigned short *) args[0] :
*(const unsigned int *) args[0] ;
char buf[sizeof value * CHAR_BIT], *p = buf;
while(value) *p++ = '0' + (value & 1), value >>= 1;
len = p - buf;
digits = info->prec < 0 ? 1 : info->prec;
if(len > digits) digits = len;
if(info->alt) {
if(digits += -digits & 3) total = digits + (digits - 1) / 4 * !!info->group;
} else {
total = digits;
group = info->group && (loc = localeconv(), *(g = loc->grouping));
if(group) {
while(*g > 0 && *g < CHAR_MAX) {
if(digits - arr <= *g) break;
++total;
arr += *g++;
}
if(!*g) total += (digits - arr - 1) / g[-1];
}
}
while(!info->left && info->width > total++) fprintf(s, "%lc", (wint_t)info->pad);
if(info->alt)
while(digits) {
fputc(digits-- > len ? '0' : *--p, s);
if(digits && !(digits % 4) && info->group) fputc('.', s);
}
else if(group) {
if(*g) {
while(digits > arr) fputc(digits-- > len ? '0' : *--p, s);
} else {
int j = (digits - arr) % g[-1];
if(!j) j = g[-1];
while(j--) fputc(digits-- > len ? '0' : *--p, s);
while(digits > arr) {
fputs(loc->thousands_sep, s);
for(j = 0; j < g[-1]; ++j) fputc(digits-- > len ? '0' : *--p, s);
}
}
while(digits) {
int i = *--g;
fputs(loc->thousands_sep, s);
while(i--) fputc(digits-- > len ? '0' : *--p, s);
}
} else while(digits) fputc(digits-- > len ? '0' : *--p, s);
while(info->left && info->width > total++) fputc(' ', s);
return total - 1;
}
static int printf_binary_arginfo(const struct printf_info *info, size_t n, int *types, int *sizes)
{
if(n < 1) return -1;
(void)sizes;
types[0] = info->is_long_double ? PA_INT | PA_FLAG_LONG_LONG :
info->is_long ? PA_INT | PA_FLAG_LONG :
info->is_char ? PA_CHAR :
info->is_short ? PA_INT | PA_FLAG_SHORT :
PA_INT ;
return 1;
}
__attribute__ (( constructor )) static void printf_binary_register(void)
{
setvbuf(stdout, NULL, _IONBF, 0);
setlocale(LC_ALL, "");
register_printf_specifier('b', printf_binary_handler, printf_binary_arginfo);
}
void gdb() { __asm__(""); }
#define dump(...) gdb("print " #__VA_ARGS__)
#define print(...) gdb("print " #__VA_ARGS__)
#define ptype(...) gdb("ptype " #__VA_ARGS__)
#define trace(...) gdb("break " #__VA_ARGS__)
#define watch(...) gdb("watch " #__VA_ARGS__)
#define print_last_statement(...) gdb("print_last_statement " #__VA_ARGS__)