1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

Merge branch 'main' into clippy2

This commit is contained in:
Sylvestre Ledru 2023-10-09 15:49:25 +02:00 committed by GitHub
commit b802c8cc3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 83 deletions

View file

@ -82,56 +82,6 @@ jobs:
grep --ignore-case "all deps seem to have been used" udeps.log || { printf "%s\n" "::${fault_type} ::${fault_prefix}: \`cargo udeps\`: style violation (unused dependency found)" ; fault=true ; } grep --ignore-case "all deps seem to have been used" udeps.log || { printf "%s\n" "::${fault_type} ::${fault_prefix}: \`cargo udeps\`: style violation (unused dependency found)" ; fault=true ; }
if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi
fuzz:
name: Run the fuzzers
runs-on: ubuntu-latest
env:
RUN_FOR: 60
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Install `cargo-fuzz`
run: cargo install cargo-fuzz
- uses: Swatinem/rust-cache@v2
- name: Run fuzz_date for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_test for XX seconds
continue-on-error: true
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_expr for XX seconds
continue-on-error: true
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_glob for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_size for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_time for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
doc_warnings: doc_warnings:
name: Documentation/warnings name: Documentation/warnings
runs-on: ${{ matrix.job.os }} runs-on: ${{ matrix.job.os }}

64
.github/workflows/fuzzing.yml vendored Normal file
View file

@ -0,0 +1,64 @@
name: Fuzzing
# spell-checker:ignore fuzzer
on: [push, pull_request]
permissions:
contents: read # to fetch code (actions/checkout)
# End the current execution if there is a new changeset in the PR.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
fuzz:
name: Run the fuzzers
runs-on: ubuntu-latest
env:
RUN_FOR: 60
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Install `cargo-fuzz`
run: cargo install cargo-fuzz
- uses: Swatinem/rust-cache@v2
- name: Run fuzz_date for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_test for XX seconds
continue-on-error: true
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_expr for XX seconds
continue-on-error: true
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_glob for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_size for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0
- name: Run fuzz_parse_time for XX seconds
shell: bash
run: |
## Run it
cd fuzz
cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0

15
Cargo.lock generated
View file

@ -783,25 +783,14 @@ dependencies = [
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.1" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
dependencies = [ dependencies = [
"errno-dragonfly",
"libc", "libc",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "exacl" name = "exacl"
version = "0.11.0" version = "0.11.0"

View file

@ -31,10 +31,12 @@ pub enum AstNode {
operands: OperandsList, operands: OperandsList,
}, },
} }
impl AstNode { impl AstNode {
fn debug_dump(&self) { fn debug_dump(&self) {
self.debug_dump_impl(1); self.debug_dump_impl(1);
} }
fn debug_dump_impl(&self, depth: usize) { fn debug_dump_impl(&self, depth: usize) {
for _ in 0..depth { for _ in 0..depth {
print!("\t",); print!("\t",);
@ -52,7 +54,7 @@ impl AstNode {
operands, operands,
} => { } => {
println!( println!(
"Node( {} ) at #{} (evaluate -> {:?})", "Node( {} ) at #{} ( evaluate -> {:?} )",
op_type, op_type,
token_idx, token_idx,
self.evaluate() self.evaluate()
@ -71,12 +73,14 @@ impl AstNode {
operands, operands,
}) })
} }
fn new_leaf(token_idx: usize, value: &str) -> Box<Self> { fn new_leaf(token_idx: usize, value: &str) -> Box<Self> {
Box::new(Self::Leaf { Box::new(Self::Leaf {
token_idx, token_idx,
value: value.into(), value: value.into(),
}) })
} }
pub fn evaluate(&self) -> Result<String, String> { pub fn evaluate(&self) -> Result<String, String> {
match self { match self {
Self::Leaf { value, .. } => Ok(value.clone()), Self::Leaf { value, .. } => Ok(value.clone()),
@ -154,9 +158,27 @@ impl AstNode {
}, },
} }
} }
pub fn operand_values(&self) -> Result<Vec<String>, String> { pub fn operand_values(&self) -> Result<Vec<String>, String> {
if let Self::Node { operands, .. } = self { if let Self::Node {
operands, op_type, ..
} = self
{
let mut out = Vec::with_capacity(operands.len()); let mut out = Vec::with_capacity(operands.len());
let mut operands = operands.iter();
// check the first value before `|`, stop evaluate and return directly if it is true.
// push dummy to pass the check of `len() == 2`
if op_type == "|" {
if let Some(value) = operands.next() {
let value = value.evaluate()?;
out.push(value.clone());
if value_as_bool(&value) {
out.push(String::from("dummy"));
return Ok(out);
}
}
}
for operand in operands { for operand in operands {
let value = operand.evaluate()?; let value = operand.evaluate()?;
out.push(value); out.push(value);
@ -240,6 +262,7 @@ fn ast_from_rpn(rpn: &mut TokenStack) -> Result<Box<AstNode>, String> {
} }
} }
} }
fn maybe_ast_node( fn maybe_ast_node(
token_idx: usize, token_idx: usize,
op_type: &str, op_type: &str,
@ -503,6 +526,7 @@ fn prefix_operator_substr(values: &[String]) -> String {
fn bool_as_int(b: bool) -> u8 { fn bool_as_int(b: bool) -> u8 {
u8::from(b) u8::from(b)
} }
fn bool_as_string(b: bool) -> String { fn bool_as_string(b: bool) -> String {
if b { if b {
"1".to_string() "1".to_string()
@ -510,6 +534,7 @@ fn bool_as_string(b: bool) -> String {
"0".to_string() "0".to_string()
} }
} }
fn value_as_bool(s: &str) -> bool { fn value_as_bool(s: &str) -> bool {
if s.is_empty() { if s.is_empty() {
return false; return false;

View file

@ -38,6 +38,7 @@ pub enum Token {
value: String, value: String,
}, },
} }
impl Token { impl Token {
fn new_infix_op(v: &str, left_assoc: bool, precedence: u8) -> Self { fn new_infix_op(v: &str, left_assoc: bool, precedence: u8) -> Self {
Self::InfixOp { Self::InfixOp {
@ -46,6 +47,7 @@ impl Token {
value: v.into(), value: v.into(),
} }
} }
fn new_value(v: &str) -> Self { fn new_value(v: &str) -> Self {
Self::Value { value: v.into() } Self::Value { value: v.into() }
} }
@ -56,12 +58,14 @@ impl Token {
_ => false, _ => false,
} }
} }
fn is_a_number(&self) -> bool { fn is_a_number(&self) -> bool {
match self { match self {
Self::Value { value, .. } => value.parse::<BigInt>().is_ok(), Self::Value { value, .. } => value.parse::<BigInt>().is_ok(),
_ => false, _ => false,
} }
} }
fn is_a_close_paren(&self) -> bool { fn is_a_close_paren(&self) -> bool {
matches!(*self, Self::ParClose) matches!(*self, Self::ParClose)
} }

View file

@ -17,23 +17,6 @@ pub enum FieldType {
Charf, Charf,
} }
// #[allow(non_camel_case_types)]
// pub enum FChar {
// d,
// e,
// E,
// i,
// f,
// F,
// g,
// G,
// u,
// x,
// X,
// o
// }
//
// a Sub Tokens' fields are stored // a Sub Tokens' fields are stored
// as a single object so they can be more simply // as a single object so they can be more simply
// passed by ref to num_format in a Sub method // passed by ref to num_format in a Sub method

View file

@ -18,7 +18,6 @@ use std::iter::Peekable;
use std::process::exit; use std::process::exit;
use std::slice::Iter; use std::slice::Iter;
use std::str::Chars; use std::str::Chars;
// use std::collections::HashSet;
use super::num_format::format_field::{FieldType, FormatField}; use super::num_format::format_field::{FieldType, FormatField};
use super::num_format::num_format; use super::num_format::num_format;

View file

@ -123,6 +123,21 @@ fn test_or() {
.args(&["-14", "|", "1"]) .args(&["-14", "|", "1"])
.succeeds() .succeeds()
.stdout_only("-14\n"); .stdout_only("-14\n");
new_ucmd!()
.args(&["1", "|", "a", "/", "5"])
.succeeds()
.stdout_only("1\n");
new_ucmd!()
.args(&["foo", "|", "a", "/", "5"])
.succeeds()
.stdout_only("foo\n");
new_ucmd!()
.args(&["0", "|", "10", "/", "5"])
.succeeds()
.stdout_only("2\n");
} }
#[test] #[test]