itob.c 1.15 KB
/* Portions of this work are derived from the Standard C Library, */
/* copyright (c) 1992 by P.J. Plauger, published by Prentice-Hall, */
/* and are used with permission. */

#include <stdlib.h>
#include <string.h>

#include "gload.h"

static char ldigs[] = "0123456789abcdef";
static char udigs[] = "0123456789ABCDEF";

void
itob(field_t *px, char code)
{	/* convert unsigned long to text */
	char ac[24];	/* safe for 64-bit integers */
	char *digs = code == 'X' ? udigs : ldigs;
	int base = code == 'o' ? 8 : code != 'x' && code != 'X' ? 10 : 16;
	int i = sizeof(ac);
	unsigned long ulval = px->v.l;

	if ((code == 'd' || code == 'i') && px->v.l < 0)
		ulval = -ulval;	/* safe against overflow */
	if (ulval || px->prec)
		ac[--i] = digs[ulval % base];
	px->v.l = ulval / base;
	while (0 < px->v.l && 0 < i) {	/* convert digits */
		lldiv_t qr = lldiv(px->v.l, (long long) base);

		px->v.l = qr.quot;
		ac[--i] = digs[qr.rem];
	}
	px->n1 = sizeof(ac) - i;
	memcpy(px->s, &ac[i], px->n1);
	if (px->n1 < px->prec)
		px->nz0 = px->prec - px->n1;
	if (px->prec < 0 && (px->flags & (_FMI | _FZE)) == _FZE
		&& 0 < (i = px->width - px->n0 - px->nz0 - px->n1))
		px->nz0 += i;
}