view release on metacpan or search on metacpan
script/gen-generic-ind-company-names view on Meta::CPAN
unshift @INC, sub {
$toc ||= do {
my $fh = \*DATA;
my $header_line;
my $header_found;
while (1) {
my $header_line = <$fh>;
defined($header_line)
or die "Unexpected end of data section while reading header line";
chomp($header_line);
if ($header_line eq 'Data::Section::Seekable v1') {
$header_found++;
last;
}
}
die "Can't find header 'Data::Section::Seekable v1'"
unless $header_found;
my %toc;
my $i = 0;
while (1) {
$i++;
my $toc_line = <$fh>;
defined($toc_line)
or die "Unexpected end of data section while reading TOC line #$i";
chomp($toc_line);
$toc_line =~ /\S/ or last;
$toc_line =~ /^([^,]+),(\d+),(\d+)(?:,(.*))?$/
or die "Invalid TOC line #$i in data section: $toc_line";
$toc{$1} = [$2, $3, $4];
}
my $pos = tell $fh;
$toc{$_}[0] += $pos for keys %toc;
# calculate the line number of data section
my $data_pos = tell(DATA);
seek DATA, 0, 0;
my $pos = 0;
while (1) {
my $line = <DATA>;
$pos += length($line);
$data_linepos++;
last if $pos >= $data_pos;
}
seek DATA, $data_pos, 0;
script/gen-generic-ind-company-names view on Meta::CPAN
my $res = Perinci::CmdLine::Util::Config::read_config(
config_paths => $_pci_r->{config_paths},
config_filename => "gen-generic-ind-company-names.conf",
config_dirs => undef // ["$ENV{HOME}/.config", $ENV{HOME}, "/etc"],
program_name => "gen-generic-ind-company-names",
);
_pci_err($res) unless $res->[0] == 200;
$_pci_r->{config} = $res->[2];
$_pci_r->{read_config_files} = $res->[3]{"func.read_files"};
$_pci_r->{_config_section_read_order} = $res->[3]{"func.section_read_order"}; # we currently dont want to publish this request key
$res = Perinci::CmdLine::Util::Config::get_args_from_config(
r => $_pci_r,
config => $_pci_r->{config},
args => \%_pci_args,
program_name => "gen-generic-ind-company-names",
subcommand_name => $_pci_r->{subcommand_name},
config_profile => $_pci_r->{config_profile},
common_opts => {},
meta => $_pci_metas->{ $_pci_r->{subcommand_name} },
meta_is_normalized => 1,
);
die $res unless $res->[0] == 200;
my $found = $res->[3]{"func.found"};
if (defined($_pci_r->{config_profile}) && !$found && defined($_pci_r->{read_config_files}) && @{$_pci_r->{read_config_files}} && !$_pci_r->{ignore_missing_config_profile_section}) {
_pci_err([412, "Profile '$_pci_r->{config_profile}' not found in configuration file"]);
}
}
my $res = Getopt::Long::EvenLess::GetOptions(%$go_spec2);
_pci_err([500, "GetOptions failed"]) unless $res;
}
### check arguments
{
script/gen-generic-ind-company-names view on Meta::CPAN
=head1 CONFIGURATION FILE
This script can read configuration files. Configuration files are in the format of L<IOD>, which is basically INI with some extra features.
By default, these names are searched for configuration filenames (can be changed using C<--config-path>): F<~/.config/gen-generic-ind-company-names.conf>, F<~/gen-generic-ind-company-names.conf>, or F</etc/gen-generic-ind-company-names.conf>.
All found files will be read and merged.
To disable searching for configuration files, pass C<--no-config>.
You can put multiple profiles in a single file by using section names like C<[profile=SOMENAME]> or C<[SOMESECTION profile=SOMENAME]>. Those sections will only be read if you specify the matching C<--config-profile SOMENAME>.
You can also put configuration for multiple programs inside a single file, and use filter C<program=NAME> in section names, e.g. C<[program=NAME ...]> or C<[SOMESECTION program=NAME]>. The section will then only be used when the reading program match...
You can also filter a section by environment variable using the filter C<env=CONDITION> in section names. For example if you only want a section to be read if a certain environment variable is true: C<[env=SOMEVAR ...]> or C<[SOMESECTION env=SOMEVAR ...
To load and configure plugins, you can use either the C<-plugins> parameter (e.g. C<< -plugins=DumpArgs >> or C<< -plugins=DumpArgs@before_validate_args >>), or use the C<[plugin=NAME ...]> sections, for example:
[plugin=DumpArgs]
-event=before_validate_args
-prio=99
[plugin=Foo]
-event=after_validate_args
arg1=val1
arg2=val2
script/gen-generic-ind-company-names view on Meta::CPAN
#copies of Perl data structures. It calls itself recursively to copy
#nested hash, array, scalar and reference types, including tied
#variables and objects.
#
#The clone() function takes a scalar argument to copy. To duplicate
#arrays or hashes, pass them in by reference:
#
# my $copy = clone(\@array); my @copy = @{ clone(\@array) };
# my $copy = clone(\%hash); my %copy = %{ clone(\%hash) };
#
#The clone() function also accepts an optional second parameter that
#can be used to limit the depth of the copy. If you pass a limit of
#0, clone will return the same value you supplied; for a limit of
#1, a shallow copy is constructed; for a limit of 2, two layers of
#copying are done, and so on.
#
# my $shallow_copy = clone( $item, 1 );
#
#To allow objects to intervene in the way they are copied, the
#clone() function checks for a couple of optional methods. If an
#object provides a method named C<clone_self>, it is called and the
script/gen-generic-ind-company-names view on Meta::CPAN
# $hash->{foo} = 2;
# $copy->{foo} = 2;
# ok( $hash->{bar} == $copy->{bar} );
#
#To report bugs via the CPAN web tracking system, go to
#C<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Clone-PP> or send mail
#to C<Dist=Clone-PP#rt.cpan.org>, replacing C<#> with C<@>.
#
#=head1 SEE ALSO
#
#L<Clone> - a baseclass which provides a C<clone()> method.
#
#L<MooseX::Clone> - find-grained cloning for Moose objects.
#
#The C<dclone()> function in L<Storable>.
#
#L<Data::Clone> -
#polymorphic data cloning (see its documentation for what that means).
#
#L<Clone::Any> - use whichever of the cloning methods is available.
#
script/gen-generic-ind-company-names view on Meta::CPAN
#L<Complete>, the convention that this module follows.
#
#Some higher-level modules that use this module (so you don't have to use this
#module directly): L<Getopt::Long::Complete> (via L<Complete::Getopt::Long>),
#L<Getopt::Long::Subcommand>, L<Perinci::CmdLine> (via
#L<Perinci::Sub::Complete>).
#
#Other modules related to bash shell tab completion: L<Bash::Completion>,
#L<Getopt::Complete>, L<Term::Bash::Completion::Generator>.
#
#Programmable Completion section in Bash manual:
#L<https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html>
#
#=head1 AUTHOR
#
#perlancar <perlancar@cpan.org>
#
#=head1 COPYRIGHT AND LICENSE
#
#This software is copyright (c) 2020, 2019, 2018, 2016, 2015, 2014 by perlancar@cpan.org.
#
script/gen-generic-ind-company-names view on Meta::CPAN
# COL_V_ENCODING => 0, # either "!j"... or '"', '[', '{', '~'
# COL_V_WS1 => 1,
# COL_V_VALUE => 2,
# COL_V_WS2 => 3,
# COL_V_COMMENT_CHAR => 4,
# COL_V_COMMENT => 5,
#};
#
#sub new {
# my ($class, %attrs) = @_;
# $attrs{default_section} //= 'GLOBAL';
# $attrs{allow_bang_only} //= 1;
# $attrs{allow_duplicate_key} //= 1;
# $attrs{enable_directive} //= 1;
# $attrs{enable_encoding} //= 1;
# $attrs{enable_quoting} //= 1;
# $attrs{enable_bracket} //= 1;
# $attrs{enable_brace} //= 1;
# $attrs{enable_tilde} //= 1;
# $attrs{enable_expr} //= 0;
# $attrs{expr_vars} //= {};
script/gen-generic-ind-company-names view on Meta::CPAN
#sub _decode_expr {
# require Config::IOD::Expr;
#
# my ($self, $val) = @_;
# no strict 'refs';
# local *{"Config::IOD::Expr::_Compiled::val"} = sub {
# my $arg = shift;
# if ($arg =~ /(.+)\.(.+)/) {
# return $self->{_res}{$1}{$2};
# } else {
# return $self->{_res}{ $self->{_cur_section} }{$arg};
# }
# };
# Config::IOD::Expr::_parse_expr($val);
#}
#
#sub _err {
# my ($self, $msg) = @_;
# die join(
# "",
# @{ $self->{_include_stack} } ? "$self->{_include_stack}[0] " : "",
script/gen-generic-ind-company-names view on Meta::CPAN
#=head1 VERSION
#
#This document describes version 0.342 of Config::IOD::Base (from Perl distribution Config-IOD-Reader), released on 2019-01-17.
#
#=head1 EXPRESSION
#
#=for BEGIN_BLOCK: expression
#
#Expression allows you to do things like:
#
# [section1]
# foo=1
# bar="monkey"
#
# [section2]
# baz =!e 1+1
# qux =!e "grease" . val("section1.bar")
# quux=!e val("qux") . " " . val('baz')
#
#And the result will be:
#
# {
# section1 => {foo=>1, bar=>"monkey"},
# section2 => {baz=>2, qux=>"greasemonkey", quux=>"greasemonkey 2"},
# }
#
#For safety, you'll need to set C<enable_expr> attribute to 1 first to enable
#this feature.
#
#The syntax of the expression (the C<expr> encoding) is not officially specified
#yet in the L<IOD> specification. It will probably be Expr (see
#L<Language::Expr::Manual::Syntax>). At the moment, this module implements a very
#limited subset that is compatible (lowest common denominator) with Perl syntax
#and uses C<eval()> to evaluate the expression. However, only the limited subset
script/gen-generic-ind-company-names view on Meta::CPAN
#
#The supported operators are:
#
# + - .
# * / % x
# **
# unary -, unary +, !, ~
#
#The C<val()> function refers to the configuration key. If the argument contains
#".", it will be assumed as C<SECTIONNAME.KEYNAME>, otherwise it will access the
#current section's key. Since parsing is done in a single pass, you can only
#refer to the already mentioned key.
#
#Code will be compiled using Perl's C<eval()> in the
#C<Config::IOD::Expr::_Compiled> namespace, with C<no strict>, C<no warnings>.
#
#=for END_BLOCK: expression
#
#=head1 ATTRIBUTES
#
#=for BEGIN_BLOCK: attributes
#
#=head2 default_section => str (default: C<GLOBAL>)
#
#If a key line is specified before any section line, this is the section that the
#key will be put in.
#
#=head2 enable_directive => bool (default: 1)
#
#If set to false, then directives will not be parsed. Lines such as below will be
#considered a regular comment:
#
# ;!include foo.ini
#
#and lines such as below will be considered a syntax error (B<regardless> of the
script/gen-generic-ind-company-names view on Meta::CPAN
#
# ;!foo
#
#is very common, the spec allows it. This reader, however, can be configured to
#be more strict.
#
#=head2 allow_duplicate_key => bool (default: 1)
#
#If set to 0, you can forbid duplicate key, e.g.:
#
# [section]
# a=1
# a=2
#
#or:
#
# [section]
# a=1
# b=2
# c=3
# a=10
#
#In traditional INI file, to specify an array you specify multiple keys. But when
#there is only a single key, it is unclear if the value is a single-element array
#or a scalar. You can use this setting to avoid this array/scalar ambiguity in
#config file and force user to use JSON encoding or bracket to specify array:
#
# [section]
# a=[1,2]
#
#B<NOTE: Turning this setting off violates IOD specification.>
#
#=head2 ignore_unknown_directive => bool (default: 0)
#
#If set to true, will not die if an unknown directive is encountered. It will
#simply be ignored as a regular comment.
#
#B<NOTE: Turning this setting on violates IOD specification.>
script/gen-generic-ind-company-names view on Meta::CPAN
#our $DATE = '2019-01-17'; # DATE
#our $VERSION = '0.342'; # VERSION
#
#use 5.010001;
#use strict;
#use warnings;
#
#use parent qw(Config::IOD::Base);
#
#sub _merge {
# my ($self, $section) = @_;
#
# my $res = $self->{_res};
# for my $msect (@{ $self->{_merge} }) {
# if ($msect eq $section) {
# # ignore merging self
# next;
# #local $self->{_linum} = $self->{_linum}-1;
# #$self->_err("Can't merge section '$msect' to '$section': ".
# # "Same section");
# }
# if (!exists($res->{$msect})) {
# local $self->{_linum} = $self->{_linum}-1;
# $self->_err("Can't merge section '$msect' to '$section': ".
# "Section '$msect' not seen yet");
# }
# for my $k (keys %{ $res->{$msect} }) {
# $res->{$section}{$k} //= $res->{$msect}{$k};
# }
# }
#}
#
#sub _init_read {
# my $self = shift;
#
# $self->SUPER::_init_read;
# $self->{_res} = {};
# $self->{_merge} = undef;
# $self->{_num_seen_section_lines} = 0;
# $self->{_cur_section} = $self->{default_section};
# $self->{_arrayified} = {};
#}
#
#sub _read_string {
# my ($self, $str, $cb) = @_;
#
# my $res = $self->{_res};
# my $cur_section = $self->{_cur_section};
#
# my $directive_re = $self->{allow_bang_only} ?
# qr/^;?\s*!\s*(\w+)\s*/ :
# qr/^;\s*!\s*(\w+)\s*/;
#
# my $_raw_val; # only to provide to callback
#
# my @lines = split /^/, $str;
# local $self->{_linum} = 0;
# LINE:
script/gen-generic-ind-company-names view on Meta::CPAN
# @{$self->{disallow_directives}};
# }
# my $args = $self->_parse_command_line($line);
# if (!defined($args)) {
# $self->_err("Invalid arguments syntax '$line'");
# }
#
# if ($cb) {
# $cb->(
# event => 'directive',
# linum=>$self->{_linum}, line=>$line, cur_section=>$self->{_cur_section},
# directive => $directive,
# args => $args,
# );
# }
#
# if ($directive eq 'include') {
# my $path;
# if (! @$args) {
# $self->_err("Missing filename to include");
# } elsif (@$args > 1) {
script/gen-generic-ind-company-names view on Meta::CPAN
# }
# next LINE;
# }
#
# # comment line
# if ($line =~ /^\s*[;#]/) {
#
# if ($cb) {
# $cb->(
# event => 'comment',
# linum=>$self->{_linum}, line=>$line, cur_section=>$self->{_cur_section},
# );
# }
#
# next LINE;
# }
#
# # section line
# if ($line =~ /^\s*\[\s*(.+?)\s*\](?: \s*[;#].*)?/) {
# my $prev_section = $self->{_cur_section};
# $self->{_cur_section} = $cur_section = $1;
# $res->{$cur_section} //= {};
# $self->{_num_seen_section_lines}++;
#
# # previous section exists? do merging for previous section
# if ($self->{_merge} && $self->{_num_seen_section_lines} > 1) {
# $self->_merge($prev_section);
# }
#
# if ($cb) {
# $cb->(
# event => 'section',
# linum=>$self->{_linum}, line=>$line, cur_section=>$self->{_cur_section},
# section => $cur_section,
# );
# }
#
# next LINE;
# }
#
# # key line
# if ($line =~ /^\s*([^=]+?)\s*=\s*(.*)/) {
# my $key = $1;
# my $val = $2;
script/gen-generic-ind-company-names view on Meta::CPAN
# if ($val =~ /\A["!\\[\{~]/) {
# $_raw_val = $val if $cb;
# my ($err, $parse_res, $decoded_val) = $self->_parse_raw_value($val);
# $self->_err("Invalid value: " . $err) if $err;
# $val = $decoded_val;
# } else {
# $_raw_val = $val if $cb;
# $val =~ s/\s*[#;].*//; # strip comment
# }
#
# if (exists $res->{$cur_section}{$key}) {
# if (!$self->{allow_duplicate_key}) {
# $self->_err("Duplicate key: $key (section $cur_section)");
# } elsif ($self->{_arrayified}{$cur_section}{$key}++) {
# push @{ $res->{$cur_section}{$key} }, $val;
# } else {
# $res->{$cur_section}{$key} = [
# $res->{$cur_section}{$key}, $val];
# }
# } else {
# $res->{$cur_section}{$key} = $val;
# }
#
# if ($cb) {
# $cb->(
# event => 'key',
# linum=>$self->{_linum}, line=>$line, cur_section=>$self->{_cur_section},
# key => $key,
# val => $val,
# raw_val => $_raw_val,
# );
# }
#
# next LINE;
# }
#
# $self->_err("Invalid syntax");
# }
#
# if ($self->{_merge} && $self->{_num_seen_section_lines} > 1) {
# $self->_merge($cur_section);
# }
#
# $res;
#}
#
#1;
## ABSTRACT: Read IOD/INI configuration files
#
#__END__
#
script/gen-generic-ind-company-names view on Meta::CPAN
#
#=head1 VERSION
#
#This document describes version 0.342 of Config::IOD::Reader (from Perl distribution Config-IOD-Reader), released on 2019-01-17.
#
#=head1 SYNOPSIS
#
# use Config::IOD::Reader;
# my $reader = Config::IOD::Reader->new(
# # list of known attributes, with their default values
# # default_section => 'GLOBAL',
# # enable_directive => 1,
# # enable_encoding => 1,
# # enable_quoting => 1,
# # enable_backet => 1,
# # enable_brace => 1,
# # allow_encodings => undef, # or ['base64','json',...]
# # disallow_encodings => undef, # or ['base64','json',...]
# # allow_directives => undef, # or ['include','merge',...]
# # disallow_directives => undef, # or ['include','merge',...]
# # allow_bang_only => 1,
script/gen-generic-ind-company-names view on Meta::CPAN
#This module reads L<IOD> configuration files (IOD is an INI-like format with
#more precise specification, some extra features, and 99% compatible with typical
#INI format). It is a minimalist alternative to the more fully-featured
#L<Config::IOD>. It cannot write IOD files and is optimized for low startup
#overhead.
#
#=head1 EXPRESSION
#
#Expression allows you to do things like:
#
# [section1]
# foo=1
# bar="monkey"
#
# [section2]
# baz =!e 1+1
# qux =!e "grease" . val("section1.bar")
# quux=!e val("qux") . " " . val('baz')
#
#And the result will be:
#
# {
# section1 => {foo=>1, bar=>"monkey"},
# section2 => {baz=>2, qux=>"greasemonkey", quux=>"greasemonkey 2"},
# }
#
#For safety, you'll need to set C<enable_expr> attribute to 1 first to enable
#this feature.
#
#The syntax of the expression (the C<expr> encoding) is not officially specified
#yet in the L<IOD> specification. It will probably be Expr (see
#L<Language::Expr::Manual::Syntax>). At the moment, this module implements a very
#limited subset that is compatible (lowest common denominator) with Perl syntax
#and uses C<eval()> to evaluate the expression. However, only the limited subset
script/gen-generic-ind-company-names view on Meta::CPAN
#
#The supported operators are:
#
# + - .
# * / % x
# **
# unary -, unary +, !, ~
#
#The C<val()> function refers to the configuration key. If the argument contains
#".", it will be assumed as C<SECTIONNAME.KEYNAME>, otherwise it will access the
#current section's key. Since parsing is done in a single pass, you can only
#refer to the already mentioned key.
#
#Code will be compiled using Perl's C<eval()> in the
#C<Config::IOD::Expr::_Compiled> namespace, with C<no strict>, C<no warnings>.
#
#=head1 ATTRIBUTES
#
#=head2 default_section => str (default: C<GLOBAL>)
#
#If a key line is specified before any section line, this is the section that the
#key will be put in.
#
#=head2 enable_directive => bool (default: 1)
#
#If set to false, then directives will not be parsed. Lines such as below will be
#considered a regular comment:
#
# ;!include foo.ini
#
#and lines such as below will be considered a syntax error (B<regardless> of the
script/gen-generic-ind-company-names view on Meta::CPAN
#
# ;!foo
#
#is very common, the spec allows it. This reader, however, can be configured to
#be more strict.
#
#=head2 allow_duplicate_key => bool (default: 1)
#
#If set to 0, you can forbid duplicate key, e.g.:
#
# [section]
# a=1
# a=2
#
#or:
#
# [section]
# a=1
# b=2
# c=3
# a=10
#
#In traditional INI file, to specify an array you specify multiple keys. But when
#there is only a single key, it is unclear if the value is a single-element array
#or a scalar. You can use this setting to avoid this array/scalar ambiguity in
#config file and force user to use JSON encoding or bracket to specify array:
#
# [section]
# a=[1,2]
#
#B<NOTE: Turning this setting off violates IOD specification.>
#
#=head2 ignore_unknown_directive => bool (default: 0)
#
#If set to true, will not die if an unknown directive is encountered. It will
#simply be ignored as a regular comment.
#
#B<NOTE: Turning this setting on violates IOD specification.>
script/gen-generic-ind-company-names view on Meta::CPAN
#C<$callback> is an optional coderef argument that will be called during various
#stages. It can be useful if you want more information (especially ordering). It
#will be called with hash argument C<%args>
#
#=over
#
#=item * Found a directive line
#
#Arguments passed: C<event> (str, has the value of 'directive'), C<linum> (int,
#line number, starts from 1), C<line> (str, raw line), C<directive> (str,
#directive name), C<cur_section> (str, current section name), C<args> (array,
#directive arguments).
#
#=item * Found a comment line
#
#Arguments passed: C<event> (str, 'comment'), C<linum>, C<line>, C<cur_section>.
#
#=item * Found a section line
#
#Arguments passed: C<event> (str, 'section'), C<linum>, C<line>, C<cur_section>,
#C<section> (str, section name).
#
#=item * Found a key line
#
#Arguments passed: C<event> (str, 'section'), C<linum>, C<line>, C<cur_section>,
#C<key> (str, key name), C<val> (any, value name, already decoded if encoded),
#C<raw_val> (str, raw value).
#
#=back
#
#TODO: callback when there is merging.
#
#=head1 HOMEPAGE
#
#Please visit the project's homepage at L<https://metacpan.org/release/Config-IOD-Reader>.
script/gen-generic-ind-company-names view on Meta::CPAN
#}
#
#$SPEC{read_config} = {
# v => 1.1,
# args => {
# config_paths => {},
# config_filename => {},
# config_dirs => {},
# program_name => {},
# # TODO: hook_file
# hook_section => {},
# # TODO: hook_param?
# },
#};
#sub read_config {
# require Config::IOD::Reader;
#
# my %args = @_;
#
# my $config_dirs = $args{config_dirs} // get_default_config_dirs();
#
# my $paths;
#
# my @filenames;
# my %section_config_filename_map;
# if (my $names = $args{config_filename}) {
# for my $name (ref($names) eq 'ARRAY' ? @$names : ($names)) {
# if (ref($name) eq 'HASH') {
# $section_config_filename_map{$name->{filename}} = $name->{section};
# push @filenames, $name->{filename};
# } else {
# $section_config_filename_map{$name} = 'GLOBAL';
# push @filenames, $name;
# }
# }
# }
# unless (@filenames) {
# @filenames = (($args{program_name} // "prog") . ".conf");
# }
#
# if ($args{config_paths}) {
# $paths = $args{config_paths};
script/gen-generic-ind-company-names view on Meta::CPAN
# for my $name (@filenames) {
# my $path = "$dir/" . $name;
# push @$paths, $path if -e $path;
# }
# }
# }
#
# my $reader = Config::IOD::Reader->new;
# my %res;
# my @read;
# my %section_read_order;
# FILE:
# for my $i (0..$#{$paths}) {
# my $path = $paths->[$i];
# my $filename = $path; $filename =~ s!.*[/\\]!!;
# my $wanted_section = $section_config_filename_map{$filename};
# log_trace "[pericmd] Reading config file '%s' ...", $path;
# my $j = 0;
# $section_read_order{GLOBAL} = [$i, $j++];
# my @file_sections = ("GLOBAL");
# my $hoh = $reader->read_file(
# $path,
# sub {
# my %args = @_;
# return unless $args{event} eq 'section';
# my $section = $args{section};
# push @file_sections, $section
# unless grep {$section eq $_} @file_sections;
# $section_read_order{$section} = [$i, $j++];
# },
# );
# push @read, $path;
# SECTION:
# for my $section (@file_sections) {
# $res{$section} //= {};
# my $hash = $hoh->{$section};
#
# my $s = $section; $s =~ s/\s*\S*=.*\z//; # strip key=value pairs
# $s = 'GLOBAL' if $s eq '';
#
# if ($args{hook_section}) {
# my $res = $args{hook_section}->($section, $hash);
# if ($res->[0] == 204) {
# log_trace "[pericmd] Skipped config section '$section' ".
# "in file '$path': hook_section returns 204";
# next SECTION;
# } elsif ($res->[0] >= 400 && $res->[0] <= 599) {
# return [$res->[0], "Error when reading config file '$path'".
# ": $res->[1]"];
# }
# }
#
# next unless !defined($wanted_section) || $s eq $wanted_section;
#
# for (keys %$hash) {
# $res{$section}{$_} = $hash->{$_};
# }
# }
# }
# [200, "OK", \%res, {
# 'func.read_files' => \@read,
# 'func.section_read_order' => \%section_read_order,
# }];
#}
#
#$SPEC{get_args_from_config} = {
# v => 1.1,
# description => <<'_',
#
#`config` is a HoH (hashes of hashrefs) produced by reading an INI (IOD)
#configuration file using modules like <pm:Config::IOD::Reader>.
#
#Hashref argument `args` will be set by parameters in `config`, while `plugins`
#will be set by parameters in `[plugin=...]` sections in `config`. For example,
#with this configuration:
#
# arg1=val1
# arg2=val2
# -special_arg1=val3
# -special_arg2=val4
#
# [plugin=DumpArgs]
# -event=before_validation
#
script/gen-generic-ind-company-names view on Meta::CPAN
# my $plugins = $fargs{plugins} // [];
# my $copts = $fargs{common_opts};
# my $meta = $fargs{meta};
# my $found;
#
# unless ($fargs{meta_is_normalized}) {
# require Perinci::Sub::Normalize;
# $meta = Perinci::Sub::Normalize::normalize_function_metadata($meta);
# }
#
# my $csro = $r->{_config_section_read_order} // {};
# my @sections = sort {
# # sort according to the order the section is seen in the file
# my $csro_a = $csro->{$a} // [0,0];
# my $csro_b = $csro->{$b} // [0,0];
# $csro_a->[0] <=> $csro_b->[0] ||
# $csro_a->[1] <=> $csro_b->[1] ||
# $a cmp $b
# } keys %$conf;
#
# my %seen_profiles; # for debugging message
# for my $section0 (@sections) {
# my %keyvals;
# my $sect_name;
# for my $word (split /\s+/, $section0) {
# if ($word =~ /(.*?)=(.*)/) {
# $keyvals{$1} = $2;
# } else {
# $sect_name //= $word;
# }
# }
# $seen_profiles{$keyvals{profile}}++ if defined $keyvals{profile};
#
# my $sect_scn = $keyvals{subcommand} // '';
# my $sect_profile = $keyvals{profile};
# my $sect_plugin = $keyvals{plugin};
#
# # if there is a subcommand name, use section with no subcommand=... or
# # the matching subcommand
# if (length $scn) {
# if (length($sect_scn) && $sect_scn ne $scn) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "subcommand does not match '$scn'",
# );
# next;
# }
# } else {
# if (length $sect_scn) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "only for a certain subcommand",
# );
# next;
# }
# }
#
# # if user chooses a profile, only use section with no profile=... or the
# # matching profile
# if (defined $profile) {
# if (defined($sect_profile) && $sect_profile ne $profile) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "profile does not match '$profile'",
# );
# next;
# }
# $found = 1 if defined($sect_profile) && $sect_profile eq $profile;
# } else {
# if (defined($sect_profile)) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "only for a certain profile",
# );
# next;
# }
# }
#
# # only use section marked with program=... if the program name matches
# if (defined($progn) && defined($keyvals{program})) {
# if ($progn ne $keyvals{program}) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "program does not match '$progn'",
# );
# next;
# }
# }
#
# # if user specifies env=... then apply filtering by ENV variable
# if (defined(my $env = $keyvals{env})) {
# my ($var, $val);
# if (($var, $val) = $env =~ /\A(\w+)=(.*)\z/) {
# if (($ENV{$var} // '') ne $val) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "env $var has non-matching value '".
# ($ENV{$var} // '')."'",
# );
# next;
# }
# } elsif (($var, $val) = $env =~ /\A(\w+)!=(.*)\z/) {
# if (($ENV{$var} // '') eq $val) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "env $var has that value",
# );
# next;
# }
# } elsif (($var, $val) = $env =~ /\A(\w+)\*=(.*)\z/) {
# if (index(($ENV{$var} // ''), $val) < 0) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "env $var has value '".
# ($ENV{$var} // '')."' which does not contain the ".
# "requested string"
# );
# next;
# }
# } else {
# if (!$ENV{$env}) {
# log_trace(
# "[pericmd] Skipped config section '%s' (%s)",
# $section0, "env $env is not set/true",
# );
# next;
# }
# }
# }
#
# log_trace("[pericmd] Reading config section '%s'", $section0);
#
# if (defined $sect_plugin) {
# # TODO: check against metadata in plugin
# my $event;
# my $prio;
# my $plugin_args = {};
# for my $k (keys %{ $conf->{$section0} }) {
# my $v = $conf->{$section0}{$k};
# if ($k eq '-event') { $event = $v }
# elsif ($k eq '-prio') { $prio = $v }
# else { $plugin_args->{$k} = $v }
# }
# push @$plugins, $sect_plugin .
# (defined $event || defined $prio ?
# '@'.($event // '') . (defined $prio ? "\@$prio" : "") : '');
# push @$plugins, $plugin_args;
# } else {
# my $as = $meta->{args} // {};
# for my $k (keys %{ $conf->{$section0} }) {
# my $v = $conf->{$section0}{$k};
# if ($copts->{$k} && $copts->{$k}{is_settable_via_config}) {
# my $sch = $copts->{$k}{schema};
# if ($sch) {
# require Data::Sah::Resolve;
# my $rsch = Data::Sah::Resolve::resolve_schema($sch);
# # since IOD might return a scalar or an array (depending on
# # whether there is a single param=val or multiple param=
# # lines), we need to arrayify the value if the argument is
# # expected to be an array.
# if (ref($v) ne 'ARRAY' && $rsch->[0] eq 'array') {
script/gen-generic-ind-company-names view on Meta::CPAN
# # expected to be an array.
# if (ref($v) ne 'ARRAY' && $as->{$k} && $as->{$k}{schema}) {
# require Data::Sah::Resolve;
# my $rsch = Data::Sah::Resolve::resolve_schema($as->{$k}{schema});
# if ($rsch->[0] eq 'array') {
# $v = [$v];
# }
# }
# $args->{$k} = $v;
# }
# } # for params in section
# } # if for plugin
# }
# log_trace("[pericmd] Seen config profiles: %s",
# [sort keys %seen_profiles]);
#
# [200, "OK", $args, {'func.found'=>$found}];
#}
#
#1;
## ABSTRACT: Utility routines related to config files
script/gen-generic-ind-company-names view on Meta::CPAN
#=head2 get_args_from_config
#
#Usage:
#
# get_args_from_config(%args) -> [status, msg, payload, meta]
#
#C<config> is a HoH (hashes of hashrefs) produced by reading an INI (IOD)
#configuration file using modules like L<Config::IOD::Reader>.
#
#Hashref argument C<args> will be set by parameters in C<config>, while C<plugins>
#will be set by parameters in C<[plugin=...]> sections in C<config>. For example,
#with this configuration:
#
# arg1=val1
# arg2=val2
# -special_arg1=val3
# -special_arg2=val4
#
# [plugin=DumpArgs]
# -event=before_validation
#
script/gen-generic-ind-company-names view on Meta::CPAN
#Arguments ('*' denotes required arguments):
#
#=over 4
#
#=item * B<config_dirs> => I<any>
#
#=item * B<config_filename> => I<any>
#
#=item * B<config_paths> => I<any>
#
#=item * B<hook_section> => I<any>
#
#=item * B<program_name> => I<any>
#
#
#=back
#
#Returns an enveloped result (an array).
#
#First element (status) is an integer containing HTTP status code
#(200 means OK, 4xx caller error, 5xx function error). Second element
script/gen-generic-ind-company-names view on Meta::CPAN
#
#=head1 SEE ALSO
#
#My L<blog post|http://neilb.org/2019/08/06/text-table-tiny-changes.html>
#where I described changes to formatting;
#this has more examples.
#
#There are many modules for formatting text tables on CPAN.
#A good number of them are listed in the
#L<See Also|https://metacpan.org/pod/Text::Table::Manifold#See-Also>
#section of the documentation for L<Text::Table::Manifold>.
#
#
#=head1 REPOSITORY
#
#L<https://github.com/neilb/Text-Table-Tiny>
#
#
#=head1 AUTHOR
#
#Neil Bowers <neilb@cpan.org>