Repository: Konstantin8105/c4go
Pull request #379 (2019-04-02 11:21:16)

reactoring operation NOT

codecov[bot]: # [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/379?src=pr&el=h1) Report
> Merging [#379](https://codecov.io/gh/Konstantin8105/c4go/pull/379?src=pr&el=desc) into [master](https://codecov.io/gh/Konstantin8105/c4go/commit/80da77a43f3e9bbe1915c402a587a1aacf80831b?src=pr&el=desc) will **decrease** coverage by `0.05%`.
> The diff coverage is `79.41%`.

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

```diff
@@            Coverage Diff             @@
##           master     #379      +/-   ##
==========================================
- Coverage   86.03%   85.97%   -0.06%     
==========================================
  Files         188      188              
  Lines       10940    10946       +6     
==========================================
- Hits         9412     9411       -1     
- Misses       1085     1097      +12     
+ Partials      443      438       -5
```


| [Impacted Files](https://codecov.io/gh/Konstantin8105/c4go/pull/379?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [transpiler/unary.go](https://codecov.io/gh/Konstantin8105/c4go/pull/379/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci91bmFyeS5nbw==) | `74.47% <100%> (-0.16%)` | :arrow_down: |
| [types/cast.go](https://codecov.io/gh/Konstantin8105/c4go/pull/379/diff?src=pr&el=tree#diff-dHlwZXMvY2FzdC5nbw==) | `70.63% <100%> (-0.11%)` | :arrow_down: |
| [noarch/noarch.go](https://codecov.io/gh/Konstantin8105/c4go/pull/379/diff?src=pr&el=tree#diff-bm9hcmNoL25vYXJjaC5nbw==) | `78.78% <75.86%> (+12.12%)` | :arrow_up: |
| [util/util.go](https://codecov.io/gh/Konstantin8105/c4go/pull/379/diff?src=pr&el=tree#diff-dXRpbC91dGlsLmdv) | `81.77% <0%> (-2.23%)` | :arrow_down: |
| [util/goast.go](https://codecov.io/gh/Konstantin8105/c4go/pull/379/diff?src=pr&el=tree#diff-dXRpbC9nb2FzdC5nbw==) | `85.42% <0%> (-1.51%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/379?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/379?src=pr&el=footer). Last update [80da77a...bffa53f](https://codecov.io/gh/Konstantin8105/c4go/pull/379?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/noarch/noarch.go b/noarch/noarch.go
index 95d4372..5576292 100644
--- a/noarch/noarch.go
+++ b/noarch/noarch.go
@@ -1,5 +1,7 @@
 package noarch
 
+import "fmt"
+
 // 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 {
@@ -10,47 +12,35 @@ func BoolToInt(x bool) int32 {
 	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
+// Not performs a logical not (!) on an integer and returns an integer.
+func Not(x interface{}) bool {
+	switch v := x.(type) {
+	case bool:
+		return !v
+	case int:
+		return v == 0
+	case int8:
+		return v == 0
+	case int16:
+		return v == 0
+	case int32:
+		return v == 0
+	case int64:
+		return v == 0
+	case uint:
+		return v == 0
+	case uint8:
+		return v == 0
+	case uint16:
+		return v == 0
+	case uint32:
+		return v == 0
+	case uint64:
+		return v == 0
+	case float32:
+		return v == 0
+	case float64:
+		return v == 0
 	}
-
-	return 0
+	panic(fmt.Errorf("not support type %T", x))
 }
diff --git a/scripts/scripts.txt b/scripts/scripts.txt
index e559089..51d0976 100644
--- a/scripts/scripts.txt
+++ b/scripts/scripts.txt
@@ -1,7 +1,7 @@
 
 Calculate warnings : ./testdata/9wm
 		After transpiling : 4 warnings.
-		Go build : 5 warnings
+		Go build : 4 warnings
 		Unsafe   : 407
 
 Calculate warnings : ./testdata/ed
@@ -51,6 +51,6 @@ Calculate warnings in file: ./testdata/neatvi/neatvi.go
 
 Calculate warnings in file: testdata/vorbis/vorbis.go
 		After transpiling : 4 warnings.
-		Go build : 42 warnings
+		Go build : 21 warnings
 		Unsafe   : 255
 
diff --git a/transpiler/unary.go b/transpiler/unary.go
index b7cd93a..1301bda 100644
--- a/transpiler/unary.go
+++ b/transpiler/unary.go
@@ -221,11 +221,9 @@ func transpileUnaryOperatorNot(n *ast.UnaryOperator, p *program.Program) (
 
 	p.AddImport("github.com/Konstantin8105/c4go/noarch")
 
-	functionName := fmt.Sprintf("noarch.Not%s",
-		util.GetExportedName(t))
-	eType = "int"
+	eType = "bool"
 
-	return util.NewCallExpr(functionName, e),
+	return util.NewCallExpr("noarch.Not", e),
 		eType, preStmts, postStmts, nil
 }
 
diff --git a/types/cast.go b/types/cast.go
index 10d03d6..1187ad2 100644
--- a/types/cast.go
+++ b/types/cast.go
@@ -111,7 +111,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 	if util.IsFunction(cFromType) && toType == "bool" {
 		return &goast.BinaryExpr{
 			X:  expr,
-			Op: token.NEQ,
+			Op: token.NEQ, // !=
 			Y:  goast.NewIdent("nil"),
 		}, nil
 	}
@@ -353,10 +353,8 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 			return e, nil
 		}
 		if fromType == "bool" && toType == v {
-			e := util.NewGoExpr(`map[bool]int32{false: 0, true: 1}[replaceme]`)
-			// Swap replaceme with the current expression
-			e.(*goast.IndexExpr).Index = expr
-			return CastExpr(p, e, "int", cToType)
+			expr = util.NewCallExpr("noarch.BoolToInt", expr)
+			return CastExpr(p, expr, "int", cToType)
 		}
 	}
 


Test patch:
diff --git a/tests/code_quality/if.go.expected b/tests/code_quality/if.go.expected
index 3f99d38..696f255 100644
--- a/tests/code_quality/if.go.expected
+++ b/tests/code_quality/if.go.expected
@@ -52,7 +52,7 @@ func if_1() {
 		return 5
 	}()
 	r = func() int32 {
-		if map[bool]int32{false: 0, true: 1}[w > 1]+map[bool]int32{false: 0, true: 1}[r == 4] != 0 {
+		if noarch.BoolToInt(w > 1)+noarch.BoolToInt(r == 4) != 0 {
 			return -1
 		}
 		return 5
diff --git a/tests/code_quality/unsafe.c b/tests/code_quality/unsafe.c
index 2935a4e..a3dad51 100644
--- a/tests/code_quality/unsafe.c
+++ b/tests/code_quality/unsafe.c
@@ -18,24 +18,24 @@ union un{
 typedef double db;
 
 // integers
-unsafetype(char,test_char)
-unsafetype(short,test_short)
-unsafetype(int,test_int)
-unsafetype(long,test_long)
-unsafetype(long int, test_li)
-unsafetype(long long,test_ll)
-unsafetype(long long int, test_lli)
+unsafetype(char,test_char);
+unsafetype(short,test_short);
+unsafetype(int,test_int);
+unsafetype(long,test_long);
+unsafetype(long int, test_li);
+unsafetype(long long,test_ll);
+unsafetype(long long int, test_lli);
 
 // floats
-unsafetype(float, test_f)
-unsafetype(double, test_d)
-unsafetype(long double, test_ld)
+unsafetype(float, test_f);
+unsafetype(double, test_d);
+unsafetype(long double, test_ld);
 
 // struct
-unsafetype(struct str, test_struct)
+unsafetype(struct str, test_struct);
 
 // union
-unsafetype(union un, test_un)
+unsafetype(union un, test_un);
 
 // typedef
-unsafetype(db, test_typedef)
+unsafetype(db, test_typedef);
diff --git a/tests/not.c b/tests/not.c
index 493d621..e65e515 100644
--- a/tests/not.c
+++ b/tests/not.c
@@ -17,6 +17,22 @@ void print_bool(int tr,int fl)
 	} else {
 		printf("print_bool fl is false\n");
 	}
+	if (tr != 0 && fl != 0) {
+		pass("test != 0");
+	}
+	if (tr == 0 && fl == 0) {
+		pass("test == 0");
+	}
+}
+
+void ok()
+{
+	pass("success");
+}
+
+void f()
+{
+	fail("need fix");
 }
 
 #define not_c_type(type)										\
@@ -27,61 +43,62 @@ diag("------------------");										\
 	int p;														\
 	diag("not for C type : zero value");						\
 	a = 0;														\
-	if (!a) { printf("a1\n"); } else { printf("a2\n"); }			\
+	if (!a) { printf("a1\n");ok(); } else { printf("a2\n"); f();}		\
 	diag("not-not for C type : zero value");					\
 	a = 0;														\
-	if (!(!a)) { printf("a3\n"); } else { printf("a4\n"); }			\
+	if (!(!a)) { printf("a3\n");f(); } else { printf("a4\n");ok(); }		\
 	diag("for C type : function");								\
 	print_bool(!a,!(!a));										\
 	diag("for C type : assign");								\
 	p = !a;														\
-	if (p) { printf("p1\n"); } else { printf("p2\n"); }				\
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			\
 	diag("not for C type : non-zero positive value");			\
 	a = 42;														\
-	if (!a) { printf("a5\n"); } else { printf("a6\n"); }			\
+	if (!a) { printf("a5\n"); } else { printf("a6\n"); }		\
 	diag("for C type : function");								\
 	print_bool(!a,!(!a));										\
 	diag("for C type : assign");								\
 	p = !a;														\
-	if (p) { printf("p1\n"); } else { printf("p2\n"); }				\
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			\
 	diag("not-not for C type : non-zero positive value");		\
 	a = 42;														\
-	if (!(!a)) { printf("a7\n"); } else { printf("a8\n"); }			\
+	if (!(!a)) { printf("a7\n"); } else { printf("a8\n"); }		\
 	diag("not for C type : non-zero negative value");			\
 	a = -42;													\
-	if (!a) { printf("a5\n"); } else { printf("a6\n"); }			\
+	if (!a) { printf("a5\n"); } else { printf("a6\n"); }		\
 	diag("not-not for C type : non-zero negative value");		\
 	a = -42;													\
-	if (!(!a)) { printf("a7\n"); } else { printf("a8\n"); }			\
+	if (!(!a)) { printf("a7\n"); } else { printf("a8\n"); }		\
 	diag("for C type : function");								\
 	print_bool(!a,!(!a));										\
 	diag("for C type : assign");								\
 	p = !a;														\
-	if (p) { printf("p1\n"); } else { printf("p2\n"); }				\
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			\
 	diag("for C type : zero value");							\
 	a = 0;														\
-	if (a) { printf("a9\n"); } else { printf("a10\n"); }			\
+	if (a) { printf("a9\n"); } else { printf("a10\n"); }		\
 	diag("for C type : positive value");						\
 	a = 15;														\
-	if (a) { printf("a11\n"); } else { printf("a12\n"); }			\
+	if (a) { printf("a11\n"); } else { printf("a12\n"); }		\
 	diag("for C type : negative value");						\
 	a = -15;													\
-	if (a) { printf("a13\n"); } else { printf("a14\n"); }			\
+	if (a) { printf("a13\n"); } else { printf("a14\n"); }		\
 	diag("for C type : assign");								\
 	p = !a;														\
-	if (p) { printf("p1\n"); } else { printf("p2\n"); }				\
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			\
 }
 
 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   );
+	not_c_type(double          );
+	not_c_type(float           );
+	not_c_type(short			);
+	not_c_type(int				);
+	not_c_type(long				);
+	not_c_type(long double     );
+	not_c_type(long long       );
+	not_c_type(signed char     );
 }
 
 #define not_c_pointer(type)										\
@@ -144,14 +161,14 @@ diag("------------------");										\
 
 void test_c_pointers()
 {
-	// not_c_pointer(char            );
-	// not_c_pointer(double          );
-	// not_c_pointer(float           );
+	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   );
+	not_c_pointer(long double     );
+	not_c_pointer(long long       );
+	not_c_pointer(signed char     );
+	not_c_pointer(unsigned long   );
 }
 
 struct str {int i;};
@@ -163,13 +180,42 @@ void test_c_struct()
 	not_c_struct(union un		);
 }
 
+void test_c_function()
+{
+	void (*a) (void) ;
+	a = NULL;
+	int p;														
+	diag("for C pointer:  null");								
+	if   ( a)  { printf("a1\n"); } else { printf("a2\n"); }			
+	diag("for C pointer: not null");							
+	if   (!a)  { printf("a2\n"); } else { printf("a3\n"); }		
+	diag("for C pointer: not-not null");						
+	if (!(!a)) { printf("a4\n"); } else { printf("a5\n"); }		
+	diag("for C type : function");								
+	print_bool(!a,!(!a));										
+	p = !a;														
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			
+	a = test_c_pointers ;										
+	diag("for C pointer:  null");								
+	if   ( a)  { printf("a11\n"); } else { printf("a12\n"); }	
+	diag("for C pointer: not null");							
+	if   (!a)  { printf("a12\n"); } else { printf("a13\n"); }	
+	diag("for C pointer: not-not null");						
+	if (!(!a)) { printf("a14\n"); } else { printf("a15\n"); }	
+	diag("for C type : function");								
+	print_bool(!a,!(!a));										
+	p = !a;														
+	if (p) { printf("p1\n"); } else { printf("p2\n"); }			
+}
+
 int main()
 {
-    plan(0);
+    plan(18);
 
 	START_TEST(c_types);
 	START_TEST(c_pointers);
 	START_TEST(c_struct);
+	START_TEST(c_function);
 
     done_testing();
 }