Skip to content
Snippets Groups Projects
Commit ad57a3e4 authored by Sylvestre Ledru's avatar Sylvestre Ledru Committed by Ritesh Raj Sarraf
Browse files

Import Debian changes 2.1.0-1

parents 82d515c8 be6d4e43
Branches debian/bookworm
Tags debian/2.1.0-1
1 merge request!1Update from debian/bookworm for apertis/v2024dev2
Pipeline #891199 canceled
os: Visual Studio 2015
environment:
matrix:
# Stable 64-bit MSVC
- channel: stable
target: x86_64-pc-windows-msvc
# Nightly 32-bit MSVC
- channel: nightly
target: i686-pc-windows-msvc
# Beta 32-bit GNU
- channel: beta
target: i686-pc-windows-gnu
matrix:
allow_failures:
- channel: nightly
- channel: beta
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init -yv --default-toolchain %channel% --default-host %target%
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
- rustc -vV
- cargo -vV
# Uses 'cargo test' to run tests and build. Alternatively, the project may call compiled programs
# directly or perform other testing commands. Rust will automatically be placed in the PATH
# environment variable.
build: false
test_script:
- cargo test --all --verbose
{
"git": {
"sha1": "bb3ffd6bf97436c0363a7f63fb00cc1620272ee9"
}
}
"sha1": "38b6cd950ff359724f4f36685bb4b5465cda06b4"
},
"path_in_vcs": ""
}
\ No newline at end of file
/target/
**/*.rs.bk
Cargo.lock
# This file is a template, and might need editing before it works on your project.
# Official language image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/rust/tags/
image: "rust:latest"
# Use cargo to test the project
test:cargo:
script:
- rustc --version && cargo --version # Print version info for debugging
- cargo test --verbose
......@@ -3,31 +3,60 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "wild"
version = "2.0.2"
version = "2.1.0"
authors = ["Kornel <kornel@geekhood.net>"]
include = [
"/src/*.rs",
"/Cargo.toml",
"/LICENSE",
"/README.md",
]
description = "Glob (wildcard) expanded command-line arguments on Windows"
homepage = "https://crates.rs/crates/wild"
homepage = "https://lib.rs/crates/wild"
documentation = "https://docs.rs/wild"
readme = "README.md"
keywords = ["wildcards", "glob", "windows", "shell", "CommandLineToArgvW"]
categories = ["command-line-interface"]
license = "MIT"
keywords = [
"wildcards",
"glob",
"windows",
"shell",
"CommandLineToArgvW",
]
categories = [
"command-line-interface",
"os::windows-apis",
]
license = "Apache-2.0 OR MIT"
repository = "https://gitlab.com/kornelski/wild"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[dev-dependencies.glob]
version = "0.3"
[target."cfg(windows)".dependencies.glob]
version = "0.3"
[badges.appveyor]
repository = "pornel/wild"
[badges.gitlab]
repository = "kornelski/wild"
[badges.maintenance]
status = "passively-maintained"
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "wild"
version = "2.0.2"
authors = ["Kornel <kornel@geekhood.net>"]
categories = ["command-line-interface", "os::windows-apis"]
description = "Glob (wildcard) expanded command-line arguments on Windows"
homepage = "https://crates.rs/crates/wild"
documentation = "https://docs.rs/wild"
readme = "README.md"
homepage = "https://lib.rs/crates/wild"
keywords = ["wildcards", "glob", "windows", "shell", "CommandLineToArgvW"]
categories = ["command-line-interface"]
license = "MIT"
license = "Apache-2.0 OR MIT"
name = "wild"
readme = "README.md"
repository = "https://gitlab.com/kornelski/wild"
[dev-dependencies.glob]
version = "0.3"
[target."cfg(windows)".dependencies.glob]
version = "0.3"
[badges.appveyor]
repository = "pornel/wild"
version = "2.1.0"
edition = "2018"
include = ["/src/*.rs", "/Cargo.toml", "/LICENSE", "/README.md"]
[badges]
gitlab = { repository = "kornelski/wild" }
appveyor = { repository = "pornel/wild" }
maintenance = { status = "passively-maintained" }
[target.'cfg(windows)'.dependencies]
glob = "0.3"
[dev-dependencies]
glob = "0.3"
[badges.gitlab]
repository = "kornelski/wild"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
# [`Wild::args`](https://crates.rs/crates/wild) for [Rust](https://www.rust-lang.org)
# [`Wild::args`](https://lib.rs/crates/wild) for [Rust](https://www.rust-lang.org)
Allows Rust applications support wildcard arguments (`*foo*`, `file.???`, `*.log.[0-9]`, etc.) on command-line, uniformly on all platforms, including Windows.
Unix shells automatically interpret wildcard arguments and pass them expanded (already converted to file names) to applications, but Windows' `cmd.exe` doesn't do that. For consistent cross-platform behavior, this crate emulates Unix-like expansion on Windows. You only need to use `wild::args()` instead of `std::env::args()`.
It is more robust than using [`glob()`](https://crates.rs/crates/glob) on values from `std::env::args()`, because this crate is aware of argument quoting, and special characteres in quotes (`"*"`) are intentionally not expanded.
It is more robust than using [`glob()`](https://lib.rs/crates/glob) on values from `std::env::args()`, because this crate is aware of argument quoting, and special characteres in quotes (`"*"`) are intentionally not expanded.
The glob syntax on Windows is limited to `*`, `?`, and `[a-z]`/`[!a-z]` ranges, as supported by the glob crate. Parsing of quoted arguments precisely follows Windows' native syntax ([`CommandLineToArgvW`][1], specifically).
......@@ -14,16 +14,19 @@ The glob syntax on Windows is limited to `*`, `?`, and `[a-z]`/`[!a-z]` ranges,
`wild::args()` is a drop-in replacement for `std::env::args()`.
```rust
extern crate wild;
```toml
[dependencies]
wild = "2"
```
```rust
fn main() {
let args = wild::args();
println!("The args are: {:?}", args.collect::<Vec<_>>());
}
```
## Usage with [Clap](https://crates.rs/crates/clap)
## Usage with [Clap](https://lib.rs/crates/clap)
```rust
let matches = clap::App::new("your_app")
......
{"package":"97d34fecce28871e5c0e059deae21ef7f7d13b98a5964b24c58b3735c8052fc8","files":{}}
{"package":"05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74","files":{}}
rust-wild (2.1.0-1) unstable; urgency=medium
* Team upload.
* Package wild 2.1.0 from crates.io using debcargo 2.5.0
-- Sylvestre Ledru <sylvestre@debian.org> Wed, 14 Sep 2022 09:24:42 +0200
rust-wild (2.0.2-1) unstable; urgency=medium
* Team upload.
......
11
12
Source: rust-wild
Section: rust
Priority: optional
Build-Depends: debhelper (>= 11),
dh-cargo (>= 15),
Build-Depends: debhelper (>= 12),
dh-cargo (>= 25),
cargo:native <!nocheck>,
rustc:native <!nocheck>,
libstd-rust-dev <!nocheck>,
......@@ -10,10 +10,11 @@ Build-Depends: debhelper (>= 11),
Maintainer: Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
Uploaders:
Helen Koike <helen@koikeco.de>
Standards-Version: 4.2.0
Standards-Version: 4.5.1
Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/wild]
Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/wild
Homepage: https://crates.rs/crates/wild
Homepage: https://lib.rs/crates/wild
Rules-Requires-Root: no
Package: librust-wild-dev
Architecture: any
......@@ -25,10 +26,10 @@ Provides:
librust-wild+default-dev (= ${binary:Version}),
librust-wild-2-dev (= ${binary:Version}),
librust-wild-2+default-dev (= ${binary:Version}),
librust-wild-2.0-dev (= ${binary:Version}),
librust-wild-2.0+default-dev (= ${binary:Version}),
librust-wild-2.0.2-dev (= ${binary:Version}),
librust-wild-2.0.2+default-dev (= ${binary:Version})
librust-wild-2.1-dev (= ${binary:Version}),
librust-wild-2.1+default-dev (= ${binary:Version}),
librust-wild-2.1.0-dev (= ${binary:Version}),
librust-wild-2.1.0+default-dev (= ${binary:Version})
Description: Glob (wildcard) expanded command-line arguments on Windows - Rust source code
This package contains the source for the Rust wild crate, packaged by debcargo
for use with cargo and dh-cargo.
......@@ -5,7 +5,7 @@ Source: https://gitlab.com/kornelski/wild
Files: *
Copyright: FIXME (overlay) UNKNOWN-YEARS Kornel <kornel@geekhood.net>
License: MIT
License: Apache-2.0 or MIT
Comment:
FIXME (overlay): Since upstream copyright years are not available in
Cargo.toml, they were extracted from the upstream Git repository. This may not
......@@ -21,9 +21,13 @@ Comment:
Files: debian/*
Copyright:
2019 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
2019 Helen Koike <helen@koikeco.de>
License: MIT
2019-2022 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
2019-2022 Helen Koike <helen@koikeco.de>
License: Apache-2.0 or MIT
License: Apache-2.0
Debian systems provide the Apache 2.0 license in
/usr/share/common-licenses/Apache-2.0
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
......
Test-Command: /usr/share/cargo/bin/cargo-auto-test wild 2.1.0 --all-targets --all-features
Features: test-name=rust-wild:@
Depends: dh-cargo (>= 18), librust-glob-0.3+default-dev, @
Restrictions: allow-stderr, skip-not-installable
Test-Command: /usr/share/cargo/bin/cargo-auto-test wild 2.1.0 --all-targets
Features: test-name=librust-wild-dev:default
Depends: dh-cargo (>= 18), librust-glob-0.3+default-dev, @
Restrictions: allow-stderr, skip-not-installable
Test-Command: /usr/share/cargo/bin/cargo-auto-test wild 2.1.0 --all-targets --no-default-features
Features: test-name=librust-wild-dev:
Depends: dh-cargo (>= 18), librust-glob-0.3+default-dev, @
Restrictions: allow-stderr, skip-not-installable
......@@ -2,4 +2,3 @@ version=4
opts=filenamemangle=s/.*\/(.*)\/download/wild-$1\.tar\.gz/g,\
uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/ \
https://qa.debian.org/cgi-bin/fakeupstream.cgi?upstream=crates.io/wild .*/crates/wild/@ANY_VERSION@/download
use globiter::*;
use crate::globiter::GlobArgs;
use std::ffi::OsString;
use glob;
use std::fmt;
/// Windows replacement for `std::env::ArgsOs`
......@@ -75,13 +74,13 @@ impl Iterator for ArgsOs {
}
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
impl fmt::Debug for ArgsOs {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.args.as_ref().map(|args| args.fmt(f))
.unwrap_or_else(|| "".fmt(f))
}
......
use crate::parser::CommandLineWParser;
use crate::parser::CharCode;
use std::ffi::OsString;
use parser;
use std::fmt;
pub(crate) struct ArgOs {
......@@ -10,13 +11,13 @@ pub(crate) struct ArgOs {
/// Iterator retuning glob-escaped arguments. Call `args()` to obtain it.
#[must_use]
pub(crate) struct GlobArgs<'a> {
line: &'a [u16],
pub(crate) struct GlobArgs<'argsline> {
parser: CommandLineWParser<'argsline>,
}
impl<'a> fmt::Debug for GlobArgs<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
String::from_utf16_lossy(self.line).fmt(f)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.parser.fmt(f)
}
}
......@@ -37,37 +38,53 @@ impl LossyOsStringExt for OsString {}
impl<'a> Iterator for GlobArgs<'a> {
type Item = ArgOs;
fn next(&mut self) -> Option<Self::Item> {
let state = (vec![], vec![], false);
let (state, rest) = parser::next_arg(self.line, state, |&mut (ref mut arg, ref mut text, ref mut contains_glob), c, quoted| {
let mut pattern = vec![];
let mut text = vec![];
let mut contains_glob = false;
let has_arg = self.parser.accumulate_next(|c| {
let (quoted, c) = match c {
CharCode::Quoted(c) => (true, c),
CharCode::Unquoted(c) => (false, c),
};
text.push(c);
match c as u8 {
b'?' | b'*' | b'[' | b']' if c < 256 => {
const Q: u16 = b'?' as u16;
const A: u16 = b'*' as u16;
const L: u16 = b'[' as u16;
const R: u16 = b']' as u16;
match c {
Q | A | L | R => {
if quoted {
arg.push(u16::from(b'['));
arg.push(c);
arg.push(u16::from(b']'));
pattern.extend([
u16::from(b'['),
c,
u16::from(b']'),
].iter().copied());
} else {
arg.push(c);
*contains_glob = true;
pattern.push(c);
contains_glob = true;
}
},
_ => arg.push(c),
_ => pattern.push(c),
};
});
self.line = rest;
state.map(|(pattern, text, contains_glob)| ArgOs {
pattern: OsString::from_wide(&pattern),
text: OsString::from_wide(&text),
contains_glob,
})
if has_arg {
Some(ArgOs {
pattern: OsString::from_wide(&pattern),
text: OsString::from_wide(&text),
contains_glob,
})
} else {
None
}
}
}
impl<'a> GlobArgs<'a> {
impl<'argsline> GlobArgs<'argsline> {
/// UTF-16/UCS2 string from `GetCommandLineW`
#[allow(dead_code)]
pub(crate) fn new(line: &'a [u16]) -> Self {
Self { line }
pub(crate) fn new(command_line_args_ucs2: &'argsline [u16]) -> Self {
Self {
parser: CommandLineWParser::new(command_line_args_ucs2),
}
}
}
#![cfg_attr(docsrs, feature(doc_cfg))]
//! Emulates glob (wildcard) argument expansion on Windows. No-op on other platforms.
//!
//! Unix shells expand command-line arguments like `a*`, `file.???` and pass them expanded to applications.
......@@ -14,29 +15,28 @@
//!
//! Use `wild::args()` instead of `std::env::args()` (or `wild::args_os()` instead of `std::env::args_os()`).
//!
//! If you use [Clap](https://crates.rs/crates/clap), use `.get_matches_from(wild::args())` instead of `.get_matches()`.
//! If you use [Clap](https://lib.rs/crates/clap), use `.get_matches_from(wild::args())` instead of `.get_matches()`.
#[cfg(any(test,windows))]
extern crate glob;
/// An optional, experimental low-level interface for parsing command-line strings from other sources. In most cases [`args`] and [`args_os`] are more appropriate.
#[cfg(any(test, windows))]
pub mod parser;
#[cfg(any(test,windows))]
mod parser;
#[cfg(any(test, windows))]
mod globiter;
#[cfg(any(test,windows))]
#[cfg(any(test, windows))]
mod argsiter;
#[cfg(windows)]
pub use argsiter::*;
#[cfg(any(test,windows))]
mod globiter;
pub use crate::argsiter::*;
/// Iterator of arguments. Equivalent to `std::env::Args`. See `args()` for details.
/// Iterator of arguments. Equivalent to `std::env::Args`. See [`args`] for details.
///
/// On unix it's an alias for `std::env::Args`.
/// On Windows it's a custom iterator that implements glog expansion.
#[cfg(not(windows))]
pub type Args = std::env::Args;
/// Same as [`Args`], but keeps invalid Unicode intact.
#[cfg(not(windows))]
pub type ArgsOs = std::env::ArgsOs;
......@@ -50,11 +50,13 @@ pub type ArgsOs = std::env::ArgsOs;
/// the file system as it parses. This allows reading potentially huge lists of
/// filenames, but it's not an atomic snapshot (use `.collect()` if you need that).
#[cfg(not(windows))]
#[must_use]
pub fn args() -> Args {
std::env::args()
}
#[cfg(not(windows))]
#[must_use]
pub fn args_os() -> ArgsOs {
std::env::args_os()
}
......@@ -69,14 +71,14 @@ pub fn args_os() -> ArgsOs {
/// On non-Windows platforms it returns `env::args()` as-is,
/// assuming expansion has already been done by the shell.
#[cfg(windows)]
#[must_use]
pub fn args() -> Args {
Args {
iter: args_os(),
}
Args { iter: args_os() }
}
/// Same as `args()`, but returns `OsString`
/// Same as [`args`], but returns `OsString`
#[cfg(windows)]
#[must_use]
pub fn args_os() -> ArgsOs {
ArgsOs {
args: globs(),
......@@ -107,7 +109,7 @@ fn raw_command_line() -> Option<&'static [u16]> {
return None;
}
let mut len = 0;
while *line_ptr.offset(len as isize) != 0 {
while *line_ptr.add(len) != 0 {
len += 1;
}
Some(std::slice::from_raw_parts(line_ptr, len))
......
use std::fmt;
/// An experimental, low-level access to each individual character of raw arguments.
#[must_use]
pub struct CommandLineWParser<'argsline> {
line: &'argsline [u16],
}
impl<'argsline> CommandLineWParser<'argsline> {
#[inline]
#[must_use]
pub fn new(command_line_args_ucs2: &'argsline [u16]) -> Self {
Self {
line: command_line_args_ucs2,
}
}
}
impl<'a> fmt::Debug for CommandLineWParser<'a> {
#[cold]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
String::from_utf16_lossy(self.line).fmt(f)
}
}
#[derive(Debug)]
enum State {
......@@ -7,101 +31,117 @@ enum State {
Backslashes(usize, bool),
}
/// A single code unit, which may be UCS-2 or half-broken UTF-16. Not a character.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CharCode {
/// This code unit was found inside quotes (it's just text)
Quoted(u16),
/// This code unit was found outside quotes (you could interpret it as a glob)
Unquoted(u16),
}
/// Given UCS2/potentially-broken-UTF-16 string parses one argument, following
/// the absolutely bizarre quoting rules of `CommandLineToArgvW`, and returns
/// parsed argument as well as a slice of the remaining arguments.
/// a bool indicating whether there's anything moe left.
///
/// Calling this repeatedly until rest is empty will parse all arguments.
/// Calling this repeatedly until it returns false will parse all arguments.
///
/// `arg` is an empty pre-allocated argument to be returned, and the callback adds a new code unit to it.
/// The last callback argument is whether the unit was quoted or not.
/// The callback is expected to accumulate code units itself.
///
/// This parses u16 code units, rather than code points.
/// This allows supporting unpaired surrogates and ensures they won't "eat" any control characters.
pub fn next_arg<AddC, ArgVec>(line: &[u16], mut arg: ArgVec, push: AddC) -> (Option<ArgVec>, &[u16])
where
AddC: Fn(&mut ArgVec, u16, bool),
{
use self::State::*;
let mut state = BetweenArgs;
for (i, &cu) in line.iter().enumerate() {
state = match state {
BetweenArgs => match cu {
c if c == u16::from(b' ') => BetweenArgs,
c if c == u16::from(b'"') => InArg(true),
c if c == u16::from(b'\\') => Backslashes(1, false),
c => {
push(&mut arg, c, false);
InArg(false)
},
},
InArg(quoted) => match cu {
c if c == u16::from(b'\\') => Backslashes(1, quoted),
c if quoted && c == u16::from(b'"') => OnQuote,
c if !quoted && c == u16::from(b'"') => InArg(true),
c if !quoted && c == u16::from(b' ') => {
return (Some(arg), &line[i+1..]);
impl<'argsline> CommandLineWParser<'argsline> {
pub fn accumulate_next<CharacterAccumulator>(&mut self, mut push: CharacterAccumulator) -> bool
where CharacterAccumulator: FnMut(CharCode)
{
use self::State::*;
let mut state = BetweenArgs;
for (i, &cu) in self.line.iter().enumerate() {
state = match state {
BetweenArgs => match cu {
c if c == u16::from(b' ') => BetweenArgs,
c if c == u16::from(b'"') => InArg(true),
c if c == u16::from(b'\\') => Backslashes(1, false),
c => {
push(CharCode::Unquoted(c));
InArg(false)
},
},
c => {
push(&mut arg, c, quoted);
InArg(quoted)
},
},
OnQuote => match cu {
c if c == u16::from(b'"') => {
// In quoted arg "" means literal quote and the end of the quoted string (but not arg)
push(&mut arg, u16::from(b'"'), true);
InArg(false)
},
c if c == u16::from(b' ') => {
return (Some(arg), &line[i+1..]);
InArg(quoted) => match cu {
c if c == u16::from(b'\\') => Backslashes(1, quoted),
c if quoted && c == u16::from(b'"') => OnQuote,
c if !quoted && c == u16::from(b'"') => InArg(true),
c if !quoted && c == u16::from(b' ') => {
self.line = &self.line[i+1..];
return true;
},
c => {
push(if quoted { CharCode::Quoted(c) } else { CharCode::Unquoted(c) });
InArg(quoted)
},
},
c => {
push(&mut arg, c, false);
InArg(false)
OnQuote => match cu {
c if c == u16::from(b'"') => {
// In quoted arg "" means literal quote and the end of the quoted string (but not arg)
push(CharCode::Quoted(u16::from(b'"')));
InArg(false)
},
c if c == u16::from(b' ') => {
self.line = &self.line[i+1..];
return true;
},
c => {
push(CharCode::Unquoted(c));
InArg(false)
},
},
},
Backslashes(count, quoted) => match cu {
c if c == u16::from(b'\\') => Backslashes(count + 1, quoted),
c if c == u16::from(b'"') => {
// backslashes followed by a quotation mark are treated as pairs of protected backslashes
for _ in 0..count/2 {
push(&mut arg, u16::from(b'\\'), quoted);
}
Backslashes(count, quoted) => match cu {
c if c == u16::from(b'\\') => Backslashes(count + 1, quoted),
c if c == u16::from(b'"') => {
// backslashes followed by a quotation mark are treated as pairs of protected backslashes
let b = if quoted { CharCode::Quoted(u16::from(b'\\')) } else { CharCode::Unquoted(u16::from(b'\\')) };
for _ in 0..count/2 {
push(b);
}
if count & 1 != 0 {
// An odd number of backslashes is treated as followed by a protected quotation mark.
push(&mut arg, u16::from(b'"'), quoted);
InArg(quoted)
} else if quoted {
// An even number of backslashes is treated as followed by a word terminator.
return (Some(arg), &line[i+1..]);
} else {
if count & 1 != 0 {
// An odd number of backslashes is treated as followed by a protected quotation mark.
let c = u16::from(b'"');
push(if quoted { CharCode::Quoted(c) } else { CharCode::Unquoted(c) });
InArg(quoted)
} else if quoted {
// An even number of backslashes is treated as followed by a word terminator.
self.line = &self.line[i+1..];
return true;
} else {
InArg(quoted)
}
},
c => {
// A string of backslashes not followed by a quotation mark has no special meaning.
let b = if quoted { CharCode::Quoted(u16::from(b'\\')) } else { CharCode::Unquoted(u16::from(b'\\')) };
for _ in 0..count {
push(b);
}
push(if quoted { CharCode::Quoted(c) } else { CharCode::Unquoted(c) });
InArg(quoted)
}
},
},
c => {
// A string of backslashes not followed by a quotation mark has no special meaning.
for _ in 0..count {
push(&mut arg, u16::from(b'\\'), quoted);
}
push(&mut arg, c, quoted);
InArg(quoted)
},
},
}
}
let arg = match state {
BetweenArgs => false,
OnQuote | InArg(..) => true,
Backslashes(count, quoted) => {
// A string of backslashes not followed by a quotation mark has no special meaning.
let b = if quoted { CharCode::Quoted(u16::from(b'\\')) } else { CharCode::Unquoted(u16::from(b'\\')) };
for _ in 0..count {
push(b);
}
true
},
};
self.line = &self.line[..0];
arg
}
let arg = match state {
BetweenArgs => None,
OnQuote | InArg(..) => Some(arg),
Backslashes(count, quoted) => {
// A string of backslashes not followed by a quotation mark has no special meaning.
for _ in 0..count {
push(&mut arg, u16::from(b'\\'), quoted);
}
Some(arg)
},
};
(arg, &line[..0])
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment