diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e2253da..a8073d8 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,67 +8,126 @@ on: - 'LICENSE*' workflow_dispatch: +env: + CARGO_BIN_NAME: objdiff + CARGO_TARGET_DIR: target + jobs: check: name: Check runs-on: ubuntu-latest - strategy: - matrix: - toolchain: [ stable, 1.62.0, nightly ] - fail-fast: false env: RUSTFLAGS: -D warnings steps: - name: Install dependencies - run: | - sudo apt install libgtk-3-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + run: sudo apt-get -y install libgtk-3-dev + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: ${{ matrix.toolchain }} - override: true components: rustfmt, clippy - - uses: EmbarkStudios/cargo-deny-action@v1 - - uses: actions-rs/cargo@v1 - with: - command: check - args: --all-features - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all-features + - name: Cargo check + run: cargo check --all-features + - name: Cargo clippy + run: cargo clippy --all-features - build: - name: Build + deny: + name: Deny + runs-on: ubuntu-latest strategy: matrix: - platform: [ ubuntu-latest, macos-latest, windows-latest ] - toolchain: [ stable, 1.62.0, nightly ] + checks: + - advisories + - bans licenses sources + # Prevent new advisories from failing CI + continue-on-error: ${{ matrix.checks == 'advisories' }} + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + command: check ${{ matrix.checks }} + + test: + name: Test + strategy: + matrix: + platform: [ ubuntu-latest, windows-latest, macos-latest ] fail-fast: false runs-on: ${{ matrix.platform }} steps: - name: Install dependencies if: matrix.platform == 'ubuntu-latest' - run: | - sudo apt install libgtk-3-dev - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + run: sudo apt-get -y install libgtk-3-dev + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Cargo test + run: cargo test --release --all-features + + build: + name: Build + strategy: + matrix: + include: + - platform: ubuntu-latest + target: x86_64-unknown-linux-gnu + name: linux-x86_64 + packages: libgtk-3-dev + - platform: windows-latest + target: x86_64-pc-windows-msvc + name: windows-x86_64 + - platform: macos-latest + target: x86_64-apple-darwin + name: macos-x86_64 + - platform: macos-latest + target: aarch64-apple-darwin + name: macos-arm64 + fail-fast: false + runs-on: ${{ matrix.platform }} + steps: + - name: Install dependencies + if: matrix.packages != '' + run: sudo apt-get -y install ${{ matrix.packages }} + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: ${{ matrix.toolchain }} - override: true - - uses: actions-rs/cargo@v1 + targets: ${{ matrix.target }} + - name: Cargo build + run: cargo build --release --all-features --target ${{ matrix.target }} --bin ${{ env.CARGO_BIN_NAME }} + - name: Upload artifacts + uses: actions/upload-artifact@v3 with: - command: test - args: --release --all-features - - uses: actions-rs/cargo@v1 - with: - command: build - args: --release --all-features - - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.platform }}-${{ matrix.toolchain }} + name: ${{ matrix.name }} path: | - target/release/objdiff - target/release/objdiff.exe + ${{ env.CARGO_TARGET_DIR }}/release/${{ env.CARGO_BIN_NAME }} + ${{ env.CARGO_TARGET_DIR }}/release/${{ env.CARGO_BIN_NAME }}.exe + ${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/release/${{ env.CARGO_BIN_NAME }} + ${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/release/${{ env.CARGO_BIN_NAME }}.exe + if-no-files-found: error + + release: + name: Release + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + needs: [ build ] + steps: + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + path: artifacts + - name: Rename artifacts + working-directory: artifacts + run: | + mkdir ../out + for i in */*/release/$CARGO_BIN_NAME*; do + mv "$i" "../out/$(sed -E "s/([^/]+)\/[^/]+\/release\/($CARGO_BIN_NAME)/\2-\1/" <<< "$i")" + done + ls -R ../out + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: out/* diff --git a/Cargo.lock b/Cargo.lock index 1263353..51ed96f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04a9283dace1c41c265496614998d5b9c4a97b3eb770e804f007c5144bf03f2b" +checksum = "4dcdbc68024b653943864d436fe8a24b028095bc1cf91a8926f8241e4aaffe59" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "ab_glyph_rasterizer" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363b9b88fad3af3be80bc8f762c9a3f9dfe906fd0327b8e92f1c12e5ae1b8bbb" +checksum = "330223a1aecc308757b9926e9391c9b47f8ef2dbd8aea9df88312aea18c5e8d6" [[package]] name = "adler" @@ -24,17 +24,11 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "ahash" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e6e951cfbb2db8de1828d49073a113a29fd7117b1596caa781a258c7e38d72" +checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" dependencies = [ "cfg-if", "getrandom", @@ -45,27 +39,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26fa4d7e3f2eebadf743988fc8aec9fa9a9e82611acafd77c1462ed6262440a" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "arboard" @@ -86,9 +71,9 @@ dependencies = [ [[package]] name = "argh" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e7e4aa7e40747e023c0761dafcb42333a9517575bbf1241747f68dd3177a62" +checksum = "c375edecfd2074d5edcc31396860b6e54b6f928714d0e097b983053fac0cabe3" dependencies = [ "argh_derive", "argh_shared", @@ -96,12 +81,12 @@ dependencies = [ [[package]] name = "argh_derive" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f2bd7ff6ed6414f4e5521bd509bae46454bbd513801767ced3f21a751ab4bc" +checksum = "aa013479b80109a1bf01a039412b0f0013d716f36921226d86c6709032fb7a03" dependencies = [ "argh_shared", - "heck 0.3.3", + "heck", "proc-macro2", "quote", "syn", @@ -109,9 +94,9 @@ dependencies = [ [[package]] name = "argh_shared" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47253b98986dafc7a3e1cf3259194f1f47ac61abb57a57f46ec09e48d004ecda" +checksum = "149f75bbec1827618262e0855a68f0f9a7f2edc13faebf33c4f16d6725edb6a9" [[package]] name = "arrayref" @@ -162,9 +147,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bindgen" @@ -203,24 +188,24 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytemuck" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9e1f5fa78f69496407a27ae9ed989e3c3b072310286f5ef385525e4cbc24a9" +checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" dependencies = [ "proc-macro2", "quote", @@ -229,9 +214,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cairo-sys-rs" @@ -245,12 +230,12 @@ dependencies = [ [[package]] name = "calloop" -version = "0.10.1" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a22a6a8f622f797120d452c630b0ab12e1331a1a753e2039ce7868d4ac77b4ee" +checksum = "19457a0da465234abd76134a5c2a910c14bd3c5558463e4396ab9a37a328e465" dependencies = [ "log", - "nix 0.24.2", + "nix 0.25.1", "slotmap", "thiserror", "vec_map", @@ -258,9 +243,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.73" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +dependencies = [ + "jobserver", +] [[package]] name = "cesu8" @@ -279,9 +267,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.10.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" +checksum = "b0357a6402b295ca3a86bc148e84df46c02e41f41fef186bda662557ef6328aa" dependencies = [ "smallvec", ] @@ -303,9 +291,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", @@ -314,9 +302,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.20" +version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", "bitflags", @@ -349,18 +337,18 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.48" +version = "0.1.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" dependencies = [ "cc", ] [[package]] name = "cocoa" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" dependencies = [ "bitflags", "block", @@ -397,6 +385,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "console" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "terminal_size", + "unicode-width", + "winapi", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -407,6 +409,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const_format" +version = "0.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -481,19 +503,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", ] [[package]] name = "crossfont" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66b1c1979c4362323f03ab6bf7fb522902bfc418e0c37319ab347f9561d980f" +checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" dependencies = [ "cocoa", "core-foundation", @@ -520,8 +541,8 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" [[package]] name = "cwdemangle" -version = "0.1.3" -source = "git+https://github.com/encounter/cwdemangle?rev=64e8b3e083343783c5b3b6329ea940f375b057b3#64e8b3e083343783c5b3b6329ea940f375b057b3" +version = "0.1.4" +source = "git+https://github.com/encounter/cwdemangle?rev=286f3d1d29ee2457db89043782725631845c3e4c#286f3d1d29ee2457db89043782725631845c3e4c" dependencies = [ "argh", ] @@ -561,15 +582,6 @@ dependencies = [ "syn", ] -[[package]] -name = "deflate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" -dependencies = [ - "adler32", -] - [[package]] name = "directories-next" version = "2.0.0" @@ -722,10 +734,45 @@ dependencies = [ ] [[package]] -name = "env_logger" -version = "0.9.0" +name = "encode_unicode" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -750,6 +797,27 @@ dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-code" version = "2.3.1" @@ -760,6 +828,16 @@ dependencies = [ "str-buf", ] +[[package]] +name = "exec" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886b70328cba8871bfc025858e1de4be16b1d5088f2ba50b57816f4210672615" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "expat-sys" version = "2.1.6" @@ -771,15 +849,24 @@ dependencies = [ ] [[package]] -name = "filetime" -version = "0.2.17" +name = "fastrand" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -790,9 +877,9 @@ checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "miniz_oxide", @@ -848,11 +935,10 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] @@ -887,6 +973,54 @@ dependencies = [ "libc", ] +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "gdk-pixbuf-sys" version = "0.15.10" @@ -929,9 +1063,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "js-sys", @@ -940,6 +1074,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "gio-sys" version = "0.15.10" @@ -953,6 +1099,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "git2" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +dependencies = [ + "bitflags", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -1086,21 +1245,31 @@ dependencies = [ "system-deps", ] +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" @@ -1116,12 +1285,83 @@ dependencies = [ "libc", ] +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1130,25 +1370,36 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4295cbb7573c16d310e99e713cf9e75101eb190ab31fccd35f2d2691b4352b19" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "inotify" version = "0.9.6" @@ -1182,10 +1433,16 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.3" +name = "ipnet" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jni" @@ -1208,10 +1465,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] -name = "js-sys" -version = "0.3.59" +name = "jobserver" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -1224,9 +1490,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kqueue" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" dependencies = [ "kqueue-sys", "libc", @@ -1256,25 +1522,49 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "libgit2-sys" +version = "0.13.4+1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", "winapi", ] [[package]] -name = "lock_api" -version = "0.4.8" +name = "libz-sys" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1298,12 +1588,6 @@ dependencies = [ "libc", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.5.0" @@ -1312,9 +1596,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" dependencies = [ "libc", ] @@ -1328,6 +1612,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1336,23 +1626,41 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.42.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -1376,7 +1684,7 @@ checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" dependencies = [ "bitflags", "jni-sys", - "ndk-sys 0.4.0", + "ndk-sys 0.4.1+23.1.7779620", "num_enum", "raw-window-handle 0.5.0", "thiserror", @@ -1414,7 +1722,7 @@ dependencies = [ "ndk 0.7.0", "ndk-context", "ndk-macro", - "ndk-sys 0.4.0", + "ndk-sys 0.4.1+23.1.7779620", "once_cell", "parking_lot", ] @@ -1443,9 +1751,9 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.4.0" +version = "0.4.1+23.1.7779620" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d83ec9c63ec5bf950200a8e508bdad6659972187b625469f58ef8c08e29046" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" dependencies = [ "jni-sys", ] @@ -1465,9 +1773,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ "bitflags", "cfg-if", @@ -1475,6 +1783,19 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -1509,6 +1830,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1518,6 +1849,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.5.7" @@ -1548,6 +1889,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "objc" version = "0.2.7" @@ -1579,51 +1926,105 @@ dependencies = [ [[package]] name = "objdiff" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", + "cfg-if", "console_error_panic_hook", + "const_format", "cwdemangle", "eframe", "egui", "egui_extras", + "exec", "flagset", "log", + "memmap2", "notify", "object", "path-slash", "ppc750cl", "rabbitizer", + "reqwest", "rfd", + "self_update", "serde", + "tempfile", "thiserror", "time", + "toml", "tracing-subscriber", "tracing-wasm", + "twox-hash", + "vergen", "winapi", ] [[package]] name = "object" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" dependencies = [ - "flate2", "memchr", ] [[package]] name = "once_cell" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "openssl" +version = "0.10.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d971fd5722fec23977260f6e81aa67d2f22cadbdc2aa049f1022d9a3be1566" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] [[package]] name = "os_str_bytes" -version = "6.3.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "osmesa-sys" @@ -1635,10 +2036,16 @@ dependencies = [ ] [[package]] -name = "owned_ttf_parser" -version = "0.15.2" +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owned_ttf_parser" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18904d3c65493a9f0d7542293d1a7f69bfdc309a6b9ef4f46dc3e58b0577edc5" dependencies = [ "ttf-parser", ] @@ -1667,15 +2074,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1692,9 +2099,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" @@ -1703,23 +2110,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] -name = "pkg-config" -version = "0.3.25" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "png" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" dependencies = [ "bitflags", "crc32fast", - "deflate", + "flate2", "miniz_oxide", ] +[[package]] +name = "portable-atomic" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15eb2c6e362923af47e13c23ca5afb859e83d54452c55b0b9ac763b8f7c1ac16" + [[package]] name = "ppc750cl" version = "0.2.0" @@ -1729,6 +2148,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.2.1" @@ -1741,14 +2166,47 @@ dependencies = [ ] [[package]] -name = "proc-macro2" -version = "1.0.43" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.21" @@ -1769,6 +2227,36 @@ dependencies = [ "glob", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "raw-window-handle" version = "0.4.3" @@ -1809,9 +2297,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -1820,9 +2308,55 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] [[package]] name = "rfd" @@ -1865,6 +2399,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + [[package]] name = "safe_arch" version = "0.5.2" @@ -1884,10 +2430,20 @@ dependencies = [ ] [[package]] -name = "scoped-tls" -version = "1.0.0" +name = "schannel" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys 0.36.1", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" @@ -1897,9 +2453,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sctk-adwaita" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04b7c47a572f73de28bee5b5060d085b42b6ce1e4ee2b49c956ea7b25e94b6f0" +checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" dependencies = [ "crossfont", "log", @@ -1908,25 +2464,94 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.144" +name = "security-framework" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_update" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e08f3ce73aed26096783c26570ba416ff8f4524c89a14bcdf068967dc80daef" +dependencies = [ + "hyper", + "indicatif", + "log", + "quick-xml", + "regex", + "reqwest", + "semver", + "serde_json", + "tempfile", +] + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" + +[[package]] +name = "serde" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "servo-fontconfig" version = "0.5.1" @@ -1973,6 +2598,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + [[package]] name = "slotmap" version = "1.0.6" @@ -1984,9 +2618,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smithay-client-toolkit" @@ -2000,7 +2634,7 @@ dependencies = [ "lazy_static", "log", "memmap2", - "nix 0.24.2", + "nix 0.24.3", "pkg-config", "wayland-client", "wayland-cursor", @@ -2017,6 +2651,22 @@ dependencies = [ "wayland-client", ] +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str-buf" version = "1.0.6" @@ -2031,9 +2681,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -2042,17 +2692,31 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.0.2" +version = "6.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" +checksum = "2955b1fe31e1fa2fbd1976b71cc69a606d7d4da16f6de3333d0c92d51419aeff" dependencies = [ "cfg-expr", - "heck 0.4.0", + "heck", "pkg-config", "toml", "version-compare", ] +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -2063,25 +2727,35 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.15.0" +name = "terminal_size" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -2099,13 +2773,31 @@ dependencies = [ [[package]] name = "time" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa", "libc", "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", ] [[package]] @@ -2148,6 +2840,47 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.42.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.5.9" @@ -2158,10 +2891,16 @@ dependencies = [ ] [[package]] -name = "tracing" -version = "0.1.36" +name = "tower-service" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -2171,9 +2910,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -2182,9 +2921,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -2203,11 +2942,11 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", + "nu-ansi-term", "sharded-slab", "smallvec", "thread_local", @@ -2227,10 +2966,27 @@ dependencies = [ ] [[package]] -name = "ttf-parser" -version = "0.15.2" +name = "try-lock" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "ttf-parser" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "rand", + "static_assertions", +] [[package]] name = "unicode-bidi" @@ -2240,34 +2996,39 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] -name = "unicode-segmentation" -version = "1.9.0" +name = "unicode-width" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -2277,6 +3038,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -2284,10 +3051,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] -name = "version-compare" -version = "0.1.0" +name = "vergen" +version = "7.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" +checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37" +dependencies = [ + "anyhow", + "cfg-if", + "enum-iterator", + "getset", + "git2", + "rustversion", + "thiserror", + "time", +] + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" [[package]] name = "version_check" @@ -2306,6 +3089,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2314,9 +3107,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2324,9 +3117,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -2339,9 +3132,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -2351,9 +3144,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2361,9 +3154,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -2374,9 +3167,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wayland-client" @@ -2387,7 +3180,7 @@ dependencies = [ "bitflags", "downcast-rs", "libc", - "nix 0.24.2", + "nix 0.24.3", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -2400,7 +3193,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" dependencies = [ - "nix 0.24.2", + "nix 0.24.3", "once_cell", "smallvec", "wayland-sys", @@ -2412,7 +3205,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ - "nix 0.24.2", + "nix 0.24.3", "wayland-client", "xcursor", ] @@ -2463,9 +3256,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2568,6 +3361,27 @@ dependencies = [ "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -2580,6 +3394,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -2592,6 +3412,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -2604,6 +3430,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -2616,6 +3448,18 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -2629,10 +3473,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" [[package]] -name = "winit" -version = "0.27.2" +name = "windows_x86_64_msvc" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a8f3e9d742401efcfe833b8f84960397482ff049cb7bf59a112e14a4be97f7" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "winit" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" dependencies = [ "bitflags", "cocoa", @@ -2657,10 +3507,19 @@ dependencies = [ "wayland-client", "wayland-protocols", "web-sys", - "windows-sys", + "windows-sys 0.36.1", "x11-dl", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "wio" version = "0.2.2" @@ -2672,9 +3531,9 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.20.0" +version = "2.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" +checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0" dependencies = [ "lazy_static", "libc", diff --git a/Cargo.toml b/Cargo.toml index c2fc6e4..1ac4cbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "objdiff" -version = "0.1.0" +version = "0.2.0" edition = "2021" rust-version = "1.62" authors = ["Luke Street "] @@ -8,35 +8,55 @@ license = "MIT OR Apache-2.0" repository = "https://github.com/encounter/objdiff" readme = "README.md" description = """ -A tool for decompilation projects. +A local diffing tool for decompilation projects. """ +publish = false + +[profile.release] +lto = "thin" +strip = "debuginfo" [dependencies] -egui = "0.19.0" +anyhow = "1.0.66" +cfg-if = "1.0.0" +const_format = "0.2.30" +cwdemangle = { git = "https://github.com/encounter/cwdemangle", rev = "286f3d1d29ee2457db89043782725631845c3e4c" } eframe = { version = "0.19.0", features = ["persistence"] } # , "wgpu" -serde = { version = "1", features = ["derive"] } -anyhow = "1.0.63" -thiserror = "1.0.33" -flagset = "0.4.3" -object = "0.29.0" -notify = "5.0.0" -cwdemangle = { git = "https://github.com/encounter/cwdemangle", rev = "64e8b3e083343783c5b3b6329ea940f375b057b3" } -log = "0.4.17" -rfd = { version = "0.10.0" } # , default-features = false, features = ['xdg-portal'] +egui = "0.19.0" egui_extras = "0.19.0" +flagset = "0.4.3" +log = "0.4.17" +memmap2 = "0.5.8" +notify = "5.0.0" +object = { version = "0.30.0", features = ["read_core", "std", "elf"], default-features = false } ppc750cl = { git = "https://github.com/encounter/ppc750cl", rev = "aa631a33de7882c679afca89350898b87cb3ba3f" } rabbitizer = { git = "https://github.com/encounter/rabbitizer-rs", rev = "10c279b2ef251c62885b1dcdcfe740b0db8e9956" } -time = { version = "0.3.14", features = ["formatting", "local-offset"] } +rfd = { version = "0.10.0" } # , default-features = false, features = ['xdg-portal'] +self_update = "0.32.0" +serde = { version = "1", features = ["derive"] } +thiserror = "1.0.37" +time = { version = "0.3.17", features = ["formatting", "local-offset"] } +toml = "0.5.9" +twox-hash = "1.6.3" +tempfile = "3.3.0" +reqwest = "0.11.13" [target.'cfg(windows)'.dependencies] -path-slash = "0.2.0" +path-slash = "0.2.1" winapi = "0.3.9" +[target.'cfg(unix)'.dependencies] +exec = "0.3.1" + # native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tracing-subscriber = "0.3" # web: [target.'cfg(target_arch = "wasm32")'.dependencies] -console_error_panic_hook = "0.1.6" +console_error_panic_hook = "0.1.7" tracing-wasm = "0.2" + +[build-dependencies] +anyhow = "1.0.66" +vergen = { version = "7.4.3", features = ["build", "cargo", "git"], default-features = false } diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..068305e --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Luke Street. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..661d40b --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright 2022 Luke Street. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 8b21c16..dd4ef24 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,12 @@ [Build Status]: https://github.com/encounter/objdiff/actions/workflows/build.yaml/badge.svg [actions]: https://github.com/encounter/objdiff/actions -A tool for decompilation projects. +A local diffing tool for decompilation projects. Currently supports: - PowerPC 750CL (GameCube & Wii) - MIPS (Nintendo 64) -**WARNING:** Very early & unstable. - ![Symbol Screenshot](assets/screen-symbols.png) ![Diff Screenshot](assets/screen-diff.png) diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e10776e --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +use anyhow::Result; +use vergen::{vergen, Config}; + +fn main() -> Result<()> { vergen(Config::default()) } diff --git a/src/app.rs b/src/app.rs index b4ae71a..2e726db 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,22 +2,23 @@ use std::{ default::Default, ffi::OsStr, path::{Path, PathBuf}, + rc::Rc, sync::{ atomic::{AtomicBool, Ordering}, - Arc, RwLock, + Arc, Mutex, RwLock, }, time::Duration, }; -use eframe::Frame; -use egui::Widget; +use egui::{Color32, FontFamily, FontId, TextStyle}; use notify::{RecursiveMode, Watcher}; use time::{OffsetDateTime, UtcOffset}; use crate::{ jobs::{ + check_update::{queue_check_update, CheckUpdateResult}, objdiff::{queue_build, BuildStatus, ObjDiffResult}, - Job, JobResult, JobState, + Job, JobResult, JobState, JobStatus, }, views::{ config::config_ui, data_diff::data_diff_ui, function_diff::function_diff_ui, jobs::jobs_ui, @@ -48,6 +49,36 @@ pub struct DiffConfig { // pub mapped_symbols: HashMap, } +const DEFAULT_COLOR_ROTATION: [Color32; 9] = [ + Color32::from_rgb(255, 0, 255), + Color32::from_rgb(0, 255, 255), + Color32::from_rgb(0, 128, 0), + Color32::from_rgb(255, 0, 0), + Color32::from_rgb(255, 255, 0), + Color32::from_rgb(255, 192, 203), + Color32::from_rgb(0, 0, 255), + Color32::from_rgb(0, 255, 0), + Color32::from_rgb(128, 128, 128), +]; + +#[derive(serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct ViewConfig { + pub ui_font: FontId, + pub code_font: FontId, + pub diff_colors: Vec, +} + +impl Default for ViewConfig { + fn default() -> Self { + Self { + ui_font: FontId { size: 14.0, family: FontFamily::Proportional }, + code_font: FontId { size: 14.0, family: FontFamily::Monospace }, + diff_colors: DEFAULT_COLOR_ROTATION.to_vec(), + } + } +} + #[derive(serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct ViewState { @@ -64,14 +95,21 @@ pub struct ViewState { #[serde(skip)] pub show_config: bool, #[serde(skip)] + pub show_demangle: bool, + #[serde(skip)] + pub demangle_text: String, + #[serde(skip)] pub diff_config: DiffConfig, #[serde(skip)] pub search: String, #[serde(skip)] pub utc_offset: UtcOffset, + #[serde(skip)] + pub check_update: Option>, // Config pub diff_kind: DiffKind, pub reverse_fn_order: bool, + pub view_config: ViewConfig, } impl Default for ViewState { @@ -83,11 +121,15 @@ impl Default for ViewState { selected_symbol: None, current_view: Default::default(), show_config: false, + show_demangle: false, + demangle_text: String::new(), diff_config: Default::default(), search: Default::default(), utc_offset: UtcOffset::UTC, + check_update: None, diff_kind: Default::default(), reverse_fn_order: false, + view_config: Default::default(), } } } @@ -95,7 +137,7 @@ impl Default for ViewState { #[derive(Default, Clone, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct AppConfig { - pub custom_make: String, + pub custom_make: Option, // WSL2 settings #[serde(skip)] pub available_wsl_distros: Option>, @@ -111,6 +153,19 @@ pub struct AppConfig { pub right_obj: Option, #[serde(skip)] pub project_dir_change: bool, + #[serde(skip)] + pub queue_update_check: bool, + pub auto_update_check: bool, +} + +#[derive(Default, Clone, serde::Deserialize)] +#[serde(default)] +pub struct ProjectConfig { + pub custom_make: Option, + pub project_dir: Option, + pub target_obj_dir: Option, + pub base_obj_dir: Option, + pub build_target: bool, } /// We derive Deserialize/Serialize so we can persist app state on shutdown. @@ -124,6 +179,10 @@ pub struct App { modified: Arc, #[serde(skip)] watcher: Option, + #[serde(skip)] + relaunch_path: Rc>>, + #[serde(skip)] + should_relaunch: bool, } impl Default for App { @@ -133,6 +192,8 @@ impl Default for App { config: Arc::new(Default::default()), modified: Arc::new(Default::default()), watcher: None, + relaunch_path: Default::default(), + should_relaunch: false, } } } @@ -141,7 +202,11 @@ const CONFIG_KEY: &str = "app_config"; impl App { /// Called once before the first frame. - pub fn new(cc: &eframe::CreationContext<'_>, utc_offset: UtcOffset) -> Self { + pub fn new( + cc: &eframe::CreationContext<'_>, + utc_offset: UtcOffset, + relaunch_path: Rc>>, + ) -> Self { // This is also where you can customized the look at feel of egui using // `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`. @@ -153,11 +218,16 @@ impl App { if config.project_dir.is_some() { config.project_dir_change = true; } + config.queue_update_check = config.auto_update_check; app.config = Arc::new(RwLock::new(config)); app.view_state.utc_offset = utc_offset; + app.relaunch_path = relaunch_path; app } else { - Self::default() + let mut app = Self::default(); + app.view_state.utc_offset = utc_offset; + app.relaunch_path = relaunch_path; + app } } } @@ -165,17 +235,44 @@ impl App { impl eframe::App for App { /// Called each time the UI needs repainting, which may be many times per second. /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. - fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { + if self.should_relaunch { + frame.close(); + return; + } + let Self { config, view_state, .. } = self; + { + let config = &view_state.view_config; + let mut style = (*ctx.style()).clone(); + style.text_styles.insert(TextStyle::Body, FontId { + size: (config.ui_font.size * 0.75).floor(), + family: config.ui_font.family.clone(), + }); + style.text_styles.insert(TextStyle::Body, config.ui_font.clone()); + style.text_styles.insert(TextStyle::Button, config.ui_font.clone()); + style.text_styles.insert(TextStyle::Heading, FontId { + size: (config.ui_font.size * 1.5).floor(), + family: config.ui_font.family.clone(), + }); + style.text_styles.insert(TextStyle::Monospace, config.code_font.clone()); + ctx.set_style(style); + } + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::menu::bar(ui, |ui| { ui.menu_button("File", |ui| { + if ui.button("Show config").clicked() { + view_state.show_config = !view_state.show_config; + } if ui.button("Quit").clicked() { frame.close(); } - if ui.button("Show config").clicked() { - view_state.show_config = !view_state.show_config; + }); + ui.menu_button("Tools", |ui| { + if ui.button("Demangle").clicked() { + view_state.show_demangle = !view_state.show_demangle; } }); }); @@ -221,31 +318,55 @@ impl eframe::App for App { } egui::Window::new("Config").open(&mut view_state.show_config).show(ctx, |ui| { - ui.label("Diff type:"); - - if egui::RadioButton::new( - view_state.diff_kind == DiffKind::SplitObj, - "Split object diff", - ) - .ui(ui) - .on_hover_text("Compare individual object files") - .clicked() - { - view_state.diff_kind = DiffKind::SplitObj; - } - - if egui::RadioButton::new( - view_state.diff_kind == DiffKind::WholeBinary, - "Whole binary diff", - ) - .ui(ui) - .on_hover_text("Compare two full binaries") - .clicked() - { - view_state.diff_kind = DiffKind::WholeBinary; - } - + ui.label("UI font:"); + egui::introspection::font_id_ui(ui, &mut view_state.view_config.ui_font); ui.separator(); + ui.label("Code font:"); + egui::introspection::font_id_ui(ui, &mut view_state.view_config.code_font); + ui.separator(); + ui.label("Diff colors:"); + if ui.button("Reset").clicked() { + view_state.view_config.diff_colors = DEFAULT_COLOR_ROTATION.to_vec(); + } + let mut remove_at: Option = None; + let num_colors = view_state.view_config.diff_colors.len(); + for (idx, color) in view_state.view_config.diff_colors.iter_mut().enumerate() { + ui.horizontal(|ui| { + ui.color_edit_button_srgba(color); + if num_colors > 1 { + if ui.small_button("-").clicked() { + remove_at = Some(idx); + } + } + }); + } + if let Some(idx) = remove_at { + view_state.view_config.diff_colors.remove(idx); + } + if ui.small_button("+").clicked() { + view_state.view_config.diff_colors.push(Color32::BLACK); + } + }); + + egui::Window::new("Demangle").open(&mut view_state.show_demangle).show(ctx, |ui| { + ui.text_edit_singleline(&mut view_state.demangle_text); + ui.add_space(10.0); + if let Some(demangled) = + cwdemangle::demangle(&view_state.demangle_text, &Default::default()) + { + ui.scope(|ui| { + ui.style_mut().override_text_style = Some(TextStyle::Monospace); + ui.colored_label(Color32::LIGHT_BLUE, &demangled); + }); + if ui.button("Copy").clicked() { + ui.output().copied_text = demangled; + } + } else { + ui.scope(|ui| { + ui.style_mut().override_text_style = Some(TextStyle::Monospace); + ui.colored_label(Color32::LIGHT_RED, "[invalid]"); + }); + } }); // Windows + request_repaint_after breaks dialogs: @@ -272,7 +393,7 @@ impl eframe::App for App { eframe::set_value(storage, eframe::APP_KEY, self); } - fn post_rendering(&mut self, _window_size_px: [u32; 2], _frame: &Frame) { + fn post_rendering(&mut self, _window_size_px: [u32; 2], _frame: &eframe::Frame) { for job in &mut self.view_state.jobs { if let Some(handle) = &job.handle { if !handle.is_finished() { @@ -305,10 +426,38 @@ impl eframe::App for App { time: OffsetDateTime::now_utc(), })); } + JobResult::CheckUpdate(state) => { + self.view_state.check_update = Some(state); + } + JobResult::Update(state) => { + if let Ok(mut guard) = self.relaunch_path.lock() { + *guard = Some(state.exe_path); + } + self.should_relaunch = true; + } } } - Err(e) => { - log::error!("Failed to join job handle: {:?}", e); + Err(err) => { + let err = if let Some(msg) = err.downcast_ref::<&'static str>() { + anyhow::Error::msg(*msg) + } else if let Some(msg) = err.downcast_ref::() { + anyhow::Error::msg(msg.clone()) + } else { + anyhow::Error::msg("Thread panicked") + }; + let result = job.status.write(); + if let Ok(mut guard) = result { + guard.error = Some(err); + } else { + drop(result); + job.status = Arc::new(RwLock::new(JobStatus { + title: "Error".to_string(), + progress_percent: 0.0, + progress_items: None, + status: "".to_string(), + error: Some(err), + })); + } } } } @@ -355,6 +504,11 @@ impl eframe::App for App { } self.modified.store(false, Ordering::Relaxed); } + + if config.queue_update_check { + self.view_state.jobs.push(queue_check_update()); + config.queue_update_check = false; + } } } } diff --git a/src/diff.rs b/src/diff.rs index 4e5cf40..984c928 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -12,6 +12,30 @@ use crate::{ }, }; +fn no_diff_code( + arch: ObjArchitecture, + data: &Vec, + symbol: &mut ObjSymbol, + relocs: &Vec, +) -> Result<()> { + let code = + &data[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize]; + let (_, ins) = match arch { + ObjArchitecture::PowerPc => ppc::process_code(code, symbol.address, relocs)?, + ObjArchitecture::Mips => { + mips::process_code(code, symbol.address, symbol.address + symbol.size, relocs)? + } + }; + + let mut diff = Vec::::new(); + for i in ins { + diff.push(ObjInsDiff { ins: Some(i), kind: ObjInsDiffKind::None, ..Default::default() }); + } + resolve_branches(&mut diff); + symbol.instructions = diff; + Ok(()) +} + pub fn diff_code( arch: ObjArchitecture, left_data: &[u8], @@ -133,8 +157,8 @@ pub fn diff_code( } else { ((total - diff_state.diff_count) as f32 / total as f32) * 100.0 }; - left_symbol.match_percent = percent; - right_symbol.match_percent = percent; + left_symbol.match_percent = Some(percent); + right_symbol.match_percent = Some(percent); left_symbol.instructions = left_diff; right_symbol.instructions = right_diff; @@ -356,13 +380,101 @@ pub fn diff_objs(left: &mut ObjInfo, right: &mut ObjInfo, _diff_config: &DiffCon &left_section.relocations, &right_section.relocations, )?; + } else { + no_diff_code( + left.architecture, + &left_section.data, + left_symbol, + &left_section.relocations, + )?; + } + } + for right_symbol in &mut right_section.symbols { + if right_symbol.instructions.is_empty() { + no_diff_code( + left.architecture, + &right_section.data, + right_symbol, + &right_section.relocations, + )?; } } } else if left_section.kind == ObjSectionKind::Data { diff_data(left_section, right_section); + // diff_data_symbols(left_section, right_section)?; + } else if left_section.kind == ObjSectionKind::Bss { + diff_bss_symbols(&mut left_section.symbols, &mut right_section.symbols)?; } } } + diff_bss_symbols(&mut left.common, &mut right.common)?; + Ok(()) +} + +fn diff_bss_symbols(left_symbols: &mut [ObjSymbol], right_symbols: &mut [ObjSymbol]) -> Result<()> { + for left_symbol in left_symbols { + if let Some(right_symbol) = find_symbol(right_symbols, &left_symbol.name) { + left_symbol.diff_symbol = Some(right_symbol.name.clone()); + right_symbol.diff_symbol = Some(left_symbol.name.clone()); + let percent = if left_symbol.size == right_symbol.size { 100.0 } else { 50.0 }; + left_symbol.match_percent = Some(percent); + right_symbol.match_percent = Some(percent); + } + } + Ok(()) +} + +// WIP diff-by-symbol +#[allow(dead_code)] +fn diff_data_symbols(left: &mut ObjSection, right: &mut ObjSection) -> Result<()> { + let mut left_ops = Vec::::with_capacity(left.symbols.len()); + let mut right_ops = Vec::::with_capacity(right.symbols.len()); + for left_symbol in &left.symbols { + let data = &left.data + [left_symbol.address as usize..(left_symbol.address + left_symbol.size) as usize]; + let hash = twox_hash::xxh3::hash64(data); + left_ops.push(hash as u32); + } + for symbol in &right.symbols { + let data = &right.data[symbol.address as usize..(symbol.address + symbol.size) as usize]; + let hash = twox_hash::xxh3::hash64(data); + right_ops.push(hash as u32); + } + + let edit_ops = editops_find(&left_ops, &right_ops); + if edit_ops.is_empty() && !left.data.is_empty() { + let mut left_iter = left.symbols.iter_mut(); + let mut right_iter = right.symbols.iter_mut(); + loop { + let (left_symbol, right_symbol) = match (left_iter.next(), right_iter.next()) { + (Some(l), Some(r)) => (l, r), + (None, None) => break, + _ => return Err(anyhow::Error::msg("L/R mismatch in diff_data_symbols")), + }; + let left_data = &left.data + [left_symbol.address as usize..(left_symbol.address + left_symbol.size) as usize]; + let right_data = &right.data[right_symbol.address as usize + ..(right_symbol.address + right_symbol.size) as usize]; + + left.data_diff.push(ObjDataDiff { + data: left_data.to_vec(), + kind: ObjDataDiffKind::None, + len: left_symbol.size as usize, + symbol: left_symbol.name.clone(), + }); + right.data_diff.push(ObjDataDiff { + data: right_data.to_vec(), + kind: ObjDataDiffKind::None, + len: right_symbol.size as usize, + symbol: right_symbol.name.clone(), + }); + left_symbol.diff_symbol = Some(right_symbol.name.clone()); + left_symbol.match_percent = Some(100.0); + right_symbol.diff_symbol = Some(left_symbol.name.clone()); + right_symbol.match_percent = Some(100.0); + } + return Ok(()); + } Ok(()) } @@ -373,11 +485,13 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: left.data.clone(), kind: ObjDataDiffKind::None, len: left.data.len(), + symbol: String::new(), }]; right.data_diff = vec![ObjDataDiff { data: right.data.clone(), kind: ObjDataDiffKind::None, len: right.data.len(), + symbol: String::new(), }]; return; } @@ -390,23 +504,7 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { let mut cur_left_data = Vec::::new(); let mut cur_right_data = Vec::::new(); for op in edit_ops { - if left_cur < op.first_start { - left_diff.push(ObjDataDiff { - data: left.data[left_cur..op.first_start].to_vec(), - kind: ObjDataDiffKind::None, - len: op.first_start - left_cur, - }); - left_cur = op.first_start; - } - if right_cur < op.second_start { - right_diff.push(ObjDataDiff { - data: right.data[right_cur..op.second_start].to_vec(), - kind: ObjDataDiffKind::None, - len: op.second_start - right_cur, - }); - right_cur = op.second_start; - } - if cur_op != op.op_type { + if cur_op != op.op_type || left_cur < op.first_start || right_cur < op.second_start { match cur_op { LevEditType::Keep => {} LevEditType::Replace => { @@ -418,11 +516,13 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: left_data, kind: ObjDataDiffKind::Replace, len: left_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: right_data, kind: ObjDataDiffKind::Replace, len: right_data_len, + symbol: String::new(), }); } LevEditType::Insert => { @@ -432,11 +532,13 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: vec![], kind: ObjDataDiffKind::Insert, len: right_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: right_data, kind: ObjDataDiffKind::Insert, len: right_data_len, + symbol: String::new(), }); } LevEditType::Delete => { @@ -446,15 +548,35 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: left_data, kind: ObjDataDiffKind::Delete, len: left_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: vec![], kind: ObjDataDiffKind::Delete, len: left_data_len, + symbol: String::new(), }); } } } + if left_cur < op.first_start { + left_diff.push(ObjDataDiff { + data: left.data[left_cur..op.first_start].to_vec(), + kind: ObjDataDiffKind::None, + len: op.first_start - left_cur, + symbol: String::new(), + }); + left_cur = op.first_start; + } + if right_cur < op.second_start { + right_diff.push(ObjDataDiff { + data: right.data[right_cur..op.second_start].to_vec(), + kind: ObjDataDiffKind::None, + len: op.second_start - right_cur, + symbol: String::new(), + }); + right_cur = op.second_start; + } match op.op_type { LevEditType::Replace => { cur_left_data.push(left.data[left_cur]); @@ -504,11 +626,13 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: left_data, kind: ObjDataDiffKind::Replace, len: left_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: right_data, kind: ObjDataDiffKind::Replace, len: right_data_len, + symbol: String::new(), }); } LevEditType::Insert => { @@ -518,11 +642,13 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: vec![], kind: ObjDataDiffKind::Insert, len: right_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: right_data, kind: ObjDataDiffKind::Insert, len: right_data_len, + symbol: String::new(), }); } LevEditType::Delete => { @@ -532,15 +658,34 @@ fn diff_data(left: &mut ObjSection, right: &mut ObjSection) { data: left_data, kind: ObjDataDiffKind::Delete, len: left_data_len, + symbol: String::new(), }); right_diff.push(ObjDataDiff { data: vec![], kind: ObjDataDiffKind::Delete, len: left_data_len, + symbol: String::new(), }); } } + if left_cur < left.data.len() { + left_diff.push(ObjDataDiff { + data: left.data[left_cur..].to_vec(), + kind: ObjDataDiffKind::None, + len: left.data.len() - left_cur, + symbol: String::new(), + }); + } + if right_cur < right.data.len() { + right_diff.push(ObjDataDiff { + data: right.data[right_cur..].to_vec(), + kind: ObjDataDiffKind::None, + len: right.data.len() - right_cur, + symbol: String::new(), + }); + } + left.data_diff = left_diff; right.data_diff = right_diff; } diff --git a/src/editops.rs b/src/editops.rs index 0e55a0b..597230d 100644 --- a/src/editops.rs +++ b/src/editops.rs @@ -47,7 +47,8 @@ pub struct LevMatchingBlock { pub len: usize, } -pub fn editops_find(query: &[u8], choice: &[u8]) -> Vec { +pub fn editops_find(query: &[T], choice: &[T]) -> Vec +where T: PartialEq { let string_affix = Affix::find(query, choice); let first_string_len = string_affix.first_string_len; @@ -96,14 +97,17 @@ pub fn editops_find(query: &[u8], choice: &[u8]) -> Vec { ) } -fn editops_from_cost_matrix( - string1: &[u8], - string2: &[u8], +fn editops_from_cost_matrix( + string1: &[T], + string2: &[T], len1: usize, len2: usize, prefix_len: usize, cache_matrix: Vec, -) -> Vec { +) -> Vec +where + T: PartialEq, +{ let mut dir = 0; let mut ops: Vec = vec![]; @@ -187,7 +191,8 @@ pub struct Affix { } impl Affix { - pub fn find(first_string: &[u8], second_string: &[u8]) -> Affix { + pub fn find(first_string: &[T], second_string: &[T]) -> Affix + where T: PartialEq { // remove common prefix and suffix (linear vs square runtime for levensthein) let mut first_iter = first_string.iter(); let mut second_iter = second_string.iter(); diff --git a/src/jobs/bindiff.rs b/src/jobs/bindiff.rs index ee8b22a..bbc0bab 100644 --- a/src/jobs/bindiff.rs +++ b/src/jobs/bindiff.rs @@ -38,7 +38,7 @@ fn run_build( } pub fn queue_bindiff(config: Arc>) -> JobState { - queue_job(Job::BinDiff, move |status, cancel| { + queue_job("Binary diff", Job::BinDiff, move |status, cancel| { run_build(status, cancel, config).map(JobResult::BinDiff) }) } diff --git a/src/jobs/check_update.rs b/src/jobs/check_update.rs new file mode 100644 index 0000000..c4ac1f8 --- /dev/null +++ b/src/jobs/check_update.rs @@ -0,0 +1,33 @@ +use std::sync::mpsc::Receiver; + +use anyhow::{Context, Result}; +use self_update::{cargo_crate_version, update::Release}; + +use crate::{ + jobs::{queue_job, update_status, Job, JobResult, JobState, Status}, + update::{build_updater, BIN_NAME}, +}; + +pub struct CheckUpdateResult { + pub update_available: bool, + pub latest_release: Release, + pub found_binary: bool, +} + +fn run_check_update(status: &Status, cancel: Receiver<()>) -> Result> { + update_status(status, "Fetching latest release".to_string(), 0, 1, &cancel)?; + let updater = build_updater().context("Failed to create release updater")?; + let latest_release = updater.get_latest_release()?; + let update_available = + self_update::version::bump_is_greater(cargo_crate_version!(), &latest_release.version)?; + let found_binary = latest_release.assets.iter().any(|a| a.name == BIN_NAME); + + update_status(status, "Complete".to_string(), 1, 1, &cancel)?; + Ok(Box::new(CheckUpdateResult { update_available, latest_release, found_binary })) +} + +pub fn queue_check_update() -> JobState { + queue_job("Check for updates", Job::CheckUpdate, move |status, cancel| { + run_check_update(status, cancel).map(JobResult::CheckUpdate) + }) +} diff --git a/src/jobs/mod.rs b/src/jobs/mod.rs index b1081b2..606aed4 100644 --- a/src/jobs/mod.rs +++ b/src/jobs/mod.rs @@ -9,15 +9,22 @@ use std::{ use anyhow::Result; -use crate::jobs::{bindiff::BinDiffResult, objdiff::ObjDiffResult}; +use crate::jobs::{ + bindiff::BinDiffResult, check_update::CheckUpdateResult, objdiff::ObjDiffResult, + update::UpdateResult, +}; pub mod bindiff; +pub mod check_update; pub mod objdiff; +pub mod update; #[derive(Debug, Eq, PartialEq, Copy, Clone)] pub enum Job { ObjDiff, BinDiff, + CheckUpdate, + Update, } pub static JOB_ID: AtomicUsize = AtomicUsize::new(0); pub struct JobState { @@ -40,6 +47,8 @@ pub enum JobResult { None, ObjDiff(Box), BinDiff(Box), + CheckUpdate(Box), + Update(Box), } fn should_cancel(rx: &Receiver<()>) -> bool { @@ -52,14 +61,15 @@ fn should_cancel(rx: &Receiver<()>) -> bool { type Status = Arc>; fn queue_job( + title: &str, job_type: Job, run: impl FnOnce(&Status, Receiver<()>) -> Result + Send + 'static, ) -> JobState { let status = Arc::new(RwLock::new(JobStatus { - title: String::new(), + title: title.to_string(), progress_percent: 0.0, progress_items: None, - status: "".to_string(), + status: String::new(), error: None, })); let status_clone = status.clone(); diff --git a/src/jobs/objdiff.rs b/src/jobs/objdiff.rs index a31a866..f58063c 100644 --- a/src/jobs/objdiff.rs +++ b/src/jobs/objdiff.rs @@ -19,6 +19,7 @@ pub struct BuildStatus { pub success: bool, pub log: String, } + pub struct ObjDiffResult { pub first_status: BuildStatus, pub second_status: BuildStatus, @@ -29,7 +30,7 @@ pub struct ObjDiffResult { fn run_make(cwd: &Path, arg: &Path, config: &AppConfig) -> BuildStatus { match (|| -> Result { - let make = if config.custom_make.is_empty() { "make" } else { &config.custom_make }; + let make = config.custom_make.as_deref().unwrap_or("make"); #[cfg(not(windows))] let mut command = { let mut command = Command::new(make); @@ -136,7 +137,7 @@ fn run_build( } pub fn queue_build(config: Arc>, diff_config: DiffConfig) -> JobState { - queue_job(Job::ObjDiff, move |status, cancel| { + queue_job("Object diff", Job::ObjDiff, move |status, cancel| { run_build(status, cancel, config, diff_config).map(JobResult::ObjDiff) }) } diff --git a/src/jobs/update.rs b/src/jobs/update.rs new file mode 100644 index 0000000..0628403 --- /dev/null +++ b/src/jobs/update.rs @@ -0,0 +1,61 @@ +use std::{ + env::{current_dir, current_exe}, + fs, + fs::File, + path::PathBuf, + sync::mpsc::Receiver, +}; + +use anyhow::{Context, Result}; +use const_format::formatcp; + +use crate::{ + jobs::{queue_job, update_status, Job, JobResult, JobState, Status}, + update::{build_updater, BIN_NAME}, +}; + +pub struct UpdateResult { + pub exe_path: PathBuf, +} + +fn run_update(status: &Status, cancel: Receiver<()>) -> Result> { + update_status(status, "Fetching latest release".to_string(), 0, 3, &cancel)?; + let updater = build_updater().context("Failed to create release updater")?; + let latest_release = updater.get_latest_release()?; + let asset = latest_release + .assets + .iter() + .find(|a| a.name == BIN_NAME) + .ok_or(anyhow::Error::msg(formatcp!("No release asset for {}", BIN_NAME)))?; + + update_status(status, "Downloading release".to_string(), 1, 3, &cancel)?; + let tmp_dir = tempfile::Builder::new().prefix("update").tempdir_in(current_dir()?)?; + let tmp_path = tmp_dir.path().join(&asset.name); + let tmp_file = File::create(&tmp_path)?; + self_update::Download::from_url(&asset.download_url) + .set_header(reqwest::header::ACCEPT, "application/octet-stream".parse()?) + .download_to(&tmp_file)?; + + update_status(status, "Extracting release".to_string(), 2, 3, &cancel)?; + let tmp_file = tmp_dir.path().join("replacement_tmp"); + let target_file = current_exe()?; + self_update::Move::from_source(&tmp_path) + .replace_using_temp(&tmp_file) + .to_dest(&target_file)?; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = fs::metadata(&target_file)?.permissions(); + perms.set_mode(0755); + fs::set_permissions(&target_file, perms)?; + } + + update_status(status, "Complete".to_string(), 3, 3, &cancel)?; + Ok(Box::from(UpdateResult { exe_path: target_file })) +} + +pub fn queue_update() -> JobState { + queue_job("Update app", Job::Update, move |status, cancel| { + run_update(status, cancel).map(JobResult::Update) + }) +} diff --git a/src/lib.rs b/src/lib.rs index 0ffed1d..6d11985 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,4 +7,5 @@ mod diff; mod editops; mod jobs; mod obj; +mod update; mod views; diff --git a/src/main.rs b/src/main.rs index 06b9960..e423f22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ #![warn(clippy::all, rust_2018_idioms)] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release +use std::{path::PathBuf, rc::Rc, sync::Mutex}; + +use cfg_if::cfg_if; use time::UtcOffset; // When compiling natively: @@ -12,15 +15,40 @@ fn main() { // Because localtime_r is unsound in multithreaded apps, // we must call this before initializing eframe. // https://github.com/time-rs/time/issues/293 - let utc_offset = UtcOffset::current_local_offset().unwrap(); + let utc_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); + let exec_path: Rc>> = Rc::new(Mutex::new(None)); + let exec_path_clone = exec_path.clone(); let native_options = eframe::NativeOptions::default(); // native_options.renderer = eframe::Renderer::Wgpu; eframe::run_native( "objdiff", native_options, - Box::new(move |cc| Box::new(objdiff::App::new(cc, utc_offset))), + Box::new(move |cc| Box::new(objdiff::App::new(cc, utc_offset, exec_path_clone))), ); + + // Attempt to relaunch application from the updated path + if let Ok(mut guard) = exec_path.lock() { + if let Some(path) = guard.take() { + cfg_if! { + if #[cfg(unix)] { + let result = exec::Command::new(path) + .args(&std::env::args().collect::>()) + .exec(); + eprintln!("Failed to relaunch: {:?}", result); + } else { + let result = std::process::Command::new(path) + .args(std::env::args()) + .spawn() + .unwrap() + .wait(); + if let Err(e) = result { + eprintln!("Failed to relaunch: {:?}", e); + } + } + } + } + }; } // when compiling to web using trunk. diff --git a/src/obj/elf.rs b/src/obj/elf.rs index be1cdfc..887e670 100644 --- a/src/obj/elf.rs +++ b/src/obj/elf.rs @@ -63,7 +63,7 @@ fn to_obj_symbol(obj_file: &File<'_>, symbol: &Symbol<'_, '_>, addend: i64) -> R addend, diff_symbol: None, instructions: vec![], - match_percent: 0.0, + match_percent: None, }) } @@ -81,7 +81,7 @@ fn filter_sections(obj_file: &File<'_>) -> Result> { continue; } let name = section.name().context("Failed to process section name")?; - let data = section.data().context("Failed to read section data")?; + let data = section.uncompressed_data().context("Failed to read section data")?; result.push(ObjSection { name: name.to_string(), kind: to_obj_section_kind(section.kind()), @@ -183,7 +183,7 @@ fn find_section_symbol( addend: offset_addr as i64, diff_symbol: None, instructions: vec![], - match_percent: 0.0, + match_percent: None, }) } @@ -290,8 +290,11 @@ fn relocations_by_section( } pub fn read(obj_path: &Path) -> Result { - let bin_data = fs::read(obj_path)?; - let obj_file = File::parse(&*bin_data)?; + let data = { + let file = fs::File::open(obj_path)?; + unsafe { memmap2::Mmap::map(&file) }? + }; + let obj_file = File::parse(&*data)?; let architecture = match obj_file.architecture() { Architecture::PowerPc => ObjArchitecture::PowerPc, Architecture::Mips => ObjArchitecture::Mips, diff --git a/src/obj/mod.rs b/src/obj/mod.rs index 97f2ab0..09e8389 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -109,6 +109,7 @@ pub struct ObjDataDiff { pub data: Vec, pub kind: ObjDataDiffKind, pub len: usize, + pub symbol: String, } #[derive(Debug, Clone)] pub struct ObjSymbol { @@ -124,7 +125,7 @@ pub struct ObjSymbol { // Diff pub diff_symbol: Option, pub instructions: Vec, - pub match_percent: f32, + pub match_percent: Option, } #[derive(Debug, Copy, Clone)] pub enum ObjArchitecture { diff --git a/src/update.rs b/src/update.rs new file mode 100644 index 0000000..fcd33c9 --- /dev/null +++ b/src/update.rs @@ -0,0 +1,37 @@ +use cfg_if::cfg_if; +use const_format::formatcp; +use self_update::{cargo_crate_version, update::ReleaseUpdate}; + +pub const OS: &str = std::env::consts::OS; +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + cfg_if! { + if #[cfg(any(windows, target_os = "macos"))] { + pub const ARCH: &str = "arm64"; + } else { + pub const ARCH: &str = std::env::consts::ARCH; + } + } + } else if #[cfg(target_arch = "arm")] { + pub const ARCH: &str = "armv7l"; + } else { + pub const ARCH: &str = std::env::consts::ARCH; + } +} +pub const GITHUB_USER: &str = "encounter"; +pub const GITHUB_REPO: &str = "objdiff"; +pub const BIN_NAME: &str = + formatcp!("{}-{}-{}{}", GITHUB_REPO, OS, ARCH, std::env::consts::EXE_SUFFIX); +pub const RELEASE_URL: &str = + formatcp!("https://github.com/{}/{}/releases/latest", GITHUB_USER, GITHUB_REPO); + +pub fn build_updater() -> self_update::errors::Result> { + self_update::backends::github::Update::configure() + .repo_owner(GITHUB_USER) + .repo_name(GITHUB_REPO) + .bin_name(BIN_NAME) + .no_confirm(true) + .show_output(false) + .current_version(cargo_crate_version!()) + .build() +} diff --git a/src/views/config.rs b/src/views/config.rs index fa17944..6e6e096 100644 --- a/src/views/config.rs +++ b/src/views/config.rs @@ -4,10 +4,14 @@ use std::sync::{Arc, RwLock}; #[cfg(windows)] use anyhow::{Context, Result}; +use const_format::formatcp; +use egui::{output::OpenUrl, Color32}; +use self_update::cargo_crate_version; use crate::{ app::{AppConfig, DiffKind, ViewState}, - jobs::{bindiff::queue_bindiff, objdiff::queue_build}, + jobs::{bindiff::queue_bindiff, objdiff::queue_build, update::queue_update}, + update::RELEASE_URL, }; #[cfg(windows)] @@ -57,8 +61,50 @@ pub fn config_ui(ui: &mut egui::Ui, config: &Arc>, view_state: left_obj, right_obj, project_dir_change, + queue_update_check, + auto_update_check, } = &mut *config_guard; + ui.heading("Updates"); + ui.checkbox(auto_update_check, "Check for updates on startup"); + if ui.button("Check now").clicked() { + *queue_update_check = true; + } + ui.label(format!("Current version: {}", cargo_crate_version!())).on_hover_ui_at_pointer(|ui| { + ui.label(formatcp!("Git branch: {}", env!("VERGEN_GIT_BRANCH"))); + ui.label(formatcp!("Git commit: {}", env!("VERGEN_GIT_SHA"))); + ui.label(formatcp!("Build target: {}", env!("VERGEN_CARGO_TARGET_TRIPLE"))); + ui.label(formatcp!("Build type: {}", env!("VERGEN_CARGO_PROFILE"))); + }); + if let Some(state) = &view_state.check_update { + ui.label(format!("Latest version: {}", state.latest_release.version)); + if state.update_available { + ui.colored_label(Color32::LIGHT_GREEN, "Update available"); + ui.horizontal(|ui| { + if state.found_binary { + if ui + .button("Automatic") + .on_hover_text_at_pointer( + "Automatically download and replace the current build", + ) + .clicked() + { + view_state.jobs.push(queue_update()); + } + } + if ui + .button("Manual") + .on_hover_text_at_pointer("Open a link to the latest release on GitHub") + .clicked() + { + ui.output().open_url = + Some(OpenUrl { url: RELEASE_URL.to_string(), new_tab: true }); + } + }); + } + } + ui.separator(); + ui.heading("Build config"); #[cfg(windows)] @@ -82,7 +128,14 @@ pub fn config_ui(ui: &mut egui::Ui, config: &Arc>, view_state: } ui.label("Custom make program:"); - ui.text_edit_singleline(custom_make); + let mut custom_make_str = custom_make.clone().unwrap_or_default(); + if ui.text_edit_singleline(&mut custom_make_str).changed() { + if custom_make_str.is_empty() { + *custom_make = None; + } else { + *custom_make = Some(custom_make_str); + } + } ui.separator(); diff --git a/src/views/data_diff.rs b/src/views/data_diff.rs index d9e8919..5df3e10 100644 --- a/src/views/data_diff.rs +++ b/src/views/data_diff.rs @@ -5,10 +5,10 @@ use egui_extras::{Size, StripBuilder, TableBuilder}; use time::format_description; use crate::{ - app::{View, ViewState}, + app::{View, ViewConfig, ViewState}, jobs::Job, obj::{ObjDataDiff, ObjDataDiffKind, ObjInfo, ObjSection}, - views::{write_text, COLOR_RED, FONT_SIZE}, + views::{write_text, COLOR_RED}, }; const BYTES_PER_ROW: usize = 16; @@ -17,12 +17,17 @@ fn find_section<'a>(obj: &'a ObjInfo, section_name: &str) -> Option<&'a ObjSecti obj.sections.iter().find(|s| s.name == section_name) } -fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { +fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff], config: &ViewConfig) { if diffs.iter().any(|d| d.kind != ObjDataDiffKind::None) { ui.painter().rect_filled(ui.available_rect_before_wrap(), 0.0, ui.visuals().faint_bg_color); } let mut job = LayoutJob::default(); - write_text(format!("{:08X}: ", address).as_str(), Color32::GRAY, &mut job); + write_text( + format!("{:08X}: ", address).as_str(), + Color32::GRAY, + &mut job, + config.code_font.clone(), + ); let mut cur_addr = 0usize; for diff in diffs { let base_color = match diff.kind { @@ -34,7 +39,7 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { if diff.data.is_empty() { let mut str = " ".repeat(diff.len); str.push_str(" ".repeat(diff.len / 8).as_str()); - write_text(str.as_str(), base_color, &mut job); + write_text(str.as_str(), base_color, &mut job, config.code_font.clone()); cur_addr += diff.len; } else { let mut text = String::new(); @@ -45,7 +50,7 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { text.push(' '); } } - write_text(text.as_str(), base_color, &mut job); + write_text(text.as_str(), base_color, &mut job, config.code_font.clone()); } } if cur_addr < BYTES_PER_ROW { @@ -53,9 +58,9 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { let mut str = " ".to_string(); str.push_str(" ".repeat(n).as_str()); str.push_str(" ".repeat(n / 8).as_str()); - write_text(str.as_str(), Color32::GRAY, &mut job); + write_text(str.as_str(), Color32::GRAY, &mut job, config.code_font.clone()); } - write_text(" ", Color32::GRAY, &mut job); + write_text(" ", Color32::GRAY, &mut job, config.code_font.clone()); for diff in diffs { let base_color = match diff.kind { ObjDataDiffKind::None => Color32::GRAY, @@ -64,7 +69,12 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { ObjDataDiffKind::Insert => Color32::GREEN, }; if diff.data.is_empty() { - write_text(" ".repeat(diff.len).as_str(), base_color, &mut job); + write_text( + " ".repeat(diff.len).as_str(), + base_color, + &mut job, + config.code_font.clone(), + ); } else { let mut text = String::new(); for byte in &diff.data { @@ -75,7 +85,7 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff]) { text.push('.'); } } - write_text(text.as_str(), base_color, &mut job); + write_text(text.as_str(), base_color, &mut job, config.code_font.clone()); } } ui.add(Label::new(job).sense(Sense::click())); @@ -101,6 +111,8 @@ fn split_diffs(diffs: &[ObjDataDiff]) -> Vec> { }, kind: diff.kind, len, + // TODO + symbol: String::new(), }); remaining_in_row -= len; cur_len += len; @@ -121,6 +133,7 @@ fn data_table_ui( left_obj: &ObjInfo, right_obj: &ObjInfo, section_name: &str, + config: &ViewConfig, ) -> Option<()> { let left_section = find_section(left_obj, section_name)?; let right_section = find_section(right_obj, section_name)?; @@ -135,13 +148,13 @@ fn data_table_ui( let right_diffs = split_diffs(&right_section.data_diff); table.body(|body| { - body.rows(FONT_SIZE, total_rows, |row_index, mut row| { + body.rows(config.code_font.size, total_rows, |row_index, mut row| { let address = row_index * BYTES_PER_ROW; row.col(|ui| { - data_row_ui(ui, address, &left_diffs[row_index]); + data_row_ui(ui, address, &left_diffs[row_index], config); }); row.col(|ui| { - data_row_ui(ui, address, &right_diffs[row_index]); + data_row_ui(ui, address, &right_diffs[row_index], config); }); }); }); @@ -233,7 +246,13 @@ pub fn data_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool { .column(Size::relative(0.5)) .column(Size::relative(0.5)) .resizable(false); - data_table_ui(table, left_obj, right_obj, selected_symbol); + data_table_ui( + table, + left_obj, + right_obj, + selected_symbol, + &view_state.view_config, + ); } }); }); diff --git a/src/views/function_diff.rs b/src/views/function_diff.rs index f93548c..15e4e7c 100644 --- a/src/views/function_diff.rs +++ b/src/views/function_diff.rs @@ -1,62 +1,62 @@ use std::default::Default; use cwdemangle::demangle; -use egui::{text::LayoutJob, Color32, Label, Sense}; +use egui::{text::LayoutJob, Color32, FontId, Label, Sense}; use egui_extras::{Size, StripBuilder, TableBuilder}; use ppc750cl::Argument; use time::format_description; use crate::{ - app::{View, ViewState}, + app::{View, ViewConfig, ViewState}, jobs::Job, obj::{ ObjInfo, ObjIns, ObjInsArg, ObjInsArgDiff, ObjInsDiff, ObjInsDiffKind, ObjReloc, ObjRelocKind, ObjSymbol, }, - views::{symbol_diff::match_color_for_symbol, write_text, COLOR_RED, FONT_SIZE}, + views::{symbol_diff::match_color_for_symbol, write_text, COLOR_RED}, }; -fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob) { +fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) { let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name); - write_text(name, Color32::LIGHT_GRAY, job); + write_text(name, Color32::LIGHT_GRAY, job, font_id.clone()); if reloc.target.addend != 0 { - write_text(&format!("+{:X}", reloc.target.addend), color, job); + write_text(&format!("+{:X}", reloc.target.addend), color, job, font_id.clone()); } } -fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob) { +fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) { match reloc.kind { ObjRelocKind::PpcAddr16Lo => { - write_reloc_name(reloc, color, job); - write_text("@l", color, job); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text("@l", color, job, font_id.clone()); } ObjRelocKind::PpcAddr16Hi => { - write_reloc_name(reloc, color, job); - write_text("@h", color, job); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text("@h", color, job, font_id.clone()); } ObjRelocKind::PpcAddr16Ha => { - write_reloc_name(reloc, color, job); - write_text("@ha", color, job); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text("@ha", color, job, font_id.clone()); } ObjRelocKind::PpcEmbSda21 => { - write_reloc_name(reloc, color, job); - write_text("@sda21", color, job); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text("@sda21", color, job, font_id.clone()); } ObjRelocKind::MipsHi16 => { - write_text("%hi(", color, job); - write_reloc_name(reloc, color, job); - write_text(")", color, job); + write_text("%hi(", color, job, font_id.clone()); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text(")", color, job, font_id.clone()); } ObjRelocKind::MipsLo16 => { - write_text("%lo(", color, job); - write_reloc_name(reloc, color, job); - write_text(")", color, job); + write_text("%lo(", color, job, font_id.clone()); + write_reloc_name(reloc, color, job, font_id.clone()); + write_text(")", color, job, font_id.clone()); } ObjRelocKind::Absolute | ObjRelocKind::PpcRel24 | ObjRelocKind::PpcRel14 | ObjRelocKind::Mips26 => { - write_reloc_name(reloc, color, job); + write_reloc_name(reloc, color, job, font_id.clone()); } }; } @@ -67,6 +67,7 @@ fn write_ins( args: &[Option], base_addr: u32, job: &mut LayoutJob, + config: &ViewConfig, ) { let base_color = match diff_kind { ObjInsDiffKind::None | ObjInsDiffKind::OpMismatch | ObjInsDiffKind::ArgMismatch => { @@ -83,54 +84,60 @@ fn write_ins( _ => base_color, }, job, + config.code_font.clone(), ); let mut writing_offset = false; for (i, arg) in ins.args.iter().enumerate() { if i == 0 { - write_text(" ", base_color, job); + write_text(" ", base_color, job, config.code_font.clone()); } if i > 0 && !writing_offset { - write_text(", ", base_color, job); + write_text(", ", base_color, job, config.code_font.clone()); } let color = if let Some(diff) = args.get(i).and_then(|a| a.as_ref()) { - COLOR_ROTATION[diff.idx % COLOR_ROTATION.len()] + config.diff_colors[diff.idx % config.diff_colors.len()] } else { base_color }; match arg { ObjInsArg::PpcArg(arg) => match arg { Argument::Offset(val) => { - write_text(&format!("{}", val), color, job); - write_text("(", base_color, job); + write_text(&format!("{}", val), color, job, config.code_font.clone()); + write_text("(", base_color, job, config.code_font.clone()); writing_offset = true; continue; } Argument::Uimm(_) | Argument::Simm(_) => { - write_text(&format!("{}", arg), color, job); + write_text(&format!("{}", arg), color, job, config.code_font.clone()); } _ => { - write_text(&format!("{}", arg), color, job); + write_text(&format!("{}", arg), color, job, config.code_font.clone()); } }, ObjInsArg::Reloc => { - write_reloc(ins.reloc.as_ref().unwrap(), base_color, job); + write_reloc(ins.reloc.as_ref().unwrap(), base_color, job, config.code_font.clone()); } ObjInsArg::RelocWithBase => { - write_reloc(ins.reloc.as_ref().unwrap(), base_color, job); - write_text("(", base_color, job); + write_reloc(ins.reloc.as_ref().unwrap(), base_color, job, config.code_font.clone()); + write_text("(", base_color, job, config.code_font.clone()); writing_offset = true; continue; } ObjInsArg::MipsArg(str) => { - write_text(str.strip_prefix('$').unwrap_or(str), color, job); + write_text( + str.strip_prefix('$').unwrap_or(str), + color, + job, + config.code_font.clone(), + ); } ObjInsArg::BranchOffset(offset) => { let addr = offset + ins.address as i32 - base_addr as i32; - write_text(&format!("{:x}", addr), color, job); + write_text(&format!("{:x}", addr), color, job, config.code_font.clone()); } } if writing_offset { - write_text(")", base_color, job); + write_text(")", base_color, job, config.code_font.clone()); writing_offset = false; } } @@ -233,24 +240,12 @@ fn ins_context_menu(ui: &mut egui::Ui, ins: &ObjIns) { }); } -const COLOR_ROTATION: [Color32; 9] = [ - Color32::from_rgb(255, 0, 255), - Color32::from_rgb(0, 255, 255), - Color32::from_rgb(0, 128, 0), - Color32::from_rgb(255, 0, 0), - Color32::from_rgb(255, 255, 0), - Color32::from_rgb(255, 192, 203), - Color32::from_rgb(0, 0, 255), - Color32::from_rgb(0, 255, 0), - Color32::from_rgb(128, 128, 128), -]; - fn find_symbol<'a>(obj: &'a ObjInfo, section_name: &str, name: &str) -> Option<&'a ObjSymbol> { let section = obj.sections.iter().find(|s| s.name == section_name)?; section.symbols.iter().find(|s| s.name == name) } -fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol) { +fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol, config: &ViewConfig) { if ins_diff.kind != ObjInsDiffKind::None { ui.painter().rect_filled(ui.available_rect_before_wrap(), 0.0, ui.visuals().faint_bg_color); } @@ -268,15 +263,26 @@ fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol) { &format!("{:<6}", format!("{:x}:", ins.address - symbol.address as u32)), base_color, &mut job, + config.code_font.clone(), ); if let Some(branch) = &ins_diff.branch_from { - write_text("~> ", COLOR_ROTATION[branch.branch_idx % COLOR_ROTATION.len()], &mut job); + write_text( + "~> ", + config.diff_colors[branch.branch_idx % config.diff_colors.len()], + &mut job, + config.code_font.clone(), + ); } else { - write_text(" ", base_color, &mut job); + write_text(" ", base_color, &mut job, config.code_font.clone()); } - write_ins(ins, &ins_diff.kind, &ins_diff.arg_diff, symbol.address as u32, &mut job); + write_ins(ins, &ins_diff.kind, &ins_diff.arg_diff, symbol.address as u32, &mut job, config); if let Some(branch) = &ins_diff.branch_to { - write_text(" ~>", COLOR_ROTATION[branch.branch_idx % COLOR_ROTATION.len()], &mut job); + write_text( + " ~>", + config.diff_colors[branch.branch_idx % config.diff_colors.len()], + &mut job, + config.code_font.clone(), + ); } ui.add(Label::new(job).sense(Sense::click())) .on_hover_ui_at_pointer(|ui| ins_hover_ui(ui, ins)) @@ -291,16 +297,22 @@ fn asm_table_ui( left_obj: &ObjInfo, right_obj: &ObjInfo, fn_name: &str, + config: &ViewConfig, ) -> Option<()> { - let left_symbol = find_symbol(left_obj, ".text", fn_name)?; - let right_symbol = find_symbol(right_obj, ".text", fn_name)?; + let left_symbol = find_symbol(left_obj, ".text", fn_name); + let right_symbol = find_symbol(right_obj, ".text", fn_name); + let instructions_len = left_symbol.or(right_symbol).map(|s| s.instructions.len())?; table.body(|body| { - body.rows(FONT_SIZE, left_symbol.instructions.len(), |row_index, mut row| { + body.rows(config.code_font.size, instructions_len, |row_index, mut row| { row.col(|ui| { - asm_row_ui(ui, &left_symbol.instructions[row_index], left_symbol); + if let Some(symbol) = left_symbol { + asm_row_ui(ui, &symbol.instructions[row_index], symbol, config); + } }); row.col(|ui| { - asm_row_ui(ui, &right_symbol.instructions[row_index], right_symbol); + if let Some(symbol) = right_symbol { + asm_row_ui(ui, &symbol.instructions[row_index], symbol, config); + } }); }); }); @@ -379,14 +391,16 @@ pub fn function_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool { ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace); ui.style_mut().wrap = Some(false); - if let Some(obj) = &result.second_obj { - if let Some(symbol) = find_symbol(obj, ".text", selected_symbol) - { - ui.colored_label( - match_color_for_symbol(symbol), - &format!("{:.0}%", symbol.match_percent), - ); - } + if let Some(match_percent) = result + .second_obj + .as_ref() + .and_then(|obj| find_symbol(obj, ".text", selected_symbol)) + .and_then(|symbol| symbol.match_percent) + { + ui.colored_label( + match_color_for_symbol(match_percent), + &format!("{:.0}%", match_percent), + ); } ui.label("Diff base:"); ui.separator(); @@ -404,7 +418,13 @@ pub fn function_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool { .column(Size::relative(0.5)) .column(Size::relative(0.5)) .resizable(false); - asm_table_ui(table, left_obj, right_obj, selected_symbol); + asm_table_ui( + table, + left_obj, + right_obj, + selected_symbol, + &view_state.view_config, + ); } }); }); diff --git a/src/views/jobs.rs b/src/views/jobs.rs index 377e70d..04821ed 100644 --- a/src/views/jobs.rs +++ b/src/views/jobs.rs @@ -2,13 +2,26 @@ use egui::{Color32, ProgressBar, Widget}; use crate::app::ViewState; -pub fn jobs_ui(ui: &mut egui::Ui, view_state: &ViewState) { +pub fn jobs_ui(ui: &mut egui::Ui, view_state: &mut ViewState) { ui.label("Jobs"); - for job in &view_state.jobs { + let mut remove_job: Option = None; + for (idx, job) in view_state.jobs.iter_mut().enumerate() { if let Ok(status) = job.status.read() { ui.group(|ui| { - ui.label(&status.title); + ui.horizontal(|ui| { + ui.label(&status.title); + if ui.small_button("✖").clicked() { + if job.handle.is_some() { + job.should_remove = true; + if let Err(e) = job.cancel.send(()) { + eprintln!("Failed to cancel job: {:?}", e); + } + } else { + remove_job = Some(idx); + } + } + }); let mut bar = ProgressBar::new(status.progress_percent); if let Some(items) = &status.progress_items { bar = bar.text(format!("{} / {}", items[0], items[1])); @@ -35,4 +48,8 @@ pub fn jobs_ui(ui: &mut egui::Ui, view_state: &ViewState) { }); } } + + if let Some(idx) = remove_job { + view_state.jobs.remove(idx); + } } diff --git a/src/views/mod.rs b/src/views/mod.rs index 908a905..3513fe0 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -1,4 +1,4 @@ -use egui::{text::LayoutJob, Color32, FontFamily, FontId, TextFormat}; +use egui::{text::LayoutJob, Color32, FontId, TextFormat}; pub(crate) mod config; pub(crate) mod data_diff; @@ -6,11 +6,8 @@ pub(crate) mod function_diff; pub(crate) mod jobs; pub(crate) mod symbol_diff; -const FONT_SIZE: f32 = 14.0; -const FONT_ID: FontId = FontId::new(FONT_SIZE, FontFamily::Monospace); - const COLOR_RED: Color32 = Color32::from_rgb(200, 40, 41); -fn write_text(str: &str, color: Color32, job: &mut LayoutJob) { - job.append(str, 0.0, TextFormat { font_id: FONT_ID, color, ..Default::default() }); +fn write_text(str: &str, color: Color32, job: &mut LayoutJob, font_id: FontId) { + job.append(str, 0.0, TextFormat { font_id, color, ..Default::default() }); } diff --git a/src/views/symbol_diff.rs b/src/views/symbol_diff.rs index e6725ac..f80ff41 100644 --- a/src/views/symbol_diff.rs +++ b/src/views/symbol_diff.rs @@ -4,16 +4,16 @@ use egui::{ use egui_extras::{Size, StripBuilder}; use crate::{ - app::{View, ViewState}, + app::{View, ViewConfig, ViewState}, jobs::objdiff::BuildStatus, obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags}, views::write_text, }; -pub fn match_color_for_symbol(symbol: &ObjSymbol) -> Color32 { - if symbol.match_percent == 100.0 { +pub fn match_color_for_symbol(match_percent: f32) -> Color32 { + if match_percent == 100.0 { Color32::GREEN - } else if symbol.match_percent >= 50.0 { + } else if match_percent >= 50.0 { Color32::LIGHT_BLUE } else { Color32::RED @@ -45,7 +45,11 @@ fn symbol_hover_ui(ui: &mut Ui, symbol: &ObjSymbol) { ui.colored_label(Color32::WHITE, format!("Name: {}", symbol.name)); ui.colored_label(Color32::WHITE, format!("Address: {:x}", symbol.address)); - ui.colored_label(Color32::WHITE, format!("Size: {:x}", symbol.size)); + if symbol.size_known { + ui.colored_label(Color32::WHITE, format!("Size: {:x}", symbol.size)); + } else { + ui.colored_label(Color32::WHITE, format!("Size: {:x} (assumed)", symbol.size)); + } }); } @@ -56,6 +60,7 @@ fn symbol_ui( highlighted_symbol: &mut Option, selected_symbol: &mut Option, current_view: &mut View, + config: &ViewConfig, ) { let mut job = LayoutJob::default(); let name: &str = @@ -64,28 +69,29 @@ fn symbol_ui( if let Some(sym) = highlighted_symbol { selected = sym == &symbol.name; } - write_text("[", Color32::GRAY, &mut job); + write_text("[", Color32::GRAY, &mut job, config.code_font.clone()); if symbol.flags.0.contains(ObjSymbolFlags::Common) { - write_text("c", Color32::from_rgb(0, 255, 255), &mut job); + write_text("c", Color32::from_rgb(0, 255, 255), &mut job, config.code_font.clone()); } else if symbol.flags.0.contains(ObjSymbolFlags::Global) { - write_text("g", Color32::GREEN, &mut job); + write_text("g", Color32::GREEN, &mut job, config.code_font.clone()); } else if symbol.flags.0.contains(ObjSymbolFlags::Local) { - write_text("l", Color32::GRAY, &mut job); + write_text("l", Color32::GRAY, &mut job, config.code_font.clone()); } if symbol.flags.0.contains(ObjSymbolFlags::Weak) { - write_text("w", Color32::GRAY, &mut job); + write_text("w", Color32::GRAY, &mut job, config.code_font.clone()); } - write_text("] ", Color32::GRAY, &mut job); - if symbol.match_percent > 0.0 { - write_text("(", Color32::GRAY, &mut job); + write_text("] ", Color32::GRAY, &mut job, config.code_font.clone()); + if let Some(match_percent) = symbol.match_percent { + write_text("(", Color32::GRAY, &mut job, config.code_font.clone()); write_text( - &format!("{:.0}%", symbol.match_percent), - match_color_for_symbol(symbol), + &format!("{:.0}%", match_percent), + match_color_for_symbol(match_percent), &mut job, + config.code_font.clone(), ); - write_text(") ", Color32::GRAY, &mut job); + write_text(") ", Color32::GRAY, &mut job, config.code_font.clone()); } - write_text(name, Color32::WHITE, &mut job); + write_text(name, Color32::WHITE, &mut job, config.code_font.clone()); let response = SelectableLabel::new(selected, job) .ui(ui) .context_menu(|ui| symbol_context_menu_ui(ui, symbol)) @@ -123,6 +129,7 @@ fn symbol_list_ui( current_view: &mut View, reverse_function_order: bool, search: &mut String, + config: &ViewConfig, ) { ui.text_edit_singleline(search); let lower_search = search.to_ascii_lowercase(); @@ -142,6 +149,7 @@ fn symbol_list_ui( highlighted_symbol, selected_symbol, current_view, + config, ); } }); @@ -163,6 +171,7 @@ fn symbol_list_ui( highlighted_symbol, selected_symbol, current_view, + config, ); } } else { @@ -177,6 +186,7 @@ fn symbol_list_ui( highlighted_symbol, selected_symbol, current_view, + config, ); } } @@ -255,6 +265,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) { current_view, view_state.reverse_fn_order, search, + &view_state.view_config, ); }); } @@ -274,6 +285,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) { current_view, view_state.reverse_fn_order, search, + &view_state.view_config, ); }); }