Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
redox-os
ion
Commits
1ab894f5
Unverified
Commit
1ab894f5
authored
May 27, 2018
by
Michael Aaron Murphy
Committed by
GitHub
May 27, 2018
Browse files
Apply cargo +nightly fmt (#740)
parent
37acfd70
Changes
45
Hide whitespace changes
Inline
Side-by-side
build.rs
View file @
1ab894f5
...
...
@@ -10,11 +10,7 @@ use version_check::is_nightly;
// const MIN_VERSION: &'static str = "1.19.0";
use
std
::{
env
,
fs
::
File
,
io
::{
self
,
Read
,
Write
},
path
::
Path
,
process
::
Command
,
env
,
fs
::
File
,
io
::{
self
,
Read
,
Write
},
path
::
Path
,
process
::
Command
,
};
fn
main
()
{
...
...
src/lib/builtins/job_control.rs
View file @
1ab894f5
...
...
@@ -2,10 +2,7 @@
//! control in the shell.
use
shell
::{
job_control
::{
JobControl
,
ProcessState
},
signals
,
status
::
*
,
Shell
,
job_control
::{
JobControl
,
ProcessState
},
signals
,
status
::
*
,
Shell
,
};
/// Disowns given process job IDs, and optionally marks jobs to not receive SIGHUP signals.
...
...
@@ -28,7 +25,8 @@ pub(crate) fn disown(shell: &mut Shell, args: &[&str]) -> Result<(), String> {
"-h"
=>
flags
|
=
NO_SIGHUP
,
"-r"
=>
flags
|
=
RUN_JOBS
,
_
=>
{
let
jobspec
=
arg
.parse
::
<
u32
>
()
let
jobspec
=
arg
.parse
::
<
u32
>
()
.map_err
(|
_
|
format!
(
"invalid jobspec: '{}'"
,
arg
))
?
;
collected_jobs
.push
(
jobspec
);
}
...
...
src/lib/builtins/man_pages.rs
View file @
1ab894f5
use
std
::{
error
::
Error
,
io
::{
stdout
,
Write
},
error
::
Error
,
io
::{
stdout
,
Write
},
};
pub
(
crate
)
fn
print_man
(
man_page
:
&
'static
str
)
{
...
...
src/lib/builtins/mod.rs
View file @
1ab894f5
...
...
@@ -18,36 +18,19 @@ mod status;
mod
test
;
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
},
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
},
env
,
error
::
Error
,
io
::{
self
,
Write
},
};
use
parser
::
Terminator
;
use
shell
::{
self
,
fork_function
::
fork_function
,
job_control
::{
JobControl
,
ProcessState
},
status
::
*
,
FlowLogic
,
Shell
,
ShellHistory
,
self
,
fork_function
::
fork_function
,
job_control
::{
JobControl
,
ProcessState
},
status
::
*
,
FlowLogic
,
Shell
,
ShellHistory
,
};
use
sys
;
...
...
src/lib/builtins/test.rs
View file @
1ab894f5
use
super
::
man_pages
::{
print_man
,
MAN_TEST
};
use
smallstring
::
SmallString
;
use
std
::{
fs
,
os
::
unix
::
fs
::{
FileTypeExt
,
MetadataExt
,
PermissionsExt
},
path
::
Path
,
time
::
SystemTime
,
fs
,
os
::
unix
::
fs
::{
FileTypeExt
,
MetadataExt
,
PermissionsExt
},
path
::
Path
,
time
::
SystemTime
,
};
pub
(
crate
)
fn
test
(
args
:
&
[
&
str
])
->
Result
<
bool
,
String
>
{
...
...
src/lib/parser/arguments.rs
View file @
1ab894f5
...
...
@@ -25,7 +25,7 @@ impl<'a> ArgumentSplitter<'a> {
pub
fn
new
(
data
:
&
'a
str
)
->
ArgumentSplitter
<
'a
>
{
ArgumentSplitter
{
data
,
read
:
0
,
read
:
0
,
bitflags
:
ArgumentFlags
::
empty
(),
}
}
...
...
@@ -95,7 +95,8 @@ impl<'a> Iterator for ArgumentSplitter<'a> {
b'('
=>
{
// Disable VARIAB + ARRAY and enable METHOD.
// if variab or array are set
if
self
.bitflags
if
self
.bitflags
.intersects
(
ArgumentFlags
::
VARIAB
|
ArgumentFlags
::
ARRAY
)
{
self
.bitflags
...
...
@@ -126,7 +127,8 @@ impl<'a> Iterator for ArgumentSplitter<'a> {
// ) && level + alevel == 0) => break,
// Break from the loop once a root-level space is found.
b' '
=>
{
if
!
self
.bitflags
if
!
self
.bitflags
.intersects
(
ArgumentFlags
::
DOUBLE
|
ArgumentFlags
::
METHOD
)
&&
level
==
0
&&
alevel
==
0
&&
blevel
==
0
{
...
...
src/lib/parser/assignments/checker.rs
View file @
1ab894f5
use
super
::{
super
::{
expand_string
,
Expander
},
Primitive
,
ReturnValue
,
TypeError
,
super
::{
expand_string
,
Expander
},
Primitive
,
ReturnValue
,
TypeError
,
};
use
std
::
iter
::
Iterator
;
...
...
src/lib/parser/assignments/mod.rs
View file @
1ab894f5
...
...
@@ -6,11 +6,8 @@ mod splitter;
pub
use
self
::
keys
::
Primitive
;
pub
(
crate
)
use
self
::{
actions
::{
Action
,
AssignmentActions
,
AssignmentError
},
checker
::{
is_array
,
value_check
},
keys
::{
Key
,
KeyBuf
,
KeyIterator
,
TypeError
},
operator
::
Operator
,
splitter
::
split_assignment
,
actions
::{
Action
,
AssignmentActions
,
AssignmentError
},
checker
::{
is_array
,
value_check
},
keys
::{
Key
,
KeyBuf
,
KeyIterator
,
TypeError
},
operator
::
Operator
,
splitter
::
split_assignment
,
};
use
types
::{
Array
,
Value
};
...
...
src/lib/parser/mod.rs
View file @
1ab894f5
...
...
@@ -8,7 +8,6 @@ mod statement;
pub
use
self
::{
arguments
::
ArgumentSplitter
,
assignments
::
Primitive
,
quotes
::
Terminator
};
pub
(
crate
)
use
self
::{
loops
::
for_grammar
::
ForExpression
,
shell_expand
::{
expand_string
,
Expander
,
Select
},
loops
::
for_grammar
::
ForExpression
,
shell_expand
::{
expand_string
,
Expander
,
Select
},
statement
::{
parse_and_validate
,
StatementSplitter
},
};
src/lib/parser/pipelines/collector.rs
View file @
1ab894f5
...
...
@@ -381,8 +381,7 @@ impl<'a> Collector<'a> {
#[cfg(test)]
mod
tests
{
use
parser
::{
pipelines
::{
Input
,
PipeItem
,
Pipeline
,
RedirectFrom
,
Redirection
},
statement
::
parse
,
pipelines
::{
Input
,
PipeItem
,
Pipeline
,
RedirectFrom
,
Redirection
},
statement
::
parse
,
};
use
shell
::{
flow_control
::
Statement
,
Job
,
JobKind
};
use
types
::
Array
;
...
...
src/lib/parser/pipelines/mod.rs
View file @
1ab894f5
...
...
@@ -72,7 +72,8 @@ impl PipeItem {
impl
Pipeline
{
pub
(
crate
)
fn
requires_piping
(
&
self
)
->
bool
{
self
.items
.len
()
>
1
||
self
.items
.iter
()
.any
(|
it
|
it
.outputs
.len
()
>
0
)
self
.items
.len
()
>
1
||
self
.items
.iter
()
.any
(|
it
|
it
.outputs
.len
()
>
0
)
||
self
.items
.iter
()
.any
(|
it
|
it
.inputs
.len
()
>
0
)
||
self
.items
.last
()
.unwrap
()
.job.kind
==
JobKind
::
Background
||
self
.items
.last
()
.unwrap
()
.job.kind
==
JobKind
::
Disown
...
...
src/lib/parser/quotes.rs
View file @
1ab894f5
...
...
@@ -108,12 +108,14 @@ impl Terminator {
return
false
;
}
else
if
instance
.contains
(
Flags
::
COMM
)
{
self
.buffer
.truncate
(
self
.read
-
1
);
return
!
self
.flags
return
!
self
.flags
.intersects
(
Flags
::
SQUOTE
|
Flags
::
DQUOTE
|
Flags
::
ARRAY
);
}
}
if
self
.flags
if
self
.flags
.intersects
(
Flags
::
SQUOTE
|
Flags
::
DQUOTE
|
Flags
::
ARRAY
)
{
if
let
Some
(
b'\\'
)
=
self
.buffer
.bytes
()
.last
()
{
...
...
src/lib/parser/shell_expand/braces.rs
View file @
1ab894f5
...
...
@@ -9,19 +9,22 @@ pub(crate) enum BraceToken {
Expander
,
}
pub
(
crate
)
fn
expand_braces
<
'a
>
(
tokens
:
&
'a
[
BraceToken
],
expanders
:
&
'a
[
&
'a
[
&
'a
str
]])
->
Box
<
Iterator
<
Item
=
String
>
+
'a
>
{
pub
(
crate
)
fn
expand_braces
<
'a
>
(
tokens
:
&
'a
[
BraceToken
],
expanders
:
&
'a
[
&
'a
[
&
'a
str
]],
)
->
Box
<
Iterator
<
Item
=
String
>
+
'a
>
{
if
expanders
.len
()
>
1
{
let
multiple_brace_expand
=
MultipleBraceExpand
{
permutator
:
Permutator
::
new
(
expanders
),
tokens
:
tokens
,
};
permutator
:
Permutator
::
new
(
expanders
),
tokens
,
};
Box
::
new
(
multiple_brace_expand
)
}
else
if
expanders
.len
()
==
1
{
let
single_brace_expand
=
SingleBraceExpand
{
elements
:
expanders
[
0
]
.iter
()
.map
(|
element
|
*
element
),
tokens
:
tokens
,
loop_count
:
0
,
};
elements
:
expanders
[
0
]
.iter
()
.map
(|
element
|
*
element
),
tokens
,
loop_count
:
0
,
};
Box
::
new
(
single_brace_expand
)
}
else
{
Box
::
new
(::
std
::
iter
::
empty
())
...
...
@@ -52,16 +55,18 @@ fn escape_string(input: &str) -> String {
pub
struct
MultipleBraceExpand
<
'a
,
'b
>
{
permutator
:
Permutator
<
'a
,
str
>
,
tokens
:
&
'b
[
BraceToken
],
tokens
:
&
'b
[
BraceToken
],
}
impl
<
'a
,
'b
>
Iterator
for
MultipleBraceExpand
<
'a
,
'b
>
{
type
Item
=
String
;
fn
next
(
&
mut
self
)
->
Option
<
Self
::
Item
>
{
if
let
Some
(
permutation
)
=
self
.permutator
.next
()
{
let
mut
strings
=
permutation
.iter
();
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
{
match
*
token
{
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
match
*
token
{
BraceToken
::
Normal
(
ref
text
)
=>
{
small_vec
.extend
(
escape_string
(
text
)
.bytes
());
small_vec
...
...
@@ -70,9 +75,9 @@ impl<'a, 'b> Iterator for MultipleBraceExpand<'a, 'b> {
small_vec
.extend
(
escape_string
(
strings
.next
()
.unwrap
())
.bytes
());
small_vec
}
}
}
);
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())})
}
,
);
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())
})
}
else
{
None
}
...
...
@@ -80,22 +85,26 @@ impl<'a, 'b> Iterator for MultipleBraceExpand<'a, 'b> {
}
pub
struct
SingleBraceExpand
<
'a
,
'b
,
I
>
where
I
:
Iterator
<
Item
=
&
'a
str
>
where
I
:
Iterator
<
Item
=
&
'a
str
>
,
{
elements
:
I
,
tokens
:
&
'b
[
BraceToken
],
elements
:
I
,
tokens
:
&
'b
[
BraceToken
],
loop_count
:
usize
,
}
impl
<
'a
,
'b
,
I
>
Iterator
for
SingleBraceExpand
<
'a
,
'b
,
I
>
where
I
:
Iterator
<
Item
=
&
'a
str
>
where
I
:
Iterator
<
Item
=
&
'a
str
>
,
{
type
Item
=
String
;
fn
next
(
&
mut
self
)
->
Option
<
Self
::
Item
>
{
match
self
.loop_count
{
0
=>
{
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
{
match
*
token
{
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
match
*
token
{
BraceToken
::
Normal
(
ref
text
)
=>
{
small_vec
.extend
(
escape_string
(
text
)
.bytes
());
small_vec
...
...
@@ -104,15 +113,16 @@ impl<'a, 'b, I> Iterator for SingleBraceExpand<'a, 'b, I>
small_vec
.extend
(
escape_string
(
self
.elements
.next
()
.unwrap
())
.bytes
());
small_vec
}
}
}
);
}
,
);
self
.loop_count
=
1
;
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())})
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())
})
}
_
=>
{
if
let
Some
(
element
)
=
self
.elements
.next
()
{
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
{
match
*
token
{
let
small_vec
:
SmallVec
<
[
u8
;
64
]
>
=
self
.tokens
.iter
()
.fold
(
SmallVec
::
with_capacity
(
64
),
|
mut
small_vec
,
token
|
match
*
token
{
BraceToken
::
Normal
(
ref
text
)
=>
{
small_vec
.extend
(
escape_string
(
text
)
.bytes
());
small_vec
...
...
@@ -121,9 +131,9 @@ impl<'a, 'b, I> Iterator for SingleBraceExpand<'a, 'b, I>
small_vec
.extend
(
escape_string
(
element
)
.bytes
());
small_vec
}
}
}
);
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())})
}
,
);
Some
(
unsafe
{
String
::
from_utf8_unchecked
(
small_vec
.to_vec
())
})
}
else
{
None
}
...
...
@@ -147,7 +157,7 @@ fn test_multiple_brace_expand() {
assert_eq!
(
MultipleBraceExpand
{
permutator
:
Permutator
::
new
(
expanders
),
tokens
:
tokens
,
tokens
,
}
.collect
::
<
Vec
<
String
>>
(),
vec!
[
"AB1CD3EF5GH"
.to_owned
(),
...
...
@@ -168,8 +178,8 @@ fn test_single_brace_expand() {
let
tokens
:
&
[
BraceToken
]
=
&
[
BraceToken
::
Normal
(
"A="
.to_owned
()),
BraceToken
::
Expander
];
assert_eq!
(
SingleBraceExpand
{
elements
:
elements
.iter
()
.map
(|
element
|
*
element
),
tokens
:
tokens
,
elements
:
elements
.iter
()
.map
(|
element
|
*
element
),
tokens
,
loop_count
:
0
,
}
.collect
::
<
Vec
<
String
>>
(),
vec!
[
"A=one"
.to_owned
(),
"A=two"
.to_owned
(),
"A=three"
.to_owned
()]
...
...
src/lib/parser/shell_expand/mod.rs
View file @
1ab894f5
...
...
@@ -17,7 +17,10 @@ use unicode_segmentation::UnicodeSegmentation;
/// bare word. For example, strings starting with '"', '\'', '@', or '$' are
/// all expressions
pub
(
crate
)
fn
is_expression
(
s
:
&
str
)
->
bool
{
s
.starts_with
(
'@'
)
||
s
.starts_with
(
'['
)
||
s
.starts_with
(
'$'
)
||
s
.starts_with
(
'"'
)
s
.starts_with
(
'@'
)
||
s
.starts_with
(
'['
)
||
s
.starts_with
(
'$'
)
||
s
.starts_with
(
'"'
)
||
s
.starts_with
(
'\''
)
}
...
...
@@ -249,7 +252,8 @@ fn expand_braces<E: Expander>(
expand_process
(
&
mut
temp
,
command
,
Select
::
All
,
expand_func
,
false
);
let
len
=
temp
.split_whitespace
()
.count
();
if
let
Some
((
start
,
length
))
=
range
.bounds
(
len
)
{
let
res
=
temp
.split_whitespace
()
let
res
=
temp
.split_whitespace
()
.skip
(
start
)
.take
(
length
)
.collect
::
<
Vec
<&
str
>>
();
...
...
@@ -521,7 +525,8 @@ pub(crate) fn expand_tokens<E: Expander>(
expand_process
(
&
mut
temp
,
command
,
Select
::
All
,
expand_func
,
false
);
if
let
Some
((
start
,
length
))
=
range
.bounds
(
temp
.split_whitespace
()
.count
())
{
let
temp
=
temp
.split_whitespace
()
let
temp
=
temp
.split_whitespace
()
.skip
(
start
)
.take
(
length
)
.collect
::
<
Vec
<
_
>>
();
...
...
src/lib/parser/shell_expand/ranges.rs
View file @
1ab894f5
use
super
::
words
::{
Index
,
Range
};
use
std
::
cmp
::
Ordering
;
fn
stepped_range_numeric
<
'a
>
(
start
:
isize
,
end
:
isize
,
step
:
isize
,
nb_digits
:
usize
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
fn
stepped_range_numeric
<
'a
>
(
start
:
isize
,
end
:
isize
,
step
:
isize
,
nb_digits
:
usize
,
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
return
if
step
==
0
{
None
}
else
if
start
<
end
&&
step
<
0
{
...
...
@@ -19,7 +24,7 @@ fn stepped_range_numeric<'a>(start: isize, end: isize, step: isize, nb_digits: u
if
end
.cmp
(
index
)
==
ordering
{
let
index_holder
=
*
index
;
*
index
+=
step
;
// This step adds
Some
(
format!
(
"{:0width$}"
,
index_holder
,
width
=
nb_digits
))
Some
(
format!
(
"{:0width$}"
,
index_holder
,
width
=
nb_digits
))
}
else
{
None
}
...
...
@@ -29,7 +34,11 @@ fn stepped_range_numeric<'a>(start: isize, end: isize, step: isize, nb_digits: u
};
}
fn
stepped_range_chars
<
'a
>
(
start
:
u8
,
end
:
u8
,
step
:
u8
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
fn
stepped_range_chars
<
'a
>
(
start
:
u8
,
end
:
u8
,
step
:
u8
,
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
if
step
==
0
{
None
}
else
{
...
...
@@ -45,7 +54,7 @@ fn stepped_range_chars<'a>(start: u8, end: u8, step: u8) -> Option<Box<Iterator<
*
index
=
match
ordering
{
Ordering
::
Greater
=>
index
.wrapping_add
(
step
),
Ordering
::
Less
=>
index
.wrapping_sub
(
step
),
_
=>
unreachable!
()
_
=>
unreachable!
()
,
};
Some
((
index_holder
as
char
)
.to_string
())
}
else
{
...
...
@@ -57,8 +66,13 @@ fn stepped_range_chars<'a>(start: u8, end: u8, step: u8) -> Option<Box<Iterator<
}
}
fn
numeric_range
<
'a
>
(
start
:
isize
,
mut
end
:
isize
,
step
:
isize
,
inclusive
:
bool
,
nb_digits
:
usize
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
fn
numeric_range
<
'a
>
(
start
:
isize
,
mut
end
:
isize
,
step
:
isize
,
inclusive
:
bool
,
nb_digits
:
usize
,
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
if
start
<
end
{
if
inclusive
{
end
+=
1
;
...
...
@@ -78,7 +92,12 @@ fn numeric_range<'a>(start: isize, mut end: isize, step: isize, inclusive: bool,
fn
byte_is_valid_range
(
b
:
u8
)
->
bool
{
(
b
>=
b'a'
&&
b
<=
b'z'
)
||
(
b
>=
b'A'
&&
b
<=
b'Z'
)
}
use
std
::
u8
;
fn
char_range
<
'a
>
(
start
:
u8
,
mut
end
:
u8
,
step
:
isize
,
inclusive
:
bool
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
fn
char_range
<
'a
>
(
start
:
u8
,
mut
end
:
u8
,
step
:
isize
,
inclusive
:
bool
,
)
->
Option
<
Box
<
Iterator
<
Item
=
String
>
+
'a
>>
{
if
!
byte_is_valid_range
(
start
)
||
!
byte_is_valid_range
(
end
)
{
return
None
;
}
...
...
@@ -114,13 +133,16 @@ fn count_minimum_digits(a: &str) -> usize {
'0'
=>
{
has_leading_zero
=
true
;
break
;
}
,
}
'1'
...
'9'
=>
break
,
_
=>
panic!
(
"count_minimum_digits should only be called for a valid number."
)
_
=>
panic!
(
"count_minimum_digits should only be called for a valid number."
)
,
}
}
if
!
has_leading_zero
{
0
}
else
{
a
.len
()
}
if
!
has_leading_zero
{
0
}
else
{
a
.len
()
}
}
fn
strings_to_isizes
(
a
:
&
str
,
b
:
&
str
)
->
Option
<
(
isize
,
isize
,
usize
)
>
{
...
...
@@ -160,7 +182,7 @@ pub(crate) fn parse_range<'a>(input: &str) -> Option<Box<Iterator<Item = String>
}
macro_rules!
finish_char
{
(
$inclusive
:
expr
,
$end_str
:
expr
,
$step
:
expr
)
=>
{
(
$inclusive:expr
,
$end_str:expr
,
$step:expr
)
=>
{
if
first
.len
()
==
1
&&
$end_str
.len
()
==
1
{
let
start
=
first
.as_bytes
()[
0
];
let
end
=
$end_str
.as_bytes
()[
0
];
...
...
@@ -172,9 +194,10 @@ pub(crate) fn parse_range<'a>(input: &str) -> Option<Box<Iterator<Item = String>
}
macro_rules!
finish
{
(
$inclusive
:
expr
,
$read
:
expr
)
=>
{
(
$inclusive:expr
,
$read:expr
)
=>
{
let
end_str
=
&
input
[
$read
..
];
if
let
Some
((
start
,
end
,
nb_digits
))
=
strings_to_isizes
(
first
,
end_str
)
{
if
let
Some
((
start
,
end
,
nb_digits
))
=
strings_to_isizes
(
first
,
end_str
)
{
return
numeric_range
(
start
,
end
,
...
...
@@ -186,9 +209,10 @@ pub(crate) fn parse_range<'a>(input: &str) -> Option<Box<Iterator<Item = String>
finish_char!
(
$inclusive
,
end_str
,
1
);
}
};
(
$inclusive
:
expr
,
$read
:
expr
,
$step
:
expr
)
=>
{
(
$inclusive:expr
,
$read:expr
,
$step:expr
)
=>
{
let
end_str
=
&
input
[
$read
..
];
if
let
Some
((
start
,
end
,
nb_digits
))
=
strings_to_isizes
(
first
,
end_str
)
{
if
let
Some
((
start
,
end
,
nb_digits
))
=
strings_to_isizes
(
first
,
end_str
)
{
return
numeric_range
(
start
,
end
,
$step
,
$inclusive
,
nb_digits
);
}
else
{
finish_char!
(
$inclusive
,
end_str
,
$step
);
...
...
@@ -359,14 +383,14 @@ fn range_expand() {
let
actual
:
Vec
<
String
>
=
parse_range
(
"-3...3"
)
.unwrap
()
.collect
();
let
expected
:
Vec
<
String
>
=
vec!
[
"-3"
.to_owned
(),
"-2"
.to_owned
(),
"-1"
.to_owned
(),
"0"
.to_owned
(),
"1"
.to_owned
(),
"2"
.to_owned
(),
"3"
.to_owned
(),
];
"-3"
.to_owned
(),
"-2"
.to_owned
(),
"-1"
.to_owned
(),
"0"
.to_owned
(),
"1"
.to_owned
(),
"2"
.to_owned
(),
"3"
.to_owned
(),
];
assert_eq!
(
actual
,
expected
);
...
...
src/lib/parser/shell_expand/words/methods/arrays.rs
View file @
1ab894f5
use
super
::{
super
::{
super
::{
expand_string
,
is_expression
,
Expander
},
Index
,
Select
,
SelectWithSize
,
super
::{
expand_string
,
is_expression
,
Expander
},
Index
,
Select
,
SelectWithSize
,
},
strings
::
unescape
,
Pattern
,
strings
::
unescape
,
Pattern
,
};
use
smallstring
::
SmallString
;
use
std
::
char
;
...
...
@@ -90,7 +86,9 @@ impl<'a> ArrayMethod<'a> {
let
res
=
match
(
&
self
.pattern
,
self
.selection
.clone
())
{
(
_
,
Select
::
None
)
=>
Some
(
""
.into
())
.into_iter
()
.collect
(),
(
&
Pattern
::
StringPattern
(
pattern
),
Select
::
All
)
=>
variable
.split
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
))
?
)
.split
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
)
)
?
)
.map
(
From
::
from
)
.collect
(),
(
&
Pattern
::
Whitespace
,
Select
::
All
)
=>
variable
...
...
@@ -99,7 +97,9 @@ impl<'a> ArrayMethod<'a> {
.map
(
From
::
from
)
.collect
(),
(
&
Pattern
::
StringPattern
(
pattern
),
Select
::
Index
(
Index
::
Forward
(
id
)))
=>
variable
.split
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
))
?
)
.split
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
)
)
?
)
.nth
(
id
)
.map
(
From
::
from
)
.into_iter
()
...
...
@@ -112,7 +112,9 @@ impl<'a> ArrayMethod<'a> {
.into_iter
()
.collect
(),
(
&
Pattern
::
StringPattern
(
pattern
),
Select
::
Index
(
Index
::
Backward
(
id
)))
=>
variable
.rsplit
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
))
?
)
.rsplit
(
&
unescape
(
&
expand_string
(
pattern
,
expand_func
,
false
)
.join
(
" "
)
)
?
)
.nth
(
id
)
.map
(
From
::
from
)
.into_iter
()
...
...
@@ -210,8 +212,7 @@ impl<'a> ArrayMethod<'a> {
#[cfg(test)]
mod
test
{
use
super
::{
super
::{
super
::
Range
,
Key
},
*
,
super
::{
super
::
Range
,
Key
},
*
,
};
use
types
::
Value
;
...
...
src/lib/parser/shell_expand/words/methods/strings.rs
View file @
1ab894f5
use
super
::{