Skip to content

Commit

Permalink
switched to simple counter
Browse files Browse the repository at this point in the history
  • Loading branch information
admercs committed Apr 17, 2024
1 parent 9866513 commit dff2dc6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 30 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.vscode/
.vscode/

Manifest.toml
4 changes: 1 addition & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name = "SimpleArgParse"
uuid = "4c739d64-e22d-44e1-ada1-53a1c3c0e953"
authors = ["Adam Erickson <adam.michael.erickson@gmail.com>"]
version = "1.0.1"
version = "1.1.0"

[deps]
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
julia = "1.0"
Expand Down
43 changes: 17 additions & 26 deletions src/SimpleArgParse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ module SimpleArgParse

export ArgumentParser, add_argument, add_example, generate_usage, help, parse_args, get_value, set_value, has_key, get_key, colorize

using Base
using SHA: sha256
using OrderedCollections: OrderedDict

###
### Data Structures
###
### Data Structures ###

"Command-line argments."
struct Arguments
Expand All @@ -32,6 +26,8 @@ mutable struct ArgumentParser
kv_store::OrderedDict{UInt16,ArgumentValues}
"key-value store: { arg: key }"
arg_store::OrderedDict{String,UInt16}
"key-value counter"
key_count::UInt16
# attributes
"file name"
filename::String
Expand All @@ -52,21 +48,19 @@ mutable struct ArgumentParser
"flag to automatically generate a help message"
add_help::Bool
"empty constructor"
ArgumentParser() = new(OrderedDict(), OrderedDict(), "", "", "", "", "", "", "", "", false)
ArgumentParser() = new(OrderedDict(), OrderedDict(), 0, "", "", "", "", "", "", "", "", false)
"keyword argument constructor"
function ArgumentParser(;
filename="", description::String="", authors::Vector{String}=String[],
documentation::String="", repository::String="", license::String="",
usage::String="", examples::Vector{String}=String[], add_help::Bool=false)
:ArgumentParser
new(OrderedDict(), OrderedDict(), filename, description, authors, documentation,
new(OrderedDict(), OrderedDict(), 0, filename, description, authors, documentation,
repository, license, usage, examples, add_help)
end
end

###
### Functions
###
### Functions ###

"Extract struct members to vector."
function args2vec(args::Arguments)
Expand All @@ -86,7 +80,7 @@ end
"Argument to argument-store key conversion by removing hypenation from prefix."
function arg2key(arg::String)
:String
return strip(arg, '-')
return lstrip(arg, '-')
end

"Add command-line argument to ArgumentParser object instance."
Expand All @@ -107,14 +101,13 @@ function add_argument(parser::ArgumentParser, arg_short::String="", arg_long::St
"""
:ArgumentParser
args::Arguments = Arguments(arg_short, arg_long)
# prefer stripped long argument for higher entropy
arg::String = !isempty(arg_long) ? arg_long : !isempty(arg_short) ? arg_short : ""
isempty(arg) && error("Argument(s) missing. See usage examples.")
# remove prepended hyphenation to increase entropy
argkey::String = arg2key(arg)
# key is first two bytes of SHA-256 hash of argument name; up to 65,536 argument keys
key::UInt16 = read(IOBuffer(sha256(argkey)[1:2]), UInt16)
# map both argument names to the same key
# key index is a simple counter.
parser.key_count += 1
key::UInt16 = parser.key_count
# map both argument names to the same key.
!isempty(arg_short) && (parser.arg_store[arg2key(arg_short)] = key)
!isempty(arg_long) && (parser.arg_store[arg2key(arg_long)] = key)
default = type == Any ? default : convert(type, default)
Expand Down Expand Up @@ -204,7 +197,7 @@ function parse_args(parser::ArgumentParser)
continue
end
# if next iteration is at the end or is an argument, treat current argument as flag/boolean
# otherwise, capture the value and skip iterating over it for efficiency
# otherwise, capture the value and skip iterating over it for efficiency.
if (i + 1 > n) || startswith(ARGS[i+1], "-")
value = true
elseif (i + 1 <= n)
Expand All @@ -213,9 +206,9 @@ function parse_args(parser::ArgumentParser)
else
error("Value failed to parse for arg: $(arg)")
end
# extract default value and update given an argument value
# extract default value and update given an argument value.
values::ArgumentValues = parser.kv_store[key]
# type cast value into tuple index 1
# type cast value into tuple index 1.
value = values.type == Any ? value : parse(values.type, value)
parser.kv_store[key] = ArgumentValues(values.args, value, values.type, values.required, values.description)
end
Expand Down Expand Up @@ -251,7 +244,7 @@ end
"Prepend hyphenation back onto argument after stripping it for the argument-store key."
function hyphenate(arg::String)
:String
argkey::String = arg2key(arg) # supports "foo" or "--foo" argument form
argkey::String = arg2key(arg) # supports "foo" or "--foo" argument form.
result::String = length(argkey) == 1 ? "-" * argkey : "--" * argkey
return result
end
Expand All @@ -278,9 +271,7 @@ Base.parse(::Type{String}, x::Bool) = x ? "true" : "false"
Base.convert(::Type{Char}, x::Nothing) = ' '
Base.convert(::Type{String}, x::Nothing) = ""

###
### Utilities
###
### Utilities ###

"Key-value store mapping from colors to ANSI codes."
ANSICODES::Base.ImmutableDict{String,Int} = Base.ImmutableDict(
Expand Down Expand Up @@ -325,4 +316,4 @@ function colorize(text::String; color::String="default", background::Bool=false,
return "\033[" * code_string * "m" * text * "\033[0m"
end

end # module SimpleArgParse
end # module SimpleArgParse

0 comments on commit dff2dc6

Please sign in to comment.