[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoOpts supports the notion of presetting
the value or state of an
option. The values may be obtained either from environment variables or from
configuration files (‘rc’ or ‘ini’ files). In order to take
advantage of this, the AutoOpts client program must specify these features in
the option descriptor file (see section Program Description Attributes) with the rcfile
or environrc
attributes.
7.10.1 configuration file presets | ||
7.10.2 Saving the presets into a configuration file | ||
7.10.3 Creating a sample configuration file | ||
7.10.4 environment variable presets | ||
7.10.5 Config file only example |
It is also possible to configure your program without using the command line option parsing code. This is done by using only the following four functions from the ‘libopts’ library:
(see section configFileLoad) will parse the contents of a config file and return a pointer to a structure representing the hierarchical value. The values are sorted alphabetically by the value name and all entries with the same name will retain their original order. Insertion sort is used.
(see section optionGetValue) will find the first value within the hierarchy with a name that matches the name passed in.
(see section optionNextValue) will return the next value that follows the value passed in as an argument. If you wish to get all the values for a particular name, you must take note when the name changes.
(see section optionUnloadNested). The pointer passed in must be
of type, OPARG_TYPE_HIERARCHY
(see the autoopts/options.h
header file). configFileLoad
will return a tOptionValue
pointer of that type. This function will release all the associated
memory. AutoOpts
generated code uses this function for its own
needs. Client code should only call this function with pointers
gotten from configFileLoad
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Configuration files are enabled by specifying the program attribute
homerc
(see section Program Description Attributes). Any option not marked
with the no-preset
attribute may appear in a configuration file.
The files loaded are selected both by the homerc
entries and,
optionally, via a command line option. The first component of the
homerc
entry may be an environment variable such as $HOME
, or
it may also be ‘$$’ (two dollar sign characters) to specify
the directory of the executable. For example:
homerc = "$$/../share/autogen"; |
will cause the AutoOpts library to look in the normal autogen datadir relative to the current installation directory for autogen.
The configuration files are processed in the order they are specified by
the homerc
attribute, so that each new file will normally override
the settings of the previous files. This may be overridden by marking some
options for immediate action
(see section Immediate Action Attributes). Any such
options are acted upon in reverse order. The disabled
load-opts
(‘--no-load-opts’) option, for example, is an
immediate action option. Its presence in the last homerc
file will
prevent the processing of any prior homerc
files because its effect
is immediate.
Configuration file processing can be completely suppressed by specifying
‘--no-load-opts’ on the command line, or PROGRAM_LOAD_OPTS=no
in
the environment (if environrc
has been specified).
See the Configuration File Format
section (see section Configuration File Format)
for details on the format of the file.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When configuration files are enabled for an application, the user is
also provided with an automatically supplied ‘--save-opts’ option.
All of the known option state will be written to either the specified
output file or, if it is not specified, then to the last specified
homerc
file.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoOpts is shipped with a template named, ‘rc-sample.tpl’.
If your option definition file specifies the homerc
attribute,
then you may invoke ‘autogen’ thus:
autogen -Trc-sample <your-option-def-file> |
This will, by default, produce a sample file named,
‘sample-<prog-name>rc’. It will be named differently if you specify your
configuration (rc) file name with the rcfile
attribute. In that case,
the output file will be named, ‘sample-<rcfile-name>’. It will contain
all of the program options not marked as no-preset
. It will also
include the text from the doc
attribute.
Doing so with getdefs’ option definitions yields this sample-getdefsrc file.
I tend to be wordy in my doc
attributes:
# getdefs sample configuration file ## This source file is copyrighted and licensed under the following terms: # # Copyright (C) 1999-2014 Bruce Korb, all rights reserved. # This is free software. It is licensed for use, modification and # redistribution under the terms of the GNU General Public License, # version 3 or later <http://gnu.org/licenses/gpl.html> # # getdefs is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # getdefs 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 General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see <http://www.gnu.org/licenses/>. # defs_to_get -- Regexp to look for after the "/*=" # # # # # If you want definitions only from a particular category, or even # with names matching particular patterns, then specify this regular # expression for the text that must follow the @code{/*=}. # Example: # #defs_to_get reg-ex # subblock -- subblock definition names # # # # # This option is used to create shorthand entries for nested definitions. # For example, with: # @table @r # @item using subblock thus # @code{--subblock=arg=argname,type,null} # @item and defining an @code{arg} thus # @code{arg: this, char *} # @item will then expand to: # @code{arg = @{ argname = this; type = "char *"; @};} # @end table # The "this, char *" string is separated at the commas, with the # white space removed. You may use characters other than commas by # starting the value string with a punctuation character other than # a single or double quote character. You may also omit intermediate # values by placing the commas next to each other with no intervening # white space. For example, "+mumble++yes+" will expand to: # @* # @code{arg = @{ argname = mumble; null = "yes"; @};}. # Example: # #subblock sub-def # listattr -- attribute with list of values # # # # # This option is used to create shorthand entries for definitions # that generally appear several times. That is, they tend to be # a list of values. For example, with: # @* # @code{listattr=foo} defined, the text: # @* # @code{foo: this, is, a, multi-list} will then expand to: # @* # @code{foo = 'this', 'is', 'a', 'multi-list';} # @* # The texts are separated by the commas, with the # white space removed. You may use characters other than commas by # starting the value string with a punctuation character other than # a single or double quote character. # Example: # #listattr def # ordering -- Alphabetize or use named file # # # # # By default, ordering is alphabetical by the entry name. Use, # @code{no-ordering} if order is unimportant. Use @code{ordering} # with no argument to order without case sensitivity. Use # @code{ordering=<file-name>} if chronological order is important. # getdefs will maintain the text content of @code{file-name}. # @code{file-name} need not exist. # Example: # #ordering file-name # first_index -- The first index to apply to groups # # This configuration value takes an integer number as its argument. # # # By default, the first occurrence of a named definition will have an # index of zero. Sometimes, that needs to be a reserved value. Provide # this option to specify a different starting point. # Example: # #first_index 0 # filelist -- Insert source file names into defs # # # # # Inserts the name of each input file into the output definitions. # If no argument is supplied, the format will be: # @example # infile = '%s'; # @end example # If an argument is supplied, that string will be used for the entry # name instead of @var{infile}. # Example: # #filelist file # assign -- Global assignments # # # # # The argument to each copy of this option will be inserted into # the output definitions, with only a semicolon attached. # Example: # #assign ag-def # common_assign -- Assignments common to all blocks # # # # # The argument to each copy of this option will be inserted into # each output definition, with only a semicolon attached. # Example: # #common_assign ag-def # copy -- File(s) to copy into definitions # # # # # The content of each file named by these options will be inserted into # the output definitions. # Example: # #copy file # srcfile -- Insert source file name into each def # # # # # Inserts the name of the input file where a definition was found # into the output definition. # If no argument is supplied, the format will be: # @example # srcfile = '%s'; # @end example # If an argument is supplied, that string will be used for the entry # name instead of @var{srcfile}. # Example: # #srcfile file # linenum -- Insert source line number into each def # # # # # Inserts the line number in the input file where a definition # was found into the output definition. # If no argument is supplied, the format will be: # @example # linenum = '%s'; # @end example # If an argument is supplied, that string will be used for the entry # name instead of @var{linenum}. # Example: # #linenum def-name # input -- Input file to search for defs # # # # # All files that are to be searched for definitions must be named on # the command line or read from @code{stdin}. If there is only one # @code{input} option and it is the string, "-", then the input file # list is read from @code{stdin}. If a command line argument is not # an option name and does not contain an assignment operator # (@code{=}), then it defaults to being an input file name. # At least one input file must be specified. # Example: # #input src-file # output -- Output file to open # # # # # If you are not sending the output to an AutoGen process, # you may name an output file instead. # Example: # #output file # autogen -- Invoke AutoGen with defs # # # # # This is the default output mode. Specifying @code{no-autogen} is # equivalent to @code{output=-}. If you supply an argument to this # option, that program will be started as if it were AutoGen and # its standard in will be set to the output definitions of this program. # Example: # #autogen ag-cmd # template -- Template Name # # # # # Specifies the template name to be used for generating the final output. # Example: # #template file # agarg -- AutoGen Argument # # # # # This is a pass-through argument. It allows you to specify any # arbitrary argument to be passed to AutoGen. # Example: # #agarg ag-opt # base_name -- Base name for output file(s) # # # # # When output is going to AutoGen, a base name must either be supplied # or derived. If this option is not supplied, then it is taken from # the @code{template} option. If that is not provided either, then # it is set to the base name of the current directory. # Example: # #base_name name |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the AutoOpts client program specifies environrc
in its
option descriptor file, then environment variables will be used for
presetting option state. Variables will be looked for that are named,
PROGRAM_OPTNAME
and PROGRAM
. PROGRAM
is the
upper cased C-name
of the program, and OPTNAME is the
upper cased C-name
of a specific option. (The C-name
s
are the regular names with all special characters converted to
underscores (_
).)
Option specific environment variables are processed after (and thus
take precedence over) the contents of the PROGRAM
environment
variable. The option argument string for these options takes on the
string value gotten from the environment. Consequently, you can only
have one instance of the OPTNAME.
If a particular option may be disabled, then its disabled state is
indicated by setting the PROGRAM_OPTNAME
value to the
disablement prefix. So, for example, if the disablement prefix were
dont
, then you can disable the optname
option by setting
the PROGRAM_OPTNAME
’ environment variable to dont
.
See section Common Option Attributes.
The PROGRAM
environment string is tokenized and parsed much
like a command line. Doubly quoted strings have backslash escapes
processed the same way they are processed in C program constant
strings. Singly quoted strings are pretty raw in that backslashes are
honored before other backslashes, apostrophes, newlines and cr/newline
pairs. The options must be introduced with hyphens in the same way as
the command line.
Note that not all options may be preset. Options that are specified with the
no-preset
attribute and the ‘--help’, ‘--more-help’,
and ‘--save-opts’ auto-supported options may not be preset.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If for some reason it is difficult or unworkable to integrate configuration
file processing with command line option parsing, the libopts
(see section libopts External Procedures) library can still be used to process
configuration files. Below is a Hello, World! greeting program that tries
to load a configuration file ‘hello.conf’ to see if it should use an
alternate greeting or to personalize the salutation.
#include <config.h> #include <sys/types.h> #include <stdio.h> #include <pwd.h> #include <string.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include <autoopts/options.h> int main(int argc, char ** argv) { char const * greeting = "Hello"; char const * greeted = "World"; tOptionValue const * pOV = configFileLoad("hello.conf"); if (pOV != NULL) { const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); if ( (pGetV != NULL) && (pGetV->valType == OPARG_TYPE_STRING)) greeting = strdup(pGetV->v.strVal); pGetV = optionGetValue(pOV, "personalize"); if (pGetV != NULL) { struct passwd * pwe = getpwuid(getuid()); if (pwe != NULL) greeted = strdup(pwe->pw_gecos); } optionUnloadNested(pOV); /* deallocate config data */ } printf("%s, %s!\n", greeting, greeted); return 0; } |
With that text in a file named “hello.c”, this short script:
cc -o hello hello.c `autoopts-config cflags ldflags` ./hello echo 'greeting Buzz off' > hello.conf ./hello echo personalize > hello.conf ./hello |
will produce the following output:
Hello, World! Buzz off, World! Hello, Bruce Korb! |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Bruce Korb on August 21, 2015 using texi2html 1.82.