summaryrefslogtreecommitdiffstats
path: root/private/crt32/convert/xtoa.c
blob: 72fcfb26559d954039db204cc402f8cf4c65d76f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/***
*xtoa.c - convert integers/longs to ASCII string
*
*	Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	The module has code to convert integers/longs to ASCII strings.  See
*
*Revision History:
*	06-06-89  PHG	Module created, based on asm version
*	03-06-90  GJF	Fixed calling type, added #include <cruntime.h> and
*			fixed copyright.
*	03-23-90  GJF	Made xtoa() _CALLTYPE4.
*	09-27-90  GJF	New-style function declarators.
*	01-21-91  GJF	ANSI naming.
*
*******************************************************************************/

#include <cruntime.h>
#include <stdlib.h>
#include <limits.h>

/***
*char *_itoa, *_ltoa, *_ultoa(val, buf, radix) - convert binary int to ASCII
*	string
*
*Purpose:
*	Converts an int to a character string.
*
*Entry:
*	val - number to be converted (int, long or unsigned long)
*	int radix - base to convert into
*	char *buf - ptr to buffer to place result
*
*Exit:
*	fills in space pointed to by buf with string result
*	returns a pointer to this buffer
*
*Exceptions:
*
*******************************************************************************/

/* helper routine that does the main job. */

static void _CALLTYPE4 xtoa (
	unsigned long val,
	char *buf,
	unsigned radix,
	int is_neg
	)
{
	char *p;		/* pointer to traverse string */
	char *firstdig; 	/* pointer to first digit */
	char temp;		/* temp char */
	unsigned digval;	/* value of digit */

	p = buf;

	if (is_neg) {
		/* negative, so output '-' and negate */
		*p++ = '-';
		val = (unsigned long)(-(long)val);
	}

	firstdig = p;		/* save pointer to first digit */

	do {
		digval = (unsigned) (val % radix);
		val /= radix;	/* get next digit */

		/* convert to ascii and store */
		if (digval > 9)
			*p++ = (char) (digval - 10 + 'a');	/* a letter */
		else
			*p++ = (char) (digval + '0');		/* a digit */
	} while (val > 0);

	/* We now have the digit of the number in the buffer, but in reverse
	   order.  Thus we reverse them now. */

	*p-- = '\0';		/* terminate string; p points to last digit */

	do {
		temp = *p;
		*p = *firstdig;
		*firstdig = temp;	/* swap *p and *firstdig */
		--p;
		++firstdig;		/* advance to next two digits */
	} while (firstdig < p); /* repeat until halfway */
}


/* Actual functions just call conversion helper with neg flag set correctly,
   and return pointer to buffer. */

char * _CALLTYPE1 _itoa (
	int val,
	char *buf,
	int radix
	)
{
	if (radix == 10 && val < 0)
		xtoa((unsigned long)val, buf, radix, 1);
	else
		xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
	return buf;
}

char * _CALLTYPE1 _ltoa (
	long val,
	char *buf,
	int radix
	)
{
	xtoa((unsigned long)val, buf, radix, (radix == 10 && val < 0));
	return buf;
}

char * _CALLTYPE1 _ultoa (
	unsigned long val,
	char *buf,
	int radix
	)
{
	xtoa(val, buf, radix, 0);
	return buf;
}