|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13: #include "stdio.h"
14: #include "stdlib.h"
15: #include "string.h"
16:
17: const static unsigned long long convert[] = {
18: 0x0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF,
19: 0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
20: };
21:
22:
23:
24: static int
25: print_itoa(char **buffer,unsigned long value, unsigned short int base)
26: {
27: const char zeichen[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
28: static char sign = 0;
29:
30: if(base <= 2 || base > 16)
31: return 0;
32:
33: if(value < 0) {
34: sign = 1;
35: value *= -1;
36: }
37:
38: if(value < base) {
39: if(sign) {
40: **buffer = '-';
41: *buffer += 1;
42: sign = 0;
43: }
44: **buffer = zeichen[value];
45: *buffer += 1;
46: } else {
47: print_itoa(buffer, value / base, base);
48: **buffer = zeichen[(value % base)];
49: *buffer += 1;
50: }
51:
52: return 1;
53: }
54:
55:
56: static unsigned int
57: print_intlen(unsigned long value, unsigned short int base)
58: {
59: int i = 0;
60:
61: while(value > 0) {
62: value /= base;
63: i++;
64: }
65: if(i == 0) i = 1;
66: return i;
67: }
68:
69:
70: static int
71: print_fill(char **buffer, char *sizec, unsigned long size, unsigned short int base, char c, int optlen)
72: {
73: int i, sizei, len;
74:
75: sizei = strtoul(sizec, NULL, 10);
76: len = print_intlen(size, base) + optlen;
77: if(sizei > len) {
78: for(i = 0; i < (sizei - len); i++) {
79: **buffer = c;
80: *buffer += 1;
81: }
82: }
83:
84: return 0;
85: }
86:
87:
88: static int
89: print_format(char **buffer, const char *format, void *var)
90: {
91: unsigned long start;
92: unsigned int i = 0, sizei = 0, len = 0, length_mod = sizeof(int);
93: unsigned long value = 0;
94: unsigned long signBit;
95: char *form, sizec[32];
96: char sign = ' ';
97:
98: form = (char *) format;
99: start = (unsigned long) *buffer;
100:
101: form++;
102: if(*form == '0' || *form == '.') {
103: sign = '0';
104: form++;
105: }
106:
107: while(*form != '\0') {
108: switch(*form) {
109: case 'u':
110: case 'd':
111: case 'i':
112: sizec[i] = '\0';
113: value = (unsigned long) var;
114: signBit = 0x1ULL << (length_mod * 8 - 1);
115: if (signBit & value) {
116: **buffer = '-';
117: *buffer += 1;
118: value = (-(unsigned long)value) & convert[length_mod];
119: }
120: print_fill(buffer, sizec, value, 10, sign, 0);
121: print_itoa(buffer, value, 10);
122: break;
123: case 'X':
124: case 'x':
125: sizec[i] = '\0';
126: value = (unsigned long) var & convert[length_mod];
127: print_fill(buffer, sizec, value, 16, sign, 0);
128: print_itoa(buffer, value, 16);
129: break;
130: case 'O':
131: case 'o':
132: sizec[i] = '\0';
133: value = (long int) var & convert[length_mod];
134: print_fill(buffer, sizec, value, 8, sign, 0);
135: print_itoa(buffer, value, 8);
136: break;
137: case 'p':
138: sizec[i] = '\0';
139: print_fill(buffer, sizec, (unsigned long) var, 16, ' ', 2);
140: **buffer = '0';
141: *buffer += 1;
142: **buffer = 'x';
143: *buffer += 1;
144: print_itoa(buffer,(unsigned long) var, 16);
145: break;
146: case 'c':
147: sizec[i] = '\0';
148: print_fill(buffer, sizec, 1, 10, ' ', 0);
149: **buffer = (unsigned long) var;
150: *buffer += 1;
151: break;
152: case 's':
153: sizec[i] = '\0';
154: sizei = strtoul(sizec, NULL, 10);
155: len = strlen((char *) var);
156: if(sizei > len) {
157: for(i = 0; i < (sizei - len); i++) {
158: **buffer = ' ';
159: *buffer += 1;
160: }
161: }
162: for(i = 0; i < strlen((char *) var); i++) {
163: **buffer = ((char *) var)[i];
164: *buffer += 1;
165: }
166: break;
167: case 'l':
168: form++;
169: if(*form == 'l') {
170: length_mod = sizeof(long long int);
171: } else {
172: form--;
173: length_mod = sizeof(long int);
174: }
175: break;
176: case 'h':
177: form++;
178: if(*form == 'h') {
179: length_mod = sizeof(signed char);
180: } else {
181: form--;
182: length_mod = sizeof(short int);
183: }
184: break;
185: default:
186: if(*form >= '0' && *form <= '9')
187: sizec[i++] = *form;
188: }
189: form++;
190: }
191:
192:
193: return (long int) (*buffer - start);
194: }
195:
196:
197: /*
198: * The vsnprintf function prints a formated strings into a buffer.
199: * BUG: buffer size checking does not fully work yet
200: */
201: int
202: vsnprintf(char *buffer, size_t bufsize, const char *format, va_list arg)
203: {
204: char *ptr, *bstart;
205:
206: bstart = buffer;
207: ptr = (char *) format;
208:
209: while(*ptr != '\0' && (buffer - bstart) < bufsize)
210: {
211: if(*ptr == '%') {
212: char formstr[20];
213: int i=0;
214:
215: do {
216: formstr[i] = *ptr;
217: ptr++;
218: i++;
219: } while(!(*ptr == 'd' || *ptr == 'i' || *ptr == 'u' || *ptr == 'x' || *ptr == 'X'
220: || *ptr == 'p' || *ptr == 'c' || *ptr == 's' || *ptr == '%'
221: || *ptr == 'O' || *ptr == 'o' ));
222: formstr[i++] = *ptr;
223: formstr[i] = '\0';
224: if(*ptr == '%') {
225: *buffer++ = '%';
226: } else {
227: print_format(&buffer, formstr, va_arg(arg, void *));
228: }
229: ptr++;
230: } else {
231:
232: *buffer = *ptr;
233:
234: buffer++;
235: ptr++;
236: }
237: }
238:
239: *buffer = '\0';
240:
241: return (buffer - bstart);
242: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.