build: Use arch-dir.
[mes.git] / lib / libc.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
4  * Copyright © 2018 Jeremiah Orians <jeremiah@pdp10.guru>
5  *
6  * This file is part of Mes.
7  *
8  * Mes is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * Mes is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <sys/ioctl.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <libmes.h>
26 #include <stdio.h>
27
28 #include <libmes.h>
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 #if __MESC__
34
35 #include <linux-mes.c>
36
37 #else // !__MESC__
38
39 #include <fcntl.h>
40 #include <assert.h>
41
42 #include <linux-gcc.c>
43
44 #endif // !__MESC__
45
46 #include <libc-mini.c>
47 #include <libmes.c>
48
49 int g_stdin = 0;
50
51 void _env ();
52
53 int
54 getchar ()
55 {
56   return fdgetc (g_stdin);
57 }
58
59 int
60 putchar (int c)
61 {
62   write (STDOUT, (char*)&c, 1);
63   return 0;
64 }
65
66 int
67 fputc (int c, FILE* stream)
68 {
69   return fdputc (c, (int)stream);
70 }
71
72 int
73 fputs (char const* s, FILE* stream)
74 {
75   return fdputs (s, (int)stream);
76 }
77
78 int
79 putc (int c, FILE* stream)
80 {
81   return fdputc (c, (int)stream);
82 }
83
84 FILE*
85 fopen (char const* file_name, char const* mode)
86 {
87   int fd;
88   if ('w' == mode[0])
89     /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
90     fd = open (file_name, 577 , 384);
91   else
92     /* Everything else is a read */
93     fd = open (file_name, 0, 0);
94
95   return (FILE*)fd;
96 }
97
98 void
99 assert_fail (char* s)
100 {
101   eputs ("assert fail: ");
102   eputs (s);
103   eputs ("\n");
104   char *fail = s;
105   fail = 0;
106   *fail = 0;
107 }
108
109 int
110 getc (FILE *stream)
111 {
112   return fdgetc ((int)stream);
113 }
114
115 int
116 fgetc (FILE *stream)
117 {
118   return fdgetc ((int)stream);
119 }
120
121 void
122 free (void *ptr)
123 {
124 }
125
126 int
127 ungetc (int c, FILE *stream)
128 {
129   return fdungetc (c, (int)stream);
130 }
131
132 int
133 strcmp (char const* a, char const* b)
134 {
135   while (*a && *b && *a == *b)
136     {
137       a++;b++;
138     }
139   return *a - *b;
140 }
141
142
143 char *
144 strcpy (char *dest, char const *src)
145 {
146   char *p = dest;
147   while (*src) *p++ = *src++;
148   *p = 0;
149   return dest;
150 }
151
152 char *g_brk = 0;
153
154 void *
155 malloc (size_t size)
156 {
157   if (!g_brk)
158     g_brk = brk (0);
159   if (brk (g_brk + size) == (void*)-1)
160     return 0;
161   char *p = g_brk;
162   g_brk += size;
163   return p;
164 }
165
166 void *
167 memcpy (void *dest, void const *src, size_t n)
168 {
169   char* p = dest;
170   char const* q = src;
171   while (n--) *p++ = *q++;
172   return dest;
173 }
174
175 void *
176 realloc (void *ptr, size_t size)
177 {
178   void *new = malloc (size);
179   if (ptr && new)
180     {
181       memcpy (new, ptr, size);
182       free (ptr);
183     }
184   return new;
185 }
186
187 int
188 strncmp (char const* a, char const* b, size_t length)
189 {
190   while (*a && *b && *a == *b && --length) {a++;b++;}
191   return *a - *b;
192 }
193
194 size_t
195 fwrite (void const *data, size_t size, size_t count, FILE *stream)
196 {
197   if (! size || !count)
198     return 0;
199   int bytes = write ((int)stream, data, size * count);
200   if (bytes > 0)
201     return count;
202   return bytes;
203 }
204
205 char *
206 getenv (char const* s)
207 {
208   char **p = g_environment;
209   int length = strlen (s);
210   while (*p)
211     {
212       if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
213       p++;
214     }
215   return 0;
216 }
217
218 int
219 setenv (char const* s, char const* v, int overwrite_p)
220 {
221   char **p = g_environment;
222   int length = strlen (s);
223   while (*p)
224     {
225       if (!strncmp (s, *p, length) && *(*p + length) == '=')
226         break;
227       p++;
228     }
229   char *entry = malloc (length + strlen (v) + 2);
230   int end_p = *p == 0;
231   *p = entry;
232   strcpy (entry, s);
233   strcpy (entry + length, "=");
234   strcpy (entry + length + 1, v);
235   *(entry + length + strlen (v) + 2) = 0;
236   if (end_p)
237     *++p = 0;
238   return 0;
239 }
240
241 int
242 vprintf (char const* format, va_list ap)
243 {
244   char const *p = format;
245   while (*p)
246     if (*p != '%')
247       putchar (*p++);
248     else
249       {
250         p++;
251         char c = *p;
252         switch (c)
253           {
254           case '%': {putchar (*p); break;}
255           case 'c': {char c; c = va_arg (ap, char); putchar (c); break;}
256           case 'd': {int d; d = va_arg (ap, int); puts (itoa (d)); break;}
257           case 's': {char *s; s = va_arg (ap, char *); puts (s); break;}
258           default: {putchar (*p); break;}
259           }
260         p++;
261       }
262   va_end (ap);
263   return 0;
264 }
265
266 int
267 printf (char const* format, ...)
268 {
269   va_list ap;
270   va_start (ap, format);
271   int r = vprintf (format, ap);
272   va_end (ap);
273   return r;
274 }
275
276 int
277 vsprintf (char *str, char const* format, va_list ap)
278 {
279   char const *p = format;
280   while (*p)
281     if (*p != '%')
282       *str++ = *p++;
283     else
284       {
285         p++;
286         char c = *p;
287         switch (c)
288           {
289           case '%': {*str++ = *p; break;}
290           case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;}
291           case 'd': {int d; d = va_arg (ap, int); char const *s; s = itoa (d); while (*s) *str++ = *s++; break;}
292           case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;}
293           default: {*str++ = *p; break;}
294           }
295         p++;
296       }
297   va_end (ap);
298   *str = 0;
299   return strlen (str);
300 }
301
302 int
303 sprintf (char *str, char const* format, ...)
304 {
305   va_list ap;
306   va_start (ap, format);
307   int r = vsprintf (str, format, ap);
308   va_end (ap);
309   return r;
310 }
311
312 int
313 isatty (int fd)
314 {
315   return ioctl (fd, TCGETS, 0) & 0xf0;
316 }
317
318 int
319 wait (int *status_ptr)
320 {
321   return waitpid  (-1, status_ptr, 0);
322 }