1 /* -*-comment-start: "//";comment-end:""-*-
2 * Mes --- Maxwell Equations of Software
3 * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
4 * Copyright © 2018 Jeremiah Orians <jeremiah@pdp10.guru>
5 * Copyright (C) 2018 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 * This file is part of Mes.
9 * Mes is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
14 * Mes is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Mes. If not, see <http://www.gnu.org/licenses/>.
38 #include <linux+tcc.c>
42 #include <libc+tcc-mes.c>
46 #include <libc+tcc-gcc.c>
51 dlclose (void *handle)
57 dlopen (char const *filename, int flags)
63 search_path (char const *file_name)
66 char *path = getenv ("PATH");
67 if (getenv ("MESC_DEBUG"))
69 eputs ("\n search-path: "); eputs (file_name); eputs ("\n");
73 char *end = strchr (path, ':');
75 end = strchr (path, '\0');
76 strncpy (buf, path, end - path);
78 if (getenv ("MESC_DEBUG"))
80 eputs (" dir: "); eputs (buf); eputs ("\n");
82 if (buf[end - path] != '/')
84 strcat (buf, file_name);
85 if (!access (buf, X_OK))
87 if (getenv ("MESC_DEBUG"))
89 eputs (" found: "); eputs (buf); eputs ("\n");
99 execvp (char const *file_name, char *const argv[])
101 if (file_name[0] != '/')
102 file_name = search_path (file_name);
108 if (getenv ("MESC_DEBUG"))
110 eputs (" EXEC: "); eputs (file_name); eputs ("\n");
114 eputs (" arg["); eputs (itoa (i)); eputs ("]: "); eputs (argv[i]); eputs ("\n");
118 return execve (file_name, argv, environ);
122 fclose (FILE *stream)
124 int fd = (int)stream;
129 fdopen (int fd, char const *mode)
135 ferror (FILE *stream)
137 int fd = (int)stream;
138 if (fd == -1) return -1;
143 fflush (FILE *stream)
149 fprintf (FILE *stream, char const *format, ...)
152 va_start (ap, format);
153 int r = vfprintf (stream, format, ap);
159 fread (void *data, size_t size, size_t count, FILE *stream)
161 if (! size || !count)
163 int bytes = read ((int)stream, data, size * count);
171 fwrite (void const *data, size_t size, size_t count, FILE *stream)
173 if (getenv ("MESC_DEBUG"))
175 eputs ("fwrite "); eputs (itoa ((int)stream));
176 eputs (" "); eputs (itoa (size)); eputs ("\n");
179 if (! size || !count)
181 int bytes = write ((int)stream, data, size * count);
183 if (getenv ("MESC_DEBUG"))
185 eputs (" => "); eputs (itoa (bytes)); eputs ("\n");
196 return lseek ((int)stream, 0, SEEK_CUR);
200 fopen (char const *file_name, char const *opentype)
202 if (getenv ("MESC_DEBUG"))
204 eputs ("fopen "); eputs (file_name);
205 eputs (" "); eputs (opentype); eputs ("\n");
210 if ((opentype[0] == 'a' || !strcmp (opentype, "r+"))
211 && !access (file_name, O_RDONLY))
213 fd = open (file_name, O_RDWR, mode);
214 if (opentype[0] == 'a')
215 lseek (fd, 0, SEEK_END);
217 else if (opentype[0] == 'w' || opentype[0] == 'a' || !strcmp (opentype, "r+"))
219 char *plus_p = strchr (opentype, '+');
220 int flags = plus_p ? O_RDWR | O_CREAT : O_WRONLY | O_CREAT | O_TRUNC;
221 fd = open (file_name, flags, mode);
224 fd = open (file_name, 0, 0);
226 if (getenv ("MESC_DEBUG"))
228 eputs (" => fd="); eputs (itoa (fd)); eputs ("\n");
235 fseek (FILE *stream, long offset, int whence)
237 int pos = lseek ((int)stream, offset, whence);
244 gettimeofday (struct timeval *tv, struct timezone *tz)
247 eputs ("gettimeofday stub\n");
254 ldexp (double x, int exp)
256 eputs ("ldexp stub\n");
261 localtime (time_t const *timep)
264 eputs ("localtime stub\n");
271 memmove (void *dest, void const *src, size_t n)
274 return memcpy (dest, src, n);
276 char const *q = src +n;
283 memset (void *s, int c, size_t n)
286 while (n--) *p++ = c;
291 memcmp (void const *s1, void const *s2, size_t n)
295 while (*a == *b && --n) {a++;b++;}
300 mprotect (void *addr, size_t len, int prot)
306 qswap (void *a, void *b, size_t size)
309 memcpy (buf, a, size);
311 memcpy (b, buf, size);
315 qpart (void *base, size_t count, size_t size, int (*compare)(void const *, void const *))
317 void* p = base + count*size;
319 for (size_t j = 0; j < count; j++)
321 if (compare (base+j*size, p) < 0)
323 qswap (base+i*size, base+j*size, size);
327 if (compare (base+count*size, base+i*size) < 0)
328 qswap (base+i*size, base+count*size, size);
333 qsort (void *base, size_t count, size_t size, int (*compare)(void const *, void const *))
337 int p = qpart (base, count-1, size, compare);
338 qsort (base, p, size, compare);
339 qsort (base+p*size, count-p, size, compare);
344 remove (char const *file_name)
347 if (stat (file_name, &buf) < 0)
349 if (S_ISDIR (buf.st_mode))
350 return rmdir (file_name);
351 return unlink (file_name);
355 sigaction (int signum, struct sigaction const *act, struct sigaction *oldact)
361 sigemptyset (sigset_t *set)
367 snprintf(char *str, size_t size, char const *format, ...)
370 va_start (ap, format);
371 int r = vsprintf (str, format, ap);
377 sscanf (char const *str, const char *template, ...)
380 va_start (ap, template);
381 int r = vsscanf (str, template, ap);
387 strcat (char *to, char const *from)
389 char *p = strchr (to, '\0');
397 strchr (char const *s, int c)
410 strncpy (char *to, char const *from, size_t size)
415 while (*from && size--)
425 strrchr (char const *s, int c)
429 char const *p = s + n - 1;
432 if (c == *p) return p;
438 /** locate a substring. #memmem# finds the first occurrence of
439 #needle# in #haystack#. This is not ANSI-C.
441 The prototype is not in accordance with the Linux Programmer's
442 Manual v1.15, but it is with /usr/include/string.h */
445 _memmem (unsigned char const *haystack, int haystack_len,
446 unsigned char const *needle, int needle_len)
448 unsigned char const *end_haystack = haystack + haystack_len - needle_len + 1;
449 unsigned char const *end_needle = needle + needle_len;
451 /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation
452 is the spice of life */
453 while (haystack < end_haystack)
455 unsigned char const *subneedle = needle;
456 unsigned char const *subhaystack = haystack;
457 while (subneedle < end_needle)
458 if (*subneedle++ != *subhaystack++)
461 /* Completed the needle. Gotcha. */
462 return (unsigned char *) haystack;
470 memmem (void const *haystack, int haystack_len,
471 void const *needle, int needle_len)
473 unsigned char const *haystack_byte_c = (unsigned char const *)haystack;
474 unsigned char const *needle_byte_c = (unsigned char const *)needle;
475 return _memmem (haystack_byte_c, haystack_len, needle_byte_c, needle_len);
479 strstr (char const *haystack, char const *needle)
481 return memmem (haystack, strlen (haystack), needle, strlen (needle));
485 strtod (char const *string, char **tailptr)
488 eputs ("strtod stub\n");
494 strtof (char const *string, char **tailptr)
496 return strtod (string, tailptr);
500 strtold (char const *string, char **tailptr)
502 return strtod (string, tailptr);
506 strtol (char const *string, char **tailptr, int base)
508 if (!strncmp (string, "0x", 2))
516 return abtoi (tailptr, base);
519 return abtoi (p, base);
525 strtoll (char const *string, char **tailptr, int base)
527 return strtol (string, tailptr, base);
531 strtoul (char const *string, char **tailptr, int base)
533 return strtol (string, tailptr, base);
537 strtoull (char const *string, char **tailptr, int base)
539 return strtol (string, tailptr, base);
545 strtoll (char const *string, char **tailptr, int base)
547 eputs ("strtoll stub\n");
552 strtoul (char const *string, char **tailptr, int base)
554 eputs ("strtoul stub\n");
559 strtoull (char const *string, char **tailptr, int base)
562 // return abtoi (endptr, base);
563 eputs ("strtoull stub\n");
573 eputs ("time stub\n");
580 vsnprintf (char *str, size_t size, char const *format, va_list ap)
582 return vsprintf (str, format, ap);
586 calloc (size_t nmemb, size_t size)
588 size_t count = nmemb * size;
589 void *p = malloc (count);
590 memset (p, 0, count);
597 return c >= 'a' && c <= 'z';
603 return c >= 'A' && c <= 'Z';
610 return c + ('a' - 'A');
618 return c - ('a' - 'A');
623 strlwr (char *string)
635 strupr (char *string)
647 vfprintf (FILE* f, char const* format, va_list ap)
650 char const *p = format;
683 if (c >= '0' && c <= '9')
685 width = abtoi (&p, 10);
690 width = va_arg (ap, int);
697 case '%': {fputc (*p, fd); count++; break;}
698 case 'c': {char c; c = va_arg (ap, int); fputc (c, fd); break;}
706 int d = va_arg (ap, int);
707 int base = c == 'o' ? 8
708 : c == 'x' || c == 'X' ? 16
710 char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X');
713 if (!precision_p && width >= 0)
714 width = width - strlen (s);
715 if (!left_p && !precision_p)
716 while (!precision_p && width-- > 0)
723 if (precision_p && width-- == 0)
728 while (!precision_p && width-- > 0)
737 char *s = va_arg (ap, char *);
738 if (!precision_p && width >= 0)
739 width = width - strlen (s);
740 if (!left_p && !precision_p)
741 while (!precision_p && width-- > 0)
748 if (precision_p && width-- == 0)
753 while (!precision_p && width-- > 0)
762 int *n = va_arg (ap, int *);
768 eputs ("vfprintf: not supported: %");
781 vprintf (char const* format, va_list ap)
783 return vfprintf (STDOUT, format, ap);
787 vsscanf (char const *s, char const *template, va_list ap)
790 char const *t = template;
804 case '%': {p++; break;}
807 char *c = va_arg (ap, char*);
816 int *d = va_arg (ap, int*);
823 eputs ("vsscanf: not supported: %");
837 vsprintf (char *str, char const* format, va_list ap)
839 char const *p = format;
872 if (c >= '0' && c <= '9')
874 width = abtoi (&p, 10);
879 width = va_arg (ap, int);
886 case '%': {*str++ = *p; count++; break;}
887 case 'c': {c = va_arg (ap, int); *str++ = c; count++; break;}
895 int d = va_arg (ap, int);
896 int base = c == 'o' ? 8
897 : c == 'x' || c == 'X' ? 16
899 char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X');
902 if (!precision_p && width >= 0)
903 width = width - strlen (s);
904 if (!left_p && !precision_p)
905 while (!precision_p && width-- > 0)
912 if (precision_p && width-- == 0)
917 while (!precision_p && width-- > 0)
926 char *s = va_arg (ap, char *);
927 if (!precision_p && width >= 0)
928 width = width - strlen (s);
929 if (!left_p && !precision_p)
930 while (!precision_p && width-- > 0)
937 if (precision_p && width-- == 0)
942 while (!precision_p && width-- > 0)
951 int *n = va_arg (ap, int *);
957 eputs ("vsprintf: not supported: %");
971 sprintf (char *str, char const* format, ...)
974 va_start (ap, format);
975 int r = vsprintf (str, format, ap);
981 printf (char const* format, ...)
984 va_start (ap, format);
985 int r = vprintf (format, ap);