Repository: Konstantin8105/c4go
Pull request #286 (2019-02-26 14:33:32)

CSTD: signal.h: prepare functions

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

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

```diff
@@            Coverage Diff             @@
##           master     #286      +/-   ##
==========================================
+ Coverage   87.08%   87.09%   +0.01%     
==========================================
  Files         183      184       +1     
  Lines       10000    10026      +26     
==========================================
+ Hits         8708     8732      +24     
- Misses        884      885       +1     
- Partials      408      409       +1
```


| [Impacted Files](https://codecov.io/gh/Konstantin8105/c4go/pull/286?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [transpiler/variables.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci92YXJpYWJsZXMuZ28=) | `83.56% <100%> (ø)` | :arrow_up: |
| [types/cast.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHlwZXMvY2FzdC5nbw==) | `72.59% <100%> (ø)` | :arrow_up: |
| [transpiler/unary.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci91bmFyeS5nbw==) | `77.31% <100%> (ø)` | :arrow_up: |
| [transpiler/branch.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci9icmFuY2guZ28=) | `78.84% <100%> (ø)` | :arrow_up: |
| [transpiler/enum.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci9lbnVtLmdv) | `88.02% <100%> (ø)` | :arrow_up: |
| [types/sizeof.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHlwZXMvc2l6ZW9mLmdv) | `93.1% <100%> (ø)` | :arrow_up: |
| [noarch/signal.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-bm9hcmNoL3NpZ25hbC5nbw==) | `100% <100%> (ø)` | |
| [transpiler/binary.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci9iaW5hcnkuZ28=) | `72.63% <100%> (ø)` | :arrow_up: |
| [transpiler/cast.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci9jYXN0Lmdv) | `74.64% <100%> (ø)` | :arrow_up: |
| [transpiler/call.go](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree#diff-dHJhbnNwaWxlci9jYWxsLmdv) | `78.63% <100%> (ø)` | :arrow_up: |
| ... and [8 more](https://codecov.io/gh/Konstantin8105/c4go/pull/286/diff?src=pr&el=tree-more) | |

------

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


Patch:
diff --git a/README.md b/README.md
index c3944bd..f7af01e 100644
--- a/README.md
+++ b/README.md
@@ -128,7 +128,7 @@ func main() {
             locale.h	       3/3	         100%
               math.h	     37/58	        63.8%
             setjmp.h	       0/3	           0%
-            signal.h	       0/3	           0%
+            signal.h	       3/3	         100%
             stdarg.h	       4/4	         100%
             stddef.h	       2/6	        33.3%
              stdio.h	     35/46	        76.1%
diff --git a/noarch/signal.go b/noarch/signal.go
new file mode 100644
index 0000000..e0e3558
--- /dev/null
+++ b/noarch/signal.go
@@ -0,0 +1,33 @@
+package noarch
+
+import (
+	"os"
+	"syscall"
+)
+
+var signals map[int]func(int)
+
+var c chan os.Signal
+
+func init() {
+	signals = map[int]func(int){}
+	c = make(chan os.Signal, 1)
+	go func() {
+		for ch := range c {
+			s := ch.(syscall.Signal)
+			Raise(int(s))
+		}
+	}()
+}
+
+func Raise(code int) {
+	if f, ok := signals[code]; ok {
+		f(0)
+	}
+}
+
+func Signal(code int, f func(param int)) (fr func(int)) {
+	fr, _ = signals[code]
+	signals[code] = f
+	return
+}
diff --git a/program/definition_function.go b/program/definition_function.go
index 2f31a50..435b76f 100644
--- a/program/definition_function.go
+++ b/program/definition_function.go
@@ -58,7 +58,13 @@ type DefinitionFunction struct {
 //     size_t fread(void*, size_t, size_t, FILE*) -> $0 = noarch.Fread(&1, $2, $3, $4)
 //
 var builtInFunctionDefinitions = map[string][]string{
+	"signal.h": {
+		// signal.h
+		"void (*signal(int , void (*)(int)))(int) -> noarch.Signal",
+		"int raise(int ) -> noarch.Raise",
+	},
 	"errno.h": {
+		// errno.h
 		"int * __errno_location(void ) -> noarch.ErrnoLocation",
 	},
 	"assert.h": {
@@ -398,6 +404,7 @@ func (p *Program) GetIncludeFileNameByFunctionSignature(
 			return k, nil
 		}
 	}
+
 	return
 }
 
@@ -460,23 +467,17 @@ func (p *Program) loadFunctionDefinitions() {
 		}
 
 		for _, f := range v {
-			match := util.GetRegex(`^(.+) ([^ ]+)\(([, a-z*A-Z_0-9.]*)\)( -> .+)?$`).
-				FindStringSubmatch(f)
-
-			// Unpack argument types.
-			argumentTypes := strings.Split(match[3], ",")
-			for i := range argumentTypes {
-				argumentTypes[i] = strings.TrimSpace(argumentTypes[i])
-			}
-			if len(argumentTypes) == 1 && argumentTypes[0] == "" {
-				argumentTypes = []string{}
+			index := strings.Index(f, "->")
+			_, a, w, e, err := util.ParseFunction(f[:index])
+			if err != nil {
+				panic(err)
 			}
 
 			// Defaults for transformations.
 			var returnParameters, parameters []int
 
 			// Substitution rules.
-			substitution := match[4]
+			substitution := strings.TrimSpace(f[index+2:])
 			if substitution != "" {
 				substitution = strings.TrimLeft(substitution, " ->")
 
@@ -497,9 +498,9 @@ func (p *Program) loadFunctionDefinitions() {
 			}
 
 			p.AddFunctionDefinition(DefinitionFunction{
-				Name:             match[2],
-				ReturnType:       match[1],
-				ArgumentTypes:    argumentTypes,
+				Name:             a,
+				ReturnType:       e[0],
+				ArgumentTypes:    w,
 				Substitution:     substitution,
 				ReturnParameters: returnParameters,
 				Parameters:       parameters,
diff --git a/program/definition_type.go b/program/definition_type.go
index 4a94ed7..f880048 100644
--- a/program/definition_type.go
+++ b/program/definition_type.go
@@ -82,4 +82,7 @@ var DefinitionType = map[string]string{
 
 	// time.h
 	"clock_t": "github.com/Konstantin8105/c4go/noarch.ClockT",
+
+	// signal.h
+	"sig_atomic_t": "int64",
 }
diff --git a/transpiler/binary.go b/transpiler/binary.go
index ffc2057..4344f04 100644
--- a/transpiler/binary.go
+++ b/transpiler/binary.go
@@ -239,7 +239,7 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 		err = fmt.Errorf("cannot atomic for right part. %v", err)
 		return nil, "unknown53", nil, nil, err
 	}
-	if types.IsPointer(leftType) && types.IsPointer(rightType) && operator == token.SUB {
+	if util.IsPointer(leftType) && util.IsPointer(rightType) && operator == token.SUB {
 		p.AddImport("unsafe")
 		left, leftType = util.GetUintptrForSlice(left)
 		right, rightType = util.GetUintptrForSlice(right)
@@ -294,11 +294,11 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 	}
 
 	// pointer arithmetic
-	if types.IsPointer(n.Type) {
+	if util.IsPointer(n.Type) {
 		if operator == token.ADD || // +
 			operator == token.SUB || // -
 			false {
-			if types.IsPointer(leftType) {
+			if util.IsPointer(leftType) {
 				expr, eType, newPre, newPost, err =
 					pointerArithmetic(p, left, leftType, right, rightType, operator)
 			} else {
@@ -380,7 +380,7 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 			// | `-DeclRefExpr 'char *' lvalue Var 0x26ba988 'c' 'char *'
 			// `-ImplicitCastExpr 'char *' <LValueToRValue>
 			//   `-DeclRefExpr 'char *' lvalue Var 0x26ba8a8 'b' 'char *'
-			if types.IsCPointer(leftType) {
+			if util.IsCPointer(leftType) {
 				left = util.GetUintptr(left)
 				right = util.GetUintptr(right)
 				p.AddImport("unsafe")
@@ -430,7 +430,7 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 	}
 
 	var resolvedLeftType = n.Type
-	if !types.IsFunction(n.Type) && !types.IsTypedefFunction(p, n.Type) {
+	if !util.IsFunction(n.Type) && !types.IsTypedefFunction(p, n.Type) {
 		if leftType != types.NullPointer {
 			resolvedLeftType, err = types.ResolveType(p, leftType)
 		} else {
diff --git a/transpiler/branch.go b/transpiler/branch.go
index dd22b97..d24b9b9 100644
--- a/transpiler/branch.go
+++ b/transpiler/branch.go
@@ -255,7 +255,7 @@ func transpileForStmt(n *ast.ForStmt, p *program.Program) (
 	var transpilate bool
 	if v, ok := children[3].(*ast.UnaryOperator); ok {
 		if vv, ok := v.Children()[0].(*ast.DeclRefExpr); ok {
-			if !types.IsPointer(vv.Type) && !types.IsFunction(vv.Type) {
+			if !util.IsPointer(vv.Type) && !util.IsFunction(vv.Type) {
 				switch v.Operator {
 				case "++":
 					// for case:
diff --git a/transpiler/call.go b/transpiler/call.go
index dff585e..586fa9d 100644
--- a/transpiler/call.go
+++ b/transpiler/call.go
@@ -354,7 +354,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		}
 		if len(n.Children()) > 0 {
 			if v, ok := n.Children()[0].(*ast.ImplicitCastExpr); ok &&
-				(types.IsFunction(v.Type) || types.IsTypedefFunction(p, v.Type)) {
+				(util.IsFunction(v.Type) || types.IsTypedefFunction(p, v.Type)) {
 				t := v.Type
 				if v, ok := p.TypedefType[t]; ok {
 					t = v
@@ -364,7 +364,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 						t = p.TypedefType[t]
 					}
 				}
-				prefix, fields, returns, err := types.ParseFunction(t)
+				prefix, _, fields, returns, err := util.ParseFunction(t)
 				if err != nil {
 					p.AddMessage(p.GenerateWarningMessage(fmt.Errorf(
 						"Cannot resolve function : %v", err), n))
@@ -537,7 +537,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			}
 
 			if len(functionDef.ArgumentTypes) > i {
-				if !types.IsPointer(functionDef.ArgumentTypes[i]) {
+				if !util.IsPointer(functionDef.ArgumentTypes[i]) {
 					if strings.HasPrefix(functionDef.ArgumentTypes[i], "union ") {
 						a = &goast.CallExpr{
 							Fun: &goast.SelectorExpr{
diff --git a/transpiler/cast.go b/transpiler/cast.go
index fdbc9db..2874efc 100644
--- a/transpiler/cast.go
+++ b/transpiler/cast.go
@@ -22,8 +22,8 @@ func transpileImplicitCastExpr(n *ast.ImplicitCastExpr, p *program.Program, expr
 		}
 	}()
 
-	n.Type = types.GenerateCorrectType(n.Type)
-	n.Type2 = types.GenerateCorrectType(n.Type2)
+	n.Type = util.GenerateCorrectType(n.Type)
+	n.Type2 = util.GenerateCorrectType(n.Type2)
 
 	if n.Kind == ast.CStyleCastExprNullToPointer {
 		expr = goast.NewIdent("nil")
@@ -44,7 +44,7 @@ func transpileImplicitCastExpr(n *ast.ImplicitCastExpr, p *program.Program, expr
 		// ImplicitCastExpr 'double *' <IntegralToPointer>
 		// `-ImplicitCastExpr 'long' <LValueToRValue>
 		//   `-DeclRefExpr 'long' lvalue Var 0x30e91d8 'pnt' 'long'
-		if types.IsCPointer(n.Type) {
+		if util.IsCPointer(n.Type) {
 			if t, ok := ast.GetTypeIfExist(n.Children()[0]); ok {
 				if types.IsCInteger(p, *t) {
 					resolveType := n.Type
@@ -132,7 +132,7 @@ func transpileImplicitCastExpr(n *ast.ImplicitCastExpr, p *program.Program, expr
 		return
 	}
 
-	if types.IsFunction(exprType) {
+	if util.IsFunction(exprType) {
 		cast = false
 	}
 	if n.Kind == ast.ImplicitCastExprArrayToPointerDecay {
@@ -154,9 +154,9 @@ func transpileImplicitCastExpr(n *ast.ImplicitCastExpr, p *program.Program, expr
 	// ImplicitCastExpr 'char *' <ArrayToPointerDecay>
 	// `-MemberExpr 'char [20]' lvalue .input_str 0x3662ba0
 	//   `-DeclRefExpr 'struct s_inp':'struct s_inp' lvalue Var 0x3662c50 's' 'struct s_inp':'struct s_inp'
-	if types.IsCPointer(n.Type) {
+	if util.IsCPointer(n.Type) {
 		if len(n.Children()) > 0 {
-			if memb, ok := n.Children()[0].(*ast.MemberExpr); ok && types.IsCArray(memb.Type) {
+			if memb, ok := n.Children()[0].(*ast.MemberExpr); ok && util.IsCArray(memb.Type) {
 				expr = &goast.SliceExpr{
 					X:      expr,
 					Lbrack: 1,
@@ -181,8 +181,8 @@ func transpileCStyleCastExpr(n *ast.CStyleCastExpr, p *program.Program, exprIsSt
 		}
 	}()
 
-	n.Type = types.GenerateCorrectType(n.Type)
-	n.Type2 = types.GenerateCorrectType(n.Type2)
+	n.Type = util.GenerateCorrectType(n.Type)
+	n.Type2 = util.GenerateCorrectType(n.Type2)
 
 	// Char overflow
 	// example for byte(-1)
@@ -244,7 +244,7 @@ func transpileCStyleCastExpr(n *ast.CStyleCastExpr, p *program.Program, exprIsSt
 		return
 	}
 
-	if !types.IsFunction(exprType) &&
+	if !util.IsFunction(exprType) &&
 		n.Kind != ast.ImplicitCastExprArrayToPointerDecay &&
 		n.Kind != "PointerToIntegral" {
 		expr, err = types.CastExpr(p, expr, exprType, n.Type)
@@ -265,7 +265,7 @@ func transpileCStyleCastExpr(n *ast.CStyleCastExpr, p *program.Program, exprIsSt
 	if len(n.Children()) > 0 {
 		if types.IsCInteger(p, n.Type) {
 			if t, ok := ast.GetTypeIfExist(n.Children()[0]); ok {
-				if types.IsPointer(*t) {
+				if util.IsPointer(*t) {
 					// main information	: https://go101.org/article/unsafe.html
 					var retType string
 					expr, retType = util.GetUintptrForSlice(expr)
diff --git a/transpiler/declarations.go b/transpiler/declarations.go
index b0cf05a..245bc10 100644
--- a/transpiler/declarations.go
+++ b/transpiler/declarations.go
@@ -35,7 +35,7 @@ func newFunctionField(p *program.Program, name, cType string) (
 		err = fmt.Errorf("Name of function field cannot be empty")
 		return
 	}
-	if !types.IsFunction(cType) {
+	if !util.IsFunction(cType) {
 		err = fmt.Errorf("Cannot create function field for type : %s", cType)
 		return
 	}
@@ -64,7 +64,7 @@ func transpileFieldDecl(p *program.Program, n *ast.FieldDecl) (
 			}
 		}
 	}()
-	if types.IsFunction(n.Type) {
+	if util.IsFunction(n.Type) {
 		field, err = newFunctionField(p, n.Name, n.Type)
 		if err == nil {
 			return
@@ -106,7 +106,7 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 
 	var addPackageUnsafe bool
 
-	n.Name = types.GenerateCorrectType(n.Name)
+	n.Name = util.GenerateCorrectType(n.Name)
 	name := n.Name
 	defer func() {
 		if err != nil {
@@ -135,7 +135,7 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 		return
 	}
 
-	name = types.GenerateCorrectType(name)
+	name = util.GenerateCorrectType(name)
 	p.DefineType(name)
 	defer func() {
 		if err != nil {
@@ -151,7 +151,7 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 			if pos < len(n.Children()) {
 				switch v := n.Children()[pos+1].(type) {
 				case *ast.FieldDecl:
-					rec.Name = types.GetBaseType(types.GenerateCorrectType(v.Type))
+					rec.Name = types.GetBaseType(util.GenerateCorrectType(v.Type))
 				default:
 					p.AddMessage(p.GenerateWarningMessage(
 						fmt.Errorf("Cannot find name for anon RecordDecl: %T",
@@ -165,8 +165,8 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 	for pos := range n.Children() {
 		switch field := n.Children()[pos].(type) {
 		case *ast.FieldDecl:
-			field.Type = types.GenerateCorrectType(field.Type)
-			field.Type2 = types.GenerateCorrectType(field.Type2)
+			field.Type = util.GenerateCorrectType(field.Type)
+			field.Type2 = util.GenerateCorrectType(field.Type2)
 			var f *goast.Field
 			f, err = transpileFieldDecl(p, field)
 			if err != nil {
@@ -348,7 +348,7 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 func transpileCXXRecordDecl(p *program.Program, n *ast.RecordDecl) (
 	decls []goast.Decl, err error) {
 
-	n.Name = types.GenerateCorrectType(n.Name)
+	n.Name = util.GenerateCorrectType(n.Name)
 	name := n.Name
 
 	defer func() {
@@ -435,9 +435,9 @@ func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (
 			}
 		}
 	}()
-	n.Name = types.CleanCType(types.GenerateCorrectType(n.Name))
-	n.Type = types.CleanCType(types.GenerateCorrectType(n.Type))
-	n.Type2 = types.CleanCType(types.GenerateCorrectType(n.Type2))
+	n.Name = util.CleanCType(util.GenerateCorrectType(n.Name))
+	n.Type = util.CleanCType(util.GenerateCorrectType(n.Type))
+	n.Type2 = util.CleanCType(util.GenerateCorrectType(n.Type2))
 	name := n.Name
 
 	if "struct "+n.Name == n.Type || "union "+n.Name == n.Type {
@@ -445,7 +445,7 @@ func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (
 		return
 	}
 
-	if types.IsFunction(n.Type) {
+	if util.IsFunction(n.Type) {
 		var field *goast.Field
 		field, err = newFunctionField(p, n.Name, n.Type)
 		if err != nil {
@@ -574,9 +574,9 @@ func transpileVarDecl(p *program.Program, n *ast.VarDecl) (
 		}
 	}()
 
-	n.Name = types.GenerateCorrectType(n.Name)
-	n.Type = types.GenerateCorrectType(n.Type)
-	n.Type2 = types.GenerateCorrectType(n.Type2)
+	n.Name = util.GenerateCorrectType(n.Name)
+	n.Type = util.GenerateCorrectType(n.Type)
+	n.Type2 = util.GenerateCorrectType(n.Type2)
 
 	// Ignore extern as there is no analogy for Go right now.
 	if n.IsExtern && len(n.ChildNodes) == 0 {
@@ -617,7 +617,7 @@ func transpileVarDecl(p *program.Program, n *ast.VarDecl) (
 		if v, ok := (n.Children()[0]).(*ast.ImplicitCastExpr); ok {
 			if len(v.Type) > 0 {
 				// Is it function ?
-				if types.IsFunction(v.Type) {
+				if util.IsFunction(v.Type) {
 					var prefix string
 					var fields, returns []string
 					prefix, fields, returns, err = types.SeparateFunction(p, v.Type)
diff --git a/transpiler/enum.go b/transpiler/enum.go
index 534a104..c651eb7 100644
--- a/transpiler/enum.go
+++ b/transpiler/enum.go
@@ -12,7 +12,6 @@ import (
 
 	"github.com/Konstantin8105/c4go/ast"
 	"github.com/Konstantin8105/c4go/program"
-	"github.com/Konstantin8105/c4go/types"
 	"github.com/Konstantin8105/c4go/util"
 )
 
@@ -52,7 +51,7 @@ func transpileEnumDecl(p *program.Program, n *ast.EnumDecl) (
 		return
 	}
 
-	n.Name = types.GenerateCorrectType(n.Name)
+	n.Name = util.GenerateCorrectType(n.Name)
 	n.Name = strings.TrimPrefix(n.Name, "enum ")
 
 	// For case `enum` without name
diff --git a/transpiler/functions.go b/transpiler/functions.go
index cd8cf26..5ef73d4 100644
--- a/transpiler/functions.go
+++ b/transpiler/functions.go
@@ -85,7 +85,7 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) (
 	if p.GetFunctionDefinition(n.Name) == nil {
 		var pr string
 		var f, r []string
-		pr, f, r, err = types.ParseFunction(n.Type)
+		pr, _, f, r, err = util.ParseFunction(n.Type)
 		if err != nil {
 			err = fmt.Errorf("Cannot get function definition : %v", err)
 			return
diff --git a/transpiler/operators.go b/transpiler/operators.go
index 4a85172..277c3ba 100644
--- a/transpiler/operators.go
+++ b/transpiler/operators.go
@@ -189,7 +189,7 @@ func transpileParenExpr(n *ast.ParenExpr, p *program.Program) (
 		return
 	}
 
-	if !types.IsFunction(exprType) &&
+	if !util.IsFunction(exprType) &&
 		exprType != "void" &&
 		exprType != "bool" &&
 		exprType != types.ToVoid {
@@ -249,7 +249,7 @@ func pointerArithmetic(p *program.Program,
 		err = fmt.Errorf("right type is not C integer type : '%s'", rightType)
 		return
 	}
-	if !types.IsPointer(leftType) {
+	if !util.IsPointer(leftType) {
 		err = fmt.Errorf("left type is not a pointer : '%s'", leftType)
 		return
 	}
@@ -352,7 +352,7 @@ func transpileCompoundAssignOperator(
 	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)
 
 	// Pointer arithmetic
-	if types.IsPointer(n.Type) &&
+	if util.IsPointer(n.Type) &&
 		(operator == token.ADD_ASSIGN || operator == token.SUB_ASSIGN) {
 		operator = convertToWithoutAssign(operator)
 		v, vType, newPre, newPost, err := pointerArithmetic(
@@ -714,7 +714,7 @@ func atomicOperation(n ast.Node, p *program.Program) (
 		if vv, ok := v.Children()[0].(*ast.UnaryOperator); ok && vv.IsPrefix && vv.Operator == "*" {
 			if vvv, ok := vv.Children()[0].(*ast.ImplicitCastExpr); ok {
 				if vvvv, ok := vvv.Children()[0].(*ast.DeclRefExpr); ok {
-					if types.IsPointer(vvvv.Type) {
+					if util.IsPointer(vvvv.Type) {
 						varName := vvvv.Name
 
 						var exprResolveType string
@@ -894,7 +894,7 @@ func atomicOperation(n ast.Node, p *program.Program) (
 		}
 
 		var cast bool = true
-		if types.IsFunction(exprType) {
+		if util.IsFunction(exprType) {
 			cast = false
 		}
 		if v.Kind == ast.ImplicitCastExprArrayToPointerDecay {
@@ -1037,7 +1037,7 @@ func atomicOperation(n ast.Node, p *program.Program) (
 
 			returnValue, _, _, _, _ := transpileToExpr(decl, p, false)
 			if d, ok := decl.(*ast.DeclRefExpr); ok &&
-				types.IsPointer(d.Type) && !types.IsPointer(v.Type) {
+				util.IsPointer(d.Type) && !util.IsPointer(v.Type) {
 				returnValue = &goast.IndexExpr{
 					X: returnValue,
 					Index: &goast.BasicLit{
diff --git a/transpiler/unary.go b/transpiler/unary.go
index e8cdcc0..bc0c676 100644
--- a/transpiler/unary.go
+++ b/transpiler/unary.go
@@ -28,7 +28,7 @@ func transpileUnaryOperatorInc(n *ast.UnaryOperator, p *program.Program, operato
 		return
 	}
 
-	if types.IsPointer(n.Type) {
+	if util.IsPointer(n.Type) {
 		switch operator {
 		case token.INC: // ++
 			operator = token.ADD
@@ -152,7 +152,7 @@ func transpileUnaryOperatorNot(n *ast.UnaryOperator, p *program.Program) (
 	// UnaryOperator <> 'int' prefix '!'
 	// `-ImplicitCastExpr <> 'int (*)(int, double)' <LValueToRValue>
 	//   `-DeclRefExpr <> 'int (*)(int, double)' lvalue Var 0x2be4e80 'T' 'int (*)(int, double)'
-	if types.IsFunction(eType) {
+	if util.IsFunction(eType) {
 		return &goast.BinaryExpr{
 			X:  e,
 			Op: token.EQL, // ==
@@ -256,11 +256,11 @@ func transpileUnaryOperatorAmpersant(n *ast.UnaryOperator, p *program.Program) (
 		return
 	}
 
-	if types.IsFunction(eType) {
+	if util.IsFunction(eType) {
 		return
 	}
 
-	if types.IsLastArray(eType) {
+	if util.IsLastArray(eType) {
 		// In : eType = 'int [5]'
 		// Out: eType = 'int *'
 		f := strings.Index(eType, "[")
diff --git a/transpiler/variables.go b/transpiler/variables.go
index b19f666..f016291 100644
--- a/transpiler/variables.go
+++ b/transpiler/variables.go
@@ -205,8 +205,8 @@ func transpileInitListExpr(e *ast.InitListExpr, p *program.Program) (
 	}()
 	resp := []goast.Expr{}
 	var hasArrayFiller = false
-	e.Type1 = types.GenerateCorrectType(e.Type1)
-	e.Type2 = types.GenerateCorrectType(e.Type2)
+	e.Type1 = util.GenerateCorrectType(e.Type1)
+	e.Type2 = util.GenerateCorrectType(e.Type2)
 
 	for _, node := range e.Children() {
 		// Skip ArrayFiller
@@ -333,8 +333,8 @@ func transpileMemberExpr(n *ast.MemberExpr, p *program.Program) (
 		}
 	}()
 
-	n.Type = types.GenerateCorrectType(n.Type)
-	n.Type2 = types.GenerateCorrectType(n.Type2)
+	n.Type = util.GenerateCorrectType(n.Type)
+	n.Type2 = util.GenerateCorrectType(n.Type2)
 
 	originTypes := []string{n.Type, n.Type2}
 	if n.Children()[0] != nil {
@@ -351,7 +351,7 @@ func transpileMemberExpr(n *ast.MemberExpr, p *program.Program) (
 	}
 
 	baseType := lhsType
-	lhsType = types.GenerateCorrectType(lhsType)
+	lhsType = util.GenerateCorrectType(lhsType)
 
 	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)
 
@@ -371,7 +371,7 @@ func transpileMemberExpr(n *ast.MemberExpr, p *program.Program) (
 	}
 	// for anonymous structs
 	if structType == nil {
-		structType = p.GetStruct(types.CleanCType(baseType))
+		structType = p.GetStruct(util.CleanCType(baseType))
 	}
 	// typedef types
 	if structType == nil {
@@ -384,7 +384,7 @@ func transpileMemberExpr(n *ast.MemberExpr, p *program.Program) (
 	// other case
 	for _, t := range originTypes {
 		if structType == nil {
-			structType = p.GetStruct(types.CleanCType(t))
+			structType = p.GetStruct(util.CleanCType(t))
 		} else {
 			break
 		}
@@ -396,7 +396,7 @@ func transpileMemberExpr(n *ast.MemberExpr, p *program.Program) (
 	}
 
 	if n.Name == "" {
-		n.Name = generateNameFieldDecl(types.GenerateCorrectType(n.Type))
+		n.Name = generateNameFieldDecl(util.GenerateCorrectType(n.Type))
 	}
 	rhs := n.Name
 	rhsType := "void *"
diff --git a/types/cast.go b/types/cast.go
index 27f7ab3..4684c6b 100644
--- a/types/cast.go
+++ b/types/cast.go
@@ -94,8 +94,8 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 		return
 	}
 
-	cFromType = CleanCType(cFromType)
-	cToType = CleanCType(cToType)
+	cFromType = util.CleanCType(cFromType)
+	cToType = util.CleanCType(cToType)
 
 	// Only for "stddef.h"
 	if p.IncludeHeaderIsExists("stddef.h") {
@@ -121,7 +121,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 		return nil, fmt.Errorf("Expr is nil")
 	}
 
-	if IsFunction(cFromType) && toType == "bool" {
+	if util.IsFunction(cFromType) && toType == "bool" {
 		return &goast.BinaryExpr{
 			X:  expr,
 			Op: token.NEQ,
@@ -133,7 +133,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 	// Example :
 	// cFromType  : double (int, float, double)
 	// cToType    : double (*)(int, float, double)
-	if IsFunction(cFromType) {
+	if util.IsFunction(cFromType) {
 		return expr, nil
 	}
 
@@ -276,7 +276,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 		return expr, nil
 	}
 
-	if IsPointer(cFromType) && cToType == "bool" {
+	if util.IsPointer(cFromType) && cToType == "bool" {
 		expr = &goast.BinaryExpr{
 			X:  expr,
 			Op: token.NEQ, // !=
@@ -478,7 +478,7 @@ func CastExpr(p *program.Program, expr goast.Expr, cFromType, cToType string) (
 		return expr, nil
 	}
 
-	if IsCInteger(p, cFromType) && IsPointer(cToType) {
+	if IsCInteger(p, cFromType) && util.IsPointer(cToType) {
 		expr = goast.NewIdent("nil")
 		return expr, nil
 	}
diff --git a/types/resolve.go b/types/resolve.go
index 31fed59..8627fcc 100644
--- a/types/resolve.go
+++ b/types/resolve.go
@@ -1,7 +1,6 @@
 package types
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"strconv"
@@ -119,7 +118,7 @@ func ResolveType(p *program.Program, s string) (resolveResult string, err error)
 		return "interface{}", errors.New("probably an incorrect type translation 0")
 	}
 
-	s = CleanCType(s)
+	s = util.CleanCType(s)
 
 	// FIXME: This is a hack to avoid casting in some situations.
 	if s == "" {
@@ -149,7 +148,7 @@ func ResolveType(p *program.Program, s string) (resolveResult string, err error)
 	if len(s) > 2 {
 		base := s[:len(s)-2]
 		if ff, ok := p.TypedefType[base]; ok {
-			if IsFunction(ff) {
+			if util.IsFunction(ff) {
 				return base, nil
 			}
 		}
@@ -171,7 +170,7 @@ func ResolveType(p *program.Program, s string) (resolveResult string, err error)
 	}
 
 	// For function
-	if IsFunction(s) {
+	if util.IsFunction(s) {
 		g, e := resolveFunction(p, s)
 		return g, e
 	}
@@ -213,7 +212,7 @@ func ResolveType(p *program.Program, s string) (resolveResult string, err error)
 	}
 
 	if v, ok := p.TypedefType[s]; ok {
-		if IsFunction(v) {
+		if util.IsFunction(v) {
 			// typedef function
 			return s, nil
 		}
@@ -349,7 +348,7 @@ func SeparateFunction(p *program.Program, s string) (
 			err = fmt.Errorf("Cannot separate function '%s' : %v", s, err)
 		}
 	}()
-	pr, f, r, err := ParseFunction(s)
+	pr, _, f, r, err := util.ParseFunction(s)
 	if err != nil {
 		return
 	}
@@ -378,354 +377,18 @@ func SeparateFunction(p *program.Program, s string) (
 	return
 }
 
-// IsFunction - return true if string is function like "void (*)(void)"
-func IsFunction(s string) bool {
-	s = strings.Replace(s, "(*)", "", -1)
-	return strings.Contains(s, "(")
-}
-
-//IsCPointer - check C type is pointer
-func IsCPointer(s string) bool {
-	if len(s) == 0 {
-		return false
-	}
-	for i := len(s) - 1; i >= 0; i-- {
-		switch s[i] {
-		case ' ':
-			continue
-		case '*':
-			return true
-		default:
-			break
-		}
-	}
-	return false
-}
-
-// IsCArray - check C type is array
-func IsCArray(s string) bool {
-	if len(s) == 0 {
-		return false
-	}
-	for i := len(s) - 1; i >= 0; i-- {
-		switch s[i] {
-		case ' ':
-			continue
-		case ']':
-			return true
-		default:
-			break
-		}
-	}
-	return false
-}
-
-// IsPointer - check type is pointer
-func IsPointer(s string) bool {
-	return strings.ContainsAny(s, "*[]")
-}
-
-// IsLastArray - check type have array '[]'
-func IsLastArray(s string) bool {
-	for _, b := range s {
-		switch b {
-		case '[':
-			return true
-		case '*':
-			break
-		}
-	}
-	return false
-}
-
 // IsTypedefFunction - return true if that type is typedef of function.
 func IsTypedefFunction(p *program.Program, s string) bool {
-	if v, ok := p.TypedefType[s]; ok && IsFunction(v) {
+	if v, ok := p.TypedefType[s]; ok && util.IsFunction(v) {
 		return true
 	}
 	s = string(s[0 : len(s)-len(" *")])
-	if v, ok := p.TypedefType[s]; ok && IsFunction(v) {
+	if v, ok := p.TypedefType[s]; ok && util.IsFunction(v) {
 		return true
 	}
 	return false
 }
 
-// ParseFunction - parsing elements of C function
-func ParseFunction(s string) (prefix string, f []string, r []string, err error) {
-	defer func() {
-		if err != nil {
-			err = fmt.Errorf("Cannot parse function '%s' : %v", s, err)
-		} else {
-			prefix = strings.TrimSpace(prefix)
-			for i := range r {
-				r[i] = strings.TrimSpace(r[i])
-			}
-			for i := range f {
-				f[i] = strings.TrimSpace(f[i])
-			}
-		}
-	}()
-
-	s = strings.TrimSpace(s)
-	if !IsFunction(s) {
-		err = fmt.Errorf("Is not function : %s", s)
-		return
-	}
-	var returns string
-	var arguments string
-	{
-		// Example of function types :
-		// int (*)(int, float)
-		// int (int, float)
-		// int (*)(int (*)(int))
-		// void (*(*)(int *, void *, const char *))(void)
-		if s[len(s)-1] != ')' {
-			err = fmt.Errorf("function type |%s| haven't last symbol ')'", s)
-			return
-		}
-		counter := 1
-		var pos int
-		for i := len(s) - 2; i >= 0; i-- {
-			if i == 0 {
-				err = fmt.Errorf("Don't found '(' in type : %s", s)
-				return
-			}
-			if s[i] == ')' {
-				counter++
-			}
-			if s[i] == '(' {
-				counter--
-			}
-			if counter == 0 {
-				pos = i
-				break
-			}
-		}
-		returns = strings.TrimSpace(s[:pos])
-		arguments = strings.TrimSpace(s[pos:])
-	}
-	if arguments == "" {
-		err = fmt.Errorf("Cannot parse (right part is nil) : %v", s)
-		return
-	}
-	// separate fields of arguments
-	{
-		pos := 1
-		counter := 0
-		for i := 1; i < len(arguments)-1; i++ {
-			if arguments[i] == '(' {
-				counter++
-			}
-			if arguments[i] == ')' {
-				counter--
-			}
-			if counter == 0 && arguments[i] == ',' {
-				f = append(f, strings.TrimSpace(arguments[pos:i]))
-				pos = i + 1
-			}
-		}
-		f = append(f, strings.TrimSpace(arguments[pos:len(arguments)-1]))
-	}
-
-	// returns
-	// Example:  __ssize_t
-	if returns[len(returns)-1] != ')' {
-		r = append(r, returns)
-		return
-	}
-
-	// Example: void  ( *(*)(int *, void *, char *))
-	//          -------  --------------------------- return type
-	//                 ==                            prefix
-	//                ++++++++++++++++++++++++++++++ block
-	// return type : void (*)(int *, void *, char *)
-	// prefix      : *
-	// Find the block
-	var counter int
-	var position int
-	for i := len(returns) - 1; i >= 0; i-- {
-		if returns[i] == ')' {
-			counter++
-		}
-		if returns[i] == '(' {
-			counter--
-		}
-		if counter == 0 {
-			position = i
-			break
-		}
-	}
-	block := string([]byte(returns[position:]))
-	returns = returns[:position]
-
-	// Examples returns:
-	// int   (*)
-	// char *(*)
-	// block is : (*)
-	if block == "(*)" {
-		r = append(r, returns)
-		return
-	}
-
-	index := strings.Index(block, "(*)")
-	if index < 0 {
-		if strings.Count(block, "(") == 1 {
-			// Examples returns:
-			// int   ( * [2])
-			// ------         return type
-			//        ======  prefix
-			//       ++++++++ block
-			bBlock := []byte(block)
-			for i := 0; i < len(bBlock); i++ {
-				switch bBlock[i] {
-				case '(', ')':
-					bBlock[i] = ' '
-				}
-			}
-			bBlock = bytes.Replace(bBlock, []byte("*"), []byte(""), 1)
-			prefix = string(bBlock)
-			r = append(r, returns)
-			return
-		}
-		// void (*(int *, void *, const char *))
-		//      ++++++++++++++++++++++++++++++++ block
-		block = block[1 : len(block)-1]
-		index := strings.Index(block, "(")
-		if index < 0 {
-			err = fmt.Errorf("Cannot found '(' in block")
-			return
-		}
-		returns = returns + block[index:]
-		prefix = block[:index]
-		if strings.Contains(prefix, "*") {
-			prefix = strings.Replace(prefix, "*", "", 1)
-		} else {
-			err = fmt.Errorf("Undefined situation")
-			return
-		}
-		r = append(r, returns)
-		return
-	}
-	if len(block)-1 > index+3 && block[index+3] == '(' {
-		// Examples returns:
-		// void  ( *(*)(int *, void *, char *))
-		//       ++++++++++++++++++++++++++++++ block
-		//            ^^                        check this
-		block = strings.Replace(block, "(*)", "", 1)
-		block = block[1 : len(block)-1]
-		index := strings.Index(block, "(")
-		if index < 0 {
-			err = fmt.Errorf("Cannot found '(' in block")
-			return
-		}
-		prefix = block[:index]
-		returns = returns + block[index:]
-
-		r = append(r, returns)
-		return
-	}
-
-	// Examples returns:
-	// int   ( *( *(*)))
-	// -----              return type
-	//        =========   prefix
-	//       +++++++++++  block
-	bBlock := []byte(block)
-	for i := 0; i < len(bBlock); i++ {
-		switch bBlock[i] {
-		case '(', ')':
-			bBlock[i] = ' '
-		}
-	}
-	bBlock = bytes.Replace(bBlock, []byte("*"), []byte(""), 1)
-	prefix = string(bBlock)
-	r = append(r, returns)
-
-	return
-}
-
-// CleanCType - remove from C type not Go type
-func CleanCType(s string) (out string) {
-	out = s
-
-	// remove space from pointer symbols
-	out = strings.Replace(out, "* *", "**", -1)
-
-	// add space for simplification redactoring
-	out = strings.Replace(out, "*", " *", -1)
-
-	out = strings.Replace(out, "( *)", "(*)", -1)
-
-	// Remove any whitespace or attributes that are not relevant to Go.
-	out = strings.Replace(out, "const", "", -1)
-	out = strings.Replace(out, "volatile", "", -1)
-	out = strings.Replace(out, "__restrict", "", -1)
-	out = strings.Replace(out, "restrict", "", -1)
-	out = strings.Replace(out, "_Nullable", "", -1)
-	out = strings.Replace(out, "\t", "", -1)
-	out = strings.Replace(out, "\n", "", -1)
-	out = strings.Replace(out, "\r", "", -1)
-
-	// remove space from pointer symbols
-	out = strings.Replace(out, "* *", "**", -1)
-	out = strings.Replace(out, "[", " [", -1)
-	out = strings.Replace(out, "] [", "][", -1)
-
-	// remove addition spaces
-	out = strings.Replace(out, "  ", " ", -1)
-
-	// remove spaces around
-	out = strings.TrimSpace(out)
-
-	if out != s {
-		return CleanCType(out)
-	}
-
-	return out
-}
-
-// GenerateCorrectType - generate correct type
-// Example: 'union (anonymous union at tests/union.c:46:3)'
-func GenerateCorrectType(name string) string {
-	if !strings.Contains(name, "anonymous") {
-		return CleanCType(name)
-	}
-	index := strings.Index(name, "(anonymous")
-	if index < 0 {
-		return name
-	}
-	name = strings.Replace(name, "anonymous", "", 1)
-	var last int
-	for last = index; last < len(name); last++ {
-		if name[last] == ')' {
-			break
-		}
-	}
-
-	// Create a string, for example:
-	// Input (name)   : 'union (anonymous union at tests/union.c:46:3)'
-	// Output(inside) : '(anonymous union at tests/union.c:46:3)'
-	inside := string(([]byte(name))[index : last+1])
-
-	// change unacceptable C name letters
-	inside = strings.Replace(inside, "(", "_", -1)
-	inside = strings.Replace(inside, ")", "_", -1)
-	inside = strings.Replace(inside, " ", "_", -1)
-	inside = strings.Replace(inside, ":", "_", -1)
-	inside = strings.Replace(inside, "/", "_", -1)
-	inside = strings.Replace(inside, "-", "_", -1)
-	inside = strings.Replace(inside, "\\", "_", -1)
-	inside = strings.Replace(inside, ".", "_", -1)
-	out := string(([]byte(name))[0:index]) + inside + string(([]byte(name))[last+1:])
-
-	// For case:
-	// struct siginfo_t::(anonymous at /usr/include/x86_64-linux-gnu/bits/siginfo.h:119:2)
-	// we see '::' before 'anonymous' word
-	out = strings.Replace(out, ":", "D", -1)
-
-	return CleanCType(out)
-}
-
 // GetAmountArraySize - return amount array size
 // Example :
 // In  : 'char [40]'
@@ -754,7 +417,7 @@ func GetAmountArraySize(cType string) (size int, err error) {
 // s =  struct BSstructSatSShomeSlepriconSgoSsrcSgithubPcomSD260D18E [7]
 func GetBaseType(s string) string {
 	s = strings.TrimSpace(s)
-	s = CleanCType(s)
+	s = util.CleanCType(s)
 	if len(s) < 1 {
 		return s
 	}
diff --git a/types/sizeof.go b/types/sizeof.go
index 3e725d4..903b255 100644
--- a/types/sizeof.go
+++ b/types/sizeof.go
@@ -5,6 +5,7 @@ import (
 	"strings"
 
 	"github.com/Konstantin8105/c4go/program"
+	"github.com/Konstantin8105/c4go/util"
 )
 
 // SizeOf returns the number of bytes for a type. This the same as using the
@@ -17,7 +18,7 @@ func SizeOf(p *program.Program, cType string) (size int, err error) {
 	}()
 
 	// Remove keywords that do not effect the size.
-	cType = CleanCType(cType)
+	cType = util.CleanCType(cType)
 	cType = strings.Replace(cType, "unsigned ", "", -1)
 	cType = strings.Replace(cType, "signed ", "", -1)
 
@@ -43,7 +44,7 @@ func SizeOf(p *program.Program, cType string) (size int, err error) {
 	// A structure will be the sum of its parts.
 	var isStruct, ok bool
 	var s *program.Struct
-	cType = GenerateCorrectType(cType)
+	cType = util.GenerateCorrectType(cType)
 	if s, ok = p.Structs[cType]; ok {
 		isStruct = true
 	} else if s, ok = p.Structs["struct "+cType]; ok {
diff --git a/util/util.go b/util/util.go
index 0de3732..ae65f70 100644
--- a/util/util.go
+++ b/util/util.go
@@ -1,8 +1,11 @@
 package util
 
 import (
+	"bytes"
+	"fmt"
 	"strconv"
 	"strings"
+	"unicode"
 )
 
 // InStrings returns true if item exists in items. It must be an exact string
@@ -60,3 +63,371 @@ func GetExportedName(field string) string {
 
 	return Ucfirst(strings.TrimLeft(field, "*_"))
 }
+
+// IsFunction - return true if string is function like "void (*)(void)"
+func IsFunction(s string) bool {
+	s = strings.Replace(s, "(*)", "", -1)
+	return strings.Contains(s, "(")
+}
+
+//IsCPointer - check C type is pointer
+func IsCPointer(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+	for i := len(s) - 1; i >= 0; i-- {
+		switch s[i] {
+		case ' ':
+			continue
+		case '*':
+			return true
+		default:
+			break
+		}
+	}
+	return false
+}
+
+// IsCArray - check C type is array
+func IsCArray(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+	for i := len(s) - 1; i >= 0; i-- {
+		switch s[i] {
+		case ' ':
+			continue
+		case ']':
+			return true
+		default:
+			break
+		}
+	}
+	return false
+}
+
+// IsPointer - check type is pointer
+func IsPointer(s string) bool {
+	return strings.ContainsAny(s, "*[]")
+}
+
+// IsLastArray - check type have array '[]'
+func IsLastArray(s string) bool {
+	for _, b := range s {
+		switch b {
+		case '[':
+			return true
+		case '*':
+			break
+		}
+	}
+	return false
+}
+
+// ParseFunction - parsing elements of C function
+func ParseFunction(s string) (prefix string, funcname string, f []string, r []string, err error) {
+	defer func() {
+		if err != nil {
+			err = fmt.Errorf("Cannot parse function '%s' : %v", s, err)
+		} else {
+			prefix = strings.TrimSpace(prefix)
+			funcname = strings.TrimSpace(funcname)
+			for i := range r {
+				r[i] = strings.TrimSpace(r[i])
+			}
+			for i := range f {
+				f[i] = strings.TrimSpace(f[i])
+			}
+		}
+	}()
+
+	s = strings.TrimSpace(s)
+	if !IsFunction(s) {
+		err = fmt.Errorf("Is not function : %s", s)
+		return
+	}
+	var returns string
+	var arguments string
+	{
+		// Example of function types :
+		// int (*)(int, float)
+		// int (int, float)
+		// int (*)(int (*)(int))
+		// void (*(*)(int *, void *, const char *))(void)
+		if s[len(s)-1] != ')' {
+			err = fmt.Errorf("function type |%s| haven't last symbol ')'", s)
+			return
+		}
+		counter := 1
+		var pos int
+		for i := len(s) - 2; i >= 0; i-- {
+			if i == 0 {
+				err = fmt.Errorf("Don't found '(' in type : %s", s)
+				return
+			}
+			if s[i] == ')' {
+				counter++
+			}
+			if s[i] == '(' {
+				counter--
+			}
+			if counter == 0 {
+				pos = i
+				break
+			}
+		}
+		// s[:pos] = `speed_t cfgetospeed`
+		if unicode.IsNumber(rune(s[pos-1])) || unicode.IsLetter(rune(s[pos-1])) {
+			for i := pos - 1; i >= 0; i-- {
+				if s[i] == ' ' {
+					funcname = s[i+1 : pos]
+					returns = strings.TrimSpace(s[:i])
+					break
+				}
+			}
+		} else {
+			returns = strings.TrimSpace(s[:pos])
+		}
+		arguments = strings.TrimSpace(s[pos:])
+	}
+	if arguments == "" {
+		err = fmt.Errorf("Cannot parse (right part is nil) : %v", s)
+		return
+	}
+	// separate fields of arguments
+	{
+		pos := 1
+		counter := 0
+		for i := 1; i < len(arguments)-1; i++ {
+			if arguments[i] == '(' {
+				counter++
+			}
+			if arguments[i] == ')' {
+				counter--
+			}
+			if counter == 0 && arguments[i] == ',' {
+				f = append(f, strings.TrimSpace(arguments[pos:i]))
+				pos = i + 1
+			}
+		}
+		f = append(f, strings.TrimSpace(arguments[pos:len(arguments)-1]))
+	}
+
+	// returns
+	// Example:  __ssize_t
+	if returns[len(returns)-1] != ')' {
+		r = append(r, returns)
+		return
+	}
+
+	// Example: void  ( *(*)(int *, void *, char *))
+	//          -------  --------------------------- return type
+	//                 ==                            prefix
+	//                ++++++++++++++++++++++++++++++ block
+	// return type : void (*)(int *, void *, char *)
+	// prefix      : *
+	// Find the block
+	var counter int
+	var position int
+	for i := len(returns) - 1; i >= 0; i-- {
+		if returns[i] == ')' {
+			counter++
+		}
+		if returns[i] == '(' {
+			counter--
+		}
+		if counter == 0 {
+			position = i
+			break
+		}
+	}
+	block := string([]byte(returns[position:]))
+	returns = returns[:position]
+
+	// Examples returns:
+	// int   (*)
+	// char *(*)
+	// block is : (*)
+	if block == "(*)" {
+		r = append(r, returns)
+		return
+	}
+
+	index := strings.Index(block, "(*)")
+	if index < 0 {
+		if strings.Count(block, "(") == 1 {
+			// Examples returns:
+			// int   ( * [2])
+			// ------         return type
+			//        ======  prefix
+			//       ++++++++ block
+			bBlock := []byte(block)
+			for i := 0; i < len(bBlock); i++ {
+				switch bBlock[i] {
+				case '(', ')':
+					bBlock[i] = ' '
+				}
+			}
+			bBlock = bytes.Replace(bBlock, []byte("*"), []byte(""), 1)
+			prefix = string(bBlock)
+			r = append(r, returns)
+			return
+		}
+		// void (*(int *, void *, const char *))
+		//      ++++++++++++++++++++++++++++++++ block
+		block = block[1 : len(block)-1]
+		index := strings.Index(block, "(")
+		if index < 0 {
+			err = fmt.Errorf("Cannot found '(' in block")
+			return
+		}
+		returns = returns + block[index:]
+		prefix = block[:index]
+		if strings.Contains(prefix, "*") {
+			prefix = strings.Replace(prefix, "*", "", 1)
+		} else {
+			err = fmt.Errorf("Undefined situation")
+			return
+		}
+		r = append(r, returns)
+		return
+	}
+	if len(block)-1 > index+3 && block[index+3] == '(' {
+		// Examples returns:
+		// void  ( *(*)(int *, void *, char *))
+		//       ++++++++++++++++++++++++++++++ block
+		//            ^^                        check this
+		block = strings.Replace(block, "(*)", "", 1)
+		block = block[1 : len(block)-1]
+		index := strings.Index(block, "(")
+		if index < 0 {
+			err = fmt.Errorf("Cannot found '(' in block")
+			return
+		}
+
+		returns = returns + block[index:]
+		// example of block[:index]
+		// `*signal`
+		// `* signal`
+		if pr := strings.TrimSpace(block[:index]); unicode.IsLetter(rune(pr[len(pr)-1])) ||
+			unicode.IsNumber(rune(pr[len(pr)-1])) {
+			pr = strings.Replace(pr, "*", " * ", -1)
+			for i := len(pr) - 1; i >= 0; i-- {
+				if unicode.IsLetter(rune(pr[i])) {
+					continue
+				}
+				if unicode.IsNumber(rune(pr[i])) {
+					continue
+				}
+				prefix = pr[:i]
+				funcname = pr[i:]
+				break
+			}
+		} else {
+			prefix = block[:index]
+		}
+
+		r = append(r, returns)
+		return
+	}
+
+	// Examples returns:
+	// int   ( *( *(*)))
+	// -----              return type
+	//        =========   prefix
+	//       +++++++++++  block
+	bBlock := []byte(block)
+	for i := 0; i < len(bBlock); i++ {
+		switch bBlock[i] {
+		case '(', ')':
+			bBlock[i] = ' '
+		}
+	}
+	bBlock = bytes.Replace(bBlock, []byte("*"), []byte(""), 1)
+	prefix = string(bBlock)
+	r = append(r, returns)
+
+	return
+}
+
+// CleanCType - remove from C type not Go type
+func CleanCType(s string) (out string) {
+	out = s
+
+	// remove space from pointer symbols
+	out = strings.Replace(out, "* *", "**", -1)
+
+	// add space for simplification redactoring
+	out = strings.Replace(out, "*", " *", -1)
+
+	out = strings.Replace(out, "( *)", "(*)", -1)
+
+	// Remove any whitespace or attributes that are not relevant to Go.
+	out = strings.Replace(out, "const", "", -1)
+	out = strings.Replace(out, "volatile", "", -1)
+	out = strings.Replace(out, "__restrict", "", -1)
+	out = strings.Replace(out, "restrict", "", -1)
+	out = strings.Replace(out, "_Nullable", "", -1)
+	out = strings.Replace(out, "\t", "", -1)
+	out = strings.Replace(out, "\n", "", -1)
+	out = strings.Replace(out, "\r", "", -1)
+
+	// remove space from pointer symbols
+	out = strings.Replace(out, "* *", "**", -1)
+	out = strings.Replace(out, "[", " [", -1)
+	out = strings.Replace(out, "] [", "][", -1)
+
+	// remove addition spaces
+	out = strings.Replace(out, "  ", " ", -1)
+
+	// remove spaces around
+	out = strings.TrimSpace(out)
+
+	if out != s {
+		return CleanCType(out)
+	}
+
+	return out
+}
+
+// GenerateCorrectType - generate correct type
+// Example: 'union (anonymous union at tests/union.c:46:3)'
+func GenerateCorrectType(name string) string {
+	if !strings.Contains(name, "anonymous") {
+		return CleanCType(name)
+	}
+	index := strings.Index(name, "(anonymous")
+	if index < 0 {
+		return name
+	}
+	name = strings.Replace(name, "anonymous", "", 1)
+	var last int
+	for last = index; last < len(name); last++ {
+		if name[last] == ')' {
+			break
+		}
+	}
+
+	// Create a string, for example:
+	// Input (name)   : 'union (anonymous union at tests/union.c:46:3)'
+	// Output(inside) : '(anonymous union at tests/union.c:46:3)'
+	inside := string(([]byte(name))[index : last+1])
+
+	// change unacceptable C name letters
+	inside = strings.Replace(inside, "(", "_", -1)
+	inside = strings.Replace(inside, ")", "_", -1)
+	inside = strings.Replace(inside, " ", "_", -1)
+	inside = strings.Replace(inside, ":", "_", -1)
+	inside = strings.Replace(inside, "/", "_", -1)
+	inside = strings.Replace(inside, "-", "_", -1)
+	inside = strings.Replace(inside, "\\", "_", -1)
+	inside = strings.Replace(inside, ".", "_", -1)
+	out := string(([]byte(name))[0:index]) + inside + string(([]byte(name))[last+1:])
+
+	// For case:
+	// struct siginfo_t::(anonymous at /usr/include/x86_64-linux-gnu/bits/siginfo.h:119:2)
+	// we see '::' before 'anonymous' word
+	out = strings.Replace(out, ":", "D", -1)
+
+	return CleanCType(out)
+}


Test patch:
diff --git a/tests/signal.c b/tests/signal.c
new file mode 100644
index 0000000..50a6b3e
--- /dev/null
+++ b/tests/signal.c
@@ -0,0 +1,22 @@
+#include "tests.h"
+#include <stdio.h>      /* printf */
+#include <signal.h>     /* signal, raise, sig_atomic_t */
+
+sig_atomic_t signaled = 0;
+
+void my_handler (int param)
+{
+  signaled = 1;
+}
+
+int main()
+{
+    plan(0);
+
+	signal (SIGINT, my_handler);
+	raise(SIGINT);
+	printf ("signaled is %d.\n",signaled);
+
+    done_testing();
+}
+
diff --git a/types/resolve_test.go b/types/resolve_test.go
index 856f1d4..e7fc02a 100644
--- a/types/resolve_test.go
+++ b/types/resolve_test.go
@@ -1,7 +1,6 @@
 package types_test
 
 import (
-	"encoding/json"
 	"fmt"
 	"strings"
 	"testing"
@@ -53,282 +52,6 @@ func TestResolve(t *testing.T) {
 	}
 }
 
-func TestResolveFunction(t *testing.T) {
-	var tcs = []struct {
-		input string
-
-		prefix  string
-		fields  []string
-		returns []string
-	}{
-		{
-			input:   "__ssize_t (void *, char *, size_t)",
-			prefix:  "",
-			fields:  []string{"void *", "char *", "size_t"},
-			returns: []string{"__ssize_t"},
-		},
-		{
-			input:  "int (*)(sqlite3_vtab *, int, const char *, void (**)(sqlite3_context *, int, sqlite3_value **), void **)",
-			prefix: "",
-			fields: []string{
-				"sqlite3_vtab *",
-				"int",
-				"const char *",
-				"void (**)(sqlite3_context *, int, sqlite3_value **)",
-				"void **"},
-			returns: []string{"int"},
-		},
-		{
-			input:   "void ( *(*)(int *, void *, char *))(void)",
-			prefix:  "*",
-			fields:  []string{"void"},
-			returns: []string{"void (int *, void *, char *)"},
-		},
-		{
-			input:   " void (*)(void)",
-			prefix:  "",
-			fields:  []string{"void"},
-			returns: []string{"void"},
-		},
-		{
-			input:   " int (*)(sqlite3_file *)",
-			prefix:  "",
-			fields:  []string{"sqlite3_file *"},
-			returns: []string{"int"},
-		},
-		{
-			input:   " int (*)(int)",
-			prefix:  "",
-			fields:  []string{"int"},
-			returns: []string{"int"},
-		},
-		{
-			input:   " int (*)(void *) ",
-			prefix:  "",
-			fields:  []string{"void *"},
-			returns: []string{"int"},
-		},
-		{
-			input:   " void (*)(sqlite3_context *, int, sqlite3_value **)",
-			prefix:  "",
-			fields:  []string{"sqlite3_context *", "int", "sqlite3_value **"},
-			returns: []string{"void"},
-		},
-		{
-			input:   "char *(*)( char *, ...)",
-			prefix:  "",
-			fields:  []string{"char *", "..."},
-			returns: []string{"char *"},
-		},
-		{
-			input:   "char *(*)( char *, struct __va_list_tag *)",
-			prefix:  "",
-			fields:  []string{"char *", "struct __va_list_tag *"},
-			returns: []string{"char *"},
-		},
-		{
-			input:   "char *(*)(const char *, ...)",
-			prefix:  "",
-			fields:  []string{"const char *", "..."},
-			returns: []string{"char *"},
-		},
-		{
-			input:   "char *(*)(ImportCtx *)",
-			prefix:  "",
-			fields:  []string{"ImportCtx *"},
-			returns: []string{"char *"},
-		},
-		{
-			input:   "char *(*)(int, char *, char *, ...)",
-			prefix:  "",
-			fields:  []string{"int", "char *", "char *", "..."},
-			returns: []string{"char *"},
-		},
-		{
-			input:   "const char *(*)(int)",
-			prefix:  "",
-			fields:  []string{"int"},
-			returns: []string{"const char *"},
-		},
-		{
-			input:   "const unsigned char *(*)(sqlite3_value *)",
-			prefix:  "",
-			fields:  []string{"sqlite3_value *"},
-			returns: []string{"const unsigned char *"},
-		},
-		{
-			input:   "int (*)(const char *, sqlite3 **)",
-			prefix:  "",
-			fields:  []string{"const char *", "sqlite3 **"},
-			returns: []string{"int"},
-		},
-		{
-			input:  "int (*)(fts5_api *, const char *, void *, fts5_extension_function, void (*)(void *))",
-			prefix: "",
-			fields: []string{"fts5_api *",
-				"const char *",
-				"void *",
-				"fts5_extension_function",
-				"void (*)(void *)"},
-			returns: []string{"int"},
-		},
-		{
-			input:  "int (*)(Fts5Context *, char *, int, void *, int (*)(void *, int, char *, int, int, int))",
-			prefix: "",
-			fields: []string{"Fts5Context *",
-				"char *",
-				"int",
-				"void *",
-				"int (*)(void *, int, char *, int, int, int)"},
-			returns: []string{"int"},
-		},
-		{
-			input:  "int (*)(sqlite3 *, char *, int, int, void *, void (*)(sqlite3_context *, int, sqlite3_value **), void (*)(sqlite3_context *, int, sqlite3_value **), void (*)(sqlite3_context *))",
-			prefix: "",
-			fields: []string{
-				"sqlite3 *",
-				"char *",
-				"int",
-				"int",
-				"void *",
-				"void (*)(sqlite3_context *, int, sqlite3_value **)",
-				"void (*)(sqlite3_context *, int, sqlite3_value **)",
-				"void (*)(sqlite3_context *)",
-			},
-			returns: []string{"int"},
-		},
-		{
-			input:  "int (*)(sqlite3_vtab *, int, const char *, void (**)(sqlite3_context *, int, sqlite3_value **), void **)",
-			prefix: "",
-			fields: []string{
-				"sqlite3_vtab *",
-				"int",
-				"const char *",
-				"void (**)(sqlite3_context *, int, sqlite3_value **)",
-				"void **"},
-			returns: []string{"int"},
-		},
-		{
-			input:   "void (*(int *, void *, const char *))(void)",
-			prefix:  "",
-			fields:  []string{"void"},
-			returns: []string{"void (int *, void *, const char *)"},
-		},
-		{
-			input:   "long (int, int)",
-			prefix:  "",
-			fields:  []string{"int", "int"},
-			returns: []string{"long"},
-		},
-		{
-			input:   "void (const char *, ...)",
-			prefix:  "",
-			fields:  []string{"const char *", "..."},
-			returns: []string{"void"},
-		},
-		{
-			input:   "void (void)",
-			prefix:  "",
-			fields:  []string{"void"},
-			returns: []string{"void"},
-		},
-		{
-			input:   "void ()",
-			prefix:  "",
-			fields:  []string{""},
-			returns: []string{"void"},
-		},
-		{
-			input:   "int (*)()",
-			prefix:  "",
-			fields:  []string{""},
-			returns: []string{"int"},
-		},
-	}
-
-	for i, tc := range tcs {
-		t.Run(fmt.Sprintf("Test %d : %s", i, tc.input), func(t *testing.T) {
-			actualPrefix, actualField, actualReturn, err :=
-				types.ParseFunction(tc.input)
-			if err != nil {
-				t.Fatal(err)
-			}
-			if actualPrefix != tc.prefix {
-				t.Errorf("Prefix is not same.\nActual: %s\nExpected: %s\n",
-					actualPrefix, tc.prefix)
-			}
-			if len(actualField) != len(tc.fields) {
-				a, _ := json.Marshal(actualField)
-				f, _ := json.Marshal(tc.fields)
-				t.Errorf("Size of field is not same.\nActual  : %s\nExpected: %s\n",
-					string(a),
-					string(f))
-				return
-			}
-			if len(actualField) != len(tc.fields) {
-				a, _ := json.Marshal(actualField)
-				f, _ := json.Marshal(tc.fields)
-				t.Errorf("Size of field is not same.\nActual  : %s\nExpected: %s\n",
-					string(a),
-					string(f))
-				return
-			}
-			for i := range actualField {
-				actualField[i] = strings.Replace(actualField[i], " ", "", -1)
-				tc.fields[i] = strings.Replace(tc.fields[i], " ", "", -1)
-				if actualField[i] != tc.fields[i] {
-					t.Errorf("Not correct field: %v\nExpected: %v", actualField, tc.fields)
-				}
-			}
-			if len(actualReturn) != len(tc.returns) {
-				a, _ := json.Marshal(actualReturn)
-				f, _ := json.Marshal(tc.returns)
-				t.Errorf("Size of return field is not same.\nActual  : %s\nExpected: %s\n",
-					string(a),
-					string(f))
-				return
-			}
-			if len(actualReturn) != len(tc.returns) {
-				t.Errorf("Amount of return elements are different\nActual  : %v\nExpected: %v\n",
-					actualReturn, tc.returns)
-			}
-			for i := range actualReturn {
-				actualReturn[i] = strings.Replace(actualReturn[i], " ", "", -1)
-				tc.returns[i] = strings.Replace(tc.returns[i], " ", "", -1)
-				if actualReturn[i] != tc.returns[i] {
-					t.Errorf("Not correct returns: %v\nExpected: %v", actualReturn, tc.returns)
-				}
-			}
-		})
-	}
-}
-
-func TestGenerateCorrectType(t *testing.T) {
-	tcs := []struct {
-		inp string
-		out string
-	}{
-		{
-			inp: "union (anonymous union at tests/union.c:46:3)",
-			out: "union __union_at_tests_union_c_46_3_",
-		},
-		{
-			inp: " const struct (anonymous struct at /home/lepricon/go/src/github.com/tests/struct.c:282:18) [7]",
-			out: "struct __struct_at__home_lepricon_go_src_github_com_tests_struct_c_282_18_ [7]",
-		},
-	}
-
-	for i, tc := range tcs {
-		t.Run(fmt.Sprintf("Test %d : %s", i, tc.inp), func(t *testing.T) {
-			act := types.GenerateCorrectType(tc.inp)
-			if act != tc.out {
-				t.Errorf("Not correct result.\nExpected:%s\nActual:%s\n",
-					tc.out, act)
-			}
-		})
-	}
-}
-
 func TestResolveError(t *testing.T) {
 	tcs := []string{"w:w", "", "const"}
 	for i, tc := range tcs {
diff --git a/util/util_test.go b/util/util_test.go
index 2c19c08..49870ab 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -1,7 +1,9 @@
 package util
 
 import (
+	"encoding/json"
 	"fmt"
+	"strings"
 	"testing"
 )
 
@@ -25,3 +27,312 @@ func TestUcfirst(t *testing.T) {
 		})
 	}
 }
+
+func TestResolveFunction(t *testing.T) {
+	var tcs = []struct {
+		input string
+
+		prefix   string
+		funcname string
+		fields   []string
+		returns  []string
+	}{
+		{
+			input:   "__ssize_t (void *, char *, size_t)",
+			prefix:  "",
+			fields:  []string{"void *", "char *", "size_t"},
+			returns: []string{"__ssize_t"},
+		},
+		{
+			input:  "int (*)(sqlite3_vtab *, int, const char *, void (**)(sqlite3_context *, int, sqlite3_value **), void **)",
+			prefix: "",
+			fields: []string{
+				"sqlite3_vtab *",
+				"int",
+				"const char *",
+				"void (**)(sqlite3_context *, int, sqlite3_value **)",
+				"void **"},
+			returns: []string{"int"},
+		},
+		{
+			input:   "void ( *(*)(int *, void *, char *))(void)",
+			prefix:  "*",
+			fields:  []string{"void"},
+			returns: []string{"void (int *, void *, char *)"},
+		},
+		{
+			input:   " void (*)(void)",
+			prefix:  "",
+			fields:  []string{"void"},
+			returns: []string{"void"},
+		},
+		{
+			input:   " int (*)(sqlite3_file *)",
+			prefix:  "",
+			fields:  []string{"sqlite3_file *"},
+			returns: []string{"int"},
+		},
+		{
+			input:   " int (*)(int)",
+			prefix:  "",
+			fields:  []string{"int"},
+			returns: []string{"int"},
+		},
+		{
+			input:   " int (*)(void *) ",
+			prefix:  "",
+			fields:  []string{"void *"},
+			returns: []string{"int"},
+		},
+		{
+			input:   " void (*)(sqlite3_context *, int, sqlite3_value **)",
+			prefix:  "",
+			fields:  []string{"sqlite3_context *", "int", "sqlite3_value **"},
+			returns: []string{"void"},
+		},
+		{
+			input:   "char *(*)( char *, ...)",
+			prefix:  "",
+			fields:  []string{"char *", "..."},
+			returns: []string{"char *"},
+		},
+		{
+			input:   "char *(*)( char *, struct __va_list_tag *)",
+			prefix:  "",
+			fields:  []string{"char *", "struct __va_list_tag *"},
+			returns: []string{"char *"},
+		},
+		{
+			input:   "char *(*)(const char *, ...)",
+			prefix:  "",
+			fields:  []string{"const char *", "..."},
+			returns: []string{"char *"},
+		},
+		{
+			input:   "char *(*)(ImportCtx *)",
+			prefix:  "",
+			fields:  []string{"ImportCtx *"},
+			returns: []string{"char *"},
+		},
+		{
+			input:   "char *(*)(int, char *, char *, ...)",
+			prefix:  "",
+			fields:  []string{"int", "char *", "char *", "..."},
+			returns: []string{"char *"},
+		},
+		{
+			input:   "const char *(*)(int)",
+			prefix:  "",
+			fields:  []string{"int"},
+			returns: []string{"const char *"},
+		},
+		{
+			input:   "const unsigned char *(*)(sqlite3_value *)",
+			prefix:  "",
+			fields:  []string{"sqlite3_value *"},
+			returns: []string{"const unsigned char *"},
+		},
+		{
+			input:   "int (*)(const char *, sqlite3 **)",
+			prefix:  "",
+			fields:  []string{"const char *", "sqlite3 **"},
+			returns: []string{"int"},
+		},
+		{
+			input:  "int (*)(fts5_api *, const char *, void *, fts5_extension_function, void (*)(void *))",
+			prefix: "",
+			fields: []string{"fts5_api *",
+				"const char *",
+				"void *",
+				"fts5_extension_function",
+				"void (*)(void *)"},
+			returns: []string{"int"},
+		},
+		{
+			input:  "int (*)(Fts5Context *, char *, int, void *, int (*)(void *, int, char *, int, int, int))",
+			prefix: "",
+			fields: []string{"Fts5Context *",
+				"char *",
+				"int",
+				"void *",
+				"int (*)(void *, int, char *, int, int, int)"},
+			returns: []string{"int"},
+		},
+		{
+			input:  "int (*)(sqlite3 *, char *, int, int, void *, void (*)(sqlite3_context *, int, sqlite3_value **), void (*)(sqlite3_context *, int, sqlite3_value **), void (*)(sqlite3_context *))",
+			prefix: "",
+			fields: []string{
+				"sqlite3 *",
+				"char *",
+				"int",
+				"int",
+				"void *",
+				"void (*)(sqlite3_context *, int, sqlite3_value **)",
+				"void (*)(sqlite3_context *, int, sqlite3_value **)",
+				"void (*)(sqlite3_context *)",
+			},
+			returns: []string{"int"},
+		},
+		{
+			input:  "int (*)(sqlite3_vtab *, int, const char *, void (**)(sqlite3_context *, int, sqlite3_value **), void **)",
+			prefix: "",
+			fields: []string{
+				"sqlite3_vtab *",
+				"int",
+				"const char *",
+				"void (**)(sqlite3_context *, int, sqlite3_value **)",
+				"void **"},
+			returns: []string{"int"},
+		},
+		{
+			input:   "void (*(int *, void *, const char *))(void)",
+			prefix:  "",
+			fields:  []string{"void"},
+			returns: []string{"void (int *, void *, const char *)"},
+		},
+		{
+			input:   "long (int, int)",
+			prefix:  "",
+			fields:  []string{"int", "int"},
+			returns: []string{"long"},
+		},
+		{
+			input:   "void (const char *, ...)",
+			prefix:  "",
+			fields:  []string{"const char *", "..."},
+			returns: []string{"void"},
+		},
+		{
+			input:   "void (void)",
+			prefix:  "",
+			fields:  []string{"void"},
+			returns: []string{"void"},
+		},
+		{
+			input:   "void ()",
+			prefix:  "",
+			fields:  []string{""},
+			returns: []string{"void"},
+		},
+		{
+			input:   "int (*)()",
+			prefix:  "",
+			fields:  []string{""},
+			returns: []string{"int"},
+		},
+		{
+			input:    "int ioctl(int , int , ... )",
+			prefix:   "",
+			funcname: "ioctl",
+			fields:   []string{"int", "int", "..."},
+			returns:  []string{"int"},
+		},
+		{
+			input:    "speed_t cfgetospeed(const struct termios *)",
+			prefix:   "",
+			funcname: "cfgetospeed",
+			fields:   []string{"const struct termios *"},
+			returns:  []string{"speed_t"},
+		},
+		{
+			input:    "void (*signal(int , void (*)(int)))(int)",
+			prefix:   "*",
+			funcname: "signal",
+			fields:   []string{"int"},
+			returns:  []string{"void(int,void(int))"},
+		},
+		{
+			input:    "void ( * signal(int , void (*)(int)))(int)",
+			prefix:   "*",
+			funcname: "signal",
+			fields:   []string{"int"},
+			returns:  []string{"void(int,void(int))"},
+		},
+	}
+
+	for i, tc := range tcs {
+		t.Run(fmt.Sprintf("Test %d : %s", i, tc.input), func(t *testing.T) {
+			actualPrefix, actualName, actualField, actualReturn, err :=
+				ParseFunction(tc.input)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if actualPrefix != tc.prefix {
+				t.Errorf("Prefix is not same.\nActual: %s\nExpected: %s\n",
+					actualPrefix, tc.prefix)
+			}
+			if actualName != tc.funcname {
+				t.Errorf("Names is not same.\nActual: %s\nExpected: %s\n",
+					actualName, tc.funcname)
+			}
+			if len(actualField) != len(tc.fields) {
+				a, _ := json.Marshal(actualField)
+				f, _ := json.Marshal(tc.fields)
+				t.Errorf("Size of field is not same.\nActual  : %s\nExpected: %s\n",
+					string(a),
+					string(f))
+				return
+			}
+			if len(actualField) != len(tc.fields) {
+				a, _ := json.Marshal(actualField)
+				f, _ := json.Marshal(tc.fields)
+				t.Errorf("Size of field is not same.\nActual  : %s\nExpected: %s\n",
+					string(a),
+					string(f))
+				return
+			}
+			for i := range actualField {
+				actualField[i] = strings.Replace(actualField[i], " ", "", -1)
+				tc.fields[i] = strings.Replace(tc.fields[i], " ", "", -1)
+				if actualField[i] != tc.fields[i] {
+					t.Errorf("Not correct field: %v\nExpected: %v", actualField, tc.fields)
+				}
+			}
+			if len(actualReturn) != len(tc.returns) {
+				a, _ := json.Marshal(actualReturn)
+				f, _ := json.Marshal(tc.returns)
+				t.Errorf("Size of return field is not same.\nActual  : %s\nExpected: %s\n",
+					string(a),
+					string(f))
+				return
+			}
+			if len(actualReturn) != len(tc.returns) {
+				t.Errorf("Amount of return elements are different\nActual  : %v\nExpected: %v\n",
+					actualReturn, tc.returns)
+			}
+			for i := range actualReturn {
+				actualReturn[i] = strings.Replace(actualReturn[i], " ", "", -1)
+				tc.returns[i] = strings.Replace(tc.returns[i], " ", "", -1)
+				if actualReturn[i] != tc.returns[i] {
+					t.Errorf("Not correct returns: %v\nExpected: %v", actualReturn, tc.returns)
+				}
+			}
+		})
+	}
+}
+
+// func TestGenerateCorrectType(t *testing.T) {
+// tcs := []struct {
+// inp string
+// out string
+// }{
+// {
+// inp: "union (anonymous union at tests/union.c:46:3)",
+// out: "union __union_at_tests_union_c_46_3_",
+// },
+// {
+// inp: " const struct (anonymous struct at /home/lepricon/go/src/github.com/tests/struct.c:282:18) [7]",
+// out: "struct __struct_at__home_lepricon_go_src_github_com_tests_struct_c_282_18_ [7]",
+// },
+// }
+//
+// for i, tc := range tcs {
+// t.Run(fmt.Sprintf("Test %d : %s", i, tc.inp), func(t *testing.T) {
+// act := types.GenerateCorrectType(tc.inp)
+// if act != tc.out {
+// t.Errorf("Not correct result.\nExpected:%s\nActual:%s\n",
+// tc.out, act)
+// }
+// })
+// }
+// }