diff --git a/.gitignore b/.gitignore index b56da706..28753c14 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,8 @@ *.hex2 *.hex2-o *.log -*.log +*.stderr +*.stdout *.mini-M1 *.mini-guile *.mini-hex2 diff --git a/build-aux/cc-mes.sh b/build-aux/cc-mes.sh index 2a51db5e..9c33e966 100755 --- a/build-aux/cc-mes.sh +++ b/build-aux/cc-mes.sh @@ -40,6 +40,7 @@ CPPFLAGS=${CPPFLAGS-" MESCCLAGS=${MESCCFLAGS-" "} +LIBC=${LIBC-lib/libc} c=$1 @@ -72,7 +73,7 @@ if [ -z "$NOLINK" ]; then $BLOOD_ELF\ -f stage0/x86.M1\ -f "$c".M1\ - -f lib/libc-mes.M1\ + -f $LIBC-mes.M1\ -o "$c".blood-elf-M1 $M1 --LittleEndian --Architecture=1\ -f "$c".blood-elf-M1\ @@ -80,7 +81,7 @@ if [ -z "$NOLINK" ]; then $HEX2 --LittleEndian --Architecture=1 --BaseAddress=0x1000000\ -f stage0/elf32-header.hex2\ -f lib/crt1.hex2\ - -f lib/libc-mes.hex2\ + -f $LIBC-mes.hex2\ -f "$c".hex2\ -f "$c".blood-elf-hex2\ --exec_enable\ diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index d36da3d2..0eb15690 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -107,19 +107,29 @@ t 82-define " -if [ ! -x ./i686-unknown-linux-gnu-tcc ]; then - tests=$(echo "$tests" | grep -Ev "02-return-1|05-call-1|80-setjmp|81-qsort") -fi +broken="$broken +" set +e +expect=$(echo $broken | wc -w) +pass=0 fail=0 total=0 +export LIBC=libc/libc for t in $tests; do + if [ -z "${t/[012][0-9]-*/}" ]; then + LIBC=lib/mini-libc; + elif [ -z "${t/8[0-9]-*/}" ]; then + LIBC=lib/libc+tcc; + else + LIBC=lib/libc; + fi sh build-aux/test.sh "scaffold/tests/$t" &> scaffold/tests/"$t".log r=$? total=$((total+1)) if [ $r = 0 ]; then echo $t: [OK] + pass=$((pass+1)) else echo $t: [FAIL] fail=$((fail+1)) @@ -141,7 +151,7 @@ tests=" 10_pointer 11_precedence 12_hashdefine - +13_integer_literals 14_if 15_recursion 16_nesting @@ -151,44 +161,71 @@ tests=" 20_pointer_comparison 21_char_array - - - +22_floating_point +23_type_coercion +24_math_library 25_quicksort - - +26_character_constants +27_sizeof +28_strings 29_array_address - +30_hanoi 31_args - - +32_led 33_ternary_op +34_array_assignment 35_sizeof +36_array_initialisers +37_sprintf +38_multiple_array_index +39_typedef - - - - - +40_stdio 41_hashif - +42_function_pointer 43_void_param 44_scoped_declarations 45_empty_for - +46_grep 47_switch_return 48_nested_break - +49_bracket_evaluation 50_logical_second_arg - - +51_static +52_unnamed_enum +55_lshift_type 54_goto - " -#13_integer_literals ; fail +broken="$broken +18_include + +22_floating_point +23_type_coercion +24_math_library +26_character_constants +27_sizeof +28_strings + +30_hanoi +32_led +34_array_assignment +37_sprintf +38_multiple_array_index +39_typedef + +40_stdio +42_function_pointer +46_grep +49_bracket_evaluation + +51_static +52_unnamed_enum +55_lshift_type +" + #22_floating_point ; float #23_type_coercion ; float #24_math_library ; float @@ -211,27 +248,33 @@ tests=" #55_lshift_type ; unsigned -# FIXME: have no diff -tests= +expect=$(echo $broken | wc -w) for t in $tests; do if [ ! -f scaffold/tinycc/"$t.c" ]; then echo ' [SKIP]' continue; fi - sh build-aux/test.sh "scaffold/tinycc/$t" &> scaffold/tinycc/"$t".log + sh build-aux/test.sh "scaffold/tinycc/$t" arg1 arg2 arg3 arg4 arg5 &> scaffold/tinycc/"$t".log r=$? total=$((total+1)) if [ $r = 0 ]; then echo $t: [OK] + pass=$((pass+1)) else echo $t: [FAIL] fail=$((fail+1)) fi done - -if [ $fail != 0 ]; then +[ $expect != 0 ] && echo "expect: $expect" +[ $fail != 0 ] && echo "failed: $fail" +[ $fail -lt $expect ] && echo "solved: $(($expect - $fail))" +echo "passed: $pass" +echo "total: $total" +if [ $fail != 0 -a $fail -gt $expect ]; then echo FAILED: $fail/$total exit 1 +elif [ $fail != 0 ]; then + echo PASS: $pass/$total else echo PASS: $total fi diff --git a/build-aux/diff.scm b/build-aux/diff.scm new file mode 100755 index 00000000..8176a2f3 --- /dev/null +++ b/build-aux/diff.scm @@ -0,0 +1,116 @@ +#! /bin/sh +# -*-scheme-*- +exec ${GUILE-guile} -L $(dirname 0) -e '(diff)' -s "$0" "$@" +!# + +;;; Mes --- Maxwell Equations of Software +;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen +;;; +;;; mes-snarf.scm: 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-module (diff) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (ice-9 rdelim) + #:export (main)) + +(cond-expand + (mes + (define %scheme "mes")) + (guile-2 + (define %scheme "guile") + (define-macro (mes-use-module . rest) #t)) + (guile + (use-modules (ice-9 syncase)) + (define %scheme "guile") + (define-macro (mes-use-module . rest) #t))) + +(mes-use-module (mes guile)) + +(format (current-error-port) "diff[~a]...\n" %scheme) + +(define (plus a) + (string-append "+" a)) +(define (minus a) + (string-append "-" a)) +(define (keep a) + (string-append " " a)) + +(define-record-type (make-hunk context after removed added) + hunk? + (context hunk.context) + (after hunk.after) + (removed hunk.removed) + (added hunk.added)) + +(define (hunk->lines o) + (append `(,(format #f "@@ -~a,~a +~a,~a" (length (hunk.removed o)) (+ 3 (car (hunk.context o))) (length (hunk.added o)) (+ 3 (cadr (hunk.context o)))) + ,@(map keep (filter identity (cddr (hunk.context o))))) + (map minus (hunk.removed o)) + (map plus (hunk.added o)) + (map keep (hunk.after o)))) + +(define (safe-list-head lst n) + (list-head lst (min n (length lst)))) + +;; naive diff +(define (diff a b) + (let ((a-lines (string-split (with-input-from-file a read-string) #\newline)) + (b-lines (string-split (with-input-from-file b read-string) #\newline))) + (let loop ((context '(1 1 #f #f #f)) (a-lines a-lines) (b-lines b-lines)) + ;;(format (current-error-port) "loop context=~s\n" context) + (cond ((and (null? a-lines) (null? b-lines)) '()) + ((null? a-lines) + (list (make-hunk context (safe-list-head a-lines 3) '() b-lines))) + ((null? b-lines) + (list (make-hunk context (safe-list-head a-lines 3) a-lines '()))) + ((equal? (car a-lines) (car b-lines)) + (loop `(,(1+ (car context)) + ,(1+ (cadr context)) + ,@(cdddr context) + ,(car a-lines)) + (cdr a-lines) (cdr b-lines))) + (else + (cond ((and (pair? (cdr b-lines)) (equal? (car a-lines) (cadr b-lines))) + (cons (make-hunk context (safe-list-head a-lines 3) '() (list (car b-lines))) + (loop `(,(+ 1 (car context)) + ,(+ 2 (cadr context)) + ,@(cdddr context) + ,(car a-lines)) + (cdr a-lines) (cddr b-lines)))) + ((and (pair? (cdr a-lines)) (equal? (cadr a-lines) (car b-lines))) + (cons (make-hunk context (safe-list-head a-lines 3) (list (car a-lines)) '()) + (loop `(,(+ 2 (car context)) + ,(+ 1 (cadr context)) + ,@(cddddr context) + ,(car a-lines) + ,(cadr a-lines)) + (cddr a-lines) (cdr b-lines)))) + (else (cons (make-hunk context (safe-list-head a-lines 3) (list (car a-lines)) (list (car b-lines))) + (loop `(,(1+ (car context)) + ,(1+ (cadr context)) + ,@(cdddr context) + ,(car a-lines)) + (cdr a-lines) (cdr b-lines)))))))))) + +(define (main args) + (let* ((files (cdr args)) + (files (if (equal? (car files) "-u") (cdr files) files)) + (hunks (apply diff (list-head files 2)))) + (when (pair? hunks) + (display (string-join (append-map hunk->lines hunks) "\n")) + (newline) + (exit 1)))) diff --git a/build-aux/test.sh b/build-aux/test.sh index 4454c488..cf9932a7 100755 --- a/build-aux/test.sh +++ b/build-aux/test.sh @@ -20,6 +20,10 @@ set -ex +GUILE=${GUILE-$MES} +DIFF=${DIFF-$(command -v diff)} +DIFF=${DIFF-sh build-aux/diff.scm} + t=${1-scaffold/tests/t} #rm -f "$t".i686-unknown-linux-gnu-out rm -f "$t".mes-out @@ -27,11 +31,14 @@ rm -f "$t".mes-out sh build-aux/cc-mes.sh "$t" r=0 +[ -f "$t".exit ] && r=$(cat "$t".exit) set +e -"$t".mes-out | tee "$t".stdout +"$t".mes-out "$@" > "$t".stdout m=$? +cat "$t".stdout +set -e [ $m = $r ] if [ -f "$t".expect ]; then - diff -u "$t".expect "$t".stdout; + $DIFF -u "$t".expect "$t".stdout; fi diff --git a/scaffold/tests/02-return-1.exit b/scaffold/tests/02-return-1.exit new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/scaffold/tests/02-return-1.exit @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/scaffold/tests/05-call-1.exit b/scaffold/tests/05-call-1.exit new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/scaffold/tests/05-call-1.exit @@ -0,0 +1 @@ +1 \ No newline at end of file