(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
test-pipe-filter-ii1.c
       1  /* Test of filtering of data through a subprocess.
       2     Copyright (C) 2009-2023 Free Software Foundation, Inc.
       3     Written by Bruno Haible <haible@clisp.cons.org>, 2009.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <config.h>
      19  
      20  #include "pipe-filter.h"
      21  
      22  #include "binary-io.h"
      23  #include "c-ctype.h"
      24  #include "read-file.h"
      25  #include "macros.h"
      26  
      27  
      28  /* Pipe a text file through 'LC_ALL=C tr "[a-z]" "[A-Z]"', or equivalently,
      29     'tr "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"', which
      30     converts ASCII characters from lower case to upper case.  */
      31  
      32  struct locals
      33  {
      34    const char *input;
      35    size_t size;
      36    size_t nwritten;
      37    size_t nread;
      38    char buf[19];
      39  };
      40  
      41  static const void *
      42  prepare_write (size_t *num_bytes_p, void *private_data)
      43  {
      44    struct locals *l = (struct locals *) private_data;
      45    if (l->nwritten < l->size)
      46      {
      47        *num_bytes_p = l->size - l->nwritten;
      48        return l->input + l->nwritten;
      49      }
      50    else
      51      return NULL;
      52  }
      53  
      54  static void
      55  done_write (void *data_written, size_t num_bytes_written, void *private_data)
      56  {
      57    struct locals *l = (struct locals *) private_data;
      58    l->nwritten += num_bytes_written;
      59  }
      60  
      61  static void *
      62  prepare_read (size_t *num_bytes_p, void *private_data)
      63  {
      64    struct locals *l = (struct locals *) private_data;
      65    *num_bytes_p = sizeof (l->buf);
      66    return l->buf;
      67  }
      68  
      69  static void
      70  done_read (void *data_read, size_t num_bytes_read, void *private_data)
      71  {
      72    struct locals *l = (struct locals *) private_data;
      73    const char *p = l->input + l->nread;
      74    const char *q = (const char *) data_read;
      75    size_t i;
      76  
      77    for (i = 0; i < num_bytes_read; i++, q++)
      78      {
      79        /* Handle conversion NL -> CRLF possibly done by the child process.  */
      80        if (!(O_BINARY && *q == '\r'))
      81          {
      82            char orig = *p;
      83            char expected = c_toupper (orig);
      84            ASSERT (*q == expected);
      85            p++;
      86          }
      87      }
      88    l->nread = p - l->input;
      89  }
      90  
      91  int
      92  main (int argc, char *argv[])
      93  {
      94    const char *tr_program;
      95    const char *input_filename;
      96    size_t input_size;
      97    char *input;
      98  
      99    ASSERT (argc == 3);
     100  
     101    tr_program = argv[1];
     102  
     103    /* Read some text from a file.  */
     104    input_filename = argv[2];
     105    input = read_file (input_filename, RF_BINARY, &input_size);
     106    ASSERT (input != NULL);
     107  
     108    /* Convert it to uppercase, line by line.  */
     109    {
     110      const char *tr_argv[4];
     111      struct locals l;
     112      int result;
     113  
     114      l.input = input;
     115      l.size = input_size;
     116      l.nwritten = 0;
     117      l.nread = 0;
     118  
     119      tr_argv[0] = tr_program;
     120      tr_argv[1] = "abcdefghijklmnopqrstuvwxyz";
     121      tr_argv[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     122      tr_argv[3] = NULL;
     123  
     124      result = pipe_filter_ii_execute ("tr", tr_program, tr_argv, false, true,
     125                                       prepare_write, done_write,
     126                                       prepare_read, done_read,
     127                                       &l);
     128      ASSERT (result == 0);
     129      ASSERT (l.nwritten == input_size);
     130      ASSERT (l.nread == input_size);
     131    }
     132  
     133    free (input);
     134  
     135    return 0;
     136  }