Repository: Konstantin8105/c4go
Pull request #378 (2019-04-02 07:41:53)

add examples


Patch:
diff --git a/noarch/math.go b/noarch/math.go
index 8f447b7..ee3f21a 100644
--- a/noarch/math.go
+++ b/noarch/math.go
@@ -4,6 +4,16 @@ import (
 	"math"
 )
 
+// BoolToInt converts boolean value to an int, which is a common operation in C.
+// 0 and 1 represent false and true respectively.
+func BoolToInt(x bool) int32 {
+	if x {
+		return 1
+	}
+
+	return 0
+}
+
 // Signbitf ...
 func Signbitf(x float32) int32 {
 	return BoolToInt(math.Signbit(float64(x)))
diff --git a/noarch/noarch.go b/noarch/noarch.go
deleted file mode 100644
index 9b49f31..0000000
--- a/noarch/noarch.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Package noarch contains low-level functions that apply to multiple platforms.
-package noarch
-
-// BoolToInt converts boolean value to an int, which is a common operation in C.
-// 0 and 1 represent false and true respectively.
-func BoolToInt(x bool) int32 {
-	if x {
-		return 1
-	}
-
-	return 0
-}
-
-// NotInt performs a logical not (!) on an integer and returns an integer.
-func NotInt(x int32) int32 {
-	if x == 0 {
-		return 1
-	}
-
-	return 0
-}
-
-// NotInt32 performs a logical not (!) on an integer and returns an integer.
-func NotInt32(x int32) int32 {
-	if x == 0 {
-		return 1
-	}
-
-	return 0
-}
-
-// NotUint16 performs a logical not (!) on an integer and returns an integer.
-func NotUint16(x uint16) int32 {
-	if x == 0 {
-		return 1
-	}
-
-	return 0
-}
-
-// NotUint32 performs a logical not (!) on an integer and returns an integer.
-func NotUint32(x uint32) int32 {
-	if x == 0 {
-		return 1
-	}
-
-	return 0
-}
-
-// NotByte performs a logical not (!) on an integer and returns an integer.
-func NotByte(x byte) int32 {
-	if x == 0 {
-		return 1
-	}
-
-	return 0
-}
diff --git a/scripts/minmad.sh b/scripts/minmad.sh
new file mode 100755
index 0000000..e3ef1fd
--- /dev/null
+++ b/scripts/minmad.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+set -e
+
+go build
+
+mkdir -p ./testdata/
+
+# prepare variables
+	export C4GO_DIR=$GOPATH/src/github.com/Konstantin8105/c4go
+	export C4GO=$C4GO_DIR/c4go
+	export GIT_SOURCE="https://github.com/aligrudi/minmad.git"
+	export NAME="minmad"
+	export TEMP_FOLDER="./testdata/$NAME"
+	export GO_FILE="$TEMP_FOLDER/$NAME.go"
+	export GO_APP="$TEMP_FOLDER/$NAME.app"
+
+# prepare C code
+    if [ ! -d $TEMP_FOLDER ]; then
+		mkdir -p $TEMP_FOLDER
+		git clone $GIT_SOURCE $TEMP_FOLDER
+	fi
+
+# remove go files from last transpilation
+	echo "***** remove go files"
+	rm -f $TEMP_FOLDER/*.go
+	rm -f $TEMP_FOLDER/*.app
+
+# transpilation of all projects
+	echo "Transpile to $GO_FILE"
+	$C4GO transpile                         \
+		-o="$GO_FILE"                       \
+		$TEMP_FOLDER/*.c
+
+# show warnings comments in Go source
+	echo "Calculate warnings in file: $GO_FILE"
+	WARNINGS=`cat $GO_FILE | grep "^// Warning" | sort | uniq | wc -l`
+	echo "		After transpiling : $WARNINGS warnings."
+
+# show other warnings
+	# show amount error from `go build`:
+		echo "Build to $GO_APP file"
+		WARNINGS_GO=`go build -o $GO_APP -gcflags="-e" $GO_FILE 2>&1 | wc -l`
+		echo "		Go build : $WARNINGS_GO warnings"
+	# amount unsafe
+		UNSAFE=`cat $GO_FILE | grep "unsafe\." | wc -l`
+		echo "		Unsafe   : $UNSAFE"
+
+
+# Arguments menu
+echo "    -s for show detail of Go build errors"
+if [ "$1" == "-s" ]; then
+	# show go build warnings	
+		# c4go warnings
+			cat $GO_FILE | grep "^// Warning" | sort | uniq
+		# show amount error from `go build`:
+			go build -o $GO_APP -gcflags="-e" $GO_FILE 2>&1
+fi
+
+
diff --git a/scripts/neatmail.sh b/scripts/neatmail.sh
new file mode 100755
index 0000000..b2b4e29
--- /dev/null
+++ b/scripts/neatmail.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+set -e
+
+go build
+
+mkdir -p ./testdata/
+
+# prepare variables
+	export C4GO_DIR=$GOPATH/src/github.com/Konstantin8105/c4go
+	export C4GO=$C4GO_DIR/c4go
+	export GIT_SOURCE="https://github.com/aligrudi/neatmail.git"
+	export NAME="neatmail"
+	export TEMP_FOLDER="./testdata/$NAME"
+	export GO_FILE="$TEMP_FOLDER/$NAME.go"
+	export GO_APP="$TEMP_FOLDER/$NAME.app"
+
+# prepare C code
+    if [ ! -d $TEMP_FOLDER ]; then
+		mkdir -p $TEMP_FOLDER
+		git clone $GIT_SOURCE $TEMP_FOLDER
+		sed -i.bak '96,110d'   $TEMP_FOLDER/regex.c
+		sed -i.bak '75,82d;14,21d'   $TEMP_FOLDER/pg.c
+		sed -i.bak '145,153d'   $TEMP_FOLDER/mk.c
+	fi
+
+# remove go files from last transpilation
+	echo "***** remove go files"
+	rm -f $TEMP_FOLDER/*.go
+	rm -f $TEMP_FOLDER/*.app
+
+# transpilation of all projects
+	echo "Transpile to $GO_FILE"
+	$C4GO transpile                         \
+		-o="$GO_FILE"                       \
+		$TEMP_FOLDER/*.c
+
+# show warnings comments in Go source
+	echo "Calculate warnings in file: $GO_FILE"
+	WARNINGS=`cat $GO_FILE | grep "^// Warning" | sort | uniq | wc -l`
+	echo "		After transpiling : $WARNINGS warnings."
+
+# show other warnings
+	# show amount error from `go build`:
+		echo "Build to $GO_APP file"
+		WARNINGS_GO=`go build -o $GO_APP -gcflags="-e" $GO_FILE 2>&1 | wc -l`
+		echo "		Go build : $WARNINGS_GO warnings"
+	# amount unsafe
+		UNSAFE=`cat $GO_FILE | grep "unsafe\." | wc -l`
+		echo "		Unsafe   : $UNSAFE"
+
+
+# Arguments menu
+echo "    -s for show detail of Go build errors"
+if [ "$1" == "-s" ]; then
+	# show go build warnings	
+		# c4go warnings
+			cat $GO_FILE | grep "^// Warning" | sort | uniq
+		# show amount error from `go build`:
+			go build -o $GO_APP -gcflags="-e" $GO_FILE 2>&1
+fi
+
+
+
diff --git a/scripts/neatvi.sh b/scripts/neatvi.sh
index 80737a6..e8971d6 100755
--- a/scripts/neatvi.sh
+++ b/scripts/neatvi.sh
@@ -33,6 +33,7 @@ mkdir -p ./testdata/
 # transpilation of all projects
 	echo "Transpile to $GO_FILE"
 	$C4GO transpile                         \
+		-s									\
 		-clang-flag="-DTROFFFDIR=\"MMM\""	\
 		-clang-flag="-DTROFFMDIR=\"WWW\""	\
 		-o="$GO_FILE"                       \
diff --git a/scripts/scripts.sh b/scripts/scripts.sh
index 0c1980f..7f1628d 100755
--- a/scripts/scripts.sh
+++ b/scripts/scripts.sh
@@ -11,22 +11,37 @@ echo "" > $OUTPUT_FILE
 
 ./scripts/9wm.sh		2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 # ./scripts/cis71.sh		2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 # echo "" >> $OUTPUT_FILE
+
 ./scripts/ed.sh			2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
+./scripts/minmad.sh			2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
+echo "" >> $OUTPUT_FILE
+
 ./scripts/neateqn.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 ./scripts/neatmkfn.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
+./scripts/neatmail.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
+echo "" >> $OUTPUT_FILE
+
 ./scripts/neatpost.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 ./scripts/neatrefer.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 ./scripts/neatroff.sh	2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 ./scripts/neatvi.sh		2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
+
 ./scripts/vorbis.sh		2>&1 | grep -E 'warning|unsafe|Unsafe' | tee -a $OUTPUT_FILE
 echo "" >> $OUTPUT_FILE
 
diff --git a/scripts/scripts.txt b/scripts/scripts.txt
index 0dbdc1e..e559089 100644
--- a/scripts/scripts.txt
+++ b/scripts/scripts.txt
@@ -1,13 +1,18 @@
 
 Calculate warnings : ./testdata/9wm
 		After transpiling : 4 warnings.
-		Go build : 4 warnings
+		Go build : 5 warnings
 		Unsafe   : 407
 
 Calculate warnings : ./testdata/ed
-		After transpiling : 3 warnings.
+		After transpiling : 1 warnings.
+		Go build : 2 warnings
+		Unsafe   : 170
+
+Calculate warnings in file: ./testdata/minmad/minmad.go
+		After transpiling : 66 warnings.
 		Go build : 2 warnings
-		Unsafe   : 169
+		Unsafe   : 17
 
 Calculate warnings in file: ./testdata/neateqn/neateqn.go
 		After transpiling : 0 warnings.
@@ -19,6 +24,11 @@ Calculate warnings in file: ./testdata/neatmkfn/neatmkfn.go
 		Go build : 72 warnings
 		Unsafe   : 44
 
+Calculate warnings in file: ./testdata/neatmail/neatmail.go
+		After transpiling : 35 warnings.
+		Go build : 2 warnings
+		Unsafe   : 175
+
 Calculate warnings in file: ./testdata/neatpost/neatpost.go
 		After transpiling : 0 warnings.
 		Go build : 23 warnings
@@ -35,12 +45,12 @@ Calculate warnings in file: ./testdata/neatroff/neatroff.go
 		Unsafe   : 254
 
 Calculate warnings in file: ./testdata/neatvi/neatvi.go
-		After transpiling : 34 warnings.
-		Go build : 12 warnings
-		Unsafe   : 130
+		After transpiling : 2 warnings.
+		Go build : 2 warnings
+		Unsafe   : 210
 
 Calculate warnings in file: testdata/vorbis/vorbis.go
-After transpiling : 4 warnings.
+		After transpiling : 4 warnings.
 		Go build : 42 warnings
 		Unsafe   : 255
 
diff --git a/util/util.go b/util/util.go
index a27f16e..c326082 100644
--- a/util/util.go
+++ b/util/util.go
@@ -100,6 +100,9 @@ func ParseFunction(s string) (prefix string, funcname string, f []string, r []st
 		}
 	}()
 
+	// remove specific attribute for function longjmp
+	s = strings.Replace(s, "__attribute__((noreturn))", "", -1)
+
 	s = strings.TrimSpace(s)
 	if !IsFunction(s) {
 		err = fmt.Errorf("Is not function : %s", s)


Test patch:
diff --git a/tests/not.c b/tests/not.c
new file mode 100644
index 0000000..f9ac96b
--- /dev/null
+++ b/tests/not.c
@@ -0,0 +1,172 @@
+#include "tests.h"
+#include <stdio.h>
+
+#define START_TEST(t) \
+    diag(#t);         \
+    test_##t();
+
+void print_bool(int tr,int fl)
+{
+	if (tr) {
+		printf("print_bool tr is true");
+	} else {
+		printf("print_bool tr is false");
+	}
+	if (fl) {
+		printf("print_bool fl is true");
+	} else {
+		printf("print_bool fl is false");
+	}
+}
+
+#define not_c_type(type)										\
+{																\
+	diag(#type);												\
+	type a;														\
+	int p;														\
+	diag("not for C type : zero value");						\
+	a = 0;														\
+	if (!a) { printf("a1"); } else { printf("a2"); }			\
+	diag("not-not for C type : zero value");					\
+	a = 0;														\
+	if (!(!a)) { printf("a3"); } else { printf("a4"); }			\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	diag("for C type : assign");								\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+	diag("not for C type : non-zero positive value");			\
+	a = 42;														\
+	if (!a) { printf("a5"); } else { printf("a6"); }			\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	diag("for C type : assign");								\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+	diag("not-not for C type : non-zero positive value");		\
+	a = 42;														\
+	if (!(!a)) { printf("a7"); } else { printf("a8"); }			\
+	diag("not for C type : non-zero negative value");			\
+	a = -42;													\
+	if (!a) { printf("a5"); } else { printf("a6"); }			\
+	diag("not-not for C type : non-zero negative value");		\
+	a = -42;													\
+	if (!(!a)) { printf("a7"); } else { printf("a8"); }			\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	diag("for C type : assign");								\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+	diag("for C type : zero value");							\
+	a = 0;														\
+	if (a) { printf("a9"); } else { printf("a10"); }			\
+	diag("for C type : positive value");						\
+	a = 15;														\
+	if (a) { printf("a11"); } else { printf("a12"); }			\
+	diag("for C type : negative value");						\
+	a = -15;													\
+	if (a) { printf("a13"); } else { printf("a14"); }			\
+	diag("for C type : assign");								\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+}
+
+void test_c_types()
+{
+	not_c_type(char            );
+	not_c_type(double          );
+	not_c_type(float           );
+	not_c_type(int             );
+	not_c_type(long double     );
+	not_c_type(long long       );
+	not_c_type(signed char     );
+	not_c_type(unsigned long   );
+}
+
+#define not_c_pointer(type)										\
+{																\
+	diag(#type);												\
+	type * a = NULL;											\
+	int p;														\
+	diag("for C pointer:  null");								\
+	if   ( a)  { printf("a1"); } else { printf("a2"); }			\
+	diag("for C pointer: not null");							\
+	if   (!a)  { printf("a2"); } else { printf("a3"); }			\
+	diag("for C pointer: not-not null");						\
+	if (!(!a)) { printf("a4"); } else { printf("a5"); }			\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+	type b = 42; a = &b ;										\
+	diag("for C pointer:  null");								\
+	if   ( a)  { printf("a11"); } else { printf("a12"); }		\
+	diag("for C pointer: not null");							\
+	if   (!a)  { printf("a12"); } else { printf("a13"); }		\
+	diag("for C pointer: not-not null");						\
+	if (!(!a)) { printf("a14"); } else { printf("a15"); }		\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+}
+
+#define not_c_struct(type)										\
+{																\
+	diag(#type);												\
+	type * a = NULL;											\
+	int p;														\
+	diag("for C pointer:  null");								\
+	if   ( a)  { printf("a1"); } else { printf("a2"); }			\
+	diag("for C pointer: not null");							\
+	if   (!a)  { printf("a2"); } else { printf("a3"); }			\
+	diag("for C pointer: not-not null");						\
+	if (!(!a)) { printf("a4"); } else { printf("a5"); }			\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+	type b ; a = &b ;											\
+	diag("for C pointer:  null");								\
+	if   ( a)  { printf("a11"); } else { printf("a12"); }		\
+	diag("for C pointer: not null");							\
+	if   (!a)  { printf("a12"); } else { printf("a13"); }		\
+	diag("for C pointer: not-not null");						\
+	if (!(!a)) { printf("a14"); } else { printf("a15"); }		\
+	diag("for C type : function");								\
+	print_bool(!a,!(!a));										\
+	p = !a;														\
+	if (p) { printf("p1"); } else { printf("p2"); }				\
+}
+
+void test_c_pointers()
+{
+	not_c_pointer(char            );
+	not_c_pointer(double          );
+	not_c_pointer(float           );
+	not_c_pointer(int             );
+	not_c_pointer(long double     );
+	not_c_pointer(long long       );
+	not_c_pointer(signed char     );
+	not_c_pointer(unsigned long   );
+}
+
+struct str {int i;};
+union un{int i;double d;};
+
+void test_c_struct()
+{
+	not_c_struct(struct str		);
+	not_c_struct(union un		);
+}
+
+int main()
+{
+    plan(0);
+
+	START_TEST(c_types);
+	START_TEST(c_pointers);
+	START_TEST(c_struct);
+
+    done_testing();
+}
diff --git a/util/util_test.go b/util/util_test.go
index 49870ab..c1c5cb8 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -248,6 +248,13 @@ func TestResolveFunction(t *testing.T) {
 			fields:   []string{"int"},
 			returns:  []string{"void(int,void(int))"},
 		},
+		{
+			input:    "void (struct __jmp_buf_tag *, int) __attribute__((noreturn))",
+			prefix:   "",
+			funcname: "",
+			fields:   []string{"struct __jmp_buf_tag *", "int"},
+			returns:  []string{"void"},
+		},
 	}
 
 	for i, tc := range tcs {