1 /*
2  * Renesas SCP/MCP Software
3  * Copyright (c) 2020-2021, Renesas Electronics Corporation. All rights
4  * reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include <fwk_arch.h>
10 #include <fwk_macros.h>
11 
12 #include <stdarg.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <string.h>
16 
memset(void * s,int c,size_t count)17 void *memset(void *s, int c, size_t count)
18 {
19     char *xs = s;
20     while (count--)
21         *xs++ = (char)c;
22     return s;
23 }
24 
memcpy(void * dst,const void * src,size_t n)25 void *memcpy(void *dst, const void *src, size_t n)
26 {
27     /* copy per 1 byte */
28     const char *p = src;
29     char *q = dst;
30 
31     while (n--) {
32         *q++ = *p++;
33     }
34 
35     return dst;
36 }
37 
strncpy(char * dest,const char * src,size_t n)38 char *strncpy(char *dest, const char *src, size_t n)
39 {
40     size_t i;
41 
42     for (i = 0; i < n && src[i] != 0; i++)
43         dest[i] = src[i];
44     for (; i < n; i++)
45         dest[i] = '\0';
46 
47     return dest;
48 }
49 
strchr(const char * str,int c)50 char *strchr(const char *str, int c)
51 {
52     do {
53         if (*str == (char)c)
54             return (char *)str;
55         str++;
56     } while (*str);
57 
58     return NULL;
59 }
60 
strlen(const char * str)61 size_t strlen(const char *str)
62 {
63     char *tmp = (char *)str;
64     size_t counter = 0;
65     while (*tmp++)
66         ++counter;
67     return counter;
68 }
69 
uint_to_str(unsigned int i,char * buf,int base)70 static void uint_to_str(unsigned int i, char *buf, int base)
71 {
72     char const digit_10[] = "0123456789";
73     char const digit_16[] = "0123456789abcdef";
74     unsigned int shifter = i;
75     char const *digit;
76 
77     if (base == 10)
78         digit = digit_10;
79     else
80         digit = digit_16;
81 
82     do {
83         ++buf;
84         shifter = shifter / base;
85     } while (shifter);
86 
87     *buf = '\0';
88 
89     do {
90         *--buf = digit[i % base];
91         i = i / base;
92     } while (i);
93 }
94 
int_to_str(int i,char * buf,int base)95 static void int_to_str(int i, char *buf, int base)
96 {
97     int sign = i;
98 
99     if (i < 0) {
100         i = -i;
101         buf++;
102     }
103 
104     uint_to_str((unsigned int)i, buf, base);
105 
106     if (sign < 0)
107         *--buf = '-';
108 }
109 
isdigit(char c)110 static int isdigit(char c)
111 {
112     return (int)(c >= '0' && c <= '9');
113 }
114 
handle_num(char type,char * buf,va_list * args)115 static int handle_num(char type, char *buf, va_list *args)
116 {
117     int int_num;
118     unsigned int uint_num;
119 
120     switch (type) {
121     case 'u':
122         uint_num = va_arg(*args, unsigned int);
123         uint_to_str(uint_num, buf, 10);
124         break;
125     case 'd':
126         int_num = va_arg(*args, int);
127         int_to_str(int_num, buf, 10);
128         break;
129     case 'x':
130         uint_num = va_arg(*args, unsigned int);
131         uint_to_str(uint_num, buf, 16);
132         break;
133     default:
134         return 1;
135         break;
136     }
137 
138     return 0;
139 }
140 
vsnprintf(char * str,size_t n,const char * format,va_list args)141 int vsnprintf(char *str, size_t n, const char *format, va_list args)
142 {
143     char *pos;
144     char *s;
145     char *tmp = str;
146     size_t length = 0;
147     int num_length, min_length;
148     char num_buf[12];
149     int not_implemented;
150 
151     for (pos = (char *)format; *pos != '\0'; pos++) {
152         while ((*pos != '%') && (*pos != '\0') && (length < n)) {
153             *tmp++ = *pos++;
154             length++;
155         }
156 
157         if (length == n)
158             break;
159 
160         if (*pos == '\0') {
161             *tmp = '\0';
162             break;
163         }
164 
165         pos++;
166 
167         not_implemented = 0;
168 
169         switch (*pos) {
170         case 's':
171             s = va_arg(args, char *);
172             strncpy(tmp, s, n - length);
173             break;
174         case '0':
175             if (isdigit(*(pos + 1)) && (*(pos + 1) > '0')) {
176                 pos++;
177             } else {
178                 not_implemented = 1;
179                 break;
180             }
181         case '1':
182         case '2':
183         case '3':
184         case '4':
185         case '5':
186         case '6':
187         case '7':
188         case '8':
189         case '9':
190             min_length = (int)(*pos - '0');
191 
192             if (handle_num(*(pos + 1), num_buf, &args)) {
193                 if (*(pos - 1) == '0')
194                     pos--;
195 
196                 not_implemented = 1;
197                 break;
198             }
199 
200             num_length = (int)strlen(num_buf);
201 
202             if (num_length < min_length) {
203                 while (num_length >= 0)
204                     num_buf[min_length--] = num_buf[num_length--];
205 
206                 if (*(pos - 1) == '0') {
207                     if (num_buf[0] == '-') {
208                         min_length++;
209                         while (min_length > 0)
210                             num_buf[min_length--] = '0';
211                     } else {
212                         while (min_length >= 0)
213                             num_buf[min_length--] = '0';
214                     }
215                 } else {
216                     while (min_length >= 0)
217                         num_buf[min_length--] = ' ';
218                 }
219             }
220             strncpy(tmp, num_buf, n - length);
221             pos++;
222             break;
223         default:
224             if (handle_num(*pos, num_buf, &args))
225                 not_implemented = 1;
226             else
227                 strncpy(tmp, num_buf, n - length);
228             break;
229         }
230 
231         if (not_implemented) {
232             va_arg(args, unsigned int);
233             *tmp++ = '%';
234             length++;
235             pos--;
236         } else {
237             while ((*tmp != '\0') && (length < n)) {
238                 tmp++;
239                 length++;
240             }
241         }
242     }
243 
244     if (tmp == str) {
245         *tmp = '\0';
246     } else if (length == n) {
247         tmp--;
248         if (*tmp != '\0')
249             *tmp = '\0';
250         else
251             length--;
252     } else if (*(tmp - 1) != '\0') {
253         *tmp = '\0';
254     } else {
255         length--;
256     }
257 
258     return (int)length;
259 }
260 
snprintf(char * str,size_t size,const char * format,...)261 int snprintf(char *str, size_t size, const char *format, ...)
262 {
263     int counter;
264     va_list args;
265     va_start(args, format);
266     counter = vsnprintf(str, size, format, args);
267     va_end(args);
268     return counter;
269 }
270 
__assert_fail(const char * assertion,const char * file,unsigned int line,const char * function)271 void __assert_fail(
272     const char *assertion,
273     const char *file,
274     unsigned int line,
275     const char *function)
276 {
277     while (1)
278         continue;
279 }
280