108 lines
3.3 KiB
C
108 lines
3.3 KiB
C
/***********************************************************************/
|
|
/* */
|
|
/* OCaml */
|
|
/* */
|
|
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
|
|
/* */
|
|
/* Copyright 2002 Institut National de Recherche en Informatique et */
|
|
/* en Automatique. All rights reserved. This file is distributed */
|
|
/* under the terms of the GNU Library General Public License, with */
|
|
/* the special exception on linking described in file ../LICENSE. */
|
|
/* */
|
|
/***********************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
/* printf-like formatting of 64-bit integers, in case the C library
|
|
printf() function does not support them. */
|
|
|
|
#ifndef CAML_INT64_FORMAT_H
|
|
#define CAML_INT64_FORMAT_H
|
|
|
|
static void I64_format(char * buffer, char * fmt, int64 x)
|
|
{
|
|
static char conv_lower[] = "0123456789abcdef";
|
|
static char conv_upper[] = "0123456789ABCDEF";
|
|
char rawbuffer[24];
|
|
char justify, signstyle, filler, alternate, signedconv;
|
|
int base, width, sign, i, rawlen;
|
|
char * cvtbl;
|
|
char * p, * r;
|
|
int64 wbase, digit;
|
|
|
|
/* Parsing of format */
|
|
justify = '+';
|
|
signstyle = '-';
|
|
filler = ' ';
|
|
alternate = 0;
|
|
base = 0;
|
|
signedconv = 0;
|
|
width = 0;
|
|
cvtbl = conv_lower;
|
|
for (p = fmt; *p != 0; p++) {
|
|
switch (*p) {
|
|
case '-':
|
|
justify = '-'; break;
|
|
case '+': case ' ':
|
|
signstyle = *p; break;
|
|
case '0':
|
|
filler = '0'; break;
|
|
case '#':
|
|
alternate = 1; break;
|
|
case '1': case '2': case '3': case '4': case '5':
|
|
case '6': case '7': case '8': case '9':
|
|
width = atoi(p);
|
|
while (p[1] >= '0' && p[1] <= '9') p++;
|
|
break;
|
|
case 'd': case 'i':
|
|
signedconv = 1; /* fallthrough */
|
|
case 'u':
|
|
base = 10; break;
|
|
case 'x':
|
|
base = 16; break;
|
|
case 'X':
|
|
base = 16; cvtbl = conv_upper; break;
|
|
case 'o':
|
|
base = 8; break;
|
|
}
|
|
}
|
|
if (base == 0) { buffer[0] = 0; return; }
|
|
/* Do the conversion */
|
|
sign = 1;
|
|
if (signedconv && I64_is_negative(x)) { sign = -1; x = I64_neg(x); }
|
|
r = rawbuffer + sizeof(rawbuffer);
|
|
wbase = I64_of_int32(base);
|
|
do {
|
|
I64_udivmod(x, wbase, &x, &digit);
|
|
*--r = cvtbl[I64_to_int32(digit)];
|
|
} while (! I64_is_zero(x));
|
|
rawlen = rawbuffer + sizeof(rawbuffer) - r;
|
|
/* Adjust rawlen to reflect additional chars (sign, etc) */
|
|
if (signedconv && (sign < 0 || signstyle != '-')) rawlen++;
|
|
if (alternate) {
|
|
if (base == 8) rawlen += 1;
|
|
if (base == 16) rawlen += 2;
|
|
}
|
|
/* Do the formatting */
|
|
p = buffer;
|
|
if (justify == '+' && filler == ' ') {
|
|
for (i = rawlen; i < width; i++) *p++ = ' ';
|
|
}
|
|
if (signedconv) {
|
|
if (sign < 0) *p++ = '-';
|
|
else if (signstyle != '-') *p++ = signstyle;
|
|
}
|
|
if (alternate && base == 8) *p++ = '0';
|
|
if (alternate && base == 16) { *p++ = '0'; *p++ = 'x'; }
|
|
if (justify == '+' && filler == '0') {
|
|
for (i = rawlen; i < width; i++) *p++ = '0';
|
|
}
|
|
while (r < rawbuffer + sizeof(rawbuffer)) *p++ = *r++;
|
|
if (justify == '-') {
|
|
for (i = rawlen; i < width; i++) *p++ = ' ';
|
|
}
|
|
*p = 0;
|
|
}
|
|
|
|
#endif /* CAML_INT64_FORMAT_H */
|