xref: /illumos-gate/usr/src/boot/common/util.c (revision dd72704bd9e794056c558153663c739e2012d721)
1 /*-
2  * Copyright (c) 1998 Robert Nordier
3  * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms are freely
7  * permitted provided that the above copyright notice and this
8  * paragraph and the following disclaimer are duplicated in all
9  * such forms.
10  *
11  * This software is provided "AS IS" and without any express or
12  * implied warranties, including, without limitation, the implied
13  * warranties of merchantability and fitness for a particular
14  * purpose.
15  */
16 
17 #include <sys/cdefs.h>
18 __FBSDID("$FreeBSD$");
19 
20 #include <sys/param.h>
21 
22 #include <stdarg.h>
23 
24 #include "cons.h"
25 #include "util.h"
26 
27 void
28 memcpy(void *dst, const void *src, int len)
29 {
30 	const char *s = src;
31 	char *d = dst;
32 
33 	while (len--)
34 		*d++ = *s++;
35 }
36 
37 void
38 memset(void *b, int c, size_t len)
39 {
40 	char *bp = b;
41 
42 	while (len--)
43 		*bp++ = (unsigned char)c;
44 }
45 
46 int
47 memcmp(const void *b1, const void *b2, size_t len)
48 {
49 	const unsigned char *p1, *p2;
50 
51 	for (p1 = b1, p2 = b2; len > 0; len--, p1++, p2++) {
52 		if (*p1 != *p2)
53 			return ((*p1) - (*p2));
54 	}
55 	return (0);
56 }
57 
58 int
59 strcmp(const char *s1, const char *s2)
60 {
61 
62 	for (; *s1 == *s2 && *s1 != '\0'; s1++, s2++)
63 		;
64 	return ((unsigned char)*s1 - (unsigned char)*s2);
65 }
66 
67 int
68 strncmp(const char *s1, const char *s2, size_t len)
69 {
70 
71 	for (; len > 0 && *s1 == *s2 && *s1 != '\0'; len--, s1++, s2++)
72 		;
73 	return (len == 0 ? 0 : (unsigned char)*s1 - (unsigned char)*s2);
74 }
75 
76 void
77 strcpy(char *dst, const char *src)
78 {
79 
80 	while (*src != '\0')
81 		*dst++ = *src++;
82 	*dst = '\0';
83 }
84 
85 void
86 strcat(char *dst, const char *src)
87 {
88 
89 	while (*dst != '\0')
90 		dst++;
91 	while (*src != '\0')
92 		*dst++ = *src++;
93 	*dst = '\0';
94 }
95 
96 char *
97 strchr(const char *s, char ch)
98 {
99 
100 	for (; *s != '\0'; s++) {
101 		if (*s == ch)
102 			return ((char *)(uintptr_t)(const void *)s);
103 	}
104 	return (NULL);
105 }
106 
107 size_t
108 strlen(const char *s)
109 {
110 	size_t len = 0;
111 
112 	while (*s++ != '\0')
113 		len++;
114 	return (len);
115 }
116 
117 int
118 printf(const char *fmt, ...)
119 {
120 	va_list ap;
121 	const char *hex = "0123456789abcdef";
122 	char buf[32], *s;
123 	uint16_t *S;
124 	unsigned long long u;
125 	int c, l;
126 
127 	va_start(ap, fmt);
128 	while ((c = *fmt++) != '\0') {
129 		if (c != '%') {
130 			putchar(c);
131 			continue;
132 		}
133 		l = 0;
134 nextfmt:
135 		c = *fmt++;
136 		switch (c) {
137 		case 'l':
138 			l++;
139 			goto nextfmt;
140 		case 'c':
141 			putchar(va_arg(ap, int));
142 			break;
143 		case 's':
144 			for (s = va_arg(ap, char *); *s != '\0'; s++)
145 				putchar(*s);
146 			break;
147 		case 'S':	/* Assume console can cope with wide chars */
148 			for (S = va_arg(ap, uint16_t *); *S != 0; S++)
149 				putchar(*S);
150 			break;
151 		case 'd':	/* A lie, always prints unsigned */
152 		case 'u':
153 		case 'x':
154 			switch (l) {
155 			case 2:
156 				u = va_arg(ap, unsigned long long);
157 				break;
158 			case 1:
159 				u = va_arg(ap, unsigned long);
160 				break;
161 			default:
162 				u = va_arg(ap, unsigned int);
163 				break;
164 			}
165 			s = buf;
166 			if (c == 'd' || c == 'u') {
167 				do
168 					*s++ = '0' + (u % 10U);
169 				while (u /= 10);
170 			} else {
171 				do
172 					*s++ = hex[u & 0xfu];
173 				while (u >>= 4);
174 			}
175 			while (--s >= buf)
176 				putchar(*s);
177 			break;
178 		}
179 	}
180 	va_end(ap);
181 	return (0);
182 }
183