Ticket #4217: remove OS/distro-specific stuff.
[midnight-commander.git] / tests / lib / utilunix__mc_pstream_get_string.c
bloba942d1ee419154f10014e206aea043480486193a
1 /*
2 lib - Read string from mc_pipe_stream
4 Copyright (C) 2021
5 Free Software Foundation, Inc.
7 Written by:
8 Andrew Borodin <aborodin@vmail.ru>, 2021
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #define TEST_SUITE_NAME "/lib/util"
28 #include "tests/mctest.h"
30 #include "lib/util.h"
32 /* --------------------------------------------------------------------------------------------- */
34 #define MAX_CHUNKS 8
36 /* --------------------------------------------------------------------------------------------- */
38 static mc_pipe_stream_t stream;
40 static char etalon_long_file_list[BUF_1K];
41 static size_t etalon_long_file_list_pos;
43 /* --------------------------------------------------------------------------------------------- */
45 /* @Before */
46 static void
47 setup (void)
51 /* @After */
52 static void
53 teardown (void)
57 /* --------------------------------------------------------------------------------------------- */
59 /* @DataSource("data_source") */
60 /* *INDENT-OFF* */
61 static const struct data_source
63 /* input */
64 const char *buf; /* string to read */
66 /* output */
67 int pos[MAX_CHUNKS]; /* ps.pos values */
68 const char *str[MAX_CHUNKS]; /* chunks */
69 size_t len[MAX_CHUNKS]; /* chunk lengths */
71 data_source[] =
73 /* 0 */
75 .buf = "",
76 .pos = { 0 },
77 .str = { "" },
78 .len = { 0 }
80 /* 1 */
82 .buf = "\n",
83 .pos = { 0, 1 },
84 .str = { "\n" },
85 .len = { 1, 0 }
87 /* 2 */
89 .buf = "\\\n",
90 .pos = { 0, 2 },
91 .str = { "\\\n" },
92 .len = { 2, 0 }
94 /* 3 */
96 .buf = "\\\\\n",
97 .pos = { 0, 3 },
98 .str = { "\\\\\n" },
99 .len = { 3, 0 }
101 /* 4 */
103 .buf = "\\\\\\\n",
104 .pos = { 0, 4 },
105 .str = { "\\\\\\\n" },
106 .len = { 4, 0 }
108 /* 5 */
110 .buf = "\\\\\\\\\n",
111 .pos = { 0, 5 },
112 .str = { "\\\\\\\\\n" },
113 .len = { 5, 0 }
115 /* 6 */
117 .buf = "12345",
118 .pos = { 0, 5 },
119 .str = { "12345" },
120 .len = { 5, 0 }
122 /* 7 */
124 .buf = "12345\n",
125 .pos = { 0, 6 },
126 .str = { "12345\n" },
127 .len = { 6, 0 }
129 /* 8 */
131 .buf = "12345\\\n",
132 .pos = { 0, 7 },
133 .str = { "12345\\\n" },
134 .len = { 7, 0 }
136 /* 9 */
138 .buf = "12345\\\\\n",
139 .pos = { 0, 8 },
140 .str = { "12345\\\\\n" },
141 .len = { 8, 0 }
143 /* 10 */
145 .buf = "12345\nabcd",
146 .pos = { 0, 6, 10 },
147 .str = { "12345\n", "abcd" },
148 .len = { 6, 4, 0 }
150 /* 11 */
152 .buf = "12345\\\nabcd",
153 .pos = { 0, 11 },
154 .str = { "12345\\\nabcd" },
155 .len = { 11, 0 }
157 /* 12 */
159 .buf = "12345\\\\\nabcd",
160 .pos = { 0, 8, 12 },
161 .str = { "12345\\\\\n", "abcd" },
162 .len = { 8, 4, 0 }
164 /* 13 */
166 .buf = "12345\\\\\\\nabcd",
167 .pos = { 0, 13 },
168 .str = { "12345\\\\\\\nabcd" },
169 .len = { 13, 0 }
171 /* 14 */
173 .buf = "12345\\\\\\\\\nabcd",
174 .pos = { 0, 10, 14 },
175 .str = { "12345\\\\\\\\\n", "abcd" },
176 .len = { 10, 4, 0 }
178 /* 15 */
180 .buf = "12345\nabcd\n",
181 .pos = { 0, 6, 11 },
182 .str = { "12345\n", "abcd\n" },
183 .len = { 6, 5, 0 }
185 /* 16 */
187 .buf = "12345\nabcd\n~!@#$%^",
188 .pos = { 0, 6, 11, 18 },
189 .str = { "12345\n", "abcd\n", "~!@#$%^" },
190 .len = { 6, 5, 7, 0 }
192 /* 17 */
194 .buf = "12345\nabcd\n~!@#$%^\n",
195 .pos = { 0, 6, 11, 19 },
196 .str = { "12345\n", "abcd\n", "~!@#$%^\n" },
197 .len = { 6, 5, 8, 0 }
200 /* *INDENT-ON* */
202 /* @Test(dataSource = "data_source") */
203 /* *INDENT-OFF* */
204 START_PARAMETRIZED_TEST (mc_pstream_get_string_test, data_source)
205 /* *INDENT-ON* */
207 /* given */
208 int j = 0;
210 /* when */
211 memset (&stream, 0, sizeof (stream));
212 stream.len = strlen (data->buf);
213 memmove (&stream.buf, data->buf, stream.len);
215 /* then */
218 GString *ret;
220 mctest_assert_int_eq (stream.pos, data->pos[j]);
222 ret = mc_pstream_get_string (&stream);
223 if (ret == NULL)
224 break;
226 mctest_assert_int_eq (ret->len, data->len[j]);
227 mctest_assert_str_eq (ret->str, data->str[j]);
229 g_string_free (ret, TRUE);
231 j++;
233 while (TRUE);
235 /* *INDENT-OFF* */
236 END_PARAMETRIZED_TEST
237 /* *INDENT-ON* */
239 /* --------------------------------------------------------------------------------------------- */
241 static mc_pipe_t *
242 test_mc_popen (void)
244 mc_pipe_t *p;
246 p = g_try_new0 (mc_pipe_t, 1);
247 /* make less than sizeof (etalon_long_file_list) */
248 p->out.len = 128;
250 etalon_long_file_list_pos = 0;
252 return p;
255 static void
256 test_mc_pread (mc_pipe_t * p)
258 size_t len;
260 p->out.pos = 0;
262 if (etalon_long_file_list_pos >= sizeof (etalon_long_file_list))
264 etalon_long_file_list_pos = sizeof (etalon_long_file_list);
265 p->out.len = MC_PIPE_STREAM_EOF;
266 return;
269 len = sizeof (etalon_long_file_list) - etalon_long_file_list_pos;
270 len = MIN (len, (size_t) p->out.len);
271 memmove (p->out.buf, etalon_long_file_list + etalon_long_file_list_pos, len);
272 p->out.len = (ssize_t) len;
274 etalon_long_file_list_pos += len;
277 /* *INDENT-OFF* */
278 START_TEST (mc_pstream_get_long_file_list_test)
279 /* *INDENT-ON* */
282 /* given */
283 GString *result_long_file_list = NULL;
284 mc_pipe_t *pip;
285 GString *remain_file_name = NULL;
287 /* when */
288 /* fill the list */
289 memset (etalon_long_file_list, 'a', sizeof (etalon_long_file_list) - 1);
290 /* create an \n-separated list */
291 etalon_long_file_list[5] = '\n';
292 etalon_long_file_list[25] = '\n';
293 etalon_long_file_list[50] = '\n';
294 etalon_long_file_list[75] = '\n';
295 etalon_long_file_list[127] = '\n';
296 etalon_long_file_list[200] = '\n';
297 etalon_long_file_list[310] = '\n';
298 etalon_long_file_list[325] = '\n';
299 etalon_long_file_list[360] = '\n';
300 etalon_long_file_list[512] = '\n';
301 etalon_long_file_list[701] = '\n';
302 etalon_long_file_list[725] = '\n';
303 etalon_long_file_list[800] = '\n';
304 etalon_long_file_list[sizeof (etalon_long_file_list) - 2] = '\n';
305 etalon_long_file_list[sizeof (etalon_long_file_list) - 1] = '\0';
307 /* then */
308 /* read file list */
309 pip = test_mc_popen ();
311 while (TRUE)
313 GString *line;
315 test_mc_pread (pip);
317 if (pip->out.len == MC_PIPE_STREAM_EOF)
318 break;
320 while ((line = mc_pstream_get_string (&pip->out)) != NULL)
322 /* handle an \n-separated file list */
324 if (line->str[line->len - 1] == '\n')
326 /* entire file name or last chunk */
328 g_string_truncate (line, line->len - 1);
330 /* join filename chunks */
331 if (remain_file_name != NULL)
333 g_string_append_len (remain_file_name, line->str, line->len);
334 g_string_free (line, TRUE);
335 line = remain_file_name;
336 remain_file_name = NULL;
339 else
341 /* first or middle chunk of file name */
342 if (remain_file_name == NULL)
343 remain_file_name = line;
344 else
346 g_string_append_len (remain_file_name, line->str, line->len);
347 g_string_free (line, TRUE);
350 line = NULL;
353 /* collect file names to assemble the result string */
354 if (line == NULL)
355 continue;
357 if (result_long_file_list == NULL)
358 result_long_file_list = line;
359 else
361 g_string_append_len (result_long_file_list, line->str, line->len);
362 g_string_free (line, TRUE);
365 g_string_append_c (result_long_file_list, '\n');
369 mctest_assert_str_eq (etalon_long_file_list, result_long_file_list->str);
370 g_string_free (result_long_file_list, TRUE);
373 /* *INDENT-OFF* */
374 END_TEST
375 /* *INDENT-ON* */
377 /* --------------------------------------------------------------------------------------------- */
380 main (void)
382 TCase *tc_core;
384 tc_core = tcase_create ("Core");
386 tcase_add_checked_fixture (tc_core, setup, teardown);
388 /* Add new tests here: *************** */
389 mctest_add_parameterized_test (tc_core, mc_pstream_get_string_test, data_source);
390 tcase_add_test (tc_core, mc_pstream_get_long_file_list_test);
391 /* *********************************** */
393 return mctest_run_all (tc_core);
396 /* --------------------------------------------------------------------------------------------- */