Repository: Konstantin8105/c4go
Pull request #377 (2019-04-02 07:10:16)

ParseFunction: add support ((noreturn))

Konstantin8105: Close #327
Konstantin8105: Close  #59
codecov[bot]: # [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=h1) Report
> Merging [#377](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=desc) into [master](https://codecov.io/gh/Konstantin8105/c4go/commit/f3d9e62a2989994db5641c2a87ecf6af3ddc6287?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/Konstantin8105/c4go/pull/377/graphs/tree.svg?width=650&token=esH2rHXlZ2&height=150&src=pr)](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #377      +/-   ##
==========================================
+ Coverage   86.01%   86.01%   +<.01%     
==========================================
  Files         188      188              
  Lines       10939    10940       +1     
==========================================
+ Hits         9409     9410       +1     
  Misses       1086     1086              
  Partials      444      444
```


| [Impacted Files](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [util/util.go](https://codecov.io/gh/Konstantin8105/c4go/pull/377/diff?src=pr&el=tree#diff-dXRpbC91dGlsLmdv) | `84% <100%> (+0.07%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=footer). Last update [f3d9e62...660b24c](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

codecov[bot]: # [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=h1) Report
> Merging [#377](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=desc) into [master](https://codecov.io/gh/Konstantin8105/c4go/commit/f3d9e62a2989994db5641c2a87ecf6af3ddc6287?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/Konstantin8105/c4go/pull/377/graphs/tree.svg?width=650&token=esH2rHXlZ2&height=150&src=pr)](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #377      +/-   ##
==========================================
+ Coverage   86.01%   86.01%   +<.01%     
==========================================
  Files         188      188              
  Lines       10939    10940       +1     
==========================================
+ Hits         9409     9410       +1     
  Misses       1086     1086              
  Partials      444      444
```


| [Impacted Files](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [util/util.go](https://codecov.io/gh/Konstantin8105/c4go/pull/377/diff?src=pr&el=tree#diff-dXRpbC91dGlsLmdv) | `84% <100%> (+0.07%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=footer). Last update [f3d9e62...660b24c](https://codecov.io/gh/Konstantin8105/c4go/pull/377?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


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/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.txt b/scripts/scripts.txt
index 0dbdc1e..ca79e60 100644
--- a/scripts/scripts.txt
+++ b/scripts/scripts.txt
@@ -1,13 +1,13 @@
 
 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   : 169
+		Unsafe   : 170
 
 Calculate warnings in file: ./testdata/neateqn/neateqn.go
 		After transpiling : 0 warnings.
@@ -35,12 +35,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 {