1#!/bin/sh
2# test splitting into newline delineated chunks (-n l/...)
3
4# Copyright (C) 2010-2023 Free Software Foundation, Inc.
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
20print_ver_ split
21
22# invalid number of chunks
23echo "split: invalid number of chunks: '1o'" > exp
24returns_ 1 split -n l/1o 2>err || fail=1
25compare exp err || fail=1
26
27rm -f x* || fail=1
28: | split -n l/1 || fail=1
29compare /dev/null xaa || fail=1
30test ! -f xab || fail=1
31
32# N can be greater than the file size
33# in which case no data is extracted, or empty files are written
34split -n l/10 /dev/null || fail=1
35test "$(stat -c %s x* | uniq -c | sed 's/^ *//; s/ /x/')" = "10x0" || fail=1
36rm x??
37
38# Ensure --elide-empty-files is honored
39split -e -n l/10 /dev/null || fail=1
40returns_ 1 stat x?? 2>/dev/null || fail=1
41
42# 80 bytes. ~ transformed to \n below
43lines=\
4412345~1~12345~1~12345~1~12345~1~12345~~~12345~1~12345~1~12345~1~12345~1~12345~1~
45
46printf "%s" "$lines" | tr '~' '\n' > in || framework_failure_
47
48echo "split: invalid chunk number: '16'" > exp
49returns_ 1 split -n l/16/15 in 2>err.t || fail=1
50sed "s/': .*/'/" < err.t > err || framework_failure_
51compare exp err || fail=1
52
53printf '%s' "\
5414 16 16 08 16 10
5514 08 08 10 14 08 08 10
5608 06 08 08 08 08 08 02 06 08 08 02
5706 08 08 02 06 08 02 06 08 02 06 08 00 08 02
5806 02 06 02 06 02 06 02 06 02 06 02 06 02 06 00 08 00 02 06 00 02
59" > exp || framework_failure_
60
61sed 's/00 *//g' exp > exp.elide_empty || framework_failure_
62
63test "$DEBUG" && test "$VERBOSE" && set +x
64for ELIDE_EMPTY in '' '-e'; do
65  for IO_BLKSIZE in 1 2 5 10 80 100; do
66    > out
67    test "$DEBUG" && printf "\n---io-blk-size=$IO_BLKSIZE $ELIDE_EMPTY\n"
68    for N in 6 8 12 15 22; do
69      rm -f x*
70
71      if test -z "$ELIDE_EMPTY"; then
72        split ---io-blksize=$IO_BLKSIZE -n l/2/$N in > chunk.k
73        returns_ 1 stat x* 2>/dev/null || fail=1
74      fi
75
76      split ---io-blksize=$IO_BLKSIZE $ELIDE_EMPTY -n l/$N in
77      echo $(stat -c "%02s" x*) >> out
78
79      if test -z "$ELIDE_EMPTY"; then
80        compare chunk.k xab || fail=1
81      fi
82
83      if test "$DEBUG"; then
84        # Output partition pattern
85        size=$(printf "%s" "$lines" | wc -c)
86        chunk_size=$(($size/$N))
87        end_size=$(($chunk_size + ($size % $N)))
88        {
89          yes "$(printf %${chunk_size}s ])" | head -n$(($N-1))
90          printf %${end_size}s ]
91        } | tr -d '\n' | sed "s/\\(^.\\{1,$size\\}\\).*/\\1/"
92        echo
93
94        # Output pattern generated for comparison
95        for s in $(stat -c "%s" x*); do
96          #s=0 transitions are not shown
97          test "$m" = "_" && m=- || m=_
98          printf "%${s}s" '' | tr ' ' $m
99        done
100        echo
101
102        # Output lines for reference
103        echo "$lines"
104      fi
105    done
106    test -z "$ELIDE_EMPTY" && EXP=exp || EXP=exp.elide_empty
107    compare out $EXP || fail=1
108  done
109done
110test "$DEBUG" && test "$VERBOSE" && set -x
111
112
113# Check extraction of particular chunks
114split -n l/13/15 in > out &&
115compare /dev/null out || fail=1
116printf '1\n12345\n' > exp || framework_failure_
117split -n l/14/15 in > out &&
118compare exp out || fail=1
119printf '1\n' > exp || framework_failure_
120split -n l/15/15 in > out &&
121compare exp out || fail=1
122
123# test input with no \n at end
124printf '12\n34\n5' > in
125printf '5' > exp
126split -n l/7/7 in > out
127compare exp out || fail=1
128
129Exit $fail
130