summaryrefslogtreecommitdiffstats
path: root/vendor/comma
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
commite02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch)
treefd60ebbbb5299e16e5fca8c773ddb74f764760db /vendor/comma
parentAdding debian version 1.73.0+dfsg1-1. (diff)
downloadrustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz
rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/comma')
-rw-r--r--vendor/comma/.cargo-checksum.json1
-rw-r--r--vendor/comma/Cargo.toml26
-rw-r--r--vendor/comma/README.md26
-rw-r--r--vendor/comma/src/lib.rs90
4 files changed, 143 insertions, 0 deletions
diff --git a/vendor/comma/.cargo-checksum.json b/vendor/comma/.cargo-checksum.json
new file mode 100644
index 000000000..5ab64dc2e
--- /dev/null
+++ b/vendor/comma/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"1948b6f99c75b25f6b70dab12155ba2854cdcebd18d823a3b84f3ea7a57e382c","README.md":"04da7267815159c07eae7f9802697cde66c49c8f2cca190c7f657841eb1dc0a8","src/lib.rs":"4beb857981727fbdd3142301bb2f945e88437320296da6d39b266aeaddbfdb22"},"package":"55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"} \ No newline at end of file
diff --git a/vendor/comma/Cargo.toml b/vendor/comma/Cargo.toml
new file mode 100644
index 000000000..2d0a24a09
--- /dev/null
+++ b/vendor/comma/Cargo.toml
@@ -0,0 +1,26 @@
+# 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]
+edition = "2018"
+name = "comma"
+version = "1.0.0"
+authors = ["Ethan McTague <ethan@tague.me>"]
+exclude = ["target", ".idea/*", ".gitignore"]
+description = "Shell-style command parser with support for escaping and quotations."
+readme = "README.md"
+keywords = ["string", "parse", "parsing", "command", "shell"]
+categories = ["command-line-interface", "parsing", "parser-implementations"]
+license = "MIT"
+repository = "https://github.com/emctague/comma"
+
+[dependencies]
diff --git a/vendor/comma/README.md b/vendor/comma/README.md
new file mode 100644
index 000000000..a6d9f5f60
--- /dev/null
+++ b/vendor/comma/README.md
@@ -0,0 +1,26 @@
+# comma
+
+[![Crates.io](https://img.shields.io/crates/v/comma?style=flat-square)](https://crates.io/crates/comma)
+[![docs.rs](https://docs.rs/comma/badge.svg)](https://docs.rs/comma)
+[![Build Status](https://travis-ci.org/emctague/comma.svg?branch=master)](https://travis-ci.org/emctague/comma)
+
+`comma` splits shell-style commands, e.g. `sendmsg joe "I say \"hi\" to you!"`, into a list of individual tokens.
+It correctly handles unicode characters, escape sequences, and single- or double-quoted strings.
+
+## Cargo
+
+```toml
+[dependencies]
+comma = "1.0.0"
+```
+
+## Usage
+
+```rust
+use comma::parse_command;
+
+fn main () {
+ let parsed = parse_command("sendmsg joe \"I say \\\"hi\\\" to you!\" 'but only\\ntoday'").unwrap();
+ println!("Result: {:#?}", parsed); // Result: [ "sendmsg", "joe", "I say \"hi\" to you!", "but only\ntoday" ]
+}
+``` \ No newline at end of file
diff --git a/vendor/comma/src/lib.rs b/vendor/comma/src/lib.rs
new file mode 100644
index 000000000..d82154e48
--- /dev/null
+++ b/vendor/comma/src/lib.rs
@@ -0,0 +1,90 @@
+//! `comma` parses command-line-style strings. See [`parse_command`] for details.
+
+use std::iter::{Peekable};
+use std::str::{Chars};
+
+fn parse_escape(chars: &mut Peekable<Chars>) -> Option<char> {
+ return Some(match chars.next()? {
+ 'n' => '\n',
+ 'r' => '\r',
+ 't' => '\t',
+ literal => literal
+ })
+}
+
+fn parse_string(chars: &mut Peekable<Chars>, delim: char) -> Option<String> {
+ let mut output = String::new();
+
+ while let Some(ch) = chars.next() {
+ if ch == delim {
+ return Some(output)
+ } else if ch == '\\' {
+ output.push(parse_escape(chars)?);
+ } else {
+ output.push(ch);
+ }
+ }
+
+ return None
+}
+
+/// Parses a command into a list of individual tokens.
+/// Each token is separated by one or more characters of whitespace.
+/// Pairs of single- or double-quotes can be used to ignore whitespace. Within pairs of quotation
+/// marks, a backslash (\) can be used to escape any character. The special escape sequences
+/// '\n', '\r', and '\t' are also handled as Newlines, Carriage Returns, and Tabs, respectively.
+/// Should a quotation mark be mismatched (no counterpart terminating mark exists), this function
+/// will return None. Otherwise, it returns a list of tokens in the input string.
+pub fn parse_command(input: &str) -> Option<Vec<String>> {
+ let mut next_push = true;
+ let mut chars = input.chars().peekable();
+ let mut output : Vec<String> = Vec::new();
+
+ while let Some(ch) = chars.next() {
+ if ch.is_whitespace() {
+ next_push = true;
+ } else{
+ if next_push { output.push(String::new()); next_push = false; }
+
+ if ch == '\\' {
+ output.last_mut()?.push(parse_escape(&mut chars)?);
+ } else if ch == '"' || ch == '\'' {
+ output.last_mut()?.push_str(parse_string(&mut chars, ch)?.as_str());
+ } else {
+ output.last_mut()?.push(ch);
+ }
+ }
+ }
+
+ return Some(output)
+}
+
+
+#[cfg(test)]
+mod tests {
+ use crate::{parse_command};
+
+ #[test]
+ fn parsing_works() {
+ let result = parse_command("hello world \\'this is\\' a \"quoted \\\"string\\\"\"").unwrap();
+ assert_eq!(result,
+ vec![String::from("hello"), String::from("world"),
+ String::from("'this"), String::from("is'"), String::from("a"),
+ String::from("quoted \"string\"")]);
+ }
+
+ #[test]
+ fn fail_mismatch() {
+ assert_eq!(parse_command("Hello 'world "), None);
+ }
+
+ #[test]
+ fn unicode() {
+ // This contains a CJK IDEOGRAPH EXTENSION G character, which is invisible.
+ let result = parse_command("ß 𱁬").unwrap();
+ assert_eq!(
+ result,
+ vec![String::from("ß"), String::from("𱁬")]
+ );
+ }
+}