. "$BST_LIB" require dos2unix dos2unix/present t=${TMPDIR:-/tmp}/bst-dos2unix.$$ rm -rf "$t"; mkdir -p "$t" || { bst_notok dos2unix/scratch "cannot create $t"; exit 0; } cd "$t" || { bst_notok dos2unix/scratch "cannot cd $t"; exit 0; } # Reference payloads. Every assertion below compares bytes against one of these # rather than eyeballing a message, so a conversion that half-works still fails. printf 'a\r\nb\r\n' > dos.in # 6 bytes, two CRLF printf 'a\nb\n' > unix.exp # 4 bytes, two LF printf 'a\rb\r' > mac.exp # 4 bytes, two lone CR # --- the four spellings are all present --------------------------------------- for tool in unix2dos mac2unix unix2mac; do if command -v "$tool" >/dev/null 2>&1; then bst_ok "dos2unix/have-$tool" else bst_notok "dos2unix/have-$tool" "$tool missing from the image"; fi done # --- identity ----------------------------------------------------------------- check_out dos2unix/version "dos2unix 7.5.2" dos2unix --version check_out dos2unix/version-unix2dos "unix2dos 7.5.2" unix2dos --version check_out dos2unix/version-mac2unix "mac2unix 7.5.2" mac2unix --version check_out dos2unix/utf16-supported "UTF-16" dos2unix --version check_out dos2unix/license "Erwin Waterlander" dos2unix -L # --- core conversions --------------------------------------------------------- cp dos.in c1.txt dos2unix c1.txt 2>/dev/null check dos2unix/dos-to-unix cmp c1.txt unix.exp cp unix.exp c2.txt unix2dos c2.txt 2>/dev/null check dos2unix/unix-to-dos cmp c2.txt dos.in cp mac.exp c3.txt mac2unix c3.txt 2>/dev/null check dos2unix/mac-to-unix cmp c3.txt unix.exp cp unix.exp c4.txt unix2mac c4.txt 2>/dev/null check dos2unix/unix-to-mac cmp c4.txt mac.exp # -c mac must equal the mac2unix spelling cp mac.exp c5.txt dos2unix -c mac c5.txt 2>/dev/null check dos2unix/convmode-mac cmp c5.txt unix.exp # mac2unix converts a LONE CR only — a CRLF file must come back untouched. # This is what separates a real Mac mode from an alias that just does DOS. cp dos.in c6.txt mac2unix c6.txt 2>/dev/null check dos2unix/mac-leaves-crlf cmp c6.txt dos.in # --- conversion is stable and reversible -------------------------------------- cp dos.in c7.txt dos2unix c7.txt 2>/dev/null; cp c7.txt c7.once dos2unix c7.txt 2>/dev/null check dos2unix/idempotent cmp c7.txt c7.once cp unix.exp c8.txt unix2dos c8.txt 2>/dev/null dos2unix c8.txt 2>/dev/null check dos2unix/roundtrip cmp c8.txt unix.exp # --- output modes ------------------------------------------------------------- cp dos.in n1.in dos2unix -n n1.in n1.out 2>/dev/null check dos2unix/newfile-output cmp n1.out unix.exp check dos2unix/newfile-input-intact cmp n1.in dos.in cp dos.in o1.txt dos2unix -O o1.txt > o1.out 2>/dev/null check dos2unix/to-stdout cmp o1.out unix.exp check dos2unix/to-stdout-intact cmp o1.txt dos.in printf 'x\r\n' > o2.txt; printf 'y\r\n' > o3.txt dos2unix -O o2.txt o3.txt > o23.out 2>/dev/null printf 'x\ny\n' > o23.exp check dos2unix/to-stdout-multi cmp o23.out o23.exp dos2unix < dos.in > s1.out 2>/dev/null check dos2unix/stdin-filter cmp s1.out unix.exp cp dos.in m1.txt; cp dos.in m2.txt dos2unix m1.txt m2.txt 2>/dev/null check dos2unix/multifile-1 cmp m1.txt unix.exp check dos2unix/multifile-2 cmp m2.txt unix.exp # --- -i / --info reporting ---------------------------------------------------- # Fields are: printf 'a\r\nb\nc\r\n' > i1.txt check_eq dos2unix/info-dos-count 2 "$(dos2unix -i i1.txt | awk '{print $1}')" check_eq dos2unix/info-unix-count 1 "$(dos2unix -i i1.txt | awk '{print $2}')" check_eq dos2unix/info-mac-count 0 "$(dos2unix -i i1.txt | awk '{print $3}')" check_eq dos2unix/info-bom no_bom "$(dos2unix -i i1.txt | awk '{print $4}')" check_eq dos2unix/info-type-text text "$(dos2unix -i i1.txt | awk '{print $5}')" check_eq dos2unix/info-unix-only 0 "$(dos2unix -i unix.exp | awk '{print $1}')" check_eq dos2unix/info-du-fields 2 "$(dos2unix -idu i1.txt | awk '{print NF-1}')" # -ic lists only files that WOULD be converted: a DOS file, never a Unix one. check_eq dos2unix/info-convertible i1.txt "$(dos2unix -ic i1.txt)" check_eq dos2unix/info-not-convertible "" "$(dos2unix -ic unix.exp)" # --- byte-order marks --------------------------------------------------------- printf '\357\273\277' > bom.bytes cp unix.exp b1.txt unix2dos -m b1.txt 2>/dev/null head -c 3 b1.txt > b1.head check dos2unix/add-bom cmp b1.head bom.bytes dos2unix -r b1.txt 2>/dev/null check dos2unix/remove-bom cmp b1.txt unix.exp printf '\357\273\277a\r\n' > b2.txt printf '\357\273\277a\n' > b2.exp dos2unix -b b2.txt 2>/dev/null check dos2unix/keep-bom cmp b2.txt b2.exp # --- line-ending extras ------------------------------------------------------- printf 'a\r\nb' > e1.txt printf 'a\nb\n' > e1.exp dos2unix -e e1.txt 2>/dev/null check dos2unix/add-eol cmp e1.txt e1.exp # -e must not double a newline that is already there cp dos.in e2.txt dos2unix -e e2.txt 2>/dev/null check dos2unix/add-eol-no-double cmp e2.txt unix.exp cp dos.in l1.txt printf 'a\n\nb\n\n' > l1.exp dos2unix -l l1.txt 2>/dev/null check dos2unix/add-newline cmp l1.txt l1.exp # --- binary safety ------------------------------------------------------------ printf 'a\r\n\000\001b\r\n' > bin.in cp bin.in bin1.bin check_out dos2unix/binary-skip-msg "Skipping binary file" dos2unix bin1.bin check dos2unix/binary-unchanged cmp bin1.bin bin.in cp bin.in bin2.bin printf 'a\n\000\001b\n' > bin.exp dos2unix -f bin2.bin 2>/dev/null check dos2unix/binary-forced cmp bin2.bin bin.exp check_eq dos2unix/info-type-binary binary "$(dos2unix -i bin.in | awk '{print $5}')" # --- symbolic links ----------------------------------------------------------- cp dos.in y1.tgt; ln -sf y1.tgt y1.lnk check_out dos2unix/symlink-skip-msg "Skipping symbolic link" dos2unix y1.lnk check dos2unix/symlink-target-intact cmp y1.tgt dos.in if [ -L y1.lnk ]; then bst_ok dos2unix/symlink-preserved else bst_notok dos2unix/symlink-preserved "-S default replaced the link"; fi cp dos.in y2.tgt; ln -sf y2.tgt y2.lnk dos2unix -F y2.lnk 2>/dev/null check dos2unix/symlink-follow cmp y2.tgt unix.exp # --- diagnostics and exit status ---------------------------------------------- check_rc dos2unix/missing-file-rc 2 dos2unix "$t/no-such-file-xyz" check_out dos2unix/missing-file-msg "No such file or directory" \ sh -c "dos2unix '$t/no-such-file-xyz' 2>&1; exit 0" check_rc dos2unix/bad-option-rc 1 dos2unix --bogus-option-xyz check_out dos2unix/help-usage "Usage: dos2unix" dos2unix --help # A missing operand must not stop the files that are fine. cp dos.in p1.txt dos2unix p1.txt "$t/no-such-file-xyz" >/dev/null 2>&1 check dos2unix/partial-still-converts cmp p1.txt unix.exp # --- character-set conversion -------------------------------------------------- # -7 maps every 8-bit byte into the 7-bit space: 0xE9 becomes 0x20. printf 'caf\351\r\n' > x1.txt printf 'caf \n' > x1.exp dos2unix -7 x1.txt 2>/dev/null check dos2unix/seven-bit cmp x1.txt x1.exp # CP1252 -> ISO-8859-1 agree on 0xE9, so only the line ending changes. printf 'caf\351\r\n' > x2.txt printf 'caf\351\n' > x2.exp dos2unix -iso -1252 x2.txt 2>/dev/null check dos2unix/iso-1252 cmp x2.txt x2.exp # --- UTF-16 ------------------------------------------------------------------- printf 'a\000\r\000\n\000b\000\r\000\n\000' > u1.txt check_out dos2unix/utf16le-msg "UTF-16LE" dos2unix -ul u1.txt check dos2unix/utf16le-to-utf8 cmp u1.txt unix.exp # A UTF-16LE BOM is detected without being told the encoding. printf '\377\376a\000\r\000\n\000' > u2.txt printf 'a\n' > u2.exp dos2unix u2.txt 2>/dev/null check dos2unix/utf16le-autodetect cmp u2.txt u2.exp # --- misc --------------------------------------------------------------------- # -k keeps the timestamp; the A/B against an unkept conversion is what makes # this meaningful rather than a clock-resolution accident. printf 'a\r\n' > k1.txt; printf 'a\r\n' > k2.txt touch -t 202001010000 k1.txt k2.txt cp -p k1.txt k.ref dos2unix -k k1.txt 2>/dev/null dos2unix k2.txt 2>/dev/null if [ ! k1.txt -nt k.ref ]; then bst_ok dos2unix/keepdate else bst_notok dos2unix/keepdate "-k did not preserve the mtime"; fi if [ k2.txt -nt k.ref ]; then bst_ok dos2unix/keepdate-ab else bst_notok dos2unix/keepdate-ab "a normal conversion did not update the mtime either"; fi check_eq dos2unix/quiet "" "$(dos2unix -q bin.in 2>&1)" check_out dos2unix/verbose "line breaks" sh -c "cp '$t/dos.in' '$t/v1.txt'; dos2unix -v '$t/v1.txt' 2>&1" : > z1.txt check dos2unix/empty-file dos2unix z1.txt check_eq dos2unix/empty-stays-empty 0 "$(wc -c < z1.txt | tr -d ' ')" cd / rm -rf "$t"