mescc: drop naive realloc.
[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 void
228 free (void *ptr)
229 {
230 }
231
232 //#define assert(x) ((x) ? (void)0 : assert_fail (#x))
233 int
234 ungetc (int c, int fd)
235 {
236   //FIXME
237   //assert (ungetc_char < 2);
238   //assert (ungetc_char == -1 || ungetc_char < 2);
239   //FIXME
240   //ungetc_buf[++ungetc_char] = c;
241   ungetc_char++;
242   ungetc_buf[ungetc_char] = c;
243   return c;
244 }
245
246 int
247 strcmp (char const* a, char const* b)
248 {
249   while (*a && *b && *a == *b)
250     {
251       a++;b++;
252     }
253   return *a - *b;
254 }
255
256
257 char *
258 strcpy (char *dest, char const *src)
259 {
260   char *p = dest;
261   while (*src) *p++ = *src++;
262   *p = 0;
263   return dest;
264 }
265
266 char itoa_buf[10];
267
268 char const*
269 itoa (int x)
270 {
271   //static char itoa_buf[10];
272   //char *p = buf+9;
273   char *p = itoa_buf;
274   p += 9;
275   *p-- = 0;
276
277   //int sign = x < 0; // FIXME
278   int sign = 0;
279   if (x < 0) sign = 1;
280   if (sign)
281     x = -x;
282
283   do
284      {
285        *p-- = '0' + (x % 10);
286        x = x / 10;
287      } while (x);
288
289   if (sign && *(p + 1) != '0')
290     *p-- = '-';
291
292   return p+1;
293 }
294
295 int
296 isdigit (char c)
297 {
298   //return (c>='0') && (c<='9');
299   if (c>='0' && c<='9') return 1;
300   return 0;
301 }
302
303 int
304 atoi (char const *s)
305 {
306   int i = 0;
307   int sign = 1;
308   if (*s && *s == '-')
309     {
310       sign = -1;
311       s++;
312     }
313   while (isdigit (*s))
314     {
315       i *= 10;
316       i += (*s - '0');
317       s++;
318     }
319   return i * sign;
320 }
321
322 char *g_brk = 0;
323
324 void *
325 malloc (size_t size)
326 {
327   if (!g_brk)
328     g_brk = brk (0);
329   if (brk (g_brk + size) == -1)
330     return 0;
331   char *p = g_brk;
332   g_brk += size;
333   return p;
334 }
335
336 void *
337 memcpy (void *dest, void const *src, size_t n)
338 {
339   char* p = dest;
340   char* q = src;
341   while (n--) *p++ = *q++;
342   return dest;
343 }
344
345 void *
346 realloc (void *ptr, size_t size)
347 {
348   void *new = malloc (size);
349   if (ptr && new)
350     {
351       memcpy (new, ptr, size);
352       free (ptr);
353     }
354   return new;
355 }
356
357 int
358 strncmp (char const* a, char const* b, int length)
359 {
360   while (*a && *b && *a == *b && --length) {a++;b++;}
361   return *a - *b;
362 }
363
364 char *
365 getenv (char const* s)
366 {
367   char **p = g_environment;
368   int length = strlen (s);
369   while (*p)
370     {
371       if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
372       p++;
373     }
374   return 0;
375 }
376
377 int
378 vprintf (char const* format, va_list ap)
379 {
380   char const *p = format;
381   while (*p)
382     if (*p != '%')
383       putchar (*p++);
384     else
385       {
386         p++;
387         char c = *p;
388         switch (c)
389           {
390           case '%': {putchar (*p); break;}
391           case 'c': {char c; c = va_arg (ap, char); putchar (c); break;}
392           case 'd': {int d; d = va_arg (ap, int); puts (itoa (d)); break;}
393           case 's': {char *s; s = va_arg (ap, char *); puts (s); break;}
394           default: {putchar (*p); break;}
395           }
396         p++;
397       }
398   va_end (ap);
399   return 0;
400 }
401
402 int
403 printf (char const* format, ...)
404 {
405   va_list ap;
406   va_start (ap, format);
407   int r = vprintf (format, ap);
408   va_end (ap);
409   return r;
410 }
411
412 int
413 sprintf (char *str, char const* format, ...)
414 {
415   va_list ap;
416   va_start (ap, format);
417   char const *p = format;
418   while (*p)
419     if (*p != '%')
420       *str++ = *p++;
421     else
422       {
423         p++;
424         char c = *p;
425         switch (c)
426           {
427           case '%': {*str++ = *p; break;}
428           case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;}
429           case 'd': {int d; d = va_arg (ap, int); char const *s; s = itoa (d); while (*s) *str++ = *s++; break;}
430           case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;}
431           default: {*str++ = *p; break;}
432           }
433         p++;
434       }
435   va_end (ap);
436   return 0;
437 }