1 /* Test of filtering of data through a subprocess.
2 Copyright (C) 2009-2025 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2009.
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.
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.
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/>. */
20 #include "pipe-filter.h"
22 #include "binary-io.h"
24 #include "read-file.h"
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. */
42 prepare_write (size_t *num_bytes_p
, void *private_data
)
44 struct locals
*l
= (struct locals
*) private_data
;
45 if (l
->nwritten
< l
->size
)
47 *num_bytes_p
= l
->size
- l
->nwritten
;
48 return l
->input
+ l
->nwritten
;
55 done_write (void *data_written
, size_t num_bytes_written
, void *private_data
)
57 struct locals
*l
= (struct locals
*) private_data
;
58 l
->nwritten
+= num_bytes_written
;
62 prepare_read (size_t *num_bytes_p
, void *private_data
)
64 struct locals
*l
= (struct locals
*) private_data
;
65 *num_bytes_p
= sizeof (l
->buf
);
70 done_read (void *data_read
, size_t num_bytes_read
, void *private_data
)
72 struct locals
*l
= (struct locals
*) private_data
;
73 const char *p
= l
->input
+ l
->nread
;
74 const char *q
= (const char *) data_read
;
77 for (i
= 0; i
< num_bytes_read
; i
++, q
++)
79 /* Handle conversion NL -> CRLF possibly done by the child process. */
80 if (!(O_BINARY
&& *q
== '\r'))
83 char expected
= c_toupper (orig
);
84 ASSERT (*q
== expected
);
88 l
->nread
= p
- l
->input
;
92 main (int argc
, char *argv
[])
94 const char *tr_program
;
95 const char *input_filename
;
101 tr_program
= argv
[1];
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
);
108 /* Convert it to uppercase, line by line. */
110 const char *tr_argv
[4];
119 tr_argv
[0] = tr_program
;
120 tr_argv
[1] = "abcdefghijklmnopqrstuvwxyz";
121 tr_argv
[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
124 result
= pipe_filter_ii_execute ("tr", tr_program
, tr_argv
, false, true,
125 prepare_write
, done_write
,
126 prepare_read
, done_read
,
128 ASSERT (result
== 0);
129 ASSERT (l
.nwritten
== input_size
);
130 ASSERT (l
.nread
== input_size
);
135 return test_exit_status
;