diff --git a/.gitignore b/.gitignore index 73458649..d20997ac 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.gcc *.gcc-o *.gcc-out +*.gcc-stdout *.go *.guile *.log diff --git a/GNUmakefile b/GNUmakefile index 506f93b3..132e8d96 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,6 +3,9 @@ GUILE_FLAGS:=--no-auto-compile -L . -L guile -C . -C guile include .config.make +.config.make: + ./configure + PHONY_TARGETS:= all all-go check clean clean-go default help install .PHONY: $(PHONY_TARGETS) diff --git a/build-aux/build-mes-gcc.sh b/build-aux/build-mes-gcc.sh index 7ce4a4b2..2dca41f1 100755 --- a/build-aux/build-mes-gcc.sh +++ b/build-aux/build-mes-gcc.sh @@ -62,12 +62,14 @@ C32FLAGS=${C32FLAGS-" -nostdlib "} +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/crt0 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 +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes-gcc.sh lib/libg sh build-aux/cc-mes-gcc.sh scaffold/main sh build-aux/cc-mes-gcc.sh scaffold/hello diff --git a/build-aux/cc.sh b/build-aux/cc.sh index 0b4610d6..19381623 100755 --- a/build-aux/cc.sh +++ b/build-aux/cc.sh @@ -55,6 +55,7 @@ $CC\ -c\ $CPPFLAGS\ $CFLAGS\ + -D WITH_GLIBC=1\ -D POSIX=1\ -o "$o".${p}o\ "$c".c diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 64a0261f..3ce4a04e 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -145,6 +145,8 @@ broken="$broken 91-fseek " +# gcc not supported +CC= set +e expect=$(echo $broken | wc -w) pass=0 diff --git a/build-aux/test.sh b/build-aux/test.sh index 9739cce0..25e83ff8 100755 --- a/build-aux/test.sh +++ b/build-aux/test.sh @@ -34,6 +34,24 @@ shift set -e +rm -f "$t".gcc-out +if [ -n "$CC" ]; then + sh build-aux/cc.sh "$t" + + r=0 + [ -f "$t".exit ] && r=$(cat "$t".exit) + set +e + "$t".gcc-out $ARGS > "$t".gcc-stdout + m=$? + cat "$t".gcc-stdout + set -e + + [ $m = $r ] + if [ -f "$t".expect ]; then + $DIFF -ub "$t".expect "$t".gcc-stdout; + fi +fi + rm -f "$t".mes-gcc-out if [ -n "$CC32" ]; then sh build-aux/cc-mes-gcc.sh "$t" diff --git a/include/alloca.h b/include/alloca.h index 07f88f3f..b06ffbaf 100644 --- a/include/alloca.h +++ b/include/alloca.h @@ -20,15 +20,15 @@ #ifndef __MES_ALLOCA_H #define __MES_ALLOCA_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_ALLOCA_H 1 #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC void* alloca (size_t); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_ALLOCA_H diff --git a/include/assert.h b/include/assert.h index eb1f3bac..317c99f4 100644 --- a/include/assert.h +++ b/include/assert.h @@ -20,15 +20,15 @@ #ifndef __MES_ASSERT_H #define __MES_ASSERT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_ASSERT_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define assert(x) ((x) ? (void)0 : assert_fail (#x)) void assert_fail (char* s); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_ASSERT_H diff --git a/include/ctype.h b/include/ctype.h index b0c7889f..c533f244 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -20,18 +20,18 @@ #ifndef __MES_CTYPE_H #define __MES_CTYPE_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_CTYPE_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include int isdigit (int); int isxdigit (int); int isspace (int); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_CTYPE_H diff --git a/include/dlfcn.h b/include/dlfcn.h index 54e85534..1774380f 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -20,11 +20,11 @@ #ifndef __MES_DLFCN_H #define __MES_DLFCN_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_DLFCN_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define RTLD_LAZY 0x00001 #define RTLD_NOW 0x00002 @@ -38,7 +38,7 @@ void *dlopen (char const *filename, int flags); int dlclose (void *handle); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_DLFCN_H diff --git a/include/endian.h b/include/endian.h index 45e57c60..192bc83a 100644 --- a/include/endian.h +++ b/include/endian.h @@ -20,17 +20,17 @@ #ifndef __MES_ENDIAN_H #define __MES_ENDIAN_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_ENDIAN_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 #define __BYTE_ORDER __LITTLE_ENDIAN -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_ENDIAN_H diff --git a/include/errno.h b/include/errno.h index 72c89a43..83655d38 100644 --- a/include/errno.h +++ b/include/errno.h @@ -20,30 +20,31 @@ #ifndef __MES_ERRNO_H #define __MES_ERRNO_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_ERRNO_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC 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 */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define EMFILE 24 /* Too many open files */ -#define EPIPE 32 /* Broken pipe */ -#define ERANGE 34 /* Math result not representable */ +#define ENOENT 2 +#define EIO 5 +#define EBADF 9 +#define EAGAIN 11 +#define ENOMEM 12 +#define EEXIST 17 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define EMFILE 24 +#define EPIPE 32 +#define ERANGE 34 -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOSYS 38 /* Invalid system call number */ -#define ELOOP 40 /* Too many symbolic links encountered */ +#define ENAMETOOLONG 36 +#define ENOSYS 38 +#define ELOOP 40 -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_ERRNO_H diff --git a/include/fcntl.h b/include/fcntl.h index 879181bc..deefe3e7 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -20,14 +20,14 @@ #ifndef __MES_FCNTL_H #define __MES_FCNTL_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_FCNTL_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 @@ -42,6 +42,6 @@ #define F_SETFL 4 int open (char const *s, int flags, ...); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_FCNTL_H diff --git a/include/features.h b/include/features.h index e887ee8f..eeecfc95 100644 --- a/include/features.h +++ b/include/features.h @@ -20,10 +20,10 @@ #ifndef __MES_FEATURES_H #define __MES_FEATURES_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_FEATURES_H #include_next -#endif // (__GNUC__ && POSIX) +#endif // (WITH_GLIBC) #endif // __MES_FEATURES_H diff --git a/include/float.h b/include/float.h index 35d9b896..d250aea8 100644 --- a/include/float.h +++ b/include/float.h @@ -20,15 +20,15 @@ #ifndef __MES_FLOAT_H #define __MES_FLOAT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_FLOAT_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define MIN_EXP -1021 #define DBL_MIN_EXP -1021 #define LDBL_MIN_EXP -1021 -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_FLOAT_H diff --git a/include/getopt.h b/include/getopt.h index 1200ff46..1c50e936 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -21,14 +21,14 @@ #ifndef __MES_GETOPT_H #define __MES_GETOPT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_GETOPT_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include int isdigit (int); int isxdigit (int); @@ -57,6 +57,6 @@ int getopt_long (int argc, char *const *argv, char const *options, int getopt_long_only (int argc, char *const *argv, char const *options, struct option const *long_options, int *opt_index); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_GETOPT_H diff --git a/include/inttypes.h b/include/inttypes.h index c963f34f..eae673aa 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -20,15 +20,15 @@ #ifndef __MES_INTTYPES_H #define __MES_INTTYPES_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_INTTYPES_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_INTTYPES_H diff --git a/include/libgen.h b/include/libgen.h index 76eb8cd9..001069a8 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -20,15 +20,15 @@ #ifndef __MES_LIBGEN_H #define __MES_LIBGEN_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_LIBGEN_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC char* dirname (char*); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_LIBGEN_H diff --git a/include/libmes.h b/include/libmes.h index ac4f1879..4d2c3d5e 100644 --- a/include/libmes.h +++ b/include/libmes.h @@ -21,7 +21,9 @@ #ifndef __MES_LIBMES_H #define __MES_LIBMES_H -char const* itoa (int); +char const* number_to_ascii (int number, int base, int signed_p); +char const* itoa (int number); +char const* utoa (unsigned number); char const* itoab (int x, int base); int _atoi (char const**, int base); int atoi (char const *s); diff --git a/include/limits.h b/include/limits.h index 9d4c3308..c1e0f4d3 100644 --- a/include/limits.h +++ b/include/limits.h @@ -20,14 +20,14 @@ #ifndef __MES_LIMITS_H #define __MES_LIMITS_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_LIMITS_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define CHAR_BIT 8 #define UCHAR_MAX 255 #define INT_MIN -2147483648 @@ -36,6 +36,6 @@ #define LONG_MIN -2147483648 #define LONG_MAX 2147483647 -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_LIMITS_H diff --git a/include/locale.h b/include/locale.h index 91d6ac65..d429a767 100644 --- a/include/locale.h +++ b/include/locale.h @@ -20,15 +20,15 @@ #ifndef __MES_LOCALE_H #define __MES_LOCALE_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_LOCALE_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC char* dirname (char*); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_LOCALE_H diff --git a/include/math.h b/include/math.h index df0006c4..a8d5636e 100644 --- a/include/math.h +++ b/include/math.h @@ -20,12 +20,12 @@ #ifndef __MES_MATH_H #define __MES_MATH_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_MATH_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC double ldexp (double x, int exp); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_MATH_H diff --git a/include/memory.h b/include/memory.h index 82c9088b..4412c56e 100644 --- a/include/memory.h +++ b/include/memory.h @@ -20,17 +20,17 @@ #ifndef __MES_MEMORY_H #define __MES_MEMORY_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_MEMORY_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_MEMORY_H diff --git a/include/pwd.h b/include/pwd.h index 09f4245a..a9b9b6d8 100644 --- a/include/pwd.h +++ b/include/pwd.h @@ -20,10 +20,10 @@ #ifndef __MES_PWD_H #define __MES_PWD_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_PWD_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC struct passwd { @@ -36,6 +36,6 @@ struct passwd char *pw_shell; }; -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_PWD_H diff --git a/include/setjmp.h b/include/setjmp.h index fdfee319..e5f1e404 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -20,10 +20,10 @@ #ifndef __MES_SETJMP_H #define __MES_SETJMP_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SETJMP_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC typedef struct { @@ -42,7 +42,7 @@ jmp_buf buf; void longjmp (jmp_buf env, int val); int setjmp (jmp_buf env); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SETJMP_H diff --git a/include/signal.h b/include/signal.h index 122fbb95..57b284b6 100644 --- a/include/signal.h +++ b/include/signal.h @@ -20,10 +20,10 @@ #ifndef __MES_SIGNAL_H #define __MES_SIGNAL_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SIGNAL_H #include_next -#else //! (__GNUC__ && POSIX) +#else //! WITH_GLIBC typedef int sigset_t; typedef int stack_t; @@ -218,6 +218,6 @@ typedef struct ucontext int sigaction (int signum, struct sigaction const *act, struct sigaction *oldact); int sigemptyset (sigset_t *set); -#endif //! (__GNUC__ && POSIX) +#endif //! WITH_GLIBC #endif // __MES_SIGNAL_H diff --git a/include/stdarg.h b/include/stdarg.h index 6675bced..03487a56 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -20,10 +20,10 @@ #ifndef __MES_STDARG_H #define __MES_STDARG_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_STDARG_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef __MES_SIZE_T #define __MES_SIZE_T @@ -48,6 +48,6 @@ int vsprintf (char *str, char const *format, va_list ap); int vsnprintf (char *str, size_t size, char const *format, va_list ap); int vsscanf (char const *s, char const *template, va_list ap); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDARG_H diff --git a/include/stdbool.h b/include/stdbool.h index 72136ece..1fc8a873 100644 --- a/include/stdbool.h +++ b/include/stdbool.h @@ -20,17 +20,17 @@ #ifndef __MES_STDBOOL_H #define __MES_STDBOOL_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STDBOOL_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC typedef int bool; #define false 0 #define true 1 -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDBOOL_H diff --git a/include/stddef.h b/include/stddef.h index 20174580..1283066f 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -20,10 +20,11 @@ #ifndef __MES_STDDEF_H #define __MES_STDDEF_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_STDDEF_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC + #include #include @@ -35,6 +36,6 @@ #endif // !__MESC__ #endif // offsetof -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDDEF_H diff --git a/include/stdint.h b/include/stdint.h index fb58223c..eb774d6c 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -20,14 +20,14 @@ #ifndef __MES_STDINT_H #define __MES_STDINT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STDINT_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #undef unsigned #undef uint8_t @@ -71,6 +71,6 @@ typedef unsigned* uintptr_t; typedef unsigned ptrdiff_t; -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDINT_H diff --git a/include/stdio.h b/include/stdio.h index 414b4ce2..9cd6ddec 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -36,14 +36,14 @@ int g_stdout; #define STDERR 2 #endif -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STDIO_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef __MESCCLIB__ #define __MESCCLIB__ 15 @@ -113,6 +113,6 @@ size_t fread (void *ptr, size_t size, size_t count, FILE *stream); size_t freadahead (FILE *fp); size_t fwrite (void const *ptr, size_t size, size_t count, FILE *stream); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDIO_H diff --git a/include/stdlib.h b/include/stdlib.h index 83686cc1..c683902c 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -20,13 +20,13 @@ #ifndef __MES_STDLIB_H #define __MES_STDLIB_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STDLIB_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef __MES_SIZE_T #define __MES_SIZE_T @@ -56,7 +56,7 @@ unsigned long long strtoull (char const *nptr, char **endptr, int base); #include -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDLIB_H diff --git a/include/stdnoreturn.h b/include/stdnoreturn.h index 434882f2..0e615ac7 100644 --- a/include/stdnoreturn.h +++ b/include/stdnoreturn.h @@ -20,15 +20,15 @@ #ifndef __MES_STDNORETURN_H #define __MES_STDNORETURN_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STDNORETURN_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC // whut? -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STDNORETURN_H diff --git a/include/string.h b/include/string.h index 556eeffe..8d503d9b 100644 --- a/include/string.h +++ b/include/string.h @@ -20,14 +20,14 @@ #ifndef __MES_STRING_H #define __MES_STRING_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_STRING_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef NULL #define NULL 0 @@ -55,10 +55,11 @@ char *strchr (char const *s, int c); int strcmp (char const*, char const*); char *strcpy (char *dest, char const *src); size_t strlen (char const*); +char *strncpy (char *to, char const *from, size_t size); int strncmp (char const*, char const*, size_t); char *strrchr (char const *s, int c); char *strstr (char const *haystack, char const *needle); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_STRING_H diff --git a/include/strings.h b/include/strings.h index e65c6a14..72c986e1 100644 --- a/include/strings.h +++ b/include/strings.h @@ -20,10 +20,10 @@ #ifndef __MES_STRINGS_H #define __MES_STRINGS_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_STRINGS_H #include_next -#endif // (__GNUC__ && POSIX) +#endif // (WITH_GLIBC) #endif // __MES_STRINGS_H diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h index 9f681488..f04c7d80 100644 --- a/include/sys/cdefs.h +++ b/include/sys/cdefs.h @@ -20,10 +20,10 @@ #ifndef __MES_SYS_CDEFS_H #define __MES_SYS_CDEFS_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_CDEFS_H #include_next -#endif // (__GNUC__ && POSIX) +#endif // (WITH_GLIBC) #endif // __MES_SYS_CDEFS_H diff --git a/include/sys/dir.h b/include/sys/dir.h index 424a093a..d7607b6d 100644 --- a/include/sys/dir.h +++ b/include/sys/dir.h @@ -20,13 +20,13 @@ #ifndef __MES_SYS_DIR_H #define __MES_SYS_DIR_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_DIR_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_DIR_H diff --git a/include/sys/file.h b/include/sys/file.h index 171469a0..e9fcd317 100644 --- a/include/sys/file.h +++ b/include/sys/file.h @@ -20,13 +20,13 @@ #ifndef __MES_SYS_FILE_H #define __MES_SYS_FILE_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_FILE_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_FILE_H diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index d24fd82b..dbe4beca 100644 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -20,17 +20,17 @@ #ifndef __MES_SYS_IOCTL_H #define __MES_SYS_IOCTL_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_IOCTL_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #define TCGETS 0x5401 #define TCGETA 0x5405 int ioctl (int fd, unsigned long request, ...); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_IOCTL_H diff --git a/include/sys/mman.h b/include/sys/mman.h index 06e99779..9d59f84f 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -20,10 +20,10 @@ #ifndef __MES_SYS_MMAN_H #define __MES_SYS_MMAN_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_MMAN_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef __MES_SIZE_T #define __MES_SIZE_T @@ -37,7 +37,7 @@ typedef unsigned long size_t; int mprotect (void *addr, size_t len, int prot); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_MMAN_H diff --git a/include/sys/param.h b/include/sys/param.h index e7998a3f..32e6d6a7 100644 --- a/include/sys/param.h +++ b/include/sys/param.h @@ -20,12 +20,12 @@ #ifndef __MES_SYS_PARAM_H #define __MES_SYS_PARAM_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_PARAM_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_PARAM_H diff --git a/include/sys/select.h b/include/sys/select.h index e6899821..ff989124 100644 --- a/include/sys/select.h +++ b/include/sys/select.h @@ -20,12 +20,12 @@ #ifndef __MES_SYS_SELECT_H #define __MES_SYS_SELECT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_SELECT_H #include_next -#else //! (__GNUC__ && POSIX) +#else //! WITH_GLIBC typedef int fd_set; -#endif //! (__GNUC__ && POSIX) +#endif //! WITH_GLIBC #endif // __MES_SYS_SELECT_H diff --git a/include/sys/stat.h b/include/sys/stat.h index 3698331f..74998f15 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -20,11 +20,11 @@ #ifndef __MES_SYS_STAT_H #define __MES_SYS_STAT_H 1lei -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_STAT_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include @@ -75,6 +75,6 @@ int rmdir (char const *file_name); #define S_IWUSR 00200 #define S_IRUSR 00400 -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_STAT_H diff --git a/include/sys/time.h b/include/sys/time.h index b48b5230..e8769fed 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -20,11 +20,11 @@ #ifndef __MES_SYS_TIME_H #define __MES_SYS_TIME_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_TIME_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC struct timeval { @@ -51,6 +51,6 @@ struct itimerval int gettimeofday (struct timeval *tv, struct timezone *tz); int setitimer (int which, struct itimerval const *new, struct itimerval *old); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_TIME_H diff --git a/include/sys/timeb.h b/include/sys/timeb.h index d89f4f96..5d1abf6c 100644 --- a/include/sys/timeb.h +++ b/include/sys/timeb.h @@ -20,10 +20,10 @@ #ifndef __MES_SYS_TIMEB_H #define __MES_SYS_TIMEB_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_TIMEB_H #include_next -#endif // (__GNUC__ && POSIX) +#endif // (WITH_GLIBC) #endif // __MES_SYS_TIMEB_H diff --git a/include/sys/times.h b/include/sys/times.h new file mode 100644 index 00000000..60da88b9 --- /dev/null +++ b/include/sys/times.h @@ -0,0 +1,49 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2017 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_TIMES_H +#define __MES_SYS_TIMES_H 1 + +#if WITH_GLIBC +#undef __MES_SYS_TIMES_H +#include_next + +#else // ! WITH_GLIBC + +#ifndef __MES_CLOCK_T +#define __MES_CLOCK_T +#undef clock_t +typedef long clock_t; +#endif + +#ifndef HZ +#define HZ 100 +#endif + +struct tms +{ + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; + +#endif // ! WITH_GLIBC + +#endif // __MES_SYS_TIMES_H diff --git a/include/sys/types.h b/include/sys/types.h index 87cbd30d..1e7c310b 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -20,22 +20,16 @@ #ifndef __MES_SYS_TYPES_H #define __MES_SYS_TYPES_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_TYPES_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #include -#ifndef __MES_SIZE_T -#define __MES_SIZE_T -#undef size_t -typedef unsigned long size_t; -#endif - -#ifndef __MES_PID_T -#define __MES_PID_T -#undef pid_t -typedef int pid_t; +#ifndef __MES_DEV_T +#define __MES_DEV_T +#undef dev_t +typedef int dev_t; #endif #ifndef __MES_GID_T @@ -44,12 +38,30 @@ typedef int pid_t; typedef int gid_t; #endif +#ifndef __MES_INO_T +#define __MES_INO_T +#undef ino_t +typedef unsigned ino_t; +#endif + +#ifndef __MES_PID_T +#define __MES_PID_T +#undef pid_t +typedef int pid_t; +#endif + +#ifndef __MES_SIZE_T +#define __MES_SIZE_T +#undef size_t +typedef unsigned long size_t; +#endif + #ifndef __MES_UID_T #define __MES_UID_T #undef uid_t typedef int uid_t; #endif -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_TYPES_H diff --git a/include/sys/ucontext.h b/include/sys/ucontext.h index 0d159402..2de76493 100644 --- a/include/sys/ucontext.h +++ b/include/sys/ucontext.h @@ -20,10 +20,10 @@ #ifndef __MES_SYS_UCONTEXT_H #define __MES_SYS_UCONTEXT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_UCONTEXT_H #include_next -#endif // (__GNUC__ && POSIX) +#endif // (WITH_GLIBC) #endif // __MES_SYS_UCONTEXT_H diff --git a/include/sys/user.h b/include/sys/user.h index 03777b71..a3ea1a15 100644 --- a/include/sys/user.h +++ b/include/sys/user.h @@ -20,11 +20,11 @@ #ifndef __MES_SYS_USER_H #define __MES_SYS_USER_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_USER_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC /* These are the 32-bit x86 structures. */ struct user_fpregs_struct @@ -104,6 +104,6 @@ struct user #define HOST_TEXT_START_ADDR (u.start_code) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_USER_H diff --git a/include/sys/wait.h b/include/sys/wait.h index 37bb299c..aa4473fb 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -20,10 +20,10 @@ #ifndef __MES_SYS_WAIT_H #define __MES_SYS_WAIT_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_SYS_WAIT_H #include_next -#else // !(__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef __MES_PID_T #define __MES_PID_T @@ -33,6 +33,6 @@ typedef int pid_t; pid_t waitpid (pid_t pid, int *status_ptr, int options); pid_t wait (int *status_ptr); -#endif // !(__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_SYS_WAIT_H diff --git a/include/time.h b/include/time.h index e5219f6b..c8bd415f 100644 --- a/include/time.h +++ b/include/time.h @@ -20,10 +20,10 @@ #ifndef __MES_TIME_H #define __MES_TIME_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #undef __MES_TIME_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC typedef int time_t; struct tm { @@ -44,21 +44,22 @@ time_t time (time_t *tloc); #ifndef __MES_STRUCT_TIMESPEC #define __MES_STRUCT_TIMESPEC -#ifndef __kernel_long_t -typedef long __kernel_long_t; -typedef unsigned long __kernel_ulong_t; -#endif +// #ifndef __kernel_long_t +// typedef long __kernel_long_t; +// typedef unsigned long __kernel_ulong_t; +// #endif -typedef __kernel_long_t __kernel_time_t; +// typedef __kernel_long_t __kernel_time_t; struct timespec { - __kernel_time_t tv_sec; + //__kernel_time_t tv_sec; + long tv_sec; long tv_nsec; }; #endif // __MES_STRUCT_TIMESPEC -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_TIME_H diff --git a/include/unistd.h b/include/unistd.h index 9cf809b7..bd21b4dd 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -20,14 +20,14 @@ #ifndef __MES_UNISTD_H #define __MES_UNISTD_H 1 -#if __GNUC__ && POSIX +#if WITH_GLIBC #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #undef __MES_UNISTD_H #include_next -#else // ! (__GNUC__ && POSIX) +#else // ! WITH_GLIBC #ifndef NULL #define NULL 0 @@ -51,8 +51,20 @@ typedef unsigned long size_t; typedef long ssize_t; #endif +#ifndef R_OK +#define F_OK 0 +#define X_OK 1 +#define W_OK 2 +#define R_OK 4 +#endif + int access (char const *s, int mode); +unsigned int alarm (unsigned int seconds); +#define alarm(x) {eputs ("alarm x="); eputs (itoa (x)); eputs ("\n"); kill (getpid (), 14);} +#define atexit(x) eputs ("atexit\n") + int close (int fd); +int execv (char const *file_name, char *const argv[]); int execve (char const *file, char *const argv[], char *const env[]); int execvp (char const *file, char *const argv[]); int fork (); @@ -62,6 +74,6 @@ off_t lseek (int fd, off_t offset, int whence); int read (int fd, void* buf, size_t n); int unlink (char const *file_name); int write (int fd, char const* s, int n); -#endif // ! (__GNUC__ && POSIX) +#endif // ! WITH_GLIBC #endif // __MES_UNISTD_H diff --git a/lib/binutils.c b/lib/binutils.c index 00175ba3..1510b8d4 100644 --- a/lib/binutils.c +++ b/lib/binutils.c @@ -157,8 +157,10 @@ strcspn (char const *string, char const *stopset) char * strncat (char *to, char const *from, size_t size) { + if (size == 0) + return to; char *p = strchr (to , '\0'); - while (*from && size--) + while (*from && size-- > 1) *p++ = *from++; *p = 0; return to; diff --git a/lib/crt0.c b/lib/crt0.c new file mode 100644 index 00000000..08cbbc80 --- /dev/null +++ b/lib/crt0.c @@ -0,0 +1,61 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2017,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 . + */ + +// no clue what crt0.o is and why gcc-2.6.3 needs it + +// instead of calling main, it seems to call either _main or ___main, +// let's try _main first + +char **environ = 0; +int _main (int argc, char *argv[]); + +void +_start () +{ + 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" + : "=environ" (environ) + : //no inputs "" + ); + asm ( + "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" + + "call _main\n\t" + + "mov %%eax,%%ebx\n\t" + "mov $1,%%eax\n\t" + "int $0x80\n\t" + "hlt \n\t" + : + ); +} diff --git a/lib/gcc.c b/lib/gcc.c new file mode 100644 index 00000000..27ae03e6 --- /dev/null +++ b/lib/gcc.c @@ -0,0 +1,48 @@ +/* -*-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 + +FILE * +freopen (char const *file_name, char const *opentype, FILE *stream) +{ + fclose (stream); + return fopen (file_name, opentype); +} + +clock_t +times (struct tms *buffer) +{ + eputs ("times stub\n"); + return 0; +} + +unsigned int +sleep (unsigned int seconds) +{ + struct timespec requested_time; + struct timespec remaining; + requested_time.tv_sec = seconds; + requested_time.tv_nsec = 0; + return nanosleep (&requested_time, &remaining); +} diff --git a/lib/libc+gnu.c b/lib/libc+gnu.c index 54329110..31229180 100644 --- a/lib/libc+gnu.c +++ b/lib/libc+gnu.c @@ -18,6 +18,9 @@ * along with Mes. If not, see . */ +#include #include +#include #include #include +#include diff --git a/lib/libc+tcc.c b/lib/libc+tcc.c index d3ee7372..26ed3011 100644 --- a/lib/libc+tcc.c +++ b/lib/libc+tcc.c @@ -1,6 +1,7 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2018 Jeremiah Orians * Copyright (C) 2018 Han-Wen Nienhuys * * This file is part of Mes. @@ -19,6 +20,8 @@ * along with Mes. If not, see . */ +#include +#include #include #include #include @@ -57,13 +60,65 @@ dlopen (char const *filename, int flags) return 0; } -int -execvp (char const *file, char *const argv[]) +char * +search_path (char const *file_name) { - eputs ("execvp stub\n"); + static char buf[256]; + char *path = getenv ("PATH"); + if (getenv ("MESC_DEBUG")) + { + eputs ("\n search-path: "); eputs (file_name); eputs ("\n"); + } + while (*path) + { + char *end = strchr (path, ':'); + if (!end) + end = strchr (path, '\0'); + strncpy (buf, path, end - path); + buf[end - path] = 0; + if (getenv ("MESC_DEBUG")) + { + eputs (" dir: "); eputs (buf); eputs ("\n"); + } + if (buf[end - path] != '/') + strcat (buf, "/"); + strcat (buf, file_name); + if (!access (buf, X_OK)) + { + if (getenv ("MESC_DEBUG")) + { + eputs (" found: "); eputs (buf); eputs ("\n"); + } + return buf; + } + path = end + 1; + } return 0; } +int +execvp (char const *file_name, char *const argv[]) +{ + if (file_name[0] != '/') + file_name = search_path (file_name); + if (!file_name) + { + errno = ENOENT; + return -1; + } + if (getenv ("MESC_DEBUG")) + { + eputs (" EXEC: "); eputs (file_name); eputs ("\n"); + int i = 0; + while (argv[i]) + { + eputs (" arg["); eputs (itoa (i)); eputs ("]: "); eputs (argv[i]); eputs ("\n"); + i++; + } + } + return execve (file_name, argv, environ); +} + int fclose (FILE *stream) { @@ -110,7 +165,18 @@ fread (void *data, size_t size, size_t count, FILE *stream) if (bytes > 0) return bytes/size; - return bytes; + return 0; +} + +size_t +fwrite (void const *data, size_t size, size_t count, FILE *stream) +{ + if (! size || !count) + return 0; + int bytes = write ((int)stream, data, size * count); + if (bytes > 0) + return bytes/size; + return 0; } long @@ -119,6 +185,31 @@ ftell (FILE *stream) return lseek ((int)stream, 0, SEEK_CUR); } +FILE* +fopen (char const *file_name, char const *opentype) +{ + int fd; + if (opentype[0] == 'a') + { + fd = open (file_name, O_RDONLY); + if (fd > 0) + { + close (fd); + fd = open (file_name, O_RDWR); + lseek (fd, 0, SEEK_END); + return fd; + } + } + if (opentype[0] == 'w' || opentype[0] == 'a') + /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */ + fd = open (file_name, 577 , 384); + else + /* Everything else is a read */ + fd = open (file_name, 0, 0); + + return (FILE*)fd; +} + int fseek (FILE *stream, long offset, int whence) { @@ -262,7 +353,6 @@ sscanf (char const *str, const char *template, ...) int r = vsscanf (str, template, ap); va_end (ap); return r; - return 0; } char * @@ -289,16 +379,18 @@ strchr (char const *s, int c) } char * -strncpy (char *dest, char const *src, size_t length) +strncpy (char *to, char const *from, size_t size) { - char *p = dest; - while (*src && length--) - *p++ = *src++; - if (*src) - length++; - while (length--) + if (size == 0) + return to; + char *p = to; + while (*from && size--) + *p++ = *from++; + if (*from) + size++; + while (size--) *p++ = 0; - return dest; + return to; } char * @@ -431,6 +523,58 @@ calloc (size_t nmemb, size_t size) return p; } + +int +islower (int c) +{ + return c >= 'a' && c <= 'z'; +} +int +isupper (int c) +{ + return c >= 'A' && c <= 'Z'; +} + +int +tolower (int c) +{ + if (isupper (c)) + return c + ('a' - 'A'); + return c; +} + +int +toupper (int c) +{ + if (islower (c)) + return c - ('a' - 'A'); + return c; +} + +char * +strlwr (char *string) +{ + char *p = string; + while (*p) + { + *p = tolower (*p); + p++; + } + return string; +} + +char * +strupr (char *string) +{ + char *p = string; + while (*p) + { + *p = toupper (*p); + p++; + } + return string; +} + int vfprintf (FILE* f, char const* format, va_list ap) { @@ -443,12 +587,90 @@ vfprintf (FILE* f, char const* format, va_list ap) { p++; char c = *p; + int left_p = 0; + int precision_p = 0; + int width = -1; + if (c == 'l') + c = *++p; + if (c == '-') + { + left_p = 1; + c = *++p; + } + if (c == '.') + { + precision_p = 1; + c = *++p; + } + char pad = ' '; + if (c == '0') + { + pad = c; + c = *p++; + } + if (c >= '0' && c <= '9') + { + width = abtoi (&p, 10); + c = *p; + } + else if (c == '*') + { + width = va_arg (ap, int); + c = *++p; + } + if (c == 'l') + c = *++p; switch (c) { case '%': {fputc (*p, fd); break;} - 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;} + case 'c': {char c; c = va_arg (ap, int); fputc (c, fd); break;} + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + { + int d = va_arg (ap, int); + int base = c == 'o' ? 8 + : c == 'x' || c == 'X' ? 16 + : 10; + char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X'); + if (c == 'X') + strupr (s); + if (!precision_p && width >= 0) + width = width - strlen (s); + if (!left_p && !precision_p) + while (!precision_p && width-- > 0) + fputc (pad, f); + while (*s) + { + if (precision_p && width-- == 0) + break; + fputc (*s++, f); + } + while (!precision_p && width-- > 0) + fputc (pad, f); + break; + } + case 's': + { + char *s = va_arg (ap, char *); + if (!precision_p && width >= 0) + width = width - strlen (s); + if (!left_p && !precision_p) + while (!precision_p && width-- > 0) + fputc (pad, f); + while (*s) + { + if (precision_p && width-- == 0) + break; + fputc (*s++, f); + } + while (!precision_p && width-- > 0) + fputc (pad, f); + break; + } default: { eputs ("vfprintf: not supported: %"); @@ -474,6 +696,7 @@ vsscanf (char const *s, char const *template, va_list ap) { char const *p = s; char const *t = template; + int count = 0; while (*t && *p) if (*t != '%') { @@ -487,10 +710,22 @@ vsscanf (char const *s, char const *template, va_list ap) switch (c) { case '%': {p++; break;} - case 'c': {char *c = va_arg (ap, char*); *c = *p++; break;} + case 'c': + { + char *c = va_arg (ap, char*); + *c = *p++; + count++; + break; + } case 'd': case 'i': - case 'u': {int *d = va_arg (ap, int*); *d = abtoi (&p, 10); break;} + case 'u': + { + int *d = va_arg (ap, int*); + *d = abtoi (&p, 10); + count++; + break; + } default: { eputs ("vsscanf: not supported: %"); @@ -503,7 +738,7 @@ vsscanf (char const *s, char const *template, va_list ap) t++; } va_end (ap); - return 0; + return count; } int @@ -518,12 +753,20 @@ vsprintf (char *str, char const* format, va_list ap) p++; char c = *p; int left_p = 0; + int precision_p = 0; int width = -1; + if (c == 'l') + c = *++p; if (c == '-') { left_p = 1; c = *++p; } + if (c == '.') + { + precision_p = 1; + c = *++p; + } char pad = ' '; if (c == '0') { @@ -535,28 +778,64 @@ vsprintf (char *str, char const* format, va_list ap) width = abtoi (&p, 10); c = *p; } + else if (c == '*') + { + width = va_arg (ap, int); + c = *++p; + } + if (c == 'l') + c = *++p; switch (c) { case '%': {*str++ = *p; break;} - case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;} + case 'c': {c = va_arg (ap, int); *str++ = c; break;} case 'd': case 'i': + case 'o': case 'u': + case 'x': + case 'X': { int d = va_arg (ap, int); - char const *s = itoa (d); - if (width >= 0) + int base = c == 'o' ? 8 + : c == 'x' || c == 'X' ? 16 + : 10; + char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X'); + if (c == 'X') + strupr (s); + if (!precision_p && width >= 0) width = width - strlen (s); - if (!left_p) - while (width-- > 0) + if (!left_p && !precision_p) + while (!precision_p && width-- > 0) *str++ = pad; while (*s) - *str++ = *s++; - while (width-- > 0) + { + if (precision_p && width-- == 0) + break; + *str++ = *s++; + } + while (!precision_p && width-- > 0) + *str++ = pad; + break; + } + case 's': + { + char *s = va_arg (ap, char *); + if (!precision_p && width >= 0) + width = width - strlen (s); + if (!left_p && !precision_p) + while (!precision_p && width-- > 0) + *str++ = pad; + while (*s) + { + if (precision_p && width-- == 0) + break; + *str++ = *s++; + } + while (!precision_p && width-- > 0) *str++ = pad; break; } - case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;} default: { eputs ("vsprintf: not supported: %"); diff --git a/lib/libc.c b/lib/libc.c index b4c3f198..18eff321 100644 --- a/lib/libc.c +++ b/lib/libc.c @@ -1,7 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen - * Copyright © 2018 Jeremiah Orians * * This file is part of Mes. * @@ -36,7 +35,6 @@ #else // !__MESC__ -#include #include #include @@ -81,20 +79,6 @@ putc (int c, FILE* stream) return fdputc (c, (int)stream); } -FILE* -fopen (char const* file_name, char const* mode) -{ - int fd; - if ('w' == mode[0]) - /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */ - fd = open (file_name, 577 , 384); - else - /* Everything else is a read */ - fd = open (file_name, 0, 0); - - return (FILE*)fd; -} - void assert_fail (char* s) { @@ -186,6 +170,8 @@ realloc (void *ptr, size_t size) int strncmp (char const* a, char const* b, size_t size) { + if (!size) + return 0; while (*a && *b && *a == *b && --size) { a++; @@ -194,17 +180,6 @@ strncmp (char const* a, char const* b, size_t size) return *a - *b; } -size_t -fwrite (void const *data, size_t size, size_t count, FILE *stream) -{ - if (! size || !count) - return 0; - int bytes = write ((int)stream, data, size * count); - if (bytes > 0) - return count; - return bytes; -} - char * getenv (char const* s) { @@ -252,3 +227,9 @@ wait (int *status_ptr) { return waitpid (-1, status_ptr, 0); } + +int +execv (char const *file_name, char *const argv[]) +{ + return execve (file_name, argv, environ); +} diff --git a/lib/libg.c b/lib/libg.c new file mode 100644 index 00000000..2c4a6067 --- /dev/null +++ b/lib/libg.c @@ -0,0 +1,96 @@ +/* -*-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 . + */ + +// gcc/xgcc wants -lg with all these +// what's the story here? + +#include + +#define exit __exit +#define fprintf _fprintf +#define longjmp _longjmp +#define malloc _malloc +#define printf _printf +#define putchar _putchar +#define setjmp _setjmp +#define signal _signal +#define strcmp _strcmp +#define sprintf _sprintf +#define sscanf _sscanf + +#include +#include +#include +#include +#include + +int +__cleanup () +{ + eputs ("cleanup stub\n"); + return 0; +} + +int +_dprop () +{ + eputs ("dprop stub\n"); +} + +int +_edprop () +{ + eputs ("edprop stub\n"); +} + +int +_eldprop () +{ + eputs ("eldprop stub\n"); +} + +int +_iprop () +{ + eputs ("iprop stub\n"); +} + +int +_lprop () +{ + eputs ("lprop stub\n"); +} + +int +_ldprop () +{ + eputs ("ldprop stub\n"); +} + +int +_uiprop () +{ + eputs ("uiprop stub\n"); +} +int +_ulprop () +{ + eputs ("ulprop stub\n"); +} diff --git a/lib/libmes.c b/lib/libmes.c index fa67879d..f6a04d78 100644 --- a/lib/libmes.c +++ b/lib/libmes.c @@ -84,7 +84,7 @@ atoi (char const *s) } char const* -itoa (int x) +number_to_ascii (int x, int base, int signed_p) { static char itoa_buf[12]; char *p = itoa_buf + 11; @@ -92,7 +92,7 @@ itoa (int x) int sign = 0; unsigned u = x; - if (x < 0) + if (signed_p && x < 0) { sign = 1; u = -x; @@ -100,8 +100,9 @@ itoa (int x) do { - *p-- = '0' + (u % 10); - u = u / 10; + int i = u % base; + *p-- = i > 9 ? 'a' + i - 10 : '0' + i; + u = u / base; } while (u); if (sign && *(p + 1) != '0') @@ -113,29 +114,19 @@ itoa (int x) char const* itoab (int x, int base) { - static char itoa_buf[12]; - char *p = itoa_buf + 11; - *p-- = 0; + return number_to_ascii (x, base, 1); +} - int sign = 0; - unsigned u = x; - if (x < 0) - { - sign = 1; - u = -x; - } +char const* +itoa (int x) +{ + return number_to_ascii (x, 10, 1); +} - do - { - int i = u % base; - *p-- = i > 9 ? 'a' + i - 10 : '0' + i; - x = u / base; - } while (u); - - if (sign && *(p + 1) != '0') - *p-- = '-'; - - return p+1; +char const* +utoa (unsigned x) +{ + return number_to_ascii (x, 10, 0); } int _ungetc_pos = -1; @@ -187,7 +178,7 @@ fdungetc (int c, int fd) return c; } -#if POSIX +#if POSIX || __x86_64__ #define STDERR 2 int eputs (char const* s) diff --git a/lib/linux+gnu-gcc.c b/lib/linux+gnu-gcc.c new file mode 100644 index 00000000..e6cd0df7 --- /dev/null +++ b/lib/linux+gnu-gcc.c @@ -0,0 +1,179 @@ +/* -*-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 . + */ + +#define SYS_link "0x09" +#define SYS_rename "0x26" +#define SYS_mkdir "0x27" +#define SYS_dup "0x29" +#define SYS_pipe "0x2a" +#define SYS_lstat "0x6b" +#define SYS_fstat "0x6c" + +#define SYS_kill 0x25 +#define SYS_nanosleep 0xa2 + +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 +kill (pid_t pid, int signum) +{ + return _sys_call2 (SYS_kill, pid, signum); +} + +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 +dup (int old) +{ +#if !__TINYC__ + int r; + asm ( + "mov %0,%%ebx\n\t" + "mov $"SYS_dup",%%eax\n\t" + "int $0x80" + : "=r" (r) + : "" (old) + ); + return r; +#endif +} + +int +pipe (int filedes[2]) +{ +#if !__TINYC__ + int r; + asm ( + "mov %0,%%ebx\n\t" + "mov $"SYS_pipe",%%eax\n\t" + "int $0x80" + : "=r" (r) + : "" (filedes) + ); + return r; +#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 +nanosleep (const struct timespec *requested_time, + struct timespec *remaining) +{ + return _sys_call2 (SYS_execve, (int)requested_time, (int)remaining); +} + +int +fstat (int fd, struct stat *statbuf) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + + "mov $"SYS_fstat",%%eax\n\t" + //"mov $"SYS_oldfstat",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (fd), "" (statbuf) + : "eax", "ebx", "ecx" + ); + return r; +#endif +} diff --git a/lib/linux+tcc-gcc.c b/lib/linux+tcc-gcc.c index 61d0c592..d73772ad 100644 --- a/lib/linux+tcc-gcc.c +++ b/lib/linux+tcc-gcc.c @@ -19,16 +19,10 @@ */ #define SYS_close "0x06" -#define SYS_link "0x09" -#define SYS_unlink "0x0a" #define SYS_lseek "0x13" -#define SYS_access "0x21" -#define SYS_rename "0x26" -#define SYS_mkdir "0x27" +#define SYS_unlink "0x0a" #define SYS_rmdir "0x28" #define SYS_stat "0x6a" -#define SYS_lstat "0x6b" -#define SYS_fstat "0x6c" #define SYS_getcwd "0xb7" int @@ -47,43 +41,6 @@ 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) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_unlink",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (file_name) - ); - return r; -#endif -} - off_t lseek (int fd, off_t offset, int whence) { @@ -107,40 +64,16 @@ lseek (int fd, off_t offset, int whence) } int -rename (char const *old_name, char const *new_name) +unlink (char const *file_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" + "mov %0,%%ebx\n\t" + "mov $"SYS_unlink",%%eax\n\t" + "int $0x80" : "=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" + : "" (file_name) ); return r; #endif @@ -179,49 +112,8 @@ stat (char const *file_name, struct stat *statbuf) : "" (file_name), "" (statbuf) : "eax", "ebx", "ecx" ); - return r; -#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) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_fstat",%%eax\n\t" - //"mov $"SYS_oldfstat",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd), "" (statbuf) - : "eax", "ebx", "ecx" - ); + if (r < 0) + errno = -r; return r; #endif } diff --git a/lib/linux+tcc-mes.c b/lib/linux+tcc-mes.c index 435d73ee..8013371a 100644 --- a/lib/linux+tcc-mes.c +++ b/lib/linux+tcc-mes.c @@ -43,7 +43,7 @@ rmdir (char const *file_name) { asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____$i32,%eax SYS_unlink"); + asm ("mov____$i32,%eax SYS_rmdir"); asm ("int____$0x80"); } diff --git a/lib/linux-gcc.c b/lib/linux-gcc.c index 1b2bde75..5ed78460 100644 --- a/lib/linux-gcc.c +++ b/lib/linux-gcc.c @@ -18,6 +18,7 @@ * along with Mes. If not, see . */ +#include #include #include #include @@ -29,13 +30,61 @@ #define SYS_read "0x03" #define SYS_open "0x05" #define SYS_waitpid "0x07" -#define SYS_execve "0x0b" +#define SYS_execve 0x0b #define SYS_chmod "0x0f" #define SYS_access "0x21" #define SYS_brk "0x2d" #define SYS_ioctl "0x36" #define SYS_fsync "0x76" +#define xSYS_execve "0x0b" + +int +_sys_call2 (int sys_call, int one, int two) +{ +#if !__TINYC__ + int r; + asm ( + "mov %2,%%ebx\n\t" + "mov %3,%%ecx\n\t" + + "mov %1,%%eax\n\t" + "int $0x80\n\t" + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (sys_call), "" (one), "" (two) + : "eax", "ebx", "ecx" + ); + if (r < 0) + errno = -r; + return r; +#endif +} + +int +_sys_call3 (int sys_call, int one, int two, int three) +{ +#if !__TINYC__ + int r; + asm ( + "mov %2,%%ebx\n\t" + "mov %3,%%ecx\n\t" + "mov %4,%%edx\n\t" + + "mov %1,%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (sys_call), "" (one), "" (two), "" (three) + : "eax", "ebx", "ecx", "edx" + ); + if (r < 0) + errno = -r; + return r; +#endif +} + int fork () { @@ -131,23 +180,7 @@ waitpid (pid_t pid, int *status_ptr, int options) int execve (char const* file_name, char *const argv[], char *const env[]) { -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_execve",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (file_name), "" (argv), "" (env) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif + return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env); } int diff --git a/lib/m4.c b/lib/m4.c index 54326c52..da1102bb 100644 --- a/lib/m4.c +++ b/lib/m4.c @@ -100,12 +100,6 @@ iscntrl (int c) return c >= 0 && c < 32; } -int -islower (int c) -{ - return c >= 'a' && c <= 'z'; -} - int isprint (int c) { @@ -118,17 +112,17 @@ ispunct (int c) return isprint (c) && !isspace (c) && !isalnum (c); } -int -isupper (int c) -{ - return c >= 'A' && c <= 'Z'; -} - char * mktemp (char *template) { - char *p = strchr (template, '0'); - *--p = &p; + char *p = strchr (template, '\0'); + int q = (int)template; + *--p = ((unsigned char)(q >> 4)) % 26 + 'a'; + *--p = ((unsigned char)(q >> 8)) % 26 + 'a'; + *--p = ((unsigned char)(q >> 12)) % 26 + 'a'; + *--p = ((unsigned char)(q >> 16)) % 26 + 'a'; + *--p = ((unsigned char)(q >> 20)) % 26 + 'a'; + *--p = ((unsigned char)(q >> 24)) % 26 + 'a'; return template; } @@ -193,19 +187,3 @@ system (int x) eputs ("system stub\n"); return 0; } - -int -tolower (int c) -{ - if (isupper (c)) - return c + ('a' - 'A'); - return c; -} - -int -toupper (int c) -{ - if (islower (c)) - return c - ('a' - 'A'); - return c; -} diff --git a/lib/x86-mes/x86.M1 b/lib/x86-mes/x86.M1 index 3c1e0f6f..277c04d8 100644 --- a/lib/x86-mes/x86.M1 +++ b/lib/x86-mes/x86.M1 @@ -217,6 +217,7 @@ DEFINE movzwl_0x8(%ebp),%eax 0fb745 DEFINE SYS_exit 01000000 DEFINE SYS_fork 02000000 DEFINE SYS_read 03000000 +DEFINE SYS_rmdir 28000000 DEFINE SYS_write 04000000 DEFINE SYS_open 05000000 DEFINE SYS_close 06000000 diff --git a/scaffold/tests/51-strcmp.c b/scaffold/tests/51-strcmp.c index 3ab20d30..d23126f2 100644 --- a/scaffold/tests/51-strcmp.c +++ b/scaffold/tests/51-strcmp.c @@ -23,6 +23,22 @@ #include #include +#if __i386__ +#define strncmp xstrncmp +int +strncmp (char const* a, char const* b, size_t size) +{ + if (!size) + return 0; + while (*a && *b && *a == *b && --size) + { + a++; + b++; + } + return *a - *b; +} +#endif + int test () { @@ -69,7 +85,7 @@ test () if (!strncmp ("abc", "x", 1)) return 10; - if (!strncmp ("abc", "", 0)) + if (strncmp ("abc", "", 0)) return 11; return 0; diff --git a/scaffold/tests/70-printf.c b/scaffold/tests/70-printf.c index 46ffcc3a..d62e3825 100644 --- a/scaffold/tests/70-printf.c +++ b/scaffold/tests/70-printf.c @@ -21,6 +21,7 @@ #include "30-test.i" #include #include +#include int test () @@ -66,5 +67,72 @@ test () if (strcmp (buf, ">44<")) return 7; + printf (">>%.*s<<\n", 5, "hello, world"); + printf (">>%.*s<<\n", 20, "hello, world"); + + printf (">>%.*s<<\n", 10, "foo"); + printf (">>%*s<<\n", 10, "bar"); + printf (">>%-*s<<\n", 10, "baz"); + + sprintf (buf, "%ld", 42); + eputs ("buf="); eputs (buf); eputs ("\n"); + if (strcmp (buf, "42")) + return 8; + + sprintf (buf, "%u", -1); + eputs ("buf="); eputs (buf); eputs ("\n"); + if (strcmp (buf, "4294967295")) + return 9; + + sprintf (buf, ">>%.5s<<\n", "hello, world"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>hello<<\n")) + return 10; + + sprintf (buf, ">>%.*s<<\n", 5, "hello, world"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>hello<<\n")) + return 11; + + sprintf (buf, ">>%.*s<<\n", 20, "hello, world"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>hello, world<<\n")) + return 12; + + sprintf (buf, ">>%.*s<<\n", 10, "foo"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>foo<<\n")) + return 13; + + sprintf (buf, ">>%*s<<\n", 10, "bar"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">> bar<<\n")) + return 14; + + sprintf (buf, ">>%-*s<<\n", 10, "baz"); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>baz <<\n")) + return 15; + + sprintf (buf, ">>%ld<<\n", 12); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>12<<\n")) + return 16; + + sprintf (buf, ">>%o<<\n", 12); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>14<<\n")) + return 17; + + sprintf (buf, ">>%x<<\n", 12); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>c<<\n")) + return 18; + + sprintf (buf, ">>%X<<\n", 12); + eputs ("buf="); eputs (buf); + if (strcmp (buf, ">>C<<\n")) + return 19; + return 0; } diff --git a/scaffold/tests/87-sscanf.c b/scaffold/tests/87-sscanf.c index adfde721..5dd62638 100644 --- a/scaffold/tests/87-sscanf.c +++ b/scaffold/tests/87-sscanf.c @@ -26,14 +26,14 @@ test () { int i; int r = sscanf ("42", "%d", &i); - if (r) + if (r != 1) return 1; if (i != 42) return 2; char c; r = sscanf ("foo bar", "foo%cbar", &c); - if (r) + if (r != 1) return 3; if (c != ' ') return 4; diff --git a/src/posix.c b/src/posix.c index d0403ce5..fc7ddd49 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, environ)); + return MAKE_NUMBER (execv (c_argv[0], c_argv)); } SCM