Unverified Commit 74bbb9ed authored by Michael Aaron Murphy's avatar Michael Aaron Murphy Committed by GitHub

Update rustfmt (#722)

parent a17abdab
# Introduction
Ion is a modern system shell that features a simple, yet powerful, syntax. It is written entirely
in Rust, which greatly increases the overall quality and security of the shell, eliminating the
possibilities of a [ShellShock](http://www.wikiwand.com/en/Shellshock_(software_bug))-like vulnerability
, and making development easier. It also offers a level of performance that exceeds that of Dash,
when taking advantage of Ion's features. While it is developed alongside, and primarily for, RedoxOS,
it is a fully capable on other \*nix platforms.
in Rust, which greatly increases the overall quality and security of the shell. It also offers a
level of performance that exceeds that of Dash, when taking advantage of Ion's features. While it
is developed alongside, and primarily for, RedoxOS, it is a fully capable on other \*nix platforms.
# Ion Shell
......@@ -37,11 +35,12 @@ We are providing our manual for Ion in the form of a markdown-based book, which
### Code Formatting
When submitting a pull request, be sure to run
`env CFG_RELEASE_CHANNEL=nightly cargo +nightly fmt` on your project with a
nightly version of **rustfmt**. This will prevent me from having to push PR's specifically
to format the code base from time to time. To install **rustfmt-nightly**, simply run
`cargo install rustfmt-nightly --force`.
When submitting a pull request, be sure to run `rustfmt`:
```
rustup component add rustfmt-preview
cargo +nightly fmt
```
### On Unit & Integration Tests
......
......@@ -9,11 +9,13 @@ use version_check::is_nightly;
// `loop` (RFC 1624, rust-lang/rust GitHub issue #37339).
// const MIN_VERSION: &'static str = "1.19.0";
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::Path;
use std::process::Command;
use std::{
env,
fs::File,
io::{self, Read, Write},
path::Path,
process::Command,
};
fn main() {
match is_nightly() {
......@@ -34,8 +36,14 @@ fn main() {
panic!("Aborting compilation due to incompatible compiler.")
}
_ => {
eprintln!("cargo:warning={}", "Ion was unable to check rustc compatibility.");
eprintln!("cargo:warning={}", "Build may fail due to incompatible rustc version.");
eprintln!(
"cargo:warning={}",
"Ion was unable to check rustc compatibility."
);
eprintln!(
"cargo:warning={}",
"Build may fail due to incompatible rustc version."
);
}
}
match write_version_file() {
......
unstable_features = true
array_horizontal_layout_threshold = 100
array_width = 100
attributes_on_same_line_as_field = false
attributes_on_same_line_as_variant = false
chain_one_line_max = 100
chain_width = 100
comment_width = 100
condense_wildcard_suffixes = true
error_on_line_overflow_comments = false
fn_call_width = 100
fn_single_line = true
format_strings = true
imports_indent = "Block"
match_pattern_separator_break_point = "Front"
max_width = 100
normalize_comments = true
reorder_imported_names = true
reorder_imports = true
reorder_imports_in_group = true
single_line_if_else_max_width = 100
reorder_modules = true
reorder_impl_items = true
struct_field_align_threshold = 30
struct_lit_width = 100
where_style = "legacy"
use_field_init_shorthand = true
wrap_comments = true
write_mode = "overwrite"
merge_imports = true
use std::mem::transmute;
use std::ops::DerefMut;
use std::{mem::transmute, ops::DerefMut};
// TODO: These could be generalised to work on non-ASCII characters (and even
// strings!) as long as the byte size of the needle and haystack match.
......
use sys;
use shell::Shell;
use shell::status::*;
use builtins::man_pages::*;
use shell::{status::*, Shell};
use sys;
use std::env;
use std::path::Path;
use std::borrow::Cow;
use std::{borrow::Cow, env, path::Path};
pub(crate) fn which(args: &[&str], shell: &mut Shell) -> Result<i32, ()> {
if check_help(args, MAN_WHICH) {
return Ok(SUCCESS)
return Ok(SUCCESS);
}
if args.len() == 1 {
eprintln!("which: Expected at least 1 args, got only 0");
return Err(())
return Err(());
}
let mut result = SUCCESS;
......@@ -24,10 +21,10 @@ pub(crate) fn which(args: &[&str], shell: &mut Shell) -> Result<i32, ()> {
"alias" => {
let alias = shell.variables.aliases.get(command).unwrap();
println!("{}: alias to {}", command, alias);
},
}
"function" => println!("{}: function", command),
"builtin" => println!("{}: built-in shell command", command),
_path => println!("{}", _path)
_path => println!("{}", _path),
}
} else {
result = FAILURE;
......@@ -40,7 +37,7 @@ pub(crate) fn find_type(args: &[&str], shell: &mut Shell) -> Result<i32, ()> {
// Type does not accept help flags, aka "--help".
if args.len() == 1 {
eprintln!("type: Expected at least 1 args, got only 0");
return Err(())
return Err(());
}
let mut result = FAILURE;
......@@ -50,11 +47,11 @@ pub(crate) fn find_type(args: &[&str], shell: &mut Shell) -> Result<i32, ()> {
"alias" => {
let alias = shell.variables.aliases.get(command).unwrap();
println!("{} is aliased to `{}`", command, alias);
},
}
// TODO Make it print the function.
"function" => println!("{} is a function", command),
"function" => println!("{} is a function", command),
"builtin" => println!("{} is a shell builtin", command),
_path => println!("{} is {}", command, _path)
_path => println!("{} is {}", command, _path),
}
result = SUCCESS;
} else {
......@@ -66,21 +63,21 @@ pub(crate) fn find_type(args: &[&str], shell: &mut Shell) -> Result<i32, ()> {
pub(crate) fn get_command_info<'a>(command: &str, shell: &mut Shell) -> Result<Cow<'a, str>, ()> {
if shell.variables.aliases.get(command).is_some() {
return Ok("alias".into())
return Ok("alias".into());
} else if shell.functions.contains_key(command) {
return Ok("function".into())
return Ok("function".into());
} else if shell.builtins.contains_key(command) {
return Ok("builtin".into())
return Ok("builtin".into());
} else {
for path in env::var("PATH")
.unwrap_or("/bin".to_string())
.split(sys::PATH_SEPARATOR)
.split(sys::PATH_SEPARATOR)
{
let executable = Path::new(path).join(command);
if executable.is_file() {
return Ok(executable.display().to_string().into())
return Ok(executable.display().to_string().into());
}
}
}
Err(())
}
\ No newline at end of file
}
use shell::Shell;
use shell::status::*;
use shell::{status::*, Shell};
macro_rules! string_function {
($method:tt) => (
($method:tt) => {
pub(crate) fn $method(args: &[&str], _: &mut Shell) -> i32 {
match args.len() {
0...2 => {
eprintln!("ion: {}: two arguments must be supplied", args[0]);
return BAD_ARG
return BAD_ARG;
}
3 => if args[1].$method(&args[2]) {
SUCCESS
} else {
FAILURE
},
3 => if args[1].$method(&args[2]) { SUCCESS } else { FAILURE },
_ => {
for arg in args[2..].iter() {
if args[1].$method(arg) { return SUCCESS }
if args[1].$method(arg) {
return SUCCESS;
}
}
FAILURE
}
}
}
)
};
}
string_function!(starts_with);
......
......@@ -28,7 +28,9 @@ pub(crate) fn exec(shell: &mut Shell, args: &[&str]) -> Result<(), String> {
&[]
};
shell.prep_for_exit();
Err(execve(argument, args, (flags & CLEAR_ENV) == 1).description().to_owned())
Err(execve(argument, args, (flags & CLEAR_ENV) == 1)
.description()
.to_owned())
}
None => Err("no command provided".to_owned()),
}
......
......@@ -2,14 +2,13 @@
use smallstring::SmallString;
#[cfg(test)]
use smallvec::SmallVec;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::{fs, os::unix::fs::PermissionsExt};
use shell::Shell;
#[cfg(test)]
use shell::flow_control::{Function, Statement};
#[cfg(test)]
use shell;
#[cfg(test)]
use shell::flow_control::{Function, Statement};
use shell::Shell;
pub(crate) fn exists(args: &[&str], shell: &Shell) -> Result<bool, String> {
let arguments = &args[1..];
......
use fnv::FnvHashMap;
use shell::flow_control::Function;
use shell::status::*;
use shell::{flow_control::Function, status::*};
use std::io::{self, Write};
use types::Identifier;
......
use shell::Shell;
use shell::status::*;
use shell::{status::*, Shell};
use std::path::Path;
use std::process::Command;
......
//! Contains the `jobs`, `disown`, `bg`, and `fg` commands that manage job
//! control in the shell.
use shell::Shell;
use shell::job_control::{JobControl, ProcessState};
use shell::signals;
use shell::status::*;
use shell::{
job_control::{JobControl, ProcessState},
signals,
status::*,
Shell,
};
/// Disowns given process job IDs, and optionally marks jobs to not receive SIGHUP signals.
/// The `-a` flag selects all jobs, `-r` selects all running jobs, and `-h` specifies to mark
......
use std::error::Error;
use std::io::{stdout, Write};
use std::{
error::Error,
io::{stdout, Write},
};
pub(crate) fn print_man(man_page: &'static str) {
let stdout = stdout();
......
pub mod source;
pub mod variables;
pub mod functions;
pub mod calc;
pub mod functions;
pub mod random;
pub mod source;
pub mod variables;
mod command_info;
mod conditionals;
mod job_control;
mod man_pages;
mod test;
mod echo;
mod set;
mod status;
mod exists;
mod exec;
mod exists;
mod ion;
mod is;
mod job_control;
mod man_pages;
mod set;
mod status;
mod test;
use self::command_info::*;
use self::conditionals::{contains, ends_with, starts_with};
use self::echo::echo;
use self::exec::exec;
use self::exists::exists;
use self::functions::fn_;
use self::ion::ion_docs;
use self::is::is;
use self::man_pages::*;
use self::source::source;
use self::status::status;
use self::test::test;
use self::variables::{alias, drop_alias, drop_array, drop_variable};
use std::env;
use std::error::Error;
use std::io::{self, Write};
use self::{
command_info::*,
conditionals::{contains, ends_with, starts_with},
echo::echo,
exec::exec,
exists::exists,
functions::fn_,
ion::ion_docs,
is::is,
man_pages::*,
source::source,
status::status,
test::test,
variables::{alias, drop_alias, drop_array, drop_variable},
};
use std::{
env,
error::Error,
io::{self, Write},
};
use parser::Terminator;
use shell::job_control::{JobControl, ProcessState};
use shell::fork_function::fork_function;
use shell::status::*;
use shell::{self, FlowLogic, Shell, ShellHistory};
use shell::{
self,
fork_function::fork_function,
job_control::{JobControl, ProcessState},
status::*,
FlowLogic,
Shell,
ShellHistory,
};
use sys;
const HELP_DESC: &str = "Display helpful information about a given command or list commands if \
......@@ -128,6 +137,10 @@ pub struct BuiltinMap {
}
impl BuiltinMap {
pub fn contains_key(&self, func: &str) -> bool { self.name.iter().any(|&name| name == func) }
pub fn keys(&self) -> &'static [&'static str] { self.name }
pub fn get(&self, func: &str) -> Option<Builtin> {
self.name.binary_search(&func).ok().map(|pos| unsafe {
Builtin {
......@@ -137,10 +150,6 @@ impl BuiltinMap {
}
})
}
pub fn keys(&self) -> &'static [&'static str] { self.name }
pub fn contains_key(&self, func: &str) -> bool { self.name.iter().any(|&name| name == func) }
}
// Definitions of simple builtins go here
......@@ -174,7 +183,7 @@ pub fn builtin_cd(args: &[&str], shell: &mut Shell) -> i32 {
shell.set_var("PWD", current_dir);
}
fork_function(shell, "CD_CHANGE", &["ion"]);
},
}
Err(_) => env::set_var("PWD", "?"),
};
SUCCESS
......@@ -557,20 +566,20 @@ fn builtin_exists(args: &[&str], shell: &mut Shell) -> i32 {
fn builtin_which(args: &[&str], shell: &mut Shell) -> i32 {
match which(args, shell) {
Ok(result) => result,
Err(()) => FAILURE
Err(()) => FAILURE,
}
}
fn builtin_type(args: &[&str], shell: &mut Shell) -> i32 {
match find_type(args, shell) {
Ok(result) => result,
Err(()) => FAILURE
Err(()) => FAILURE,
}
}
fn builtin_isatty(args: &[&str], _: &mut Shell) -> i32 {
if check_help(args, MAN_ISATTY) {
return SUCCESS
return SUCCESS;
}
if args.len() > 1 {
......@@ -578,20 +587,20 @@ fn builtin_isatty(args: &[&str], _: &mut Shell) -> i32 {
#[cfg(target_os = "redox")]
match args[1].parse::<usize>() {
Ok(r) => if sys::isatty(r) {
return SUCCESS
return SUCCESS;
},
Err(_) => eprintln!("ion: isatty given bad number")
Err(_) => eprintln!("ion: isatty given bad number"),
}
#[cfg(not(target_os = "redox"))]
match args[1].parse::<i32>() {
Ok(r) => if sys::isatty(r) {
return SUCCESS
return SUCCESS;
},
Err(_) => eprintln!("ion: isatty given bad number")
Err(_) => eprintln!("ion: isatty given bad number"),
}
} else {
return SUCCESS
return SUCCESS;
}
FAILURE
......
use liner::KeyBindings;
use shell::Shell;
use shell::flags::*;
use shell::{flags::*, Shell};
use std::iter;
enum PositionalArgs {
......
use shell::{FlowLogic, Shell};
use std::fs::File;
use std::io::Read;
use std::{fs::File, io::Read};
/// Evaluates the given file and returns 'SUCCESS' if it succeeds.
pub(crate) fn source(shell: &mut Shell, arguments: &[&str]) -> Result<(), String> {
......
use smallstring::SmallString;
use std::fs;
use std::os::unix::fs::{FileTypeExt, MetadataExt, PermissionsExt};
use std::path::Path;
use std::time::SystemTime;
use super::man_pages::{print_man, MAN_TEST};
use smallstring::SmallString;
use std::{
fs,
os::unix::fs::{FileTypeExt, MetadataExt, PermissionsExt},
path::Path,
time::SystemTime,
};
pub(crate) fn test(args: &[&str]) -> Result<bool, String> {
let arguments = &args[1..];
......
......@@ -2,8 +2,7 @@
use std::io::{self, Write};
use shell::status::*;
use shell::variables::Variables;
use shell::{status::*, variables::Variables};
use types::*;
fn print_list(list: &VariableContext) {
......
#![allow(unknown_lints)]
#![allow(while_let_on_iterator)]
#![feature(conservative_impl_trait)]
#![feature(integer_atomics)]
#![feature(pointer_methods)]
#![feature(getpid)]
......@@ -43,12 +42,11 @@ mod sys;
mod types;
#[macro_use]
pub mod parser;
mod ascii_helpers;
mod builtins;
mod shell;
mod ascii_helpers;
pub use shell::binary::MAN_ION;
pub use shell::flags;
pub use shell::status;
pub use shell::{Binary, Capture, Fork, IonError, IonResult, Shell, ShellBuilder};
pub use shell::pipe_exec::job_control::JobControl;
pub use shell::{
binary::MAN_ION, flags, pipe_exec::job_control::JobControl, status, Binary, Capture, Fork,
IonError, IonResult, Shell, ShellBuilder,
};
bitflags! {
struct ArgumentFlags: u8 {
/// Double quotes
/// Double quotes
const DOUBLE = 0b00000001;
/// Command flags
const COMM_1 = 0b00000010; // found $
const COMM_2 = 0b00000100; // found ( after $
/// String variable
/// String variable
const VARIAB = 0b00001000;
/// Array variable
/// Array variable
const ARRAY = 0b00010000;
const METHOD = 0b00100000;
const METHOD = 0b00100000;
}
}
/// An efficient `Iterator` structure for splitting arguments
pub struct ArgumentSplitter<'a> {
data: &'a str,
data: &'a str,
/// Number of bytes read
read: usize,
read: usize,
bitflags: ArgumentFlags,
}
impl<'a> ArgumentSplitter<'a> {
pub fn new(data: &'a str) -> ArgumentSplitter<'a> {
ArgumentSplitter {
data: data,
read: 0,
data,
read: 0,
bitflags: ArgumentFlags::empty(),
}
}
......@@ -61,7 +61,6 @@ impl<'a> Iterator for ArgumentSplitter<'a> {
let (mut level, mut alevel) = (0, 0);
let mut bytes = data.iter().cloned().skip(self.read);
while let Some(character) = bytes.next() {
match character {
// Skip the next byte.
b'\\' => {
......@@ -72,18 +71,16 @@ impl<'a> Iterator for ArgumentSplitter<'a> {
// Disable COMM_1 and enable COMM_2 + ARRAY.
b'@' => {
self.bitflags.remove(ArgumentFlags::COMM_1);