From f1efaa0e937aba468c5b90471a03b7cf48ed26da Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Wed, 30 May 2018 21:55:39 +0200 Subject: [PATCH] mescc: Support binutils-2.5.1. * include/stdint.h: #undef types before typedef'ing them. * include/sys/types.h: Likewise. * include/string.h (NULL): New define. * include/stdio.h (BUFSIZ): New define. --- build-aux/build-mes-gcc.sh | 2 + build-aux/build-mes.sh | 1 + build-aux/check-mescc.sh | 21 ++-- build-aux/test.sh | 4 +- include/errno.h | 1 + include/fcntl.h | 5 - include/getopt.h | 11 +- include/limits.h | 2 + include/memory.h | 36 +++++++ include/pwd.h | 41 +++++++ include/signal.h | 1 + include/stdint.h | 19 ++++ include/stdio.h | 15 ++- include/string.h | 4 + include/sys/dir.h | 32 ++++++ include/sys/file.h | 32 ++++++ include/sys/param.h | 31 ++++++ include/sys/stat.h | 22 +++- include/sys/time.h | 18 +++- include/sys/types.h | 9 +- include/sys/user.h | 109 +++++++++++++++++++ include/unistd.h | 4 + lib/binutils.c | 210 ++++++++++++++++++++++++++++++++++++ lib/crt1.c | 6 +- lib/getopt.c | 20 ++-- lib/libc+gnu.c | 23 ++++ lib/libc+tcc.c | 130 +++++++++++++++++++--- lib/libc.c | 84 ++------------- lib/libgetopt.c | 21 ++++ lib/linux+tcc-gcc.c | 110 +++++++++++++++++-- lib/linux+tcc-mes.c | 19 ++++ lib/linux-gcc.c | 46 ++++---- lib/linux-mini-gcc.c | 10 +- lib/m4.c | 38 +++---- module/mescc/preprocess.scm | 1 + scaffold/tests/70-printf.c | 33 +++++- scaffold/tests/90-strpbrk.c | 52 +++++++++ scaffold/tests/91-fseek.c | 58 ++++++++++ src/posix.c | 2 +- 39 files changed, 1102 insertions(+), 181 deletions(-) create mode 100644 include/memory.h create mode 100644 include/pwd.h create mode 100644 include/sys/dir.h create mode 100644 include/sys/file.h create mode 100644 include/sys/param.h create mode 100644 include/sys/user.h create mode 100644 lib/binutils.c create mode 100644 lib/libc+gnu.c create mode 100644 lib/libgetopt.c create mode 100644 scaffold/tests/90-strpbrk.c create mode 100644 scaffold/tests/91-fseek.c diff --git a/build-aux/build-mes-gcc.sh b/build-aux/build-mes-gcc.sh index 71552ae9..7ce4a4b2 100755 --- a/build-aux/build-mes-gcc.sh +++ b/build-aux/build-mes-gcc.sh @@ -65,7 +65,9 @@ C32FLAGS=${C32FLAGS-" ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/crt1 ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libc-mini ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libc +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libgetopt ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libc+tcc +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libc+gnu sh build-aux/cc-mes-gcc.sh scaffold/main sh build-aux/cc-mes-gcc.sh scaffold/hello diff --git a/build-aux/build-mes.sh b/build-aux/build-mes.sh index 7166c0e0..b3134f91 100755 --- a/build-aux/build-mes.sh +++ b/build-aux/build-mes.sh @@ -100,6 +100,7 @@ PREPROCESS=1 ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/crt1 ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc-mini ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libgetopt ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc+tcc [ -n "$SEED" ] && exit 0 diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 84d8f18d..64a0261f 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -134,10 +134,15 @@ t 85-sizeof 86-strncpy 87-sscanf +90-strpbrk +91-fseek " +# 90: needs GNU, fails for mescc, passes for tcc broken="$broken 7s-struct-short +90-strpbrk +91-fseek " set +e @@ -149,9 +154,12 @@ for t in $tests; do if [ -z "${t/[012][0-9]-*/}" ]; then LIBC=c-mini MESCCLIBS="-l c-mini" - elif [ -z "${t/8[0-9]-*/}" ]; then + elif [ -z "${t/[78][0-9a-z]-*/}" ]; then LIBC=c+tcc MESCCLIBS="-l c+tcc" + elif [ -z "${t/9[0-9]-*/}" ]; then + LIBC=c+gnu + MESCCLIBS="-l c+gnu" else LIBC=c MESCCLIBS= @@ -219,7 +227,6 @@ tests=" 43_void_param 44_scoped_declarations 45_empty_for -46_grep 47_switch_return 48_nested_break 49_bracket_evaluation @@ -241,14 +248,11 @@ broken="$broken 27_sizeof 28_strings -31_args 34_array_assignment -37_sprintf 39_typedef 40_stdio 42_function_pointer -46_grep 49_bracket_evaluation 55_lshift_type " @@ -260,17 +264,18 @@ broken="$broken #28_strings ; TODO: strncpy strchr strrchr memset memcpy memcmp #30_hanoi ; fails with GCC #34_array_assignment ; fails with GCC -#37_sprintf ; integer formatting unsupported #39_typedef ;unsupported: (decl (decl-spec-list (stor-spec (typedef)) (type-spec (typename "MyFunStruct"))) (init-declr-list (init-declr (ptr-declr (pointer) (ident "MoreFunThanEver"))))) #40_stdio ; f* functions #42_function_pointer ; f* functions -#46_grep ; f* functions #49_bracket_evaluation ; float - +LIBC=c+gnu +MESCCLIBS="-l c+tcc" expect=$(echo $broken | wc -w) +ARGS="arg1 arg2 arg3 arg4 arg5" +export ARGS for t in $tests; do if [ ! -f scaffold/tinycc/"$t.c" ]; then echo ' [SKIP]' diff --git a/build-aux/test.sh b/build-aux/test.sh index 33f5919e..9739cce0 100755 --- a/build-aux/test.sh +++ b/build-aux/test.sh @@ -41,7 +41,7 @@ if [ -n "$CC32" ]; then r=0 [ -f "$t".exit ] && r=$(cat "$t".exit) set +e - "$t".mes-gcc-out > "$t".mes-gcc-stdout + "$t".mes-gcc-out $ARGS > "$t".mes-gcc-stdout m=$? cat "$t".mes-gcc-stdout set -e @@ -58,7 +58,7 @@ sh build-aux/cc-mes.sh "$t" r=0 [ -f "$t".exit ] && r=$(cat "$t".exit) set +e -"$t".mes-out > "$t".mes-stdout +"$t".mes-out $ARGS > "$t".mes-stdout m=$? cat "$t".mes-stdout set -e diff --git a/include/errno.h b/include/errno.h index a6ca9e61..72c89a43 100644 --- a/include/errno.h +++ b/include/errno.h @@ -29,6 +29,7 @@ #else // ! (__GNUC__ && POSIX) int errno; #define ENOENT 2 /* No such file or directory */ +#define EIO 5 /* I/O error */ #define EBADF 9 /* Bad file number */ #define ENOMEM 12 /* Out of memory */ #define EEXIST 17 /* File exists */ diff --git a/include/fcntl.h b/include/fcntl.h index e3f1fad3..879181bc 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -35,11 +35,6 @@ #define O_EXCL 128 #define O_TRUNC 512 -#define S_IRWXU 00700 -#define S_IXUSR 00100 -#define S_IWUSR 00200 -#define S_IRUSR 00400 - #define F_DUPFD 0 #define F_GETFD 1 #define F_SETFD 2 diff --git a/include/getopt.h b/include/getopt.h index 3c0aa1b5..1200ff46 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -1,7 +1,7 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software * Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. - * Copyright © 2017 Jan (janneke) Nieuwenhuizen + * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen * * This file is part of Mes. * @@ -51,11 +51,12 @@ enum _argtype optional_argument }; -int getopt (int argc, char *const *argv, char const *shortopts); -int getopt_long (int argc, char *const *argv, char const *shortopts, - struct option const *longopts, int *longind); +int getopt (int argc, char *const *argv, char const *options); +int getopt_long (int argc, char *const *argv, char const *options, + struct option const *long_options, int *opt_index); +int getopt_long_only (int argc, char *const *argv, char const *options, + struct option const *long_options, int *opt_index); #endif // ! (__GNUC__ && POSIX) #endif // __MES_GETOPT_H - diff --git a/include/limits.h b/include/limits.h index 99e6083e..9d4c3308 100644 --- a/include/limits.h +++ b/include/limits.h @@ -33,6 +33,8 @@ #define INT_MIN -2147483648 #define INT_MAX 2147483647 #define MB_CUR_MAX 1 +#define LONG_MIN -2147483648 +#define LONG_MAX 2147483647 #endif // ! (__GNUC__ && POSIX) diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 00000000..82c9088b --- /dev/null +++ b/include/memory.h @@ -0,0 +1,36 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_MEMORY_H +#define __MES_MEMORY_H 1 + +#if __GNUC__ && POSIX +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#undef __MES_MEMORY_H +#include_next + +#else // ! (__GNUC__ && POSIX) + +#include + +#endif // ! (__GNUC__ && POSIX) + +#endif // __MES_MEMORY_H diff --git a/include/pwd.h b/include/pwd.h new file mode 100644 index 00000000..09f4245a --- /dev/null +++ b/include/pwd.h @@ -0,0 +1,41 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_PWD_H +#define __MES_PWD_H 1 + +#if __GNUC__ && POSIX +#undef __MES_PWD_H +#include_next +#else // !(__GNUC__ && POSIX) + +struct passwd +{ + char *pw_name; + char *pw_passwd; + uid_t pw_uid; + gid_t pw_gid; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +}; + +#endif // !(__GNUC__ && POSIX) + +#endif // __MES_PWD_H diff --git a/include/signal.h b/include/signal.h index 43f2a7e7..122fbb95 100644 --- a/include/signal.h +++ b/include/signal.h @@ -41,6 +41,7 @@ typedef int uid_t; typedef int clock_t; typedef int sigval_t; +#define NSIG 30 #define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 diff --git a/include/stdint.h b/include/stdint.h index 91ae6b67..fb58223c 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -29,6 +29,25 @@ #else // ! (__GNUC__ && POSIX) +#undef unsigned +#undef uint8_t +#undef int8_t + +#undef uint16_t +#undef int16_t + +#undef uint32_t +#undef int32_t + +#undef uint64_t +#undef int64_t + +#undef uintptr_t +#undef intmax_t +#undef intptr_t +#undef uintmax_t +#undef ptrdiff_t + typedef unsigned char uint8_t; typedef char int8_t; typedef unsigned short uint16_t; diff --git a/include/stdio.h b/include/stdio.h index c7e55cfb..414b4ce2 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -20,7 +20,7 @@ #ifndef __MES_STDIO_H #define __MES_STDIO_H 1 -char **g_environment; +char **environ; int g_stdin; int g_stdout; @@ -45,6 +45,10 @@ int g_stdout; #else // ! (__GNUC__ && POSIX) +#ifndef __MESCCLIB__ +#define __MESCCLIB__ 15 +#endif + #ifndef EOF #define EOF -1 #endif @@ -53,6 +57,14 @@ int g_stdout; #define NULL 0 #endif +#ifndef BUFSIZ +#define BUFSIZ 256 +#endif + +#ifndef L_tmpnam +#define L_tmpnam 100 +#endif + // Hmm #define stdin 0 #define stdout 1 @@ -76,6 +88,7 @@ FILE *fopen (char const *file_name, char const *mode); int eputc (int c); int eputs (char const* s); int fclose (FILE *stream); +int feof (FILE *stream); int ferror (FILE *stream); int fflush (FILE *stream); int fgetc (FILE* stream); diff --git a/include/string.h b/include/string.h index 32502021..556eeffe 100644 --- a/include/string.h +++ b/include/string.h @@ -29,6 +29,10 @@ #else // ! (__GNUC__ && POSIX) +#ifndef NULL +#define NULL 0 +#endif + #ifndef __MES_SIZE_T #define __MES_SIZE_T #undef size_t diff --git a/include/sys/dir.h b/include/sys/dir.h new file mode 100644 index 00000000..424a093a --- /dev/null +++ b/include/sys/dir.h @@ -0,0 +1,32 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_SYS_DIR_H +#define __MES_SYS_DIR_H 1 + +#if __GNUC__ && POSIX +#undef __MES_SYS_DIR_H +#include_next + +#else // !(__GNUC__ && POSIX) + + +#endif // !(__GNUC__ && POSIX) + +#endif // __MES_SYS_DIR_H diff --git a/include/sys/file.h b/include/sys/file.h new file mode 100644 index 00000000..171469a0 --- /dev/null +++ b/include/sys/file.h @@ -0,0 +1,32 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_SYS_FILE_H +#define __MES_SYS_FILE_H 1 + +#if __GNUC__ && POSIX +#undef __MES_SYS_FILE_H +#include_next + +#else // !(__GNUC__ && POSIX) + + +#endif // !(__GNUC__ && POSIX) + +#endif // __MES_SYS_FILE_H diff --git a/include/sys/param.h b/include/sys/param.h new file mode 100644 index 00000000..e7998a3f --- /dev/null +++ b/include/sys/param.h @@ -0,0 +1,31 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_SYS_PARAM_H +#define __MES_SYS_PARAM_H 1 + +#if __GNUC__ && POSIX +#undef __MES_SYS_PARAM_H +#include_next + +#else // !(__GNUC__ && POSIX) + +#endif // !(__GNUC__ && POSIX) + +#endif // __MES_SYS_PARAM_H diff --git a/include/sys/stat.h b/include/sys/stat.h index d377d717..3698331f 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -26,13 +26,13 @@ #else // !(__GNUC__ && POSIX) +#include + #ifndef __MES_MODE_T #define __MES_MODE_T typedef int mode_t; #endif -int chmod (char const *file_name, mode_t mode); - struct stat { unsigned long st_dev; /* Device. */ @@ -57,6 +57,24 @@ struct stat unsigned int __unused5; }; +int chmod (char const *file_name, mode_t mode); +int mkdir (char const *file_name, mode_t mode); +int chown (char const *file_name, uid_t owner, gid_t group); +int rmdir (char const *file_name); + +#define S_IFMT 0170000 +#define S_IFDIR 0040000 +#define S_IFREG 0100000 +#define S_IFLNK 0120000 + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + +#define S_IRWXU 00700 +#define S_IXUSR 00100 +#define S_IWUSR 00200 +#define S_IRUSR 00400 + #endif // !(__GNUC__ && POSIX) #endif // __MES_SYS_STAT_H diff --git a/include/sys/time.h b/include/sys/time.h index eed34b52..b48b5230 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -26,19 +26,31 @@ #else // !(__GNUC__ && POSIX) -struct timeval { +struct timeval +{ long tv_sec; long tv_usec; }; -struct timezone { +struct timezone +{ int tz_minuteswest; int tz_dsttime; }; +struct itimerval +{ + struct timeval it_interval; + struct timeval it_value; +}; + +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + int gettimeofday (struct timeval *tv, struct timezone *tz); +int setitimer (int which, struct itimerval const *new, struct itimerval *old); #endif // !(__GNUC__ && POSIX) #endif // __MES_SYS_TIME_H - diff --git a/include/sys/types.h b/include/sys/types.h index 33681f91..87cbd30d 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -34,15 +34,22 @@ typedef unsigned long size_t; #ifndef __MES_PID_T #define __MES_PID_T +#undef pid_t typedef int pid_t; #endif +#ifndef __MES_GID_T +#define __MES_GID_T +#undef gid_t +typedef int gid_t; +#endif + #ifndef __MES_UID_T #define __MES_UID_T +#undef uid_t typedef int uid_t; #endif #endif // ! (__GNUC__ && POSIX) #endif // __MES_SYS_TYPES_H - diff --git a/include/sys/user.h b/include/sys/user.h new file mode 100644 index 00000000..03777b71 --- /dev/null +++ b/include/sys/user.h @@ -0,0 +1,109 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ +#ifndef __MES_SYS_USER_H +#define __MES_SYS_USER_H 1 + +#if __GNUC__ && POSIX +#undef __MES_SYS_USER_H +#include_next + +#else // !(__GNUC__ && POSIX) + +/* These are the 32-bit x86 structures. */ +struct user_fpregs_struct +{ + long int cwd; + long int swd; + long int twd; + long int fip; + long int fcs; + long int foo; + long int fos; + long int st_space [20]; +}; + +struct user_fpxregs_struct +{ + unsigned short int cwd; + unsigned short int swd; + unsigned short int twd; + unsigned short int fop; + long int fip; + long int fcs; + long int foo; + long int fos; + long int mxcsr; + long int reserved; + long int st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long int xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long int padding[56]; +}; + +struct user_regs_struct +{ + long int ebx; + long int ecx; + long int edx; + long int esi; + long int edi; + long int ebp; + long int eax; + long int xds; + long int xes; + long int xfs; + long int xgs; + long int orig_eax; + long int eip; + long int xcs; + long int eflags; + long int esp; + long int xss; +}; + +struct user +{ + struct user_regs_struct regs; + int u_fpvalid; + struct user_fpregs_struct i387; + unsigned long int u_tsize; + unsigned long int u_dsize; + unsigned long int u_ssize; + unsigned long int start_code; + unsigned long int start_stack; + long int signal; + int reserved; + struct user_regs_struct* u_ar0; + struct user_fpregs_struct* u_fpstate; + unsigned long int magic; + char u_comm [32]; + int u_debugreg [8]; +}; + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif // !(__GNUC__ && POSIX) + +#endif // __MES_SYS_USER_H diff --git a/include/unistd.h b/include/unistd.h index dc11ec78..9cf809b7 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -29,6 +29,10 @@ #else // ! (__GNUC__ && POSIX) +#ifndef NULL +#define NULL 0 +#endif + #ifndef __MES_OFF_T #define __MES_OFF_T #undef off_t diff --git a/lib/binutils.c b/lib/binutils.c new file mode 100644 index 00000000..00175ba3 --- /dev/null +++ b/lib/binutils.c @@ -0,0 +1,210 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include + +int +abs (int x) +{ + if (x < 0) + return -x; + return x; +} + +int +chown (char const *file_name, uid_t owner, gid_t group) +{ + eputs ("chown stub\n"); + return 0; +} + +int +ctime (int x) +{ + eputs ("ctime stub\n"); + return 0; +} + +int +fcntl (int x) +{ + eputs ("fcntl stub\n"); + return 0; +} + +char * +fdgets (char *s, int count, int fd) +{ + int c = 0; + char *p = s; + while (--count > 0 && c != '\n') + { + c = fdgetc (fd); + if (c == EOF) + break; + *p++ = c; + } + if (p == s && (c == EOF || count == -1)) + return 0; + *p = 0; + return s; +} + +int +feof (FILE *stream) +{ + char c = fgetc (stream); + if (c != EOF) + ungetc (c, stream); + return c == EOF; +} + +char * +fgets (char *s, int count, FILE *stream) +{ + return fdgets (s, count, (int)stream); +} + +int +frexp (int x) +{ + eputs ("frexp stub\n"); + return 0; +} + +int +getgid (int x) +{ + eputs ("getgid stub\n"); + return 0; +} + +int +getpid (int x) +{ + eputs ("getpid stub\n"); + return 0; +} + +int +getuid (int x) +{ + eputs ("getuid stub\n"); + return 0; +} + +int +perror (int x) +{ + eputs ("perror stub\n"); + return 0; +} + +void* +sbrk (ptrdiff_t delta) +{ + void *p = malloc (delta); + if (p <= 0) + return 0; + return p+delta; +} + +int +setitimer (int which, struct itimerval const *new, + struct itimerval *old) +{ + eputs ("setitimer stub\n"); + return 0; +} + +int +sigsetmask (int x) +{ + eputs ("sigsetmask stub\n"); + return 0; +} + +size_t +strcspn (char const *string, char const *stopset) +{ + char *p = string; + while (*p) + if (strchr (stopset, *p)) + break; + else + p++; + return p - string; +} + +char * +strncat (char *to, char const *from, size_t size) +{ + char *p = strchr (to , '\0'); + while (*from && size--) + *p++ = *from++; + *p = 0; + return to; +} + +char * +strpbrk (char const *string, char const* stopset) +{ + char *p = string; + while (*p) + if (strchr (stopset, *p)) + break; + else + p++; + return p; +} + +size_t +strspn (char const *string, char const *skipset) +{ + char *p = string; + while (*p) + if (!strchr (skipset, *p)) + break; + else + p++; + return p - string; +} + +int +sys_siglist (int x) +{ + eputs ("sys_siglist stub\n"); + return 0; +} + +int +umask (int x) +{ + eputs ("umask stub\n"); + return 0; +} + +int +utime (int x) +{ + eputs ("utime stub\n"); + return 0; +} diff --git a/lib/crt1.c b/lib/crt1.c index 9fadbb59..6c133b98 100644 --- a/lib/crt1.c +++ b/lib/crt1.c @@ -18,7 +18,7 @@ * along with Mes. If not, see . */ -char **g_environment = 0; +char **environ = 0; int main (int argc, char *argv[]); #if __GNUC__ @@ -34,7 +34,7 @@ _start () "shl $2,%%eax\n\t" "add %%ebp,%%eax\n\t" "movl %%eax,%0\n\t" - : "=g_environment" (g_environment) + : "=environ" (environ) : //no inputs "" ); asm ( @@ -70,7 +70,7 @@ _start () asm ("shl____$i8,%eax !0x02"); asm ("add____%ebp,%eax"); - asm ("mov____%eax,0x32 &g_environment"); + asm ("mov____%eax,0x32 &environ"); asm ("mov____%ebp,%eax"); asm ("add____$i8,%eax !8"); diff --git a/lib/getopt.c b/lib/getopt.c index 0256a574..956a1052 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -1,6 +1,6 @@ /* Getopt for GNU. Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc. - Copyright (C) 2017 Jan (janneke) Nieuwenhuizen + Copyright (C) 2017,2018 Jan (janneke) Nieuwenhuizen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -361,16 +361,22 @@ _getopt_internal (int argc, char *const } int -getopt (int argc, char *const *argv, char const *optstring) +getopt (int argc, char *const *argv, char const *options) { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); + return _getopt_internal (argc, argv, options, + (const struct option *) 0, (int *) 0, 0); } int -getopt_long (int argc, char *const *argv, const char *options, struct option const *long_options, int *opt_index) +getopt_long (int argc, char *const *argv, char const *options, + struct option const *long_options, int *opt_index) { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } + +int +getopt_long_only (int argc, char *const *argv, char const *options, + struct option const *long_options, int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} diff --git a/lib/libc+gnu.c b/lib/libc+gnu.c new file mode 100644 index 00000000..54329110 --- /dev/null +++ b/lib/libc+gnu.c @@ -0,0 +1,23 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include +#include diff --git a/lib/libc+tcc.c b/lib/libc+tcc.c index cd94d5c0..d3ee7372 100644 --- a/lib/libc+tcc.c +++ b/lib/libc+tcc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -36,14 +37,11 @@ #include #include -#include #else // !__MESC__ #include #include -#include -#include #endif // !__MESC__ @@ -226,8 +224,12 @@ qsort (void *base, size_t count, size_t size, int (*compare)(void const *, void int remove (char const *file_name) { - eputs ("remove stub\n"); - return 0; + struct stat buf; + if (stat (file_name, &buf) < 0) + return -1; + if (S_ISDIR (buf.st_mode)) + return rmdir (file_name); + return unlink (file_name); } int @@ -264,12 +266,13 @@ sscanf (char const *str, const char *template, ...) } char * -strcat (char *dest, char const *src) +strcat (char *to, char const *from) { - char *p = strchr (dest, '\0'); - while (*src++) *p++ = *src++; + char *p = strchr (to, '\0'); + while (*from) + *p++ = *from++; *p = 0; - return dest; + return to; } char * @@ -278,7 +281,8 @@ strchr (char const *s, int c) char const *p = s; while (*p || !c) { - if (c == *p) return p; + if (c == *p) + return p; *p++; } return 0; @@ -360,7 +364,7 @@ strstr (char const *haystack, char const *needle) double strtod (char const *nptr, char **endptr) { - eputs ("strtoul stub\n"); + eputs ("strtod stub\n"); } float @@ -445,7 +449,13 @@ vfprintf (FILE* f, char const* format, va_list ap) case 'c': {char c; c = va_arg (ap, char); fputc (c, fd); break;} case 'd': {int d; d = va_arg (ap, int); fputs (itoa (d), fd); break;} case 's': {char *s; s = va_arg (ap, char *); fputs (s, fd); break;} - default: {fputc (*p, fd); break;} + default: + { + eputs ("vfprintf: not supported: %"); + eputc (c); + eputs ("\n"); + p++; + } } p++; } @@ -453,6 +463,12 @@ vfprintf (FILE* f, char const* format, va_list ap) return 0; } +int +vprintf (char const* format, va_list ap) +{ + return vfprintf (STDOUT, format, ap); +} + int vsscanf (char const *s, char const *template, va_list ap) { @@ -472,7 +488,9 @@ vsscanf (char const *s, char const *template, va_list ap) { case '%': {p++; break;} case 'c': {char *c = va_arg (ap, char*); *c = *p++; break;} - case 'd': {int *d = va_arg (ap, int*); *d = abtoi (&p, 10); break;} + case 'd': + case 'i': + case 'u': {int *d = va_arg (ap, int*); *d = abtoi (&p, 10); break;} default: { eputs ("vsscanf: not supported: %"); @@ -487,3 +505,89 @@ vsscanf (char const *s, char const *template, va_list ap) va_end (ap); return 0; } + +int +vsprintf (char *str, char const* format, va_list ap) +{ + char const *p = format; + while (*p) + if (*p != '%') + *str++ = *p++; + else + { + p++; + char c = *p; + int left_p = 0; + int width = -1; + if (c == '-') + { + left_p = 1; + c = *++p; + } + char pad = ' '; + if (c == '0') + { + pad = c; + c = *p++; + } + if (c >= '0' && c <= '9') + { + width = abtoi (&p, 10); + c = *p; + } + switch (c) + { + case '%': {*str++ = *p; break;} + case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;} + case 'd': + case 'i': + case 'u': + { + int d = va_arg (ap, int); + char const *s = itoa (d); + if (width >= 0) + width = width - strlen (s); + if (!left_p) + while (width-- > 0) + *str++ = pad; + while (*s) + *str++ = *s++; + while (width-- > 0) + *str++ = pad; + break; + } + case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;} + default: + { + eputs ("vsprintf: not supported: %"); + eputc (c); + eputs ("\n"); + p++; + } + } + p++; + } + va_end (ap); + *str = 0; + return strlen (str); +} + +int +sprintf (char *str, char const* format, ...) +{ + va_list ap; + va_start (ap, format); + int r = vsprintf (str, format, ap); + va_end (ap); + return r; +} + +int +printf (char const* format, ...) +{ + va_list ap; + va_start (ap, format); + int r = vprintf (format, ap); + va_end (ap); + return r; +} diff --git a/lib/libc.c b/lib/libc.c index b50a1126..b4c3f198 100644 --- a/lib/libc.c +++ b/lib/libc.c @@ -139,7 +139,6 @@ strcmp (char const* a, char const* b) return *a - *b; } - char * strcpy (char *dest, char const *src) { @@ -185,9 +184,13 @@ realloc (void *ptr, size_t size) } int -strncmp (char const* a, char const* b, size_t length) +strncmp (char const* a, char const* b, size_t size) { - while (*a && *b && *a == *b && --length) {a++;b++;} + while (*a && *b && *a == *b && --size) + { + a++; + b++; + } return *a - *b; } @@ -205,7 +208,7 @@ fwrite (void const *data, size_t size, size_t count, FILE *stream) char * getenv (char const* s) { - char **p = g_environment; + char **p = environ; int length = strlen (s); while (*p) { @@ -218,7 +221,7 @@ getenv (char const* s) int setenv (char const* s, char const* v, int overwrite_p) { - char **p = g_environment; + char **p = environ; int length = strlen (s); while (*p) { @@ -238,77 +241,6 @@ setenv (char const* s, char const* v, int overwrite_p) return 0; } -int -vprintf (char const* format, va_list ap) -{ - char const *p = format; - while (*p) - if (*p != '%') - putchar (*p++); - else - { - p++; - char c = *p; - switch (c) - { - case '%': {putchar (*p); break;} - case 'c': {char c; c = va_arg (ap, char); putchar (c); break;} - case 'd': {int d; d = va_arg (ap, int); puts (itoa (d)); break;} - case 's': {char *s; s = va_arg (ap, char *); puts (s); break;} - default: {putchar (*p); break;} - } - p++; - } - va_end (ap); - return 0; -} - -int -printf (char const* format, ...) -{ - va_list ap; - va_start (ap, format); - int r = vprintf (format, ap); - va_end (ap); - return r; -} - -int -vsprintf (char *str, char const* format, va_list ap) -{ - char const *p = format; - while (*p) - if (*p != '%') - *str++ = *p++; - else - { - p++; - char c = *p; - switch (c) - { - case '%': {*str++ = *p; break;} - case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;} - case 'd': {int d; d = va_arg (ap, int); char const *s; s = itoa (d); while (*s) *str++ = *s++; break;} - case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;} - default: {*str++ = *p; break;} - } - p++; - } - va_end (ap); - *str = 0; - return strlen (str); -} - -int -sprintf (char *str, char const* format, ...) -{ - va_list ap; - va_start (ap, format); - int r = vsprintf (str, format, ap); - va_end (ap); - return r; -} - int isatty (int fd) { diff --git a/lib/libgetopt.c b/lib/libgetopt.c new file mode 100644 index 00000000..62d3f85d --- /dev/null +++ b/lib/libgetopt.c @@ -0,0 +1,21 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include diff --git a/lib/linux+tcc-gcc.c b/lib/linux+tcc-gcc.c index 61d195f9..61d0c592 100644 --- a/lib/linux+tcc-gcc.c +++ b/lib/linux+tcc-gcc.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software - * Copyright © 2016,2017 Jan (janneke) Nieuwenhuizen + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen * * This file is part of Mes. * @@ -18,18 +18,17 @@ * along with Mes. If not, see . */ -#define SYS_exit "0x01" -#define SYS_read "0x03" -#define SYS_write "0x04" -#define SYS_open "0x05" #define SYS_close "0x06" +#define SYS_link "0x09" #define SYS_unlink "0x0a" #define SYS_lseek "0x13" #define SYS_access "0x21" -#define SYS_brk "0x2d" +#define SYS_rename "0x26" +#define SYS_mkdir "0x27" +#define SYS_rmdir "0x28" #define SYS_stat "0x6a" +#define SYS_lstat "0x6b" #define SYS_fstat "0x6c" -#define SYS_fsync "0x76" #define SYS_getcwd "0xb7" int @@ -48,6 +47,27 @@ close (int fd) #endif } +int +link (char const *old_name, char const *new_name) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + + "mov $"SYS_link",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (old_name), "" (new_name) + : "eax", "ebx", "ecx" + ); + return r; +#endif +} + int unlink (char const *file_name) { @@ -86,6 +106,61 @@ lseek (int fd, off_t offset, int whence) #endif } +int +rename (char const *old_name, char const *new_name) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + + "mov $"SYS_rename",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (old_name), "" (new_name) + : "eax", "ebx", "ecx" + ); + return r; +#endif +} + +int +mkdir (char const *s, mode_t mode) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + "mov $"SYS_mkdir",%%eax\n\t" + "int $0x80\n\t" + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (s), "" (mode) + : "eax", "ebx", "ecx" + ); + return r; +#endif +} + +int +rmdir (char const *file_name) +{ +#if !__TINYC__ + int r; + asm ( + "mov %0,%%ebx\n\t" + "mov $"SYS_rmdir",%%eax\n\t" + "int $0x80" + : "=r" (r) + : "" (file_name) + ); + return r; +#endif +} int stat (char const *file_name, struct stat *statbuf) @@ -108,6 +183,27 @@ stat (char const *file_name, struct stat *statbuf) #endif } +int +lstat (char const *file_name, struct stat *statbuf) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + + "mov $"SYS_lstat",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (file_name), "" (statbuf) + : "eax", "ebx", "ecx" + ); + return r; +#endif +} + int fstat (int fd, struct stat *statbuf) { diff --git a/lib/linux+tcc-mes.c b/lib/linux+tcc-mes.c index 3dbb8365..435d73ee 100644 --- a/lib/linux+tcc-mes.c +++ b/lib/linux+tcc-mes.c @@ -38,6 +38,25 @@ unlink (char const *file_name) asm ("int____$0x80"); } +int +rmdir (char const *file_name) +{ + asm ("mov____0x8(%ebp),%ebx !8"); + + asm ("mov____$i32,%eax SYS_unlink"); + asm ("int____$0x80"); +} + +int +stat (char const *file_name, struct stat *statbuf) +{ + asm ("mov____0x8(%ebp),%ebx !8"); + asm ("mov____0x8(%ebp),%ecx !12"); + + asm ("mov____$i32,%eax SYS_getcwd"); + asm ("int____$0x80"); +} + off_t lseek (int fd, off_t offset, int whence) { diff --git a/lib/linux-gcc.c b/lib/linux-gcc.c index 9294cb02..1b2bde75 100644 --- a/lib/linux-gcc.c +++ b/lib/linux-gcc.c @@ -22,16 +22,27 @@ #include #include #include +#include #include +#define SYS_fork "0x02" +#define SYS_read "0x03" +#define SYS_open "0x05" +#define SYS_waitpid "0x07" +#define SYS_execve "0x0b" +#define SYS_chmod "0x0f" +#define SYS_access "0x21" +#define SYS_brk "0x2d" +#define SYS_ioctl "0x36" +#define SYS_fsync "0x76" + int fork () { #if !__TINYC__ int r; - //syscall (SYS_fork, fd)); asm ( - "mov $0x02,%%eax\n\t" + "mov $"SYS_fork",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -47,14 +58,13 @@ read (int fd, void* buf, size_t n) { #if !__TINYC__ int r; - //syscall (SYS_write, fd, s, n)); asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "movl $0x3,%%eax\n\t" - "int $0x80\n\t" + "mov $"SYS_read",%%eax\n\t" + "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -84,7 +94,8 @@ open (char const *s, int flags, ...) "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "mov $0x5,%%eax\n\t" + + "mov $"SYS_open",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -100,13 +111,12 @@ waitpid (pid_t pid, int *status_ptr, int options) { #if !__TINYC__ int r; - //syscall (SYS_execve, file_name, argv, env)); asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "mov $0x07,%%eax\n\t" + "mov $"SYS_waitpid",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" @@ -123,13 +133,12 @@ execve (char const* file_name, char *const argv[], char *const env[]) { #if !__TINYC__ int r; - //syscall (SYS_execve, file_name, argv, env)); asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "mov $0x0b,%%eax\n\t" + "mov $"SYS_execve",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" @@ -142,15 +151,15 @@ execve (char const* file_name, char *const argv[], char *const env[]) } int -chmod (char const *s, int mode) +chmod (char const *s, mode_t mode) { #if !__TINYC__ int r; - //syscall (SYS_chmod, mode)); asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" - "mov $0x0f,%%eax\n\t" + + "mov $"SYS_chmod",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -166,11 +175,11 @@ access (char const *s, int mode) { #if !__TINYC__ int r; - //syscall (SYS_access, mode)); asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" - "mov $0x21,%%eax\n\t" + + "mov $"SYS_access",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -189,9 +198,8 @@ brk (void *p) asm ( "mov %1,%%ebx\n\t" - "mov $0x2d,%%eax\n\t" + "mov $"SYS_brk",%%eax\n\t" "int $0x80\n\t" - "mov %%eax,%0\n\t" : "=r" (r) : "" (p) @@ -221,7 +229,7 @@ ioctl (int fd, unsigned long request, ...) "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "mov $0x36, %%eax\n\t" + "mov $"SYS_ioctl",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -241,7 +249,7 @@ fsync (int fd) asm ( "mov %1,%%ebx\n\t" - "mov $0x76, %%eax\n\t" + "mov $"SYS_fsync",%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) diff --git a/lib/linux-mini-gcc.c b/lib/linux-mini-gcc.c index 01ce07b3..f8386526 100644 --- a/lib/linux-mini-gcc.c +++ b/lib/linux-mini-gcc.c @@ -18,6 +18,9 @@ * along with Mes. If not, see . */ +#define SYS_exit "0x01" +#define SYS_write "0x04" + void exit (int code) { @@ -32,7 +35,8 @@ exit (int code) #else // __TINYC__ asm ( "mov %0,%%ebx\n\t" - "mov $1,%%eax\n\t" + + "mov $"SYS_exit",%%eax\n\t" "int $128\n\t" : // no outputs "=" (r) : "Ir" (code) @@ -59,15 +63,13 @@ write (int fd, char const* s, int n) : "" (fd), "" (s), "" (n) : "eax", "ebx", "ecx", "edx" ); - - //syscall (SYS_write, fd, s, n)); #elif __TINYC__ asm ( "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - "mov $4, %%eax\n\t" + "mov $"SYS_write",%%eax\n\t" "int $128\n\t" "mov %%eax,%0\n\t" : "=r" (r) diff --git a/lib/m4.c b/lib/m4.c index a746a3ae..54326c52 100644 --- a/lib/m4.c +++ b/lib/m4.c @@ -33,17 +33,15 @@ atof (int x) } int -atol (int x) +atol (char const *s) { - eputs ("atol stub\n"); - return 0; + return atoi (s); } int -bcmp (int x) +bcmp (void const *s1, void const *s2, size_t size) { - eputs ("bcmp stub\n"); - return 0; + return memcmp (s1, s2, size); } void @@ -53,10 +51,9 @@ bcopy (void const *src, void *dest, size_t n) } int -bzero (int x) +bzero (void *block, size_t size) { - eputs ("bzero stub\n"); - return 0; + return memset (block, 0, size); } int @@ -127,11 +124,12 @@ isupper (int c) return c >= 'A' && c <= 'Z'; } -int -mktemp (int x) +char * +mktemp (char *template) { - eputs ("mktemp stub\n"); - return 0; + char *p = strchr (template, '0'); + *--p = &p; + return template; } int @@ -197,15 +195,17 @@ system (int x) } int -tolower (int x) +tolower (int c) { - eputs ("tolower stub\n"); - return 0; + if (isupper (c)) + return c + ('a' - 'A'); + return c; } int -toupper (int x) +toupper (int c) { - eputs ("toupper stub\n"); - return 0; + if (islower (c)) + return c - ('a' - 'A'); + return c; } diff --git a/module/mescc/preprocess.scm b/module/mescc/preprocess.scm index 34252b3e..9a4d7367 100644 --- a/module/mescc/preprocess.scm +++ b/module/mescc/preprocess.scm @@ -49,6 +49,7 @@ "__i386__=1" "POSIX=0" "_POSIX_SOURCE=0" + "__STDC__=1" "__MESC__=1" ,(if mes? "__MESC_MES__=1" "__MESC_MES__=0") ,@defines) diff --git a/scaffold/tests/70-printf.c b/scaffold/tests/70-printf.c index 469e17ec..46ffcc3a 100644 --- a/scaffold/tests/70-printf.c +++ b/scaffold/tests/70-printf.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software - * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen * * This file is part of Mes. * @@ -28,20 +28,43 @@ test () char *s = "mes"; char c = 'm'; int i = 3; - char buf[10]; + char buf[20]; printf ("c=%c\n", c); sprintf (buf, "c=%c\n", c); - if (strcmp (buf, "c=m\n")) return 1; + if (strcmp (buf, "c=m\n")) + return 1; if (i != 3) return 15; printf ("i=%d\n", i); sprintf (buf, "i=%d\n", i); - if (strcmp (buf, "i=3\n")) return 2; + if (strcmp (buf, "i=3\n")) + return 2; printf ("s=%s\n", s); sprintf (buf, "s=%s\n", s); - if (strcmp (buf, "s=mes\n")) return 3; + if (strcmp (buf, "s=mes\n")) + return 3; + + sprintf (buf, ">%3d<", 11); + eputs (buf); eputs ("\n"); + if (strcmp (buf, "> 11<")) + return 4; + + sprintf (buf, ">%03d<", 22); + eputs (buf); eputs ("\n"); + if (strcmp (buf, ">022<")) + return 5; + + sprintf (buf, ">%-10d<", 33); + eputs (buf); eputs ("\n"); + if (strcmp (buf, ">33 <")) + return 6; + + sprintf (buf, ">%0d<", 44); + eputs (buf); eputs ("\n"); + if (strcmp (buf, ">44<")) + return 7; return 0; } diff --git a/scaffold/tests/90-strpbrk.c b/scaffold/tests/90-strpbrk.c new file mode 100644 index 00000000..548b843e --- /dev/null +++ b/scaffold/tests/90-strpbrk.c @@ -0,0 +1,52 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include + +int +main () +{ + char buf[100]; + strcpy (buf, "foo"); + + strcat (buf, " bar"); + eputs (buf); eputs ("\n"); + if (strcmp (buf, "foo bar")) + return 22; + + strncat (buf, " bazzzz", 4); + eputs (buf); eputs ("\n"); + if (strcmp (buf, "foo bar baz")) + return 2; + + char *p = strpbrk ("hello, world", " \t\n,.;!?"); + if (strcmp (p, ", world")) + return 3; + eputs ("\n"); + + if (strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz") != 5) + return 4; + + if (strcspn ("hello, world", " \t\n,.;!?") != 5) + return 5; + + + return 0; +} diff --git a/scaffold/tests/91-fseek.c b/scaffold/tests/91-fseek.c new file mode 100644 index 00000000..3aa53a7d --- /dev/null +++ b/scaffold/tests/91-fseek.c @@ -0,0 +1,58 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include +#include +#include +#include + +int +main () +{ + int fd = open ("COPYING", 0); + if (fd <= 0) + return 1; + FILE* f = fdopen (fd, "r"); + int r = fseek (f, 0, SEEK_CUR); + if (r != 0) + return 2; + int pos = ftell (f); + if (pos != 0) + return 3; + + r = fseek (f, 0, SEEK_END); + if (r != 0) + return 4; + + pos = ftell (f); + eputs ("size="); eputs (itoa (pos)); eputs ("\n"); + if (pos != 35147) + return 5; + r = fseek (f, 0, SEEK_SET); + + char buf[4096]; + fgets (buf, 200, f); + eputs (buf); + if (strcmp (buf, " GNU GENERAL PUBLIC LICENSE\n")) + return 6; + + return 0; +} diff --git a/src/posix.c b/src/posix.c index b8dbf601..d0403ce5 100644 --- a/src/posix.c +++ b/src/posix.c @@ -284,7 +284,7 @@ execl_ (SCM file_name, SCM args) ///((name . "execl")) args = CDR (args); } c_argv[i] = 0; - return MAKE_NUMBER (execve (c_argv[0], c_argv, g_environment)); + return MAKE_NUMBER (execve (c_argv[0], c_argv, environ)); } SCM