Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * Copyright (C) Paul Mackerras 1997.
  3 *
  4 * This program is free software; you can redistribute it and/or
  5 * modify it under the terms of the GNU General Public License
  6 * as published by the Free Software Foundation; either version
  7 * 2 of the License, or (at your option) any later version.
  8 */
  9#include <stdarg.h>
 10#include <stddef.h>
 11
 12size_t strnlen(const char * s, size_t count)
 13{
 14	const char *sc;
 15
 16	for (sc = s; count-- && *sc != '\0'; ++sc)
 17		/* nothing */;
 18	return sc - s;
 19}
 20
 21# define do_div(n, base) ({						\
 22	unsigned int __base = (base);					\
 23	unsigned int __rem;						\
 24	__rem = ((unsigned long long)(n)) % __base;			\
 25	(n) = ((unsigned long long)(n)) / __base;			\
 26	__rem;								\
 27})
 28
 29
 30static int skip_atoi(const char **s)
 31{
 32	int i, c;
 33
 34	for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
 35		i = i*10 + c - '0';
 36	return i;
 37}
 38
 39#define ZEROPAD	1		/* pad with zero */
 40#define SIGN	2		/* unsigned/signed long */
 41#define PLUS	4		/* show plus */
 42#define SPACE	8		/* space if plus */
 43#define LEFT	16		/* left justified */
 44#define SPECIAL	32		/* 0x */
 45#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
 46
 47static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
 48{
 49	char c,sign,tmp[66];
 50	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
 51	int i;
 52
 53	if (type & LARGE)
 54		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 55	if (type & LEFT)
 56		type &= ~ZEROPAD;
 57	if (base < 2 || base > 36)
 58		return 0;
 59	c = (type & ZEROPAD) ? '0' : ' ';
 60	sign = 0;
 61	if (type & SIGN) {
 62		if ((signed long long)num < 0) {
 63			sign = '-';
 64			num = - (signed long long)num;
 65			size--;
 66		} else if (type & PLUS) {
 67			sign = '+';
 68			size--;
 69		} else if (type & SPACE) {
 70			sign = ' ';
 71			size--;
 72		}
 73	}
 74	if (type & SPECIAL) {
 75		if (base == 16)
 76			size -= 2;
 77		else if (base == 8)
 78			size--;
 79	}
 80	i = 0;
 81	if (num == 0)
 82		tmp[i++]='0';
 83	else while (num != 0) {
 84		tmp[i++] = digits[do_div(num, base)];
 85	}
 86	if (i > precision)
 87		precision = i;
 88	size -= precision;
 89	if (!(type&(ZEROPAD+LEFT)))
 90		while(size-->0)
 91			*str++ = ' ';
 92	if (sign)
 93		*str++ = sign;
 94	if (type & SPECIAL) {
 95		if (base==8)
 96			*str++ = '0';
 97		else if (base==16) {
 98			*str++ = '0';
 99			*str++ = digits[33];
100		}
101	}
102	if (!(type & LEFT))
103		while (size-- > 0)
104			*str++ = c;
105	while (i < precision--)
106		*str++ = '0';
107	while (i-- > 0)
108		*str++ = tmp[i];
109	while (size-- > 0)
110		*str++ = ' ';
111	return str;
112}
113
114int vsprintf(char *buf, const char *fmt, va_list args)
115{
116	int len;
117	unsigned long long num;
118	int i, base;
119	char * str;
120	const char *s;
121
122	int flags;		/* flags to number() */
123
124	int field_width;	/* width of output field */
125	int precision;		/* min. # of digits for integers; max
126				   number of chars for from string */
127	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
128	                        /* 'z' support added 23/7/1999 S.H.    */
129				/* 'z' changed to 'Z' --davidm 1/25/99 */
130
131
132	for (str=buf ; *fmt ; ++fmt) {
133		if (*fmt != '%') {
134			*str++ = *fmt;
135			continue;
136		}
137
138		/* process flags */
139		flags = 0;
140		repeat:
141			++fmt;		/* this also skips first '%' */
142			switch (*fmt) {
143				case '-': flags |= LEFT; goto repeat;
144				case '+': flags |= PLUS; goto repeat;
145				case ' ': flags |= SPACE; goto repeat;
146				case '#': flags |= SPECIAL; goto repeat;
147				case '0': flags |= ZEROPAD; goto repeat;
148				}
149
150		/* get field width */
151		field_width = -1;
152		if ('0' <= *fmt && *fmt <= '9')
153			field_width = skip_atoi(&fmt);
154		else if (*fmt == '*') {
155			++fmt;
156			/* it's the next argument */
157			field_width = va_arg(args, int);
158			if (field_width < 0) {
159				field_width = -field_width;
160				flags |= LEFT;
161			}
162		}
163
164		/* get the precision */
165		precision = -1;
166		if (*fmt == '.') {
167			++fmt;
168			if ('0' <= *fmt && *fmt <= '9')
169				precision = skip_atoi(&fmt);
170			else if (*fmt == '*') {
171				++fmt;
172				/* it's the next argument */
173				precision = va_arg(args, int);
174			}
175			if (precision < 0)
176				precision = 0;
177		}
178
179		/* get the conversion qualifier */
180		qualifier = -1;
181		if (*fmt == 'l' && *(fmt + 1) == 'l') {
182			qualifier = 'q';
183			fmt += 2;
184		} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
185			|| *fmt == 'Z') {
186			qualifier = *fmt;
187			++fmt;
188		}
189
190		/* default base */
191		base = 10;
192
193		switch (*fmt) {
194		case 'c':
195			if (!(flags & LEFT))
196				while (--field_width > 0)
197					*str++ = ' ';
198			*str++ = (unsigned char) va_arg(args, int);
199			while (--field_width > 0)
200				*str++ = ' ';
201			continue;
202
203		case 's':
204			s = va_arg(args, char *);
205			if (!s)
206				s = "<NULL>";
207
208			len = strnlen(s, precision);
209
210			if (!(flags & LEFT))
211				while (len < field_width--)
212					*str++ = ' ';
213			for (i = 0; i < len; ++i)
214				*str++ = *s++;
215			while (len < field_width--)
216				*str++ = ' ';
217			continue;
218
219		case 'p':
220			if (field_width == -1) {
221				field_width = 2*sizeof(void *);
222				flags |= ZEROPAD;
223			}
224			str = number(str,
225				(unsigned long) va_arg(args, void *), 16,
226				field_width, precision, flags);
227			continue;
228
229
230		case 'n':
231			if (qualifier == 'l') {
232				long * ip = va_arg(args, long *);
233				*ip = (str - buf);
234			} else if (qualifier == 'Z') {
235				size_t * ip = va_arg(args, size_t *);
236				*ip = (str - buf);
237			} else {
238				int * ip = va_arg(args, int *);
239				*ip = (str - buf);
240			}
241			continue;
242
243		case '%':
244			*str++ = '%';
245			continue;
246
247		/* integer number formats - set up the flags and "break" */
248		case 'o':
249			base = 8;
250			break;
251
252		case 'X':
253			flags |= LARGE;
254		case 'x':
255			base = 16;
256			break;
257
258		case 'd':
259		case 'i':
260			flags |= SIGN;
261		case 'u':
262			break;
263
264		default:
265			*str++ = '%';
266			if (*fmt)
267				*str++ = *fmt;
268			else
269				--fmt;
270			continue;
271		}
272		if (qualifier == 'l') {
273			num = va_arg(args, unsigned long);
274			if (flags & SIGN)
275				num = (signed long) num;
276		} else if (qualifier == 'q') {
277			num = va_arg(args, unsigned long long);
278			if (flags & SIGN)
279				num = (signed long long) num;
280		} else if (qualifier == 'Z') {
281			num = va_arg(args, size_t);
282		} else if (qualifier == 'h') {
283			num = (unsigned short) va_arg(args, int);
284			if (flags & SIGN)
285				num = (signed short) num;
286		} else {
287			num = va_arg(args, unsigned int);
288			if (flags & SIGN)
289				num = (signed int) num;
290		}
291		str = number(str, num, base, field_width, precision, flags);
292	}
293	*str = '\0';
294	return str-buf;
295}
296
297int sprintf(char * buf, const char *fmt, ...)
298{
299	va_list args;
300	int i;
301
302	va_start(args, fmt);
303	i=vsprintf(buf,fmt,args);
304	va_end(args);
305	return i;
306}
v4.10.11
  1/*
  2 * Copyright (C) Paul Mackerras 1997.
  3 *
  4 * This program is free software; you can redistribute it and/or
  5 * modify it under the terms of the GNU General Public License
  6 * as published by the Free Software Foundation; either version
  7 * 2 of the License, or (at your option) any later version.
  8 */
  9#include <stdarg.h>
 10#include <stddef.h>
 11
 12size_t strnlen(const char * s, size_t count)
 13{
 14	const char *sc;
 15
 16	for (sc = s; count-- && *sc != '\0'; ++sc)
 17		/* nothing */;
 18	return sc - s;
 19}
 20
 21# define do_div(n, base) ({						\
 22	unsigned int __base = (base);					\
 23	unsigned int __rem;						\
 24	__rem = ((unsigned long long)(n)) % __base;			\
 25	(n) = ((unsigned long long)(n)) / __base;			\
 26	__rem;								\
 27})
 28
 29
 30static int skip_atoi(const char **s)
 31{
 32	int i, c;
 33
 34	for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
 35		i = i*10 + c - '0';
 36	return i;
 37}
 38
 39#define ZEROPAD	1		/* pad with zero */
 40#define SIGN	2		/* unsigned/signed long */
 41#define PLUS	4		/* show plus */
 42#define SPACE	8		/* space if plus */
 43#define LEFT	16		/* left justified */
 44#define SPECIAL	32		/* 0x */
 45#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
 46
 47static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
 48{
 49	char c,sign,tmp[66];
 50	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
 51	int i;
 52
 53	if (type & LARGE)
 54		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 55	if (type & LEFT)
 56		type &= ~ZEROPAD;
 57	if (base < 2 || base > 36)
 58		return 0;
 59	c = (type & ZEROPAD) ? '0' : ' ';
 60	sign = 0;
 61	if (type & SIGN) {
 62		if ((signed long long)num < 0) {
 63			sign = '-';
 64			num = - (signed long long)num;
 65			size--;
 66		} else if (type & PLUS) {
 67			sign = '+';
 68			size--;
 69		} else if (type & SPACE) {
 70			sign = ' ';
 71			size--;
 72		}
 73	}
 74	if (type & SPECIAL) {
 75		if (base == 16)
 76			size -= 2;
 77		else if (base == 8)
 78			size--;
 79	}
 80	i = 0;
 81	if (num == 0)
 82		tmp[i++]='0';
 83	else while (num != 0) {
 84		tmp[i++] = digits[do_div(num, base)];
 85	}
 86	if (i > precision)
 87		precision = i;
 88	size -= precision;
 89	if (!(type&(ZEROPAD+LEFT)))
 90		while(size-->0)
 91			*str++ = ' ';
 92	if (sign)
 93		*str++ = sign;
 94	if (type & SPECIAL) {
 95		if (base==8)
 96			*str++ = '0';
 97		else if (base==16) {
 98			*str++ = '0';
 99			*str++ = digits[33];
100		}
101	}
102	if (!(type & LEFT))
103		while (size-- > 0)
104			*str++ = c;
105	while (i < precision--)
106		*str++ = '0';
107	while (i-- > 0)
108		*str++ = tmp[i];
109	while (size-- > 0)
110		*str++ = ' ';
111	return str;
112}
113
114int vsprintf(char *buf, const char *fmt, va_list args)
115{
116	int len;
117	unsigned long long num;
118	int i, base;
119	char * str;
120	const char *s;
121
122	int flags;		/* flags to number() */
123
124	int field_width;	/* width of output field */
125	int precision;		/* min. # of digits for integers; max
126				   number of chars for from string */
127	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
128	                        /* 'z' support added 23/7/1999 S.H.    */
129				/* 'z' changed to 'Z' --davidm 1/25/99 */
130
131
132	for (str=buf ; *fmt ; ++fmt) {
133		if (*fmt != '%') {
134			*str++ = *fmt;
135			continue;
136		}
137
138		/* process flags */
139		flags = 0;
140		repeat:
141			++fmt;		/* this also skips first '%' */
142			switch (*fmt) {
143				case '-': flags |= LEFT; goto repeat;
144				case '+': flags |= PLUS; goto repeat;
145				case ' ': flags |= SPACE; goto repeat;
146				case '#': flags |= SPECIAL; goto repeat;
147				case '0': flags |= ZEROPAD; goto repeat;
148				}
149
150		/* get field width */
151		field_width = -1;
152		if ('0' <= *fmt && *fmt <= '9')
153			field_width = skip_atoi(&fmt);
154		else if (*fmt == '*') {
155			++fmt;
156			/* it's the next argument */
157			field_width = va_arg(args, int);
158			if (field_width < 0) {
159				field_width = -field_width;
160				flags |= LEFT;
161			}
162		}
163
164		/* get the precision */
165		precision = -1;
166		if (*fmt == '.') {
167			++fmt;
168			if ('0' <= *fmt && *fmt <= '9')
169				precision = skip_atoi(&fmt);
170			else if (*fmt == '*') {
171				++fmt;
172				/* it's the next argument */
173				precision = va_arg(args, int);
174			}
175			if (precision < 0)
176				precision = 0;
177		}
178
179		/* get the conversion qualifier */
180		qualifier = -1;
181		if (*fmt == 'l' && *(fmt + 1) == 'l') {
182			qualifier = 'q';
183			fmt += 2;
184		} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
185			|| *fmt == 'Z') {
186			qualifier = *fmt;
187			++fmt;
188		}
189
190		/* default base */
191		base = 10;
192
193		switch (*fmt) {
194		case 'c':
195			if (!(flags & LEFT))
196				while (--field_width > 0)
197					*str++ = ' ';
198			*str++ = (unsigned char) va_arg(args, int);
199			while (--field_width > 0)
200				*str++ = ' ';
201			continue;
202
203		case 's':
204			s = va_arg(args, char *);
205			if (!s)
206				s = "<NULL>";
207
208			len = strnlen(s, precision);
209
210			if (!(flags & LEFT))
211				while (len < field_width--)
212					*str++ = ' ';
213			for (i = 0; i < len; ++i)
214				*str++ = *s++;
215			while (len < field_width--)
216				*str++ = ' ';
217			continue;
218
219		case 'p':
220			if (field_width == -1) {
221				field_width = 2*sizeof(void *);
222				flags |= ZEROPAD;
223			}
224			str = number(str,
225				(unsigned long) va_arg(args, void *), 16,
226				field_width, precision, flags);
227			continue;
228
229
230		case 'n':
231			if (qualifier == 'l') {
232				long * ip = va_arg(args, long *);
233				*ip = (str - buf);
234			} else if (qualifier == 'Z') {
235				size_t * ip = va_arg(args, size_t *);
236				*ip = (str - buf);
237			} else {
238				int * ip = va_arg(args, int *);
239				*ip = (str - buf);
240			}
241			continue;
242
243		case '%':
244			*str++ = '%';
245			continue;
246
247		/* integer number formats - set up the flags and "break" */
248		case 'o':
249			base = 8;
250			break;
251
252		case 'X':
253			flags |= LARGE;
254		case 'x':
255			base = 16;
256			break;
257
258		case 'd':
259		case 'i':
260			flags |= SIGN;
261		case 'u':
262			break;
263
264		default:
265			*str++ = '%';
266			if (*fmt)
267				*str++ = *fmt;
268			else
269				--fmt;
270			continue;
271		}
272		if (qualifier == 'l') {
273			num = va_arg(args, unsigned long);
274			if (flags & SIGN)
275				num = (signed long) num;
276		} else if (qualifier == 'q') {
277			num = va_arg(args, unsigned long long);
278			if (flags & SIGN)
279				num = (signed long long) num;
280		} else if (qualifier == 'Z') {
281			num = va_arg(args, size_t);
282		} else if (qualifier == 'h') {
283			num = (unsigned short) va_arg(args, int);
284			if (flags & SIGN)
285				num = (signed short) num;
286		} else {
287			num = va_arg(args, unsigned int);
288			if (flags & SIGN)
289				num = (signed int) num;
290		}
291		str = number(str, num, base, field_width, precision, flags);
292	}
293	*str = '\0';
294	return str-buf;
295}
296
297int sprintf(char * buf, const char *fmt, ...)
298{
299	va_list args;
300	int i;
301
302	va_start(args, fmt);
303	i=vsprintf(buf,fmt,args);
304	va_end(args);
305	return i;
306}