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