Merge branch 'rust'
This commit is contained in:
commit
e6a82cfd36
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
target/
|
288
Cargo.lock
generated
Normal file
288
Cargo.lock
generated
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.63.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"peeking_take_while",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
"shlex",
|
||||||
|
"syn",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.147"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peeking_take_while"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.171"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomcat"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"toml",
|
||||||
|
"yacexits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yacexits"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53fe740dd05c1bbc919431e842e6c1bea30195e0518ae99cae35b7f0730ddc18"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"libc",
|
||||||
|
]
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "tomcat"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "AGPL-3.0-or-later"
|
||||||
|
authors = [ "Emma Tebibyte <emma@tebibyte.media>" ]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
toml = "0.5.9"
|
||||||
|
yacexits = "0.1.2"
|
33
README.md
33
README.md
@ -1,10 +1,33 @@
|
|||||||
`tomcat` – a [TOML](https://toml.io) parser in POSIX shell
|
`tomcat` – a minimal [TOML](https://toml.io) parser for the command line.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### From Source
|
### From Source
|
||||||
|
|
||||||
Clone this repository and move the `tomcat` binary wherever your operating
|
1. Run `cargo --install --git https://git.tebibyte.media/emma/tomcat.git`
|
||||||
system stores locally-installed binaries. This is usually `/usr/local/bin` or
|
2. ???
|
||||||
`$HOME/.local/bin` for your user. Make sure the installation location is in your
|
3. Profit
|
||||||
`$PATH`.
|
|
||||||
|
Also make sure that your cargo `bin` directory (by default in
|
||||||
|
`"$CARGO_HOME"/bin`) is in your `$PATH`; I recommend symlinking the folder to
|
||||||
|
`"$HOME/.local/bin` and adding that to your user `$PATH`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Assuming the TOML file being parsed is `file.toml`:
|
||||||
|
|
||||||
|
To get the value of top-level key `notable`:
|
||||||
|
|
||||||
|
`tomcat notable file.toml`
|
||||||
|
|
||||||
|
To get the value of `key` from the `main` table:
|
||||||
|
|
||||||
|
`tomcat main.key file.toml`
|
||||||
|
|
||||||
|
To get the value of `key` from the subtable `subtab` in table `main`:
|
||||||
|
|
||||||
|
`tomcat main.subtab.key file.toml`
|
||||||
|
|
||||||
|
To get the value of index `3` in array `arr` in table `main`:
|
||||||
|
|
||||||
|
`tomcat main.arr[3] file.toml`
|
||||||
|
171
src/main.rs
Normal file
171
src/main.rs
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022–2023 Emma Tebibyte
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
env::args,
|
||||||
|
fs::File,
|
||||||
|
io::Read,
|
||||||
|
iter::Peekable,
|
||||||
|
os::fd::{ FromRawFd },
|
||||||
|
path::Path,
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
use toml::Value;
|
||||||
|
use yacexits::*;
|
||||||
|
|
||||||
|
fn parse_toml(
|
||||||
|
mut root: Value,
|
||||||
|
mut tabkey: Peekable<std::slice::Iter<'_, &str>>,
|
||||||
|
index: Option<usize>,
|
||||||
|
) -> Result<String, (String, u32)> {
|
||||||
|
let mut out = String::new();
|
||||||
|
|
||||||
|
while let Some(item) = tabkey.next() {
|
||||||
|
let mut value = match root.get(item) {
|
||||||
|
Some(val) => val,
|
||||||
|
None => {
|
||||||
|
return Err((format!("{}: No such table or key.", item), EX_DATAERR));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
match value {
|
||||||
|
Value::Array(array) => {
|
||||||
|
let i = match index {
|
||||||
|
Some(i) => i,
|
||||||
|
None => {
|
||||||
|
for v in array.iter() {
|
||||||
|
out.push_str(&format!("{}\n", v.to_string()));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
match array.get(i) {
|
||||||
|
Some(val) => value = val,
|
||||||
|
None => {
|
||||||
|
return Err((format!("No value at index {}.", i), EX_DATAERR));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
Value::Table(table) => {
|
||||||
|
if tabkey.peek().is_some() {
|
||||||
|
root = toml::Value::Table(table.to_owned());
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
if tabkey.peek().is_some() {
|
||||||
|
return Err((format!("{}: Not a table.", item), EX_DATAERR));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
match value {
|
||||||
|
Value::Array(_) => {},
|
||||||
|
Value::Boolean(boolean) => out.push_str(&format!("{:?}\n", boolean)),
|
||||||
|
Value::Datetime(datetime) => out.push_str(&format!("{:?}\n", datetime)),
|
||||||
|
Value::Float(float) => out.push_str(&format!("{:?}\n", float)),
|
||||||
|
Value::Integer(int) => out.push_str(&format!("{:?}\n", int)),
|
||||||
|
Value::String(string) => {
|
||||||
|
let contents = string.to_owned();
|
||||||
|
let mut lines: Vec<&str> = contents.lines().collect();
|
||||||
|
if lines.last().unwrap().is_empty() { _ = lines.pop(); }
|
||||||
|
|
||||||
|
for line in lines.iter() { out.push_str(&format!("{}\n", line)); }
|
||||||
|
},
|
||||||
|
_ => return Err((format!("{:?}: No such key.", item), EX_DATAERR)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let argv: Vec<String> = args().collect();
|
||||||
|
let usage_info = format!("Usage: {} [table.]key[[index]] [file...]", argv[0]);
|
||||||
|
|
||||||
|
if argv.len() <= 1 {
|
||||||
|
eprintln!("{}", usage_info);
|
||||||
|
exit(EX_USAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
let input = argv.get(2).unwrap_or(&"".to_owned()).to_owned();
|
||||||
|
|
||||||
|
let mut content = Vec::new();
|
||||||
|
|
||||||
|
match input.as_str() {
|
||||||
|
"-" | "" => unsafe { File::from_raw_fd(0) },
|
||||||
|
_ => {
|
||||||
|
File::open(Path::new(&input)).unwrap_or_else(|_| {
|
||||||
|
eprintln!(
|
||||||
|
"{}: {}: No such file or directory.",
|
||||||
|
argv[0],
|
||||||
|
&input
|
||||||
|
);
|
||||||
|
exit(EX_UNAVAILABLE);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}.read_to_end(&mut content).unwrap_or_else(|_| {
|
||||||
|
eprintln!("{}: Could not read input.", argv[0]);
|
||||||
|
exit(EX_OSERR);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let mut tabkey: Vec<&str> = argv[1].split(".").collect();
|
||||||
|
let mut indexvec = Vec::new();
|
||||||
|
let mut index: Option<usize> = None;
|
||||||
|
|
||||||
|
if tabkey.iter().skip(1).peekable().peek().is_some() {
|
||||||
|
indexvec = tabkey[1].split(&['[', ']'][..]).collect();
|
||||||
|
tabkey[1] = indexvec.remove(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ! indexvec.is_empty() {
|
||||||
|
let istr = indexvec.remove(0);
|
||||||
|
match usize::from_str(istr) {
|
||||||
|
Ok(i) => index = Some(i),
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("{}: {}: Cannot index by given value.", argv[0], istr);
|
||||||
|
exit(EX_USAGE);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let root = String::from_utf8(content)
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
eprintln!("{}: Input is not valid UTF-8.", argv[0]);
|
||||||
|
exit(EX_DATAERR);
|
||||||
|
})
|
||||||
|
.parse::<Value>()
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
eprintln!("{}: Unable to parse TOML.", argv[0]);
|
||||||
|
exit(EX_DATAERR);
|
||||||
|
});
|
||||||
|
|
||||||
|
let valiter = tabkey.iter().peekable();
|
||||||
|
print!(
|
||||||
|
"{}",
|
||||||
|
match parse_toml(root, valiter, index) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err((err, code)) => {
|
||||||
|
eprintln!("{}: {}", argv[0], err);
|
||||||
|
exit(code);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
73
tomcat
73
tomcat
@ -1,73 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
argv0="$0"
|
|
||||||
argv1="$1"
|
|
||||||
argv2="$2"
|
|
||||||
|
|
||||||
# check usage
|
|
||||||
if ! test -n "$1"; then
|
|
||||||
printf "Usage: %s [OPTIONS] [TABLE.KEY[INDEX]] [FILE]\n" "$0" 1>&2
|
|
||||||
exit 64 # sysexits(3) EX_USAGE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# test if input has a period
|
|
||||||
if test -n "$(printf "%s\n" "$argv1" | sed -n '/.*\..*/p')"; then
|
|
||||||
# cut out everything beyond the first period for TABLE
|
|
||||||
TABLE=$(printf "%s\n" "$argv1" | sed -n 's/\..*//p')
|
|
||||||
|
|
||||||
# cut out everything before the first period for KEY
|
|
||||||
KEY=$(printf "%s\n" "$argv1" | sed -n 's/^[^.]*\.//p')
|
|
||||||
! test -n "$KEY" &&\
|
|
||||||
printf "%s: No key specified\n" "$argv0" 1>&2 &&\
|
|
||||||
exit 65 # sysexits(3) EX_DATAERR
|
|
||||||
else
|
|
||||||
printf "%s: No key specified\n" "$argv0" 1>&2
|
|
||||||
exit 65 # sysexits(3) EX_DATAERR
|
|
||||||
fi
|
|
||||||
|
|
||||||
# remove array index from KEY
|
|
||||||
KEY=$(printf "%s\n" "$KEY" | sed 's/\[.*\]//g')
|
|
||||||
# set ARR to the array index
|
|
||||||
ARR=$(printf "%s\n" "$argv1" | sed -n 's/.\+\[//p' | tr -d ']')
|
|
||||||
|
|
||||||
# test if argument 2 is a file or not
|
|
||||||
if test -e "$argv2"; then
|
|
||||||
# set TOML to the text from the file
|
|
||||||
TOML=$(sed 's/[^"#]#\+.*//g' <"$argv2" | sed 's/^#.*//g' )
|
|
||||||
else
|
|
||||||
# set TOML to the text from stdin
|
|
||||||
TOML=$(printf "%s\n" "$argv2" | sed 's/[^"#]#\+.*//g')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -n "$TABLE"; then
|
|
||||||
KEYS=$(printf "%s\n" "$TOML" |\
|
|
||||||
# output only lines between TABLE and the next table
|
|
||||||
awk "/^\[$TABLE\]/{flag=1; next} /^\[/{flag=0} flag" - )
|
|
||||||
else
|
|
||||||
KEYS=$(printf "%s\n" "$TOML" |\
|
|
||||||
# output only lines before the first table
|
|
||||||
awk '1;/^\[/{exit}' - | sed -n '/^[^[]/p')
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set VAL to the parsed KEYS list
|
|
||||||
VAL=$(printf "%s\n" "$KEYS" |\
|
|
||||||
# remove the key from the string and delineate arrays, removing
|
|
||||||
# brackets, trailing commas, and leading spaces
|
|
||||||
sed -n "s/$KEY *= *//p" | sed 's/", "/ /g' | tr -d '[]"' |\
|
|
||||||
sed 's/, *$//g' | sed 's/^ \+//g' | sed 's/ \+$//g')
|
|
||||||
|
|
||||||
# test if ARR is set; if it is, then we have an array index to grab
|
|
||||||
if test -n "$ARR"; then
|
|
||||||
# change the line delineator to newlines for parsing and output the result
|
|
||||||
printf "%s\n" "$VAL" | sed 's/ /\n/g' | head -n "$ARR" |\
|
|
||||||
tail -n 1
|
|
||||||
elif ! test -n "$VAL"; then
|
|
||||||
printf "%s: %s: No such key or table\n" "$argv0" "$argv1" 1>&2
|
|
||||||
exit 65 # sysexits(3) EX_DATAERR
|
|
||||||
else
|
|
||||||
printf "%s\n" "$VAL"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
Loading…
Reference in New Issue
Block a user