(root)/
coreutils-9.4/
gnulib-tests/
test-getndelim2.c
       1  /* Test of getndelim2() function.
       2     Copyright (C) 2008-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Eric Blake <ebb9@byu.net>, 2008.  */
      18  
      19  #include <config.h>
      20  
      21  #include "getndelim2.h"
      22  
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  
      27  #include "macros.h"
      28  
      29  int
      30  main (void)
      31  {
      32    FILE *f;
      33    char *line = NULL;
      34    size_t len = 0;
      35    ssize_t result;
      36  
      37    /* Create test file.  */
      38    f = fopen ("test-getndelim2.txt", "wb+");
      39    if (!f || fwrite ("a\nbc\nd\0f", 1, 8, f) != 8)
      40      {
      41        fputs ("Failed to create sample file.\n", stderr);
      42        remove ("test-getndelim2.txt");
      43        return 1;
      44      }
      45    rewind (f);
      46  
      47    /* Unlimited lines.  */
      48  
      49    /* Test initial allocation, which must include trailing NUL.  */
      50    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', '\n', f);
      51    ASSERT (result == 2);
      52    ASSERT (strcmp (line, "a\n") == 0);
      53    ASSERT (2 < len);
      54  
      55    /* Test growth of buffer, must not leak.  */
      56    free (line);
      57    line = malloc (1);
      58    len = 0;
      59    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, EOF, '\n', f);
      60    ASSERT (result == 3);
      61    ASSERT (strcmp (line, "bc\n") == 0);
      62    ASSERT (3 < len);
      63  
      64    /* Test embedded NULs and EOF behavior.  */
      65    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', EOF, f);
      66    ASSERT (result == 3);
      67    ASSERT (memcmp (line, "d\0f", 4) == 0);
      68    ASSERT (3 < len);
      69  
      70    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', EOF, f);
      71    ASSERT (result == -1);
      72  
      73    /* Using offset and nmax.  */
      74  
      75    /* Limit growth to four bytes, including NUL, but parse to next 'd'.  */
      76    free (line);
      77    rewind (f);
      78    line = malloc (8);
      79    memset (line, 'e', 8);
      80    len = 8;
      81    result = getndelim2 (&line, &len, 6, 10, 'd', 'd', f);
      82    ASSERT (result == 3);
      83    ASSERT (10 == len);
      84    ASSERT (strcmp (line, "eeeeeea\nb") == 0);
      85  
      86    /* No change if offset larger than limit.  */
      87    result = getndelim2 (&line, &len, len, 1, EOF, EOF, f);
      88    ASSERT (result == -1);
      89    ASSERT (10 == len);
      90    ASSERT (strcmp (line, "eeeeeea\nb") == 0);
      91  
      92    /* Consume to end of file, including embedded NUL.  */
      93    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, EOF, EOF, f);
      94    ASSERT (result == 2);
      95    ASSERT (10 == len);
      96    ASSERT (memcmp (line, "\0f\0eeea\nb", 10) == 0);
      97  
      98    result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', '\r', f);
      99    ASSERT (result == -1);
     100  
     101    /* Larger file size.  */
     102    rewind (f);
     103    {
     104      int i;
     105      for (i = 0; i < 16; i++)
     106        fprintf (f, "%500x%c", i + 0u, i % 2 ? '\n' : '\r');
     107    }
     108    rewind (f);
     109    {
     110      char buffer[502];
     111  
     112      result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', '\r', f);
     113      ASSERT (result == 501);
     114      ASSERT (501 < len);
     115      memset (buffer, ' ', 499);
     116      buffer[499] = '0';
     117      buffer[500] = '\r';
     118      buffer[501] = '\0';
     119      ASSERT (strcmp (buffer, line) == 0);
     120  
     121      result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, '\n', '\r', f);
     122      ASSERT (result == 501);
     123      ASSERT (501 < len);
     124      buffer[499] = '1';
     125      buffer[500] = '\n';
     126      ASSERT (strcmp (buffer, line) == 0);
     127  
     128      result = getndelim2 (&line, &len, 0, GETNLINE_NO_LIMIT, 'g', 'f', f);
     129      ASSERT (result == 501 * 14 - 1);
     130      ASSERT (501 * 14 <= len);
     131      buffer[499] = 'f';
     132      buffer[500] = '\0';
     133      ASSERT (strcmp (buffer, line + 501 * 13) == 0);
     134  
     135      result = getndelim2 (&line, &len, 501 * 14 - 1, GETNLINE_NO_LIMIT,
     136                           EOF, EOF, f);
     137      ASSERT (result == 1);
     138      buffer[500] = '\n';
     139      ASSERT (strcmp (buffer, line + 501 * 13) == 0);
     140  
     141      result = getndelim2 (&line, &len, 501 * 14 - 1, GETNLINE_NO_LIMIT,
     142                           EOF, EOF, f);
     143      buffer[500] = '\0';
     144      ASSERT (strcmp (buffer, line + 501 * 13) == 0);
     145      ASSERT (result == -1);
     146    }
     147  
     148    fclose (f);
     149    remove ("test-getndelim2.txt");
     150    return 0;
     151  }