diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml deleted file mode 100644 index ee06c498..00000000 --- a/.github/workflows/CICD.yml +++ /dev/null @@ -1,334 +0,0 @@ -name: CICD - -env: - CICD_INTERMEDIATES_DIR: "_cicd-intermediates" - MSRV_FEATURES: "" - -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - tags: - - '*' - -jobs: - crate_metadata: - name: Extract crate metadata - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Extract crate information - id: crate_metadata - run: | - cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT - cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT - cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT - cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT - cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT - outputs: - name: ${{ steps.crate_metadata.outputs.name }} - version: ${{ steps.crate_metadata.outputs.version }} - maintainer: ${{ steps.crate_metadata.outputs.maintainer }} - homepage: ${{ steps.crate_metadata.outputs.homepage }} - msrv: ${{ steps.crate_metadata.outputs.msrv }} - - ensure_cargo_fmt: - name: Ensure 'cargo fmt' has been run - runs-on: ubuntu-20.04 - steps: - - uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt - - uses: actions/checkout@v3 - - run: cargo fmt -- --check - - min_version: - name: Minimum supported rust version - runs-on: ubuntu-20.04 - needs: crate_metadata - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }}) - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ needs.crate_metadata.outputs.msrv }} - components: clippy - - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix) - run: cargo clippy --locked --all-targets ${{ env.MSRV_FEATURES }} - - name: Run tests - run: cargo test --locked ${{ env.MSRV_FEATURES }} - - build: - name: ${{ matrix.job.target }} (${{ matrix.job.os }}) - runs-on: ${{ matrix.job.os }} - needs: crate_metadata - strategy: - fail-fast: false - matrix: - job: - - { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - - { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true } - - { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true } - - { target: i686-pc-windows-msvc , os: windows-2019 } - - { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - - { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } - - { target: x86_64-apple-darwin , os: macos-12 } - - { target: x86_64-pc-windows-gnu , os: windows-2019 } - - { target: x86_64-pc-windows-msvc , os: windows-2019 } - - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } - env: - BUILD_CMD: cargo - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Install prerequisites - shell: bash - run: | - case ${{ matrix.job.target }} in - arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; - aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; - esac - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ matrix.job.target }} - - - name: Install cross - if: matrix.job.use-cross - uses: taiki-e/install-action@v2 - with: - tool: cross - - - name: Overwrite build command env variable - if: matrix.job.use-cross - shell: bash - run: echo "BUILD_CMD=cross" >> $GITHUB_ENV - - - name: Show version information (Rust, cargo, GCC) - shell: bash - run: | - gcc --version || true - rustup -V - rustup toolchain list - rustup default - cargo -V - rustc -V - - - name: Build - shell: bash - run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }} - - - name: Run example - if: ${{ !matrix.job.use-cross }} - shell: bash - run: $BUILD_CMD run --release --target=${{ matrix.job.target }} --example=simple - - - name: Set binary name & path - id: bin - shell: bash - run: | - # Figure out suffix of binary - EXE_suffix="" - case ${{ matrix.job.target }} in - *-pc-windows-*) EXE_suffix=".exe" ;; - esac; - - # Setup paths - BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}" - BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}" - - # Let subsequent steps know where to find the binary - echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT - echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT - - - name: Set testing options - id: test-options - shell: bash - run: | - # test only library unit tests and binary for arm-type targets - unset CARGO_TEST_OPTIONS - unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac; - echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT - - - name: Run tests - shell: bash - run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} - - - name: Setup Pandoc - uses: r-lib/actions/setup-pandoc@v2 - - - name: Generate man page - run: pandoc -s -f markdown -t man -o "doc/${{ needs.crate_metadata.outputs.name }}.1" "doc/${{ needs.crate_metadata.outputs.name }}.1.md" - - - name: Create tarball - id: package - shell: bash - run: | - PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac; - PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }} - PKG_NAME=${PKG_BASENAME}${PKG_suffix} - echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT - - PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package" - ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/" - mkdir -p "${ARCHIVE_DIR}" - - # Binary - cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR" - - # README, LICENSE and CHANGELOG files - cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR" - - # Man page - cp "doc/${{ needs.crate_metadata.outputs.name }}.1" "$ARCHIVE_DIR" - - # base compressed package - pushd "${PKG_STAGING}/" >/dev/null - case ${{ matrix.job.target }} in - *-pc-windows-*) 7z -y a "${PKG_NAME}" "${PKG_BASENAME}"/* | tail -2 ;; - *) tar czf "${PKG_NAME}" "${PKG_BASENAME}"/* ;; - esac; - popd >/dev/null - - # Let subsequent steps know where to find the compressed package - echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT - - - name: Create Debian package - id: debian-package - shell: bash - if: startsWith(matrix.job.os, 'ubuntu') - run: | - COPYRIGHT_YEARS="2018 - "$(date "+%Y") - DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package" - DPKG_DIR="${DPKG_STAGING}/dpkg" - mkdir -p "${DPKG_DIR}" - - DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }} - DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }}-musl - case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-musl ; DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }} ;; esac; - DPKG_VERSION=${{ needs.crate_metadata.outputs.version }} - - unset DPKG_ARCH - case ${{ matrix.job.target }} in - aarch64-*-linux-*) DPKG_ARCH=arm64 ;; - arm-*-linux-*hf) DPKG_ARCH=armhf ;; - i686-*-linux-*) DPKG_ARCH=i686 ;; - x86_64-*-linux-*) DPKG_ARCH=amd64 ;; - *) DPKG_ARCH=notset ;; - esac; - - DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb" - echo "DPKG_NAME=${DPKG_NAME}" >> $GITHUB_OUTPUT - - # Binary - install -Dm755 "${{ steps.bin.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.bin.outputs.BIN_NAME }}" - - # Man page - install -Dm644 'doc/${{ needs.crate_metadata.outputs.name }}.1' "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1" - gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1" - - # README and LICENSE - install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md" - install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT" - install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE" - install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog" - gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog" - - cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" < "${DPKG_DIR}/DEBIAN/control" <> $GITHUB_OUTPUT - - # build dpkg - fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}" - - - name: "Artifact upload: tarball" - uses: actions/upload-artifact@master - with: - name: ${{ steps.package.outputs.PKG_NAME }} - path: ${{ steps.package.outputs.PKG_PATH }} - - - name: "Artifact upload: Debian package" - uses: actions/upload-artifact@master - if: steps.debian-package.outputs.DPKG_NAME - with: - name: ${{ steps.debian-package.outputs.DPKG_NAME }} - path: ${{ steps.debian-package.outputs.DPKG_PATH }} - - - name: Check for release - id: is-release - shell: bash - run: | - unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi - echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT - - - name: Publish archives and packages - uses: softprops/action-gh-release@v1 - if: steps.is-release.outputs.IS_RELEASE - with: - files: | - ${{ steps.package.outputs.PKG_PATH }} - ${{ steps.debian-package.outputs.DPKG_PATH }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..43bec088 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,67 @@ +name: Release + +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+-custom + - v[0-9]+.[0-9]+.[0-9]+-custom-r[0-9]+ + +permissions: + contents: write + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-22.04 + rust-target: x86_64-unknown-linux-musl + - os: macos-12 + rust-target: x86_64-apple-darwin + - os: macos-12 + rust-target: aarch64-apple-darwin + env: + xcode_version: 14.2 + macosx_sdk: macosx13.1 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set RUST_TARGET + run: echo 'RUST_TARGET=${{ matrix.rust-target }}' >> $GITHUB_ENV + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: ${{ matrix.rust-target }} + + - name: Setup Homebrew for Linux + if: matrix.os == 'ubuntu-22.04' + run: echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH + + - name: Setup Pandoc + run: brew install pandoc + + - name: Setup Xcode for macOS + if: matrix.os == 'macos-12' + run: sudo xcode-select -s '/Applications/Xcode_${{ env.xcode_version }}.app' + + - name: Set environment variables for Apple Silicon + if: matrix.rust-target == 'aarch64-apple-darwin' + run: | + export SDKROOT=$(xcrun -sdk ${{ env.macosx_sdk }} --show-sdk-path) + [[ -n $SDKROOT ]] && echo "SDKROOT=$SDKROOT" >> $GITHUB_ENV + export MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk ${{ env.macosx_sdk }} --show-sdk-platform-version) + [[ -n $MACOSX_DEPLOYMENT_TARGET ]] && echo "MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV + + - name: Build + run: make + + - name: Release + uses: ncipollo/release-action@v1 + with: + artifacts: "*.tar.xz" + allowUpdates: true diff --git a/Cargo.lock b/Cargo.lock index 41dcc8e4..9a3c8163 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,15 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "clap_complete" +version = "4.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b3c9eae0de7bf8e3f904a5e40612b21fb2e2e566456d177809a48b892d24da" +dependencies = [ + "clap", +] + [[package]] name = "clap_lex" version = "0.3.0" @@ -205,6 +214,7 @@ dependencies = [ "anyhow", "assert_cmd", "clap", + "clap_complete", "const_format", "libc", "owo-colors", diff --git a/Cargo.toml b/Cargo.toml index a92aab16..102f87f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ owo-colors = "3" supports-color = "1" thiserror = "1.0" terminal_size = "0.2" +clap_complete = "4.0.6" [dependencies.clap] version = "4" @@ -31,5 +32,7 @@ predicates = "2.0" pretty_assertions = "1.3.0" [profile.release] -lto = true codegen-units = 1 +lto = true +opt-level = 3 +strip = true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..de7acdc7 --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +ifeq ($(RUST_TARGET),) + TARGET := + RELEASE_SUFFIX := +else + TARGET := $(RUST_TARGET) + RELEASE_SUFFIX := -$(TARGET) + export CARGO_BUILD_TARGET = $(RUST_TARGET) +endif + +PROJECT_NAME := hexyl + +_HASH := \# +VERSION := $(lastword $(subst @, ,$(subst $(_HASH), ,$(shell cargo pkgid)))) +RELEASE := $(PROJECT_NAME)-$(VERSION)$(RELEASE_SUFFIX) + +DIST_DIR := dist +RELEASE_DIR := $(DIST_DIR)/$(RELEASE) +MANUAL_DIR := $(RELEASE_DIR)/manual + +BINARY := target/$(TARGET)/release/$(PROJECT_NAME) +MAN1 := doc/$(PROJECT_NAME).1 + +RELEASE_BINARY := $(RELEASE_DIR)/$(PROJECT_NAME) +MANUAL := $(MANUAL_DIR)/$(PROJECT_NAME).1 + +ARTIFACT := $(RELEASE).tar.xz + +.PHONY: all +all: $(ARTIFACT) + +$(BINARY): + cargo build --locked --release + +$(MAN1): + pandoc -s -f markdown -t man -o $@ $(@).md + +$(DIST_DIR) $(RELEASE_DIR) $(MANUAL_DIR): + mkdir -p $@ + +$(RELEASE_BINARY): $(BINARY) $(RELEASE_DIR) + cp -f $< $@ + +$(MANUAL): $(MAN1) $(MANUAL_DIR) + cp -f $< $@ + +$(ARTIFACT): $(RELEASE_BINARY) $(MANUAL) + tar -C $(DIST_DIR) -Jcvf $@ $(RELEASE) + +.PHONY: clean +clean: + $(RM) -rf $(ARTIFACT) $(DIST_DIR) $(MAN1) diff --git a/patch.zsh b/patch.zsh new file mode 100755 index 00000000..735244b8 --- /dev/null +++ b/patch.zsh @@ -0,0 +1,10 @@ +#!/usr/bin/env zsh + +local -a trans=( + '\u00D7' '\u2716' + '\u2022' '\u272D' +) + +for from to ($trans); do + rg -l0 $from | xargs -0 --no-run-if-empty sd $from $to +done diff --git a/src/bin/hexyl.rs b/src/bin/hexyl.rs index 5456c321..f962b94a 100644 --- a/src/bin/hexyl.rs +++ b/src/bin/hexyl.rs @@ -7,7 +7,9 @@ use std::io::{self, prelude::*, BufWriter, SeekFrom}; use std::num::{NonZeroI64, NonZeroU64, NonZeroU8}; use clap::builder::ArgPredicate; -use clap::{crate_name, crate_version, Arg, ArgAction, ColorChoice, Command}; +use clap::{crate_name, crate_version, Arg, ArgAction, ColorChoice, Command, ValueHint}; + +use clap_complete::Shell; use anyhow::{anyhow, Context, Result}; @@ -21,14 +23,15 @@ use hexyl::{Base, BorderStyle, Endianness, Input, PrinterBuilder}; const DEFAULT_BLOCK_SIZE: i64 = 512; -fn run() -> Result<()> { - let command = Command::new(crate_name!()) +fn build_cli() -> Command { + Command::new(crate_name!()) .color(ColorChoice::Auto) .max_term_width(90) .version(crate_version!()) .about(crate_description!()) .arg( Arg::new("FILE") + .value_hint(ValueHint::AnyPath) .help("The file to display. If no FILE argument is given, read from STDIN."), ) .arg( @@ -218,8 +221,8 @@ fn run() -> Result<()> { .help( "Sets the base used for the bytes. The possible options are \ binary, octal, decimal, and hexadecimal. The default base \ - is hexadecimal." - ) + is hexadecimal.", + ), ) .arg( Arg::new("terminal_width") @@ -234,9 +237,22 @@ fn run() -> Result<()> { width but still leave some space to the right.\nCannot be used with other \ width-setting options.", ), - ); + ) + .arg( + Arg::new("completion") + .long("completion") + .value_name("shell") + .value_parser(value_parser!(Shell)) + .help("Generate shell completion script for the specified shell."), + ) +} - let matches = command.get_matches(); +fn run() -> Result<()> { + let matches = build_cli().get_matches(); + + if let Some(shell) = matches.get_one::("completion").copied() { + return print_completion(shell); + } let stdin = io::stdin(); @@ -766,6 +782,16 @@ fn try_parse_as_hex_number(n: &str) -> Option> }) } +fn print_completion(shell: Shell) -> Result<()> { + let mut buf = Vec::new(); + clap_complete::generate(shell, &mut build_cli(), crate_name!(), &mut buf); + + let completion = std::str::from_utf8(buf.as_slice()).unwrap(); + println!("{}", completion); + + Ok(()) +} + #[test] fn unit_multipliers() { use Unit::*; diff --git a/src/lib.rs b/src/lib.rs index cc2a04ec..fc272f71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,9 +81,9 @@ impl Byte { Null => '⋄', AsciiPrintable => self.0 as char, AsciiWhitespace if self.0 == 0x20 => ' ', - AsciiWhitespace => '_', - AsciiOther => '•', - NonAscii => '×', + AsciiWhitespace => '⣿', + AsciiOther => '✭', + NonAscii => '✖', } } } @@ -273,6 +273,7 @@ pub struct Printer<'a, Writer: Write> { endianness: Endianness, } +#[allow(clippy::too_many_arguments)] impl<'a, Writer: Write> Printer<'a, Writer> { fn new( writer: &'a mut Writer, diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index fc10dfaa..379256db 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -38,7 +38,7 @@ mod basic { .success() .stdout( "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\ - │00000000│ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde_│\n\ + │00000000│ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde⣿│\n\ └────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n", ); } @@ -90,8 +90,8 @@ mod length { .success() .stdout( "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\ - │00000000│ 7f 45 4c 46 02 01 01 00 ┊ 00 00 00 00 00 00 00 00 │•ELF•••⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│\n\ - │00000010│ 02 00 3e 00 01 00 00 00 ┊ 00 10 40 00 00 00 00 00 │•⋄>⋄•⋄⋄⋄┊⋄•@⋄⋄⋄⋄⋄│\n\ + │00000000│ 7f 45 4c 46 02 01 01 00 ┊ 00 00 00 00 00 00 00 00 │✭ELF✭✭✭⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│\n\ + │00000010│ 02 00 3e 00 01 00 00 00 ┊ 00 10 40 00 00 00 00 00 │✭⋄>⋄✭⋄⋄⋄┊⋄✭@⋄⋄⋄⋄⋄│\n\ └────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n", ); } @@ -206,7 +206,7 @@ mod display_offset { .success() .stdout( "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\ - │00c0ffee│ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde_│\n\ + │00c0ffee│ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde⣿│\n\ └────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n", ); } @@ -223,7 +223,7 @@ mod display_offset { .success() .stdout( "┌────────┬─────────────────────────┬─────────────────────────┬────────┬────────┐\n\ - │00000030│ 02 00 3e 00 01 00 00 00 ┊ 00 10 40 00 00 00 00 00 │•⋄>⋄•⋄⋄⋄┊⋄•@⋄⋄⋄⋄⋄│\n\ + │00000030│ 02 00 3e 00 01 00 00 00 ┊ 00 10 40 00 00 00 00 00 │✭⋄>⋄✭⋄⋄⋄┊⋄✭@⋄⋄⋄⋄⋄│\n\ └────────┴─────────────────────────┴─────────────────────────┴────────┴────────┘\n", ); } @@ -286,7 +286,7 @@ mod display_settings { .success() .stdout( "┌─────────────────────────┬─────────────────────────┬────────┬────────┐\n\ - │ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde_│\n\ + │ 30 31 32 33 34 35 36 37 ┊ 38 39 61 62 63 64 65 0a │01234567┊89abcde⣿│\n\ └─────────────────────────┴─────────────────────────┴────────┴────────┘\n", ); } @@ -306,7 +306,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬─────────────────────┬─────────────────────┬────────┬────────┐\n\ - │00000000│ 3031 3233 3435 3637 ┊ 3839 6162 6364 650a │01234567┊89abcde_│\n\ + │00000000│ 3031 3233 3435 3637 ┊ 3839 6162 6364 650a │01234567┊89abcde⣿│\n\ └────────┴─────────────────────┴─────────────────────┴────────┴────────┘\n", ); } @@ -322,7 +322,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬─────────────────────┬─────────────────────┬────────┬────────┐\n\ - │00000000│ 3130 3332 3534 3736 ┊ 3938 6261 6463 0a65 │01234567┊89abcde_│\n\ + │00000000│ 3130 3332 3534 3736 ┊ 3938 6261 6463 0a65 │01234567┊89abcde⣿│\n\ └────────┴─────────────────────┴─────────────────────┴────────┴────────┘\n", ); } @@ -337,7 +337,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬───────────────────┬───────────────────┬────────┬────────┐\n\ - │00000000│ 30313233 34353637 ┊ 38396162 6364650a │01234567┊89abcde_│\n\ + │00000000│ 30313233 34353637 ┊ 38396162 6364650a │01234567┊89abcde⣿│\n\ └────────┴───────────────────┴───────────────────┴────────┴────────┘\n", ); } @@ -353,7 +353,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬───────────────────┬───────────────────┬────────┬────────┐\n\ - │00000000│ 33323130 37363534 ┊ 62613938 0a656463 │01234567┊89abcde_│\n\ + │00000000│ 33323130 37363534 ┊ 62613938 0a656463 │01234567┊89abcde⣿│\n\ └────────┴───────────────────┴───────────────────┴────────┴────────┘\n", ); } @@ -368,7 +368,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬──────────────────┬──────────────────┬────────┬────────┐\n\ - │00000000│ 3031323334353637 ┊ 383961626364650a │01234567┊89abcde_│\n\ + │00000000│ 3031323334353637 ┊ 383961626364650a │01234567┊89abcde⣿│\n\ └────────┴──────────────────┴──────────────────┴────────┴────────┘\n", ); } @@ -384,7 +384,7 @@ mod group_and_endianness { .success() .stdout( "┌────────┬──────────────────┬──────────────────┬────────┬────────┐\n\ - │00000000│ 3736353433323130 ┊ 0a65646362613938 │01234567┊89abcde_│\n\ + │00000000│ 3736353433323130 ┊ 0a65646362613938 │01234567┊89abcde⣿│\n\ └────────┴──────────────────┴──────────────────┴────────┴────────┘\n", ); } @@ -492,8 +492,8 @@ mod group_and_endianness { ┌─────────────────────────┬─────────────────────────┬────────┬────────┐ │ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ │* ┊ │ ┊ │ -│ ba 0e 00 00 00 b9 00 20 ┊ 40 00 bb 01 00 00 00 b8 │ו⋄⋄⋄×⋄ ┊@⋄ו⋄⋄⋄×│ -│ 04 00 00 00 cd 80 b8 01 ┊ 00 00 00 cd 80 00 00 00 │•⋄⋄⋄××ו┊⋄⋄⋄××⋄⋄⋄│ +│ ba 0e 00 00 00 b9 00 20 ┊ 40 00 bb 01 00 00 00 b8 │✖✭⋄⋄⋄✖⋄ ┊@⋄✖✭⋄⋄⋄✖│ +│ 04 00 00 00 cd 80 b8 01 ┊ 00 00 00 cd 80 00 00 00 │✭⋄⋄⋄✖✖✖✭┊⋄⋄⋄✖✖⋄⋄⋄│ │ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ │* ┊ │ ┊ │ │* ┊ │ ┊ │ @@ -517,10 +517,10 @@ mod group_and_endianness { ┌─────────────────────────┬────────┐ │ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄│ │* │ │ -│ ba 0e 00 00 00 b9 00 20 │ו⋄⋄⋄×⋄ │ -│ 40 00 bb 01 00 00 00 b8 │@⋄ו⋄⋄⋄×│ -│ 04 00 00 00 cd 80 b8 01 │•⋄⋄⋄××ו│ -│ 00 00 00 cd 80 00 00 00 │⋄⋄⋄××⋄⋄⋄│ +│ ba 0e 00 00 00 b9 00 20 │✖✭⋄⋄⋄✖⋄ │ +│ 40 00 bb 01 00 00 00 b8 │@⋄✖✭⋄⋄⋄✖│ +│ 04 00 00 00 cd 80 b8 01 │✭⋄⋄⋄✖✖✖✭│ +│ 00 00 00 cd 80 00 00 00 │⋄⋄⋄✖✖⋄⋄⋄│ │ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄│ │* │ │ │* │ │ @@ -543,8 +543,8 @@ mod group_and_endianness { ┌────────┬─────────────────────────┬─────────────────────────┬─────────────────────────┬────────┬────────┬────────┐ │00000400│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ │* │ ┊ ┊ │ ┊ ┊ │ -│00001000│ ba 0e 00 00 00 b9 00 20 ┊ 40 00 bb 01 00 00 00 b8 ┊ 04 00 00 00 cd 80 b8 01 │ו⋄⋄⋄×⋄ ┊@⋄ו⋄⋄⋄×┊•⋄⋄⋄××ו│ -│00001018│ 00 00 00 cd 80 00 00 00 ┊ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄××⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ +│00001000│ ba 0e 00 00 00 b9 00 20 ┊ 40 00 bb 01 00 00 00 b8 ┊ 04 00 00 00 cd 80 b8 01 │✖✭⋄⋄⋄✖⋄ ┊@⋄✖✭⋄⋄⋄✖┊✭⋄⋄⋄✖✖✖✭│ +│00001018│ 00 00 00 cd 80 00 00 00 ┊ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄✖✖⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ │00001030│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 00 00 00 00 │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄⋄⋄⋄⋄│ │* │ ┊ ┊ │ ┊ ┊ │ │000013f0│ 00 00 00 00 00 00 00 00 ┊ 00 00 00 00 ┊ │⋄⋄⋄⋄⋄⋄⋄⋄┊⋄⋄⋄⋄ ┊ │