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