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

     1  // This program actually still works without including stdio.h but it should be
     2  // here for consistency.
     3  
     4  #include "tests.h"
     5  #include <assert.h>
     6  #include <stdarg.h>
     7  #include <stdio.h>
     8  #include <string.h>
     9  
    10  #define START_TEST(t) \
    11      diag(#t);         \
    12      test_##t();
    13  
    14  // size of that file
    15  int filesize = 32;
    16  char* test_file = "tests/stdio.txt";
    17  
    18  void test_putchar()
    19  {
    20      putchar('#');
    21      char c;
    22      for (c = 'A'; c <= 'Z'; c++)
    23          putchar(c);
    24      putchar('\n');
    25  
    26      pass("%s", "putchar");
    27  }
    28  
    29  void test_puts()
    30  {
    31      puts("#c4go");
    32  
    33      pass("%s", "puts");
    34  }
    35  
    36  void test_printf()
    37  {
    38      // TODO: printf() has a different syntax to Go
    39      // https://github.com/Konstantin8105/c4go/issues/94
    40  
    41      printf("# Characters: %c %c \n", 'a', 65);
    42      //printf("Decimals: %d %ld\n", 1977, 650000L);
    43      printf("# Preceding with blanks: %10d \n", 1977);
    44      printf("# Preceding with zeros: %010d \n", 1977);
    45      printf("# Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
    46      printf("# floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
    47      printf("# Width trick: %*d \n", 5, 10);
    48      printf("# %s \n", "A string");
    49  
    50      // Type printf
    51      unsigned long long ull = 42;
    52      printf("Long long : %u\n", ull);
    53      unsigned int ui = 42;
    54      printf("uint : %u\n", ui);
    55      double d = 42.42;
    56      printf("double : %f\n", d);
    57      printf("double : %lf\n", d);
    58      printf("double : %2.2f\n", d);
    59  
    60      // Literal error
    61      printf("Символьный литерал \'A\':\t%d\n", sizeof('A'));
    62  
    63      int magnitude = 4;
    64      char printfFormat[30] = "%0";
    65      char magnitudeString[10];
    66      sprintf(magnitudeString, "%d", magnitude);
    67      strcat(printfFormat, magnitudeString);
    68      strcat(printfFormat, "d  ");
    69      printf("# ");
    70      printf(printfFormat, 120);
    71      printf(" \n");
    72  
    73      pass("%s", "printf");
    74  }
    75  
    76  void test_remove()
    77  {
    78      // TODO: This does not actually test successfully deleting a file.
    79      if (remove("myfile.txt") != 0) {
    80          pass("%s", "error deleting file");
    81      } else {
    82          fail("%s", "file successfully deleted");
    83      }
    84  }
    85  
    86  void test_rename()
    87  {
    88      // TODO: This does not actually test successfully renaming a file.
    89      int result;
    90      char oldname[] = "oldname.txt";
    91      char newname[] = "newname.txt";
    92      result = rename(oldname, newname);
    93      if (result == 0) {
    94          fail("%s", "File successfully renamed");
    95      } else {
    96          pass("%s", "Error renaming file");
    97      }
    98  }
    99  
   100  void test_fopen()
   101  {
   102      FILE* pFile;
   103      pFile = fopen("./testdata/myfile.txt", "w");
   104      if (pFile != NULL) {
   105          is_not_null(pFile);
   106          fclose(pFile);
   107      }
   108  }
   109  
   110  void test_tmpfile()
   111  {
   112      char buffer[256];
   113      FILE* pFile;
   114      pFile = tmpfile();
   115  
   116      fputs("hello world", pFile);
   117      rewind(pFile);
   118      fputs(fgets(buffer, 256, pFile), stdout);
   119      fclose(pFile);
   120  }
   121  
   122  void test_tmpnam()
   123  {
   124      // TODO: This is a tricky one to test because the output of tmpnam() in C
   125      // and Go will be different. I will keep the test here so at least it tries
   126      // to run the code but the test itself is not actually proving anything.
   127  
   128      char* pointer;
   129  
   130      // FIXME: We cannot pass variables by reference yet, which is a legitimate
   131      // way to use tmpnam(). I have to leave this disabled for now.
   132      //
   133      //     char buffer[L_tmpnam];
   134      //     tmpnam(buffer);
   135      //     assert(buffer != NULL);
   136  
   137      pointer = tmpnam(NULL);
   138      is_not_null(pointer);
   139  }
   140  
   141  void test_fclose()
   142  {
   143      remove("./testdata/myfile.txt");
   144      FILE* pFile;
   145      pFile = fopen("./testdata/myfile.txt", "w");
   146      fputs("fclose example", pFile);
   147      fclose(pFile);
   148      // remove temp file
   149      is_eq(remove("./testdata/myfile.txt"), 0)
   150  }
   151  
   152  void test_fflush()
   153  {
   154      char mybuffer[80];
   155      FILE* pFile;
   156      pFile = fopen("./testdata/example.txt", "w+");
   157      is_not_null(pFile) or_return();
   158  
   159      fputs("test", pFile);
   160      fflush(pFile); // flushing or repositioning required
   161      fgets(mybuffer, 80, pFile);
   162      fclose(pFile);
   163      // remove temp file
   164      is_eq(remove("./testdata/example.txt"), 0)
   165  }
   166  
   167  void test_fprintf()
   168  {
   169      remove("./testdata/myfile1.txt");
   170      FILE* pFile;
   171      int n;
   172      char* name = "John Smith";
   173  
   174      pFile = fopen("./testdata/myfile1.txt", "w");
   175      is_not_null(pFile);
   176  
   177      for (n = 0; n < 3; n++) {
   178          fprintf(pFile, "Name %d [%-10.10s]\n", n + 1, name);
   179      }
   180  
   181      fclose(pFile);
   182      // remove temp file
   183      is_eq(remove("./testdata/myfile1.txt"), 0)
   184  }
   185  
   186  void test_fscanf()
   187  {
   188      remove("./testdata/myfile2.txt");
   189  
   190      char str[80];
   191      char end[80];
   192      float f;
   193      int i;
   194      FILE* pFile;
   195  
   196      pFile = fopen("./testdata/myfile2.txt", "w+");
   197      is_not_null(pFile);
   198  
   199      fprintf(pFile, "%f \r\n\t\n %s %d %s", 3.1416, "PI", 42, "end");
   200      rewind(pFile);
   201      fscanf(pFile, "%f", &f);
   202      fscanf(pFile, "%s", str);
   203      fscanf(pFile, "%d", &i);
   204      fscanf(pFile, "%s", end);
   205      fclose(pFile);
   206      pFile = NULL;
   207  
   208      is_eq(f, 3.1416);
   209      is_streq(str, "PI");
   210      is_eq(i, 42);
   211      is_streq(end, "end");
   212  
   213      // read again
   214      FILE* pFile2;
   215      pFile2 = fopen("./testdata/myfile2.txt", "r");
   216      is_not_null(pFile2);
   217  
   218      fscanf(pFile2, "%f", &f);
   219      fscanf(pFile2, "%s", str);
   220      fscanf(pFile2, "%d", &i);
   221      fscanf(pFile2, "%s", end);
   222      fclose(pFile2);
   223      pFile2 = NULL;
   224  
   225      is_eq(f, 3.1416);
   226      is_streq(str, "PI");
   227      is_eq(i, 42);
   228      is_streq(end, "end");
   229  
   230      // remove temp file
   231      is_eq(remove("./testdata/myfile2.txt"), 0)
   232  
   233          // test file fscan.txt
   234          FILE* in
   235          = fopen("./tests/stdio_fscan.txt", "r");
   236      char dummy[128];
   237  
   238      for (int iter = 0; iter < 10; iter++) {
   239          int e = fscanf(in, "%s", dummy);
   240          printf("fscan : iter[%d] : err = %d\n", iter, e);
   241          if (e < 0) {
   242              break;
   243          }
   244          printf("fscan : iter[%d] : str = %s\n", iter, dummy);
   245      }
   246  }
   247  
   248  void test_fgetc()
   249  {
   250      FILE* pFile;
   251      int c;
   252      int n = 0;
   253      pFile = fopen("tests/stdio.c", "r");
   254      is_not_null(pFile);
   255  
   256      do {
   257          c = fgetc(pFile);
   258          if (c == '$')
   259              n++;
   260      } while (c != EOF);
   261      fclose(pFile);
   262  
   263      is_eq(n, 2);
   264  }
   265  
   266  void test_fgets()
   267  {
   268      FILE* pFile;
   269      char* mystring;
   270      char dummy[20];
   271  
   272      pFile = fopen("tests/stdio.c", "r");
   273      is_not_null(pFile);
   274  
   275      mystring = fgets(dummy, 20, pFile);
   276      is_not_null(mystring);
   277  
   278      fclose(pFile);
   279  }
   280  
   281  void test_fputc()
   282  {
   283      char c;
   284  
   285      fputc('#', stdout);
   286      for (c = 'A'; c <= 'Z'; c++)
   287          fputc(c, stdout);
   288      fputc('\n', stdout);
   289  }
   290  
   291  void test_fputs()
   292  {
   293      FILE* pFile;
   294      char* sentence = "Hello, World";
   295  
   296      pFile = fopen("./testdata/mylog.txt", "w");
   297      fputs(sentence, pFile);
   298      fclose(pFile);
   299      // remove temp file
   300      is_eq(remove("./testdata/mylog.txt"), 0)
   301  }
   302  
   303  void test_getc()
   304  {
   305      FILE* pFile;
   306      int c;
   307      int n = 0;
   308      pFile = fopen("tests/stdio.c", "r");
   309      is_not_null(pFile);
   310  
   311      do {
   312          c = getc(pFile);
   313          if (c == '$')
   314              n++;
   315      } while (c != EOF);
   316      fclose(pFile);
   317  
   318      is_eq(n, 2);
   319  }
   320  
   321  void test_putc()
   322  {
   323      FILE* pFile;
   324      char c;
   325  
   326      pFile = fopen("./testdata/whatever.txt", "w");
   327      for (c = 'A'; c <= 'Z'; c++) {
   328          putc(c, pFile);
   329      }
   330      fclose(pFile);
   331      // remove temp file
   332      is_eq(remove("./testdata/whatever.txt"), 0)
   333  }
   334  
   335  void test_fseek()
   336  {
   337      FILE* pFile;
   338      pFile = fopen("./testdata/example.txt", "w");
   339      fputs("This is an apple.", pFile);
   340      fseek(pFile, 9, SEEK_SET);
   341      fputs(" sam", pFile);
   342      fclose(pFile);
   343      // remove temp file
   344      is_eq(remove("./testdata/example.txt"), 0)
   345  }
   346  
   347  void test_ftell()
   348  {
   349      FILE* pFile;
   350      long size;
   351  
   352      pFile = fopen(test_file, "r");
   353      is_not_null(pFile);
   354  
   355      fseek(pFile, 0, SEEK_END); // non-portable
   356      size = ftell(pFile);
   357      fclose(pFile);
   358  
   359      is_eq(size, filesize);
   360  }
   361  
   362  void test_fread()
   363  {
   364      FILE* pFile;
   365      int lSize;
   366      char buffer[1024];
   367      int result;
   368  
   369      pFile = fopen("tests/getchar.c", "r");
   370      is_not_null(pFile);
   371  
   372      // obtain file size:
   373      fseek(pFile, 0, SEEK_END);
   374      lSize = ftell(pFile);
   375      is_eq(lSize, 216);
   376  
   377      rewind(pFile);
   378  
   379      // copy the file into the buffer:
   380      result = fread(buffer, 1, lSize, pFile);
   381      is_eq(result, lSize);
   382  
   383      // See issue #107
   384      buffer[lSize - 1] = 0;
   385  
   386      is_eq(strlen(buffer), 215);
   387  
   388      // terminate
   389      fclose(pFile);
   390  }
   391  
   392  void test_fwrite()
   393  {
   394      FILE* pFile;
   395      pFile = fopen("./testdata/myfile.bin", "w");
   396      fwrite("xyz", 1, 3, pFile);
   397      fclose(pFile);
   398      // remove temp file
   399      is_eq(remove("./testdata/myfile.bin"), 0)
   400  }
   401  
   402  void test_fgetpos()
   403  {
   404      FILE* pFile;
   405      int c;
   406      int n;
   407      fpos_t pos;
   408  
   409      pFile = fopen("tests/stdio.c", "r");
   410      is_not_null(pFile);
   411  
   412      c = fgetc(pFile);
   413      is_eq(c, '/');
   414  
   415      fgetpos(pFile, &pos);
   416      for (n = 0; n < 3; n++) {
   417          fsetpos(pFile, &pos);
   418          c = fgetc(pFile);
   419          is_eq(c, '/');
   420      }
   421  
   422      fclose(pFile);
   423  }
   424  
   425  void test_fsetpos()
   426  {
   427      FILE* pFile;
   428      fpos_t position;
   429  
   430      pFile = fopen("./testdata/myfile.txt", "w");
   431      fgetpos(pFile, &position);
   432      fputs("That is a sample", pFile);
   433      fsetpos(pFile, &position);
   434      fputs("This", pFile);
   435      fclose(pFile);
   436      // remove temp file
   437      is_eq(remove("./testdata/myfile.txt"), 0)
   438  }
   439  
   440  void test_rewind()
   441  {
   442      int n;
   443      FILE* pFile;
   444      char buffer[27];
   445  
   446      pFile = fopen("./testdata/myfile.txt", "w+");
   447      for (n = 'A'; n <= 'Z'; n++)
   448          fputc(n, pFile);
   449      rewind(pFile);
   450      fread(buffer, 1, 26, pFile);
   451      fclose(pFile);
   452      buffer[26] = '\0';
   453  
   454      is_eq(strlen(buffer), 26);
   455  
   456      // remove temp file
   457      is_eq(remove("./testdata/myfile.txt"), 0)
   458  }
   459  
   460  void test_feof()
   461  {
   462      FILE* pFile;
   463      int n = 0;
   464      pFile = fopen(test_file, "r");
   465      is_not_null(pFile);
   466  
   467      while (fgetc(pFile) != EOF) {
   468          ++n;
   469      }
   470      if (feof(pFile)) {
   471          pass("%s", "End-of-File reached.");
   472          is_eq(n, filesize);
   473      } else {
   474          fail("%s", "End-of-File was not reached.");
   475      }
   476  
   477      fclose(pFile);
   478  }
   479  
   480  void test_sprintf()
   481  {
   482      char buffer[100];
   483      int cx;
   484      cx = snprintf(buffer, 100, "The half of %d is %d", 60, 60 / 2);
   485      is_streq(buffer, "The half of 60 is 30");
   486      is_eq(cx, 20);
   487  }
   488  
   489  void test_snprintf()
   490  {
   491      char buffer[50];
   492      int n, a = 5, b = 3;
   493      n = sprintf(buffer, "%d plus %d is %d", a, b, a + b);
   494      is_streq(buffer, "5 plus 3 is 8");
   495      is_eq(n, 13);
   496  
   497      char status[80];
   498      char* filename = "out.txt";
   499      int numrows = 10;
   500      int dirty = 1;
   501      int len = snprintf(status, sizeof(status), "%.20s - %d lines %s",
   502          filename, numrows, dirty ? "(modified)" : "");
   503      printf("%s\n", status);
   504      is_eq(len, 29);
   505  }
   506  
   507  int PrintFError(const char* format, ...)
   508  {
   509      char buffer[256];
   510      va_list args;
   511      va_start(args, format);
   512      int s = vsprintf(buffer, format, args);
   513      va_end(args);
   514      printf("vsnprintf buffer: `%s`\n", buffer);
   515      return s;
   516  }
   517  
   518  void test_vsprintf()
   519  {
   520      int s = PrintFError("Success function '%s' %.2f", "vsprintf", 3.1415926);
   521      is_true(s == 19 + 8 + 5);
   522  }
   523  
   524  int PrintFError2(const char* format, ...)
   525  {
   526      char buffer[256];
   527      va_list args;
   528      va_start(args, format);
   529      int s = vsnprintf(buffer, 256, format, args);
   530      va_end(args);
   531      printf("vsnprintf buffer: `%s`\n", buffer);
   532      return s;
   533  }
   534  
   535  void test_vsnprintf()
   536  {
   537      int s = PrintFError2("Success function '%s' %.2f", "vsprintf", 3.1415926);
   538      is_true(s == 19 + 8 + 5);
   539      s = PrintFError2("HHELP %d", (int)(2));
   540      is_true(s == 7);
   541  }
   542  
   543  void test_eof()
   544  {
   545      if ((int)(EOF) == -1) {
   546          pass("ok");
   547      }
   548      char c = EOF;
   549      if (c == (char)(EOF)) {
   550          pass("ok");
   551      }
   552      char a[1];
   553      a[0] = 's';
   554      if (a[0] != EOF) {
   555          pass("ok");
   556      }
   557      a[0] = EOF;
   558      if (a[0] != EOF) {
   559          fail("EOF == EOF - fail");
   560      } else {
   561          pass("ok");
   562      }
   563  }
   564  
   565  void test_perror()
   566  {
   567      perror("test perror");
   568  }
   569  
   570  void test_getline()
   571  {
   572      {
   573          diag("getline: not empty file");
   574          FILE* pFile;
   575          pFile = fopen(test_file, "r");
   576          is_not_null(pFile);
   577  
   578          size_t len;
   579          char* line = NULL;
   580          char** pnt = &line;
   581          size_t* l = &len;
   582          ssize_t pos = getline(pnt, l, pFile);
   583          for (int i = 0; i < pos; i++) {
   584              printf("[%d] : `%d`\n", i, line[i]);
   585          }
   586          printf("pos [%d] == filesize [%d]\n", pos, filesize);
   587          is_eq(pos, filesize);
   588      }
   589      {
   590          diag("getline: not empty file");
   591          FILE* pFile;
   592          pFile = fopen("./tests/empty.txt", "r");
   593          is_not_null(pFile);
   594  
   595          size_t len;
   596          char* line = NULL;
   597          char** pnt = &line;
   598          size_t* l = &len;
   599          ssize_t pos = getline(pnt, l, pFile);
   600          is_eq(pos, -1);
   601      }
   602  }
   603  
   604  void test_sscanf()
   605  {
   606      char sentence[] = "Example\nRudolph is 12 years old";
   607      char header[50];
   608      char temp[50];
   609      char str[20];
   610      int i;
   611      sscanf(sentence, "%s %s %s %d", header, str, temp, &i);
   612      printf("Header: %s\n", header);
   613      is_eq(i, 12);
   614      is_streq(str, "Rudolph");
   615  }
   616  
   617  void test_FILE()
   618  {
   619      FILE* p = stdout;
   620      is_true(p != stderr);
   621      is_true(p == stdout);
   622      (void)p;
   623  }
   624  
   625  void WriteFormatted(const char* format, ...)
   626  {
   627      va_list args;
   628      va_start(args, format);
   629      vprintf(format, args);
   630      va_end(args);
   631  }
   632  
   633  void test_vprintf()
   634  {
   635      WriteFormatted("Call with %d variable argument.\n", 1);
   636      WriteFormatted("Call with %d variable %s.\n", 2, "arguments");
   637  }
   638  
   639  void FWriteFormatted(FILE* stream, const char* format, ...)
   640  {
   641      va_list args;
   642      va_start(args, format);
   643      vfprintf(stream, format, args);
   644      va_end(args);
   645  }
   646  
   647  void test_vfprintf()
   648  {
   649      FILE* pFile;
   650      pFile = fopen("./testdata/vfprintf.txt", "w");
   651      FWriteFormatted(pFile, "Call with %d variable argument.\n", 1);
   652      FWriteFormatted(pFile, "Call with %d variable %s.\n", 2, "arguments");
   653      fclose(pFile);
   654  }
   655  
   656  void test_setbuf()
   657  {
   658      char buffer[BUFSIZ];
   659      FILE *pFile1, *pFile2;
   660  
   661      pFile1 = fopen("./testdata/setbuf.txt", "w");
   662      pFile2 = fopen("./testdata/setbuf2.txt", "a");
   663  
   664      setbuf(pFile1, buffer);
   665      fputs("This is sent to a buffered stream", pFile1);
   666      fflush(pFile1);
   667  
   668      setbuf(pFile2, NULL);
   669      fputs("This is sent to an unbuffered stream", pFile2);
   670  
   671      fclose(pFile1);
   672      fclose(pFile2);
   673      (void)(buffer);
   674  }
   675  
   676  void test_setvbuf()
   677  {
   678      FILE* pFile;
   679      pFile = fopen("./testdata/detvbuf.txt", "w");
   680      setvbuf(pFile, NULL, _IOFBF, 1024);
   681      fclose(pFile);
   682  }
   683  
   684  int main()
   685  {
   686      plan(71);
   687  
   688      START_TEST(putchar);
   689      START_TEST(puts);
   690      START_TEST(printf);
   691      START_TEST(remove);
   692      START_TEST(rename);
   693      START_TEST(fopen);
   694      START_TEST(tmpfile);
   695      START_TEST(tmpnam);
   696      START_TEST(fclose);
   697      START_TEST(fflush);
   698      START_TEST(printf);
   699      START_TEST(fprintf);
   700      START_TEST(fscanf);
   701      START_TEST(fgetc);
   702      START_TEST(fgets);
   703      START_TEST(fputc);
   704      START_TEST(fputs);
   705      START_TEST(getc);
   706      START_TEST(putc);
   707      START_TEST(fseek);
   708      START_TEST(ftell);
   709      START_TEST(fread);
   710      START_TEST(fwrite);
   711      START_TEST(fgetpos);
   712      START_TEST(fsetpos);
   713      START_TEST(rewind);
   714      START_TEST(feof);
   715      START_TEST(sprintf);
   716      START_TEST(snprintf);
   717      START_TEST(vsprintf);
   718      START_TEST(vsnprintf);
   719      START_TEST(eof);
   720      START_TEST(getline);
   721      START_TEST(sscanf);
   722      START_TEST(FILE);
   723      START_TEST(vprintf);
   724      START_TEST(vfprintf);
   725      START_TEST(setbuf);
   726      START_TEST(setvbuf);
   727  
   728      // that test must be last test
   729      START_TEST(perror);
   730  
   731      done_testing();
   732  }