* module/mes/libc-i386.mes (i386:_start): Push environment pointer.
* module/mes/libc.mes (g_environment): New global.
(_env): New function.
(_start): Use it to set g_environment.
(getenv): New function.
* lib/mlibc.c (strncmp): New function.
(getenv): Implement.
* lib/mstart.c (_start): Set g_environment.
* module/mes/libc.mes (strncmp): New function.
(libc): Add it.
* scaffold/t.c: (array_ref): Test it.
SHELL:=bash
+export SHELL
QUIET:=@
default: all
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
+char **g_environment = 0;
int g_stdin = 0;
#define EOF -1
exit (0);
}
-char const*
-getenv (char const* p)
-{
- return 0;
-}
-
int
read (int fd, void* buf, size_t n)
{
return c;
}
+char const* itoa (int);
+
+int
+strncmp (char const* a, char const* b, int length)
+{
+ while (*a && *b && *a == *b && --length) {a++;b++;}
+ return *a - *b;
+}
+
+char const*
+getenv (char const* s)
+{
+ char **p = g_environment;
+ int length = strlen (s);
+ while (*p)
+ {
+ if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
+ p++;
+ }
+ return 0;
+}
+
int
isdigit (int c)
{
void
_start ()
{
+ // char **;
+ asm (
+ "mov %%ebp,%%eax\n\t"
+ "addl $4,%%eax\n\t"
+ "movzbl (%%eax),%%eax\n\t"
+ "addl $3,%%eax\n\t"
+ "shl $2,%%eax\n\t"
+ "add %%ebp,%%eax\n\t"
+ "movl %%eax,%0\n\t"
+ : "=g_environment" (g_environment)
+ : //no inputs ""
+ );
int r;
asm (
- "mov %%ebp,%%eax\n\t"
- "addl $8,%%eax\n\t"
- "push %%eax\n\t"
+ "mov %%ebp,%%eax\n\t"
+ "addl $8,%%eax\n\t"
+ "push %%eax\n\t"
- "mov %%ebp,%%eax\n\t"
- "addl $4,%%eax\n\t"
- "movzbl (%%eax),%%eax\n\t"
- "push %%eax\n\t"
+ "mov %%ebp,%%eax\n\t"
+ "addl $4,%%eax\n\t"
+ "movzbl (%%eax),%%eax\n\t"
+ "push %%eax\n\t"
- "call main\n\t"
- "movl %%eax,%0\n\t"
+ "call main\n\t"
+ "movl %%eax,%0\n\t"
: "=r" (r)
- : //no inputs "" (&main)
+ : //no inputs ""
);
exit (r);
}
(if global
(let ((ptr (ident->pointer info o)))
(case ptr
- ((10)
- (list (lambda (f g ta t d)
- (i386:global->accu (+ (data-offset o g) d)))))
+ ;; ((1)
+ ;; (list (lambda (f g ta t d)
+ ;; (i386:global->accu (+ (data-offset o g) d)))))
(else (list (lambda (f g ta t d)
(append (i386:value->accu (+ (data-offset o g) d))))))))
(error "TODO ident-address->accu" o))))))
-
(define (ident-address->base info)
(lambda (o)
(let ((local (assoc-ref (.locals info) o))
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x08" ; add $0x8,%eax
" 0x50" ; push %eax
+
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x04" ; add $0x4,%eax
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
" 0x50" ; push %eax
+
+ " 0x89 0xe8" ; mov %ebp,%eax
+ " 0x83 0xc0 0x04" ; add $0x4,%eax
+ " 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
+ " 0x83 0xc0 0x03" ; add $0x3,%eax
+ " 0xc1 0xe0 0x02" ; shl $0x2,%eax
+ " 0x01 0xe8" ; add %ebp,%eax
+ " 0x50" ; push %eax
))
(define i386:libc
(define _start
(let* ((argc-argv (i386:_start))
(ast (with-input-from-string
- (string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}")
+ (string-append "
+char **g_environment;
+char **
+_env (char **e)
+{
+ return e;
+}
+
+int
+_start ()
+{
+ asm(\"" argc-argv "\");
+ g_environment = _env ();
+ asm (\".byte 0x58\");
+ int r = main ();
+ exit (r);
+}
+")
parse-c99)))
ast))
parse-c99)))
ast))
+(define strncmp
+ (let* ((ast (with-input-from-string
+ "
+int
+strncmp (char const* a, char const* b, int length)
+{
+ while (*a && *b && *a == *b && --length) {a++;b++;}
+ return *a - *b;
+}
+"
+;;paredit:"
+ parse-c99)))
+ ast))
+
+(define c:getenv
+ (let* ((ast (with-input-from-string
+ "
+char **g_environment;
+char const*
+getenv (char const* s)
+{
+ char **p = g_environment;
+ p = *g_environment;
+ int length = strlen (s);
+ while (*p)
+ {
+ if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
+ p++;
+ }
+ return 0;
+}
+"
+;;paredit:"
+ parse-c99)))
+ ast))
+
+
(define libc
(list
strlen
isdigit
malloc
realloc
+ strncmp
+ c:getenv
))
#endif
#if __MESC__
+char **g_environment;
int g_stdin = 0;
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#endif
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
+#if __MESC__
+char **g_environment;
+int g_stdin = 0;
+#define assert(x) ((x) ? (void)0 : assert_fail (#x))
+#endif
+
#if !__MESC__
#include "mlibc.c"
#endif
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
+#if __MESC__
+char **g_environment;
+int g_stdin = 0;
+#define assert(x) ((x) ? (void)0 : assert_fail (#x))
+#endif
+
#if !__MESC__
#include "mlibc.c"
#endif
#error "POSIX not supported"
#endif
+#if __MESC__
+char **g_environment;
+int g_stdin = 0;
+#define assert(x) ((x) ? (void)0 : assert_fail (#x))
+#endif
+
#if !__MESC__
#include "mlibc.c"
#endif
#endif
#if __MESC__
+char **g_environment;
int g_stdin = 0;
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#endif
TARGET:=hello.mlibc
C_FILES:=$(DIR)/hello.c
INCLUDES:=libc
-C_FLAGS:=-nostdinc
-LD_FLAGS:=-nostdlib
+C_FLAGS:=-nostdinc -g
+LD_FLAGS:=-nostdlib -g
CROSS:=$(CC32:%gcc=%)
include make/bin.make
puts ("t: *(p + 1)\n");
if (*(*p + 1) != 'e') return 1;
+ puts ("t: getenv ()");
+ if (!getenv ("SHELL")) return 1;
+
return read_test ();
}
#error "POSIX not supported"
#endif
+#if __MESC__
+char **g_environment;
+int g_stdin = 0;
+#define assert(x) ((x) ? (void)0 : assert_fail (#x))
+#endif
+
#if !__MESC__
#include "mlibc.c"
#endif
*/
#if __MESC__
+char **g_environment;
int g_stdin = 0;
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#endif
SCM
getenv_ (SCM s) ///((name . "getenv"))
{
-#if _POSIX_SOURCE
- char *p = getenv (string_to_cstring (s));
+ char *p;
+ p = getenv (string_to_cstring (s));
return p ? MAKE_STRING (cstring_to_list (p)) : cell_f;
-#else
- return cell_t;
-#endif
}
SCM