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