github.com/gotranspile/cxgo@v0.3.7/c_decl_test.go (about)

     1  package cxgo
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/gotranspile/cxgo/types"
     7  )
     8  
     9  var casesTranslateDecls = []parseCase{
    10  	{
    11  		name: "typedef primitive",
    12  		src:  `typedef int int_t;`,
    13  		exp:  `type int_t int32`,
    14  	},
    15  	{
    16  		name: "function decl",
    17  		src: `
    18  void foo() {}
    19  `,
    20  		exp: `
    21  func foo() {
    22  }
    23  `,
    24  	},
    25  	{
    26  		name: "function forward decl",
    27  		src: `
    28  void foo1();
    29  int foo2();
    30  int foo3(int*);
    31  int (*a)();
    32  int (*b)(int*);
    33  `,
    34  		exp: `
    35  func foo1()
    36  func foo2() int32
    37  func foo3(*int32) int32
    38  
    39  var a func() int32
    40  var b func(*int32) int32
    41  `,
    42  	},
    43  	{
    44  		name: "function forward decl 2",
    45  		src: `
    46  void foo1();
    47  int foo2();
    48  int foo3(int);
    49  void foo1() {}
    50  int foo2() {}
    51  int foo3(int) {}
    52  `,
    53  		exp: `
    54  func foo1() {
    55  }
    56  func foo2() int32 {
    57  }
    58  func foo3(int32) int32 {
    59  }
    60  `,
    61  	},
    62  	{
    63  		name: "var",
    64  		src: `
    65  int foo;
    66  char byte;
    67  `,
    68  		exp: `
    69  var foo int32
    70  var byte_ int8
    71  `,
    72  	},
    73  	{
    74  		name: "var init",
    75  		src: `
    76  int foo = 1;
    77  `,
    78  		exp: `
    79  var foo int32 = 1
    80  `,
    81  	},
    82  	{
    83  		name: "multiple vars",
    84  		src: `
    85  int foo = 1, *bar;
    86  `,
    87  		exp: `
    88  var foo int32 = 1
    89  var bar *int32
    90  `,
    91  	},
    92  	{
    93  		name: "multiple vars 2",
    94  		src: `
    95  int a = 1, *p, f(void), (*pf)(double);
    96  `,
    97  		exp: `
    98  var a int32 = 1
    99  var p *int32
   100  
   101  func f() int32
   102  
   103  var pf func(float64) int32
   104  `,
   105  	},
   106  	{
   107  		name: "complex var",
   108  		src: `
   109  int (*(*foo)(double))[3] = 0;
   110  `,
   111  		exp: `
   112  var foo func(float64) *[3]int32 = nil
   113  `,
   114  	},
   115  	{
   116  		name: "function var",
   117  		src: `
   118  void (*foo)(void);
   119  `,
   120  		exp: `
   121  var foo func()
   122  `,
   123  	},
   124  	{
   125  		name: "struct forward decl",
   126  		src: `
   127  struct foo;
   128  struct foo2;
   129  
   130  struct foo {
   131  	int a;
   132  };
   133  `,
   134  		exp: `
   135  type foo struct {
   136  	A int32
   137  }
   138  type foo2 struct {
   139  }
   140  `,
   141  	},
   142  	{
   143  		name: "typedef struct",
   144  		inc: `
   145  typedef struct bar {
   146  	int d;
   147  } BAR;
   148  `,
   149  		src: `
   150  typedef struct { int a; } foo;
   151  typedef struct foo2 { int b; } foo2;
   152  typedef struct foo3 { int c; } FOO3;
   153  struct bar bar1;
   154  BAR bar2;
   155  `,
   156  		exp: `
   157  type foo struct {
   158  	A int32
   159  }
   160  type foo2 struct {
   161  	B int32
   162  }
   163  type foo3 struct {
   164  	C int32
   165  }
   166  type FOO3 foo3
   167  
   168  var bar1 bar
   169  var bar2 BAR
   170  `,
   171  	},
   172  	{
   173  		name: "typedef struct 3",
   174  		src: `
   175  struct baz { int d; } bar3;
   176  `,
   177  		exp: `
   178  type baz struct {
   179  	D int32
   180  }
   181  
   182  var bar3 baz
   183  `,
   184  	},
   185  	{
   186  		name: "typedef alias",
   187  		src: `
   188  typedef struct { int a; } A;
   189  typedef A B;
   190  typedef B C;
   191  
   192  struct T1 {
   193    C (*f1)[3];
   194    C *f2;
   195  };
   196  typedef struct T1 T2;
   197  
   198  void foo(C* c) {}
   199  `,
   200  		exp: `
   201  type A struct {
   202  	A int32
   203  }
   204  type T1 struct {
   205  	F1 *[3]A
   206  	F2 *A
   207  }
   208  type T2 T1
   209  
   210  func foo(c *A) {
   211  }
   212  `,
   213  		configFuncs: []configFunc{
   214  			withAlias("B"),
   215  			withAlias("C"),
   216  		},
   217  	},
   218  	{
   219  		name: "typedef alias 2",
   220  		inc: `
   221  typedef struct { int a; } A;
   222  typedef A B;
   223  typedef B C;
   224  `,
   225  		src: `
   226  struct T1 {
   227    C (*f1)[3];
   228    C *f2;
   229  };
   230  typedef struct T1 T2;
   231  
   232  void foo(C* c) {}
   233  `,
   234  		exp: `
   235  type T1 struct {
   236  	F1 *[3]A
   237  	F2 *A
   238  }
   239  type T2 T1
   240  
   241  func foo(c *A) {
   242  }
   243  `,
   244  		configFuncs: []configFunc{
   245  			withAlias("B"),
   246  			withAlias("C"),
   247  		},
   248  	},
   249  	{
   250  		name: "recursive struct",
   251  		inc: `
   252  typedef struct _A* HA;
   253  typedef struct _B* HB;
   254  `,
   255  		src: `
   256  struct _A {
   257  	HB b;
   258  };
   259  struct _B {
   260  	HA a;
   261  };
   262  `,
   263  		exp: `
   264  type _A struct {
   265  	B HB
   266  }
   267  type _B struct {
   268  	A HA
   269  }
   270  `,
   271  	},
   272  	{
   273  		name: "named enum",
   274  		src: `
   275  	enum Enum
   276  	{
   277  	   VALUE_1,
   278  	   VALUE_2,
   279  	};
   280  	`,
   281  		exp: `
   282  type Enum int32
   283  
   284  const (
   285  	VALUE_1 = Enum(iota)
   286  	VALUE_2
   287  )
   288  	`,
   289  	},
   290  	{
   291  		name: "forward enum",
   292  		src: `
   293  	enum Enum;
   294  	enum Enum
   295  	{
   296  	   VALUE_1,
   297  	   VALUE_2,
   298  	};
   299  	`,
   300  		exp: `
   301  type Enum int32
   302  
   303  const (
   304  	VALUE_1 = Enum(iota)
   305  	VALUE_2
   306  )
   307  	`,
   308  	},
   309  	{
   310  		name: "return enum",
   311  		src: `
   312  	enum Enum
   313  	{
   314  	   VALUE_1,
   315  	   VALUE_2,
   316  	};
   317  	extern enum Enum foo();
   318  	`,
   319  		exp: `
   320  type Enum int32
   321  
   322  const (
   323  	VALUE_1 = Enum(iota)
   324  	VALUE_2
   325  )
   326  
   327  func foo() Enum
   328  	`,
   329  	},
   330  	{
   331  		name: "unnamed enum",
   332  		src: `
   333  enum
   334  {
   335      VALUE_1,
   336      VALUE_2,
   337  };
   338  `,
   339  		exp: `
   340  const (
   341  	VALUE_1 = iota
   342  	VALUE_2
   343  )
   344  `,
   345  	},
   346  	{
   347  		name: "typedef enum",
   348  		src: `
   349  typedef enum {
   350      VALUE_1,
   351      VALUE_2,
   352  } Enum;
   353  `,
   354  		exp: `
   355  type Enum int32
   356  
   357  const (
   358  	VALUE_1 = Enum(iota)
   359  	VALUE_2
   360  )
   361  `,
   362  	},
   363  	{
   364  		name: "enum zero",
   365  		src: `
   366  	enum Enum
   367  	{
   368  	   VALUE_1 = 0,
   369  	   VALUE_2,
   370  	};
   371  	`,
   372  		exp: `
   373  type Enum int32
   374  
   375  const (
   376  	VALUE_1 = Enum(iota)
   377  	VALUE_2
   378  )
   379  	`,
   380  	},
   381  	{
   382  		name: "enum start",
   383  		src: `
   384  	enum Enum
   385  	{
   386  	   VALUE_1 = 1,
   387  	   VALUE_2,
   388  	};
   389  	`,
   390  		exp: `
   391  type Enum int32
   392  
   393  const (
   394  	VALUE_1 = Enum(iota + 1)
   395  	VALUE_2
   396  )
   397  	`,
   398  	},
   399  	{
   400  		name: "enum fixed",
   401  		src: `
   402  	enum Enum
   403  	{
   404  	   VALUE_1 = 1,
   405  	   VALUE_2 = 2,
   406  	};
   407  	`,
   408  		exp: `
   409  type Enum int32
   410  
   411  const (
   412  	VALUE_1 Enum = 1
   413  	VALUE_2 Enum = 2
   414  )
   415  	`,
   416  	},
   417  	{
   418  		name: "enum no zero",
   419  		src: `
   420  	enum Enum
   421  	{
   422  	   VALUE_1,
   423  	   VALUE_2 = 1,
   424  	};
   425  	`,
   426  		exp: `
   427  type Enum int32
   428  
   429  const (
   430  	VALUE_1 Enum = 0
   431  	VALUE_2 Enum = 1
   432  )
   433  	`,
   434  	},
   435  	{
   436  		name: "enum no zero 2",
   437  		src: `
   438  	enum Enum
   439  	{
   440  	   VALUE_1,
   441  	   VALUE_2 = 42,
   442  	   VALUE_3,
   443  	};
   444  	`,
   445  		exp: `
   446  type Enum int32
   447  
   448  const (
   449  	VALUE_1 Enum = 0
   450  	VALUE_2 Enum = 42
   451  	VALUE_3 Enum = 43
   452  )
   453  	`,
   454  	},
   455  	{
   456  		name: "enum negative",
   457  		src: `
   458  	enum Enum
   459  	{
   460  	   VALUE_1 = -3,
   461  	   VALUE_2,
   462  	   VALUE_3 = 1,
   463  	};
   464  	`,
   465  		exp: `
   466  type Enum int32
   467  
   468  const (
   469  	VALUE_1 Enum = -3
   470  	VALUE_2 Enum = -2
   471  	VALUE_3 Enum = 1
   472  )
   473  	`,
   474  	},
   475  	{
   476  		name: "use enum",
   477  		src: `
   478  enum Enum
   479  {
   480     VALUE_1,
   481     VALUE_2,
   482  };
   483  enum Enum foo() {
   484  	return VALUE_1;
   485  }
   486  	`,
   487  		exp: `
   488  type Enum int32
   489  
   490  const (
   491  	VALUE_1 = Enum(iota)
   492  	VALUE_2
   493  )
   494  
   495  func foo() Enum {
   496  	return VALUE_1
   497  }
   498  	`,
   499  	},
   500  	{
   501  		name: "enum in func",
   502  		src: `
   503  void foo() {
   504  	typedef enum { A, B, C } Enum;
   505  	typedef enum { D, E, F } Enum2;
   506  	Enum x;
   507  }
   508  	`,
   509  		exp: `
   510  func foo() {
   511  	type Enum int32
   512  	const (
   513  		A = Enum(iota)
   514  		B
   515  		C
   516  	)
   517  	type Enum2 int32
   518  	const (
   519  		D = Enum2(iota)
   520  		E
   521  		F
   522  	)
   523  	var x Enum
   524  	_ = x
   525  }
   526  	`,
   527  	},
   528  	{
   529  		name: "struct and func", skip: true, // TODO
   530  		src: `
   531  struct foo;
   532  void foo();
   533  `,
   534  		exp: `
   535  type foo struct {
   536  }
   537  
   538  func foo_2()
   539  `,
   540  	},
   541  	{
   542  		name: "struct and var",
   543  		inc: `
   544  struct foo {};
   545  `,
   546  		src: `
   547  struct foo foo;
   548  `,
   549  		exp: `
   550  var foo foo
   551  `,
   552  	},
   553  	{
   554  		name: "func arg",
   555  		src: `
   556  void foo(int (*a)(void)) {
   557  }
   558  `,
   559  		exp: `
   560  func foo(a func() int32) {
   561  }
   562  `,
   563  	},
   564  	{
   565  		name: "local func var",
   566  		src: `
   567  void foo() {
   568  	int (*a)();
   569  }
   570  `,
   571  		exp: `
   572  func foo() {
   573  	var a func() int32
   574  	_ = a
   575  }
   576  `,
   577  	},
   578  	{
   579  		name: "for init",
   580  		src: `
   581  void foo() {
   582  	for (int i = 0; i < 5; i++) {}
   583  }
   584  `,
   585  		exp: `
   586  func foo() {
   587  	for i := int32(0); i < 5; i++ {
   588  	}
   589  }
   590  `,
   591  	},
   592  	{
   593  		name: "for init multiple",
   594  		skip: true, // TODO
   595  		src: `
   596  	void foo() {
   597  		for (int i = 0, j = 1; i < 5; i++) {}
   598  	}
   599  	`,
   600  		exp: `
   601  	func foo() {
   602  		for i, j := int32(0), int32(1); i < 5; i++ {
   603  		}
   604  	}
   605  	`,
   606  	},
   607  	{
   608  		name: "extern var",
   609  		src: `
   610  extern int a;
   611  `,
   612  		exp: `
   613  `,
   614  	},
   615  	{
   616  		name: "use incomplete type",
   617  		src: `
   618  typedef struct MyType MyType;
   619  MyType *new_type(void) {
   620  	return 0;
   621  }
   622  `,
   623  		exp: `
   624  type MyType struct {
   625  }
   626  
   627  func new_type() *MyType {
   628  	return nil
   629  }
   630  `,
   631  	},
   632  	{
   633  		name: "unnamed struct var",
   634  		src: `
   635  void foo() {
   636  	struct{
   637  		int field;
   638  	} a = {0};
   639  	struct{
   640  		int field;
   641  		int field2;
   642  	} b = {0};
   643  }
   644  `,
   645  		exp: `
   646  func foo() {
   647  	var a struct {
   648  		Field int32
   649  	} = struct {
   650  		Field int32
   651  	}{}
   652  	_ = a
   653  	var b struct {
   654  		Field  int32
   655  		Field2 int32
   656  	} = struct {
   657  		Field  int32
   658  		Field2 int32
   659  	}{}
   660  	_ = b
   661  }
   662  `,
   663  	},
   664  	{
   665  		name: "empty array decl",
   666  		src: `
   667  void foo() {
   668  	int a[1][0];
   669  }
   670  `,
   671  		exp: `
   672  func foo() {
   673  	var a [1][0]int32
   674  	_ = a
   675  }
   676  `,
   677  	},
   678  	{
   679  		name: "rename decl func",
   680  		src: `
   681  void foo() {}
   682  `,
   683  		exp: `
   684  func Bar() {
   685  }
   686  `,
   687  		configFuncs: []configFunc{
   688  			withRename("foo", "Bar"),
   689  		},
   690  	},
   691  	{
   692  		name: "rename decl struct",
   693  		src: `
   694  struct foo {};
   695  `,
   696  		exp: `
   697  type Bar struct {
   698  }
   699  `,
   700  		configFuncs: []configFunc{
   701  			withRename("foo", "Bar"),
   702  		},
   703  	},
   704  	{
   705  		name: "args partially named",
   706  		src: `
   707  void (*foo)(void *a, int, const char *);
   708  `,
   709  		exp: `
   710  var foo func(a unsafe.Pointer, a2 int32, a3 *byte)
   711  `,
   712  	},
   713  	{
   714  		name: "go ints",
   715  		src: `
   716  typedef unsigned int word;
   717  `,
   718  		exp: `
   719  type word uint
   720  `,
   721  		envFuncs: []envFunc{
   722  			func(c *types.Config) {
   723  				c.UseGoInt = true
   724  			},
   725  		},
   726  	},
   727  	{
   728  		name: "unused vars",
   729  		src: `
   730  void foo(int x) {
   731  	int a;
   732  }
   733  
   734  void bar() {
   735  	int a = 0;
   736  	int b;
   737  	int c = b;
   738  }
   739  `,
   740  		exp: `
   741  func foo(x int32) {
   742  	var a int32
   743  	_ = a
   744  }
   745  func bar() {
   746  	var a int32 = 0
   747  	_ = a
   748  	var b int32
   749  	var c int32 = b
   750  	_ = c
   751  }
   752  `,
   753  	},
   754  	{
   755  		name: "tcc 10",
   756  		src: `
   757  struct z
   758  {
   759     int a;
   760  } foo;
   761  `,
   762  		exp: `
   763  type z struct {
   764  	A int32
   765  }
   766  
   767  var foo z
   768  `,
   769  	},
   770  	{
   771  		name: "stdlib forward decl",
   772  		src: `
   773  int printf(const char*, ...);
   774  
   775  void foo() {
   776  	printf("%d\n", 1);
   777  }
   778  `,
   779  		exp: `
   780  func foo() {
   781  	stdio.Printf("%d\n", 1)
   782  }
   783  `,
   784  	},
   785  	{
   786  		name: "macro empty",
   787  		src: `
   788  #define MY_DEF
   789  
   790  int a;
   791  `,
   792  		exp: `
   793  var a int32
   794  `,
   795  	},
   796  	{
   797  		name: "macro untyped int",
   798  		src: `
   799  #define MY_CONST 1
   800  
   801  int a = MY_CONST;
   802  `,
   803  		exp: `
   804  const MY_CONST = 1
   805  
   806  var a int32 = MY_CONST
   807  `,
   808  	},
   809  	{
   810  		// TODO: cc.AST.Eval() doesn't support cast expressions?
   811  		skip: true,
   812  		name: "macro typed int",
   813  		src: `
   814  #define MY_CONST ((int)1)
   815  
   816  int a = MY_CONST;
   817  `,
   818  		exp: `
   819  const MY_CONST = int32(1)
   820  
   821  var a int32 = MY_CONST
   822  `,
   823  	},
   824  	{
   825  		name: "macro string",
   826  		src: `
   827  #define MY_CONST "abc"
   828  
   829  char* a = MY_CONST;
   830  `,
   831  		exp: `
   832  const MY_CONST = "abc"
   833  
   834  var a *byte = libc.CString(MY_CONST)
   835  `,
   836  	},
   837  	{
   838  		name: "macro order",
   839  		src: `
   840  #define MY_CONST 1
   841  
   842  int a = MY_CONST;
   843  
   844  #define MY_CONST_2 2
   845  `,
   846  		exp: `
   847  const MY_CONST = 1
   848  
   849  var a int32 = MY_CONST
   850  
   851  const MY_CONST_2 = 2
   852  `,
   853  		// TODO: we don't handle order yet
   854  		skipExp: `
   855  const MY_CONST = 1
   856  const MY_CONST_2 = 2
   857  
   858  var a int32 = MY_CONST
   859  `,
   860  	},
   861  }
   862  
   863  func TestDecls(t *testing.T) {
   864  	runTestTranslate(t, casesTranslateDecls)
   865  }