LAL 7.7.0.1-678514e
UserInput.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Karl Wette
3 * Copyright (C) 2015 Reinhard Prix
4 * Copyright (C) 2010 Reinhard Prix (xlalified)
5 * Copyright (C) 2004, 2005 Reinhard Prix
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with with program; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301 USA
21 */
22
23#ifndef _USERINPUT_H /* Double-include protection. */
24#define _USERINPUT_H
25
26#ifdef __cplusplus /* C++ protection. */
27extern "C" {
28#endif
29
30#include <lal/ConfigFile.h>
31#include <lal/UserInputParse.h>
32#include <lal/LALVCSInfoType.h>
33
34/**
35 * \defgroup UserInput_h Header UserInput.h
36 * \ingroup lal_support
37 * \author Reinhard Prix
38 * \brief Module for simple unified handling of user-input from config-file and/or command-line.
39 *
40 *
41 * ### Description ###
42 *
43 * This module provides functions and macros to 'register' a set off C-variables as 'User Variables',
44 * which can then be read in from the commandline and/or an input config file, as parsed by \ref ConfigFile_h.
45 *
46 * The module also handles generating and outputting a help-string on the available input options when requested, and
47 * can deal with enforcing input of required options and using default values.
48 *
49 * ### Usage ###
50 *
51 * The general approach consists of the following steps:
52 * <ol>
53 * <li> set default-values for optional user-variables as appropriate</li>
54 * <li> \c register all user-variables using calls to \c XLALRegisterUvarMember(), which assumes a
55 * pointer named 'uvar' to a struct containing all user-variables in the form 'uvar->UserVariable'.</li>
56 * <li> parse user-input using XLALUserVarReadAllInput()</li>
57 * </ol>
58 *
59 * One can use XLALUserVarWasSet() to determine whether a given user-input option has been set by the user.
60 *
61 * The function XLALUserVarGetLog() can be used to obtain a log-string containing the full user-input, either in \c commandline- or \c ConfigFile format.
62 *
63 * Here is a worked simple example of its recommended use:
64 * \code
65 * #include <stdio.h>
66 * #include <lal/XLALError.h>
67 * #include <lal/LALDatatypes.h>
68 *
69 * #include <lal/UserInput.h>
70 *
71 * // these are the C-variables we want to read in from user-input
72 * typedef struct {
73 * BOOLEAN help; // did user request help-output?
74 * INT4 anInteger;
75 * REAL8 aDoubleVar;
76 * CHAR *andAString;
77 * REAL8 specialGeekSwitch;
78 * LIGOTimeGPS someEpoch;
79 * REAL8 RA;
80 * REAL8 DEC;
81 * } UserInput_t;
82 *
83 *
84 * int main(int argc,char *argv[])
85 * {
86 * UserInput_t XLAL_INIT_DECL(UserVariables); // initializes this struct to {0}
87 * UserInput_t *uvar = &UserVariables; // struct-pointer allows us to use the XLALreg<TYPE>UserStruct() macros...
88 *
89 * // 1. step: set default-values for optional user-input variables
90 * uvar->anInteger = 0;
91 * uvar->andAString = NULL; // Note: need to assign allocated strings here as default!!
92 *
93 * // 2. step: Register all user-variables using the shortcut macros:
94 * XLALRegisterUvarMember( help, BOOLEAN, 'h', HELP, "Output this help-message");
95 * XLALRegisterUvarMember( anInteger, INT4, 'i', OPTIONAL, "An example user-variable of an optional integer");
96 * XLALRegisterUvarMember( aDoubleVar, REAL8, 'r', REQUIRED, "This REAL8 user-variable is required");
97 * XLALRegisterUvarMember( andAString, STRING, 0, OPTIONAL, "Optional string-input, has no short-option");
98 * XLALRegisterUvarMember( someEpoch, EPOCH, 0, OPTIONAL, "Reference epoch (format 'xx.yy[GPS|MJD]')");
99 * XLALRegisterUvarMember( RAJ, RAJ, 0, OPTIONAL, "Sky location: equatorial right ascension in [0,2pi] (in radians or hours:minutes:seconds)");
100 * XLALRegisterUvarMember( DEC, DECJ, 0, OPTIONAL, "Sky location: equatorial declination [-pi/2,pi/2] (in radians or degrees:minutes:seconds)");
101 * XLALRegisterUvarMember( specialGeekSwitch, REAL8, 'g', DEVELOPER, "This REAL8 user-variable may not be relevant for standard usage");
102 *
103 * // 3. step: parse all user-input, from either config-file if given, or commandline (overloads config-file values)
104 * XLAL_CHECK ( XLALUserVarReadAllInput ( argc, argv, lalAppsVCSInfoList ) == XLAL_SUCCESS, XLAL_EFUNC);
105 *
106 * if (uvar->help){ // if user had requested help, then we're already done here
107 * return 0;
108 * }
109 *
110 * printf ("User-input was: anInteger = %d, aDoubleVar = %f, andAString = %s\n", uvar->anInteger, uvar->aDoubleVar, uvar->andAString );
111 * printf ("someEpoch = {%d s, %d ns}, RA = %f rad, DEC = %f rad\n", uvar->someEpoch.gpsSeconds, uvar->someEpoch.gpsNanoSeconds, uvar->RA, uvar->DEC );
112 *
113 * // 4. step: free user-input module memory
114 * XLALDestroyUserVars();
115 *
116 * LALCheckMemoryLeaks();
117 * return 0;
118 * } // main()
119 * \endcode
120 *
121 * \note This code can be compiled <b>as is</b> within lalapps, and yields
122 *
123 * \verbatim
124$ LAL_DEBUG_LEVEL=1 ./tmp --help
125
126Usage: ./tmp [@ConfigFile] [options], where options are:
127
128-h, --help BOOLEAN Output this help-message []
129-i, --anInteger INT4 An example user-variable of an optional integer [0]
130-r, --aDoubleVar REAL8 This REAL8 user-variable is required [REQUIRED]
131 --andAString STRING Optional string-input, has no short-option [NULL]
132 --someEpoch EPOCH Reference epoch (format 'xx.yy[GPS|MJD]') [0.000000000GPS]
133 --RA RAJ Sky location: right ascension in [0,2pi] (in radians or hours:minutes:seconds) [0.0]
134 --DEC DECJ Sky location: declination [-pi/2,pi/2] (in radians or degrees:minutes:seconds) [0.0]
135
136---------- The following are 'Developer'-options not useful for most users:----------
137
138-g, --specialGeekSwitch REAL8 This REAL8 user-variable may not be relevant for standard usage [0.0]
139
140\endverbatim
141 *
142 * And if called
143 * \verbatim
144$ ./tmp -r 3.1415 --andAString="stupid example" --someEpoch=5555MJD --RA=10:25:10.123 --DEC=-30:0:0
145User-input was: anInteger = 0, aDoubleVar = 3.141500, andAString = stupid example
146someEpoch = {2147483596 s, 816000000 ns}, RA = 2.727813 rad, DEC = -0.523599 rad
147\endverbatim
148 *
149 * \note For a real-world example of usage, see various codes under lalapps/src/pulsar/{Injections,Fstatistic}
150 *
151 */
152/** @{ */
153
154/**
155 * Shortcut macro for registering new user variables, which are accessed via the \e struct-pointer '*uvar'
156 */
157#define XLALRegisterUvarMember(name,type,option,category,...) \
158 XLALRegister ##type## UserVar( &(uvar-> name), NULL, #name, option, UVAR_CATEGORY_ ## category, __VA_ARGS__)
159
160/**
161 * Shortcut macro for registering new user variables, which are accessed via the \e struct-pointer '*uvar',
162 * and which acquire some auxilliary data in order to be parsed
163 */
164#define XLALRegisterUvarAuxDataMember(name,type,cdata,option,category,...) \
165 XLALRegister ##type## UserVar( &(uvar-> name), cdata, #name, option, UVAR_CATEGORY_ ## category, __VA_ARGS__)
166
167/**
168 * Shortcut macro for registering new user variables, named 'name' and accessed via the \e variable-pointer '*cvar'
169 * \note This style of user variable is deprecated; XLALRegisterUvarMember() is preferred
170 */
171#define XLALRegisterNamedUvar(cvar,name,type,option,category,...) \
172 XLALRegister ##type## UserVar( cvar, NULL, name, option, UVAR_CATEGORY_ ## category, __VA_ARGS__)
173
174/**
175 * Shortcut macro for registering new user variables, named 'name' and accessed via the \e variable-pointer '*cvar',
176 * and which acquire some auxilliary data in order to be parsed
177 * \note This style of user variable is deprecated; XLALRegisterUvarAuxDataMember() is preferred
178 */
179#define XLALRegisterNamedUvarAuxData(cvar,name,type,cdata,option,category,...) \
180 XLALRegister ##type## UserVar( cvar, cdata, name, option, UVAR_CATEGORY_ ## category, __VA_ARGS__)
181
182/**
183 * Mutually-exclusive user variable categories: optional, required, help, developer, ...
184 */
185typedef enum tagUserVarCategory {
186 UVAR_CATEGORY_START = 0, ///< internal start marker for range checking
187
190 UVAR_CATEGORY_DEVELOPER, ///< optional and hidden in help-output until lalDebugLevel>=warning
191 UVAR_CATEGORY_DEPRECATED, ///< optional and hidden until lalDebugLevel>=info; still supported but output warning if used
192 UVAR_CATEGORY_DEFUNCT, ///< hidden completely from help output; not supported, will output error + help-string if used
193 UVAR_CATEGORY_NODEFAULT, ///< optional and supresses printing the default value in the help, where it doesn't make sense
194 UVAR_CATEGORY_END ///< internal end marker for range checking
196
197/**
198 * Format for logging User-input: configFile- or cmdLine-style.
199 * This determines the format of the string returned from XLALUserVarGetLog().
200 */
201typedef enum tagUserVarLogFormat {
202 UVAR_LOGFMT_RAWFORM, /**< return UserVars in a raw format suitable for further parsing */
203 UVAR_LOGFMT_CFGFILE, /**< return UserVars as a config-file */
204 UVAR_LOGFMT_CMDLINE, /**< return UserVars as a command-line */
205 UVAR_LOGFMT_PROCPARAMS, /**< return UserVars suitable for filling in process-params struct */
208
209/* Global variables */
210#ifndef SWIG /* exclude from SWIG interface */
211extern const char *lalUserVarHelpBrief;
212extern const char *lalUserVarHelpDescription;
213extern const char *lalUserVarHelpOptionSubsection;
214#endif /* SWIG */
215
216/* Function prototypes */
217void XLALDestroyUserVars( void );
218int XLALUserVarReadCmdline( BOOLEAN *should_exit, int argc, char *argv[], const LALVCSInfoList vcs_list );
219int XLALUserVarReadCfgfile( BOOLEAN *should_exit, const CHAR *cfgfile );
220int XLALUserVarReadAllInput( BOOLEAN *should_exit, int argc, char *argv[], const LALVCSInfoList vcs_list );
221int XLALUserVarWasSet( const void *cvar );
222void XLALUserVarCheck( BOOLEAN *should_exit, const int assertion, const CHAR *fmt, ... ) _LAL_GCC_PRINTF_FORMAT_(3,4);
224CHAR * XLALUserVarGetLogEx ( UserVarLogFormat format, const BOOLEAN skip_unset );
225
226/**
227 * \name Convenience macros for checking how many of a set of user input variables were set
228 */
229/** @{ */
230#define UVAR_SET(n) (XLALUserVarWasSet(&(uvar-> n)) ? 1 : 0)
231#define UVAR_SET2(n1,n2) (UVAR_SET(n1) + UVAR_SET(n2))
232#define UVAR_SET3(n1,n2,n3) (UVAR_SET2(n1,n2) + UVAR_SET(n3))
233#define UVAR_SET4(n1,n2,n3,n4) (UVAR_SET3(n1,n2,n3) + UVAR_SET(n4))
234#define UVAR_SET5(n1,n2,n3,n4,n5) (UVAR_SET4(n1,n2,n3,n4) + UVAR_SET(n5))
235#define UVAR_SET6(n1,n2,n3,n4,n5,n6) (UVAR_SET5(n1,n2,n3,n4,n5) + UVAR_SET(n6))
236/** @} */
237
238/**
239 * \name Convenience macros for checking whether all of a set of user input variables were set
240 */
241/** @{ */
242#define UVAR_ALLSET2(n1,n2) (UVAR_SET2(n1,n2) == 2)
243#define UVAR_ALLSET3(n1,n2,n3) (UVAR_SET3(n1,n2,n3) == 3)
244#define UVAR_ALLSET4(n1,n2,n3,n4) (UVAR_SET4(n1,n2,n3,n4) == 4)
245#define UVAR_ALLSET5(n1,n2,n3,n4,n5) (UVAR_SET5(n1,n2,n3,n4,n5) == 5)
246#define UVAR_ALLSET6(n1,n2,n3,n4,n5,n6) (UVAR_SET6(n1,n2,n3,n4,n5,n6) == 6)
247/** @} */
248
249/**
250 * \name Convenience macros for checking whether any of a set of user input variables were set
251 */
252/** @{ */
253#define UVAR_ANYSET2(n1,n2) (UVAR_SET2(n1,n2) > 0)
254#define UVAR_ANYSET3(n1,n2,n3) (UVAR_SET3(n1,n2,n3) > 0)
255#define UVAR_ANYSET4(n1,n2,n3,n4) (UVAR_SET4(n1,n2,n3,n4) > 0)
256#define UVAR_ANYSET5(n1,n2,n3,n4,n5) (UVAR_SET5(n1,n2,n3,n4,n5) > 0)
257#define UVAR_ANYSET6(n1,n2,n3,n4,n5,n6) (UVAR_SET6(n1,n2,n3,n4,n5,n6) > 0)
258/** @} */
259
260/**
261 * \name Convenience macros for printing user input variables in error messages
262 */
263/** @{ */
264#define UVAR_FMT "`--%s'"
265#define UVAR_STR(n) "`--"#n"'"
266#define UVAR_STR2AND(n1,n2) "`--"#n1"' and `--"#n2"'"
267#define UVAR_STR2OR(n1,n2) "`--"#n1"' or `--"#n2"'"
268#define UVAR_STR3AND(n1,n2,n3) "`--"#n1"', `--"#n2"', and `--"#n3"'"
269#define UVAR_STR3OR(n1,n2,n3) "`--"#n1"', `--"#n2"', or `--"#n3"'"
270#define UVAR_STR4AND(n1,n2,n3,n4) "`--"#n1"', `--"#n2"', `--"#n3"', and `--"#n4"'"
271#define UVAR_STR4OR(n1,n2,n3,n4) "`--"#n1"', `--"#n2"', `--"#n3"', or `--"#n4"'"
272#define UVAR_STR5AND(n1,n2,n3,n4,n5) "`--"#n1"', `--"#n2"', `--"#n3"', `--"#n4"', and `--"#n5"'"
273#define UVAR_STR5OR(n1,n2,n3,n4,n5) "`--"#n1"', `--"#n2"', `--"#n3"', `--"#n4"', or `--"#n5"'"
274#define UVAR_STR6AND(n1,n2,n3,n4,n5,n6) "`--"#n1"', `--"#n2"', `--"#n3"', `--"#n4"', `--"#n5"', and `--"#n6"'"
275#define UVAR_STR6OR(n1,n2,n3,n4,n5,n6) "`--"#n1"', `--"#n2"', `--"#n3"', `--"#n4"', `--"#n5"', or `--"#n6"'"
276/** @} */
277
278// declare type-specific wrappers to XLALRegisterUserVar() to allow for strict C type-checking!
279#define DECL_REGISTER_UVAR(UTYPE,CTYPE) \
280 DECL_REGISTER_UVAR_AUX_DATA(UTYPE,CTYPE,void)
281#define DECL_REGISTER_UVAR_AUX_DATA(UTYPE,CTYPE,DTYPE) \
282 int XLALRegister ##UTYPE## UserVar ( CTYPE *cvar, const DTYPE *cdata, const CHAR *name, CHAR optchar, UserVarCategory category, const CHAR *fmt, ... ) _LAL_GCC_PRINTF_FORMAT_(6,7)
283
284// ------ declare registration functions
295
301
304
309
310/** @} */
311
312#ifdef __cplusplus
313}
314#endif /* C++ protection. */
315
316#endif /* Double-include protection. */
#define _LAL_GCC_PRINTF_FORMAT_(NFMT, NARG)
Definition: LALStddef.h:47
#define STRING(a)
Definition: PrintVector.c:12
unsigned char BOOLEAN
Boolean logical type, see Headers LAL(Atomic)Datatypes.h for more details.
uint64_t UINT8
Eight-byte unsigned integer; on some platforms this is equivalent to unsigned long int instead.
double REAL8
Double precision real floating-point number (8 bytes).
int64_t INT8
Eight-byte signed integer; on some platforms this is equivalent to long int instead.
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
const LALVCSInfo *const LALVCSInfoList[16]
NULL-terminated list of VCS and build information structures
const char * lalUserVarHelpOptionSubsection
An optional subsection heading under OPTIONS, under which all subsequently-defined user variables are...
Definition: UserInput.c:258
const char * lalUserVarHelpBrief
An optional brief description of the program, printed after its name as part of the help page.
Definition: UserInput.c:248
UserVarLogFormat
Format for logging User-input: configFile- or cmdLine-style.
Definition: UserInput.h:201
int XLALUserVarReadAllInput(BOOLEAN *should_exit, int argc, char *argv[], const LALVCSInfoList vcs_list)
Put all the pieces together, and basically does everything: print help (if requested),...
Definition: UserInput.c:1064
void XLALDestroyUserVars(void)
Free all memory associated with user-variable linked list.
Definition: UserInput.c:349
#define DECL_REGISTER_UVAR_AUX_DATA(UTYPE, CTYPE, DTYPE)
Definition: UserInput.h:281
CHAR * XLALUserVarGetLogEx(UserVarLogFormat format, const BOOLEAN skip_unset)
Return a log-string representing the complete user-input.
Definition: UserInput.c:1238
#define DECL_REGISTER_UVAR(UTYPE, CTYPE)
Definition: UserInput.h:279
void XLALUserVarCheck(BOOLEAN *should_exit, const int assertion, const CHAR *fmt,...) _LAL_GCC_PRINTF_FORMAT_(3
UserVarCategory
Mutually-exclusive user variable categories: optional, required, help, developer, ....
Definition: UserInput.h:185
int XLALUserVarReadCmdline(BOOLEAN *should_exit, int argc, char *argv[], const LALVCSInfoList vcs_list)
Parse command-line into UserVariable array.
Definition: UserInput.c:394
void CHAR * XLALUserVarGetLog(UserVarLogFormat format)
Return a log-string representing the complete user-input.
Definition: UserInput.c:1228
const char * lalUserVarHelpDescription
An optional longer description of the program, printed in its own section as part of the help page.
Definition: UserInput.c:253
int XLALUserVarWasSet(const void *cvar)
Has this user-variable been set by the user? returns 1 (=TRUE) or 0 (=FALSE) on success,...
Definition: UserInput.c:1175
int XLALUserVarReadCfgfile(BOOLEAN *should_exit, const CHAR *cfgfile)
Read config-variables from cfgfile and parse into input-structure.
Definition: UserInput.c:647
@ UVAR_LOGFMT_RAWFORM
return UserVars in a raw format suitable for further parsing
Definition: UserInput.h:202
@ UVAR_LOGFMT_CMDLINE
return UserVars as a command-line
Definition: UserInput.h:204
@ UVAR_LOGFMT_LAST
Definition: UserInput.h:206
@ UVAR_LOGFMT_PROCPARAMS
return UserVars suitable for filling in process-params struct
Definition: UserInput.h:205
@ UVAR_LOGFMT_CFGFILE
return UserVars as a config-file
Definition: UserInput.h:203
@ UVAR_CATEGORY_START
internal start marker for range checking
Definition: UserInput.h:186
@ UVAR_CATEGORY_REQUIRED
required
Definition: UserInput.h:189
@ UVAR_CATEGORY_DEFUNCT
hidden completely from help output; not supported, will output error + help-string if used
Definition: UserInput.h:192
@ UVAR_CATEGORY_OPTIONAL
optional
Definition: UserInput.h:188
@ UVAR_CATEGORY_NODEFAULT
optional and supresses printing the default value in the help, where it doesn't make sense
Definition: UserInput.h:193
@ UVAR_CATEGORY_DEVELOPER
optional and hidden in help-output until lalDebugLevel>=warning
Definition: UserInput.h:190
@ UVAR_CATEGORY_DEPRECATED
optional and hidden until lalDebugLevel>=info; still supported but output warning if used
Definition: UserInput.h:191
@ UVAR_CATEGORY_END
internal end marker for range checking
Definition: UserInput.h:194
LIGOTimeGPS LIGOTimeGPSRange[2]
A range of GPS times; first element is minimum, second element is maximum of range.
REAL8 REAL8Range[2]
A range of REAL8 values; first element is minimum, second element is maximum of range.
INT4 INT4Range[2]
A range of INT4 values; first element is minimum, second element is maximum of range.
Vector of type INT4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:109
Vector of type CHAR*, ie 'strings', see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:82
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Definition: LALDatatypes.h:458
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
Vector of type UINT4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:118
Possible choices the user may select for an enumeration or bitflag.