mescc: Tinycc support: strncpy.
[mes.git] / lib / libc+tcc.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <setjmp.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <signal.h>
28 #include <sys/mman.h>
29 #include <sys/time.h>
30 #include <unistd.h>
31
32 int
33 dlclose (void *handle)
34 {
35   return 0;
36 }
37
38 void *
39 dlopen (char const *filename, int flags)
40 {
41   return 0;
42 }
43
44 int
45 execvp (char const *file, char *const argv[])
46 {
47   eputs ("execvp stub\n");
48   return 0;
49 }
50
51 int
52 fclose (FILE *stream)
53 {
54   int fd = (int)stream;
55   return close (fd);
56 }
57
58 FILE *
59 fdopen (int fd, char const *mode)
60 {
61   return (FILE*)fd;
62 }
63
64 int
65 ferror (FILE *stream)
66 {
67   int fd = (int)stream;
68   if (fd == -1) return -1;
69   return 0;
70 }
71
72 int
73 fflush (FILE *stream)
74 {
75   eputs ("fflush stub\n");
76   return 0;
77 }
78
79 FILE *
80 fopen (char const *pathname, char const *mode)
81 {
82   eputs ("fopen stub\n");
83   return 0;
84 }
85
86 int
87 fprintf (FILE *stream, char const *format, ...)
88 {
89   va_list ap;
90   va_start (ap, format);
91   int r = vfprintf (stream, format, ap);
92   va_end (ap);
93   return r;
94 }
95
96 size_t
97 fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
98 {
99   eputs ("fread stub\n");
100   return 0;
101 }
102
103 int
104 fseek (FILE *stream, long offset, int whence)
105 {
106   eputs ("fseek stub\n");
107   return 0;
108 }
109
110 long
111 ftell (FILE *stream)
112 {
113   eputs ("ftell stub\n");
114   return 0;
115 }
116
117 size_t
118 fwrite (void const *ptr, size_t size, size_t nmemb, FILE *stream)
119 {
120   int fd = (int)stream;
121   return write (fd, ptr, size * nmemb);
122 }
123
124 int
125 gettimeofday (struct timeval *tv, struct timezone *tz)
126 {
127   return 0;
128 }
129
130 double
131 ldexp (double x, int exp)
132 {
133   eputs ("ldexp stub\n");
134   return 0;
135 }
136
137 struct tm *
138 localtime (time_t const *timep)
139 {
140   eputs ("localtime stub\n");
141   return 0;
142 }
143
144 void *
145 memmove (void *dest, void const *src, size_t n)
146 {
147   if (dest < src)
148     return memcpy (dest, src, n);
149   char *p = dest + n;
150   char const *q = src +n;
151   while (n--)
152     *--p = *--q;
153   return dest;
154 }
155
156 void *
157 memset (void *s, int c, size_t n)
158 {
159   char *p = s;
160   while (n--) *p++ = c;
161   return s;
162 }
163
164 int
165 memcmp (void const *s1, void const *s2, size_t n)
166 {
167   char *a = s1;
168   char *b = s2;
169   while (*a == *b && --n) {a++;b++;}
170   return *a - *b;
171 }
172
173 int
174 mprotect (void *addr, size_t len, int prot)
175 {
176   return 0;
177 }
178
179 void
180 qswap (void *a, void *b, size_t size)
181 {
182   char *buf[8];
183   memcpy (buf, a, size);
184   memcpy (a, b, size);
185   memcpy (b, buf, size);
186 }
187
188 size_t
189 qpart (void *base, size_t count, size_t size, int (*compare)(void const *, void const *))
190 {
191   void* p = base + count*size;
192   size_t i = 0;
193   for (size_t j = 0; j < count; j++)
194     {
195       if (compare (base+j*size, p) < 0)
196         {
197           qswap (base+i*size, base+j*size, size);
198           i++;
199         }
200     }
201   if (compare (base+count*size, base+i*size) < 0)
202     qswap (base+i*size, base+count*size, size);
203   return i;
204 }
205
206 void
207 qsort (void *base, size_t count, size_t size, int (*compare)(void const *, void const *))
208 {
209   if (count > 1)
210     {
211       int p = qpart (base, count-1, size, compare);
212       qsort (base, p, size, compare);
213       qsort (base+p*size, count-p, size, compare);
214     }
215 }
216
217 int
218 remove (char const *file_name)
219 {
220   eputs ("remove stub\n");
221   return 0;
222 }
223
224 int
225 sigaction (int signum, struct sigaction const *act, struct sigaction *oldact)
226 {
227   return 0;
228 }
229
230 int
231 sigemptyset (sigset_t *set)
232 {
233   return 0;
234 }
235
236 int
237 snprintf(char *str,  size_t size,  char const *format, ...)
238 {
239   va_list ap;
240   va_start (ap, format);
241   int r = vsprintf (str, format, ap);
242   va_end (ap);
243   return r;
244 }
245
246 int
247 sscanf (char const *str, const char *format, ...)
248 {
249   eputs ("sscanf stub\n");
250   return 0;
251 }
252
253 char *
254 strcat (char *dest, char const *src)
255 {
256   char *p = strchr (dest, '\0');
257   while (*src++) *p++ = *src++;
258   *p = 0;
259   return dest;
260 }
261
262 char *
263 strchr (char const *s, int c)
264 {
265   char const *p = s;
266   while (*p || !c)
267     {
268       if (c == *p) return p;
269       *p++;
270     }
271   return 0;
272 }
273
274 char *
275 strncpy (char *dest, char const *src, size_t length)
276 {
277   char *p = dest;
278   while (*src && length--)
279     *p++ = *src++;
280   if (*src)
281     length++;
282   while (length--)
283     *p++ = 0;
284   return dest;
285 }
286
287 char *
288 strrchr (char const *s, int c)
289 {
290   int n = strlen (s);
291   if (!n) return 0;
292   char const *p = s + n - 1;
293   while (*p || !c)
294     {
295       if (c == *p) return p;
296       *p--;
297     }
298   return 0;
299 }
300
301 char *
302 strstr (char const *haystack, char const *needle)
303 {
304   eputs ("strstr stub\n");
305   return 0;
306 }
307
308 double
309 strtod (char const *nptr, char **endptr)
310 {
311   eputs ("strtoul stub\n");
312 }
313
314 float
315 strtof (char const *nptr, char **endptr)
316 {
317   return strtod (nptr, endptr);
318 }
319
320 long double
321 strtold (char const *nptr, char **endptr)
322 {
323   return strtod (nptr, endptr);
324 }
325
326 long
327 strtol (char const *nptr, char **endptr, int base)
328 {
329   if (!strncmp (nptr, "0x", 2))
330     {
331       char const *p = nptr + 2;
332       return abtoi (&p, 16);
333     }
334   return abtoi (&nptr, base);
335 }
336
337 long long int
338 strtoll (char const *nptr, char **endptr, int base)
339 {
340   eputs ("strtoll stub\n");
341   return 0;
342 }
343
344 unsigned long
345 strtoul (char const *nptr, char **endptr, int base)
346 {
347   eputs ("strtoul stub\n");
348   return 0;
349 }
350
351 unsigned long long
352 strtoull (char const *p, char **endptr, int base)
353 {
354   *endptr = p;
355   return abtoi (endptr, base);
356 }
357
358 time_t time (time_t *tloc)
359 {
360   return 0;
361 }
362
363 int
364 vsnprintf (char *str, size_t size, char const *format, va_list ap)
365 {
366   return vsprintf (str, format, ap);
367 }
368
369 void *
370 calloc (size_t nmemb, size_t size)
371 {
372   size_t count = nmemb * size;
373   void *p = malloc (count);
374   memset (p, 0, count);
375   return p;
376 }
377
378 int
379 vfprintf (FILE* f, char const* format, va_list ap)
380 {
381   int fd = (int)f;
382   char const *p = format;
383   while (*p)
384     if (*p != '%')
385       fputc (*p++, fd);
386     else
387       {
388         p++;
389         char c = *p;
390         switch (c)
391           {
392           case '%': {fputc (*p, fd); break;}
393           case 'c': {char c; c = va_arg (ap, char); fputc (c, fd); break;}
394           case 'd': {int d; d = va_arg (ap, int); fputs (itoa (d), fd); break;}
395           case 's': {char *s; s = va_arg (ap, char *); fputs (s, fd); break;}
396           default: {fputc (*p, fd); break;}
397           }
398         p++;
399       }
400   va_end (ap);
401   return 0;
402 }