mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
2029 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac76107940 | |||
| c25fe53251 | |||
| 4137b3829a | |||
| 0bb08049bf | |||
| 293576f6d6 | |||
| 0bc725c5f6 | |||
| c1c735001c | |||
| e350cce99e | |||
| 1c24cb3ebb | |||
| 0662af17f4 | |||
| 9fee532cb6 | |||
| 57f88d2167 | |||
| ed879ee53c | |||
| 6eae425679 | |||
| 182c90b22c | |||
| 2c2e0582a9 | |||
| 4216d40696 | |||
| af6f395ba3 | |||
| 3fda6e425a | |||
| 82581aa9e4 | |||
| 6bd515fed4 | |||
| 20970c6b71 | |||
| 532007267c | |||
| 87a4758497 | |||
| 6a9cce62ab | |||
| 2816ea3797 | |||
| 5144081971 | |||
| ccfe961a1f | |||
| 97211df285 | |||
| 4868517d53 | |||
| 2979bfe4ca | |||
| 42fd1a9cd7 | |||
| 36298b8e93 | |||
| 7168cc2ef2 | |||
| c398dc6c07 | |||
| 390801aee7 | |||
| e3f5563f8d | |||
| 4a54b20c68 | |||
| ea3d904bfe | |||
| 67f4b991d7 | |||
| 53922779ba | |||
| 1431cdcc83 | |||
| 968a43cb29 | |||
| 0c522bdc10 | |||
| 5db3c903e5 | |||
| 91c23c533a | |||
| 00721630ce | |||
| 167b130011 | |||
| aca502e9a0 | |||
| 36f18d0961 | |||
| e67a6856ce | |||
| 3a0b132001 | |||
| f63f31db0a | |||
| 96d60184d5 | |||
| 919bd8231e | |||
| 41fed1da5f | |||
| a846780382 | |||
| c10d7a8233 | |||
| cdcc976cd3 | |||
| b52e812c2c | |||
| aa45945b57 | |||
| eea6e81276 | |||
| 0bac93093b | |||
| 7bcb015a06 | |||
| 02bdcd355c | |||
| fa90e01bc5 | |||
| 1dec514129 | |||
| f81d09bddc | |||
| 03916b6a1d | |||
| 5338583c48 | |||
| 6c492882a3 | |||
| 98c7c7ed4f | |||
| a7a96a8954 | |||
| 1a5044add9 | |||
| 7befd71069 | |||
| 3d44a1befe | |||
| 57e734e628 | |||
| 3eadd332bb | |||
| 825db4fead | |||
| ad5be0f0c2 | |||
| 6d22a76946 | |||
| 40e977be31 | |||
| 29d93d5c67 | |||
| 9b2c59936f | |||
| bb02ba0b2e | |||
| 0987f68409 | |||
| 647403fc30 | |||
| 854a7cfeba | |||
| f78f6ceb54 | |||
| 975081aa27 | |||
| b0d3e7ef9e | |||
| 6fe0eb5677 | |||
| 42c03b2383 | |||
| b1319b34e7 | |||
| 5162b4fdec | |||
| 42f647378a | |||
| 97b3938dd5 | |||
| 2e46b5932e | |||
| 4510ef7e1c | |||
| 36bf978dc1 | |||
| 7f999dfaaf | |||
| 6f6a68f7e5 | |||
| 960bbfef59 | |||
| cabd5899f7 | |||
| 730c0d1c92 | |||
| ce6041938a | |||
| 998193b014 | |||
| f8ba138b8d | |||
| 3f9462d7c8 | |||
| 413984963e | |||
| 5aab0e2dd9 | |||
| 1ba5e6e8f7 | |||
| 2a53b012ea | |||
| 5d44efbf62 | |||
| 6ad83af2b5 | |||
| fceb19affe | |||
| ee7d3d471e | |||
| 8e9c571293 | |||
| a44b8264af | |||
| 84a5a4033e | |||
| f2fc92dbf7 | |||
| 2af338f425 | |||
| 41aaaa3429 | |||
| f9597eba39 | |||
| b4cd47cbc4 | |||
| 22de71efeb | |||
| ac654ff346 | |||
| df2fdf05e6 | |||
| 788307e98d | |||
| f93341ac61 | |||
| 3e0d97db2e | |||
| 864e707224 | |||
| c42b68404f | |||
| 18374467e6 | |||
| 499e6c85a0 | |||
| 0610faf1be | |||
| 778c6f0513 | |||
| c55ba2685f | |||
| aae66aa966 | |||
| a95b60167c | |||
| f5b987dba9 | |||
| f8eabdd8a6 | |||
| 5ab2c3456d | |||
| 97d9ffd193 | |||
| fa86bb1f0b | |||
| 5b9c5ebb5a | |||
| 56b03a93c5 | |||
| 3b319f0a1e | |||
| c3352d6d28 | |||
| f8426384d8 | |||
| 8791281b48 | |||
| 76ec8aff2e | |||
| 7660b0a091 | |||
| 7a8e484634 | |||
| ed01272b91 | |||
| 1c660caa85 | |||
| c241ead1d5 | |||
| 168d96a182 | |||
| 2075761282 | |||
| d59de1f158 | |||
| d64716ab74 | |||
| 0ffbb8c364 | |||
| c29960abf2 | |||
| 315cb24046 | |||
| 4cabc5684b | |||
| 256c9be19b | |||
| 1b3d713e50 | |||
| 6e816fca6e | |||
| 5a699af610 | |||
| 390119c592 | |||
| 11d7eec4db | |||
| f59be1faf2 | |||
| 7bc4c63eb4 | |||
| 4bf9f524d9 | |||
| 6508ccfc0d | |||
| d0a8d3cdc4 | |||
| 494cc1493e | |||
| 761c649817 | |||
| a2f576f3e5 | |||
| 3b9b03a086 | |||
| ab51a209d7 | |||
| 38ac339011 | |||
| b4777fe73a | |||
| b6e759f3a2 | |||
| 9ddefbc1a2 | |||
| a16851f5de | |||
| 8fe291d161 | |||
| 9ac50fc42f | |||
| c6e5221826 | |||
| 5b2006cd06 | |||
| d3f673dc6f | |||
| b99f444234 | |||
| c504096181 | |||
| c9ef47271a | |||
| fc3891c913 | |||
| cd07354b6f | |||
| fd5aeb2052 | |||
| b1b583721a | |||
| 4c3372a886 | |||
| cf66679323 | |||
| 55b41144db | |||
| ae34208247 | |||
| b462006280 | |||
| 485bcbf054 | |||
| 2e30a57889 | |||
| b439d9c203 | |||
| 08a717f5f7 | |||
| 3a84a1a5fa | |||
| 627d5fc659 | |||
| 25849dc4bb | |||
| 63032cd840 | |||
| 2414246de9 | |||
| c52353b4b8 | |||
| 799628c083 | |||
| 38d5791d57 | |||
| 9d664e2b61 | |||
| 2eb21e3521 | |||
| bfe1265c44 | |||
| dd3109cd89 | |||
| 130d5a5202 | |||
| cda4c62e9e | |||
| df245f32ec | |||
| 04409f4381 | |||
| 155e4a5b80 | |||
| 59a9209621 | |||
| cd5e14a834 | |||
| e707cf8464 | |||
| 8bdd410e97 | |||
| f45654620f | |||
| 72d138f8c4 | |||
| 6a0df7ae49 | |||
| 23def0a1c7 | |||
| 3236ef075d | |||
| d00b301904 | |||
| 6c82686283 | |||
| 399e2235d4 | |||
| bd898e4006 | |||
| 2c49dcceaf | |||
| 3c5b002414 | |||
| ca37206a49 | |||
| 8a939e981c | |||
| bed1b4cf0f | |||
| 04c3a4ccf7 | |||
| f50368a949 | |||
| 4e018dbf26 | |||
| fa02217ff4 | |||
| 22080d36b0 | |||
| 3303f4e1ce | |||
| 11d03ad59e | |||
| 504f1533c2 | |||
| bf1d1cbac5 | |||
| 94119d1674 | |||
| f4a263df01 | |||
| 533231825c | |||
| 40e2787d94 | |||
| 281af9c86f | |||
| fc0db8c291 | |||
| 48d2dbad34 | |||
| be2af8aeaf | |||
| a7621a7301 | |||
| ec87790e4f | |||
| 44632e9bf6 | |||
| 824ada49b6 | |||
| e7938216ba | |||
| 40d6d0b7b5 | |||
| 3f4d4c8eea | |||
| e2fe94d4e4 | |||
| debb5d8ad1 | |||
| f61794ea70 | |||
| d15a977431 | |||
| ef5268f78d | |||
| 7362808d5d | |||
| 27cfec68ed | |||
| ea85f40682 | |||
| 0cc38c20be | |||
| d29931a91a | |||
| 17c007348b | |||
| 33953a0d18 | |||
| 98e8e599a6 | |||
| 5e19838713 | |||
| 501803c873 | |||
| e9c2a43de1 | |||
| af94596202 | |||
| 42e87b498c | |||
| 839ff311de | |||
| ebab281471 | |||
| 582788645d | |||
| 643fed7d1c | |||
| 076324e60e | |||
| 1fe92738d8 | |||
| e319be19de | |||
| ab8448ee47 | |||
| 5493f418ed | |||
| 4e75fa958d | |||
| 0847432dd9 | |||
| e297144fe2 | |||
| 42cf88be9d | |||
| 6b008ed93b | |||
| c96d21c7c0 | |||
| 2feb53149a | |||
| e7df94495c | |||
| 42f6d029b0 | |||
| ccbb252466 | |||
| d16bdb30b9 | |||
| 8fa6aee571 | |||
| 4194e56912 | |||
| a0343d6bf7 | |||
| 44b417deca | |||
| 5ccd196ae4 | |||
| b76d6e9faa | |||
| 2d2e0ddc6d | |||
| 430da1578d | |||
| 1188db9475 | |||
| 685676bd0f | |||
| fa46dce0e1 | |||
| 2e60f34cd8 | |||
| dc50e24a29 | |||
| 1f23e93951 | |||
| 8df6409cb1 | |||
| 5c5c66d960 | |||
| 0b0e286b9c | |||
| b2130477ae | |||
| 085d0924db | |||
| 78249bf4f7 | |||
| 4c9d9f6223 | |||
| d7649d9f8f | |||
| 49e2acd15e | |||
| e4a6bf17e4 | |||
| 276e22f6b0 | |||
| b1d63e03d8 | |||
| 55f0f75c95 | |||
| fe4eb564e1 | |||
| 90ea096ca3 | |||
| 3077f885d8 | |||
| 41551ef200 | |||
| 4c96d0453e | |||
| d7ef7bc078 | |||
| c77a758741 | |||
| 12208b2c7c | |||
| 23d2cc3fdc | |||
| 1dfa0315db | |||
| f78f97a726 | |||
| 9972c61bbe | |||
| 8795d99f79 | |||
| f8aafb7ce4 | |||
| 27581d92b5 | |||
| 4a89b92185 | |||
| 1a4eb25194 | |||
| 3eb9acea2e | |||
| be860064c5 | |||
| 1985552636 | |||
| 985264d485 | |||
| e3c69c4569 | |||
| 45f523adb8 | |||
| f7cc4fb4b1 | |||
| ddec13be29 | |||
| 74ac023cb0 | |||
| 7f75d42ec8 | |||
| e53acf42ec | |||
| 18233a27c5 | |||
| 9857f48bb9 | |||
| 289976372f | |||
| 72d2ce4b43 | |||
| eb0faec74a | |||
| 767f99cffa | |||
| 7caa8d4618 | |||
| 88c12486bf | |||
| 8b357c27b4 | |||
| a7a8f2f461 | |||
| 5e5c0b4a58 | |||
| 154657b455 | |||
| 3866f27448 | |||
| b4f29918ed | |||
| b29b78b321 | |||
| 917b049030 | |||
| 4843dedb4d | |||
| 69373906ca | |||
| 24a6efa227 | |||
| 9004d9e05c | |||
| fa4fccd426 | |||
| 57bd741d96 | |||
| 50c8809d51 | |||
| e4c1ec916b | |||
| a4bc07cba5 | |||
| 40e542852f | |||
| bde2d67f25 | |||
| 6d1bde17c8 | |||
| ad0c2aa2e9 | |||
| ddbd198864 | |||
| 3e768ddfd4 | |||
| 6ccf8856b9 | |||
| 1caaa69deb | |||
| 5aa2798e42 | |||
| 597daddf2a | |||
| ff1c3d9888 | |||
| cc6cdb96fb | |||
| db5619541a | |||
| d94fc32f45 | |||
| 34723bba89 | |||
| a0efbd20a1 | |||
| 4d86c53e81 | |||
| 560c2acb88 | |||
| 592de4c8f2 | |||
| 8cbe3f6453 | |||
| ec8ee1a509 | |||
| 30ae8a2f96 | |||
| 5337e5cead | |||
| 576fcd7d3d | |||
| 64615e635f | |||
| 38c22bf771 | |||
| 064f624eab | |||
| 26e5790a78 | |||
| 48cecd0ad1 | |||
| 69e57e52ab | |||
| dbd6e45aba | |||
| 3714dfdca7 | |||
| 06b1051a7e | |||
| 8edb7d3833 | |||
| 8a14cbae0c | |||
| 7f727086af | |||
| 7cd79d34bb | |||
| 939165d4cf | |||
| b4f063e1da | |||
| bdc79a2995 | |||
| 2bb78af1a7 | |||
| d8e4575157 | |||
| b54e182c0f | |||
| fe89e71200 | |||
| fb69d56297 | |||
| 6c1b39ae60 | |||
| 2082e01555 | |||
| 24a9231ad0 | |||
| 3c7903cc14 | |||
| b721f9020e | |||
| bd02e5c632 | |||
| 0d5cf52f08 | |||
| f97cddf2da | |||
| 49f42cd003 | |||
| 0d7dc2d692 | |||
| 2039bed70d | |||
| 9535b6a8bf | |||
| df945e824b | |||
| 237c6f1c9e | |||
| 61131073f2 | |||
| 013abe2b3e | |||
| 63c29b10fe | |||
| f5ad07a87b | |||
| 28d40d9037 | |||
| b3bdf494ab | |||
| 8d914ace33 | |||
| 58f234638b | |||
| 7dfc0d8e60 | |||
| 2963e3bd93 | |||
| 3dfa99c232 | |||
| 804463a470 | |||
| 77466ba6f5 | |||
| 3a8819d42b | |||
| 9765885fe6 | |||
| 16b01a06e0 | |||
| c400261a11 | |||
| 9b72971dc9 | |||
| 4449173b3d | |||
| 10a249d3a8 | |||
| e91d011c8c | |||
| 4124c12bac | |||
| a927f4a04d | |||
| f3ec60a061 | |||
| 2251086c0f | |||
| 9447f1ca80 | |||
| f13b771317 | |||
| 257439477e | |||
| c702865332 | |||
| e2abe31fc1 | |||
| 82c300f7f6 | |||
| 94eb3b89e8 | |||
| f662cc0aa2 | |||
| 1526930e54 | |||
| 1cdc99f327 | |||
| d97b16950c | |||
| aff4a57092 | |||
| 826aa2e46d | |||
| 2c59a05dff | |||
| aafd773fe7 | |||
| 4356974c5b | |||
| 7f1e2d2f03 | |||
| cde2ba2c18 | |||
| a093ca2001 | |||
| fe9fcd603b | |||
| d8b2151143 | |||
| 904c9eb3c4 | |||
| 598dfd2b02 | |||
| 77d388ce1d | |||
| 9eb35d3967 | |||
| 34902db21c | |||
| cdaf5e9281 | |||
| 98833b4d74 | |||
| f995d8d806 | |||
| eb4636b947 | |||
| a7c6e1165c | |||
| 8bb88d1806 | |||
| 849ff95116 | |||
| dc29271987 | |||
| 623c5d8eb9 | |||
| e0ce520e0a | |||
| f9cd032a5f | |||
| 39b21f95b7 | |||
| dfbfb88a45 | |||
| 971a69ad1b | |||
| fddf6ddf1e | |||
| 81c625e7c9 | |||
| 97293ddee1 | |||
| 21f36b564f | |||
| 34e2b0f89c | |||
| d5ca6aa462 | |||
| 639ad436a0 | |||
| 76fce2c5a9 | |||
| 632718e1d0 | |||
| a4fababb71 | |||
| ac8741d57d | |||
| 28e412b79d | |||
| 01aa9b9516 | |||
| acd353b8b3 | |||
| c5d8d976f6 | |||
| 3d44514b24 | |||
| fb3fb1bf99 | |||
| 757e5f8174 | |||
| 3669f2aee4 | |||
| 14f26879de | |||
| 2f46a77ff2 | |||
| 10853fdf35 | |||
| 591fd558e1 | |||
| b863e65ea3 | |||
| fc61f64630 | |||
| 3483673ef7 | |||
| 9e839d3b8b | |||
| 33f121d7fb | |||
| 9500ca8f83 | |||
| 4dfbc0f909 | |||
| effb685fba | |||
| 3692e49e9b | |||
| 04d56d9b6a | |||
| 34417ae692 | |||
| 67d04a746e | |||
| 552e0f84aa | |||
| 3e880fedf7 | |||
| e5c4a6ed2c | |||
| 0bda7d80c2 | |||
| 7cb86df48d | |||
| 21e5df2826 | |||
| a5ee51e156 | |||
| bddcb4772c | |||
| a3f13bdca9 | |||
| 55444b9c4e | |||
| 2f14d7742e | |||
| 0534882f4e | |||
| ce2f2f4416 | |||
| 5259aeb039 | |||
| e51999edd1 | |||
| 2f96c847b9 | |||
| 32d6436027 | |||
| 7358326a13 | |||
| 434a879538 | |||
| 745a8dda65 | |||
| c40086615f | |||
| fe3d38e542 | |||
| f19a3b5549 | |||
| eb308e1861 | |||
| 9a4e7874d6 | |||
| d78e528527 | |||
| 81f0e4d583 | |||
| 1d9f462071 | |||
| 047dca3849 | |||
| 1f7c6ab70c | |||
| 1c49ae5324 | |||
| 2e82f8294f | |||
| b2ead8735b | |||
| 5e9166847d | |||
| 28c01599d5 | |||
| ce47a82fb5 | |||
| f1b047c32b | |||
| bc6ed4f4a2 | |||
| b1ac31f590 | |||
| 326d83f25b | |||
| 7218164088 | |||
| 6f970c36e3 | |||
| eea4150dbd | |||
| afa736c37d | |||
| 643e632368 | |||
| ffe354ab07 | |||
| f77090070c | |||
| fd5d2c84e8 | |||
| ef6af84ea1 | |||
| f64bf73279 | |||
| 157be8443d | |||
| 154e15e88f | |||
| 159122eb98 | |||
| 7b6e157a4d | |||
| c6eff111cc | |||
| f23384725f | |||
| 970863e7df | |||
| 0b473e3bff | |||
| 5a43adb62b | |||
| 1a4a949dfe | |||
| 069c20be40 | |||
| c7f0172b25 | |||
| 125759dc75 | |||
| f0a10fcc6d | |||
| c70b9cb84e | |||
| 5ebdd9a989 | |||
| 77e0d9dba1 | |||
| 55b9e274b6 | |||
| 67fe1e66b5 | |||
| ea2a26bd57 | |||
| 55b279ab09 | |||
| e5e4c8bf88 | |||
| c888254f70 | |||
| 75323d64f8 | |||
| a0c4f2febd | |||
| 4b714c7057 | |||
| 559bca4223 | |||
| 8ed28673a9 | |||
| ed9639c66b | |||
| 98b9ef74cf | |||
| e6be90614a | |||
| 20c2cdf7ba | |||
| c70787bde9 | |||
| 8835f66b8c | |||
| 2b2ebe0823 | |||
| 3ff3feb0e1 | |||
| ee4bc2302a | |||
| cd4a512291 | |||
| f6d4282a4f | |||
| a85da5401d | |||
| e19242d9f3 | |||
| 86dffe751f | |||
| 02adbb462a | |||
| 65d25446fe | |||
| b39c84f81e | |||
| 0291f35030 | |||
| 550011c5f1 | |||
| 1adbe9ee92 | |||
| 9bc1ec9f36 | |||
| 658598f43a | |||
| 290e721ee1 | |||
| a34980e339 | |||
| 0b5631471a | |||
| 082038f5fa | |||
| 1f265c5d5c | |||
| a87a0470ca | |||
| 97b779aefb | |||
| 46b0c6e76b | |||
| 519f3bfd50 | |||
| 045d7052d1 | |||
| d05cbc0af0 | |||
| 28d95c9f45 | |||
| 5a4de8b428 | |||
| b847fcac8b | |||
| 126034f33e | |||
| ff685a52b4 | |||
| 8493c99146 | |||
| 9177bc2b9b | |||
| d84bf00ca0 | |||
| d1a92f8cf9 | |||
| 8d7318c024 | |||
| 978e578e7a | |||
| 3c817ecf6d | |||
| add33186a8 | |||
| 75ba116146 | |||
| 0f8d757950 | |||
| 8151848a5a | |||
| f478b5bfb3 | |||
| 77f79dc5d7 | |||
| e0c59b9395 | |||
| b4ad245212 | |||
| 3bd4694a52 | |||
| 2f2856eacb | |||
| 33dc097c3f | |||
| 3bab3eddfc | |||
| fada8113c1 | |||
| e7487e24ae | |||
| 7965107347 | |||
| d8e221517b | |||
| 4b57e4261e | |||
| 6c156ebba4 | |||
| 921f3e3c34 | |||
| 44d02b3bfc | |||
| 008c9a597e | |||
| abae204ab8 | |||
| 1d1ce83567 | |||
| bb0279bae1 | |||
| 3acbe84570 | |||
| 7598e57704 | |||
| 5c603145ab | |||
| c28ced9dcb | |||
| a58db92ab8 | |||
| 38044acf75 | |||
| 4bef1274c8 | |||
| e7f05258fb | |||
| cebc5cd77a | |||
| 6071c1b09d | |||
| cc1a35e379 | |||
| 2c71568448 | |||
| 74233ac0cb | |||
| f1d4611a7d | |||
| eef8040ea9 | |||
| 97f3860d1e | |||
| 16aedae843 | |||
| a971f6d933 | |||
| 0c2edd4064 | |||
| 819c78e74c | |||
| f2b3418482 | |||
| c1b75c0e4d | |||
| f42fb5365f | |||
| 1d1dc56ec1 | |||
| fa13906e47 | |||
| 26bb2dc998 | |||
| f659595066 | |||
| 7d347a9b46 | |||
| 34e2af4c4b | |||
| 897d1e7a11 | |||
| e4a99b2d6d | |||
| c0317e2086 | |||
| 04ede28dbe | |||
| 9686467886 | |||
| 0c86e458ce | |||
| 5137b7d646 | |||
| df374f8234 | |||
| 172b3b2968 | |||
| 81f7861147 | |||
| f1ec86a371 | |||
| aa49877610 | |||
| 5562bc6264 | |||
| a986edbffb | |||
| 674618930d | |||
| 9e64e66254 | |||
| ca31f67c82 | |||
| fd8794e6c8 | |||
| b4d1c97d2c | |||
| f906d02720 | |||
| 6e7652e5be | |||
| 4f54eab672 | |||
| b3f8798f73 | |||
| 893f45e6b1 | |||
| 2a39fd35a3 | |||
| 0bc8ccd870 | |||
| 2fa7f1157f | |||
| 90bf6cbe44 | |||
| 09f73235aa | |||
| c78c18d63a | |||
| 5291d1a190 | |||
| 124a49098e | |||
| 340f2b2374 | |||
| a2b00cbf9e | |||
| 7abf91aa7f | |||
| be93714fd3 | |||
| 7147029c96 | |||
| 92b1d74d12 | |||
| 5fcf5b7f64 | |||
| af2c6a832e | |||
| c9741d1662 | |||
| de3cb1f855 | |||
| 8cbeb709f9 | |||
| 2f0d0a5a02 | |||
| 841be619ba | |||
| 309d1d2130 | |||
| e685a00a4b | |||
| 62cfd27ac0 | |||
| fc6acd1e3f | |||
| 2aa637ecc8 | |||
| e8d075907f | |||
| 5220144ad8 | |||
| 4202e618db | |||
| 30791e14bd | |||
| 9af5c36e16 | |||
| 1feb3915a0 | |||
| 48a22db969 | |||
| 76f3090e2a | |||
| 250d3c349e | |||
| d33ef3173d | |||
| 493824113b | |||
| d13e72b815 | |||
| e9ec7d3597 | |||
| 00a5f1bf3f | |||
| d3ff245e1b | |||
| a0cfbe74c4 | |||
| 9de7a78f43 | |||
| e55da74c5c | |||
| e25eed5896 | |||
| 3c5c2d2ca8 | |||
| 396cec8033 | |||
| 8ef2bb788f | |||
| 7d91e7b7b4 | |||
| e48a7aa92f | |||
| f1ebcd7c31 | |||
| 1dc0ee183c | |||
| 59dc2f82e3 | |||
| f34d51b911 | |||
| 1e57c4c088 | |||
| 68f71c5421 | |||
| 44faa3aa84 | |||
| a5c838e4a0 | |||
| 80007233fa | |||
| c79120b99c | |||
| eea70020c3 | |||
| c1d5a3eb1c | |||
| 6f0b4c0ce6 | |||
| a77553409b | |||
| 7705237f10 | |||
| e4b3d7e6cf | |||
| ddc55d70a7 | |||
| 64ea1af991 | |||
| 1ddecf4cdb | |||
| f6101a6629 | |||
| 426aae1ab6 | |||
| a9466654b2 | |||
| 55e0f8e5dd | |||
| 87ebdef8df | |||
| 872b108e52 | |||
| d3d121a965 | |||
| da4ec98f47 | |||
| c9735984e9 | |||
| 67d3910fd3 | |||
| ad627e0e0a | |||
| 63fbaa146c | |||
| dfefb802d0 | |||
| 11adefd839 | |||
| 992fd6e5ad | |||
| ced2347829 | |||
| 7dae59ee92 | |||
| d53b584ba2 | |||
| 9c9ba2f1a1 | |||
| c1b2ebc66e | |||
| 301e6153e1 | |||
| 7bd0780f1a | |||
| ad9103c767 | |||
| 9719c17d19 | |||
| e611ce5733 | |||
| 856d732e13 | |||
| d5f0ccae88 | |||
| e99b45a24b | |||
| cad89fccd1 | |||
| 98079f583c | |||
| da6dafe49a | |||
| d0ce6aabb6 | |||
| 300d06ffcd | |||
| f1667357f5 | |||
| 30afe7e86b | |||
| faf6d139d1 | |||
| 55c516a14b | |||
| 713a62b383 | |||
| 11cd795425 | |||
| 09d843d47f | |||
| 53569d5a66 | |||
| b9f192682c | |||
| e7db3cd7fe | |||
| 71ed353fde | |||
| 36950a9539 | |||
| dad5457700 | |||
| 0e5932fbc1 | |||
| 341b2ef62d | |||
| 5e9f850fe1 | |||
| 7bd9e1e750 | |||
| 03442022ed | |||
| 763890053b | |||
| d9f5c4d894 | |||
| 92588e1159 | |||
| 3245b8a453 | |||
| 948a480859 | |||
| ee90d886ab | |||
| f74c643a84 | |||
| 03efbe5f6a | |||
| 085479a923 | |||
| 482b15c62e | |||
| 1f5da2736e | |||
| 55234ff1f3 | |||
| 3b799756dd | |||
| 2a20338885 | |||
| 65dabd392e | |||
| 41cef6274c | |||
| c6416b5ccb | |||
| 107b3dc1e3 | |||
| bd3bf9b623 | |||
| cf91981d49 | |||
| be5a782598 | |||
| b294f45a22 | |||
| 2491956fff | |||
| ebbadbed4f | |||
| c3f39b0d9e | |||
| e7474bda1f | |||
| fa8bfd08f9 | |||
| 11827d64be | |||
| 47ac01c8e1 | |||
| 23c8937362 | |||
| ad3b7762a3 | |||
| b6c5f49650 | |||
| 5b6416e13c | |||
| 9d4ec4ca65 | |||
| 4652002e8c | |||
| 2729d72c68 | |||
| c18bcd316d | |||
| 8fd30e814a | |||
| b1b637fe2f | |||
| 86806b64a2 | |||
| 96a8548c59 | |||
| c7becf82bd | |||
| 2d80085d6e | |||
| e63669bea3 | |||
| 9568eb8dd3 | |||
| a63925483c | |||
| 67689f9229 | |||
| 161f86eb45 | |||
| 1994219531 | |||
| 2ec0353423 | |||
| 8088905721 | |||
| ec049fd490 | |||
| 033cced5a9 | |||
| a059c55f05 | |||
| 0b00b5ffe0 | |||
| 6e7a6174ba | |||
| 07eddf9772 | |||
| c451a377c9 | |||
| e5de3a90c6 | |||
| 7aecf385e2 | |||
| 1de049bdf5 | |||
| 55b8c0947b | |||
| 51ba806e6d | |||
| ae2855d123 | |||
| 9000432b52 | |||
| 618e5f01df | |||
| 0486ad8da7 | |||
| d23831465a | |||
| 6ba95d7017 | |||
| 6acfc1b715 | |||
| af2e9a9a78 | |||
| af33627c4c | |||
| b8a9b74978 | |||
| e2cef238ec | |||
| 1f799d16c9 | |||
| 1c62a07099 | |||
| ac07ae739b | |||
| cf62e61001 | |||
| b4049c195c | |||
| 6528f076fa | |||
| 651b33082d | |||
| 0f8ebd2269 | |||
| 13f58f5f1b | |||
| 4c7036a2ce | |||
| ecfe4287aa | |||
| fd4ed07449 | |||
| 0e97df08c2 | |||
| 98985e9a27 | |||
| c6c6b2a0a6 | |||
| c5b5c0d9fd | |||
| f0844d7636 | |||
| 9021c6ee82 | |||
| 773c5b04c7 | |||
| ab3290d9cb | |||
| c4c490663b | |||
| 8fc31c700f | |||
| dfc9b15dce | |||
| 59bcf5206d | |||
| 9ab5ed9a86 | |||
| b84720c040 | |||
| 726ed35f61 | |||
| 82ed8c8cfd | |||
| 75e29726e2 | |||
| 296eaa592c | |||
| 40a487d7ed | |||
| d0f093c567 | |||
| 48b01c9665 | |||
| 6b96ad4b71 | |||
| cff95e66be | |||
| 20f8b8558d | |||
| fc587ecffa | |||
| 466477429d | |||
| e4e5560b75 | |||
| a35d1a32ea | |||
| 376cb4a1eb | |||
| 0e4da16d9e | |||
| 5394d6da8a | |||
| 291c43dd31 | |||
| 3c414abc8f | |||
| e261bf8be0 | |||
| 1ad204e0a1 | |||
| 9794c4b78f | |||
| dbda2f84bc | |||
| 85597e4d46 | |||
| f7059783dc | |||
| d50d77f528 | |||
| 26978b7d48 | |||
| d6879219e7 | |||
| be8782231b | |||
| 66126d8e7c | |||
| 9ddec1d9aa | |||
| 5b5527f4c9 | |||
| 151753cb2f | |||
| 1c65c75dba | |||
| 68feaa2800 | |||
| a88f603e6d | |||
| 113848c578 | |||
| 9d6e1eb47d | |||
| 1716489396 | |||
| baebbb61eb | |||
| 54f6b6a9c9 | |||
| a53d74e483 | |||
| bd71bfd9f3 | |||
| 9369122017 | |||
| 31dbd4b941 | |||
| 4905d5aded | |||
| ce864b88df | |||
| 054093025e | |||
| 2ff4daef20 | |||
| 9bd8a788c8 | |||
| eef3afabb7 | |||
| 9f5dc24bf6 | |||
| bc7d84fea2 | |||
| 16d2fd7f9b | |||
| baa8992322 | |||
| da76c6efbe | |||
| 805fb13b13 | |||
| 463838a198 | |||
| 6a44242795 | |||
| 3670238f04 | |||
| ba45229db0 | |||
| 35e57741d3 | |||
| afe8d00936 | |||
| fbbd549db2 | |||
| 36a2fee9d5 | |||
| 2998b1f02e | |||
| ea1e1b245d | |||
| b8d01755a0 | |||
| d508dc69dc | |||
| 594765658a | |||
| 4bde3afe8a | |||
| a994d398d9 | |||
| 6bb5f9d1ab | |||
| 184a6de1e9 | |||
| d1dc04020a | |||
| 64bdb59683 | |||
| 5678019204 | |||
| 40ae2fb1da | |||
| 30dd291d3d | |||
| 98a7ea5a10 | |||
| 05c41ffd89 | |||
| 5483cb9143 | |||
| 4360450ac6 | |||
| eea02ffb80 | |||
| 59ec3ca697 | |||
| 2647d04da3 | |||
| 46de2ec047 | |||
| 2486e68fe3 | |||
| 2896ea0437 | |||
| 7d28409f8d | |||
| 592354b449 | |||
| 0685c7afd6 | |||
| 9c66732593 | |||
| 464768a460 | |||
| 10a39b88d7 | |||
| b5da203571 | |||
| 2e22b5f601 | |||
| 16181b7272 | |||
| a18073f5de | |||
| 3c8688345f | |||
| 05a8bd7f74 | |||
| 592ff603ca | |||
| 257a97ed55 | |||
| b87997caa2 | |||
| be40894bbd | |||
| 679622bac0 | |||
| 92d234fb3e | |||
| 9cb5375f30 | |||
| 043c41dfc7 | |||
| 17b6ff1a6d | |||
| ba4c18f80b | |||
| 2c2a231330 | |||
| 429d7c1ed9 | |||
| 3bf83e45ed | |||
| d5a3802492 | |||
| 88f354a872 | |||
| fa99508a69 | |||
| cba352cca6 | |||
| fc12494ac1 | |||
| a42e807276 | |||
| 67349354e4 | |||
| 29f070fc1f | |||
| 216ae71f7f | |||
| 0cf114c399 | |||
| b784fd266a | |||
| 298b669ff9 | |||
| 465387fd65 | |||
| c99dd33246 | |||
| 47bf785752 | |||
| 6568cd8e0d | |||
| e9b3a799bc | |||
| d7115022e4 | |||
| df4d6627ee | |||
| 9b9d03947d | |||
| 40a1f75895 | |||
| 6a71e0fa75 | |||
| c33eb8c265 | |||
| 74e61369f2 | |||
| 6f9167c725 | |||
| 56effcb189 | |||
| 8a284ae9a1 | |||
| 71beb626c3 | |||
| e68efb184b | |||
| ac32de7bf1 | |||
| bab103ff17 | |||
| a3a60176b1 | |||
| 9c35e3a17a | |||
| 3f97e8195b | |||
| 4575ee0d97 | |||
| ec03294ebc | |||
| aa0d1d94b2 | |||
| 662f081f49 | |||
| f65a3d1e75 | |||
| 977da91aa6 | |||
| c7a11e050c | |||
| 6d6eee9968 | |||
| abe0d2ca78 | |||
| 174e1f9d4b | |||
| cb8dc0326c | |||
| 3227eee080 | |||
| 0021219f42 | |||
| e3ec136cad | |||
| db98e406c2 | |||
| 7f9ff587ce | |||
| a4a801d83a | |||
| fde86657f2 | |||
| 0adecd3cb0 | |||
| 969c787ff8 | |||
| 748a67d47a | |||
| 692dd841e3 | |||
| e484c6cdfc | |||
| d731051cb7 | |||
| 11d8142cea | |||
| 54a1890aca | |||
| a3524c3af1 | |||
| 823f773e26 | |||
| d5557976d5 | |||
| 100ce5844d | |||
| 13ae9aff44 | |||
| 786d538276 | |||
| fa28529308 | |||
| 2f5c198a81 | |||
| f3190b8979 | |||
| 31241b64d8 | |||
| dab5dbf759 | |||
| a4c8b93a07 | |||
| 51bc06f60b | |||
| 39582471e8 | |||
| 6d002c175f | |||
| c7119498a3 | |||
| 2df1305521 | |||
| 7e85db6843 | |||
| 0b96818f6d | |||
| 3526092b38 | |||
| 8dc443f827 | |||
| 623557f521 | |||
| 2359b7e2f4 | |||
| 9addc016fb | |||
| e3e8c689ed | |||
| 83dda3e8ab | |||
| 305533a0d4 | |||
| 0f3fa38c04 | |||
| f205982ae5 | |||
| 9209ac5773 | |||
| ff721218f5 | |||
| dca9ce4b2d | |||
| 5f52c64d4d | |||
| 5da3127344 | |||
| 010330ac90 | |||
| 5f3154acc6 | |||
| fb2004a6f9 | |||
| e812380f20 | |||
| ae08966d40 | |||
| 76da3d811c | |||
| 0377793102 | |||
| 169785a8bb | |||
| 9c066e9494 | |||
| 04180a7389 | |||
| da81111575 | |||
| c5dcf522c4 | |||
| da5da85c07 | |||
| 0ab2eda0ae | |||
| 4cf130bd07 | |||
| 161c4ac028 | |||
| d4549d6849 | |||
| 790ca460d4 | |||
| cbaeed7e8e | |||
| 4e3e469ba8 | |||
| 6cb073e6a5 | |||
| de2a346601 | |||
| 8b285af276 | |||
| be60eaf7c8 | |||
| 2235c3e8e4 | |||
| 68ae9248a6 | |||
| b9742642fc | |||
| 356c905703 | |||
| 47a5473a35 | |||
| 96bca6888a | |||
| bbf31c1a95 | |||
| 42b8c1b429 | |||
| 77fde11039 | |||
| e13f04e80f | |||
| ad026f6105 | |||
| 9107d0e107 | |||
| ee876c54bf | |||
| 4af44a40bf | |||
| 399cfe2fbc | |||
| 71d0cdbfce | |||
| aae740472f | |||
| 8f9beb2789 | |||
| 77b93a904f | |||
| 7934c16bca | |||
| 941ddee2fc | |||
| 16113bf330 | |||
| 505182428b | |||
| 3c2a84ff78 | |||
| 8a3346b650 | |||
| 5b63fb1362 | |||
| 393857b067 | |||
| cb8a9c0796 | |||
| 036752763f | |||
| 3a90af1f44 | |||
| 772de0ff97 | |||
| 53a61a8e58 | |||
| a37328c1aa | |||
| 782325395c | |||
| e13d554433 | |||
| 15c72c04af | |||
| b797246607 | |||
| d54bb4fd16 | |||
| 0a946e3976 | |||
| a339f00d83 | |||
| de15866c9a | |||
| 24ee87720e | |||
| 7310b3ed09 | |||
| bb6cdc7bb0 | |||
| 4a2d20fb74 | |||
| b136b86300 | |||
| d4a7ae8b34 | |||
| 04da7cebdb | |||
| ccb227e694 | |||
| 9c7b868227 | |||
| f333937b35 | |||
| e4f6f15d70 | |||
| 5ae8ef1cb3 | |||
| d863652e1b | |||
| ac540d73b7 | |||
| 37b9da7337 | |||
| 93c0dbde0d | |||
| aa236b4da0 | |||
| 2fd3643632 | |||
| 24f9247c54 | |||
| d312b752a1 | |||
| 1b476757a0 | |||
| c78a8f6317 | |||
| 24c3788055 | |||
| a644762a60 | |||
| 3185d92fb5 | |||
| 2c629bc821 | |||
| 1a6c38bc26 | |||
| 589f9aa8f3 | |||
| 70e5d0b235 | |||
| aa81d80578 | |||
| 7bc6676680 | |||
| ab9b10824f | |||
| f5931e80e7 | |||
| bf4f86b4f6 | |||
| 7f59f22cf4 | |||
| 14f4817381 | |||
| e821468bb0 | |||
| d9315d2332 | |||
| a2b4be388e | |||
| 35e06642f9 | |||
| 92de3e4f30 | |||
| 5b65e182e9 | |||
| a7896c39f0 | |||
| 4f19bf9a18 | |||
| c379c65960 | |||
| 1ae0a83880 | |||
| 77f7c813f4 | |||
| bfec8b5634 | |||
| 15a43a6b11 | |||
| c9e3c34ce1 | |||
| b99b3ad982 | |||
| f4ce5c4143 | |||
| bb4bf63621 | |||
| 60c1a552bb | |||
| 0a979ddd1e | |||
| e45c4b49fd | |||
| b89ace7aae | |||
| 424ca923fc | |||
| e837e1e1d1 | |||
| aea0986928 | |||
| dc2a3492f0 | |||
| 8cf033002c | |||
| 4d7cb25aa6 | |||
| 60cf3ec861 | |||
| 4fd82b16e8 | |||
| 26feccc0e4 | |||
| 9a1bc66dfc | |||
| 24a3783d7c | |||
| 7e072c395f | |||
| 94e1ed1d7e | |||
| 94e6f4040d | |||
| d570e59818 | |||
| 0e9d48fff0 | |||
| e690d73434 | |||
| 8f2b3c6b69 | |||
| 3c0b2fc910 | |||
| 7d0a1c8987 | |||
| 757d947446 | |||
| 4ced4f9631 | |||
| c6859d7edd | |||
| 94cf9a89cc | |||
| bd8d78427b | |||
| e40d4b9b68 | |||
| 4a07485a19 | |||
| 71614e0b0c | |||
| d5b6c14bdf | |||
| 9509718b0e | |||
| c0ca022ac2 | |||
| 708b4a8981 | |||
| 8006b0ca4f | |||
| cc2286f056 | |||
| 81a4be498b | |||
| 56477f5ea6 | |||
| ca05e2e905 | |||
| a524302ea7 | |||
| 945b5f1b15 | |||
| ccb0f853db | |||
| b8f1b0d6aa | |||
| aa7d5bd704 | |||
| 9ee4c08790 | |||
| 725d2f2612 | |||
| 4d5ad691f3 | |||
| b2f3bf3461 | |||
| 44c389d29f | |||
| ac8e03419e | |||
| babb836f91 | |||
| 95e0a5ee95 | |||
| 642a0c78cc | |||
| 1ac90584cb | |||
| ccef5de86e | |||
| e526ec9c32 | |||
| b15e68658f | |||
| dcd0f8d3f6 | |||
| b3da6b0e89 | |||
| ff8c761de0 | |||
| e6258acb55 | |||
| ecafed8fd5 | |||
| 73f99b1298 | |||
| 7a6ed854ec | |||
| e923d78016 | |||
| 615b2f72ae | |||
| 9773349253 | |||
| fc57fa5415 | |||
| bdd9d46517 | |||
| 013499f7a2 | |||
| c4416379bb | |||
| c0c07e7dc9 | |||
| 38ec3718ce | |||
| e2e3561443 | |||
| 199f2fc0cd | |||
| c944b2f599 | |||
| fdd0d47762 | |||
| e5f851dcbb | |||
| 78cb2781e6 | |||
| ef9b5c57b1 | |||
| 52eacd7140 | |||
| b19d8d6700 | |||
| 6b0add44ee | |||
| b66338494f | |||
| 47cec48a49 | |||
| 09ccbca79c | |||
| 4f28ae62a7 | |||
| e953ea6542 | |||
| de72c98a28 | |||
| 7f15f91bd3 | |||
| c570c5bf97 | |||
| 52c304ecae | |||
| 4f4860eee8 | |||
| 695e3cc692 | |||
| e05d9da231 | |||
| c16f9a9e20 | |||
| 74b1871f18 | |||
| 8fdb877840 | |||
| 3a7d7d79c0 | |||
| 28baf2596e | |||
| 30d1a55dde | |||
| 3e068d16df | |||
| c283e39b22 | |||
| f6702d83d0 | |||
| b1a779c178 | |||
| cc1260ee3c | |||
| 92b1788825 | |||
| efdbeb585b | |||
| 304f171d38 | |||
| 9a3909f8ba | |||
| 6ca4b5391b | |||
| cabd36d078 | |||
| 64bacd2572 | |||
| 47be29b89c | |||
| 6407bf6a1f | |||
| e2d145cf31 | |||
| b634c70f80 | |||
| e29169711c | |||
| 662ddac050 | |||
| b90d543afc | |||
| f05d134aa7 | |||
| 74a68aa626 | |||
| fcc5170a10 | |||
| 3a9403a2f1 | |||
| ff170caff6 | |||
| 532b493c42 | |||
| 51cc87e0db | |||
| 878d4608b1 | |||
| 03d1c62787 | |||
| 5c46271898 | |||
| 9a7c732555 | |||
| 8ffe6fda9b | |||
| e563417166 | |||
| ec3f9acd76 | |||
| 6c22fd6902 | |||
| 82b10a527b | |||
| 92c744d971 | |||
| 7a691a4286 | |||
| e98489a74b | |||
| 7a5da23b0c | |||
| edf4837ed6 | |||
| 749bd8db0e | |||
| d2460d8e85 | |||
| eead4cf70e | |||
| 291f88b1e4 | |||
| 93f1a44d0f | |||
| 550e107683 | |||
| 7a8b94b6d4 | |||
| 2005b396fa | |||
| 2a80b5ed36 | |||
| 47a32c725d | |||
| fc26acd0ab | |||
| e57f7d378a | |||
| 6de74587bd | |||
| 6e5e7851d4 | |||
| 84ccda45b0 | |||
| ec3cd6cc68 | |||
| cae9fee30a | |||
| f0111a8037 | |||
| 8fad590f8b | |||
| 2ae5a9d725 | |||
| 8153c8b82c | |||
| 159f4a3a3c | |||
| 3dbfff57e7 | |||
| a063cd4feb | |||
| dc5da3c3b3 | |||
| 79c9c19b1a | |||
| b49b583e64 | |||
| 0b8e8ad4f2 | |||
| 7fc2c4dcf1 | |||
| a74cbc5781 | |||
| 619ec921ee | |||
| 1b23c9a030 | |||
| d4c11b9a1f | |||
| 55da030e2a | |||
| c64f306550 | |||
| 7ee4a648d0 | |||
| 78ca4e7c87 | |||
| 7a2826358b | |||
| df84721b55 | |||
| f53a1f785d | |||
| 4f3b9776ae | |||
| 39f47d65a9 | |||
| a92e6b6d91 | |||
| 00e044c431 | |||
| 7132762c9c | |||
| 2476b44300 | |||
| d36e827ec9 | |||
| a37115cb00 | |||
| 7dc73c61ab | |||
| a14ef06d14 | |||
| 212e7aa47e | |||
| ebe26eddf0 | |||
| 517e3fcff9 | |||
| 679162c762 | |||
| e4973b3262 | |||
| a1ea7804f3 | |||
| 2c51d55ba2 | |||
| 3b0e1a5833 | |||
| 9bb6d8fd6e | |||
| 4afba798ba | |||
| f4cefe955b | |||
| 1c38ebb551 | |||
| 14dcafe2ca | |||
| cf78216d78 | |||
| 0c256e2908 | |||
| 00fc3f1a1d | |||
| 672e309d89 | |||
| b0c19256f0 | |||
| 205e664b4d | |||
| cb466aec08 | |||
| 33f3744a63 | |||
| 7adb1606f1 | |||
| 184ada6ae8 | |||
| 856c9d58b8 | |||
| f3fba8a389 | |||
| 10468a559a | |||
| c4c9f02433 | |||
| f2dd288a0d | |||
| aa36a83182 | |||
| dd9047c4e9 | |||
| 11634b9a67 | |||
| d832324306 | |||
| a7af5c4f66 | |||
| 0f2022bd40 | |||
| e598598ca8 | |||
| 85599fcf53 | |||
| 6961488d38 | |||
| 209d0c98d9 | |||
| d718cc997c | |||
| 4967d0a222 | |||
| 17ebd5cea8 | |||
| 25e81b39f9 | |||
| 4b253aa4cf | |||
| d7b84bed9f | |||
| 298d091e2e | |||
| ebe30394f2 | |||
| 4c7d479e93 | |||
| d6d204ae5f | |||
| ed23eb0fde | |||
| fbbfc7f73c | |||
| e0b2db17c2 | |||
| f360e10050 | |||
| c15f55762d | |||
| 7edc715cba | |||
| 27f76599bc | |||
| e8bde5a394 | |||
| 3b820f1145 | |||
| c1444c0822 | |||
| b424c525cc | |||
| f640102b0e | |||
| d9e79a5376 | |||
| 734ee38641 | |||
| e651633c54 | |||
| 6d4bd06ffe | |||
| 2af07fee4f | |||
| 6f4bdafb0c | |||
| a71f2142bb | |||
| 1e9ec5424a | |||
| 068cbafe3d | |||
| 4ce618c33c | |||
| 10b997608b | |||
| 5edab414d8 | |||
| 6e904047f9 | |||
| fdb0cfb4df | |||
| 58999995f1 | |||
| f4a58036fa | |||
| 65e2331979 | |||
| 622a5c267b | |||
| c746cde61e | |||
| 68977be256 | |||
| f28805fb94 | |||
| df793c20fd | |||
| a4e4e9c495 | |||
| b1ccd2e2c0 | |||
| 9a2687768f | |||
| ab7b0571f3 | |||
| 14286e8c0f | |||
| 6b41b85d4d | |||
| cc7724dec4 | |||
| c832c7d794 | |||
| 52f36d29dc | |||
| 9b6dafe715 | |||
| d4ecbc6638 | |||
| 1c93d68e7b | |||
| c1d92206f5 | |||
| 7bef5008c2 | |||
| 3ef3cca76b | |||
| a1d8e3e598 | |||
| dd77ebe11e | |||
| 27efc94b09 | |||
| b6abc6e326 | |||
| f13a502123 | |||
| f77f617bc2 | |||
| 6ae9e0b332 | |||
| 8a054706b5 | |||
| 6e1d656a60 | |||
| 53430b9827 | |||
| 026424ab8c | |||
| 9c0fc63ee9 | |||
| cdff99339e | |||
| b739d94f23 | |||
| e076097a7c | |||
| 3cee8f5475 | |||
| 83ea189d81 | |||
| dcf04aa4fe | |||
| 67ab7c0779 | |||
| 2b5511997c | |||
| 53c6a0ec9f | |||
| 1a710e4094 | |||
| 5a90d8b545 | |||
| f794053f99 | |||
| 670cf6fe90 | |||
| 46ed8aa87c | |||
| 387b8298bd | |||
| c4aa55d522 | |||
| c3861954dc | |||
| ebfbf108a2 | |||
| 66ed9adcda | |||
| eb02206c05 | |||
| cd0b74b0de | |||
| 6ca3b76a42 | |||
| 84a03e80de | |||
| a74f813df1 | |||
| 99fc4e76ec | |||
| 7145f5252d | |||
| 9dab23b5fc | |||
| 09ff8d35bc | |||
| ee903d2d07 | |||
| b2f978aa7c | |||
| 76d957a144 | |||
| a0acfeed56 | |||
| b1f63ab822 | |||
| 54ea9c2386 | |||
| ccdb5c54d0 | |||
| b8393051e4 | |||
| 94a8e0339e | |||
| a67ba713f5 | |||
| 8ffbae80b8 | |||
| db17f95ce8 | |||
| c6365755c7 | |||
| ef2a5110fe | |||
| 7f97725d7f | |||
| af03c74fba | |||
| bc8a7a03c3 | |||
| d4c361ae12 | |||
| 8f932ac3d6 | |||
| 4cc5f35b04 | |||
| 476b0495e0 | |||
| 85098a6627 | |||
| d9a022ffff | |||
| 8db1534ef3 | |||
| 0aa7d646a7 | |||
| 599c06e981 | |||
| 078cb6e5b7 | |||
| 5cc17bc306 | |||
| ef18c8e3f7 | |||
| 012c7552eb | |||
| 0fd63084dc | |||
| 0b12e73eef | |||
| 4daf3016f8 | |||
| 9f8e256bb4 | |||
| 1bbcd9ad0d | |||
| b1c0a2dc1e | |||
| 2a092de8d8 | |||
| bb57714ac9 | |||
| 137039f868 | |||
| e7af38aa11 | |||
| d0bab2ca22 | |||
| 2621c48f92 | |||
| 959540f17c | |||
| 3e2c344417 | |||
| a307977ec1 | |||
| f3db4e49b6 | |||
| 30f9bcbd22 | |||
| a98c71aab4 | |||
| 0d722ebe0b | |||
| 3caa92c567 | |||
| ae6d921f23 | |||
| d692fe91fb | |||
| 822496808d | |||
| 8533dc234b | |||
| 2193fb531f | |||
| c069d14af5 | |||
| 02abc07bc1 | |||
| 34c33dd42f | |||
| dcc22f3bd7 | |||
| 4247d15672 | |||
| 39d8ebc3c9 | |||
| 8e3b6280af | |||
| 4a781d8471 | |||
| 9f93ca8019 | |||
| 4890cb641c | |||
| 90bb004940 | |||
| 70df34caf9 | |||
| c04b421f26 | |||
| e292470ade | |||
| c0d3dc30e1 | |||
| 01df2ae3e4 | |||
| f8174a67d7 | |||
| 53265f6b7f | |||
| f245492679 | |||
| 6f92524ada | |||
| b2ff1501aa | |||
| fbb4ab590f | |||
| e2cadf85f8 | |||
| b5c2c9ee7a | |||
| 1dabac9782 | |||
| 50983f83f5 | |||
| 5026be2d28 | |||
| 70aad5c320 | |||
| e74d21c0e5 | |||
| 90d8677b7a | |||
| 7a5d88270e | |||
| 5599335965 | |||
| e829589875 | |||
| 98acd516b8 | |||
| 584d792f5a | |||
| e6db860861 | |||
| f0ec3cb9ec | |||
| 0801e22dce | |||
| 5efd7b9ac4 | |||
| f2bae200d3 | |||
| fd14513aef | |||
| 6becc8f334 | |||
| 90359d227e | |||
| 6ff67e87eb | |||
| 0a83423731 | |||
| 5160644016 | |||
| d956bd2643 | |||
| 7a6a2ad530 | |||
| 21c76f31c4 | |||
| cb48c1277a | |||
| 3c18fd8920 | |||
| 83c6e809c6 | |||
| dc35fedd74 | |||
| 947923567f | |||
| 3d19388086 | |||
| 051f6643a6 | |||
| 47e01a7157 | |||
| a336145ed9 | |||
| ecc6b477dc | |||
| e0c6c462a6 | |||
| 3e607680e2 | |||
| 89347b7bee | |||
| c45ef08926 | |||
| 8d40b2cd0e | |||
| 14e318c273 | |||
| f50b478966 | |||
| 0cacedfc5d | |||
| 5283f10189 | |||
| c9c2526f08 | |||
| fba4bca46e | |||
| a95eb65faa | |||
| bcc7b630ae | |||
| a247a8d6ba | |||
| 620adc0ec6 | |||
| d5b3ae9056 | |||
| afe56a36c9 | |||
| 265b98311a | |||
| 89983a28b4 | |||
| c9918035ed | |||
| 225d1dd4d2 | |||
| 985fc991e8 | |||
| 8f3900a9df | |||
| d21ce9b10f | |||
| 1153d29099 | |||
| 75341e8172 | |||
| 2f5cbfb03a | |||
| 01d2d77efd | |||
| 1b2a61ed49 | |||
| 10584eb01a | |||
| d4ec500b1b | |||
| c7bec3d0c9 | |||
| ff6e982050 | |||
| 6a49ae60a1 | |||
| 27fb0c6c06 | |||
| 047b32e7d9 | |||
| eeb008f505 | |||
| 704834b370 | |||
| a3cb6608ce | |||
| 7640042905 | |||
| d601cc823c | |||
| 338cc1db40 | |||
| 6710967d19 | |||
| e4a5194115 | |||
| d151901049 | |||
| c9e9ec3a80 | |||
| 54912df237 | |||
| b09aa3240a | |||
| c9bc1f8306 | |||
| 7e98fa8626 | |||
| 3b2c189083 | |||
| c242001a77 | |||
| b21cfc127a | |||
| 3a5af1bbb3 | |||
| 68b98c1bd2 | |||
| 24ae7ec6e0 | |||
| e3590bc673 | |||
| 72dcc5223d | |||
| 4558af2e43 | |||
| ed259fad9c | |||
| b4e2997389 | |||
| d946a46d3f | |||
| 983bd50a09 | |||
| 4f0be4f72c | |||
| 58aa3e94e4 | |||
| 19ec59cca5 | |||
| 911780ba3c | |||
| 8b0d034a94 | |||
| 2a8235ae38 | |||
| 15a98a83cd | |||
| 1dc578badb | |||
| be698bd806 | |||
| 0cad657ce2 | |||
| 7991abab0b | |||
| b3e635a923 | |||
| 57b794cbd9 | |||
| 974dc96259 | |||
| db33d246cb | |||
| 5e5442426c | |||
| a55add190c | |||
| 5c381460ce | |||
| 4cf1d5bf94 | |||
| 4316ba988b | |||
| c6a9217c74 | |||
| 34d3021b80 | |||
| c57417e834 | |||
| 00f86c6346 | |||
| 0ab38bb4d7 | |||
| 7da45d6c2c | |||
| 3c7f02bee3 | |||
| 686a66e5f1 | |||
| c50d7bf974 | |||
| d70b3100f2 | |||
| d500bdff96 | |||
| 8de88adc0b | |||
| 4b3ed67877 | |||
| 11258c0d8d | |||
| 325aa536c4 | |||
| 31863baee2 | |||
| 0f08233581 | |||
| b28da1057c | |||
| 4fa3ca98a2 | |||
| 66f8a8cdd0 | |||
| 051423e75e | |||
| ae562ac962 | |||
| 772dd1e294 | |||
| 27212e8b98 | |||
| 629c2de253 | |||
| 9ef95e43a3 | |||
| 6a304dbb4d | |||
| 4355039329 | |||
| 5aebb400da | |||
| fbd8c0237f | |||
| 04c9d16c16 | |||
| 308408a962 | |||
| 19c5904561 | |||
| c0037c99e4 | |||
| b85c1c44b8 | |||
| 1c69d6c788 | |||
| b6b95581cd | |||
| 55c6374949 | |||
| 0a65867937 | |||
| 859f645fe5 | |||
| f1cc94207e | |||
| 70847857f7 | |||
| 2a34978487 | |||
| fde9379bb2 | |||
| e8e586ce7c | |||
| fb78d9bbb9 | |||
| a498e9e142 | |||
| d0d6f48751 | |||
| 0361a30c40 | |||
| d0c18c4679 | |||
| 8aca8a2229 | |||
| 0bbecb3b33 | |||
| 3f008c4b6d | |||
| 227eb707d2 | |||
| a5306d60ee | |||
| e3de39d3ab | |||
| f4666fcb0a | |||
| 85a554b60d | |||
| 1ea44417d0 | |||
| 0605cb754b | |||
| f889d919f8 | |||
| d670a9a584 | |||
| e51b8276cd | |||
| 67feba6171 | |||
| 922de3755b | |||
| 9da7bb3f30 | |||
| 46ebb52afa | |||
| 4f97692245 | |||
| 25a833207e | |||
| 8224f8c4c6 | |||
| c455718ada | |||
| 37b1d24575 | |||
| 449d121f19 | |||
| 9a51d203de | |||
| 0e92fc2289 | |||
| 54c649e76e | |||
| 45f8b86f13 | |||
| a8a1f98a8f | |||
| b8f14c964a | |||
| de964d3e77 | |||
| 4634606a36 | |||
| 5d306ed9f3 | |||
| ba1fc7a03e | |||
| 8b43605abf | |||
| 2ee5b3b7a5 | |||
| 302a588812 | |||
| 2a1330dea3 | |||
| 5472621ac0 | |||
| 9ad7ba7144 | |||
| 895d151e2e | |||
| 3ee15d0401 | |||
| 60ad6792ba | |||
| b878d3ccf6 | |||
| f93bd9e28b | |||
| 9c73f6b787 | |||
| 64b9f69fb1 | |||
| aca2c01c9e | |||
| 470d160346 | |||
| e225b496b1 | |||
| f470744e44 | |||
| 42fec6e61f | |||
| 883a535441 | |||
| 65b342cac7 | |||
| 1395abcf09 | |||
| e59d64513f | |||
| ed85b8249a | |||
| bddf1c67bf | |||
| 62ab091350 | |||
| 1588f58726 | |||
| 688a16c941 | |||
| 69b3a6871f | |||
| 0aac358e33 | |||
| 7f82f8d679 | |||
| 5fb96223a8 | |||
| e13c88cea6 | |||
| fbc76714f5 | |||
| c7adbc1309 | |||
| b27453d275 | |||
| aa0501b853 | |||
| 596c776463 | |||
| eb1738b1c6 | |||
| 0505926c75 | |||
| 581c6f547d | |||
| 3d5ef186ba | |||
| e3ea39afaa | |||
| 7f9269cff2 | |||
| bbcc040dc4 | |||
| 727a6988c2 | |||
| 7bbd2aee94 | |||
| b812f1dcb4 | |||
| fb2dca2eaf | |||
| a03eaed4e2 | |||
| ee705363c1 | |||
| c1fec9b411 | |||
| 19a9b18c69 | |||
| 38b3aae1e3 | |||
| 5d5663e2a7 | |||
| 973eb8127e | |||
| 2499cbdab8 | |||
| ec80a41871 | |||
| a829e85ef5 | |||
| a090bed6c0 | |||
| 76684e49ca | |||
| c1fc6e2762 | |||
| 437431a821 | |||
| 5749a8f7c1 | |||
| 54e271c985 | |||
| b042b90d9b | |||
| a99ca9a1a1 | |||
| f05d036023 | |||
| 5a55691358 | |||
| 4f0dd51761 | |||
| 0ca6f76e88 | |||
| 869f544bab | |||
| 4f67ed2b77 | |||
| 3f4926cbd5 | |||
| af93157a76 | |||
| 220a7d24bc | |||
| 3b541d3670 | |||
| 4bd6f2da89 | |||
| d5e00c3517 | |||
| 1b7a2c2ed5 | |||
| 11ad7a8a3d | |||
| 622f84c971 | |||
| 779a33349a | |||
| 135ca1eeba | |||
| 2dee7f5982 | |||
| 1513b8c0db | |||
| 693cc1e730 | |||
| e18980be9f | |||
| cf048bc723 | |||
| 3004d8c9dc | |||
| 6f66b87262 | |||
| 79cfa96616 | |||
| 952cacf3ff | |||
| 3cc6611614 | |||
| 457c2da67d | |||
| 13769e0e52 | |||
| b33e042cd4 | |||
| 2689a20889 | |||
| d769fd32f0 | |||
| 2c82c9a6dc | |||
| 3850130583 | |||
| 06262c078d | |||
| b64a234f8a | |||
| dfed3812ce | |||
| 1b594d9ed1 | |||
| d0f589bb3e | |||
| bc72f3cd64 | |||
| de8f1a86c6 | |||
| 4bae08c159 | |||
| 34cd81b4d9 | |||
| 8c127a175c | |||
| 5e3e2b6137 | |||
| 88a16d4c7d | |||
| 296674cfd6 | |||
| 875174e2e0 | |||
| 4393fa1a47 | |||
| 5ae2031bcf | |||
| 779266e61e | |||
| 8e8d283959 | |||
| 2cb7be67bd | |||
| 9bc5c99fc8 | |||
| 424fbfc9c9 | |||
| 3d2497f963 | |||
| 2e42bbb1a2 | |||
| 9879a95570 | |||
| d54f14a14c | |||
| cdcac06dbf | |||
| 6b81223002 | |||
| df986d36a2 | |||
| 173c9043e3 | |||
| 488986e42e |
@@ -0,0 +1,5 @@
|
||||
[codespell]
|
||||
check-filenames =
|
||||
builtin = clear,rare,usage,informal
|
||||
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
|
||||
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,sur,doas
|
||||
+1
-1
@@ -10,7 +10,7 @@ trim_trailing_whitespace = true
|
||||
[*.{md,fflogo}]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{txt,fflogo}]
|
||||
[*.{fflogo}]
|
||||
insert_final_newline = false
|
||||
|
||||
[*.yml]
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
github: LinusDierheimer
|
||||
github: [LinusDierheimer, CarterLi]
|
||||
|
||||
@@ -7,27 +7,31 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- We will try hard to solve the issue. However since platforms and hardwares vary greatly, it can be hard to find the root cause is. Providing following information may help us greatly. Thanks in advance -->
|
||||
|
||||
# General description of bug:
|
||||
|
||||
* What happened:
|
||||
* What should happen:
|
||||
* Did it work in an older version: <!-- if yes, which version -->
|
||||
* Where did you get the binary: <!-- Github Release / Github Actions / Installed with a package manager (What package manager) / Built from source yourself -->
|
||||
* Does this issue still occurs in [the latest dev build](https://github.com/fastfetch-cli/fastfetch/actions/)?
|
||||
|
||||
# Often helpful questions:
|
||||
* Does the issue occur across multiple terminal emulators? [Y/N]
|
||||
* Does the issue occur across multiple shells? (bash, zsh, fish, etc) [Y/N]
|
||||
# Often helpful information:
|
||||
|
||||
Output of `fastfetch --version`:
|
||||
The content of the configuration file you use (if any)
|
||||
```
|
||||
//paste here
|
||||
```
|
||||
|
||||
Output of `fastfetch --load-config devinfo`:
|
||||
```
|
||||
//paste here
|
||||
```
|
||||
|
||||
Output of `fastfetch --load-config devinfo-verbose`:
|
||||
Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`:
|
||||
<!--
|
||||
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
|
||||
|
||||
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
|
||||
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false && fastfetch --version`.
|
||||
-->
|
||||
|
||||
```
|
||||
//paste here
|
||||
```
|
||||
@@ -37,7 +41,39 @@ Output of `fastfetch --list-features`:
|
||||
//paste here
|
||||
```
|
||||
|
||||
<!--
|
||||
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
|
||||
If this isn't possible (or too much work) for you, post the output of `fastfetch --show-errors --recache --multithreading false --disable-linewrap false`.
|
||||
-->
|
||||
## If fastfatch crashed
|
||||
|
||||
Paste the stacktrace here. You may get it with:
|
||||
|
||||
```
|
||||
$ gdb /path/to/fastfetch
|
||||
$ run
|
||||
$ bt
|
||||
```
|
||||
|
||||
If you are able to identify which module crashed, the strace can be helpful too
|
||||
|
||||
```
|
||||
$ strace /path/to/fastfetch --multithreading false --structure {MODULE} --pipe
|
||||
```
|
||||
|
||||
If you cannot do the instructions above, please upload the core dump file:
|
||||
|
||||
## If my image logo didn't show / work
|
||||
|
||||
<!-- Please make sure the terminal does support the image protocol you used. Note Gnome terminal doesn't support any image protocols -->
|
||||
|
||||
* The image protocol you used:
|
||||
* The terminal you used:
|
||||
* Upload the image file here, or paste the image URL:
|
||||
* Does it work with `--logo-width {WIDTH} --logo-height {HEIGHT}`?
|
||||
|
||||
## If fastfetch behaves incorrectly on shell starting
|
||||
|
||||
<!-- NOTE for zsh / p10k users:
|
||||
There are known incompatibility between fastfetch and p10k instant prompt.
|
||||
The p10k doc clearly states that you should NOT print anything to stdout after p10k-instant-prompt is initialized.
|
||||
You should either put `fastfetch` before initialization of p10k-instant-prompt (recommended), remove it or use `fastfetch --pipe false` -->
|
||||
|
||||
* The bug is reproduceable with fresh / clean shell configuration (i.e. `fastfetch` is the single line of `.zshrc` or `~/.config/fish/config.fish`):
|
||||
* Does `sleep 1` before running `fastfetch` work?
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install codespell
|
||||
shell: bash
|
||||
run: sudo apt update && sudo apt install -y codespell
|
||||
|
||||
- name: Run Spellchecker
|
||||
run: codespell
|
||||
|
||||
linux-buildtest:
|
||||
name: Linux build test
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
compiler: [
|
||||
{ cc: gcc, cxx: "g++" },
|
||||
{ cc: clang, cxx: "clang++" },
|
||||
{ cc: "musl-gcc", cxx: "musl-g++" }
|
||||
]
|
||||
enableFeatures: [ON, OFF]
|
||||
exclude:
|
||||
# The feature libraries are all build against glibc, so they can't be used with musl
|
||||
- compiler: { cc: "musl-gcc", cxx: "musl-g++" }
|
||||
enableFeatures: ON
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev libdrm-dev
|
||||
|
||||
- name: configure project
|
||||
env:
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} -DENABLE_DRM=${{ matrix.enableFeatures }} .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: run fastfetch --list-features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-20.04 # 22.04 ships a newer version of glibc than debian stable, allow those people to use the debian package
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
outputs:
|
||||
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev directx-headers-dev
|
||||
|
||||
- name: install linuxbrew packages
|
||||
run: |
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick ddcutil --ignore-dependencies
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: print dependencies
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: get fastfetch version
|
||||
id: ffversion
|
||||
run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-linux
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
macos:
|
||||
name: MacOS
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: install required packages
|
||||
run: |
|
||||
brew uninstall aws-sam-cli azure-cli qemu lima colima gradle kotlin maven pipx aria2 || true
|
||||
brew update
|
||||
brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: print dependencies
|
||||
run: otool -L fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-macos
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
freebsd:
|
||||
name: FreeBSD
|
||||
runs-on: macos-12
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: cross-platform-actions/action@v0.21.1
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: '13.2'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
sudo pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-freebsd
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
win64:
|
||||
name: Win64
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
- name: configure project
|
||||
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --verbose
|
||||
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: print dependencies
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-win64
|
||||
path: ./fastfetch-*-Win64.*
|
||||
|
||||
win32:
|
||||
name: Win32
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: CLANG32
|
||||
update: true
|
||||
install: git mingw-w64-clang-i686-7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c, cpp
|
||||
|
||||
- name: configure project
|
||||
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: print dependencies
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-win32
|
||||
path: ./fastfetch-*-Win32.*
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- freebsd
|
||||
- win64
|
||||
- win32
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
|
||||
- name: get latest release version
|
||||
id: get_version_release
|
||||
uses: pozetroninc/github-action-get-latest-release@master
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
|
||||
- name: create release
|
||||
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ needs.linux.outputs.ffversion }}
|
||||
commit: ${{ github.sha }}
|
||||
artifactErrorsFailBuild: true
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-freebsd/*,fastfetch-win64/*,fastfetch-win32/*
|
||||
@@ -1,153 +0,0 @@
|
||||
name: manage pushes
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
outputs:
|
||||
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libcjson-dev
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: run fastfetch
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: get fastfetch version
|
||||
id: ffversion
|
||||
run: echo "::set-output name=ffversion::$(./fastfetch --version-raw)"
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-linux
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
macos:
|
||||
name: MacOS
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: brew install vulkan-loader molten-vk
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: run fastfetch
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-macos
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
bsd:
|
||||
name: BSD
|
||||
runs-on: macos-12
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package
|
||||
./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
./flashfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-bsd
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch'
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- bsd
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
|
||||
- name: get latest release version
|
||||
id: get_version_release
|
||||
uses: pozetroninc/github-action-get-latest-release@master
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
|
||||
- name: create release
|
||||
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ needs.linux.outputs.ffversion }}
|
||||
commit: ${{ github.sha }}
|
||||
artifactErrorsFailBuild: true
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*
|
||||
@@ -3,6 +3,7 @@
|
||||
**/.cache/
|
||||
**/.kdev4/
|
||||
**/.DS_Store
|
||||
/.vs
|
||||
cscope.*
|
||||
tags
|
||||
fastfetch.kdev4
|
||||
|
||||
+689
-3
@@ -1,3 +1,689 @@
|
||||
# 2.3.1
|
||||
|
||||
Bugfixes:
|
||||
* Man page install location
|
||||
|
||||
# 2.3.0
|
||||
|
||||
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.**
|
||||
|
||||
Config related changes:
|
||||
* The deprecated flag `--gen-config conf` is removed
|
||||
* Flag `--gen-config` now does the same thing as `--migrate-config`, which can be used as config migration and default config file generation. Flag `--migrate-config` is removed
|
||||
* Fastfetch now searches for config files in the order of `fastfetch --list-config-paths`, and won't load other config if one is found.
|
||||
* The undocumented flag `--load-user-config` is removed. As an alternative, `--config none` can be used to disable loading config files.
|
||||
* `--config` (previously named `--load-config`) is now supported for command line arguments only. If specified, other config files won't be loaded, which works like other programs.
|
||||
* Config files will always be loaded before other command line flags being parsed. That is to say, command line flags will always override options defined in config files.
|
||||
* the value of GPUType `integrated` contained a typo and was fixed. Existing config files may need to be updated.
|
||||
|
||||
Features:
|
||||
* Support Oils and elvish shell version detection (Shell)
|
||||
* Support Windows Server Core (Windows)
|
||||
* Better ddcutil 2.x compatibility (Brightness, Linux)
|
||||
* Add completion support for fish (natively) and nushell (via [carapace-bin](https://github.com/rsteube/carapace-bin))
|
||||
* Support nix in macOS (Packages, macOS)
|
||||
* Print module description for `--list-modules`
|
||||
* Support `alacritty.toml` (TerminalFont)
|
||||
* Support board detection on macOS. It simplily prints machine model identifier as for now (Board, macOS)
|
||||
* Add general method to query product name (Host, macOS)
|
||||
* Use `libdrm` as a better fall back for detecting displays, which correctly detects current mode; supports refresh rate detection and maybe also faster than using `/sys/class/drm` (Display, Linux)
|
||||
* Support physical disk size detection (DiskIO)
|
||||
* Support physical disk name and type detection (DiskIO, FreeBSD)
|
||||
|
||||
Bugfixes:
|
||||
* End `va_list` before returning (@VoltrexKeyva)
|
||||
* Don't use background color when printing blocks (Color)
|
||||
* Fix lots of typos
|
||||
* Fix compatibility with Linux containers (Linux)
|
||||
* Don't report disabled monitors when using DRM (Linux)
|
||||
* Fix bad performance in some cases when using X11 (Display, Linux)
|
||||
* Fix some memory leaks
|
||||
* Fix used swap space detection (Swap, FreeBSD)
|
||||
* Don't leak fds to child processes (Linux)
|
||||
* Fix possible issues when reading procfs (Linux, @apocelipes)
|
||||
|
||||
Logos:
|
||||
* Add Adelie, Ironclad
|
||||
* Update parch
|
||||
|
||||
# 2.2.3
|
||||
|
||||
Features:
|
||||
* Update the latest mac models (Host, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Fix local ips detection on Android. Regression from `2.0.0` (LocalIP, Android)
|
||||
* Fix terminal detection on NixOS (Terminal)
|
||||
|
||||
# 2.2.2
|
||||
|
||||
Changes:
|
||||
* `--percent-type` now defaults to 9 (colored percentage numbers)
|
||||
* `fastfetch` now prints LocalIp module by default
|
||||
|
||||
Features:
|
||||
* LocalIP module now prints netmask in CIDR format for IPv4 (LocalIP)
|
||||
* Bios module now detects system firmware type (Bios)
|
||||
* Improve detection of `Battery`
|
||||
* Detect cycle count on supported platforms
|
||||
* Detect temperature on Linux when supported
|
||||
* Status detection on macOS has been adjusted to be consistent with other platforms
|
||||
* Linux binaries are built with imagemagick7 support
|
||||
|
||||
Bugfixes:
|
||||
* Fix uninitialized variables (#609)
|
||||
* Fix spelling of `--preserve-aspect-ratio` (#614)
|
||||
|
||||
Logos:
|
||||
|
||||
* Update NixOS_small
|
||||
|
||||
# 2.2.1
|
||||
|
||||
Hotfix release for #606
|
||||
|
||||
Bugfixes:
|
||||
* Fix broken presets due to the breaking changes introduced in 2.2.0
|
||||
|
||||
Features:
|
||||
* Pretty print `fastfetch --help`
|
||||
|
||||
# 2.2.0
|
||||
|
||||
This release introduces a new option `--migrate-config`, which migrates old flag based config file to new JSONC format
|
||||
|
||||
Changes:
|
||||
* `--pipe` and `--stat` are moved from `general` options to `display` options. This affects cjson configuration.
|
||||
* Display keys `percent*` and `size*` in JSON config are restructured. e.g. `{ "sizeNdigits": 1 }` is now `{ "size": { "ndigits": 1 } }`
|
||||
* With the introduction of `--migrate-config`, the old flag based config file is deprecated, and will be removed in 3.0.0 (next major version)
|
||||
* Support of `--gen-config conf` is deprecated accordingly, and will be removed in 2.3.0 (next minor version)
|
||||
* The global flag `--allow-slow-operations` is split into some explicit flags in different modules
|
||||
* `--packages-winget`: control whether `winget` packages count should be detected. Note it's a very slow operation, please enable it with caution.
|
||||
* `--chassis-use-wmi`: control whether `WMI` query should be used to detect chassis type, which detects more information, but slower. This flag only affects `--chassis-format` and `--format json`.
|
||||
* `--battery-use-setup-api`: control whether `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower.
|
||||
* `--wm-detect-plugin`: control whether WM plugins should be detected. Note it's implemented with global processes enumeration and can report false results.
|
||||
* `--de-slow-version-detection`: control DE version should be detected with slow operations. It's usually not necessary and only provided as a backup.
|
||||
* `--localip-default-route-only` and `--netio-default-route-only` defaults to true to avoid large number of results
|
||||
|
||||
Features:
|
||||
* Quirks for MIPS platforms (CPU, Linux)
|
||||
* Use devicetree path for OBP hosts (Host, Linux)
|
||||
* Detect `tmux: server` as tmux (Terminal, Linux)
|
||||
* Support urxvt version detection (Terminal, Linux)
|
||||
* Support st version detection (Terminal, Linux)
|
||||
* Support st terminal font detection (TerminalFont, Linux)
|
||||
* Support xfce4-terminal 1.1.0+ terminal font detection (TerminalFont, Linux)
|
||||
* Add option `--migrate-config <?target-file-path>`
|
||||
* Support Nvidia GPU temp and cuda core count detection via nvml. Use `--gpu-use-nvml` to enable it (GPU)
|
||||
* Try supporting Wifi authentication type detection in macOS Sonoma. Please file a feature request if you get `to be supported (num)` with result of `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep auth` (Wifi, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Better GPU memory and type detection (GPU, Windows)
|
||||
* Don't print display type twice (Display)
|
||||
* Detect BSSID instead of Wifi MAC address to align with other platforms (Wifi, macOS)
|
||||
* Remove support of used GPU memory detection, which is not reliable and only supported with `--gpu-force-vulkan`. (GPU)
|
||||
* Fix flag `--brightness-ddcci-sleep` (Brightness, Linux)
|
||||
* Fix hanging if a child process prints to both stdout and stderr (Linux)
|
||||
|
||||
Logos:
|
||||
* Add Black Mesa
|
||||
* Add cycledream
|
||||
* Add Evolinx
|
||||
* Add azos
|
||||
* Add Interix
|
||||
|
||||
# 2.1.2
|
||||
|
||||
Bugfixes:
|
||||
* Fix icon detection on Windows. It shows enabled system icons in desktop (`This PC`, `Recycle Bin`, etc) (Icon, Windows)
|
||||
* Fix compatibility with ddcutil 2.0 (Brightness, Linux)
|
||||
* Fix a compile warning (CPUUsage, FreeBSD)
|
||||
|
||||
# 2.1.1
|
||||
|
||||
Features:
|
||||
* Support opkg (Packages, Linux)
|
||||
* Support GNOME Console terminal version and font detection (Terminal, Linux)
|
||||
* Add `--cpu-freq-ndigits` to set number of digits for CPU frequency (CPU)
|
||||
* New module to detect physical disk I/O usage (DiskIO)
|
||||
* Add `--cpuusage-separate` to display CPU usage per CPU logical core
|
||||
* Add `--brightness-ddcci-sleep` to set the sleep times (in ms) when sending DDC/CI requests (Brightness, #580)
|
||||
|
||||
Bugfixes:
|
||||
* Fix possible crashes on Windows 7 (Disk, Windows)
|
||||
* Fix possible crashes caused by uninitialized strings (Users, Windows)
|
||||
* Improve support of `--help *-format` and several bugs are found and fixed
|
||||
* Don't incorrectly print `No active sound devices found` when using a non-controllable sound device (Sound, macOS)
|
||||
* Fix implementation processes counting (Processes, Linux)
|
||||
* Work around a issue that SSID cannot be detected on macOS Sonoma (Wifi, macOS)
|
||||
|
||||
Logo:
|
||||
* Add Chimera Linux
|
||||
* Add EndeavourSmall
|
||||
* Add Xenia
|
||||
* Add MainsailOS
|
||||
* Fix phyOS
|
||||
|
||||
# 2.1.0
|
||||
|
||||
This release introduces a new output format: JSON result
|
||||
|
||||
Changes:
|
||||
* Users module detects and prints user login time by default. Specifying `--users-compact` to disable it
|
||||
* Fastfetch now requires yyjson 0.8.0 or later, which is embedded in fastfetch source tree. If you build fastfetch with `-DENABLE_SYSTEM_YYJSON` cmake option, you must upgrade your yyjson package
|
||||
* Reduced information supported by `--terminal-format`, `--shell-format`
|
||||
* Some config presets (`devinfo` and `verbose`) are obsolete and removed. They are barely maintained and can be replaced with `--format json` now.
|
||||
* Custom strings in `--module-key` and `--module-format` are no longer trimmed.
|
||||
* `/boot` is hidden by default (FreeBSD, Disk)
|
||||
|
||||
Features:
|
||||
* Add `--format json`, which prints system information as JSON format
|
||||
* Add fast path for xfce4 version detection (DE, FreeBSD)
|
||||
* Support contour terminal version and font detection (Terminal / TerminalFont)
|
||||
* Support `kitty-direct` / `iterm` without specifying logo width / height. Note: in this case, the entre screen will be cleared.
|
||||
* Support new flag `--logo-separate`. If true, print modules at bottom of the logo
|
||||
* Support Apple Silicon CPU frequency detection (CPU, macOS)
|
||||
* Support user login time detection (Users)
|
||||
* Support winget package manager detection, guarded behind `--allow-slow-operations` (Packages, Windows)
|
||||
* Print monitor type (built-in or external) (Display)
|
||||
* Support full GPU detection in WSL (Linux, GPU)
|
||||
* Add `--module-key " "` as a special case for hiding keys
|
||||
* Support `--title-format`. See `fastfetch --help title-format` for detail
|
||||
* Support `--colors-key` (Colors)
|
||||
* Add `-c` as a shortcut of `--load-config`. Note it was used as the shortcut of `--color` before 2.0.5
|
||||
* Support Windows Service Pack version detection (Kernel, Windows)
|
||||
* Support Debian point releases detection (OS, Linux)
|
||||
* Add new module `NetIO` which prints network throughput (usage) of specified interface. Note this module costs about 1 second to finish.
|
||||
* Use `lscpu` to detect CPU name for ARM CPUs (CPU, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix fastfetch hanging in specific environment (#561)
|
||||
* Fix short read when reading from stdin (Logo)
|
||||
* Fix `poll() timeout or failed` error when image is very large (Logo)
|
||||
* Fix Termux Monet terminal version detection (Terminal)
|
||||
* Fix zpool volumes detection (Disk, Linux)
|
||||
* Fix external volumes detection (Disk, Linux)
|
||||
* Fix snap package number detection on systems other than Ubuntu (Packages, Linux)
|
||||
* Fix dpkg / apt package number detection (Packages, Linux)
|
||||
* Fix bluetooth mac address detection (Bluetooth, Windows)
|
||||
|
||||
Logo:
|
||||
* Add Afterglow
|
||||
* Add Elbrus
|
||||
* Update EvolutionOS
|
||||
* Update AOSC OS
|
||||
* Update Ubuntu_old
|
||||
* Update Windows 11_small
|
||||
* Add Amazon Linux
|
||||
* Add LainOS
|
||||
* Fix colors of Slackware
|
||||
|
||||
# 2.0.5
|
||||
|
||||
Bugfixes:
|
||||
* Fix segfault when using libxrandr (#544, Display, Linux)
|
||||
* Don't print 0px (#544, Cursor)
|
||||
|
||||
Features:
|
||||
* Add option `--disk-use-available` (#543)
|
||||
* Add option `--disk-show-readonly`
|
||||
|
||||
# 2.0.4
|
||||
|
||||
Bugfixes:
|
||||
* Fix building on 32-bit FreeBSD (Memory, FreeBSD)
|
||||
* Fix `--file-raw` doesn't work (Logo)
|
||||
|
||||
Features:
|
||||
* Trait `-` as an alias for `/dev/stdin`. Available for `--file`, `--file-raw` and `--raw` (Logo)
|
||||
|
||||
# 2.0.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix typo in config parsing for --color-title (#534)
|
||||
* Fix percent formatting for `--*-format` (#535)
|
||||
* Fix loading presets for homebrew (macOS)
|
||||
|
||||
Features:
|
||||
* Add option `--percent-ndigits`
|
||||
* Add command flag `--config` as an alias of `--load-config`
|
||||
* Windows packages now include presets (Windows)
|
||||
|
||||
# 2.0.2
|
||||
|
||||
Bugfixes:
|
||||
* Workaround [a compiler bug of GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282) (Windows)
|
||||
* Fix presets not detected by file name (#529)
|
||||
|
||||
Logo:
|
||||
* Add Tuxedo OS
|
||||
|
||||
# 2.0.1
|
||||
|
||||
First stable release of Fastfetch V2
|
||||
|
||||
Changes:
|
||||
* Unescape strings only when parsing `.conf` files
|
||||
* Previously: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\: *`. Note the backslashes are unescaped twice (once by shell and once by fastfetch).
|
||||
* Now: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\\: *`
|
||||
* Remove option shortcut `-c` (alias of `--color`), which is more commonly used as alias of `--config`
|
||||
* Rename `--recache` to `--logo-recache` (which is used for regenerate image logo cache). Remove option shortcut `-r` (alias of `--recache`).
|
||||
* Detecting brightness of external displays with DDC/CI is no longer guarded behind `--allow-slow-operations` (Brightness)
|
||||
|
||||
Features:
|
||||
* Add `--key-width` for aligning the left edge of values, supported both for global `--key-width` and specific module `--module-key-width`
|
||||
* Add `--bar-char-elapsed`, `--bar-char-total`, `--bar-width` and `--bar-border` options
|
||||
* Add CMake option `ENABLE_SYSTEM_YYJSON`, which allow building fastfetch with system-provided yyjson (for package managers)
|
||||
* Add new module `Version`, which prints fastfetch version (like `fastfetch --version`)
|
||||
|
||||
Bugfixes:
|
||||
* Fix label detection. Use `--disk-key 'Disk ({2})'` to display it (Disk, Linux)
|
||||
* Fix some module options were not inited
|
||||
* Fix terminal version and font detection on NixOS (Terminal, Linux)
|
||||
|
||||
# 2.0.0-beta
|
||||
|
||||
Fastfetch v2 introduces a new configuration file format: JSON config. Please refer to <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration> for details.
|
||||
|
||||
Changes:
|
||||
* Drop the dependency of cJSON. We now use [yyjson](https://ibireme.github.io/yyjson/doc/doxygen/html/index.html) to parse JSON documents.
|
||||
* Remove `--shell-version` and `--terminal-version`. They are always enabled (Terminal / Shell)
|
||||
* Remove `--*-error-format`, which seems to be useless
|
||||
* Remove `--display-detect-name`. Display name is always detected, and will be printed if multiple displays are detected
|
||||
* Deprecate `--set` and `--set-keyless`; they may be removed in future releases. Use JSON config with Custom module instead
|
||||
* Remove the special handling of Command module (it can be set once in the triditional `config.conf`). Use JSON config with Command module instead
|
||||
* Change `--wm-theme-*` to `--wmtheme-*`. Affect `key` and `format` (WMTheme)
|
||||
* Change `--terminal-font-*` to `--terminalfont-*`. Affect `key` and `format` (TerminalFont)
|
||||
* Module `Command` uses `/bin/sh` as the default shell on systems other than Windows (Command)
|
||||
* Fix M2 CPU temperature detection (CPU, macOS)
|
||||
* Detect monitor name when available, instead of using DRM connector name (Display / Brightness, Linux)
|
||||
|
||||
Features:
|
||||
* FreeBSD support is improved greatly, and actually tested in a physical machine
|
||||
* Add `--no-buffer` option for easier debugging. CMake option `ENABLE_BUFFER` is removed and always enabled.
|
||||
* Support `--*-key-color` option to change the key color of specified module
|
||||
* Support `--colors-symbol` and `--colors-padding-left` (Colors)
|
||||
* Add LM (Login Manager) module. Currently requires systemd installed (thus Linux only)
|
||||
* Add `--wmi-timeout` option (Windows)
|
||||
* Add `--logo-type small` to search for small logos
|
||||
* Support detecting brightness of external displays with DDC/CI (guard behind `--allow-slow-operations`) (Brightness)
|
||||
* Add option `--size-ndigits` and `--size-max-prefix` (#494)
|
||||
* Add option `--processing-timeout` to the timeout when waiting for child processes.
|
||||
* Public IP module prints the IP location if `--publicip-url` is not set (PublicIP)
|
||||
* Add option `--localip-default-route-only` (LocalIP)
|
||||
* Add option `--weather-location` (Weather)
|
||||
* Support iTerm non-ascii font detection (Terminal, macOS)
|
||||
* Add option `--title-color-user`, `--title-color-at` and `--title-color-host` (Title)
|
||||
* Add Exherbo logo and package manager count (Packages, Linux, #503)
|
||||
* Add module `Terminal Size` which prints the number of terminal width and height in characters and pixels
|
||||
* Add new option `--temperature-unit`
|
||||
* Better CPU and Host detection for Android (Android)
|
||||
* Support yakuake terminal version & font detection (Terminal, Linux)
|
||||
* Add new option `--bright-color` which can be used to disable the default bright color of keys, title and ASCII logo.
|
||||
* Add module `Monitor` which prints physical parameters (native resolutions and dimensions) of connected monitors
|
||||
* Support path with environment variables for `--logo-source` and `--load-config`.
|
||||
|
||||
Bugfixes:
|
||||
* Fix possible hanging (TerminalFont, #493)
|
||||
* Fix heap-buffer-overflow reading (DisplayServer, Linux)
|
||||
* Fix false errors when built without libnm support (Wifi, Linux)
|
||||
* Properly detect CPU on POWER (CPU, Linux)
|
||||
* Fix compatibility with Fig (Terminal, macOS)
|
||||
* Fix option `--title-fqdn` doesn't work (Title)
|
||||
* Fix used spaces calculation (Disk, Linux / BSD / macOS, #508)
|
||||
* Fix `--brightness-format` (Brightness)
|
||||
* Fix specifying `--set-keyless` with the same key second time won't override the value set before (#517)
|
||||
* Fix specifying `--color` second time won't clear the value set before (#517)
|
||||
|
||||
Logo:
|
||||
* Change the special handling of `kitty` protocol with `.png` image file to a new image protocol `kitty-direct`. This is the fastest image protocol because fastfetch doesn't need to pre-encode the image to base64 or something and the image content doesn't need to be transmitted via tty. Note:
|
||||
1. Although konsole was said to support `kitty` image protocol, it doesn't support `kitty-direct`
|
||||
2. wezterm support more image formats other than `.png` (tested with `.jpg` and `.webp`)
|
||||
* Port all logos supported by neo(wo)fetch. Fastfetch now has 350 builtin logos in total.
|
||||
|
||||
# 1.12.2
|
||||
|
||||
Features:
|
||||
* Support terminator terminal version detection (Linux, Terminal)
|
||||
* Support `pkgtool` package manager detection (Linux, Packages)
|
||||
* Support `Far` shell version detection (Windows, Shell)
|
||||
|
||||
Bugfixes:
|
||||
* Fix ConEmu terminal detection in some special cases (Windows, Terminal, #488)
|
||||
* Fix incorrect Host on M2 Mac Studio with M2 Max CPU (macOS, Host, #490)
|
||||
|
||||
# 1.12.1
|
||||
|
||||
Bugfixes:
|
||||
* Fix compiling error on Apple Slicon (Bios, macOS)
|
||||
|
||||
# 1.12.0
|
||||
|
||||
This release backports some changes from dev branch, and fixes 2 crashing issues
|
||||
|
||||
Features:
|
||||
* Support KDE / LXQT / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
|
||||
* Support QTerminal version & terminal font detection
|
||||
* Support MATE Terminal version & terminal font detection
|
||||
* Set `--pipe true` automatically if stdout is not a tty
|
||||
* Detect new macs released on WWDC 2023 (macOS, Host)
|
||||
* Count cached memory as free memory (FreeBSD, Memory)
|
||||
* Support sound detection (FreeBSD, Sound)
|
||||
|
||||
Bugfixes:
|
||||
* Fix DE detection on Windows 8.1 (Windows, DE)
|
||||
* Fix `--logo-padding-left` doesn't work when `--logo-padding-top` is set (Logo)
|
||||
* Fix KDE version detection on Fedora (DE)
|
||||
* Include limits.h when needed (Linux, #472)
|
||||
* Fix Windows drives detection in WSL (Linux, Disk)
|
||||
* Fix CPU temp detection (FreeBSD, CPU)
|
||||
* Fix disk detection (Android, Disk)
|
||||
* Fix Gnome Terminal version and font detection (FreeBSD, TerminalFont)
|
||||
* Fix crash on newer wayland desktops (Linux, Display, #477)
|
||||
* Fix vendor detection for Intel GPU (macOS, GPU)
|
||||
* Fix possible crashes on Windows Server (Windows, GPU, #484)
|
||||
|
||||
Logo:
|
||||
* Add bsd, freebsd_small, ghostbsd
|
||||
* Make Windows 11 logo colorable
|
||||
|
||||
# 1.11.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix a segfault bug, regression of `1.11.1` (Linux, wmtheme, #467)
|
||||
|
||||
# 1.11.2
|
||||
|
||||
This release should be the last version of fastfetch 1.x (if no serious bugs found, hopefully)
|
||||
|
||||
Features:
|
||||
* Support display name, type, rotation detection on Wayland (Linux, Display)
|
||||
* Print more useful display name instead of intel_backlight (Linux, Brightness)
|
||||
* Icons module supports Windows (Windows, Icons)
|
||||
* Add Wallpaper module which shows the current wallpaper image path
|
||||
* Add mac address detection `--localip-show-mac` (LocalIP, #451)
|
||||
|
||||
Bugfixes:
|
||||
* Fix Gnome version detection on Fedora (DE)
|
||||
* Fix Windows drives detection in WSL (Disk)
|
||||
|
||||
Changes:
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
|
||||
* `--theme-format` no longer supports individual GTK / plasma theme params.
|
||||
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
|
||||
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
|
||||
* `--localip-v6first` is no longer supported.
|
||||
|
||||
# 1.11.1
|
||||
|
||||
Features:
|
||||
* Support xonsh detection (TerminalShell)
|
||||
* Support Tabby version / terminal font detection (TerminalFont)
|
||||
|
||||
Bugfixes:
|
||||
* Fix name of Pro Controller (Gamepad, Windows)
|
||||
* Fix compile error with imagemagick enabled (Windows)
|
||||
* Fix copy-and-paste errors (Gamepad)
|
||||
* Flatpak: Fix user package count
|
||||
* Flatpak: Count runtime packages too (#441)
|
||||
* Fix flatpak package count (#441)
|
||||
* Don't print white color blocks with `--pipe` (#450)
|
||||
* Fix iTerm being detected as iTermServer-* sometimes
|
||||
* Fix sound device volume being incorrectly detected as muted sometimes (Sound)
|
||||
* Fix memleaks reported by LeakSanitizer (Linux)
|
||||
* Fix potential memory corruption bug in unicode.c (Windows)
|
||||
|
||||
Logo:
|
||||
* Update Windows 11 ASCII logo to look more visually consistent (#445)
|
||||
* Add another font color index to arch icon (#446)
|
||||
* Add SteamOS
|
||||
* Add macOS small / small2
|
||||
|
||||
# 1.11.0
|
||||
|
||||
Features:
|
||||
* Support linuxbrew (Packages, Linux)
|
||||
* Support foot terminal (#431, Linux)
|
||||
* Support cursor size detection on Windows (Cursor, Windows)
|
||||
* Support cursor detection on macOS (Cursor, macOS)
|
||||
* Support display name, display type and decimal refresh rate detection (Display, macOS / Windows)
|
||||
* Support `--display-compact-type` to display multiple resolutions in one line (Display)
|
||||
* Support flatpak-user (Packages, Linux, #436)
|
||||
* Support `--gpu-force-vulkan` to force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations` (GPU)
|
||||
|
||||
Bugfixes:
|
||||
* Fix date time format
|
||||
* Fix compiling with musl (Wifi, Linux, #429)
|
||||
* Don't exit if libpci is failed to init (GPU, Linux, #433)
|
||||
* Names of most well-known gamepads are correctly printed instead of `Wireless Controller` on Windows
|
||||
|
||||
Logo:
|
||||
* Small update for nobara logo (#435, @regulargvy13)
|
||||
|
||||
# 1.10.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix uninitialized variables (GPU, Windows)
|
||||
* Fix compiling errors (Windows)
|
||||
|
||||
Improvements:
|
||||
* Improve performance (WmTheme amd Font, Windows and macOS)
|
||||
* Enable nonblocking public-ip / weather detection (Android)
|
||||
|
||||
# 1.10.2
|
||||
|
||||
Bugfixes:
|
||||
* Handle `kAudioObjectPropertyElementMain` for macOS **SDK** < 12 (#425, @nandahkrishna)
|
||||
* Add missing `NULL` for `ffProcessAppendStdOut` (#421)
|
||||
|
||||
# 1.10.1
|
||||
|
||||
New release for debugging #421
|
||||
|
||||
# 1.10.0
|
||||
|
||||
Notable Changes:
|
||||
|
||||
* With the support of Win32 platform, original Windows 64bit artifact file is renamed to Win64 to avoid possible confusion
|
||||
|
||||
Features:
|
||||
* Bluetooth module
|
||||
* Sound module
|
||||
* Gamepad module
|
||||
* Support colored percentage numbers output (#409)
|
||||
* Support `--localip-compact-type` option (#408)
|
||||
* Terminator terminal font detection (@Zerogiven, #415)
|
||||
* Windows 32bit compatibility
|
||||
* Support global configuration in MSYS2 environment (Windows)
|
||||
* Support GPU driver version detection on Windows 11
|
||||
* Support scaled resolution detection for wayland (Linux)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Fix build with older libnm versions
|
||||
* Fix a rare case that fails to detect terminal
|
||||
* Fix Muffin detection (@Zerogiven, #411)
|
||||
* Fix IPv6 detection (Windows)
|
||||
* Fix scoop package count detection when scoop is installed in non-default path (Windows, #417)
|
||||
* Fix UB reported by clang
|
||||
* Honor $SCOOP when detecting scoop packages (#417)
|
||||
|
||||
Other:
|
||||
|
||||
* Simplified wmtheme output format (Windows)
|
||||
* Improved GPU detection performance on Windows 11
|
||||
* Latest Mac model identifier support (macOS)
|
||||
|
||||
# 1.9.1
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Fix builds on s390x (@jonathanspw, #402)
|
||||
* Fix zero refresh rate on some monitors (macOS)
|
||||
* Fix default formatting of Wifi module
|
||||
|
||||
# 1.9.0
|
||||
|
||||
Notable Changes:
|
||||
* fastfetch no longer creates a sample config file silently. Use `--gen-config` to generate one.
|
||||
* fastfetch now search for user config file in the order of `fastfetch --list-config-paths`
|
||||
* Unknown disks are hidden by default.
|
||||
* `Resolution` module is renamed to `Display`. (#393)
|
||||
|
||||
Features:
|
||||
* `--logo-padding-top` option (@CarterLi, #372)
|
||||
* Raw image file as logo support (@CarterLi)
|
||||
* Look for config files in `$APPDATA` ([RoamingAppData](https://superuser.com/questions/21458/why-are-there-directories-called-local-locallow-and-roaming-under-users-user#answer-21462)) (Windows)
|
||||
* Look for config files in `~/Library/Preferences` (macOS)
|
||||
* Add `--list-config-paths` option which list search paths of config files
|
||||
* Add `--list-data-paths` option which list search paths for presets and logos
|
||||
* Add `Brightness` module support
|
||||
* Add `Battery` module support for FreeBSD
|
||||
* Add `--disk-show-unknown` option for Disk module
|
||||
* Add `--disk-show-subvolumes` option for Disk module
|
||||
* Add `--gpu-hide-integrated` option (#379)
|
||||
* Add `--gpu-hide-discrete` option (#379)
|
||||
* Detect terminal version when available
|
||||
* Support `WezTerm` terminal font detection (requires [`wezterm` executable](https://wezfurlong.org/wezterm/cli/general.html) being available)
|
||||
* Add `--shell-version` and `--terminal-version` options to disable shell / terminal version detection
|
||||
* Enhance `--percent-type` to allow hiding other texts (#387)
|
||||
* Add Wifi module support for Linux
|
||||
* Detect scaled resolutions (Windows, macOS)
|
||||
* Optimise font module printing (Windows)
|
||||
* Detect pacman package count inside MSYS2 environment (Windows)
|
||||
* Add Wifi / Battery module support for Android
|
||||
* Disk name support for Linux
|
||||
|
||||
Logos:
|
||||
* Raspbian (@IamNoRobot, #373)
|
||||
|
||||
Bugfixes:
|
||||
* `--logo-type` now does accept `iterm` too (@CarterLi, #374)
|
||||
* Fix mintty terminal font detection (Windows)
|
||||
* Fix bug that line buffering doesn't work properly (Windows)
|
||||
* Fix rpm package count detection (Linux)
|
||||
* Fix cpu temp detection (Linux)
|
||||
|
||||
Other:
|
||||
* Fixed a Typo in iterm error message (@jessebot, #376)
|
||||
* Don't try to load config file in `/etc` (Windows)
|
||||
|
||||
# 1.8.2
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Fix memleaks Users module (Windows)
|
||||
* Fix shell detection when installed with scoop (Windows)
|
||||
* Don't use libcJSON as wlanapi's dll name (Windows)
|
||||
* Align artifact names to other platforms (Windows)
|
||||
|
||||
# 1.8.1
|
||||
|
||||
Notable Changes:
|
||||
|
||||
* `Song` was used as an alias to `Media` module. It's removed to avoid confusion. All song related flags (`--song-key`, etc) should change to media (`--media-key`, etc). (@CarterLi)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Mountpoint paths on linux get decoded correctly (#364)
|
||||
* Color parsing once again works (@IanManske, #365)
|
||||
* Using a custom key with a placeholder for the local ip module now does work correctly if multiple interfaces are present (#368)
|
||||
|
||||
# 1.8.0
|
||||
|
||||
This release introduces Windows support! Fastfetch now fully support all major desktop OSes (Linux, macOS, Windows and FreeBSD)
|
||||
|
||||
Notable Changes:
|
||||
* Bios / Board / Chassis modules are split against Host module for performance reasons
|
||||
* Caching is removed. Option `--nocache` is removed accordingly
|
||||
|
||||
Features:
|
||||
* Windows (7 and newer) is officially and fully supported
|
||||
* FreeBSD support is improved greatly (Bios, Cpu Temp, Cpu Usage, Disk, Host, Processes, Swap, Terminal / Shell, Uptime)
|
||||
* Adds a new flag `--stat`, which prints time usage for individual modules
|
||||
* Adds Wifi module which supports Windows and macOS
|
||||
* Adds data source option for logo printing
|
||||
* Detects Homebrew Cellar and Cask separately
|
||||
* Detects WSL version
|
||||
* Detects disk based on mount point
|
||||
* Exposes more chafa configs
|
||||
* Improves performance for Cpu Usage, Public IP, Weather modules
|
||||
* Improves performance for Kitty image protocol when both image width / height specified
|
||||
* Improves performance for large file loading
|
||||
* Improves performance for macOS WM and Host detection
|
||||
* Improves shell and terminal detection on macOS
|
||||
* Supports Deepin Terminal terminal font
|
||||
* Supports GPU detection on Android
|
||||
* Supports Kitty Terminal terminal font
|
||||
* Supports bar output for percentage values
|
||||
* Supports Bios module on macOS
|
||||
* Supports eopkg package manager detection
|
||||
* Supports iTerm image logo protocol
|
||||
* Supports image logo printing on macOS
|
||||
* Supports tcsh version detection
|
||||
* Vulkan module on macOS no longer requires vulkan-loader to work
|
||||
|
||||
Logos:
|
||||
* Alpine
|
||||
* CRUX
|
||||
* EndeavourOS
|
||||
* Enso
|
||||
* Garuda small
|
||||
* Nobara
|
||||
* OpenMandriva
|
||||
* Parabola GNU/Linux-libre
|
||||
* Rocky
|
||||
* Rosa
|
||||
* Solus
|
||||
* Univalent
|
||||
* Vanilla OS
|
||||
|
||||
Bugfixes:
|
||||
* Fixes disk size detection on 32bit Linux (#337)
|
||||
* Fixes cpu freq detection in WSL
|
||||
* Fixes internal bug of FFstrbuf
|
||||
* Fixes some memory leaks
|
||||
* Fixes segfault if 0 is given as argument index
|
||||
* Lots of code refactors
|
||||
|
||||
# 1.7.5
|
||||
|
||||
Fixes a crash on linux that could happen when getting zsh version (#285)
|
||||
|
||||
# 1.7.4
|
||||
|
||||
The last element in the default structure (currently the color blocks) is now printed again (#283)
|
||||
|
||||
# 1.7.3
|
||||
|
||||
A lot of small improvements for MacOS & BSD platforms.
|
||||
|
||||
Features:
|
||||
* BSD is now officially supported (#228)
|
||||
* MacPorts package manager support (@SladeGetz, #234)
|
||||
* Battery support for MacOS (@CarterLi, #235)
|
||||
* Processes, swap & terminal font support for MacOS(@CarterLi, #237)
|
||||
* Media support for MacOS (@CarterLi, #242)
|
||||
* Player support for MacOS (@CarterLi, #245)
|
||||
* WM theme support for MacOS (@CarterLi, #246)
|
||||
* CPU usage support for MacOS (@CarterLi, #247)
|
||||
* Power Adapter module (@CarterLi, #249)
|
||||
* Windows terminal font for WSL (@CarterLi, #254)
|
||||
* Temps & Font support for MacOS (@CarterLi, #258)
|
||||
* Terminal font support for Termux (@CarterLi, #263)
|
||||
* Weather module (@CarterLi, #266)
|
||||
|
||||
Logos
|
||||
* Crystal linux (@AloneER0, #239)
|
||||
* FreeBSD (@draumaz, #244)
|
||||
* New Ubuntu (@AloneER0, #259)
|
||||
|
||||
Bugfixes:
|
||||
* Don't segfault in GPU code on Intel Macs (@CarterLi, #236)
|
||||
* Don't use hardcoded size units in presets (@dr460nf1r3, #255)
|
||||
* Don't crash with some format strings (#252)
|
||||
* --logo none keeps key color now (#264)
|
||||
|
||||
# 1.7.2
|
||||
|
||||
Fixes the bash completions
|
||||
@@ -30,12 +716,12 @@ Other:
|
||||
|
||||
# 1.7.0
|
||||
|
||||
This release brings support for MacOS!
|
||||
This release brings support for MacOS!
|
||||
The basics things are working, but it is far from feature parity with Linux.
|
||||
I developed this in a VM, so bugs on real hardware are likely.
|
||||
If you have a Mac and no idea what to do with your free time, i am very happy to accept pull requests / work on issues.
|
||||
|
||||
A lot of things were changed under the hood to make this possible, which should bring better performance and stability on all platforms.
|
||||
A lot of things were changed under the hood to make this possible, which should bring better performance and stability on all platforms.
|
||||
|
||||
Besides that, the following things have changed:
|
||||
|
||||
@@ -101,7 +787,7 @@ Features:
|
||||
* Load `/etc/fastfetch/config.conf` before user config
|
||||
* Disk: print one decimal point if size < 100GB
|
||||
* `--title-fqdn` option, to print fully qualified domain name instead of host name in title
|
||||
|
||||
|
||||
Logos:
|
||||
* updated old NixOS logo
|
||||
|
||||
|
||||
+762
-299
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -16,7 +16,7 @@ Here i just add things that are easy to forget.
|
||||
- [ ] ZSH completions
|
||||
- [ ] Fish completions
|
||||
- [ ] Make CPU usage detection much faster and more accurate
|
||||
- [ ] Detect CPU usage in a common detection methode and expose it both to the cpuUsage module and the cpu format string
|
||||
- [ ] Detect CPU usage in a common detection method and expose it both to the cpuUsage module and the cpu format string
|
||||
- [ ] Per session caching
|
||||
|
||||
### General
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
# Fastfetch
|
||||
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, BSD, MacOS and Windows on [MSYS2](https://www.msys2.org/) are supported.
|
||||
[](https://github.com/fastfetch-cli/fastfetch/actions)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/blob/dev/LICENSE)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/graphs/contributors)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L5)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/commits)
|
||||
[](https://formulae.brew.sh/formula/fastfetch#default)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/releases)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/releases)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
|
||||
|
||||
<img src="screenshots/example1.png" width="49%" align="left" />
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||
@@ -10,98 +21,55 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
|
||||
<img src="screenshots/example3.png" width="48%" align="top" />
|
||||
<img src="screenshots/example5.png" height="15%" align="top" />
|
||||
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
||||
|
||||
## Installation
|
||||
|
||||
### Linux
|
||||
|
||||
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `sudo apt install fastfetch-<version>-Linux.deb`
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
|
||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging)
|
||||
|
||||
### macOS
|
||||
|
||||
`brew install fastfetch`
|
||||
|
||||
### Windows
|
||||
|
||||
`scoop install fastfetch`
|
||||
|
||||
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
`pkg install fastfetch`
|
||||
|
||||
### Android (Termux)
|
||||
|
||||
`pkg install fastfetch`
|
||||
|
||||
## Build from source
|
||||
|
||||
See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
|
||||
## Usage
|
||||
|
||||
* Run it with default configuration: `fastfetch`
|
||||
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what you interest: `fastfetch -c all.jsonc`
|
||||
* Find all data that fastfetch detects: `fastfetch -s <module> --format json`
|
||||
* Display help messages: `fastfetch --help`
|
||||
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --gen-config`
|
||||
|
||||
## Customization
|
||||
|
||||
With customization and speed being two competing goals, this project actually builds two executables.
|
||||
The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`.
|
||||
The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c).
|
||||
At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference.
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
|
||||
|
||||
There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config <filename>`. They may also serve as a good example for format arguments.
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and `libpthread`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it.
|
||||
|
||||
The following libraries are used if present at runtime:
|
||||
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
|
||||
* [`libxcb-randr`](https://xcb.freedesktop.org/),
|
||||
[`libXrandr`](https://gitlab.freedesktop.org/xorg/lib/libxrandr),
|
||||
[`libxcb`](https://xcb.freedesktop.org/),
|
||||
[`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better resolution detection and faster WM detection. The `*randr` ones provide multi monitor support The `libxcb*` ones usually have better performance.
|
||||
* [`libwayland-client`](https://wayland.freedesktop.org/): Better resolution performance and output in wayland sessions. Supports different refresh rates per monitor.
|
||||
* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings.
|
||||
* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings.
|
||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol.
|
||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art.
|
||||
* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol.
|
||||
* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Needed for detecting current media player and song.
|
||||
* [`libEGL`](https://www.khronos.org/registry/EGL/),
|
||||
[`libGLX`](https://dri.freedesktop.org/wiki/GLX/),
|
||||
[`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation.
|
||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
|
||||
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
|
||||
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ).
|
||||
* [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ).
|
||||
|
||||
## Support status
|
||||
All categories not listed here should work without needing a specific implementation.
|
||||
|
||||
##### Available Modules
|
||||
```
|
||||
Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
```
|
||||
|
||||
##### Logos
|
||||
```
|
||||
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin
|
||||
```
|
||||
* Most of the logos have a small variant. Access it by appending _small to the logo name.
|
||||
* Some logos have an old variant. Access it by appending _old to the logo name.
|
||||
* To disable the logo, use `--logo none`.
|
||||
* Get a list of all available logos with `fastfetch --print-logos`.
|
||||
* Printing images as logo is supported using Sixel / Kitty graphics protocol or chafas image to text conversion.
|
||||
|
||||
##### Package managers
|
||||
```
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop
|
||||
```
|
||||
|
||||
##### WM themes
|
||||
```
|
||||
KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), DWM (Windows)
|
||||
```
|
||||
|
||||
##### DE versions
|
||||
```
|
||||
KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
|
||||
```
|
||||
|
||||
##### Terminal fonts
|
||||
```
|
||||
Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux, mintty
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
fastfetch uses [`cmake`](https://cmake.org/) and [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) for building. The simplest steps to build the fastfetch and flashfetch binaries are:
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --target fastfetch --target flashfetch
|
||||
```
|
||||
|
||||
If pkg-config fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available.
|
||||
|
||||
### Building on Windows
|
||||
|
||||
Currently [MSYS2](https://www.msys2.org/) is required to build fastfetch. Running fastfetch requires msys2 runtime library (`msys-2.0.dll`) but not full MSYS2 environment.
|
||||
|
||||
Full native Windows executable is planned.
|
||||
|
||||
## Packaging
|
||||
|
||||
@@ -117,7 +85,7 @@ Full native Windows executable is planned.
|
||||
## FAQ
|
||||
|
||||
Q: Why do you need a very performant version of neofetch?
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever i use the terminal, but the slow speed annoyed me, so i created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overview whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
|
||||
Q: It does not display [*] correctly for me, what can i do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment i am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
Q: It does not display [*] correctly for me, what can I do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
|
||||
+92
-67
@@ -5,7 +5,7 @@ __fastfetch_complete_help()
|
||||
local __ff_helps=(
|
||||
"color"
|
||||
"format"
|
||||
"load-config"
|
||||
"config"
|
||||
"os-format"
|
||||
"host-format"
|
||||
"kernel-format"
|
||||
@@ -13,18 +13,18 @@ __fastfetch_complete_help()
|
||||
"processes-format"
|
||||
"packages-format"
|
||||
"shell-format"
|
||||
"resolution-format"
|
||||
"display-format"
|
||||
"de-format"
|
||||
"wm-format"
|
||||
"wm-theme-format"
|
||||
"wmtheme-format"
|
||||
"theme-format"
|
||||
"icons-format"
|
||||
"font-format"
|
||||
"cursor-format"
|
||||
"terminal-format"
|
||||
"terminal-font-format"
|
||||
"terminalfont-format"
|
||||
"cpu-format"
|
||||
"cpu-usage-format"
|
||||
"cpuusage-format"
|
||||
"gpu-format"
|
||||
"memory-format"
|
||||
"swap-format"
|
||||
@@ -32,8 +32,8 @@ __fastfetch_complete_help()
|
||||
"battery-format"
|
||||
"poweradapter-format"
|
||||
"locale-format"
|
||||
"local-ip-format"
|
||||
"public-ip-format"
|
||||
"localip-format"
|
||||
"publicip-format"
|
||||
"player-format"
|
||||
"media-format"
|
||||
"datetime-format"
|
||||
@@ -42,6 +42,7 @@ __fastfetch_complete_help()
|
||||
"vulkan-format"
|
||||
"opengl-format"
|
||||
"opencl-format"
|
||||
"bluetooth-format"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_helps[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
@@ -65,7 +66,7 @@ __fastfetch_complete_path()
|
||||
|
||||
__fastfetch_complete_logo()
|
||||
{
|
||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos-autocompletion)" -- "$CURRENT_WORD"))
|
||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos autocompletion)" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_logo_type()
|
||||
@@ -112,7 +113,7 @@ __fastfetch_complete_option()
|
||||
"${FF_OPTIONS_LOGO[@]}"
|
||||
"${FF_OPTIONS_LOGO_TYPE[@]}"
|
||||
"${FF_OPTIONS_BINARY_PREFIX[@]}"
|
||||
"${FF_OPTIONS_GL[@]}"
|
||||
"${FF_OPTIONS_OPENGL[@]}"
|
||||
)
|
||||
|
||||
if [[ $WORD_COUND -lt 3 ]]; then
|
||||
@@ -160,6 +161,8 @@ __fastfetch_completion()
|
||||
"--print-config-system"
|
||||
"--print-config-user"
|
||||
"--print-structure"
|
||||
"--gen-config"
|
||||
"--gen-config-force"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_HELP=(
|
||||
@@ -169,25 +172,35 @@ __fastfetch_completion()
|
||||
|
||||
local FF_OPTIONS_BOOL=(
|
||||
"-r"
|
||||
"--recache"
|
||||
"--nocache"
|
||||
"--show-errors"
|
||||
"--logo-print-remaining"
|
||||
"--multithreading"
|
||||
"--stat"
|
||||
"--allow-slow-operations"
|
||||
"--disable-linewrap"
|
||||
"--hide-cursor"
|
||||
"--cpu-temp"
|
||||
"--gpu-temp"
|
||||
"--battery-temp"
|
||||
"--display-precise-refresh-rate"
|
||||
"--localip-show-ipv4"
|
||||
"--localip-show-ipv6"
|
||||
"--localip-show-loop"
|
||||
"--localip-name-prefix"
|
||||
"--localip-compact-type"
|
||||
"--escape-bedrock"
|
||||
"--pipe"
|
||||
"--title-fqdn"
|
||||
"--escape-bedrock"
|
||||
"--disk-folders"
|
||||
"--disk-show-external"
|
||||
"--disk-show-hidden"
|
||||
"--disk-show-subvolumes"
|
||||
"--gpu-hide-integrated"
|
||||
"--gpu-hide-discrete"
|
||||
"--gpu-force-vulkan"
|
||||
"--disk-show-unknown"
|
||||
"--bluetooth-show-disconnected"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_STRING=(
|
||||
@@ -195,6 +208,7 @@ __fastfetch_completion()
|
||||
"--logo-padding"
|
||||
"--logo-padding-left"
|
||||
"--logo-padding-right"
|
||||
"--logo-padding-top"
|
||||
"--logo-color-1"
|
||||
"--logo-color-2"
|
||||
"--logo-color-3"
|
||||
@@ -203,141 +217,149 @@ __fastfetch_completion()
|
||||
"--logo-color-6"
|
||||
"--logo-color-7"
|
||||
"--logo-color-8"
|
||||
"--logo-color-9"
|
||||
"--logo-width"
|
||||
"--logo-height"
|
||||
"--logo-color-9"
|
||||
"-c"
|
||||
"--color"
|
||||
"--color-keys"
|
||||
"--color-title"
|
||||
"--display-compact-type"
|
||||
"--separator"
|
||||
"-s"
|
||||
"--structure"
|
||||
"--set"
|
||||
"--set-keyless"
|
||||
"--player-name"
|
||||
"--public-ip-url"
|
||||
"--public-ip-timeout"
|
||||
"--percent-type"
|
||||
"--publicip-url"
|
||||
"--publicip-timeout"
|
||||
"--weather-output-format"
|
||||
"--weather-timeout"
|
||||
"--os-key"
|
||||
"--os-format"
|
||||
"--os-error"
|
||||
"--os-key-color"
|
||||
"--host-key"
|
||||
"--host-format"
|
||||
"--host-error"
|
||||
"--host-key-color"
|
||||
"--kernel-key"
|
||||
"--kernel-format"
|
||||
"--kernel-error"
|
||||
"--kernel-key-color"
|
||||
"--uptime-key"
|
||||
"--uptime-format"
|
||||
"--uptime-error"
|
||||
"--uptime-key-color"
|
||||
"--processes-key"
|
||||
"--processes-format"
|
||||
"--processes-error"
|
||||
"--processes-key-color"
|
||||
"--packages-key"
|
||||
"--packages-format"
|
||||
"--packages-error"
|
||||
"--packages-key-color"
|
||||
"--shell-key"
|
||||
"--shell-format"
|
||||
"--shell-error"
|
||||
"--resolution-key"
|
||||
"--resolution-format"
|
||||
"--resolution-error"
|
||||
"--shell-key-color"
|
||||
"--display-key"
|
||||
"--display-format"
|
||||
"--display-key-color"
|
||||
"--de-key"
|
||||
"--de-format"
|
||||
"--de-error"
|
||||
"--de-key-color"
|
||||
"--wm-key"
|
||||
"--wm-format"
|
||||
"--wm-error"
|
||||
"--wm-theme-key"
|
||||
"--wm-theme-format"
|
||||
"--wm-theme-error"
|
||||
"--wm-key-color"
|
||||
"--wmtheme-key"
|
||||
"--wmtheme-format"
|
||||
"--wmtheme-key-color"
|
||||
"--theme-key"
|
||||
"--theme-format"
|
||||
"--theme-error"
|
||||
"--theme-key-color"
|
||||
"--icons-key"
|
||||
"--icons-format"
|
||||
"--icons-error"
|
||||
"--icons-key-color"
|
||||
"--font-key"
|
||||
"--font-format"
|
||||
"--font-error"
|
||||
"--font-key-color"
|
||||
"--cursor-key"
|
||||
"--cursor-format"
|
||||
"--cursor-error"
|
||||
"--cursor-key-color"
|
||||
"--terminal-key"
|
||||
"--terminal-format"
|
||||
"--terminal-error"
|
||||
"--terminal-font-key"
|
||||
"--terminal-font-format"
|
||||
"--terminal-font-error"
|
||||
"--terminal-key-color"
|
||||
"--terminalfont-key"
|
||||
"--terminalfont-format"
|
||||
"--terminalfont-key-color"
|
||||
"--cpu-key"
|
||||
"--cpu-format"
|
||||
"--cpu-error"
|
||||
"--cpu-key-color"
|
||||
"--cpu-useage-key"
|
||||
"--cpu-useage-format"
|
||||
"--cpu-useage-error"
|
||||
"--cpu-useage-key-color"
|
||||
"--gpu-key"
|
||||
"--gpu-format"
|
||||
"--gpu-error"
|
||||
"--gpu-key-color"
|
||||
"--memory-key"
|
||||
"--memory-format"
|
||||
"--memory-error"
|
||||
"--memory-key-color"
|
||||
"--swap-key"
|
||||
"--swap-format"
|
||||
"--swap-error"
|
||||
"--swap-key-color"
|
||||
"--disk-key"
|
||||
"--disk-format"
|
||||
"--disk-error"
|
||||
"--disk-key-color"
|
||||
"--battery-key"
|
||||
"--battery-format"
|
||||
"--battery-error"
|
||||
"--battery-key-color"
|
||||
"--poweradapter-key"
|
||||
"--poweradapter-format"
|
||||
"--poweradapter-error"
|
||||
"--poweradapter-key-color"
|
||||
"--locale-key"
|
||||
"--locale-format"
|
||||
"--locale-error"
|
||||
"--local-ip-key"
|
||||
"--local-ip-format"
|
||||
"--local-ip-error"
|
||||
"--public-ip-key"
|
||||
"--public-ip-format"
|
||||
"--public-ip-error"
|
||||
"--locale-key-color"
|
||||
"--localip-key"
|
||||
"--localip-format"
|
||||
"--localip-key-color"
|
||||
"--publicip-key"
|
||||
"--publicip-format"
|
||||
"--publicip-key-color"
|
||||
"--wifi-key"
|
||||
"--wifi-format"
|
||||
"--wifi-key-color"
|
||||
"--weather-key"
|
||||
"--weather-format"
|
||||
"--weather-error"
|
||||
"--weather-key-color"
|
||||
"--player-key"
|
||||
"--player-format"
|
||||
"--player-error"
|
||||
"--player-key-color"
|
||||
"--media-key"
|
||||
"--media-format"
|
||||
"--media-error"
|
||||
"--media-key-color"
|
||||
"--datetime-key"
|
||||
"--datetime-format"
|
||||
"--datetime-error"
|
||||
"--datetime-key-color"
|
||||
"--date-key"
|
||||
"--date-format"
|
||||
"--date-error"
|
||||
"--date-key-color"
|
||||
"--time-key"
|
||||
"--time-format"
|
||||
"--time-error"
|
||||
"--time-key-color"
|
||||
"--vulkan-key"
|
||||
"--vulkan-format"
|
||||
"--vulkan-error"
|
||||
"--vulkan-key-color"
|
||||
"--opengl-key"
|
||||
"--opengl-format"
|
||||
"--opengl-error"
|
||||
"--opengl-key-color"
|
||||
"--opencl-key"
|
||||
"--opencl-format"
|
||||
"--opencl-error"
|
||||
"--opencl-key-color"
|
||||
"--users-key"
|
||||
"--users-format"
|
||||
"--users-error"
|
||||
"--users-key-color"
|
||||
"--bluetooth-key"
|
||||
"--bluetooth-format"
|
||||
"--bluetooth-key-color"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_PATH=(
|
||||
"--load-config"
|
||||
"-c"
|
||||
"--config"
|
||||
"--os-file"
|
||||
"--lib-pci"
|
||||
"--lib-vulkan"
|
||||
@@ -359,6 +381,9 @@ __fastfetch_completion()
|
||||
"--lib-glx"
|
||||
"--lib-osmesa"
|
||||
"--lib-opencl"
|
||||
"--lib-pulse"
|
||||
"--lib-ddcutil"
|
||||
"--lib-nm"
|
||||
"--battery-dir"
|
||||
)
|
||||
|
||||
@@ -375,8 +400,8 @@ __fastfetch_completion()
|
||||
"--binary-prefix"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_GL=(
|
||||
"--gl"
|
||||
local FF_OPTIONS_OPENGL=(
|
||||
"--opengl-type"
|
||||
)
|
||||
|
||||
if __fastfetch_previous_matches "${FF_OPTIONS_SINGLE[@]}"; then
|
||||
@@ -399,7 +424,7 @@ __fastfetch_completion()
|
||||
__fastfetch_complete_logo_type
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_BINARY_PREFIX[@]}"; then
|
||||
__fastfetch_complete_binary_prefix
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_GL[@]}"; then
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_OPENGL[@]}"; then
|
||||
__fastfetch_complete_gl
|
||||
else
|
||||
__fastfetch_complete_option
|
||||
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
if not test -x fastfetch
|
||||
return
|
||||
end
|
||||
|
||||
complete -c fastfetch -f
|
||||
|
||||
function __fastfetch_complete_bool
|
||||
echo -e "true\tBool"
|
||||
echo -e "false\tBool"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_color
|
||||
echo -e "black\tColor"
|
||||
echo -e "red\tColor"
|
||||
echo -e "green\tColor"
|
||||
echo -e "yellow\tColor"
|
||||
echo -e "blue\tColor"
|
||||
echo -e "magenta\tColor"
|
||||
echo -e "cyan\tColor"
|
||||
echo -e "white\tColor"
|
||||
echo -e "default\tColor"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_command
|
||||
for line in (fastfetch --list-modules autocompletion)
|
||||
set -l pair (string split -m 2 : $line)
|
||||
set -l module (string lower $pair[1])
|
||||
|
||||
echo -e "$module-format\tModule format"
|
||||
end
|
||||
echo -e "format\tCustom format"
|
||||
echo -e "color\tColor format"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_config
|
||||
for line in (fastfetch --list-presets autocompletion)
|
||||
echo -e "$line\tPreset"
|
||||
end
|
||||
echo -e "none\tDisable loading config file"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_logo
|
||||
for line in (fastfetch --list-logos autocompletion)
|
||||
echo -e "$line\tBuiltin logo"
|
||||
end
|
||||
echo -e "none\tDon't print logo"
|
||||
echo -e "small\tPrint small ascii logo if available"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_structure
|
||||
for line in (fastfetch --list-modules autocompletion)
|
||||
set -l pair (string split -m 2 : $line)
|
||||
echo -e "$pair[1]\t$pair[2]"
|
||||
end
|
||||
end
|
||||
|
||||
string match -r -a -g "^###> ?(.*)" < (status -f) | string collect | python3 | source
|
||||
|
||||
###> #!/usr/bin/env python3
|
||||
###>
|
||||
###> import json, subprocess, sys
|
||||
###>
|
||||
###> def main():
|
||||
###> data: dict[str, list[dict]] = json.loads(subprocess.check_output(['fastfetch', '--help-raw']))
|
||||
###>
|
||||
###> for key in data:
|
||||
###> for flag in data[key]:
|
||||
###> if flag.get('pseudo', False):
|
||||
###> continue
|
||||
###>
|
||||
###> command_prefix: str = f'complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}"';
|
||||
###> if 'short' in flag:
|
||||
###> command_prefix += f' -o "{flag["short"]}"'
|
||||
###>
|
||||
###> if 'arg' in flag:
|
||||
###> type: str = flag['arg']['type'];
|
||||
###> if type == 'bool':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_bool)"')
|
||||
###> elif type == 'color':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_color)"')
|
||||
###> elif type == 'command':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_command)"')
|
||||
###> elif type == 'config':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_config)"')
|
||||
###> elif type == 'enum':
|
||||
###> temp: str = ' '.join(map(lambda x: f"{x[0]}\\t{x[1]}", flag["arg"]["enum"].items()))
|
||||
###> print(f'{command_prefix} -x -a "{temp}"')
|
||||
###> elif type == 'logo':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_logo)"')
|
||||
###> elif type == 'structure':
|
||||
###> print(f'{command_prefix} -x -a "(__fish_complete_list : __fastfetch_complete_structure)"')
|
||||
###> elif type == 'path':
|
||||
###> print(f'{command_prefix} -r -F')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -x')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -f')
|
||||
###>
|
||||
###> if __name__ == "__main__":
|
||||
###> try:
|
||||
###> main()
|
||||
###> except:
|
||||
###> sys.exit(1)
|
||||
###>
|
||||
@@ -0,0 +1,134 @@
|
||||
.TH FASTFETCH 1 "@FASTFETCH_BUILD_DATE@" "@CMAKE_PROJECT_NAME@ @CMAKE_PROJECT_VERSION@"
|
||||
|
||||
.SH NAME
|
||||
fastfetch \- a neofetch\-like tool for fetching system information and
|
||||
displaying them in a pretty way
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
.B fastfetch
|
||||
.I [options...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
Fastfetch is a neofetch\-like tool for fetching system information and
|
||||
displaying them in a pretty way. It is written mainly in C, with performance
|
||||
and customizability in mind.
|
||||
Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
|
||||
|
||||
.SH "EXIT STATUS"
|
||||
|
||||
On successful execution, fastfetch returns zero. If any error happened,
|
||||
the exit code will be non\-zero.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.SS "Informative Options"
|
||||
.TP
|
||||
|
||||
.B \-h, \-\-help \fI [command]
|
||||
Show help output, displaying all available options or help for given command
|
||||
.TP
|
||||
|
||||
.B \-v, \-\-version
|
||||
Show version of fastfetch
|
||||
.TP
|
||||
|
||||
.B \-\-list\-config\-paths
|
||||
List search paths of config files
|
||||
.TP
|
||||
|
||||
.B \-\-list\-data\-paths
|
||||
List search paths of presets and logos
|
||||
.TP
|
||||
|
||||
.B \-\-list\-logos
|
||||
List available logos, they can be loaded with \fI \-\-logo
|
||||
.TP
|
||||
|
||||
.B \-\-list\-modules
|
||||
List available modules
|
||||
.TP
|
||||
|
||||
.B \-\-list\-presets
|
||||
List available presets, they can be loaded with \fI \-\-config
|
||||
.TP
|
||||
|
||||
.B \-\-list\-features
|
||||
List the supported features fastfetch was compiled with
|
||||
.TP
|
||||
|
||||
.B \-\-print\-logos
|
||||
Print available logos
|
||||
.TP
|
||||
|
||||
.B \-\-print\-structure
|
||||
Print the default structure
|
||||
|
||||
|
||||
.SS "Display Options"
|
||||
.TP
|
||||
|
||||
.B \-l, \-\-logo \fI <logo>
|
||||
Set the logo to display
|
||||
.TP
|
||||
|
||||
.B \-s, \-\-structure \fI <structure>
|
||||
Set the structure of the fetch. For details about the structure,
|
||||
see the CONFIGURATION section.
|
||||
|
||||
|
||||
.SS "Config Options"
|
||||
.TP
|
||||
|
||||
.B \-c, \-\-config \fI <config>
|
||||
Use the specified config file or preset. If "none", disable further config
|
||||
loading. For details about config files, see the CONFIGURATION section
|
||||
.TP
|
||||
|
||||
.B \-\-gen\-config \fI [file]
|
||||
Generate a config file with options specified on the command line.
|
||||
If \fI file \fR is specified, the configuration will written to the
|
||||
file, otherwise it will be written to stdout.
|
||||
.TP
|
||||
|
||||
.B \-\-gen\-config\-force \fI [file]
|
||||
Same as \fB \-\-gen\-config\fR, but overwrites existing config
|
||||
.TP
|
||||
|
||||
|
||||
To list all options, use \fB \-\-help\fR this will also print all available module options.
|
||||
|
||||
.SH CONFIGURATION
|
||||
.SS "Fetch Structure"
|
||||
The structure of a fetch describes the modules that should be included in
|
||||
the output. It consists of a string of modules, separated by a colon (:).
|
||||
To list all available modules, use \fB \-\-list\-modules \fR
|
||||
|
||||
.SS "Config Files"
|
||||
|
||||
fastfetch supports two types of config files. The legacy
|
||||
configuration files and a JSONC based format.
|
||||
|
||||
A JSONC config file is a JSON file that also supports comments with (//). Those
|
||||
files must have the extension '.jsonc'. You can migrate a legacy config
|
||||
file to the JSONC format by using \fB\-\-gen\-config\fR.
|
||||
|
||||
The specified configuration/preset files are searched in the following order:
|
||||
|
||||
1. relative to the current working directory
|
||||
|
||||
2. relative to ~/.local/share/fastfetch/presets/
|
||||
|
||||
3. relative to /usr/share/fastfetch/presets/
|
||||
|
||||
When both a '.jsonc' and a '.conf' file with the same name is found,
|
||||
the '.jsonc' file is preferred.
|
||||
|
||||
Fastfetch provides some default presets. List them with \fB \-\-print\-available\-presets\fR.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR neofetch (1)
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs to:\fI https://github.com/fastfetch\-cli/fastfetch/issues \fR
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1 +1 @@
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
|
||||
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
"host",
|
||||
"bios",
|
||||
"board",
|
||||
"chassis",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
"display",
|
||||
"brightness",
|
||||
"monitor",
|
||||
"lm",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"wallpaper",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"terminalsize",
|
||||
"cpu",
|
||||
"cpuusage",
|
||||
"gpu",
|
||||
"memory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
"publicip",
|
||||
"localip",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"users",
|
||||
"bluetooth",
|
||||
"sound",
|
||||
"gamepad",
|
||||
"weather",
|
||||
"netio",
|
||||
"diskio",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "builtin",
|
||||
"source": "arch"
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
{
|
||||
"type": "os",
|
||||
"format": "Arch Linux ({12})"
|
||||
},
|
||||
"host",
|
||||
"kernel",
|
||||
"uptime",
|
||||
{
|
||||
"type": "packages",
|
||||
"format": "{} (pacman)"
|
||||
},
|
||||
"shell",
|
||||
"display",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"cpu",
|
||||
"gpu",
|
||||
"memory",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"locale",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"display": {
|
||||
"stat": true,
|
||||
"pipe": true,
|
||||
"showErrors": true,
|
||||
"noBuffer": true
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
"host",
|
||||
"bios",
|
||||
"board",
|
||||
"chassis",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
"display",
|
||||
"brightness",
|
||||
"monitor",
|
||||
"lm",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"wallpaper",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"terminalsize",
|
||||
"cpu",
|
||||
"cpuusage",
|
||||
"gpu",
|
||||
"memory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
"publicip",
|
||||
"localip",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"users",
|
||||
"bluetooth",
|
||||
"sound",
|
||||
"gamepad",
|
||||
{
|
||||
"type": "weather",
|
||||
"timeout": 1000
|
||||
},
|
||||
"netio",
|
||||
"diskio",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
--disable-linewrap false
|
||||
--multithreading false
|
||||
--show-errors
|
||||
--recache
|
||||
@@ -1,3 +0,0 @@
|
||||
--load-config devinfo
|
||||
--load-config all
|
||||
--load-config verbose
|
||||
@@ -0,0 +1,150 @@
|
||||
// Load with --load-config examples/2.jsonc
|
||||
// Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"padding": {
|
||||
"top": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": " -> "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"keyWidth": 10
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": " \u001b[90m \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m \u001b[38m \u001b[39m \u001b[38m \u001b[37m \u001b[36m \u001b[35m \u001b[34m \u001b[33m \u001b[32m \u001b[31m \u001b[90m"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": " OS",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "│ ├",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": "│ ├",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "│ └",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": " DE/WM",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "lm",
|
||||
"key": "│ ├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wmtheme",
|
||||
"key": "│ ├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": "│ ├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "│ ├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wallpaper",
|
||||
"key": "│ └",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": " PC",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "│ ├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": "│ └",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "sound",
|
||||
"key": " SND",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "player",
|
||||
"key": "│ ├",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "media",
|
||||
"key": "│ └",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "custom",
|
||||
"format": " \u001b[90m \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m \u001b[38m \u001b[39m \u001b[38m \u001b[37m \u001b[36m \u001b[35m \u001b[34m \u001b[33m \u001b[32m \u001b[31m \u001b[90m"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "file:///C:/msys64/home/zhang/fastfetch/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"separator": "\u001b[31m-> "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"key": "Distro ",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "Shell ",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "Terminal ",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "Display ",
|
||||
"type": "display"
|
||||
},
|
||||
{
|
||||
"key": "Backlight ",
|
||||
"type": "brightness"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 6,
|
||||
"symbol": "circle"
|
||||
}
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -20,5 +20,5 @@
|
||||
--wm-key " "
|
||||
--shell-key " "
|
||||
--terminal-key " "
|
||||
--terminal-font-key " "
|
||||
--terminalfont-key " "
|
||||
--packages-key " "
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
// Load with --load-config examples/2.jsonc
|
||||
// Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
// "logo": {
|
||||
// "type": "iterm",
|
||||
// "source": "/Users/carter/Desktop/apple1.png",
|
||||
// "width": 28,
|
||||
// "height": 12
|
||||
// },
|
||||
"display": {
|
||||
"separator": " "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom", // HardwareStart
|
||||
"format": "┌─────────── \u001b[1mHardware Information\u001b[0m ───────────┐" // `\u001b` is `\033`, or `\e`
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "brightness",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "poweradapter",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "bluetooth",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "sound",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "gamepad",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "custom", // SoftwareStart
|
||||
"format": "├─────────── \u001b[1mSoftware Information\u001b[0m ───────────┤"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": " ",
|
||||
"format": "{1}@{2}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": " " // Just get your distro's logo off nerdfonts.com
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": " ",
|
||||
"format": "{1} {2}"
|
||||
},
|
||||
{
|
||||
"type": "lm",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "de",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "theme",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "wallpaper",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "media",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": " ",
|
||||
"compact": true
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "wifi",
|
||||
"key": " ",
|
||||
"format": "{4}" // ssid
|
||||
},
|
||||
{
|
||||
"type": "locale",
|
||||
"key": " "
|
||||
},
|
||||
{
|
||||
"type": "custom", // InformationEnd
|
||||
"format": "└────────────────────────────────────────────┘"
|
||||
},
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 2,
|
||||
"symbol": "circle"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Load with --load-config examples/3.jsonc
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": "debian_small",
|
||||
"display": {
|
||||
"binaryPrefix": "si"
|
||||
},
|
||||
"modules": [
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"memory",
|
||||
{
|
||||
"type": "disk",
|
||||
"folders": "/:/home:/boot:/efi"
|
||||
},
|
||||
"localip"
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
--logo arch_small
|
||||
--logo-padding-right 1
|
||||
--separator " "
|
||||
--structure Date:Time:Break:Player:Media
|
||||
--structure DateTime:Break:Player:Media
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Load with --load-config examples/4.jsonc
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"source": "arch_small",
|
||||
"padding": {
|
||||
"right": 1
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"binaryPrefix": "si",
|
||||
"color": "blue",
|
||||
"separator": " "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "datetime",
|
||||
"key": "Date",
|
||||
"format": "{1}-{3}-{11}"
|
||||
},
|
||||
{
|
||||
"type": "datetime",
|
||||
"key": "Time",
|
||||
"format": "{14}:{17}:{20}"
|
||||
},
|
||||
"break",
|
||||
"player",
|
||||
"media"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Load with --load-config examples/5.jsonc
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": null,
|
||||
"display": {
|
||||
"color": "reset_magenta"
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "theme",
|
||||
"key": "T",
|
||||
"format": "{7}"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": "I",
|
||||
"format": "{5}"
|
||||
},
|
||||
{
|
||||
"type": "font",
|
||||
"key": "F"
|
||||
},
|
||||
{
|
||||
"type": "cursor",
|
||||
"key": "C"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// Load with --load-config examples/2.jsonc
|
||||
// Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
// "logo": {
|
||||
// "type": "iterm",
|
||||
// "source": "/Users/carter/Desktop/apple1.png",
|
||||
// "width": 28,
|
||||
// "height": 12
|
||||
// },
|
||||
"display": {
|
||||
"separator": " "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "host",
|
||||
"key": "╭─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "brightness",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "poweradapter",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "gamepad",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "bluetooth",
|
||||
"key": "├─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "sound",
|
||||
"key": "╰─",
|
||||
"keyColor": "green"
|
||||
},
|
||||
"break",
|
||||
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "╭─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "lm",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "de",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "theme",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": "├─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "wallpaper",
|
||||
"key": "╰─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
|
||||
"break",
|
||||
{
|
||||
"type": "title",
|
||||
"key": "╭─",
|
||||
"format": "{1}@{2}",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "├─", // Just get your distro's logo off nerdfonts.com
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "├─",
|
||||
"format": "{1} {2}",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": "├─",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "├─",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "media",
|
||||
"key": "├─",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "├─",
|
||||
"compact": true,
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "├─",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wifi",
|
||||
"key": "├─",
|
||||
"format": "{4}", // ssid
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "locale",
|
||||
"key": "╰─",
|
||||
"keyColor": "blue"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// Load with --load-config examples/2.jsonc
|
||||
// Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"padding": {
|
||||
"top": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": " -> "
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
{
|
||||
"type": "os",
|
||||
"key": " OS",
|
||||
"keyColor": "yellow",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "├", // Just get your distro's logo off nerdfonts.com
|
||||
"keyColor": "yellow",
|
||||
"format": "{6}{?6} {?}{10} {8}"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "├",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": "├",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "└",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
"break",
|
||||
|
||||
{
|
||||
"type": "wm",
|
||||
"key": " DE/WM",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "lm",
|
||||
"key": "├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wmtheme",
|
||||
"key": "├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": "├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "├",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wallpaper",
|
||||
"key": "└",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
|
||||
"break",
|
||||
{
|
||||
"type": "host",
|
||||
"key": " PC",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "├",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": "└",
|
||||
"keyColor": "green"
|
||||
},
|
||||
|
||||
"break",
|
||||
{
|
||||
"type": "sound",
|
||||
"key": " SOUND",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "player",
|
||||
"key": "├",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "media",
|
||||
"key": "└",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"separator": " ",
|
||||
"color": {
|
||||
"keys": "magenta"
|
||||
},
|
||||
"size": {
|
||||
"ndigits": 0,
|
||||
"maxPrefix": "MB"
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "title",
|
||||
"color": {
|
||||
"user": "green",
|
||||
"at": "red",
|
||||
"host": "blue"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "",
|
||||
"format": "{2} {8}"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": ""
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": ""
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": ""
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": ""
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"key": "",
|
||||
"format": "\u001b[31m███\u001b[32m███\u001b[33m███\u001b[34m███\u001b[35m███\u001b[36m███"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"keyWidth": 11,
|
||||
"bar": {
|
||||
"charElapsed": "=",
|
||||
"charTotal": "-",
|
||||
"width": 13
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"memory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 11,
|
||||
"symbol": "circle"
|
||||
}
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
--structure Host:Resolution:CPU:GPU:Memory:Disk:Battery
|
||||
--structure Host:Display:CPU:GPU:Memory:Disk:Battery
|
||||
--memory-format "{?2}{2}{?}"
|
||||
--disk-format "{?2}{2}{?}"
|
||||
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "builtin",
|
||||
"source": "arch"
|
||||
},
|
||||
"modules": [
|
||||
"host",
|
||||
"display",
|
||||
"cpu",
|
||||
"gpu",
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "{?2}{2}{?}"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"format": "{?2}{2}{?}"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
}
|
||||
]
|
||||
}
|
||||
+4
-5
@@ -1,10 +1,9 @@
|
||||
--structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors"
|
||||
--structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors"
|
||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--os-format "{3} {12}"
|
||||
--resolution-format "{}x{}"
|
||||
--display-key Resolution
|
||||
--display-compact-type original
|
||||
--de-format "{2} {3}"
|
||||
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
--terminal-font-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--terminalfont-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
||||
--gpu-key "GPU"
|
||||
--resolution-key "Resolution"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
{
|
||||
"type": "os",
|
||||
"format": "{3} {12}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
},
|
||||
"kernel",
|
||||
"uptime",
|
||||
"packages",
|
||||
"shell",
|
||||
{
|
||||
"type": "display",
|
||||
"compactType": "original",
|
||||
"key": "Resolution"
|
||||
},
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
{
|
||||
"type": "theme",
|
||||
"format": "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
},
|
||||
"icons",
|
||||
"terminal",
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
},
|
||||
"cpu",
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "GPU"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
||||
},
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Battery:Break:Packages:Shell:Resolution:Terminal:Break:CPU:GPU:Memory:Break:Colors
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Battery:Break:Packages:Shell:Display:Terminal:Break:CPU:GPU:Memory:Break:Colors
|
||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--battery-format "{/4}{-}{/}{4}%{?5} [{5}]{?}"
|
||||
--resolution-key "Resolution"
|
||||
--display-key "Display"
|
||||
--gpu-key "GPU"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
{
|
||||
"type": "host",
|
||||
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
},
|
||||
"kernel",
|
||||
"uptime",
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "{/4}{-}{/}{4}%{?5} [{5}]{?}"
|
||||
},
|
||||
"break",
|
||||
"packages",
|
||||
"shell",
|
||||
{
|
||||
"type": "display",
|
||||
"key": "Display"
|
||||
},
|
||||
"terminal",
|
||||
"break",
|
||||
"cpu",
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "GPU"
|
||||
},
|
||||
"memory",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"modules": [
|
||||
"os",
|
||||
"kernel",
|
||||
"shell",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"terminal",
|
||||
"terminalfont"
|
||||
]
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
--os-format System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}
|
||||
--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {}
|
||||
--kernel-format Sysname: {}; Release: {}; Version: {}
|
||||
--uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {}
|
||||
--processes-format Count: {}
|
||||
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}
|
||||
--shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}
|
||||
--resolution-format Width: {}; Height: {}; Refresh rate: {}
|
||||
--de-format Process name: {}; Pretty name: {}; Version: {}
|
||||
--wm-format Process name: {}; Pretty name: {}; Protocol: {}
|
||||
--wm-theme-format Name: {}
|
||||
--theme-format Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--icons-format Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--font-format Font1: {}; Font2: {}; Font3: {}; Font4: {}
|
||||
--cursor-format Theme: {}; Size: {}
|
||||
--terminal-format Process: {}; Path: {}; Exe: {}
|
||||
--terminal-font-format Pretty: {}; Name: {}; Size: {}; Styles: {}
|
||||
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
|
||||
--cpu-usage-format Percentage: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
|
||||
--memory-format Used: {}; Total: {}; Percentage: {}
|
||||
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
|
||||
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
|
||||
--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {}
|
||||
--player-format Pretty: {}; Name: {}; Bus: {}; Url: {}
|
||||
--media-format Pretty: {}; Name: {}; Artist: {}; Album: {}
|
||||
--datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}
|
||||
--vulkan-format driver: {}; Api Version: {}; Conformance Version: {}
|
||||
--opengl-format version: {}; renderer: {}; vendor: {}
|
||||
--opencl-format version: {}; device: {}; vendor: {}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"home": "https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c",
|
||||
"license": "Embed in source",
|
||||
"version": "2007-05-26 (Unicode 5.0)",
|
||||
"author": "Markus Kuhn",
|
||||
"modified": "CarterLi"
|
||||
}
|
||||
Vendored
+314
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* This is an implementation of wcwidth() and wcswidth() (defined in
|
||||
* IEEE Std 1002.1-2001) for Unicode.
|
||||
*
|
||||
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
|
||||
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
|
||||
*
|
||||
* In fixed-width output devices, Latin characters all occupy a single
|
||||
* "cell" position of equal width, whereas ideographic CJK characters
|
||||
* occupy two such cells. Interoperability between terminal-line
|
||||
* applications and (teletype-style) character terminals using the
|
||||
* UTF-8 encoding requires agreement on which character should advance
|
||||
* the cursor by how many cell positions. No established formal
|
||||
* standards exist at present on which Unicode character shall occupy
|
||||
* how many cell positions on character terminals. These routines are
|
||||
* a first attempt of defining such behavior based on simple rules
|
||||
* applied to data provided by the Unicode Consortium.
|
||||
*
|
||||
* For some graphical characters, the Unicode standard explicitly
|
||||
* defines a character-cell width via the definition of the East Asian
|
||||
* FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
|
||||
* In all these cases, there is no ambiguity about which width a
|
||||
* terminal shall use. For characters in the East Asian Ambiguous (A)
|
||||
* class, the width choice depends purely on a preference of backward
|
||||
* compatibility with either historic CJK or Western practice.
|
||||
* Choosing single-width for these characters is easy to justify as
|
||||
* the appropriate long-term solution, as the CJK practice of
|
||||
* displaying these characters as double-width comes from historic
|
||||
* implementation simplicity (8-bit encoded characters were displayed
|
||||
* single-width and 16-bit ones double-width, even for Greek,
|
||||
* Cyrillic, etc.) and not any typographic considerations.
|
||||
*
|
||||
* Much less clear is the choice of width for the Not East Asian
|
||||
* (Neutral) class. Existing practice does not dictate a width for any
|
||||
* of these characters. It would nevertheless make sense
|
||||
* typographically to allocate two character cells to characters such
|
||||
* as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
|
||||
* represented adequately with a single-width glyph. The following
|
||||
* routines at present merely assign a single-cell width to all
|
||||
* neutral characters, in the interest of simplicity. This is not
|
||||
* entirely satisfactory and should be reconsidered before
|
||||
* establishing a formal standard in this area. At the moment, the
|
||||
* decision which Not East Asian (Neutral) characters should be
|
||||
* represented by double-width glyphs cannot yet be answered by
|
||||
* applying a simple rule from the Unicode database content. Setting
|
||||
* up a proper standard for the behavior of UTF-8 character terminals
|
||||
* will require a careful analysis not only of each Unicode character,
|
||||
* but also of each presentation form, something the author of these
|
||||
* routines has avoided to do so far.
|
||||
*
|
||||
* http://www.unicode.org/unicode/reports/tr11/
|
||||
*
|
||||
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* for any purpose and without fee is hereby granted. The author
|
||||
* disclaims all warranties with regard to this software.
|
||||
*
|
||||
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
||||
*/
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
struct interval {
|
||||
int first;
|
||||
int last;
|
||||
};
|
||||
|
||||
/* auxiliary function for binary search in interval table */
|
||||
static int bisearch(wchar_t ucs, const struct interval *table, int max) {
|
||||
int min = 0;
|
||||
int mid;
|
||||
|
||||
if (ucs < table[0].first || ucs > table[max].last)
|
||||
return 0;
|
||||
while (max >= min) {
|
||||
mid = (min + max) / 2;
|
||||
if (ucs > table[mid].last)
|
||||
min = mid + 1;
|
||||
else if (ucs < table[mid].first)
|
||||
max = mid - 1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* The following two functions define the column width of an ISO 10646
|
||||
* character as follows:
|
||||
*
|
||||
* - The null character (U+0000) has a column width of 0.
|
||||
*
|
||||
* - Other C0/C1 control characters and DEL will lead to a return
|
||||
* value of -1.
|
||||
*
|
||||
* - Non-spacing and enclosing combining characters (general
|
||||
* category code Mn or Me in the Unicode database) have a
|
||||
* column width of 0.
|
||||
*
|
||||
* - SOFT HYPHEN (U+00AD) has a column width of 1.
|
||||
*
|
||||
* - Other format characters (general category code Cf in the Unicode
|
||||
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
|
||||
*
|
||||
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
|
||||
* have a column width of 0.
|
||||
*
|
||||
* - Spacing characters in the East Asian Wide (W) or East Asian
|
||||
* Full-width (F) category as defined in Unicode Technical
|
||||
* Report #11 have a column width of 2.
|
||||
*
|
||||
* - All remaining characters (including all printable
|
||||
* ISO 8859-1 and WGL4 characters, Unicode control characters,
|
||||
* etc.) have a column width of 1.
|
||||
*
|
||||
* This implementation assumes that wchar_t characters are encoded
|
||||
* in ISO 10646.
|
||||
*/
|
||||
|
||||
int mk_wcwidth(wchar_t ucs)
|
||||
{
|
||||
/* sorted list of non-overlapping intervals of non-spacing characters */
|
||||
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
|
||||
static const struct interval combining[] = {
|
||||
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
|
||||
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
|
||||
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
|
||||
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
|
||||
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
|
||||
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
|
||||
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
|
||||
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
|
||||
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
|
||||
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
|
||||
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
|
||||
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
|
||||
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
|
||||
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
|
||||
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
|
||||
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
|
||||
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
|
||||
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
|
||||
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
|
||||
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
|
||||
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
|
||||
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
|
||||
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
|
||||
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
|
||||
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
|
||||
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
|
||||
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
|
||||
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
|
||||
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
|
||||
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
|
||||
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
|
||||
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
|
||||
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
|
||||
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
|
||||
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
|
||||
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
|
||||
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
|
||||
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
|
||||
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
|
||||
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
|
||||
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
|
||||
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
|
||||
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
|
||||
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
|
||||
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
|
||||
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
|
||||
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
|
||||
{ 0xE0100, 0xE01EF }
|
||||
};
|
||||
|
||||
/* test for 8-bit control characters */
|
||||
if (ucs == 0)
|
||||
return 0;
|
||||
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
|
||||
return -1;
|
||||
|
||||
/* binary search in table of non-spacing characters */
|
||||
if (bisearch(ucs, combining,
|
||||
sizeof(combining) / sizeof(struct interval) - 1))
|
||||
return 0;
|
||||
|
||||
/* if we arrive here, ucs is not a combining or C0/C1 control character */
|
||||
|
||||
return 1 +
|
||||
(ucs >= 0x1100 &&
|
||||
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
|
||||
ucs == 0x2329 || ucs == 0x232a ||
|
||||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
|
||||
ucs != 0x303f) || /* CJK ... Yi */
|
||||
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
|
||||
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
|
||||
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
|
||||
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
|
||||
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
|
||||
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
|
||||
|
||||
#ifndef _WIN32 // sizeof(wchar_t) == 2
|
||||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
|
||||
(ucs >= 0x30000 && ucs <= 0x3fffd) ||
|
||||
#endif
|
||||
0
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
||||
{
|
||||
int w, width = 0;
|
||||
|
||||
for (;*pwcs && n-- > 0; pwcs++)
|
||||
if ((w = mk_wcwidth(*pwcs)) < 0)
|
||||
return -1;
|
||||
else
|
||||
width += w;
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following functions are the same as mk_wcwidth() and
|
||||
* mk_wcswidth(), except that spacing characters in the East Asian
|
||||
* Ambiguous (A) category as defined in Unicode Technical Report #11
|
||||
* have a column width of 2. This variant might be useful for users of
|
||||
* CJK legacy encodings who want to migrate to UCS without changing
|
||||
* the traditional terminal character-width behaviour. It is not
|
||||
* otherwise recommended for general use.
|
||||
*/
|
||||
int mk_wcwidth_cjk(wchar_t ucs)
|
||||
{
|
||||
/* sorted list of non-overlapping intervals of East Asian Ambiguous
|
||||
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
|
||||
static const struct interval ambiguous[] = {
|
||||
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
|
||||
{ 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
|
||||
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
|
||||
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
|
||||
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
|
||||
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
|
||||
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
|
||||
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
|
||||
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
|
||||
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
|
||||
{ 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
|
||||
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
|
||||
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
|
||||
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
|
||||
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
|
||||
{ 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
|
||||
{ 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
|
||||
{ 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
|
||||
{ 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
|
||||
{ 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
|
||||
{ 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
|
||||
{ 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
|
||||
{ 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
|
||||
{ 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
|
||||
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
|
||||
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
|
||||
{ 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
|
||||
{ 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
|
||||
{ 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
|
||||
{ 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
|
||||
{ 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
|
||||
{ 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
|
||||
{ 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
|
||||
{ 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
|
||||
{ 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
|
||||
{ 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
|
||||
{ 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
|
||||
{ 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
|
||||
{ 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
|
||||
{ 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
|
||||
{ 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
|
||||
{ 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
|
||||
{ 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
|
||||
{ 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
|
||||
{ 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
|
||||
{ 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
|
||||
{ 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
|
||||
{ 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
|
||||
{ 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
|
||||
{ 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
|
||||
{ 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
|
||||
{ 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
|
||||
};
|
||||
|
||||
/* binary search in table of non-spacing characters */
|
||||
if (bisearch(ucs, ambiguous,
|
||||
sizeof(ambiguous) / sizeof(struct interval) - 1))
|
||||
return 2;
|
||||
|
||||
return mk_wcwidth(ucs);
|
||||
}
|
||||
|
||||
|
||||
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
||||
{
|
||||
int w, width = 0;
|
||||
|
||||
for (;*pwcs && n-- > 0; pwcs++)
|
||||
if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
|
||||
return -1;
|
||||
else
|
||||
width += w;
|
||||
|
||||
return width;
|
||||
}
|
||||
Vendored
+10359
File diff suppressed because it is too large
Load Diff
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h",
|
||||
"license": "Embed in source",
|
||||
"version": "545.23.06",
|
||||
"author": "NVIDIA Corporation"
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/ibireme/yyjson",
|
||||
"license": "MIT ( embed in source )",
|
||||
"version": "0.8.0",
|
||||
"author": "ibireme"
|
||||
}
|
||||
Vendored
+9447
File diff suppressed because it is too large
Load Diff
Vendored
+7910
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
||||
#include "common/bar.h"
|
||||
#include "common/color.h"
|
||||
#include "util/textModifier.h"
|
||||
|
||||
void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, uint8_t red)
|
||||
{
|
||||
assert(green <= 100 && yellow <= 100 && red <= 100);
|
||||
|
||||
const FFOptionsDisplay* options = &instance.config.display;
|
||||
|
||||
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksGreen = (uint32_t) (green / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksRed = (uint32_t) (red / 100.0 * options->barWidth + 0.5);
|
||||
assert(blocksPercent <= options->barWidth);
|
||||
|
||||
if(options->barBorder)
|
||||
{
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
|
||||
else
|
||||
ffStrbufAppendS(buffer, "[ ");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < blocksPercent; ++i)
|
||||
{
|
||||
if(!options->pipe)
|
||||
{
|
||||
if (i == blocksGreen)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||
else if (i == blocksYellow)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
|
||||
else if (i == blocksRed)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||
}
|
||||
ffStrbufAppend(buffer, &options->barCharElapsed);
|
||||
}
|
||||
|
||||
if (blocksPercent < options->barWidth)
|
||||
{
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
|
||||
for (uint32_t i = blocksPercent; i < options->barWidth; ++i)
|
||||
ffStrbufAppend(buffer, &options->barCharTotal);
|
||||
}
|
||||
|
||||
if(options->barBorder)
|
||||
{
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
|
||||
else
|
||||
ffStrbufAppendS(buffer, " ]");
|
||||
}
|
||||
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
// if (green < yellow)
|
||||
// [0, green]: print green
|
||||
// (green, yellow]: print yellow
|
||||
// (yellow, 100]: print red
|
||||
//
|
||||
// if (green > yellow)
|
||||
// [green, 100]: print green
|
||||
// [yellow, green): print yellow
|
||||
// [0, yellow): PRINT RED
|
||||
void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, bool parentheses)
|
||||
{
|
||||
assert(green <= 100 && yellow <= 100);
|
||||
|
||||
const FFOptionsDisplay* options = &instance.config.display;
|
||||
|
||||
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
|
||||
|
||||
if (parentheses)
|
||||
ffStrbufAppendC(buffer, '(');
|
||||
|
||||
if (colored && !options->pipe)
|
||||
{
|
||||
if(percent != percent)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
|
||||
else if(green < yellow)
|
||||
{
|
||||
if (percent <= green)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||
else if (percent <= yellow)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
|
||||
else
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (percent >= green)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||
else if (percent >= yellow)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
|
||||
else
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||
}
|
||||
}
|
||||
ffStrbufAppendF(buffer, "%.*f%%", options->percentNdigits, percent);
|
||||
|
||||
if (colored && !options->pipe)
|
||||
{
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
if (parentheses)
|
||||
ffStrbufAppendC(buffer, ')');
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
enum
|
||||
{
|
||||
FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0,
|
||||
FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1,
|
||||
FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT = 1 << 2,
|
||||
FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3,
|
||||
};
|
||||
|
||||
void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, uint8_t red);
|
||||
void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, bool parentheses);
|
||||
@@ -1,327 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/caching.h"
|
||||
#include "common/io.h"
|
||||
#include "common/printing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FF_CACHE_VERSION_NAME "cacheversion"
|
||||
#define FF_CACHE_VERSION_EXTENSION "ffv"
|
||||
|
||||
#define FF_CACHE_VALUE_EXTENSION "ffcv"
|
||||
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
|
||||
|
||||
#define FF_CACHE_EXTENSION_V1 "ffc1"
|
||||
|
||||
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufAppend(buffer, &instance->state.cacheDir);
|
||||
ffStrbufAppendS(buffer, moduleName);
|
||||
|
||||
if(extension != NULL)
|
||||
{
|
||||
ffStrbufAppendC(buffer, '.');
|
||||
ffStrbufAppendS(buffer, extension);
|
||||
}
|
||||
}
|
||||
|
||||
static void readCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 64);
|
||||
getCacheFilePath(instance, moduleName, extension, &path);
|
||||
ffAppendFileBuffer(path.chars, buffer);
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
static void writeCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 64);
|
||||
getCacheFilePath(instance, moduleName, extension, &path);
|
||||
ffWriteFileBuffer(path.chars, content);
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
void ffCacheValidate(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInit(&content);
|
||||
readCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &content);
|
||||
|
||||
const char exactVersion[] = FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK;
|
||||
|
||||
bool isSameVersion = ffStrbufCompS(&content, exactVersion) == 0;
|
||||
ffStrbufDestroy(&content);
|
||||
if(isSameVersion)
|
||||
return;
|
||||
|
||||
instance->config.recache = true;
|
||||
|
||||
FFstrbuf version;
|
||||
ffStrbufInitA(&version, sizeof(exactVersion));
|
||||
ffStrbufAppendS(&version, exactVersion);
|
||||
writeCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &version);
|
||||
ffStrbufDestroy(&version);
|
||||
}
|
||||
|
||||
void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache)
|
||||
{
|
||||
FFstrbuf cacheFileValue;
|
||||
ffStrbufInitA(&cacheFileValue, 64);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &cacheFileValue);
|
||||
cache->value = fopen(cacheFileValue.chars, "w");
|
||||
ffStrbufDestroy(&cacheFileValue);
|
||||
|
||||
FFstrbuf cacheFileSplit;
|
||||
ffStrbufInitA(&cacheFileSplit, 64);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &cacheFileSplit);
|
||||
cache->split = fopen(cacheFileSplit.chars, "w");
|
||||
ffStrbufDestroy(&cacheFileSplit);
|
||||
}
|
||||
|
||||
void ffCacheClose(FFcache* cache)
|
||||
{
|
||||
if(cache->value != NULL)
|
||||
fclose(cache->value);
|
||||
|
||||
if(cache->split != NULL)
|
||||
fclose(cache->split);
|
||||
}
|
||||
|
||||
static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInitA(&content, 512);
|
||||
readCacheFile(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &content);
|
||||
|
||||
ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length
|
||||
|
||||
if(content.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&content);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t moduleCounter = 1;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < content.length)
|
||||
{
|
||||
uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0');
|
||||
uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter;
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key);
|
||||
puts(content.chars + startIndex);
|
||||
startIndex = nullByteIndex + 1;
|
||||
++moduleCounter;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
return moduleCounter > 1;
|
||||
}
|
||||
|
||||
static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInitA(&content, 512);
|
||||
readCacheFile(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &content);
|
||||
|
||||
ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length
|
||||
|
||||
if(content.length == 0)
|
||||
return false;
|
||||
|
||||
uint8_t moduleCounter = 1;
|
||||
|
||||
FFformatarg* arguments = calloc(numArgs, sizeof(FFformatarg));
|
||||
uint32_t argumentCounter = 0;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < content.length)
|
||||
{
|
||||
arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING;
|
||||
arguments[argumentCounter].value = &content.chars[startIndex];
|
||||
++argumentCounter;
|
||||
|
||||
uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0');
|
||||
|
||||
if(argumentCounter == numArgs)
|
||||
{
|
||||
uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter;
|
||||
ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments);
|
||||
++moduleCounter;
|
||||
argumentCounter = 0;
|
||||
}
|
||||
|
||||
startIndex = nullByteIndex + 1;
|
||||
}
|
||||
|
||||
free(arguments);
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
return moduleCounter > 1;
|
||||
}
|
||||
|
||||
bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs)
|
||||
{
|
||||
if(instance->config.recache)
|
||||
return false;
|
||||
|
||||
if(moduleArgs->outputFormat.length == 0)
|
||||
return printCachedValue(instance, moduleName, moduleArgs);
|
||||
else
|
||||
return printCachedFormat(instance, moduleName, moduleArgs, numArgs);
|
||||
}
|
||||
|
||||
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(moduleArgs->outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key);
|
||||
ffStrbufPutTo(value, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments);
|
||||
}
|
||||
|
||||
if(cache->value != NULL)
|
||||
{
|
||||
ffStrbufWriteTo(value, cache->value);
|
||||
fputc('\0', cache->value);
|
||||
}
|
||||
|
||||
if(cache->split == NULL)
|
||||
return;
|
||||
|
||||
for(uint32_t i = 0; i < numArgs; i++)
|
||||
{
|
||||
FFstrbuf buffer;
|
||||
ffStrbufInitA(&buffer, 64);
|
||||
ffFormatAppendFormatArg(&buffer, &arguments[i]);
|
||||
ffStrbufWriteTo(&buffer, cache->split);
|
||||
ffStrbufDestroy(&buffer);
|
||||
fputc('\0', cache->split);
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
FFcache cache;
|
||||
ffCacheOpenWrite(instance, moduleName, &cache);
|
||||
ffPrintAndAppendToCache(instance, moduleName, 0, moduleArgs, &cache, value, numArgs, arguments);
|
||||
ffCacheClose(&cache);
|
||||
}
|
||||
|
||||
typedef struct FFCacheRead
|
||||
{
|
||||
FFstrbuf data;
|
||||
uint32_t position;
|
||||
} FFCacheRead;
|
||||
|
||||
static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf)
|
||||
{
|
||||
if(cacheRead->position >= cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position);
|
||||
cacheRead->position += strbuf->length + 1; // skip the null byte too
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
if(cacheRead->position + dataSize > cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize);
|
||||
cacheRead->position += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf)
|
||||
{
|
||||
FF_UNUSED(cache);
|
||||
ffStrbufClear(strbuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
FF_UNUSED(cacheRead, dataSize, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(instance->config.recache)
|
||||
return false;
|
||||
|
||||
FFCacheRead cache;
|
||||
bool result;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
cache.position = 0;
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
result = ffAppendFileBuffer(path.chars, &cache.data);
|
||||
|
||||
if(result)
|
||||
result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData);
|
||||
|
||||
if(result)
|
||||
result = cache.position == cache.data.length;
|
||||
|
||||
if(!result)
|
||||
callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct FFCacheWrite
|
||||
{
|
||||
FFstrbuf data;
|
||||
} FFCacheWrite;
|
||||
|
||||
static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, strbuf->length);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too
|
||||
cacheWrite->data.length += strbuf->length + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize);
|
||||
cacheWrite->data.length += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(!instance->config.cacheSave)
|
||||
return;
|
||||
|
||||
FFCacheWrite cache;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData);
|
||||
ffWriteFileBuffer(path.chars, &cache.data);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_caching
|
||||
#define FF_INCLUDED_common_caching
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
|
||||
typedef struct FFcache
|
||||
{
|
||||
FILE* value;
|
||||
FILE* split;
|
||||
} FFcache;
|
||||
|
||||
void ffCacheValidate(FFinstance* instance);
|
||||
|
||||
void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache);
|
||||
void ffCacheClose(FFcache* cache);
|
||||
|
||||
bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs);
|
||||
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
typedef void FFCache;
|
||||
|
||||
typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf);
|
||||
typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data);
|
||||
typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod);
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#define FF_COLOR_MODE_RESET "0;"
|
||||
#define FF_COLOR_MODE_BOLD "1;"
|
||||
#define FF_COLOR_MODE_DIM "2;"
|
||||
#define FF_COLOR_MODE_ITALIC "3;"
|
||||
#define FF_COLOR_MODE_UNDERLINE "4;"
|
||||
#define FF_COLOR_MODE_BLINK "5;"
|
||||
#define FF_COLOR_MODE_INVERSE "7;"
|
||||
#define FF_COLOR_MODE_HIDDEN "8;"
|
||||
#define FF_COLOR_MODE_STRIKETHROUGH "9;"
|
||||
|
||||
#define FF_COLOR_FG_BLACK "30"
|
||||
#define FF_COLOR_FG_RED "31"
|
||||
#define FF_COLOR_FG_GREEN "32"
|
||||
#define FF_COLOR_FG_YELLOW "33"
|
||||
#define FF_COLOR_FG_BLUE "34"
|
||||
#define FF_COLOR_FG_MAGENTA "35"
|
||||
#define FF_COLOR_FG_CYAN "36"
|
||||
#define FF_COLOR_FG_WHITE "37"
|
||||
#define FF_COLOR_FG_DEFAULT "39"
|
||||
|
||||
#define FF_COLOR_FG_LIGHT_BLACK "90"
|
||||
#define FF_COLOR_FG_LIGHT_RED "91"
|
||||
#define FF_COLOR_FG_LIGHT_GREEN "92"
|
||||
#define FF_COLOR_FG_LIGHT_YELLOW "93"
|
||||
#define FF_COLOR_FG_LIGHT_BLUE "94"
|
||||
#define FF_COLOR_FG_LIGHT_MAGENTA "95"
|
||||
#define FF_COLOR_FG_LIGHT_CYAN "96"
|
||||
#define FF_COLOR_FG_LIGHT_WHITE "97"
|
||||
|
||||
#define FF_COLOR_BG_BLACK "40"
|
||||
#define FF_COLOR_BG_RED "41"
|
||||
#define FF_COLOR_BG_GREEN "42"
|
||||
#define FF_COLOR_BG_YELLOW "43"
|
||||
#define FF_COLOR_BG_BLUE "44"
|
||||
#define FF_COLOR_BG_MAGENTA "45"
|
||||
#define FF_COLOR_BG_CYAN "46"
|
||||
#define FF_COLOR_BG_WHITE "47"
|
||||
#define FF_COLOR_BG_DEFAULT "49"
|
||||
|
||||
#define FF_COLOR_BG_LIGHT_BLACK "100"
|
||||
#define FF_COLOR_BG_LIGHT_RED "101"
|
||||
#define FF_COLOR_BG_LIGHT_GREEN "102"
|
||||
#define FF_COLOR_BG_LIGHT_YELLOW "103"
|
||||
#define FF_COLOR_BG_LIGHT_BLUE "104"
|
||||
#define FF_COLOR_BG_LIGHT_MAGENTA "105"
|
||||
#define FF_COLOR_BG_LIGHT_CYAN "106"
|
||||
#define FF_COLOR_BG_LIGHT_WHITE "107"
|
||||
|
||||
#define FF_COLOR_FG_256 "38;5;"
|
||||
#define FF_COLOR_BG_256 "48;5;"
|
||||
|
||||
#define FF_COLOR_FG_RGB "38;2;"
|
||||
#define FF_COLOR_BG_RGB "48;2;"
|
||||
@@ -0,0 +1,184 @@
|
||||
#include "commandoption.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/time.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "fastfetch_datatext.h"
|
||||
#include "modules/modules.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value)
|
||||
{
|
||||
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
|
||||
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
if (baseInfo->parseCommandOptions(baseInfo, key, value)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffPrepareCommandOption(FFdata* data)
|
||||
{
|
||||
FFOptionsModules* const options = &instance.config.modules;
|
||||
//If we don't have a custom structure, use the default one
|
||||
if(data->structure.length == 0)
|
||||
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_CPUUSAGE_MODULE_NAME))
|
||||
ffPrepareCPUUsage();
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
|
||||
ffPrepareDiskIO(&options->diskIo);
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
|
||||
ffPrepareNetIO(&options->netIo);
|
||||
|
||||
if(instance.config.general.multithreading)
|
||||
{
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
|
||||
ffPreparePublicIp(&options->publicIP);
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
|
||||
ffPrepareWeather(&options->weather);
|
||||
}
|
||||
}
|
||||
|
||||
static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
|
||||
if (!modules)
|
||||
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
|
||||
|
||||
yyjson_mut_val* module = yyjson_mut_obj(doc);
|
||||
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
|
||||
ffStrbufLowerCase(&type);
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
|
||||
|
||||
if (baseInfo->generateJsonConfig)
|
||||
baseInfo->generateJsonConfig(baseInfo, doc, module);
|
||||
|
||||
if (yyjson_mut_obj_size(module) > 1)
|
||||
yyjson_mut_arr_add_val(modules, module);
|
||||
else
|
||||
yyjson_mut_arr_add_strbuf(doc, modules, &type);
|
||||
}
|
||||
|
||||
static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||
if (baseInfo->generateJsonResult)
|
||||
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||
else
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||
}
|
||||
|
||||
static void parseStructureCommand(
|
||||
const char* line,
|
||||
FFlist* customValues,
|
||||
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
|
||||
yyjson_mut_doc* jsonDoc
|
||||
)
|
||||
{
|
||||
// handle `--set` and `--set-keyless`
|
||||
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
|
||||
{
|
||||
if (ffStrbufEqualS(&customValue->key, line))
|
||||
{
|
||||
__attribute__((__cleanup__(ffDestroyCustomOptions))) FFCustomOptions options;
|
||||
ffInitCustomOptions(&options);
|
||||
if (customValue->printKey)
|
||||
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
|
||||
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
fn((FFModuleBaseInfo*) &options, jsonDoc);
|
||||
else
|
||||
ffPrintCustom(&options);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(isalpha(line[0]))
|
||||
{
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
if (ffStrEqualsIgnCase(line, baseInfo->name))
|
||||
{
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
fn(baseInfo, jsonDoc);
|
||||
else
|
||||
baseInfo->printModule(baseInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
||||
}
|
||||
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
//Parse the structure and call the modules
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
uint64_t ms = 0;
|
||||
if(instance.config.display.stat)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
|
||||
|
||||
if(instance.config.display.stat)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout);
|
||||
#endif
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
//If we don't have a custom structure, use the default one
|
||||
if(data->structure.length == 0)
|
||||
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||
|
||||
//Parse the structure and call the modules
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCustomValue
|
||||
{
|
||||
bool printKey;
|
||||
FFstrbuf key;
|
||||
FFstrbuf value;
|
||||
} FFCustomValue;
|
||||
|
||||
// Things only needed by fastfetch
|
||||
typedef struct FFdata
|
||||
{
|
||||
FFstrbuf structure;
|
||||
FFlist customValues; // List of FFCustomValue
|
||||
bool configLoaded;
|
||||
} FFdata;
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value);
|
||||
void ffPrepareCommandOption(FFdata* data);
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "dbus.h"
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
static bool loadLibSymbols(FFDBusLibrary* lib)
|
||||
{
|
||||
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init_append, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_append_basic, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_get_arg_type, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_get_basic, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_recurse, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_has_next, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_next, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_unref, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_send_with_reply_and_block, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_flush, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_pending_call_block, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_pending_call_steal_reply, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_pending_call_unref, false)
|
||||
dbus = NULL; // don't auto dlclose
|
||||
return true;
|
||||
}
|
||||
|
||||
static const FFDBusLibrary* loadLib(void)
|
||||
{
|
||||
static FFDBusLibrary lib;
|
||||
static bool loaded = false;
|
||||
static bool loadSuccess = false;
|
||||
|
||||
if(!loaded)
|
||||
{
|
||||
loaded = true;
|
||||
loadSuccess = loadLibSymbols(&lib);
|
||||
}
|
||||
|
||||
return loadSuccess ? &lib : NULL;
|
||||
}
|
||||
|
||||
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data)
|
||||
{
|
||||
data->lib = loadLib();
|
||||
if(data->lib == NULL)
|
||||
return "Failed to load DBus library";
|
||||
|
||||
data->connection = data->lib->ffdbus_bus_get(busType, NULL);
|
||||
if(data->connection == NULL)
|
||||
return "Failed to connect to DBus";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ffDBusGetValue(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
|
||||
{
|
||||
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
||||
|
||||
if(argType == DBUS_TYPE_STRING)
|
||||
{
|
||||
const char* value = NULL;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||
|
||||
if(!ffStrSet(value))
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(result, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY)
|
||||
return false;
|
||||
|
||||
DBusMessageIter subIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
||||
|
||||
if(argType == DBUS_TYPE_VARIANT)
|
||||
return ffDBusGetValue(dbus, &subIter, result);
|
||||
|
||||
//At this point we have an array
|
||||
|
||||
bool foundAValue = false;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(ffDBusGetValue(dbus, &subIter, result))
|
||||
{
|
||||
foundAValue = true;
|
||||
ffStrbufAppendS(result, ", ");
|
||||
}
|
||||
|
||||
FF_DBUS_ITER_CONTINUE(dbus, &subIter);
|
||||
}
|
||||
|
||||
if(foundAValue)
|
||||
ffStrbufSubstrBefore(result, result->length - 2);
|
||||
|
||||
return foundAValue;
|
||||
}
|
||||
|
||||
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result)
|
||||
{
|
||||
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
||||
|
||||
if(argType == DBUS_TYPE_BOOLEAN)
|
||||
{
|
||||
dbus_bool_t value = 0;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||
*result = value != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType != DBUS_TYPE_VARIANT)
|
||||
return false;
|
||||
|
||||
DBusMessageIter subIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
||||
return ffDBusGetBool(dbus, &subIter, result);
|
||||
}
|
||||
|
||||
bool ffDBusGetByte(FFDBusData* dbus, DBusMessageIter* iter, uint8_t* result)
|
||||
{
|
||||
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
||||
|
||||
if(argType == DBUS_TYPE_BYTE)
|
||||
{
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType != DBUS_TYPE_VARIANT)
|
||||
return false;
|
||||
|
||||
DBusMessageIter subIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
||||
return ffDBusGetByte(dbus, &subIter, result);
|
||||
}
|
||||
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method)
|
||||
{
|
||||
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
|
||||
if(message == NULL)
|
||||
return NULL;
|
||||
|
||||
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
|
||||
|
||||
dbus->lib->ffdbus_message_unref(message);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property)
|
||||
{
|
||||
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
|
||||
if(message == NULL)
|
||||
return NULL;
|
||||
|
||||
DBusMessageIter requestIterator;
|
||||
dbus->lib->ffdbus_message_iter_init_append(message, &requestIterator);
|
||||
|
||||
if(!dbus->lib->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &interface))
|
||||
{
|
||||
dbus->lib->ffdbus_message_unref(message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!dbus->lib->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &property))
|
||||
{
|
||||
dbus->lib->ffdbus_message_unref(message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
|
||||
|
||||
dbus->lib->ffdbus_message_unref(message);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result)
|
||||
{
|
||||
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
|
||||
if(reply == NULL)
|
||||
return;
|
||||
|
||||
DBusMessageIter rootIterator;
|
||||
if(!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator))
|
||||
{
|
||||
dbus->lib->ffdbus_message_unref(reply);
|
||||
return;
|
||||
}
|
||||
|
||||
ffDBusGetValue(dbus, &rootIterator, result);
|
||||
|
||||
dbus->lib->ffdbus_message_unref(reply);
|
||||
}
|
||||
|
||||
#endif //FF_HAVE_DBUS
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "common/library.h"
|
||||
|
||||
#define FF_DBUS_TIMEOUT_MILLISECONDS 35
|
||||
|
||||
#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
|
||||
{ \
|
||||
if(!(dbus)->lib->ffdbus_message_iter_has_next(iterator)) \
|
||||
break; \
|
||||
(dbus)->lib->ffdbus_message_iter_next(iterator); \
|
||||
continue; \
|
||||
}
|
||||
|
||||
typedef struct FFDBusLibrary
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(dbus_bus_get)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_new_method_call)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_init)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_init_append)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_append_basic)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_get_arg_type)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_get_basic)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_recurse)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_has_next)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_iter_next)
|
||||
FF_LIBRARY_SYMBOL(dbus_message_unref)
|
||||
FF_LIBRARY_SYMBOL(dbus_connection_send_with_reply_and_block)
|
||||
FF_LIBRARY_SYMBOL(dbus_connection_flush)
|
||||
FF_LIBRARY_SYMBOL(dbus_pending_call_block)
|
||||
FF_LIBRARY_SYMBOL(dbus_pending_call_steal_reply)
|
||||
FF_LIBRARY_SYMBOL(dbus_pending_call_unref)
|
||||
} FFDBusLibrary;
|
||||
|
||||
typedef struct FFDBusData
|
||||
{
|
||||
const FFDBusLibrary* lib;
|
||||
DBusConnection* connection;
|
||||
} FFDBusData;
|
||||
|
||||
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); //Returns an error message or NULL on success
|
||||
bool ffDBusGetValue(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
|
||||
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
|
||||
bool ffDBusGetByte(FFDBusData* dbus, DBusMessageIter* iter, uint8_t* result);
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method);
|
||||
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property);
|
||||
void ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
|
||||
|
||||
#endif // FF_HAVE_DBUS
|
||||
+8
-7
@@ -3,12 +3,13 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static void fontInit(FFfont* font)
|
||||
void ffFontInit(FFfont* font)
|
||||
{
|
||||
// Ensure no memory allocates
|
||||
ffStrbufInit(&font->pretty);
|
||||
ffStrbufInit(&font->name);
|
||||
ffStrbufInitA(&font->size, 4);
|
||||
ffListInitA(&font->styles, sizeof(FFstrbuf), 4);
|
||||
ffStrbufInit(&font->size);
|
||||
ffListInit(&font->styles, sizeof(FFstrbuf));
|
||||
}
|
||||
|
||||
static void fontInitPretty(FFfont* font)
|
||||
@@ -44,7 +45,7 @@ static void fontInitPretty(FFfont* font)
|
||||
|
||||
void ffFontInitQt(FFfont* font, const char* data)
|
||||
{
|
||||
fontInit(font);
|
||||
ffFontInit(font);
|
||||
|
||||
//See https://doc.qt.io/qt-5/qfont.html#toString
|
||||
|
||||
@@ -181,7 +182,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
|
||||
|
||||
void ffFontInitPango(FFfont* font, const char* data)
|
||||
{
|
||||
fontInit(font);
|
||||
ffFontInit(font);
|
||||
|
||||
while(*data != '\0' && *data != '`' && *data != '\\')
|
||||
fontPangoParseWord(&data, font, NULL);
|
||||
@@ -191,7 +192,7 @@ void ffFontInitPango(FFfont* font, const char* data)
|
||||
|
||||
void ffFontInitValues(FFfont* font, const char* name, const char* size)
|
||||
{
|
||||
fontInit(font);
|
||||
ffFontInit(font);
|
||||
|
||||
ffStrbufAppendS(&font->name, name);
|
||||
ffStrbufAppendS(&font->size, size);
|
||||
@@ -213,7 +214,7 @@ void ffFontInitWithSpace(FFfont* font, const char* rawName)
|
||||
return;
|
||||
}
|
||||
|
||||
fontInit(font);
|
||||
ffFontInit(font);
|
||||
|
||||
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
|
||||
ffStrbufAppendS(&font->size, pspace + 1);
|
||||
|
||||
+1
-5
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_font
|
||||
#define FF_INCLUDED_common_font
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "util/FFlist.h"
|
||||
|
||||
@@ -14,11 +11,10 @@ typedef struct FFfont
|
||||
FFlist styles;
|
||||
} FFfont;
|
||||
|
||||
void ffFontInit(FFfont* font);
|
||||
void ffFontInitQt(FFfont* font, const char* data);
|
||||
void ffFontInitPango(FFfont* font, const char* data);
|
||||
void ffFontInitCopy(FFfont* font, const char* name);
|
||||
void ffFontInitValues(FFfont* font, const char* name, const char* size);
|
||||
void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
||||
void ffFontDestroy(FFfont* font);
|
||||
|
||||
#endif
|
||||
|
||||
+27
-27
@@ -1,23 +1,33 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
#include "common/parsing.h"
|
||||
#include "util/textModifier.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
{
|
||||
if(formatarg->type == FF_FORMAT_ARG_TYPE_INT)
|
||||
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
|
||||
ffStrbufAppendF(buffer, "%u", *(uint32_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT64)
|
||||
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
|
||||
ffStrbufAppendF(buffer, "%hu", *(uint16_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
|
||||
ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING)
|
||||
ffStrbufAppendS(buffer, (const char*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF)
|
||||
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_FLOAT)
|
||||
ffStrbufAppendF(buffer, "%f", *(float*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE)
|
||||
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL)
|
||||
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST)
|
||||
{
|
||||
const FFlist* list = formatarg->value;
|
||||
@@ -34,6 +44,14 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parses a string to a uint32_t
|
||||
*
|
||||
* If the string can't be parsed, or is < 1, uint32_t max is returned.
|
||||
*
|
||||
* @param placeholderValue the string to parse
|
||||
* @return uint32_t the parsed value
|
||||
*/
|
||||
static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue)
|
||||
{
|
||||
uint32_t result = UINT32_MAX;
|
||||
@@ -41,7 +59,7 @@ static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue)
|
||||
if(placeholderValue->chars[0] != '-')
|
||||
sscanf(placeholderValue->chars, "%u", &result);
|
||||
|
||||
return result;
|
||||
return result == 0 ? UINT32_MAX : result;
|
||||
}
|
||||
|
||||
static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength)
|
||||
@@ -72,7 +90,8 @@ static inline bool formatArgSet(const FFformatarg* arg)
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0)
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && arg->value != NULL)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,18 +136,14 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
FFstrbuf placeholderValue;
|
||||
ffStrbufInit(&placeholderValue);
|
||||
FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate();
|
||||
|
||||
while(i < formatstr->length && formatstr->chars[i] != '}')
|
||||
ffStrbufAppendC(&placeholderValue, formatstr->chars[i++]);
|
||||
|
||||
// test if for stop, if so break the loop
|
||||
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '-')
|
||||
{
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
break;
|
||||
}
|
||||
|
||||
// test for end of an if, if so do nothing
|
||||
if(placeholderValue.length == 1 && placeholderValue.chars[0] == '?')
|
||||
@@ -138,7 +153,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
else
|
||||
--numOpenIfs;
|
||||
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -150,7 +164,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
else
|
||||
--numOpenNotIfs;
|
||||
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -165,7 +178,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
--numOpenColors;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -180,7 +192,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
if(index > numArgs)
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length);
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -188,13 +199,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
if(formatArgSet(&arguments[index - 1]))
|
||||
{
|
||||
++numOpenIfs;
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
// fastforward to the end of the if without printing the in between
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increament it again directly after continue
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increment it again directly after continue
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -209,7 +218,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
if(index > numArgs)
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length);
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -217,13 +225,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
if(!formatArgSet(&arguments[index - 1]))
|
||||
{
|
||||
++numOpenNotIfs;
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
// fastforward to the end of the if without printing the in between
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increament it again directly after continue
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increment it again directly after continue
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -235,7 +241,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
ffStrbufAppendS(buffer, "\033[");
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
ffStrbufAppendC(buffer, 'm');
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -245,16 +250,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
if(index > numArgs)
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
|
||||
ffStrbufDestroy(&placeholderValue);
|
||||
}
|
||||
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
+4
-6
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_format
|
||||
#define FF_INCLUDED_common_format
|
||||
|
||||
typedef enum FFformatargtype
|
||||
{
|
||||
FF_FORMAT_ARG_TYPE_NULL = 0,
|
||||
FF_FORMAT_ARG_TYPE_UINT,
|
||||
FF_FORMAT_ARG_TYPE_UINT64,
|
||||
FF_FORMAT_ARG_TYPE_UINT16,
|
||||
FF_FORMAT_ARG_TYPE_UINT8,
|
||||
FF_FORMAT_ARG_TYPE_INT,
|
||||
FF_FORMAT_ARG_TYPE_STRING,
|
||||
FF_FORMAT_ARG_TYPE_STRBUF,
|
||||
FF_FORMAT_ARG_TYPE_FLOAT,
|
||||
FF_FORMAT_ARG_TYPE_DOUBLE,
|
||||
FF_FORMAT_ARG_TYPE_LIST
|
||||
FF_FORMAT_ARG_TYPE_LIST,
|
||||
FF_FORMAT_ARG_TYPE_BOOL
|
||||
} FFformatargtype;
|
||||
|
||||
typedef struct FFformatarg
|
||||
@@ -24,5 +24,3 @@ typedef struct FFformatarg
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
|
||||
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
#endif
|
||||
|
||||
+107
-444
@@ -1,386 +1,116 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/caching.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/qt.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "common/thread.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/textModifier.h"
|
||||
#include "logo/logo.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <locale.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "util/windows/unicode.h"
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
static bool strbufEqualsAdapter(const void* first, const void* second)
|
||||
{
|
||||
return ffStrbufComp(second, first) == 0;
|
||||
}
|
||||
|
||||
static void initConfigDirs(FFstate* state)
|
||||
{
|
||||
ffListInit(&state->configDirs, sizeof(FFstrbuf));
|
||||
|
||||
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
if(ffStrSet(xdgConfigHome))
|
||||
{
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, xdgConfigHome);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
}
|
||||
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
|
||||
--state->configDirs.length; \
|
||||
}
|
||||
|
||||
FFstrbuf* userConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userConfigHome, 64);
|
||||
ffStrbufAppendS(userConfigHome, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(userConfigHome, "/.config/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(userConfigHome)
|
||||
|
||||
FFstrbuf* userHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userHome, 64);
|
||||
ffStrbufAppendS(userHome, state->passwd->pw_dir);
|
||||
ffStrbufEnsureEndsWithC(userHome, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(userHome)
|
||||
|
||||
FFstrbuf xdgConfigDirs;
|
||||
ffStrbufInitA(&xdgConfigDirs, 64);
|
||||
ffStrbufAppendS(&xdgConfigDirs, getenv("XDG_CONFIG_DIRS"));
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < xdgConfigDirs.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&xdgConfigDirs, startIndex, ':');
|
||||
xdgConfigDirs.chars[colonIndex] = '\0';
|
||||
|
||||
if(!ffStrSet(xdgConfigDirs.chars + startIndex))
|
||||
{
|
||||
startIndex = colonIndex + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(buffer, 64);
|
||||
ffStrbufAppendS(buffer, xdgConfigDirs.chars + startIndex);
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(buffer);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
ffStrbufDestroy(&xdgConfigDirs);
|
||||
|
||||
FFstrbuf* systemConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfigHome, 64);
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome)
|
||||
|
||||
FFstrbuf* systemConfig = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfig, 64);
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfig)
|
||||
|
||||
#undef FF_ENSURE_ONLY_ONCE_IN_LIST
|
||||
}
|
||||
|
||||
static void initCacheDir(FFstate* state)
|
||||
{
|
||||
ffStrbufInitA(&state->cacheDir, 64);
|
||||
|
||||
ffStrbufAppendS(&state->cacheDir, getenv("XDG_CACHE_HOME"));
|
||||
|
||||
if(state->cacheDir.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&state->cacheDir, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(&state->cacheDir, "/.cache/");
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureEndsWithC(&state->cacheDir, '/');
|
||||
|
||||
mkdir(state->cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder, but who knows
|
||||
|
||||
ffStrbufAppendS(&state->cacheDir, "fastfetch/");
|
||||
mkdir(state->cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
}
|
||||
FFinstance instance; // Global singleton
|
||||
|
||||
static void initState(FFstate* state)
|
||||
{
|
||||
state->logoWidth = 0;
|
||||
state->logoHeight = 0;
|
||||
state->keysHeight = 0;
|
||||
state->passwd = getpwuid(getuid());
|
||||
uname(&state->utsname);
|
||||
|
||||
#if FF_HAVE_SYSINFO_H
|
||||
sysinfo(&state->sysinfo);
|
||||
ffPlatformInit(&state->platform);
|
||||
state->configDoc = NULL;
|
||||
state->resultDoc = NULL;
|
||||
}
|
||||
|
||||
static void defaultConfig(void)
|
||||
{
|
||||
ffOptionsInitLogo(&instance.config.logo);
|
||||
ffOptionsInitGeneral(&instance.config.general);
|
||||
ffOptionsInitModules(&instance.config.modules);
|
||||
ffOptionsInitDisplay(&instance.config.display);
|
||||
ffOptionsInitLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
void ffInitInstance(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
//https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support
|
||||
setlocale(LC_ALL, ".UTF8");
|
||||
#else
|
||||
// used for mbsrtowcs in Module `separator`
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
initConfigDirs(state);
|
||||
initCacheDir(state);
|
||||
initState(&instance.state);
|
||||
defaultConfig();
|
||||
}
|
||||
|
||||
static void initModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufInitA(&args->key, 0);
|
||||
ffStrbufInitA(&args->outputFormat, 0);
|
||||
ffStrbufInitA(&args->errorFormat, 0);
|
||||
}
|
||||
|
||||
static void defaultConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufInitA(&instance->config.logo.source, 0);
|
||||
instance->config.logo.type = FF_LOGO_TYPE_AUTO;
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufInit(&instance->config.logo.colors[i]);
|
||||
instance->config.logo.width = 0;
|
||||
instance->config.logo.height = 0; //preserve aspect ratio
|
||||
instance->config.logo.paddingLeft = 0;
|
||||
instance->config.logo.paddingRight = 4;
|
||||
instance->config.logo.printRemaining = true;
|
||||
|
||||
ffStrbufInit(&instance->config.colorKeys);
|
||||
ffStrbufInit(&instance->config.colorTitle);
|
||||
|
||||
ffStrbufInit(&instance->config.separator);
|
||||
ffStrbufAppendS(&instance->config.separator, ": ");
|
||||
|
||||
instance->config.showErrors = false;
|
||||
instance->config.recache = false;
|
||||
instance->config.cacheSave = true;
|
||||
instance->config.allowSlowOperations = false;
|
||||
instance->config.disableLinewrap = true;
|
||||
instance->config.hideCursor = true;
|
||||
instance->config.escapeBedrock = true;
|
||||
instance->config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
|
||||
instance->config.glType = FF_GL_TYPE_AUTO;
|
||||
instance->config.pipe = false;
|
||||
instance->config.multithreading = true;
|
||||
|
||||
initModuleArg(&instance->config.os);
|
||||
initModuleArg(&instance->config.host);
|
||||
initModuleArg(&instance->config.bios);
|
||||
initModuleArg(&instance->config.board);
|
||||
initModuleArg(&instance->config.kernel);
|
||||
initModuleArg(&instance->config.uptime);
|
||||
initModuleArg(&instance->config.processes);
|
||||
initModuleArg(&instance->config.packages);
|
||||
initModuleArg(&instance->config.shell);
|
||||
initModuleArg(&instance->config.resolution);
|
||||
initModuleArg(&instance->config.de);
|
||||
initModuleArg(&instance->config.wm);
|
||||
initModuleArg(&instance->config.wmTheme);
|
||||
initModuleArg(&instance->config.theme);
|
||||
initModuleArg(&instance->config.icons);
|
||||
initModuleArg(&instance->config.font);
|
||||
initModuleArg(&instance->config.cursor);
|
||||
initModuleArg(&instance->config.terminal);
|
||||
initModuleArg(&instance->config.terminalFont);
|
||||
initModuleArg(&instance->config.cpu);
|
||||
initModuleArg(&instance->config.cpuUsage);
|
||||
initModuleArg(&instance->config.gpu);
|
||||
initModuleArg(&instance->config.memory);
|
||||
initModuleArg(&instance->config.swap);
|
||||
initModuleArg(&instance->config.disk);
|
||||
initModuleArg(&instance->config.battery);
|
||||
initModuleArg(&instance->config.powerAdapter);
|
||||
initModuleArg(&instance->config.locale);
|
||||
initModuleArg(&instance->config.localIP);
|
||||
initModuleArg(&instance->config.publicIP);
|
||||
initModuleArg(&instance->config.weather);
|
||||
initModuleArg(&instance->config.player);
|
||||
initModuleArg(&instance->config.song);
|
||||
initModuleArg(&instance->config.dateTime);
|
||||
initModuleArg(&instance->config.date);
|
||||
initModuleArg(&instance->config.time);
|
||||
initModuleArg(&instance->config.vulkan);
|
||||
initModuleArg(&instance->config.openGL);
|
||||
initModuleArg(&instance->config.openCL);
|
||||
initModuleArg(&instance->config.users);
|
||||
|
||||
ffStrbufInitA(&instance->config.libPCI, 0);
|
||||
ffStrbufInitA(&instance->config.libVulkan, 0);
|
||||
ffStrbufInitA(&instance->config.libWayland, 0);
|
||||
ffStrbufInitA(&instance->config.libXcbRandr, 0);
|
||||
ffStrbufInitA(&instance->config.libXcb, 0);
|
||||
ffStrbufInitA(&instance->config.libXrandr, 0);
|
||||
ffStrbufInitA(&instance->config.libX11, 0);
|
||||
ffStrbufInitA(&instance->config.libGIO, 0);
|
||||
ffStrbufInitA(&instance->config.libDConf, 0);
|
||||
ffStrbufInitA(&instance->config.libDBus, 0);
|
||||
ffStrbufInitA(&instance->config.libXFConf, 0);
|
||||
ffStrbufInitA(&instance->config.libSQLite3, 0);
|
||||
ffStrbufInitA(&instance->config.librpm, 0);
|
||||
ffStrbufInitA(&instance->config.libImageMagick, 0);
|
||||
ffStrbufInitA(&instance->config.libZ, 0);
|
||||
ffStrbufInitA(&instance->config.libChafa, 0);
|
||||
ffStrbufInitA(&instance->config.libEGL, 0);
|
||||
ffStrbufInitA(&instance->config.libGLX, 0);
|
||||
ffStrbufInitA(&instance->config.libOSMesa, 0);
|
||||
ffStrbufInitA(&instance->config.libOpenCL, 0);
|
||||
ffStrbufInitA(&instance->config.libcJSON, 0);
|
||||
ffStrbufInitA(&instance->config.libfreetype, 0);
|
||||
|
||||
instance->config.cpuTemp = false;
|
||||
instance->config.gpuTemp = false;
|
||||
instance->config.batteryTemp = false;
|
||||
|
||||
instance->config.titleFQDN = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.diskFolders, 0);
|
||||
instance->config.diskRemovable = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.batteryDir, 0);
|
||||
|
||||
ffStrbufInitA(&instance->config.separatorString, 0);
|
||||
|
||||
instance->config.localIpShowIpV4 = true;
|
||||
instance->config.localIpShowIpV6 = false;
|
||||
instance->config.localIpShowLoop = false;
|
||||
ffStrbufInit(&instance->config.localIpNamePrefix);
|
||||
|
||||
instance->config.publicIpTimeout = 0;
|
||||
ffStrbufInit(&instance->config.publicIpUrl);
|
||||
|
||||
instance->config.weatherTimeout = 0;
|
||||
ffStrbufInitS(&instance->config.weatherOutputFormat, "%t+-+%C+(%l)");
|
||||
|
||||
ffStrbufInitA(&instance->config.osFile, 0);
|
||||
|
||||
ffStrbufInitA(&instance->config.playerName, 0);
|
||||
}
|
||||
|
||||
void ffInitInstance(FFinstance* instance)
|
||||
{
|
||||
initState(&instance->state);
|
||||
defaultConfig(instance);
|
||||
}
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__)
|
||||
|
||||
static void* connectDisplayServerThreadMain(void* instance)
|
||||
{
|
||||
ffConnectDisplayServer((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
|
||||
static void* detectPlasmaThreadMain(void* instance)
|
||||
{
|
||||
ffDetectQt((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK2ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK2((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK3ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK3((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK4ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK4((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* startThreadsThreadMain(void* instance)
|
||||
{
|
||||
pthread_t dsThread;
|
||||
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
pthread_detach(dsThread);
|
||||
|
||||
pthread_t gtk2Thread;
|
||||
pthread_create(>k2Thread, NULL, detectGTK2ThreadMain, instance);
|
||||
pthread_detach(gtk2Thread);
|
||||
|
||||
pthread_t gtk3Thread;
|
||||
pthread_create(>k3Thread, NULL, detectGTK3ThreadMain, instance);
|
||||
pthread_detach(gtk3Thread);
|
||||
|
||||
pthread_t gtk4Thread;
|
||||
pthread_create(>k4Thread, NULL, detectGTK4ThreadMain, instance);
|
||||
pthread_detach(gtk4Thread);
|
||||
|
||||
pthread_t plasmaThread;
|
||||
pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance);
|
||||
pthread_detach(plasmaThread);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
|
||||
#else // !__APPLE__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
#else // !__ANDROID__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
}
|
||||
#endif // __ANDROID__
|
||||
|
||||
static volatile bool ffDisableLinewrap = true;
|
||||
static volatile bool ffHideCursor = true;
|
||||
|
||||
static void resetConsole()
|
||||
static void resetConsole(void)
|
||||
{
|
||||
if(ffDisableLinewrap)
|
||||
fputs("\033[?7h", stdout);
|
||||
|
||||
if(ffHideCursor)
|
||||
fputs("\033[?25h", stdout);
|
||||
|
||||
#if defined(_WIN32)
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI consoleHandler(DWORD signal)
|
||||
{
|
||||
FF_UNUSED(signal);
|
||||
resetConsole();
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
static void exitSignalHandler(int signal)
|
||||
{
|
||||
FF_UNUSED(signal);
|
||||
resetConsole();
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ffStart(FFinstance* instance)
|
||||
void ffStart(void)
|
||||
{
|
||||
if(instance->config.multithreading)
|
||||
startDetectionThreads(instance);
|
||||
#ifdef FF_START_DETECTION_THREADS
|
||||
if(instance.config.general.multithreading)
|
||||
startDetectionThreads();
|
||||
#endif
|
||||
|
||||
ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe;
|
||||
ffHideCursor = instance->config.hideCursor && !instance->config.pipe;
|
||||
|
||||
struct sigaction action = {};
|
||||
action.sa_handler = exitSignalHandler;
|
||||
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||
|
||||
#ifdef _WIN32
|
||||
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
|
||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
GetConsoleMode(hStdout, &mode);
|
||||
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#else
|
||||
if (instance.config.display.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
|
||||
struct sigaction action = { .sa_handler = exitSignalHandler };
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
sigaction(SIGQUIT, &action, NULL);
|
||||
|
||||
//We do the cache validation here, so we can skip it if --recache is given
|
||||
if(!instance->config.recache)
|
||||
ffCacheValidate(instance);
|
||||
#endif
|
||||
|
||||
//reset everything to default before we start printing
|
||||
if(!instance->config.pipe)
|
||||
if(!instance.config.display.pipe && !instance.state.resultDoc)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
if(ffHideCursor)
|
||||
@@ -389,126 +119,47 @@ void ffStart(FFinstance* instance)
|
||||
if(ffDisableLinewrap)
|
||||
fputs("\033[?7l", stdout);
|
||||
|
||||
ffLogoPrint(instance);
|
||||
ffLogoPrint();
|
||||
}
|
||||
|
||||
void ffFinish(FFinstance* instance)
|
||||
void ffFinish(void)
|
||||
{
|
||||
if(instance->config.logo.printRemaining)
|
||||
ffLogoPrintRemaining(instance);
|
||||
if(instance.config.logo.printRemaining)
|
||||
ffLogoPrintRemaining();
|
||||
|
||||
resetConsole();
|
||||
}
|
||||
|
||||
static void destroyModuleArg(FFModuleArgs* args)
|
||||
static void destroyConfig(void)
|
||||
{
|
||||
ffStrbufDestroy(&args->key);
|
||||
ffStrbufDestroy(&args->outputFormat);
|
||||
ffStrbufDestroy(&args->errorFormat);
|
||||
ffOptionsDestroyLogo(&instance.config.logo);
|
||||
ffOptionsDestroyGeneral(&instance.config.general);
|
||||
ffOptionsDestroyModules(&instance.config.modules);
|
||||
ffOptionsDestroyDisplay(&instance.config.display);
|
||||
ffOptionsDestroyLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
static void destroyConfig(FFinstance* instance)
|
||||
static void destroyState(void)
|
||||
{
|
||||
ffStrbufDestroy(&instance->config.logo.source);
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufDestroy(&instance->config.logo.colors[i]);
|
||||
ffStrbufDestroy(&instance->config.colorKeys);
|
||||
ffStrbufDestroy(&instance->config.colorTitle);
|
||||
ffStrbufDestroy(&instance->config.separator);
|
||||
|
||||
destroyModuleArg(&instance->config.os);
|
||||
destroyModuleArg(&instance->config.host);
|
||||
destroyModuleArg(&instance->config.bios);
|
||||
destroyModuleArg(&instance->config.board);
|
||||
destroyModuleArg(&instance->config.kernel);
|
||||
destroyModuleArg(&instance->config.uptime);
|
||||
destroyModuleArg(&instance->config.processes);
|
||||
destroyModuleArg(&instance->config.packages);
|
||||
destroyModuleArg(&instance->config.shell);
|
||||
destroyModuleArg(&instance->config.resolution);
|
||||
destroyModuleArg(&instance->config.de);
|
||||
destroyModuleArg(&instance->config.wm);
|
||||
destroyModuleArg(&instance->config.wmTheme);
|
||||
destroyModuleArg(&instance->config.theme);
|
||||
destroyModuleArg(&instance->config.icons);
|
||||
destroyModuleArg(&instance->config.font);
|
||||
destroyModuleArg(&instance->config.cursor);
|
||||
destroyModuleArg(&instance->config.terminal);
|
||||
destroyModuleArg(&instance->config.terminalFont);
|
||||
destroyModuleArg(&instance->config.cpu);
|
||||
destroyModuleArg(&instance->config.cpuUsage);
|
||||
destroyModuleArg(&instance->config.gpu);
|
||||
destroyModuleArg(&instance->config.memory);
|
||||
destroyModuleArg(&instance->config.swap);
|
||||
destroyModuleArg(&instance->config.disk);
|
||||
destroyModuleArg(&instance->config.battery);
|
||||
destroyModuleArg(&instance->config.powerAdapter);
|
||||
destroyModuleArg(&instance->config.locale);
|
||||
destroyModuleArg(&instance->config.localIP);
|
||||
destroyModuleArg(&instance->config.publicIP);
|
||||
destroyModuleArg(&instance->config.weather);
|
||||
destroyModuleArg(&instance->config.player);
|
||||
destroyModuleArg(&instance->config.song);
|
||||
destroyModuleArg(&instance->config.dateTime);
|
||||
destroyModuleArg(&instance->config.date);
|
||||
destroyModuleArg(&instance->config.time);
|
||||
destroyModuleArg(&instance->config.vulkan);
|
||||
destroyModuleArg(&instance->config.openGL);
|
||||
destroyModuleArg(&instance->config.openCL);
|
||||
destroyModuleArg(&instance->config.users);
|
||||
|
||||
ffStrbufDestroy(&instance->config.libPCI);
|
||||
ffStrbufDestroy(&instance->config.libVulkan);
|
||||
ffStrbufDestroy(&instance->config.libWayland);
|
||||
ffStrbufDestroy(&instance->config.libXcbRandr);
|
||||
ffStrbufDestroy(&instance->config.libXcb);
|
||||
ffStrbufDestroy(&instance->config.libXrandr);
|
||||
ffStrbufDestroy(&instance->config.libX11);
|
||||
ffStrbufDestroy(&instance->config.libGIO);
|
||||
ffStrbufDestroy(&instance->config.libDConf);
|
||||
ffStrbufDestroy(&instance->config.libDBus);
|
||||
ffStrbufDestroy(&instance->config.libXFConf);
|
||||
ffStrbufDestroy(&instance->config.libSQLite3);
|
||||
ffStrbufDestroy(&instance->config.librpm);
|
||||
ffStrbufDestroy(&instance->config.libImageMagick);
|
||||
ffStrbufDestroy(&instance->config.libZ);
|
||||
ffStrbufDestroy(&instance->config.libChafa);
|
||||
ffStrbufDestroy(&instance->config.libEGL);
|
||||
ffStrbufDestroy(&instance->config.libGLX);
|
||||
ffStrbufDestroy(&instance->config.libOSMesa);
|
||||
ffStrbufDestroy(&instance->config.libOpenCL);
|
||||
ffStrbufDestroy(&instance->config.libcJSON);
|
||||
ffStrbufDestroy(&instance->config.libfreetype);
|
||||
|
||||
ffStrbufDestroy(&instance->config.diskFolders);
|
||||
ffStrbufDestroy(&instance->config.batteryDir);
|
||||
ffStrbufDestroy(&instance->config.separatorString);
|
||||
ffStrbufDestroy(&instance->config.localIpNamePrefix);
|
||||
ffStrbufDestroy(&instance->config.publicIpUrl);
|
||||
ffStrbufDestroy(&instance->config.weatherOutputFormat);
|
||||
ffStrbufDestroy(&instance->config.osFile);
|
||||
ffStrbufDestroy(&instance->config.playerName);
|
||||
ffPlatformDestroy(&instance.state.platform);
|
||||
yyjson_doc_free(instance.state.configDoc);
|
||||
yyjson_mut_doc_free(instance.state.resultDoc);
|
||||
ffStrbufDestroy(&instance.state.genConfigPath);
|
||||
}
|
||||
|
||||
static void destroyState(FFinstance* instance)
|
||||
void ffDestroyInstance(void)
|
||||
{
|
||||
for(uint32_t i = 0; i < instance->state.configDirs.length; ++i)
|
||||
ffStrbufDestroy((FFstrbuf*)ffListGet(&instance->state.configDirs, i));
|
||||
ffListDestroy(&instance->state.configDirs);
|
||||
|
||||
ffStrbufDestroy(&instance->state.cacheDir);
|
||||
}
|
||||
|
||||
void ffDestroyInstance(FFinstance* instance)
|
||||
{
|
||||
destroyConfig(instance);
|
||||
destroyState(instance);
|
||||
destroyConfig();
|
||||
destroyState();
|
||||
}
|
||||
|
||||
//Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
|
||||
void ffListFeatures()
|
||||
void ffListFeatures(void)
|
||||
{
|
||||
fputs(
|
||||
#ifdef FF_HAVE_THREADS
|
||||
"threads\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_LIBPCI
|
||||
"libpci\n"
|
||||
#endif
|
||||
@@ -530,6 +181,9 @@ void ffListFeatures()
|
||||
#ifdef FF_HAVE_X11
|
||||
"x11\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_DRM
|
||||
"drm\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_GIO
|
||||
"gio\n"
|
||||
#endif
|
||||
@@ -572,11 +226,20 @@ void ffListFeatures()
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
"opencl\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_LIBCJSON
|
||||
"libcjson\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
"freetype"
|
||||
"freetype\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_PULSE
|
||||
"libpulse\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_LIBNM
|
||||
"libnm\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_DDCUTIL
|
||||
"libddcutil\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_DIRECTX_HEADERS
|
||||
"Directx Headers\n"
|
||||
#endif
|
||||
""
|
||||
, stdout);
|
||||
|
||||
-192
@@ -1,192 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInit(&path);
|
||||
|
||||
while(*fileName != '\0')
|
||||
{
|
||||
ffStrbufAppendC(&path, *fileName);
|
||||
if(*fileName == '/')
|
||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
++fileName;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
bool ffWriteFDBuffer(int fd, const FFstrbuf* content)
|
||||
{
|
||||
return write(fd, content->chars, content->length) != -1;
|
||||
}
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
int fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = write(fd, data, dataSize) != -1;
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer)
|
||||
{
|
||||
return ffWriteFileData(fileName, buffer->length, buffer->chars);
|
||||
}
|
||||
|
||||
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t readed = 0;
|
||||
|
||||
ffStrbufEnsureFree(buffer, 31); // 32 - 1 for the null terminator
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
|
||||
while(
|
||||
(readed = read(fd, buffer->chars + buffer->length, free)) > 0 &&
|
||||
(uint32_t) readed == free
|
||||
) {
|
||||
buffer->length += (uint32_t) readed;
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
|
||||
// In case of failure, read returns -1. We don't want to substract the length of the buffer.
|
||||
if(readed > 0)
|
||||
buffer->length += (uint32_t) readed;
|
||||
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
|
||||
return readed >= 0;
|
||||
}
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
{
|
||||
int fd = open(fileName, O_RDONLY);
|
||||
if(fd == -1)
|
||||
return -1;
|
||||
|
||||
ssize_t readed = read(fd, data, dataSize);
|
||||
|
||||
close(fd);
|
||||
|
||||
return readed;
|
||||
}
|
||||
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
int fd = open(fileName, O_RDONLY);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
|
||||
bool ret = ffAppendFDBuffer(fd, buffer);
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufClear(buffer);
|
||||
return ffAppendFileBuffer(fileName, buffer);
|
||||
}
|
||||
|
||||
// Not thread safe!
|
||||
void ffSuppressIO(bool suppress)
|
||||
{
|
||||
static bool init = false;
|
||||
static int origOut = -1;
|
||||
static int origErr = -1;
|
||||
static int nullFile = -1;
|
||||
|
||||
if(!init)
|
||||
{
|
||||
if(!suppress)
|
||||
return;
|
||||
|
||||
origOut = dup(STDOUT_FILENO);
|
||||
origErr = dup(STDERR_FILENO);
|
||||
nullFile = open("/dev/null", O_WRONLY);
|
||||
init = true;
|
||||
}
|
||||
|
||||
if(nullFile == -1)
|
||||
return;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
dup2(suppress ? nullFile : origOut, STDOUT_FILENO);
|
||||
dup2(suppress ? nullFile : origErr, STDERR_FILENO);
|
||||
}
|
||||
|
||||
bool ffFileExists(const char* fileName, mode_t mode)
|
||||
{
|
||||
struct stat fileStat;
|
||||
return stat(fileName, &fileStat) == 0 && ((fileStat.st_mode & S_IFMT) == mode);
|
||||
}
|
||||
|
||||
void ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
struct termios oldTerm, newTerm;
|
||||
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
|
||||
return;
|
||||
|
||||
newTerm = oldTerm;
|
||||
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
|
||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
|
||||
return;
|
||||
|
||||
fputs(request, stdout);
|
||||
fflush(stdout);
|
||||
|
||||
struct pollfd pfd;
|
||||
pfd.fd = STDIN_FILENO;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
|
||||
//Give the terminal 35ms to respond
|
||||
if(poll(&pfd, 1, 35) <= 0)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
ssize_t readed = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
|
||||
if(readed <= 0)
|
||||
return;
|
||||
|
||||
buffer[readed] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_io
|
||||
#define FF_INCLUDED_common_io
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <sys/types.h> //mode_t
|
||||
|
||||
bool ffWriteFDBuffer(int fd, const FFstrbuf* content);
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
|
||||
bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer);
|
||||
|
||||
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer);
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data);
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
|
||||
bool ffFileExists(const char* fileName, mode_t mode);
|
||||
|
||||
// Not thread safe!
|
||||
void ffSuppressIO(bool suppress);
|
||||
|
||||
FF_C_SCANF(2, 3) void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,156 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fileapi.h>
|
||||
#include <handleapi.h>
|
||||
#include <io.h>
|
||||
typedef HANDLE FFNativeFD;
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
typedef int FFNativeFD;
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
|
||||
#define PROC_FILE_BUFFSIZ 8192
|
||||
#endif
|
||||
|
||||
static inline FFNativeFD FFUnixFD2NativeFD(int unixfd)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return unixfd;
|
||||
#else
|
||||
return (FFNativeFD) _get_osfhandle(unixfd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool ffWriteFDData(FFNativeFD fd, size_t dataSize, const void* data)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return write(fd, data, dataSize) != -1;
|
||||
#else
|
||||
DWORD written;
|
||||
return WriteFile(fd, data, (DWORD) dataSize, &written, NULL) && written == dataSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool ffWriteFDBuffer(FFNativeFD fd, const FFstrbuf* content)
|
||||
{
|
||||
return ffWriteFDData(fd, content->length, content->chars);
|
||||
}
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
|
||||
|
||||
static inline bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer)
|
||||
{
|
||||
return ffWriteFileData(fileName, buffer->length, buffer->chars);
|
||||
}
|
||||
|
||||
static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return read(fd, data, dataSize);
|
||||
#else
|
||||
DWORD bytesRead;
|
||||
if(!ReadFile(fd, data, (DWORD)dataSize, &bytesRead, NULL))
|
||||
return -1;
|
||||
|
||||
return (ssize_t)bytesRead;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data);
|
||||
|
||||
bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer);
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
|
||||
static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufClear(buffer);
|
||||
return ffAppendFileBuffer(fileName, buffer);
|
||||
}
|
||||
|
||||
//Bit flags, combine with |
|
||||
typedef enum FFPathType
|
||||
{
|
||||
FF_PATHTYPE_REGULAR = 1,
|
||||
FF_PATHTYPE_LINK = 2,
|
||||
FF_PATHTYPE_DIRECTORY = 4
|
||||
} FFPathType;
|
||||
|
||||
#define FF_PATHTYPE_FILE (FF_PATHTYPE_REGULAR | FF_PATHTYPE_LINK)
|
||||
#define FF_PATHTYPE_ANY (FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY)
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType pathType);
|
||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
|
||||
|
||||
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
|
||||
|
||||
FF_C_SCANF(2, 3)
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
|
||||
// Not thread safe!
|
||||
bool ffSuppressIO(bool suppress);
|
||||
|
||||
static inline void ffUnsuppressIO(bool* suppressed)
|
||||
{
|
||||
if (!*suppressed) return;
|
||||
ffSuppressIO(false);
|
||||
*suppressed = false;
|
||||
}
|
||||
|
||||
#define FF_SUPPRESS_IO() bool __attribute__((__cleanup__(ffUnsuppressIO), __unused__)) io_suppressed__ = ffSuppressIO(true)
|
||||
|
||||
void ffListFilesRecursively(const char* path, bool pretty);
|
||||
|
||||
static inline bool wrapClose(FFNativeFD* pfd)
|
||||
{
|
||||
assert(pfd);
|
||||
|
||||
#ifndef WIN32
|
||||
if (*pfd < 0)
|
||||
return false;
|
||||
close(*pfd);
|
||||
#else
|
||||
// https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
|
||||
if (*pfd == NULL || *pfd == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
CloseHandle(*pfd);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose)))
|
||||
|
||||
static inline bool wrapFclose(FILE** pfile)
|
||||
{
|
||||
assert(pfile);
|
||||
if (!*pfile)
|
||||
return false;
|
||||
fclose(*pfile);
|
||||
return true;
|
||||
}
|
||||
#define FF_AUTO_CLOSE_FILE __attribute__((__cleanup__(wrapFclose)))
|
||||
|
||||
#ifndef _WIN32
|
||||
static inline bool wrapClosedir(DIR** pdir)
|
||||
{
|
||||
assert(pdir);
|
||||
if (!*pdir)
|
||||
return false;
|
||||
closedir(*pdir);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool wrapClosedir(HANDLE* pdir)
|
||||
{
|
||||
assert(pdir);
|
||||
if (!*pdir)
|
||||
return false;
|
||||
FindClose(*pdir);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#define FF_AUTO_CLOSE_DIR __attribute__((__cleanup__(wrapClosedir)))
|
||||
@@ -0,0 +1,269 @@
|
||||
#include "io.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/unused.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#if __has_include(<wordexp.h>)
|
||||
#include <wordexp.h>
|
||||
#endif
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
|
||||
char *token = NULL;
|
||||
while((token = strchr(fileName, '/')) != NULL)
|
||||
{
|
||||
ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
|
||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
fileName = token + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
|
||||
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return write(fd, data, dataSize) > 0;
|
||||
}
|
||||
|
||||
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t bytesRead = 0;
|
||||
|
||||
struct stat fileInfo;
|
||||
if(fstat(fd, &fileInfo) != 0)
|
||||
return false;
|
||||
|
||||
if (fileInfo.st_size > 0)
|
||||
{
|
||||
// optimize for files has a fixed length,
|
||||
// file can be very large, only keep necessary memory to save time and resources.
|
||||
ffStrbufEnsureFixedLengthFree(buffer, (uint32_t)fileInfo.st_size);
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureFree(buffer, 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
// procfs file's st_size is always zero
|
||||
// choose a signed int type so that can store a native number
|
||||
ssize_t remain = fileInfo.st_size;
|
||||
|
||||
while(
|
||||
(bytesRead = read(fd, buffer->chars + buffer->length, free)) > 0
|
||||
) {
|
||||
buffer->length += (uint32_t) bytesRead;
|
||||
// if remain > 0, it means there is some data left in the file.
|
||||
// if remain == 0, it means reading has completed, no need to grow up the buffer.
|
||||
// if remain < 0, we are reading a file from procfs/sysfs and its st_size is zero,
|
||||
// we cannot detect how many data remains in the file, we only can call ffStrbufEnsureFree and read again.
|
||||
remain -= bytesRead;
|
||||
if((uint32_t) bytesRead == free && remain != 0)
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
|
||||
return buffer->length > 0;
|
||||
}
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
{
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC);
|
||||
if(fd == -1)
|
||||
return -1;
|
||||
|
||||
return ffReadFDData(fd, dataSize, data);
|
||||
}
|
||||
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
|
||||
return ffAppendFDBuffer(fd, buffer);
|
||||
}
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType type)
|
||||
{
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
|
||||
if(type & FF_PATHTYPE_REGULAR && mode == S_IFREG)
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_LINK && mode == S_IFLNK)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
#if __has_include(<wordexp.h>) // https://github.com/termux/termux-packages/pull/7056
|
||||
|
||||
wordexp_t exp;
|
||||
if(wordexp(in, &exp, WRDE_NOCMD) != 0)
|
||||
return false;
|
||||
|
||||
if (exp.we_wordc == 1)
|
||||
{
|
||||
result = true;
|
||||
ffStrbufSetS(out, exp.we_wordv[0]);
|
||||
}
|
||||
|
||||
wordfree(&exp);
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
struct termios oldTerm, newTerm;
|
||||
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
|
||||
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
|
||||
|
||||
newTerm = oldTerm;
|
||||
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
|
||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
|
||||
return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)";
|
||||
|
||||
fputs(request, stdout);
|
||||
fflush(stdout);
|
||||
|
||||
//Give the terminal 35ms to respond
|
||||
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
return "poll() timeout or failed";
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
|
||||
if(bytesRead <= 0)
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
|
||||
buffer[bytesRead] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
static bool init = false;
|
||||
static int origOut = -1;
|
||||
static int origErr = -1;
|
||||
static int nullFile = -1;
|
||||
|
||||
if(!init)
|
||||
{
|
||||
if(!suppress)
|
||||
return true;
|
||||
|
||||
origOut = dup(STDOUT_FILENO);
|
||||
origErr = dup(STDERR_FILENO);
|
||||
nullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
|
||||
init = true;
|
||||
}
|
||||
|
||||
if(nullFile == -1)
|
||||
return false;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
dup2(suppress ? nullFile : origOut, STDOUT_FILENO);
|
||||
dup2(suppress ? nullFile : origErr, STDERR_FILENO);
|
||||
return true;
|
||||
}
|
||||
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
{
|
||||
DIR* dir = opendir(folder->chars);
|
||||
if(dir == NULL)
|
||||
return;
|
||||
|
||||
uint32_t folderLength = folder->length;
|
||||
|
||||
if(pretty && folderName != NULL)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation - 1; i++)
|
||||
fputs(" | ", stdout);
|
||||
printf("%s/\n", folderName);
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(entry->d_type == DT_DIR)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(folder, entry->d_name);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(folder->chars + baseLength, stdout);
|
||||
}
|
||||
|
||||
puts(entry->d_name);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
void ffListFilesRecursively(const char* path, bool pretty)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
#include "io.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
char *token = NULL;
|
||||
while((token = strchr(fileName, '/')) != NULL)
|
||||
{
|
||||
ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
|
||||
CreateDirectoryA(path.chars, NULL);
|
||||
fileName = token + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
return !!WriteFile(handle, data, (DWORD)dataSize, &written, NULL);
|
||||
}
|
||||
|
||||
bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
|
||||
{
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if(!GetFileSizeEx(handle, &fileSize))
|
||||
fileSize.QuadPart = 0;
|
||||
|
||||
if (fileSize.QuadPart > 0)
|
||||
{
|
||||
// optimize for files has a fixed length,
|
||||
// file can be very large, only keep necessary memory to save time and resources.
|
||||
ffStrbufEnsureFixedLengthFree(buffer, (uint32_t)fileSize.QuadPart);
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureFree(buffer, 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
ssize_t remain = fileSize.QuadPart;
|
||||
|
||||
bool success;
|
||||
while(
|
||||
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &bytesRead, NULL)) &&
|
||||
bytesRead > 0
|
||||
) {
|
||||
buffer->length += (uint32_t) bytesRead;
|
||||
remain -= (ssize_t)bytesRead;
|
||||
if((uint32_t) bytesRead == free && remain != 0)
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
return ffReadFDData(handle, dataSize, data);
|
||||
}
|
||||
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
return ffAppendFDBuffer(handle, buffer);
|
||||
}
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType type)
|
||||
{
|
||||
DWORD attr = GetFileAttributesA(path);
|
||||
if(attr == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
if(type & FF_PATHTYPE_REGULAR && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_LINK && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||
{
|
||||
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
|
||||
if (length <= 1) return false;
|
||||
|
||||
ffStrbufClear(out);
|
||||
ffStrbufEnsureFree(out, (uint32_t)length);
|
||||
ExpandEnvironmentStringsA(in, out->chars, length);
|
||||
out->length = (uint32_t)length - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
(void) suppress; //Not implemented.
|
||||
return false;
|
||||
}
|
||||
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
{
|
||||
uint32_t folderLength = folder->length;
|
||||
|
||||
if(pretty && folderName != NULL)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation - 1; i++)
|
||||
fputs(" | ", stdout);
|
||||
printf("%s/\n", folderName);
|
||||
}
|
||||
|
||||
ffStrbufAppendC(folder, '*');
|
||||
WIN32_FIND_DATAA entry;
|
||||
HANDLE hFind = FindFirstFileA(folder->chars, &entry);
|
||||
ffStrbufTrimRight(folder, '*');
|
||||
if(hFind == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if(ffStrEquals(entry.cFileName, ".") || ffStrEquals(entry.cFileName, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
ffStrbufAppendS(folder, entry.cFileName);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry.cFileName, pretty);
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(folder->chars + baseLength, stdout);
|
||||
}
|
||||
|
||||
puts(entry.cFileName);
|
||||
} while (FindNextFileA(hFind, &entry));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
void ffListFilesRecursively(const char* path, bool pretty)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
||||
}
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD prev_mode;
|
||||
GetConsoleMode(hInput, &prev_mode);
|
||||
SetConsoleMode(hInput, 0);
|
||||
|
||||
FlushConsoleInputBuffer(hInput);
|
||||
|
||||
DWORD bytes = 0;
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0)
|
||||
{
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
return "WaitForSingleObject() failed or timeout";
|
||||
}
|
||||
|
||||
// Ignore all unexpected input events
|
||||
INPUT_RECORD record;
|
||||
DWORD len = 0;
|
||||
if (!PeekConsoleInputW(hInput, &record, 1, &len))
|
||||
break;
|
||||
|
||||
if (
|
||||
record.EventType == KEY_EVENT &&
|
||||
record.Event.KeyEvent.uChar.UnicodeChar != L'\r' &&
|
||||
record.Event.KeyEvent.uChar.UnicodeChar != L'\n'
|
||||
)
|
||||
break;
|
||||
else
|
||||
ReadConsoleInputW(hInput, &record, 1, &len);
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
bytes = 0;
|
||||
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
|
||||
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
|
||||
if(bytes <= 0)
|
||||
return "ReadFile() failed";
|
||||
|
||||
buffer[bytes] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/time.h"
|
||||
#include "modules/modules.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs)
|
||||
{
|
||||
if(ffStrEqualsIgnCase(key, "key"))
|
||||
{
|
||||
ffStrbufSetNS(&moduleArgs->key, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "format"))
|
||||
{
|
||||
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "keyColor"))
|
||||
{
|
||||
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "keyWidth"))
|
||||
{
|
||||
moduleArgs->keyWidth = (uint32_t) yyjson_get_uint(val);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs)
|
||||
{
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->key, &moduleArgs->key))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "key", &moduleArgs->key);
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->outputFormat, &moduleArgs->outputFormat))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "format", &moduleArgs->outputFormat);
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->keyColor, &moduleArgs->keyColor))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
|
||||
if (moduleArgs->keyWidth != defaultModuleArgs->keyWidth)
|
||||
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
|
||||
}
|
||||
|
||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
|
||||
{
|
||||
if (yyjson_is_int(val))
|
||||
{
|
||||
int intVal = yyjson_get_int(val);
|
||||
|
||||
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
|
||||
{
|
||||
if (intVal == pPair->value)
|
||||
{
|
||||
*result = pPair->value;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return "Invalid enum integer";
|
||||
}
|
||||
else if (yyjson_is_str(val))
|
||||
{
|
||||
const char* strVal = yyjson_get_str(val);
|
||||
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
|
||||
{
|
||||
if (ffStrEqualsIgnCase(strVal, pPair->key))
|
||||
{
|
||||
*result = pPair->value;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return "Invalid enum string";
|
||||
}
|
||||
else
|
||||
return "Invalid enum value type; must be a string or integer";
|
||||
}
|
||||
|
||||
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||
if (baseInfo->generateJsonResult)
|
||||
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||
else
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||
}
|
||||
|
||||
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
if(!isalpha(type[0])) return false;
|
||||
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
||||
{
|
||||
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
genJsonResult(baseInfo, jsonDoc);
|
||||
else
|
||||
baseInfo->printModule(baseInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void prepareModuleJsonObject(const char* type, yyjson_val* module)
|
||||
{
|
||||
FFconfig* cfg = &instance.config;
|
||||
switch (type[0])
|
||||
{
|
||||
case 'b': case 'B': {
|
||||
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME))
|
||||
ffPrepareCPUUsage();
|
||||
break;
|
||||
}
|
||||
case 'd': case 'D': {
|
||||
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
|
||||
{
|
||||
if (module) cfg->modules.diskIo.moduleInfo.parseJsonObject(&cfg->modules.diskIo, module);
|
||||
ffPrepareDiskIO(&cfg->modules.diskIo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'n': case 'N': {
|
||||
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
|
||||
{
|
||||
if (module) cfg->modules.netIo.moduleInfo.parseJsonObject(&cfg->modules.netIo, module);
|
||||
ffPrepareNetIO(&cfg->modules.netIo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'p': case 'P': {
|
||||
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
|
||||
{
|
||||
if (module) cfg->modules.publicIP.moduleInfo.parseJsonObject(&cfg->modules.publicIP, module);
|
||||
ffPreparePublicIp(&cfg->modules.publicIP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w': case 'W': {
|
||||
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
|
||||
{
|
||||
if (module) cfg->modules.weather.moduleInfo.parseJsonObject(&cfg->modules.weather, module);
|
||||
ffPrepareWeather(&cfg->modules.weather);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||
assert(root);
|
||||
|
||||
if (!yyjson_is_obj(root))
|
||||
return "Invalid JSON config format. Root value must be an object";
|
||||
|
||||
yyjson_val* modules = yyjson_obj_get(root, "modules");
|
||||
if (!modules) return NULL;
|
||||
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
||||
|
||||
yyjson_val* item;
|
||||
size_t idx, max;
|
||||
yyjson_arr_foreach(modules, idx, max, item)
|
||||
{
|
||||
uint64_t ms = 0;
|
||||
if(!prepare && instance.config.display.stat)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
yyjson_val* module = item;
|
||||
const char* type = yyjson_get_str(module);
|
||||
if (type)
|
||||
module = NULL;
|
||||
else if (yyjson_is_obj(module))
|
||||
{
|
||||
type = yyjson_get_str(yyjson_obj_get(module, "type"));
|
||||
if (!type) return "module object must contain a \"type\" key ( case sensitive )";
|
||||
if (yyjson_obj_size(module) == 1) // contains only Property type
|
||||
module = NULL;
|
||||
}
|
||||
else
|
||||
return "modules must be an array of strings or objects";
|
||||
|
||||
if(prepare)
|
||||
prepareModuleJsonObject(type, module);
|
||||
else if(!parseModuleJsonObject(type, module, jsonDoc))
|
||||
return "Unknown module type";
|
||||
|
||||
if(!prepare && instance.config.display.stat)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
const char* error = printJsonConfig(prepare, jsonDoc);
|
||||
if (error)
|
||||
{
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc);
|
||||
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
|
||||
yyjson_mut_doc_set_root(jsonDoc, obj);
|
||||
}
|
||||
else
|
||||
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
|
||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
|
||||
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc);
|
||||
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs);
|
||||
|
||||
yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc *doc, const FFstrbuf* buf) {
|
||||
return yyjson_mut_strncpy(doc, buf->chars, buf->length);
|
||||
}
|
||||
|
||||
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
|
||||
yyjson_mut_val *obj,
|
||||
const char *_key,
|
||||
const FFstrbuf* buf) {
|
||||
return yyjson_mut_obj_add_strncpy(doc, obj, _key, buf->chars, buf->length);
|
||||
}
|
||||
|
||||
yyjson_api_inline bool yyjson_mut_arr_add_strbuf(yyjson_mut_doc *doc,
|
||||
yyjson_mut_val *obj,
|
||||
const FFstrbuf* buf) {
|
||||
return yyjson_mut_arr_add_strncpy(doc, obj, buf->chars, buf->length);
|
||||
}
|
||||
@@ -10,17 +10,19 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#ifndef FF_DLOPEN_FLAGS
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void* libraryLoad(const char* path, int maxVersion)
|
||||
{
|
||||
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
|
||||
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
|
||||
FF_UNUSED(maxVersion)
|
||||
@@ -30,8 +32,7 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
if(result != NULL || maxVersion < 0)
|
||||
return result;
|
||||
|
||||
FFstrbuf pathbuf;
|
||||
ffStrbufInitA(&pathbuf, 64);
|
||||
FF_STRBUF_AUTO_DESTROY pathbuf = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&pathbuf, path);
|
||||
ffStrbufAppendC(&pathbuf, '.');
|
||||
|
||||
@@ -47,8 +48,6 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
ffStrbufSubstrBefore(&pathbuf, originalLength);
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&pathbuf);
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
||||
+39
-15
@@ -1,11 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_library
|
||||
#define FF_INCLUDED_common_library
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#if defined(_WIN32)
|
||||
#include <libloaderapi.h>
|
||||
#define FF_DLOPEN_FLAGS 0
|
||||
FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); }
|
||||
FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return (void*) GetProcAddress((HMODULE)handle, symbol); }
|
||||
static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); }
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
#define FF_LIBRARY_EXTENSION ".dll"
|
||||
#elif defined(__APPLE__)
|
||||
#define FF_LIBRARY_EXTENSION ".dylib"
|
||||
@@ -13,37 +21,53 @@
|
||||
#define FF_LIBRARY_EXTENSION ".so"
|
||||
#endif
|
||||
|
||||
static inline void ffLibraryUnload(void** handle)
|
||||
{
|
||||
assert(handle);
|
||||
if (*handle)
|
||||
dlclose(*handle);
|
||||
}
|
||||
|
||||
#define FF_LIBRARY_SYMBOL(symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName;
|
||||
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
|
||||
void* libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
|
||||
void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
|
||||
if(libraryObjectName == NULL) \
|
||||
return returnValue;
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
||||
symbolMapping = dlsym(library, #symbolName); \
|
||||
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
|
||||
if(symbolMapping == NULL) \
|
||||
{ \
|
||||
dlclose(library); \
|
||||
return returnValue; \
|
||||
}
|
||||
return returnValue;
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
|
||||
symbolMapping = dlsym(library, #symbolName); \
|
||||
if(symbolMapping == NULL && !(symbolMapping = (__typeof__(&symbolName)) dlsym(library, #alternateName))) \
|
||||
return returnValue;
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName = (__typeof__(&symbolName)) dlsym(library, #symbolName);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, returnValue);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName->ff ## symbolName, symbolName, returnValue);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
static FFModuleBaseInfo* A[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* B[] = {
|
||||
(void*) &instance.config.modules.battery,
|
||||
(void*) &instance.config.modules.bios,
|
||||
(void*) &instance.config.modules.bluetooth,
|
||||
(void*) &instance.config.modules.board,
|
||||
(void*) &instance.config.modules.break_,
|
||||
(void*) &instance.config.modules.brightness,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* C[] = {
|
||||
(void*) &instance.config.modules.chassis,
|
||||
(void*) &instance.config.modules.command,
|
||||
(void*) &instance.config.modules.colors,
|
||||
(void*) &instance.config.modules.cpu,
|
||||
(void*) &instance.config.modules.cpuUsage,
|
||||
(void*) &instance.config.modules.cursor,
|
||||
(void*) &instance.config.modules.custom,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* D[] = {
|
||||
(void*) &instance.config.modules.dateTime,
|
||||
(void*) &instance.config.modules.de,
|
||||
(void*) &instance.config.modules.display,
|
||||
(void*) &instance.config.modules.disk,
|
||||
(void*) &instance.config.modules.diskIo,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* E[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* F[] = {
|
||||
(void*) &instance.config.modules.font,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* G[] = {
|
||||
(void*) &instance.config.modules.gamepad,
|
||||
(void*) &instance.config.modules.gpu,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* H[] = {
|
||||
(void*) &instance.config.modules.host,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* I[] = {
|
||||
(void*) &instance.config.modules.icons,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* J[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* K[] = {
|
||||
(void*) &instance.config.modules.kernel,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* L[] = {
|
||||
(void*) &instance.config.modules.lm,
|
||||
(void*) &instance.config.modules.locale,
|
||||
(void*) &instance.config.modules.localIP,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* M[] = {
|
||||
(void*) &instance.config.modules.media,
|
||||
(void*) &instance.config.modules.memory,
|
||||
(void*) &instance.config.modules.monitor,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* N[] = {
|
||||
(void*) &instance.config.modules.netIo,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* O[] = {
|
||||
(void*) &instance.config.modules.openCL,
|
||||
(void*) &instance.config.modules.openGL,
|
||||
(void*) &instance.config.modules.os,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* P[] = {
|
||||
(void*) &instance.config.modules.packages,
|
||||
(void*) &instance.config.modules.player,
|
||||
(void*) &instance.config.modules.powerAdapter,
|
||||
(void*) &instance.config.modules.processes,
|
||||
(void*) &instance.config.modules.publicIP,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Q[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* R[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* S[] = {
|
||||
(void*) &instance.config.modules.separator,
|
||||
(void*) &instance.config.modules.shell,
|
||||
(void*) &instance.config.modules.sound,
|
||||
(void*) &instance.config.modules.swap,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* T[] = {
|
||||
(void*) &instance.config.modules.terminal,
|
||||
(void*) &instance.config.modules.terminalFont,
|
||||
(void*) &instance.config.modules.terminalSize,
|
||||
(void*) &instance.config.modules.title,
|
||||
(void*) &instance.config.modules.theme,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* U[] = {
|
||||
(void*) &instance.config.modules.uptime,
|
||||
(void*) &instance.config.modules.users,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* V[] = {
|
||||
(void*) &instance.config.modules.version,
|
||||
(void*) &instance.config.modules.vulkan,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* W[] = {
|
||||
(void*) &instance.config.modules.wallpaper,
|
||||
(void*) &instance.config.modules.weather,
|
||||
(void*) &instance.config.modules.wm,
|
||||
(void*) &instance.config.modules.wifi,
|
||||
(void*) &instance.config.modules.wmTheme,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* X[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Y[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Z[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
FFModuleBaseInfo** ffModuleInfos[] = {
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "netif.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#define IF_NAMESIZE 16
|
||||
#endif
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex);
|
||||
enum { IF_INDEX_UNINITIALIZED = (uint32_t) -1, IF_INDEX_INVALID = (uint32_t) -2 };
|
||||
static uint32_t ifIndex = IF_INDEX_UNINITIALIZED;
|
||||
static char ifName[IF_NAMESIZE + 1];
|
||||
|
||||
static inline void init()
|
||||
{
|
||||
if (ifIndex == (uint32_t) IF_INDEX_UNINITIALIZED && !ffNetifGetDefaultRouteImpl(ifName, &ifIndex))
|
||||
ifIndex = (uint32_t) IF_INDEX_INVALID;
|
||||
}
|
||||
|
||||
const char* ffNetifGetDefaultRouteIfName()
|
||||
{
|
||||
init();
|
||||
return ifName;
|
||||
}
|
||||
|
||||
uint32_t ffNetifGetDefaultRouteIfIndex()
|
||||
{
|
||||
init();
|
||||
return ifIndex;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
const char* ffNetifGetDefaultRouteIfName();
|
||||
#endif
|
||||
|
||||
uint32_t ffNetifGetDefaultRouteIfIndex();
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "netif.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||
#elif defined(__NetBSD__)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
|
||||
#elif defined(__FreeBSD__)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||
#elif defined(__OpenBSD__)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||
#else
|
||||
# error unknown platform
|
||||
#endif
|
||||
|
||||
static struct sockaddr *
|
||||
get_rt_address(struct rt_msghdr *rtm, int desired)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
|
||||
|
||||
for (int i = 0; i < RTAX_MAX; i++)
|
||||
{
|
||||
if (rtm->rtm_addrs & (1 << i))
|
||||
{
|
||||
if ((1 <<i ) == desired)
|
||||
return sa;
|
||||
sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
|
||||
|
||||
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
|
||||
if (pfRoute < 0)
|
||||
return false;
|
||||
|
||||
{
|
||||
struct timeval timeout = {1, 0};
|
||||
setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
|
||||
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
|
||||
}
|
||||
|
||||
int pid = getpid();
|
||||
|
||||
struct {
|
||||
struct rt_msghdr hdr;
|
||||
struct sockaddr_in dst;
|
||||
uint8_t data[512];
|
||||
} rtmsg = {
|
||||
.hdr = {
|
||||
.rtm_type = RTM_GET,
|
||||
.rtm_flags = RTF_UP | RTF_GATEWAY,
|
||||
.rtm_version = RTM_VERSION,
|
||||
.rtm_addrs = RTA_DST | RTA_IFP,
|
||||
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
|
||||
.rtm_pid = pid,
|
||||
.rtm_seq = 1,
|
||||
},
|
||||
.dst = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_len = sizeof(rtmsg.dst),
|
||||
},
|
||||
};
|
||||
|
||||
if (write(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen) != rtmsg.hdr.rtm_msglen)
|
||||
return false;
|
||||
|
||||
while (read(pfRoute, &rtmsg, sizeof(rtmsg)) > 0)
|
||||
{
|
||||
if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid)
|
||||
{
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
|
||||
if (sdl)
|
||||
{
|
||||
assert(sdl->sdl_nlen <= IF_NAMESIZE);
|
||||
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
|
||||
iface[sdl->sdl_nlen] = '\0';
|
||||
*ifIndex = sdl->sdl_index;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "netif.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <net/if.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r");
|
||||
if (!netRoute) return false;
|
||||
|
||||
// skip first line
|
||||
flockfile(netRoute);
|
||||
while (getc_unlocked(netRoute) != '\n');
|
||||
funlockfile(netRoute);
|
||||
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
|
||||
|
||||
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
|
||||
{
|
||||
if (destination != 0) continue;
|
||||
*ifIndex = if_nametoindex(iface);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "netif.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <iphlpapi.h>
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(FF_MAYBE_UNUSED char* iface/* unsupported */, uint32_t* ifIndex)
|
||||
{
|
||||
ULONG size = 0;
|
||||
if (GetIpForwardTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER)
|
||||
return false;
|
||||
|
||||
FF_AUTO_FREE MIB_IPFORWARDTABLE* pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(size);
|
||||
if (GetIpForwardTable(pIpForwardTable, &size, TRUE) != ERROR_SUCCESS)
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < pIpForwardTable->dwNumEntries; ++i)
|
||||
{
|
||||
MIB_IPFORWARDROW* ipForwardRow = &pIpForwardTable->table[i];
|
||||
if (ipForwardRow->dwForwardDest == 0 && ipForwardRow->dwForwardMask == 0)
|
||||
{
|
||||
*ifIndex = ipForwardRow->dwForwardIfIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return -1;
|
||||
|
||||
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
FFstrbuf command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(sockfd, command.chars, command.length, 0) == -1)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
|
||||
if(sockfd > 0)
|
||||
return ffNetworkingRecvHttpResponse(sockfd, buffer);
|
||||
return false;
|
||||
}
|
||||
+29
-7
@@ -1,12 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_networking
|
||||
#define FF_INCLUDED_common_networking
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
|
||||
bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer);
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <minwindef.h>
|
||||
#endif
|
||||
|
||||
typedef struct FFNetworkingState {
|
||||
#ifdef _WIN32
|
||||
uintptr_t sockfd;
|
||||
OVERLAPPED overlapped;
|
||||
#else
|
||||
int sockfd;
|
||||
FFstrbuf host;
|
||||
FFstrbuf command;
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
FFThreadType thread;
|
||||
#endif
|
||||
#endif
|
||||
} FFNetworkingState;
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
|
||||
|
||||
static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
FFNetworkingState state;
|
||||
if(ffNetworkingSendHttpRequest(&state, host, path, headers))
|
||||
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
static void connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
|
||||
goto error;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||
{
|
||||
close(state->sockfd);
|
||||
goto error;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
state->sockfd = -1;
|
||||
|
||||
exit:
|
||||
ffStrbufDestroy(&state->host);
|
||||
ffStrbufDestroy(&state->command);
|
||||
}
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
ffStrbufInitS(&state->host, host);
|
||||
|
||||
ffStrbufInitA(&state->command, 64);
|
||||
ffStrbufAppendS(&state->command, "GET ");
|
||||
ffStrbufAppendS(&state->command, path);
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&state->command, host);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
ffStrbufAppendS(&state->command, headers);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||
return !!state->thread;
|
||||
#else
|
||||
connectAndSend(state);
|
||||
return state->sockfd != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
if (!ffThreadJoin(state->thread, timeout))
|
||||
return false;
|
||||
#endif
|
||||
if(state->sockfd == -1)
|
||||
return false;
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = timeout / 1000;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
close(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
//Must be included after <mswsock.h>
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
static LPFN_CONNECTEX ConnectEx;
|
||||
|
||||
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
|
||||
{
|
||||
(void)once;
|
||||
(void)param;
|
||||
static WSADATA wsaData;
|
||||
*context = &wsaData;
|
||||
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
return FALSE;
|
||||
|
||||
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
|
||||
return FALSE;
|
||||
|
||||
//Dummy socket needed for WSAIoctl
|
||||
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
return FALSE;
|
||||
|
||||
DWORD dwBytes;
|
||||
GUID guid = WSAID_CONNECTEX;
|
||||
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||
&guid, sizeof(guid),
|
||||
&ConnectEx, sizeof(ConnectEx),
|
||||
&dwBytes, NULL, NULL) != 0)
|
||||
return FALSE;
|
||||
|
||||
return closesocket(sockfd) == 0;
|
||||
}
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
|
||||
WSADATA* pData;
|
||||
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
|
||||
return false;
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return false;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
//ConnectEx requires the socket to be initially bound
|
||||
struct sockaddr_in addr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
.sin_port = 0,
|
||||
};
|
||||
if(bind(state->sockfd, (SOCKADDR *)&addr, sizeof(addr)) != 0)
|
||||
{
|
||||
printf("bind %d\n", WSAGetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped);
|
||||
freeaddrinfo(addr);
|
||||
|
||||
if(!result && WSAGetLastError() != WSA_IO_PENDING)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
DWORD transfer, flags;
|
||||
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
closesocket(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "common/option.h"
|
||||
#include "common/color.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise
|
||||
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
|
||||
{
|
||||
const char* subKey = argumentKey;
|
||||
if(!(subKey[0] == '-' && subKey[1] == '-'))
|
||||
return NULL;
|
||||
|
||||
subKey += 2;
|
||||
uint32_t moduleNameLen = (uint32_t)strlen(moduleName);
|
||||
if(strncasecmp(subKey, moduleName, moduleNameLen) != 0)
|
||||
return NULL;
|
||||
|
||||
subKey += moduleNameLen;
|
||||
|
||||
if(subKey[0] == '\0')
|
||||
return subKey;
|
||||
|
||||
if(subKey[0] != '-')
|
||||
return NULL;
|
||||
|
||||
subKey += 1;
|
||||
|
||||
return subKey;
|
||||
}
|
||||
|
||||
bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const char* value, FFModuleArgs* result)
|
||||
{
|
||||
if(ffStrEqualsIgnCase(subKey, "key"))
|
||||
{
|
||||
ffOptionParseString(argumentKey, value, &result->key);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "format"))
|
||||
{
|
||||
ffOptionParseString(argumentKey, value, &result->outputFormat);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "key-color"))
|
||||
{
|
||||
if(value == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
|
||||
exit(477);
|
||||
}
|
||||
ffOptionParseColor(value, &result->keyColor);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "key-width"))
|
||||
{
|
||||
result->keyWidth = ffOptionParseUInt32(argumentKey, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer)
|
||||
{
|
||||
if(value == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
|
||||
exit(477);
|
||||
}
|
||||
|
||||
ffStrbufSetS(buffer, value);
|
||||
}
|
||||
|
||||
uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value)
|
||||
{
|
||||
if(value == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||
exit(480);
|
||||
}
|
||||
|
||||
char* end;
|
||||
uint32_t num = (uint32_t) strtoul(value, &end, 10);
|
||||
if(*end != '\0')
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||
exit(479);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int32_t ffOptionParseInt32(const char* argumentKey, const char* value)
|
||||
{
|
||||
if(value == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||
exit(480);
|
||||
}
|
||||
|
||||
char* end;
|
||||
int32_t num = (int32_t) strtol(value, &end, 10);
|
||||
if(*end != '\0')
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||
exit(479);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[])
|
||||
{
|
||||
if(requestedKey == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <value>\n", argumentKey);
|
||||
exit(476);
|
||||
}
|
||||
|
||||
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
|
||||
{
|
||||
if(ffStrEqualsIgnCase(requestedKey, pPair->key))
|
||||
return pPair->value;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey);
|
||||
exit(478);
|
||||
}
|
||||
|
||||
bool ffOptionParseBoolean(const char* str)
|
||||
{
|
||||
return (
|
||||
!ffStrSet(str) ||
|
||||
ffStrEqualsIgnCase(str, "true") ||
|
||||
ffStrEqualsIgnCase(str, "yes") ||
|
||||
ffStrEqualsIgnCase(str, "on") ||
|
||||
ffStrEqualsIgnCase(str, "1")
|
||||
);
|
||||
}
|
||||
|
||||
void ffOptionParseColor(const char* value, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufClear(buffer);
|
||||
ffStrbufEnsureFree(buffer, 63);
|
||||
|
||||
while(*value != '\0')
|
||||
{
|
||||
#define FF_APPEND_COLOR_CODE_COND(prefix, code) \
|
||||
if(strncasecmp(value, #prefix, strlen(#prefix)) == 0) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); }
|
||||
|
||||
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
|
||||
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
|
||||
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
|
||||
else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
|
||||
else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
|
||||
else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
|
||||
else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW)
|
||||
else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE)
|
||||
else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA)
|
||||
else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN)
|
||||
else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE)
|
||||
else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN)
|
||||
else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE)
|
||||
else
|
||||
{
|
||||
ffStrbufAppendC(buffer, *value);
|
||||
++value;
|
||||
}
|
||||
|
||||
#undef FF_APPEND_COLOR_CODE_COND
|
||||
}
|
||||
}
|
||||
|
||||
void ffOptionInitModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufInit(&args->key);
|
||||
ffStrbufInit(&args->keyColor);
|
||||
ffStrbufInit(&args->outputFormat);
|
||||
args->keyWidth = 0;
|
||||
}
|
||||
|
||||
void ffOptionDestroyModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufDestroy(&args->key);
|
||||
ffStrbufDestroy(&args->keyColor);
|
||||
ffStrbufDestroy(&args->outputFormat);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
struct yyjson_val;
|
||||
struct yyjson_mut_doc;
|
||||
struct yyjson_mut_val;
|
||||
|
||||
// Must be the first field of FFModuleOptions
|
||||
typedef struct FFModuleBaseInfo
|
||||
{
|
||||
const char* name;
|
||||
const char* description;
|
||||
// A dirty polymorphic implementation in C.
|
||||
// This is UB, because `void*` is not compatible with `FF*Options*`.
|
||||
// However we can't do it better unless we move to C++, so that `option` becomes a `this` pointer
|
||||
// https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type
|
||||
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
|
||||
void (*parseJsonObject)(void* options, struct yyjson_val *module);
|
||||
void (*printModule)(void* options);
|
||||
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
||||
void (*printHelpFormat)(void);
|
||||
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
|
||||
} FFModuleBaseInfo;
|
||||
|
||||
static inline void ffOptionInitModuleBaseInfo(
|
||||
FFModuleBaseInfo* baseInfo,
|
||||
const char* name,
|
||||
const char* description,
|
||||
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
|
||||
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
|
||||
void* printModule, // void (*const printModule)(void* options)
|
||||
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
void (*printHelpFormat)(void),
|
||||
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
)
|
||||
{
|
||||
baseInfo->name = name;
|
||||
baseInfo->description = description;
|
||||
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
||||
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
||||
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
||||
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
|
||||
baseInfo->printHelpFormat = printHelpFormat;
|
||||
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
|
||||
}
|
||||
|
||||
typedef struct FFModuleArgs
|
||||
{
|
||||
FFstrbuf key;
|
||||
FFstrbuf keyColor;
|
||||
FFstrbuf outputFormat;
|
||||
uint32_t keyWidth;
|
||||
} FFModuleArgs;
|
||||
|
||||
typedef struct FFKeyValuePair
|
||||
{
|
||||
const char* key;
|
||||
int value;
|
||||
} FFKeyValuePair;
|
||||
|
||||
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName);
|
||||
bool ffOptionParseModuleArgs(const char* argumentKey, const char* pkey, const char* value, FFModuleArgs* result);
|
||||
void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer);
|
||||
FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value);
|
||||
FF_C_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value);
|
||||
FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]);
|
||||
FF_C_NODISCARD bool ffOptionParseBoolean(const char* str);
|
||||
void ffOptionParseColor(const char* value, FFstrbuf* buffer);
|
||||
void ffOptionInitModuleArg(FFModuleArgs* args);
|
||||
void ffOptionDestroyModuleArg(FFModuleArgs* args);
|
||||
+45
-25
@@ -1,18 +1,13 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/parsing.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool ffStrSet(const char* str)
|
||||
{
|
||||
if(str == NULL)
|
||||
return false;
|
||||
|
||||
while(isspace(*str))
|
||||
str++;
|
||||
|
||||
return *str != '\0';
|
||||
}
|
||||
#ifdef _WIN32
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
#endif
|
||||
|
||||
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch)
|
||||
{
|
||||
@@ -65,12 +60,12 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty)
|
||||
ffStrbufAppendF(pretty, ".%u", version->patch);
|
||||
}
|
||||
|
||||
static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t prefixesLength, const char** prefixes)
|
||||
static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const char** prefixes)
|
||||
{
|
||||
long double size = (long double) bytes;
|
||||
double size = (double) bytes;
|
||||
uint8_t counter = 0;
|
||||
|
||||
while(size > base && counter < prefixesLength - 1)
|
||||
while(size >= base && counter < instance.config.display.sizeMaxPrefix && prefixes[counter + 1])
|
||||
{
|
||||
size /= base;
|
||||
counter++;
|
||||
@@ -78,22 +73,43 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t p
|
||||
|
||||
if(counter == 0)
|
||||
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
|
||||
else if(counter < 3 || (counter == 3 && size < 100.0))
|
||||
ffStrbufAppendF(result, "%.2Lf %s", size, prefixes[counter]);
|
||||
else
|
||||
ffStrbufAppendF(result, "%.0Lf %s", size, prefixes[counter]);
|
||||
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
|
||||
}
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result)
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||
{
|
||||
if(binaryPrefix == FF_BINARY_PREFIX_TYPE_IEC)
|
||||
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB"});
|
||||
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_SI)
|
||||
parseSize(result, bytes, 1000, 5, (const char*[]) {"B", "kB", "MB", "GB", "TB"});
|
||||
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_JEDEC)
|
||||
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KB", "MB", "GB", "TB"});
|
||||
else
|
||||
parseSize(result, bytes, 1024, 1, (const char*[]) {"B"});
|
||||
switch (instance.config.display.binaryPrefixType)
|
||||
{
|
||||
case FF_BINARY_PREFIX_TYPE_IEC:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_SI:
|
||||
parseSize(result, bytes, 1000, (const char*[]) {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL});
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_JEDEC:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KB", "MB", "GB", "TB", NULL});
|
||||
break;
|
||||
default:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", NULL});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ffParseTemperature(double celsius, FFstrbuf* buffer)
|
||||
{
|
||||
switch (instance.config.display.temperatureUnit)
|
||||
{
|
||||
case FF_TEMPERATURE_UNIT_CELSIUS:
|
||||
ffStrbufAppendF(buffer, "%.1f°C", celsius);
|
||||
break;
|
||||
case FF_TEMPERATURE_UNIT_FAHRENHEIT:
|
||||
ffStrbufAppendF(buffer, "%.1f°F", celsius * 1.8 + 32);
|
||||
break;
|
||||
case FF_TEMPERATURE_UNIT_KELVIN:
|
||||
ffStrbufAppendF(buffer, "%.1f K", celsius + 273.15);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
|
||||
@@ -175,3 +191,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
|
||||
ffStrbufAppendS(buffer, " [GTK4]");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_parsing_h
|
||||
#define FF_INCLUDED_parsing_h
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -14,13 +13,11 @@ typedef struct FFVersion
|
||||
|
||||
#define FF_VERSION_INIT ((FFVersion) {0})
|
||||
|
||||
bool ffStrSet(const char* str);
|
||||
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch);
|
||||
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4);
|
||||
|
||||
void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty);
|
||||
int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result);
|
||||
|
||||
#endif
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result);
|
||||
void ffParseTemperature(double celsius, FFstrbuf* buffer);
|
||||
|
||||
+74
-88
@@ -1,22 +1,33 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "util/textModifier.h"
|
||||
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat)
|
||||
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
|
||||
{
|
||||
ffLogoPrintLine(instance);
|
||||
ffLogoPrintLine();
|
||||
|
||||
//This is used by --set-keyless, in this case we wan't neither the module name nor the separator
|
||||
//This is used by --set-keyless, in this case we want neither the module name nor the separator
|
||||
if(moduleName == NULL)
|
||||
return;
|
||||
|
||||
if(!instance->config.pipe)
|
||||
//This is used as a magic value for hiding keys
|
||||
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
|
||||
return;
|
||||
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
||||
ffPrintColor(&instance->config.colorKeys);
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
if (instance.config.display.brightColor)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
||||
|
||||
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
|
||||
ffPrintColor(&moduleArgs->keyColor);
|
||||
else
|
||||
ffPrintColor(&instance.config.display.colorKeys);
|
||||
}
|
||||
|
||||
//NULL check is required for modules with custom keys, e.g. disk with the folder path
|
||||
if(customKeyFormat == NULL || customKeyFormat->length == 0)
|
||||
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
|
||||
{
|
||||
fputs(moduleName, stdout);
|
||||
|
||||
@@ -25,91 +36,76 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod
|
||||
}
|
||||
else
|
||||
{
|
||||
FFstrbuf key;
|
||||
ffStrbufInit(&key);
|
||||
ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
ffParseFormatString(&key, &moduleArgs->key, 1, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
|
||||
});
|
||||
ffPrintUserString(key.chars);
|
||||
ffStrbufDestroy(&key);
|
||||
ffStrbufWriteTo(&key, stdout);
|
||||
}
|
||||
|
||||
if(!instance->config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
ffStrbufWriteTo(&instance->config.separator, stdout);
|
||||
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
|
||||
|
||||
if(!instance->config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
|
||||
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
||||
{
|
||||
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
|
||||
if (keyWidth > 0)
|
||||
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments)
|
||||
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
FFstrbuf buffer;
|
||||
ffStrbufInitA(&buffer, 256);
|
||||
|
||||
ffParseFormatString(&buffer, format, numArgs, arguments);
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (moduleArgs)
|
||||
ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
|
||||
else
|
||||
ffStrbufAppendS(&buffer, "unknown");
|
||||
|
||||
if(buffer.length > 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat);
|
||||
ffPrintUserString(buffer.chars);
|
||||
putchar('\n');
|
||||
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&buffer);
|
||||
}
|
||||
|
||||
void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments)
|
||||
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
|
||||
{
|
||||
ffPrintFormatString(instance, moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->outputFormat, numArgs, arguments);
|
||||
}
|
||||
|
||||
static void printError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, va_list arguments)
|
||||
{
|
||||
bool hasCustomErrorFormat = customErrorFormat != NULL && customErrorFormat->length > 0;
|
||||
if(!hasCustomErrorFormat && !instance->config.showErrors)
|
||||
if(!instance.config.display.showErrors)
|
||||
return;
|
||||
|
||||
if(hasCustomErrorFormat)
|
||||
{
|
||||
FFstrbuf error;
|
||||
ffStrbufInit(&error);
|
||||
ffStrbufAppendVF(&error, message, arguments);
|
||||
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
|
||||
|
||||
ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, customErrorFormat, 1, (FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &error}
|
||||
});
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
|
||||
|
||||
ffStrbufDestroy(&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat);
|
||||
vprintf(message, arguments);
|
||||
|
||||
if(!instance->config.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
vprintf(message, arguments);
|
||||
|
||||
if(!instance->config.pipe)
|
||||
puts(FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...)
|
||||
void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...)
|
||||
{
|
||||
va_list arguments;
|
||||
va_start(arguments, message);
|
||||
printError(instance, moduleName, moduleIndex, customKeyFormat, customErrorFormat, message, arguments);
|
||||
printError(moduleName, moduleIndex, moduleArgs, printType, message, arguments);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...)
|
||||
void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...)
|
||||
{
|
||||
va_list arguments;
|
||||
va_start(arguments, message);
|
||||
printError(instance, moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->errorFormat, message, arguments);
|
||||
printError(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, message, arguments);
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
@@ -120,44 +116,34 @@ void ffPrintColor(const FFstrbuf* colorValue)
|
||||
if(colorValue->length == 0)
|
||||
return;
|
||||
|
||||
fputs("\033[", stdout);
|
||||
ffStrbufWriteTo(colorValue, stdout);
|
||||
fputc('m', stdout);
|
||||
printf("\e[%sm", colorValue->chars);
|
||||
}
|
||||
|
||||
void ffPrintCharTimes(char c, uint32_t times)
|
||||
{
|
||||
for(uint32_t i = 0; i < times; i++)
|
||||
putchar(c);
|
||||
if(times == 0)
|
||||
return;
|
||||
|
||||
char str[32];
|
||||
memset(str, c, sizeof(str)); //2 instructions when compiling with AVX2 enabled
|
||||
for(uint32_t i = sizeof(str); i <= times; i += (uint32_t)sizeof(str))
|
||||
fwrite(str, 1, sizeof(str), stdout);
|
||||
uint32_t remaining = times % sizeof(str);
|
||||
if(remaining > 0)
|
||||
fwrite(str, 1, remaining, stdout);
|
||||
}
|
||||
|
||||
void ffPrintUserString(const char* value)
|
||||
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
|
||||
{
|
||||
while(*value != '\0')
|
||||
{
|
||||
if(*value != '\\')
|
||||
{
|
||||
putchar(*value);
|
||||
++value;
|
||||
continue;
|
||||
}
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
|
||||
ffStrbufLowerCase(&buffer);
|
||||
printf("--%s-format:\n", buffer.chars);
|
||||
printf("Sets the format string for %s output.\n", name);
|
||||
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
|
||||
puts("The following values are passed:");
|
||||
|
||||
++value;
|
||||
for(unsigned i = 0; i < numArgs; i++)
|
||||
printf(" {%u}: %s\n", i + 1, args[i]);
|
||||
|
||||
if(*value == 'n')
|
||||
putchar('\n');
|
||||
else if(*value == 't')
|
||||
putchar('\t');
|
||||
else if(*value == 'e')
|
||||
putchar('\e');
|
||||
else if(*value == '\\')
|
||||
putchar('\\');
|
||||
else
|
||||
{
|
||||
putchar('\\');
|
||||
putchar(*value);
|
||||
}
|
||||
|
||||
++value;
|
||||
}
|
||||
printf("The default is something similar to \"%s\".\n", def);
|
||||
}
|
||||
|
||||
+17
-10
@@ -1,18 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_printing
|
||||
#define FF_INCLUDED_common_printing
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat);
|
||||
void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments);
|
||||
FF_C_PRINTF(6, 7) void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
FF_C_PRINTF(5, 6) void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
typedef enum FFPrintType {
|
||||
FF_PRINT_TYPE_DEFAULT = 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
|
||||
} FFPrintType;
|
||||
|
||||
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
|
||||
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
|
||||
static inline void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
ffPrintFormatString(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, numArgs, arguments);
|
||||
}
|
||||
FF_C_PRINTF(5, 6) void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
|
||||
FF_C_PRINTF(4, 5) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
void ffPrintUserString(const char* str);
|
||||
|
||||
#endif
|
||||
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
|
||||
|
||||
+22
-5
@@ -1,10 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_processing
|
||||
#define FF_INCLUDED_common_processing
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr);
|
||||
|
||||
#endif
|
||||
static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
const char* error = ffProcessAppendOutput(buffer, argv, false);
|
||||
if (!error)
|
||||
{
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
const char* error = ffProcessAppendOutput(buffer, argv, true);
|
||||
if (!error)
|
||||
{
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,96 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/io.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/time.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
static inline void waitpid_wrapper(const pid_t* pid)
|
||||
{
|
||||
// remove zombie processes
|
||||
if (*pid > 0)
|
||||
waitpid(*pid, NULL, 0);
|
||||
}
|
||||
|
||||
static inline int ffPipe2(int *fds, int flags)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if(pipe(fds) == -1)
|
||||
return -1;
|
||||
fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags);
|
||||
fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | flags);
|
||||
return 0;
|
||||
#else
|
||||
return pipe2(fds, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||
{
|
||||
int pipes[2];
|
||||
const int timeout = instance.config.general.processingTimeout;
|
||||
|
||||
if(pipe(pipes) == -1)
|
||||
if(ffPipe2(pipes, O_CLOEXEC) == -1)
|
||||
return "pipe() failed";
|
||||
|
||||
pid_t childPid = fork();
|
||||
__attribute__((__cleanup__(waitpid_wrapper))) pid_t childPid = fork();
|
||||
if(childPid == -1)
|
||||
{
|
||||
close(pipes[0]);
|
||||
close(pipes[1]);
|
||||
return "fork() failed";
|
||||
}
|
||||
|
||||
//Child
|
||||
if(childPid == 0)
|
||||
{
|
||||
dup2(pipes[1], STDOUT_FILENO);
|
||||
close(pipes[0]);
|
||||
close(pipes[1]);
|
||||
close(STDERR_FILENO);
|
||||
int nullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
|
||||
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
||||
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||
setenv("LANG", "C", 1);
|
||||
execvp(argv[0], argv);
|
||||
exit(901);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
//Parent
|
||||
close(pipes[1]);
|
||||
waitpid(childPid, NULL, 0);
|
||||
ffAppendFDBuffer(pipes[0], buffer);
|
||||
close(pipes[0]);
|
||||
|
||||
return NULL;
|
||||
int FF_AUTO_CLOSE_FD childPipeFd = pipes[0];
|
||||
char str[FF_PIPE_BUFSIZ];
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
{
|
||||
struct pollfd pollfd = { childPipeFd, POLLIN, 0 };
|
||||
if (poll(&pollfd, 1, timeout) == 0)
|
||||
{
|
||||
kill(childPid, SIGTERM);
|
||||
return "poll(&pollfd, 1, timeout) timeout";
|
||||
}
|
||||
else if (pollfd.revents & POLLERR)
|
||||
{
|
||||
kill(childPid, SIGTERM);
|
||||
return "poll(&pollfd, 1, timeout) error";
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t nRead = read(childPipeFd, str, FF_PIPE_BUFSIZ);
|
||||
if (nRead > 0)
|
||||
ffStrbufAppendNS(buffer, (uint32_t) nRead, str);
|
||||
else if (nRead == 0)
|
||||
return NULL;
|
||||
else if (nRead < 0)
|
||||
break;
|
||||
};
|
||||
|
||||
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
|
||||
}
|
||||
|
||||
+105
-47
@@ -1,69 +1,127 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
//We can't use this native version yet because we still use POSIX path ( eg /usr/bin/fish ) at a lot of places.
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||
{
|
||||
SECURITY_ATTRIBUTES saAttr = {
|
||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||
.lpSecurityDescriptor = NULL,
|
||||
.bInheritHandle = TRUE,
|
||||
};
|
||||
int timeout = instance.config.general.processingTimeout;
|
||||
|
||||
HANDLE hChildStdoutRead, hChildStdoutWrite;
|
||||
if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0))
|
||||
return "CreatePipe() failed";
|
||||
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
|
||||
L"\\\\.\\pipe\\LOCAL\\",
|
||||
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | (timeout < 0 ? 0 : FILE_FLAG_OVERLAPPED),
|
||||
0,
|
||||
1,
|
||||
FF_PIPE_BUFSIZ,
|
||||
FF_PIPE_BUFSIZ,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
if (hChildPipeRead == INVALID_HANDLE_VALUE)
|
||||
return "CreateNamedPipeW(L\"\\\\.\\pipe\\LOCAL\\\") failed";
|
||||
|
||||
if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0))
|
||||
return "SetHandleInformation(hChildStdoutRead) failed";
|
||||
HANDLE hChildPipeWrite = CreateFileW(
|
||||
L"\\\\.\\pipe\\LOCAL\\",
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
&(SECURITY_ATTRIBUTES){
|
||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||
.lpSecurityDescriptor = NULL,
|
||||
.bInheritHandle = TRUE,
|
||||
},
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
if (hChildPipeWrite == INVALID_HANDLE_VALUE)
|
||||
return "CreateFileW(L\"\\\\.\\pipe\\LOCAL\\\") failed";
|
||||
|
||||
PROCESS_INFORMATION piProcInfo = {0};
|
||||
STARTUPINFOA siStartInfo = {
|
||||
.cb = sizeof(siStartInfo),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
.hStdOutput = hChildStdoutWrite,
|
||||
};
|
||||
|
||||
FFstrbuf cmdline;
|
||||
ffStrbufInit(&cmdline);
|
||||
for(char* const* parg = argv; *parg; ++parg)
|
||||
BOOL success;
|
||||
|
||||
{
|
||||
if(cmdline.length > 0)
|
||||
STARTUPINFOA siStartInfo = {
|
||||
.cb = sizeof(siStartInfo),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
};
|
||||
if (useStdErr)
|
||||
siStartInfo.hStdError = hChildPipeWrite;
|
||||
else
|
||||
siStartInfo.hStdOutput = hChildPipeWrite;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]);
|
||||
for(char* const* parg = &argv[1]; *parg; ++parg)
|
||||
{
|
||||
ffStrbufAppendC(&cmdline, ' ');
|
||||
ffStrbufAppendF(&cmdline, "\"%s\"", * parg);
|
||||
ffStrbufAppendS(&cmdline, *parg);
|
||||
}
|
||||
|
||||
success = CreateProcessA(
|
||||
NULL, // application name
|
||||
cmdline.chars, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo // receives PROCESS_INFORMATION
|
||||
);
|
||||
}
|
||||
|
||||
BOOL success = CreateProcessA(
|
||||
NULL, // application name
|
||||
cmdline.chars, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
|
||||
CloseHandle(hChildStdoutWrite);
|
||||
CloseHandle(hChildPipeWrite);
|
||||
if(!success)
|
||||
{
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return "CreateProcessA() failed";
|
||||
}
|
||||
|
||||
char str[128];
|
||||
DWORD nRead;
|
||||
while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0)
|
||||
FF_AUTO_CLOSE_FD HANDLE hProcess = piProcInfo.hProcess;
|
||||
FF_MAYBE_UNUSED FF_AUTO_CLOSE_FD HANDLE hThread = piProcInfo.hThread;
|
||||
|
||||
char str[FF_PIPE_BUFSIZ];
|
||||
DWORD nRead = 0;
|
||||
FF_AUTO_CLOSE_FD HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
OVERLAPPED overlapped = { .hEvent = hEvent };
|
||||
// ReadFile always completes synchronously if the pipe is not created with FILE_FLAG_OVERLAPPED
|
||||
do
|
||||
{
|
||||
ffStrbufAppendNS(buffer, nRead, str);
|
||||
if(nRead < sizeof(str))
|
||||
break;
|
||||
}
|
||||
if (!ReadFile(hChildPipeRead, str, sizeof(str), &nRead, &overlapped))
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_IO_PENDING:
|
||||
if (!timeout || WaitForSingleObject(hEvent, (DWORD) timeout) != WAIT_OBJECT_0)
|
||||
{
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "WaitForSingleObject(hEvent) failed or timeout";
|
||||
}
|
||||
|
||||
if (!GetOverlappedResult(hChildPipeRead, &overlapped, &nRead, FALSE))
|
||||
{
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
||||
return NULL;
|
||||
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "GetOverlappedResult(hChildPipeRead) failed";
|
||||
}
|
||||
break;
|
||||
|
||||
case ERROR_BROKEN_PIPE:
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
CancelIo(hChildPipeRead);
|
||||
TerminateProcess(hProcess, 1);
|
||||
return "ReadFile(hChildPipeRead) failed";
|
||||
}
|
||||
}
|
||||
ffStrbufAppendNS(buffer, nRead, str);
|
||||
} while (nRead > 0);
|
||||
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+12
-36
@@ -2,6 +2,9 @@
|
||||
#include "common/properties.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef _WIN32
|
||||
#include "util/windows/getline.h"
|
||||
#endif
|
||||
|
||||
static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
@@ -88,7 +91,7 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
|
||||
|
||||
// The following functions return true if the file was found, independently if start was found
|
||||
// Buffers which already contain content are not overwritten
|
||||
// The last occurence of start in the first file will be the one used
|
||||
// The last occurrence of start in the first file will be the one used
|
||||
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
@@ -141,42 +144,22 @@ done:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
|
||||
bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
|
||||
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateF("%s/%s", instance.state.platform.homeDir.chars, relativeFile);
|
||||
return ffParsePropFileValues(absolutePath.chars, numQueries, queries);
|
||||
}
|
||||
|
||||
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
FFstrbuf absolutePath;
|
||||
ffStrbufInitA(&absolutePath, 64);
|
||||
ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir);
|
||||
ffStrbufAppendC(&absolutePath, '/');
|
||||
ffStrbufAppendS(&absolutePath, relativeFile);
|
||||
|
||||
bool result = ffParsePropFileValues(absolutePath.chars, numQueries, queries);
|
||||
|
||||
ffStrbufDestroy(&absolutePath);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
bool foundAFile = false;
|
||||
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
|
||||
|
||||
for(uint32_t i = 0; i < instance->state.configDirs.length; i++)
|
||||
FF_LIST_FOR_EACH(FFstrbuf, dirPrefix, *list)
|
||||
{
|
||||
//We need to copy the config dir each time, because it used by multiple threads, so we can't directly write to it.
|
||||
ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i));
|
||||
//We need to copy the dir each time, because it used by multiple threads, so we can't directly write to it.
|
||||
ffStrbufSet(&baseDir, dirPrefix);
|
||||
ffStrbufAppendS(&baseDir, relativeFile);
|
||||
|
||||
if(ffParsePropFileValues(baseDir.chars, numQueries, queries))
|
||||
@@ -196,12 +179,5 @@ bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativ
|
||||
break;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&baseDir);
|
||||
|
||||
return foundAFile;
|
||||
}
|
||||
|
||||
bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
+37
-10
@@ -1,9 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_properties
|
||||
#define FF_INCLUDED_common_properties
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFpropquery
|
||||
{
|
||||
@@ -14,10 +11,40 @@ typedef struct FFpropquery
|
||||
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
|
||||
#endif
|
||||
static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileHome(const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileHomeValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileList(const FFlist* list, const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileListValues(list, relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileConfigValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
return ffParsePropFileListValues(&instance.state.platform.configDirs, relativeFile, numQueries, queries);
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileConfig(const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileConfigValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileDataValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
return ffParsePropFileListValues(&instance.state.platform.dataDirs, relativeFile, numQueries, queries);
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFileData(const char* relativeFile, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileDataValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
+109
-50
@@ -1,9 +1,9 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/library.h"
|
||||
#include "common/io.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum FFInitState
|
||||
@@ -15,18 +15,14 @@ typedef enum FFInitState
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
|
||||
static dataObject data; \
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
|
||||
pthread_mutex_lock(&mutex); \
|
||||
if(initState != FF_INITSTATE_UNINITIALIZED) {\
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
|
||||
} \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
|
||||
if(libraryHandle == NULL) { \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
@@ -35,20 +31,17 @@ typedef enum FFInitState
|
||||
if(data.ff ## symbolName == NULL) { \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_RETURN \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return &data;
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_ERROR \
|
||||
{ \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
@@ -57,23 +50,31 @@ typedef enum FFInitState
|
||||
|
||||
typedef struct GVariantGetters
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(g_variant_get_string)
|
||||
FF_LIBRARY_SYMBOL(g_variant_dup_string)
|
||||
FF_LIBRARY_SYMBOL(g_variant_get_boolean)
|
||||
FF_LIBRARY_SYMBOL(g_variant_get_int32)
|
||||
FF_LIBRARY_SYMBOL(g_variant_unref)
|
||||
} GVariantGetters;
|
||||
|
||||
static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters)
|
||||
{
|
||||
FFvariant result;
|
||||
|
||||
if(variant == NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
result = FF_VARIANT_NULL;
|
||||
else if(type == FF_VARIANT_TYPE_STRING)
|
||||
return (FFvariant) {.strValue = variantGetters->ffg_variant_get_string(variant, NULL)};
|
||||
result = (FFvariant) {.strValue = variantGetters->ffg_variant_dup_string(variant, NULL)}; // Dup string, so that variant itself can be freed
|
||||
else if(type == FF_VARIANT_TYPE_BOOL)
|
||||
return (FFvariant) {.boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true};
|
||||
result = (FFvariant) {.boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true};
|
||||
else if(type == FF_VARIANT_TYPE_INT)
|
||||
return (FFvariant) {.intValue = variantGetters->ffg_variant_get_int32(variant)};
|
||||
result = (FFvariant) {.intValue = variantGetters->ffg_variant_get_int32(variant)};
|
||||
else
|
||||
return FF_VARIANT_NULL;
|
||||
result = FF_VARIANT_NULL;
|
||||
|
||||
if(variant)
|
||||
variantGetters->ffg_variant_unref(variant);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct GSettingsData
|
||||
@@ -89,9 +90,9 @@ typedef struct GSettingsData
|
||||
GVariantGetters variantGetters;
|
||||
} GSettingsData;
|
||||
|
||||
static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
static const GSettingsData* getGSettingsData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
|
||||
@@ -102,9 +103,10 @@ static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_get_default)
|
||||
|
||||
#define data data.variantGetters
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref);
|
||||
#undef data
|
||||
|
||||
data.schemaSource = data.ffg_settings_schema_source_get_default();
|
||||
@@ -114,9 +116,9 @@ static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
const GSettingsData* data = getGSettingsData(instance);
|
||||
const GSettingsData* data = getGSettingsData();
|
||||
if(data == NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
@@ -143,9 +145,9 @@ FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaN
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_GIO
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, schemaName, path, key, type)
|
||||
FF_UNUSED(schemaName, path, key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_GIO
|
||||
@@ -161,17 +163,18 @@ typedef struct DConfData
|
||||
DConfClient* client;
|
||||
} DConfData;
|
||||
|
||||
static const DConfData* getDConfData(const FFinstance* instance)
|
||||
static const DConfData* getDConfData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
|
||||
|
||||
#define data data.variantGetters
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref)
|
||||
#undef data
|
||||
|
||||
data.client = data.ffdconf_client_new();
|
||||
@@ -181,9 +184,9 @@ static const DConfData* getDConfData(const FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
|
||||
{
|
||||
const DConfData* data = getDConfData(instance);
|
||||
const DConfData* data = getDConfData();
|
||||
if(data == NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
@@ -199,23 +202,23 @@ FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvari
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_DCONF
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, key, type)
|
||||
FF_UNUSED(key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_DCONF
|
||||
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
{
|
||||
FFvariant gsettings = ffSettingsGetGSettings(instance, gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
|
||||
FFvariant gsettings = ffSettingsGetGSettings(gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
|
||||
|
||||
if(
|
||||
(type == FF_VARIANT_TYPE_BOOL && gsettings.boolValueSet) ||
|
||||
(type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != NULL)
|
||||
) return gsettings;
|
||||
|
||||
return ffSettingsGetDConf(instance, dconfKey, type);
|
||||
return ffSettingsGetDConf(dconfKey, type);
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_XFCONF
|
||||
@@ -231,9 +234,9 @@ typedef struct XFConfData
|
||||
FF_LIBRARY_SYMBOL(xfconf_init)
|
||||
} XFConfData;
|
||||
|
||||
static const XFConfData* getXFConfData(const FFinstance* instance)
|
||||
static const XFConfData* getXFConfData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
|
||||
@@ -248,9 +251,9 @@ static const XFConfData* getXFConfData(const FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
const XFConfData* data = getXFConfData(instance);
|
||||
const XFConfData* data = getXFConfData();
|
||||
if(data == NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
@@ -271,16 +274,15 @@ FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelNam
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#else //FF_HAVE_XFCONF
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, channelName, propertyName, type)
|
||||
FF_UNUSED(channelName, propertyName, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_XFCONF
|
||||
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef struct SQLiteData
|
||||
{
|
||||
@@ -289,31 +291,33 @@ typedef struct SQLiteData
|
||||
FF_LIBRARY_SYMBOL(sqlite3_step)
|
||||
FF_LIBRARY_SYMBOL(sqlite3_data_count)
|
||||
FF_LIBRARY_SYMBOL(sqlite3_column_int)
|
||||
FF_LIBRARY_SYMBOL(sqlite3_column_text)
|
||||
FF_LIBRARY_SYMBOL(sqlite3_finalize)
|
||||
FF_LIBRARY_SYMBOL(sqlite3_close)
|
||||
} SQLiteData;
|
||||
|
||||
static const SQLiteData* getSQLiteData(const FFinstance* instance)
|
||||
static const SQLiteData* getSQLiteData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3.so", 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_step)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_data_count)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_int)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_text)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_finalize)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_close)
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query)
|
||||
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
|
||||
{
|
||||
if(!ffFileExists(dbPath, S_IFREG))
|
||||
if(!ffPathExists(dbPath, FF_PATHTYPE_FILE))
|
||||
return 0;
|
||||
|
||||
const SQLiteData* data = getSQLiteData(instance);
|
||||
const SQLiteData* data = getSQLiteData();
|
||||
if(data == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -342,19 +346,74 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons
|
||||
|
||||
return result;
|
||||
}
|
||||
#else //FF_HAVE_SQLITE3
|
||||
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query)
|
||||
|
||||
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result)
|
||||
{
|
||||
FF_UNUSED(instance, dbPath, query)
|
||||
if(!ffPathExists(dbPath, FF_PATHTYPE_FILE))
|
||||
return false;
|
||||
|
||||
const SQLiteData* data = getSQLiteData();
|
||||
if(data == NULL)
|
||||
return false;
|
||||
|
||||
sqlite3* db;
|
||||
if(data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK)
|
||||
return false;
|
||||
|
||||
sqlite3_stmt* stmt;
|
||||
if(data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK)
|
||||
{
|
||||
data->ffsqlite3_close(db);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1)
|
||||
{
|
||||
data->ffsqlite3_finalize(stmt);
|
||||
data->ffsqlite3_close(db);
|
||||
return false;
|
||||
}
|
||||
|
||||
ffStrbufSetS(result, (const char *) data->ffsqlite3_column_text(stmt, 0));
|
||||
|
||||
data->ffsqlite3_finalize(stmt);
|
||||
data->ffsqlite3_close(db);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else //FF_HAVE_SQLITE3
|
||||
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
|
||||
{
|
||||
FF_UNUSED(dbPath, query)
|
||||
return 0;
|
||||
}
|
||||
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result)
|
||||
{
|
||||
FF_UNUSED(dbPath, query, result)
|
||||
return false;
|
||||
}
|
||||
#endif //FF_HAVE_SQLITE3
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <sys/system_properties.h>
|
||||
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
|
||||
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
|
||||
ffStrbufEnsureFree(result, PROP_VALUE_MAX);
|
||||
result->length += (uint32_t) __system_property_get(propName, result->chars + result->length);
|
||||
int len = __system_property_get(propName, result->chars + result->length);
|
||||
if (len <= 0) return false;
|
||||
result->length += (uint32_t) len;
|
||||
result->chars[result->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
#endif //__ANDROID__
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <kenv.h>
|
||||
bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result)
|
||||
{
|
||||
//https://wiki.ghostbsd.org/index.php/Kenv
|
||||
ffStrbufEnsureFree(result, KENV_MVALLEN);
|
||||
int len = kenv(KENV_GET, propName, result->chars + result->length, KENV_MVALLEN);
|
||||
if (len <= 0) return false;
|
||||
result->length += (uint32_t) len;
|
||||
result->chars[result->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
+9
-11
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_settings
|
||||
#define FF_INCLUDED_common_settings
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef enum FFvarianttype
|
||||
@@ -25,15 +22,16 @@ typedef union FFvariant
|
||||
|
||||
#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL})
|
||||
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
|
||||
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query);
|
||||
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query);
|
||||
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
#endif
|
||||
|
||||
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
#elif defined(__FreeBSD__)
|
||||
bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result);
|
||||
#endif
|
||||
|
||||
+4
-2
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
{
|
||||
size_t neededLength;
|
||||
if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
|
||||
return;
|
||||
return "sysctlbyname() failed";
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
@@ -14,6 +14,8 @@ void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
result->length += (uint32_t) neededLength - 1;
|
||||
|
||||
result->chars[result->length] = '\0';
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue)
|
||||
|
||||
+6
-9
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_sysctl
|
||||
#define FF_INCLUDED_common_sysctl
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
#endif
|
||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
#if defined(_WIN32)
|
||||
#include <handleapi.h>
|
||||
#include <synchapi.h>
|
||||
#include <process.h>
|
||||
#include <processthreadsapi.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
typedef SRWLOCK FFThreadMutex;
|
||||
typedef HANDLE FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); }
|
||||
static inline FFThreadType ffThreadCreate(unsigned (__stdcall* func)(void*), void* data) {
|
||||
return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL);
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static __stdcall unsigned fn ## ThreadMain () { fn(); return 0; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); }
|
||||
static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout)
|
||||
{
|
||||
if (WaitForSingleObject(thread, timeout == 0 ? (DWORD) -1 : timeout) != 0 /*WAIT_OBJECT_0*/)
|
||||
{
|
||||
TerminateThread(thread, (DWORD) -1);
|
||||
CloseHandle(thread);
|
||||
return false;
|
||||
}
|
||||
CloseHandle(thread);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#if __has_include(<pthread_np.h>)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t FFThreadMutex;
|
||||
typedef pthread_t FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
|
||||
static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
|
||||
FFThreadType newThread = 0;
|
||||
pthread_create(&newThread, NULL, func, data);
|
||||
return newThread;
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static void* fn ## ThreadMain () { fn(); return NULL; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
|
||||
static inline bool ffThreadJoin(FFThreadType thread, FF_MAYBE_UNUSED uint32_t timeout)
|
||||
{
|
||||
#if (defined(__linux__) && !defined(__ANDROID__)) || __has_include(<pthread_np.h>)
|
||||
if (timeout > 0)
|
||||
{
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
||||
{
|
||||
ts.tv_sec += ts.tv_sec / 1000;
|
||||
ts.tv_nsec += (ts.tv_nsec % 1000) * 1000000;
|
||||
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
|
||||
{
|
||||
pthread_kill(thread, SIGTERM);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pthread_join(thread, NULL);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#else //FF_HAVE_THREADS
|
||||
#define FF_THREAD_MUTEX_INITIALIZER 0
|
||||
typedef char FFThreadMutex;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType)
|
||||
#endif //FF_HAVE_THREADS
|
||||
+25
-13
@@ -1,35 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_time
|
||||
#define FF_INCLUDED_common_time
|
||||
|
||||
#include <stdint.h>
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
#include <synchapi.h>
|
||||
#include <profileapi.h>
|
||||
#include <sysinfoapi.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static inline uint64_t ffTimeGetTick() //In msec
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
return GetTickCount64();
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
LARGE_INTEGER start;
|
||||
QueryPerformanceCounter(&start);
|
||||
return (uint64_t)(start.QuadPart * 1000 / frequency.QuadPart);
|
||||
#else
|
||||
struct timeval timeNow;
|
||||
gettimeofday(&timeNow, NULL);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000));
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t ffTimeGetNow()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint64_t timeNow;
|
||||
GetSystemTimeAsFileTime((FILETIME*) &timeNow);
|
||||
return (timeNow - 116444736000000000ull) / 10000ull;
|
||||
#else
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_REALTIME, &timeNow);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ffTimeSleep(uint32_t msec)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
SleepEx(msec, TRUE);
|
||||
#else
|
||||
nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Fastfetch system configuration
|
||||
# This file sets the default config for all users of the system.
|
||||
|
||||
# For more information about how configuration files work,
|
||||
# see ~/.config/fastfetch/config.conf, generated during first run.
|
||||
# All options that can be put there (or passed as argument) can be put here too.
|
||||
|
||||
# Use fastfetch --print-config-system > /etc/fastfetch/config.conf
|
||||
# to overwrite this file with the current default file.
|
||||
|
||||
# User config option
|
||||
# Sets if fastfetch should load user provided configuration.
|
||||
# If this is off, fastfetch ignores the user config file and any passed arguments
|
||||
# Must be true or false
|
||||
# Default is true.
|
||||
#--load-user-config true
|
||||
@@ -1,351 +0,0 @@
|
||||
# Fastfetch configuration
|
||||
# Write every argument in different lines.
|
||||
# Direct arguments will overwrite the corresponding ones in this file.
|
||||
# Argument keys are not case sensitive.
|
||||
# Whitespaces are trimmed at the beginning and the end.
|
||||
# Empty lines or lines starting with # are ignored.
|
||||
|
||||
# This file was shipped with $" FASTFETCH_PROJECT_VERSION $".
|
||||
# Use fastfetch --print-config-user > ~/.config/fastfetch/config.conf to overwrite this file with the current defaults
|
||||
|
||||
# Below some often usefull options are listed. Uncomment and modify them so they take affect.
|
||||
# Note that there are a lot more options than the ones listed here, take a look at "fastfetch --help".
|
||||
# Of course all of them can be made persistent here too.
|
||||
|
||||
# Config option:
|
||||
# Load additional config files.
|
||||
# Some are shipped with fastfetch, list them with "fastfetch --list-presets".
|
||||
# Must be a path to a config file or the name of a shipped preset.
|
||||
# The config file is completly loaded before continuing in the current file, so the placement of this option matters, as later options overwrite already set ones.
|
||||
# Can be used multiple times to load multiple config files / presets.
|
||||
#--load-config /path/to/config.txt
|
||||
|
||||
# Structure option:
|
||||
# Sets the modules to use and their order.
|
||||
# Must be a list of module names, separated by colons.
|
||||
# List available modules with "fastfetch --list-modules".
|
||||
# Get the default structure with "fastfetch --print-structure".
|
||||
#--structure $" FASTFETCH_DATATEXT_STRUCTURE $"
|
||||
|
||||
# Multithreading option:
|
||||
# Sets if fastfetch should use multiple threads to detect the values.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--multithreading true
|
||||
|
||||
# Slow operations option:
|
||||
# Sets if fastfetch is allowed to use known slow operations to detect more / better values.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--allow-slow-operations false
|
||||
|
||||
# Linewrap option:
|
||||
# Sets if fastfetch should disable linewrap during the run.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--disable-linewrap true
|
||||
|
||||
# Cursor option:
|
||||
# Sets if fastfetch should hide the console cursor during the run.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--hide-cursor true
|
||||
|
||||
# Logo option:
|
||||
# Sets the logo to use.
|
||||
# List available logos with "fastfetch --list-logos".
|
||||
# Print available logos with "fastfetch --print-logos".
|
||||
# Must be the name of an available logo or a path to a text file containing a custom logo.
|
||||
# Default is the current distribution.
|
||||
#--logo arch
|
||||
|
||||
# Logo type option:
|
||||
# Sets the logo type to use.
|
||||
# Must be auto, builtin, file, raw, sixel, kitty or chafa.
|
||||
# Default is auto.
|
||||
#--logo-type auto
|
||||
|
||||
# Logo width option:
|
||||
# Sets the width of the logo (in characters) if the logo is an image.
|
||||
# Must be a positive integer.
|
||||
# Default is 65.
|
||||
#--logo-width 65
|
||||
|
||||
# Logo height option:
|
||||
# Sets the height of the logo (in characters) if the logo is an image.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (keeps aspect ration).
|
||||
#--logo-height 0
|
||||
|
||||
# Logo color options:
|
||||
# Overwrite a color in the logo. Also works for user provided logos.
|
||||
# In the user logo, they replace $[1-9]. Use $$ to print a single $ sign.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the one specified by the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
# Valid index range is [1-9].
|
||||
#--logo-color-1 red
|
||||
#--logo-color-2 32
|
||||
# [...]
|
||||
#--logo-color-9 yellow
|
||||
|
||||
# Logo padding option:
|
||||
# Adds a padding to the left and the right side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding 0
|
||||
|
||||
# Logo padding left option:
|
||||
# Adds a padding to the left side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding-left 0
|
||||
|
||||
# Logo padding right option:
|
||||
# Adds a padding to the right side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding-right 0
|
||||
|
||||
# Logo print remaining option:
|
||||
# Sets if the remaining logo should be printed, it is has more lines than modules to show.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--logo-print-remaining true
|
||||
|
||||
# Color keys option:
|
||||
# Sets the color of the keys.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the key color of the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
#--color-keys magenta
|
||||
|
||||
# Color title option:
|
||||
# Sets the color of the title.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the title color of the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
#--color-title magenta
|
||||
|
||||
# Binary prefix option:
|
||||
# Sets the binary prefix to use.
|
||||
# Must be a IEC, SI or JEDEC.
|
||||
# Default is IEC.
|
||||
#--binary-prefix IEC
|
||||
|
||||
# Title FQDN option:
|
||||
# Sets if the title should use the fully qualified domain name.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--title-fqdn false
|
||||
|
||||
# Separator option:
|
||||
# Sets the string placed between a key and its value.
|
||||
# Can be any string.
|
||||
# Default is ": ".
|
||||
#--separator ": "
|
||||
|
||||
# Separator string option:
|
||||
# Sets the string printed by the "separator" module (usually between title and rest of output)
|
||||
# Must be any string. It is repated / cut to fit perfectly.
|
||||
# Default is "-"
|
||||
#--separator-string -
|
||||
|
||||
# Public IP URL option:
|
||||
# Sets the URL of public IP detection server to be used.
|
||||
# Only HTTP protocol is supported, and the value should not contain "http://" prefix.
|
||||
# Default is "ipinfo.io/ip".
|
||||
#--public-ip-url "ipinfo.io/ip"
|
||||
|
||||
# Public IP timeout option:
|
||||
# Sets the time to wait for the public ip server to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--public-ip-timeout 0
|
||||
|
||||
# Weather output format option:
|
||||
# Sets the weather format to be used. It must be URI encoded.
|
||||
# See: https://github.com/chubin/wttr.in#one-line-output
|
||||
# Default is "%t+-+%C+(%l)".
|
||||
#--weather-output-format "%t+-+%C+(%l)"
|
||||
|
||||
# Weather timeout option:
|
||||
# Sets the time to wait for the weather server (wttr.in) to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--weather-timeout 0
|
||||
|
||||
# OS file option
|
||||
# Sets the path to the file containing the operating system information.
|
||||
# Should be a valid path to an existing file.
|
||||
# Note that you might need to run fastfetch with --recache once for it to take affect.
|
||||
# Default is /etc/os-release.
|
||||
#--os-file /etc/os-release
|
||||
|
||||
# Player name option
|
||||
# Sets the name of the player. This is also used in song detection
|
||||
# Must be the exact name of the player or a dbus address (e.g. org.mpris.MediaPlayer2.spotify)
|
||||
# Default is the first match starting with org.mpris.MediaPlayer2.
|
||||
#--player-name spotify
|
||||
|
||||
# Escape bedrock option
|
||||
# Sets if fastfetch should escape the bedrock jail, if it detectes that it is running in one
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--escape-bedrock true
|
||||
|
||||
# GL option
|
||||
# Sets with opengl context creation library to use
|
||||
# Must be either auto, egl, glx or osmesa
|
||||
# Default is auto.
|
||||
#--gl auto
|
||||
|
||||
# Key options:
|
||||
# Sets the displayed key of a module
|
||||
# Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help.
|
||||
#--os-key OS
|
||||
#--host-key Host
|
||||
#--kernel-key Kernel
|
||||
#--uptime-key Uptime
|
||||
#--processes-key Processes
|
||||
#--packages-key Packages
|
||||
#--shell-key Shell
|
||||
#--resolution-key Resolution {1}
|
||||
#--de-key DE
|
||||
#--wm-key WM
|
||||
#--wm-theme-key WM Theme
|
||||
#--theme-key Theme
|
||||
#--icons-key Icons
|
||||
#--font-key Font
|
||||
#--cursor-key Cursor
|
||||
#--terminal-key Terminal
|
||||
#--terminal-font-key Terminal Font
|
||||
#--cpu-key CPU
|
||||
#--cpu-usage-key CPU Usage
|
||||
#--gpu-key GPU {1}
|
||||
#--memory-key Memory
|
||||
#--swap-key Swap
|
||||
#--disk-key Disk ({1})
|
||||
#--battery-key Battery {1}
|
||||
#--poweradapter-key Power Adapter {1}
|
||||
#--locale-key Locale
|
||||
#--local-ip-key Local IP ({1})
|
||||
#--public-ip-key Public IP
|
||||
#--weather-key Weather
|
||||
#--player-key Media Player
|
||||
#--song-key Song
|
||||
#--datetime-key Date Time
|
||||
#--vulkan-key Vulkan
|
||||
#--opengl-key OpenGL
|
||||
#--opencl-key OpenCL
|
||||
#--users-key Users
|
||||
|
||||
# Format options:
|
||||
# Sets the format string for module values.
|
||||
# For information on format strings, see "fastfetch --help format".
|
||||
# To see the parameter they take and their default value, see "fastfetch --help *-format", e.g. "fastfetch --help os-format".
|
||||
# An empty format string (As they are currently below) will behave as if it was not set.
|
||||
#--os-format
|
||||
#--host-format
|
||||
#--kernel-format
|
||||
#--uptime-format
|
||||
#--processes-format
|
||||
#--packages-format
|
||||
#--shell-format
|
||||
#--resolution-format
|
||||
#--de-format
|
||||
#--wm-format
|
||||
#--wm-theme-format
|
||||
#--theme-format
|
||||
#--icons-format
|
||||
#--font-format
|
||||
#--cursor-format
|
||||
#--terminal-format
|
||||
#--terminal-font-format
|
||||
#--cpu-format
|
||||
#--cpu-usage-format
|
||||
#--gpu-format
|
||||
#--memory-format
|
||||
#--swap-format
|
||||
#--disk-format
|
||||
#--battery-format
|
||||
#--poweradapter-format
|
||||
#--locale-format
|
||||
#--local-ip-format
|
||||
#--public-ip-format
|
||||
#--weather-format
|
||||
#--player-format
|
||||
#--song-format
|
||||
#--datetime-format
|
||||
#--vulkan-format
|
||||
#--opengl-format
|
||||
#--opencl-format
|
||||
#--users-format
|
||||
|
||||
# Error options:
|
||||
# Sets the format string to use if an error occured
|
||||
# For information on format strings, see "fastfetch --help format".
|
||||
# Each of them take the error as first and only argument.
|
||||
# If one of them is set, the module will appear, even if --show-errors is not given.
|
||||
#--os-error
|
||||
#--host-error
|
||||
#--kernel-error
|
||||
#--uptime-error
|
||||
#--processes-error
|
||||
#--packages-error
|
||||
#--shell-error
|
||||
#--resolution-error
|
||||
#--de-error
|
||||
#--wm-error
|
||||
#--wm-theme-error
|
||||
#--theme-error
|
||||
#--icons-error
|
||||
#--font-error
|
||||
#--cursor-error
|
||||
#--terminal-error
|
||||
#--terminal-font-error
|
||||
#--cpu-error
|
||||
#--cpu-usage-error
|
||||
#--gpu-error
|
||||
#--memory-error
|
||||
#--swap-error
|
||||
#--disk-error
|
||||
#--battery-error
|
||||
#--poweradapter-error
|
||||
#--locale-error
|
||||
#--local-ip-error
|
||||
#--public-ip-error
|
||||
#--weather-error
|
||||
#--player-error
|
||||
#--song-error
|
||||
#--datetime-error
|
||||
#--vulkan-error
|
||||
#--opengl-error
|
||||
#--opencl-error
|
||||
#--users-error
|
||||
|
||||
# Library options:
|
||||
# Sets an user specific path to a library to load.
|
||||
# Must be a valid path to a library.
|
||||
#--lib-PCI /usr/lib/libpci.so
|
||||
#--lib-vulkan /usr/lib/libvulkan.so
|
||||
#--lib-wayland /usr/lib/libwayland-client.so
|
||||
#--lib-xcb-randr /usr/lib/libxcb-randr.so
|
||||
#--lib-xcb /usr/lib/libxcb.so
|
||||
#--lib-Xrandr /usr/lib/libXrandr.so
|
||||
#--lib-X11 /usr/lib/libX11.so
|
||||
#--lib-gio /usr/lib/libgio-2.0.so
|
||||
#--lib-DConf /usr/lib/libdconf.so
|
||||
#--lib-DBus /usr/lib/libdbus-1.so
|
||||
#--lib-XFConf /usr/lib/libxfconf-0.so
|
||||
#--lib-sqlite3 /usr/lib/libsqlite3.so
|
||||
#--lib-rpm /usr/lib/librpm.so
|
||||
#--lib-imagemagick /usr/lib/libMagickCore-7.Q16HDRI.so
|
||||
#--lib-z /usr/lib/libz.so
|
||||
#--lib-chafa /usr/lib/libchafa.so
|
||||
#--lib-egl /usr/lib/libEGL.so
|
||||
#--lib-glx /usr/lib/libGLX.so
|
||||
#--lib-osmesa /usr/lib/libOSMesa.so
|
||||
#--lib-opencl /usr/lib/libOpenCL.so
|
||||
#--lib-cjson /usr/lib/libcjson.so
|
||||
#--lib-freetype /data/data/com.termux/files/usr/lib
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user