github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/function.c (about)

     1  #include "tests.h"
     2  #include <stdio.h>
     3  
     4  void my_function();
     5  
     6  int i = 40;
     7  
     8  void function()
     9  {
    10      i += 2;
    11  }
    12  
    13  void function2()
    14  {
    15      i += 8;
    16  }
    17  
    18  int (*f)(int, int);
    19  
    20  int add(int a, int b)
    21  {
    22      return a + b;
    23  }
    24  
    25  int mul(int a, int b)
    26  {
    27      return a * b;
    28  }
    29  
    30  double (*f2)(int, float, double);
    31  
    32  double add2(int a, float b, double c)
    33  {
    34      return c + a + b;
    35  }
    36  
    37  double mul2(int a, float b, double c)
    38  {
    39      return a * b * c;
    40  }
    41  
    42  double action(double (*F)(int, float, double))
    43  {
    44      return F(2, 3, 4);
    45  }
    46  
    47  // Go keywords in C function
    48  int chan() { return 42; }
    49  int defer() { return 42; }
    50  int fallthrough() { return 42; }
    51  int func() { return 42; }
    52  int go() { return 42; }
    53  int import() { return 42; }
    54  int interface() { return 42; }
    55  int map() { return 42; }
    56  int package() { return 42; }
    57  int range() { return 42; }
    58  // int select() { return 42; }
    59  int type() { return 42; }
    60  int var() { return 42; }
    61  int _() { return 42; }
    62  int init() { return 42; }
    63  int len() { return 42; }
    64  int copy() { return 42; }
    65  int fmt() { return 42; }
    66  int cap() { return 42; }
    67  
    68  void exit2(int t)
    69  {
    70      (void)(t);
    71  }
    72  void empty_return()
    73  {
    74      int i = 0;
    75      (void)(i);
    76      exit2(-1);
    77  }
    78  int empty_return_int(int a)
    79  {
    80      if (a > 0) {
    81          return 1;
    82      } else {
    83          exit2(-1);
    84      }
    85  }
    86  int empty_return_int2(int* a)
    87  {
    88      if (*a > 0) {
    89          return 1;
    90      } else {
    91          exit2(-1);
    92      }
    93  }
    94  double empty_return_double(double a)
    95  {
    96      if (a > 0.0) {
    97          return 1.0;
    98      } else {
    99          exit2(-1);
   100      }
   101  }
   102  double empty_return_double2(double* a)
   103  {
   104      if (*a > 0.0) {
   105          return 1.0;
   106      } else {
   107          exit2(-1);
   108      }
   109  }
   110  typedef struct RE RE;
   111  struct RE {
   112      int re;
   113  };
   114  RE empty_return_struct(int a)
   115  {
   116      if (a > 0.0) {
   117          RE r;
   118          r.re = 1;
   119          return r;
   120      } else {
   121          exit2(-1);
   122      }
   123  }
   124  RE* empty_return_struct2(int a)
   125  {
   126      if (a > 0.0) {
   127          RE r;
   128          r.re = 1;
   129          return &r;
   130      } else {
   131          exit2(-1);
   132      }
   133  }
   134  
   135  typedef int (*operators)(int a, int b);
   136  int call_a_func(operators call_this)
   137  {
   138      int output = call_this(5, 8);
   139      return output;
   140  }
   141  
   142  // TODO : add function separation by C headers
   143  // long tolower(int a, int b) { return (long)(a + b); }
   144  // long toupper(int a, int b) { return (long)(a + b); }
   145  
   146  char* readline();
   147  char* readline(char* string, FILE* infile, char* infilename)
   148  {
   149      (void)(infile);
   150      (void)(infilename);
   151      return string;
   152  }
   153  void test_string()
   154  {
   155      is_streq(readline("rt", NULL, NULL), "rt");
   156  }
   157  
   158  int run_function(int a, void* v, char** c, void (*f)(void))
   159  {
   160      (void)(v);
   161      (void)(c);
   162      return a;
   163  }
   164  void test_null_function()
   165  {
   166      is_eq(run_function(5, NULL, NULL, NULL), 5);
   167      is_eq(run_function(5, 0, 0, 0), 5);
   168  }
   169  
   170  void test_function_if()
   171  {
   172      int (*T)(int, double) = NULL;
   173      is_null(T);
   174      if (!T) {
   175          pass("!T");
   176      }
   177      void (*R)(void) = NULL;
   178      is_null(R);
   179      R = my_function;
   180      is_not_null(R);
   181      if (!R) {
   182          pass("!R");
   183      }
   184      if (!R || !T) {
   185          pass("!R || !T");
   186      }
   187      void (*V1)(void) = NULL;
   188      is_null(V1);
   189      if (!V1) {
   190          pass("!V1");
   191      }
   192      void (*V2)(void*) = NULL;
   193      is_null(V2);
   194      if (!(!V2)) {
   195          fail("!V2");
   196      }
   197  }
   198  
   199  void NullPointerCheck()
   200  {
   201      void* p = NULL;
   202      if (p) {
   203          fail("p == NULL");
   204      }
   205      if (!p) {
   206          pass("p ^^ NULL");
   207      }
   208      double d = 99;
   209      p = &d;
   210      if (p) {
   211          pass("p __ NULL");
   212      }
   213      if (!p) {
   214          fail("p != NULL");
   215      }
   216  }
   217  
   218  int main()
   219  {
   220      plan(62);
   221  
   222      test_string();
   223      test_null_function();
   224  
   225      pass("%s", "Main function.");
   226  
   227      my_function();
   228  
   229      pass("%s", "Back in function main.");
   230  
   231      diag("pointer on function. Part 1");
   232      void* a = NULL;
   233      is_null(a);
   234      a = function;
   235      is_not_null(a);
   236      void (*t)(void) = a;
   237      is_not_null(t);
   238      t();
   239      is_eq(i, 42);
   240      t = function2;
   241      is_not_null(t);
   242      t();
   243      is_eq(i, 50);
   244  
   245      diag("pointer on function. Part 2");
   246      f = add;
   247      int i = f(3, 4);
   248      is_eq(i, 7);
   249      f = mul;
   250      int j = f(3, 4);
   251      is_eq(j, 12);
   252      if (f(2, 3) == 6) {
   253          pass("Ok")
   254      }
   255  
   256      diag("pointer on function. Part 3");
   257      {
   258          f2 = add2;
   259          double temp_data;
   260          temp_data = f2(4, 2, 3);
   261          is_eq(temp_data, 9);
   262          f2 = mul2;
   263          is_eq(f2(4, 2, 3), 24);
   264          double ttt = f2(1, 1, 1);
   265          is_eq(ttt, 1);
   266          if (add2(2, 3, 1) == 6.0) {
   267              pass("Ok")
   268          }
   269      }
   270  
   271      diag("Not allowable function name for Go");
   272      is_eq(chan(), 42);
   273      is_eq(defer(), 42);
   274      is_eq(fallthrough(), 42);
   275      is_eq(func(), 42);
   276      is_eq(go(), 42);
   277      is_eq(import(), 42);
   278      is_eq(interface(), 42);
   279      is_eq(map(), 42);
   280      is_eq(package(), 42);
   281      is_eq(range(), 42);
   282      // is_eq(select(), 42);
   283      is_eq(type(), 42);
   284      is_eq(var(), 42);
   285      is_eq(_(), 42);
   286      is_eq(init(), 42);
   287      is_eq(len(), 42);
   288      is_eq(copy(), 42);
   289      is_eq(fmt(), 42);
   290      is_eq(cap(), 42);
   291  
   292      diag("Function pointer inside function");
   293      is_eq(action(add2), add2(2, 3, 4));
   294      is_eq(action(mul2), mul2(2, 3, 4));
   295  
   296      diag("Function with empty return");
   297      {
   298          empty_return();
   299          pass("ok");
   300      }
   301      {
   302          empty_return_int(2);
   303          pass("ok");
   304      }
   305      {
   306          int Y = 6;
   307          is_eq(empty_return_int2(&Y), 1);
   308      }
   309      {
   310          double Y = 6;
   311          is_eq(empty_return_double(Y), 1);
   312      }
   313      {
   314          double Y = 6;
   315          is_eq(empty_return_double2(&Y), 1);
   316      }
   317      {
   318          is_eq((empty_return_struct(6)).re, 1);
   319      }
   320      {
   321          is_eq((*(empty_return_struct2(6))).re, 1);
   322      }
   323  
   324      diag("typedef function");
   325      {
   326          int result = call_a_func(&mul);
   327          is_eq(result, 40);
   328      }
   329      {
   330          is_eq(call_a_func(&mul), 40);
   331      }
   332  
   333      // diag("function name like in CSTD");
   334      // {
   335      // is_eq(tolower(34, 52), 86);
   336      // is_eq(toupper(34, 52), 86);
   337      // }
   338  
   339      diag("function argument from array to slice");
   340      {
   341          char input_str[20];
   342          strncpy(input_str, "Hello", 20);
   343          is_streq(input_str, "Hello");
   344      }
   345      {
   346          struct s_inp {
   347              char input_str[20];
   348          };
   349          struct s_inp s;
   350          strncpy(s.input_str, "Hello", 20);
   351          is_streq(s.input_str, "Hello");
   352      }
   353      test_function_if();
   354      NullPointerCheck();
   355  
   356      {
   357          diag("not argument in argument");
   358          int t = 0;
   359          exit2(t = 2);
   360          is_eq(t, 2);
   361          exit2(t += 2);
   362          is_eq(t, 4);
   363      }
   364  
   365      done_testing();
   366  }
   367  
   368  void my_function()
   369  {
   370      pass("%s", "Welcome to my function. Feel at home.");
   371  }