Tests for module 'pipe-filter-gi'.
[gnulib.git] / tests / test-pipe-filter-gi1.c
1 /* Test of filtering of data through a subprocess.
2    Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include "pipe-filter.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "binary-io.h"
26 #include "c-ctype.h"
27 #include "read-file.h"
28 #include "progname.h"
29
30 #define ASSERT(expr) \
31   do                                                                         \
32     {                                                                        \
33       if (!(expr))                                                           \
34         {                                                                    \
35           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
36           fflush (stderr);                                                   \
37           abort ();                                                          \
38         }                                                                    \
39     }                                                                        \
40   while (0)
41
42
43 /* Pipe a text file through 'tr a-z A-Z', which converts ASCII characters from
44    lower case to upper case.  */
45
46 struct locals
47 {
48   const char *input;
49   size_t nread;
50   char buf[19];
51 };
52
53 static void *
54 prepare_read (size_t *num_bytes_p, void *private_data)
55 {
56   struct locals *l = (struct locals *) private_data;
57   *num_bytes_p = sizeof (l->buf);
58   return l->buf;
59 }
60
61 static void
62 done_read (void *data_read, size_t num_bytes_read, void *private_data)
63 {
64   struct locals *l = (struct locals *) private_data;
65   const char *p = l->input + l->nread;
66   const char *q = (const char *) data_read;
67   size_t i;
68
69   for (i = 0; i < num_bytes_read; i++, q++)
70     {
71       /* Handle conversion NL -> CRLF possibly done by the child process.  */
72       if (!(O_BINARY && *q == '\r'))
73         {
74           char orig = *p;
75           char expected = c_toupper (orig);
76           ASSERT (*q == expected);
77           p++;
78         }
79     }
80   l->nread = p - l->input;
81 }
82
83 int
84 main (int argc, char *argv[])
85 {
86   const char *input_filename;
87   size_t input_size;
88   char *input;
89
90   set_program_name (argv[0]);
91
92   ASSERT (argc == 2);
93
94   /* Read some text from a file.  */
95   input_filename = argv[1];
96   input = read_binary_file (input_filename, &input_size);
97   ASSERT (input != NULL);
98
99   /* Convert it to uppercase, line by line.  */
100   {
101     const char *argv[4];
102     struct locals l;
103     struct pipe_filter_gi *f;
104     int result;
105
106     l.input = input;
107     l.nread = 0;
108
109     argv[0] = "tr";
110     argv[1] = "a-z";
111     argv[2] = "A-Z";
112     argv[3] = NULL;
113
114     f = pipe_filter_gi_create ("tr", "tr", argv, false, true,
115                                prepare_read, done_read, &l);
116     ASSERT (f != NULL);
117     result = pipe_filter_gi_write (f, input, input_size);
118     ASSERT (result == 0);
119     result = pipe_filter_gi_close (f);
120     ASSERT (result == 0);
121     ASSERT (l.nread == input_size);
122   }
123
124   return 0;
125 }