670eaca4b926a92cc2b34e2ca60cbe632303bdf0
[mes.git] / lib / libc-mes.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017 Jan 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 <stdarg.h>
22 #include <stdlib.h>
23
24 char **g_environment = 0; // FIXME: todo extern
25 int g_stdin = 0;
26
27 void _env ();
28
29 void
30 exit ()
31 {
32   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
33
34   asm ("mov____$i32,%eax SYS_exit");              // mov    $0x1,%eax
35   asm ("int____$0x80");                           // int    $0x80
36 }
37
38 void
39 read ()
40 {
41   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
42   asm ("mov____0x8(%ebp),%ecx !12");              // mov    0x8(%ebp),%ecx
43   asm ("mov____0x8(%ebp),%edx !16");              // mov    0x8(%ebp),%edx
44
45   asm ("mov____$i32,%eax SYS_read");              // mov    $0x3,%eax
46   asm ("int____$0x80");                           // int    $0x80
47 }
48
49 void
50 write ()
51 {
52   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
53   asm ("mov____0x8(%ebp),%ecx !12");              // mov    0x8(%ebp),%ecx
54   asm ("mov____0x8(%ebp),%edx !16");              // mov    0x8(%ebp),%edx
55
56   asm ("mov____$i32,%eax SYS_write");             // mov    $0x4,%eax
57   asm ("int____$0x80");                           // int    $0x80
58 }
59
60 void
61 open ()
62 {
63   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
64   asm ("mov____0x8(%ebp),%ecx !12");              // mov    0x8(%ebp),%ecx
65   asm ("mov____0x8(%ebp),%edx !16");              // mov    0x8(%ebp),%edx
66
67   asm ("mov____$i32,%eax SYS_open");              // mov    $0x5,%eax
68   asm ("int____$0x80");                           // int    $0x80
69 }
70
71 void
72 chmod ()
73 {
74   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
75   asm ("mov____0x8(%ebp),%ecx !12");              // mov    0x8(%ebp),%ecx
76
77   asm ("mov____$i32,%eax SYS_chmod");             // mov    $0x0f,%eax
78   asm ("int____$0x80");                           // int    $0x80
79 }
80
81 void
82 access ()
83 {
84   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
85   asm ("mov____0x8(%ebp),%ecx !12");              // mov    0x8(%ebp),%ecx
86
87   asm ("mov____$i32,%eax SYS_access");            // mov    $0x21,%eax
88   asm ("int____$0x80");                           // int    $0x80
89 }
90
91 void
92 brk ()
93 {
94   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
95
96   asm ("mov____$i32,%eax SYS_brk");               // mov    $0x2d,%eax
97   asm ("int____$0x80");                           // int    $0x80
98 }
99
100 void
101 fsync ()
102 {
103   asm ("mov____0x8(%ebp),%ebx !8");               // mov    0x8(%ebp),%ebx
104
105   asm ("mov____$i32,%eax SYS_fsync");             // mov    $0x7c,%eax
106   asm ("int____$0x80");                           // int    $0x80
107 }
108
109 int
110 strlen (char const* s)
111 {
112   int i = 0;
113   while (s[i]) i++;
114   return i;
115 }
116
117 int
118 eputc (int c)
119 {
120   return fputc (c, 2);
121 }
122
123 int
124 eputs (char const* s)
125 {
126   int i = strlen (s);
127   write (2, s, i);
128   return 0;
129 }
130
131 int
132 fputs (char const* s, int fd)
133 {
134   int i = strlen (s);
135   write (fd, s, i);
136   return 0;
137 }
138
139 int
140 puts (char const* s)
141 {
142   int i = strlen (s);
143   write (1, s, i);
144   return 0;
145 }
146
147 int
148 putchar (int c)
149 {
150   write (1, (char*)&c, 1);
151   return 0;
152 }
153
154 int
155 fputc (int c, int fd)
156 {
157   write (fd, (char*)&c, 1);
158   return 0;
159 }
160
161 void
162 assert_fail (char* s)
163 {
164   eputs ("assert fail: ");
165   eputs (s);
166   eputs ("\n");
167   //*((int*)0) = 0;
168   char *fail = s;
169   fail = 0;
170   *fail = 0;
171 }
172
173 int ungetc_char = -1;
174 char ungetc_buf[2];
175
176 int
177 getchar ()
178 {
179   char c;
180   int i;
181   if (ungetc_char == -1)
182     {
183       int r = read (g_stdin, &c, 1);
184       if (r < 1) return -1;
185       i = c;
186    }
187   else
188     {
189        //FIXME
190        //i = ungetc_buf[ungetc_char--];
191        i = ungetc_buf[ungetc_char];
192        //ungetc_char--;
193        ungetc_char = ungetc_char - 1;
194      }
195   if (i < 0) i += 256;
196
197   return i;
198 }
199
200 int
201 fgetc (int fd)
202 {
203   char c;
204   int i;
205   int r = read (fd, &c, 1);
206   if (r < 1) return -1;
207   i = c;
208   return i;
209 }
210
211 void
212 free (void *ptr)
213 {
214 }
215
216 //#define assert(x) ((x) ? (void)0 : assert_fail (#x))
217 int
218 ungetc (int c, int fd)
219 {
220   //FIXME
221   //assert (ungetc_char < 2);
222   //assert (ungetc_char == -1 || ungetc_char < 2);
223   //FIXME
224   //ungetc_buf[++ungetc_char] = c;
225   ungetc_char++;
226   ungetc_buf[ungetc_char] = c;
227   return c;
228 }
229
230 int
231 strcmp (char const* a, char const* b)
232 {
233   while (*a && *b && *a == *b)
234     {
235       a++;b++;
236     }
237   return *a - *b;
238 }
239
240
241 char *
242 strcpy (char *dest, char const *src)
243 {
244   char *p = dest;
245   while (*src) *p++ = *src++;
246   *p = 0;
247   return dest;
248 }
249
250 char itoa_buf[10];
251
252 char const*
253 itoa (int x)
254 {
255   //static char itoa_buf[10];
256   //char *p = buf+9;
257   char *p = itoa_buf;
258   p += 9;
259   *p-- = 0;
260
261   //int sign = x < 0; // FIXME
262   int sign = 0;
263   if (x < 0) sign = 1;
264   if (sign)
265     x = -x;
266
267   do
268      {
269        *p-- = '0' + (x % 10);
270        x = x / 10;
271      } while (x);
272
273   if (sign && *(p + 1) != '0')
274     *p-- = '-';
275
276   return p+1;
277 }
278
279 int
280 isdigit (int c)
281 {
282   return (c>='0') && (c<='9');
283 }
284
285 int
286 isxdigit (int c)
287 {
288   return isdigit (c) || (c>='a') && (c<='f');
289 }
290
291 int
292 isnumber (int c, int base)
293 {
294   if (base == 2)
295     return (c>='0') && (c<='1');
296   if (base == 8)
297     return (c>='0') && (c<='7');
298   if (base == 10)
299     return isdigit (c);
300   if (base == 16)
301     return isxdigit (c);
302 }
303
304 int
305 _atoi (char const **p, int base)
306 {
307   char const *s = *p;
308   int i = 0;
309   int sign = 1;
310   if (!base) base = 10;
311   if (*s && *s == '-')
312     {
313       sign = -1;
314       s++;
315     }
316   while (isnumber (*s, base))
317     {
318       i *= base;
319       int m = *s > '9' ? 'a' - 10 : '0';
320       i += *s - m;
321       s++;
322     }
323   *p = s;
324   return i * sign;
325 }
326
327 int
328 atoi (char const *s)
329 {
330   char const *p = s;
331   return _atoi (&p, 0);
332 }
333
334 char *g_brk = 0;
335
336 void *
337 malloc (size_t size)
338 {
339   if (!g_brk)
340     g_brk = brk (0);
341   if (brk (g_brk + size) == -1)
342     return 0;
343   char *p = g_brk;
344   g_brk += size;
345   return p;
346 }
347
348 void *
349 memcpy (void *dest, void const *src, size_t n)
350 {
351   char* p = dest;
352   char* q = src;
353   while (n--) *p++ = *q++;
354   return dest;
355 }
356
357 void *
358 realloc (void *ptr, size_t size)
359 {
360   void *new = malloc (size);
361   if (ptr && new)
362     {
363       memcpy (new, ptr, size);
364       free (ptr);
365     }
366   return new;
367 }
368
369 int
370 strncmp (char const* a, char const* b, int length)
371 {
372   while (*a && *b && *a == *b && --length) {a++;b++;}
373   return *a - *b;
374 }
375
376 char *
377 getenv (char const* s)
378 {
379   char **p = g_environment;
380   int length = strlen (s);
381   while (*p)
382     {
383       if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
384       p++;
385     }
386   return 0;
387 }
388
389 int
390 vprintf (char const* format, va_list ap)
391 {
392   char const *p = format;
393   while (*p)
394     if (*p != '%')
395       putchar (*p++);
396     else
397       {
398         p++;
399         char c = *p;
400         switch (c)
401           {
402           case '%': {putchar (*p); break;}
403           case 'c': {char c; c = va_arg (ap, char); putchar (c); break;}
404           case 'd': {int d; d = va_arg (ap, int); puts (itoa (d)); break;}
405           case 's': {char *s; s = va_arg (ap, char *); puts (s); break;}
406           default: {putchar (*p); break;}
407           }
408         p++;
409       }
410   va_end (ap);
411   return 0;
412 }
413
414 int
415 printf (char const* format, ...)
416 {
417   va_list ap;
418   va_start (ap, format);
419   int r = vprintf (format, ap);
420   va_end (ap);
421   return r;
422 }
423
424 int
425 vsprintf (char *str, char const* format, va_list ap)
426 {
427   char const *p = format;
428   while (*p)
429     if (*p != '%')
430       *str++ = *p++;
431     else
432       {
433         p++;
434         char c = *p;
435         switch (c)
436           {
437           case '%': {*str++ = *p; break;}
438           case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;}
439           case 'd': {int d; d = va_arg (ap, int); char const *s; s = itoa (d); while (*s) *str++ = *s++; break;}
440           case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;}
441           default: {*str++ = *p; break;}
442           }
443         p++;
444       }
445   va_end (ap);
446   *str = 0;
447   return strlen (str);
448 }
449
450 int
451 sprintf (char *str, char const* format, ...)
452 {
453   va_list ap;
454   va_start (ap, format);
455   int r = vsprintf (str, format, ap);
456   va_end (ap);
457   return r;
458 }