31#ifdef HAVE_SYS_IOCTL_H
35#include <lal/LALStdio.h>
36#include <lal/LALgetopt.h>
37#include <lal/LogPrintf.h>
38#include <lal/LALString.h>
40#include <lal/StringVector.h>
41#include <lal/AVFactories.h>
43#include <lal/UserInputParse.h>
44#include <lal/UserInputPrint.h>
46#include <lal/UserInput.h>
55#define DEFN_REGISTER_UVAR(UTYPE,CTYPE) \
56 DEFN_REGISTER_UVAR_AUX_DATA(UTYPE,CTYPE,void)
57#define DEFN_REGISTER_UVAR_AUX_DATA(UTYPE,CTYPE,DTYPE) \
58int XLALRegister ##UTYPE## UserVar ( CTYPE *cvar, const DTYPE *cdata, const CHAR *name, CHAR optchar, UserVarCategory category, const CHAR *fmt, ... ) \
63 vsnprintf(helpstr, sizeof(helpstr), fmt, ap); \
65 return XLALRegisterUserVar (cvar, (const void*)cdata, name, UVAR_TYPE_ ## UTYPE, optchar, category, helpstr); \
105typedef struct tagLALUserVariable {
115 struct tagLALUserVariable *
next;
153typedef int (*
parserT)(
void *cvar,
const char *valstr);
154typedef char *(*printerT)(
const void *cvar);
155typedef int (*
parser_cdataT)(
void *cvar,
const void *cdata,
const char *valstr);
156typedef char *(*printer_cdataT)(
const void *cvar,
const void *cdata);
157typedef char *(*format_help_cdataT)(
const void *cdata);
160#define REGULAR_MAP_ENTRY(UTYPE,DESTRUCTOR,FORMATHELP) \
161 [UVAR_TYPE_##UTYPE] = { \
163 .destructor = (destructorT)DESTRUCTOR, \
164 .parser = (parserT)XLALParseStringValueAs##UTYPE, \
165 .printer = (printerT)XLALPrintStringValueOf##UTYPE, \
166 .format_help_str = FORMATHELP, \
168#define REGULAR_MAP_ENTRY_AUX_DATA(UTYPE,DESTRUCTOR,DTYPE) \
169 [UVAR_TYPE_##UTYPE] = { \
171 .destructor = (destructorT)DESTRUCTOR, \
172 .parser_cdata = (parser_cdataT)XLALParseStringValueAs##UTYPE, \
173 .printer_cdata = (printer_cdataT)XLALPrintStringValueOf##UTYPE, \
174 .format_help_cdata = (format_help_cdataT)XLALFormatHelpStringOf##UTYPE, \
219 REGULAR_MAP_ENTRY ( EPOCH, NULL,
"=<seconds>[.<frac-seconds>][GPS] | <days>[.<frac-days>]MJD" ),
225 REGULAR_MAP_ENTRY ( EPOCHRange, NULL,
"=<start>[,<end>|/<band>|~<plus-minus>] where <>=<seconds>[.<frac-seconds>][GPS] | <days>[.<frac-days>]MJD" ),
226 REGULAR_MAP_ENTRY ( RAJRange, NULL,
"=<start>[,<end>|/<band>|~<plus-minus>] where <>=<radians>|<hours>:<minutes>:<seconds>" ),
227 REGULAR_MAP_ENTRY ( DECJRange, NULL,
"=<start>[,<end>|/<band>|~<plus-minus>] where <>=<radians>|<degrees>:<minutes>:<seconds>" ),
302 XLAL_CHECK ( optchar !=
'v',
XLAL_EINVAL,
"Short-option '-%c' is reserved for version!\n", optchar );
306 while ( ptr->
next != NULL )
331 strncpy( ptr->
help, help,
sizeof(ptr->
help) - 1 );
355 while ( (ptr=ptr->
next) != NULL )
367 if ( lastptr != NULL ) {
375 if ( lastptr != NULL ) {
407 char optstring[512] =
"\0";
411 optstring[pos++] =
'v';
412 optstring[pos++] =
':';
413 optstring[pos++] =
':';
417 while ( (ptr = ptr->
next) != NULL )
423 optstring[pos++] = ptr->
optchar;
424 optstring[pos++] =
':';
426 optstring[pos++] =
':';
431 optstring[pos] =
'\0';
438 long_options[pos].
name =
"version";
440 long_options[pos].
flag = NULL;
441 long_options[pos].
val = 0;
446 while ( (ptr= ptr->
next) != NULL)
450 long_options[pos].
flag = NULL;
451 long_options[pos].
val = 0;
456 long_options[pos].
name = 0;
458 long_options[pos].
flag = 0;
459 long_options[pos].
val = 0;
476 char *old_argv0 = argv[0];
479 int c =
LALgetopt_long(argc, argv, optstring, long_options, &longindex);
484 if ( c ==
'?' || c ==
':' ) {
491 if ( (c != 0) ? (c ==
'v') : !strcmp(long_options[longindex].
name,
"version") )
522 }
while ( (ptr=ptr->
next) != NULL);
527 while ( (ptr=ptr->
next) != NULL) {
528 if ( !strcmp (long_options[longindex].
name, ptr->
name) ) {
534 XLAL_CHECK ( ptr != NULL,
XLAL_EFAILED,
"ERROR: failed to find matching option ... this points to a coding-error!\n" );
578 *(
char**)ptr->
cvar = NULL;
660 while ( (ptr=ptr->
next) != NULL)
666 CHAR *valString = NULL;
674 *(
char**)ptr->
cvar = NULL;
676 if ( valString == NULL || strlen(valString) == 0 )
699 XLALUserVarCheck( should_exit, 0,
"configuration option `%s' was set more than once!", ptr->
name );
710 if ( unread != NULL )
712 XLALPrintWarning (
"The following entries in config-file '%s' have not been parsed:\n", cfgfile );
738 switch ( ptr->category )
751 if ( ptr->optchar != 0 ) {
771 while ( ( s = strchr( s,
'`' ) ) != NULL )
773 while ( *s !=
'\0' && *s !=
'\'' )
775 if ( *s ==
'_' ) *s =
'-';
789 line_width -= strlen(
prefix) + 1;
792 if ( line_width < 1 ) {
793 line_width = INT_MAX;
797 char *pstart = text, *pline = text, *pbreak = NULL;
798 char empty_line[2] =
"";
799 char list_indent[16] =
"";
800 for (
char *pend = text; *pend !=
'\0'; ++pend )
804 if ( isspace( *pend ) ) {
809 strcpy( list_indent,
"" );
810 if ( pline != pstart ) {
811 for (
size_t i = 0; i + 1 <
XLAL_NUM_ELEM( list_indent ) && strchr(
" -", pline[i] ) != NULL; ++i ) {
812 list_indent[i] =
' ';
817 int indented_line_width = line_width - strlen( list_indent );
818 if ( ( pend - pstart ) == indented_line_width || *pend ==
'\n' ) {
821 if ( *pend ==
'\n' ) {
825 if ( pbreak != NULL ) {
828 const char old_pbreak = *pbreak;
831 strcpy( empty_line,
"" );
832 *pbreak = old_pbreak;
835 for ( pend = pbreak + 1; *pend !=
'\0' && *pend ==
'\n'; ++pend ) {
836 strcpy( empty_line,
"\n" );
849 const char old_pend = *pend;
852 strcpy( empty_line,
"" );
864 if ( strlen( pstart ) > 0 ) {
866 strcpy( empty_line,
"" );
884#if defined(HAVE_ISATTY) && defined(HAVE_FILENO) && defined(HAVE_IOCTL)
885#if HAVE_DECL_TIOCGWINSZ && HAVE_STRUCT_WINSIZE_WS_COL
886 if ( isatty( fileno(
file ) ) ) {
888 ioctl( fileno(
file ), TIOCGWINSZ, &w );
889 line_width = w.ws_col;
895#if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE)
896 f = popen(PAGER,
"w");
913 CHAR help_str[] =
"Display this help page.";
919 CHAR help_str[] =
"Display a short usage string of available options.";
925 CHAR help_str[] =
"Display (verbose) version information.";
931 CHAR help_str[] =
"Run the program. Options are parsed from, if given:\n- Configuration file <config-file>: format is INI file style, one <option>=<value> pair per line.\n- Command line <options>: format is --<option>=<value>, --<option> <value>, or -<short-option> <value>.";
944 const char* section_headers[] = {
"OPTIONS",
"DEVELOPER OPTIONS",
"DEPRECATED OPTIONS" };
945 for (
size_t section = 0; section <
XLAL_NUM_ELEM(section_headers); ++section )
947 BOOLEAN print_section_header = 1;
950 const char *subsection = NULL;
955 size_t print_section = 0;
956 BOOLEAN print_format_help = 1, print_default_value = 1;
957 switch ( ptr->category )
964 print_format_help = print_default_value = 0;
973 if ( print_section == section )
977 if ( print_section_header )
979 fprintf(
f,
"%s\n", section_headers[section] );
980 print_section_header = 0;
982 if ( ptr->subsection != NULL && ( subsection == NULL || strcmp( ptr->subsection, subsection ) != 0 ) )
984 fprintf(
f,
" %s\n", ptr->subsection );
985 subsection = ptr->subsection;
990 if ( ptr->optchar != 0 )
992 fprintf(
f,
"-%c, ", ptr->optchar );
995 if ( print_format_help )
997 if ( ptr->cdata != NULL )
1009 if ( print_default_value )
1019 else if ( ptr->cvar )
1021 CHAR *valstr = ptr->cdata != NULL ?
UserVarTypeMap [ ptr->type ].printer_cdata( ptr->cvar, ptr->cdata ) :
UserVarTypeMap [ ptr->type ].printer( ptr->cvar );
1023 fprintf(
f,
" [default: %s]", valstr );
1044#if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE)
1084 for (
INT4 i = 1; i < argc; i++ )
1087 if ( strcmp( argv[i],
"-h" ) == 0 )
1093 else if ( strcmp( argv[i],
"--help" ) == 0 || strcmp( argv[i],
"-help" ) == 0 )
1102 CHAR* cfgfile_name = NULL;
1103 for (
INT4 i = 1; i < argc; i++ )
1105 char *argi = argv[i];
1108 if ( argi[0] ==
'@' )
1110 XLAL_CHECK ( cfgfile_name == NULL,
XLAL_EINVAL,
"Can only handle *one* config-file passed on commandline!\n" );
1118 if ( cfgfile_name != NULL )
1121 if ( *should_exit ) {
1129 if ( *should_exit ) {
1145 if ( *should_exit ) {
1152 if ( !skipCheckRequired ) {
1158 if ( *should_exit ) {
1182 while ( (ptr = ptr->
next) != NULL )
1184 if ( ptr->
cvar != NULL && ptr->
cvar == cvar) {
1189 XLAL_CHECK ( ptr != NULL,
XLAL_EINVAL,
"Variable pointer passed UVARwasSet is not a registered User-variable\n" );
1208 if ( !( *should_exit ) && !assertion ) {
1211 va_start( ap, fmt );
1212 vsnprintf( buf,
sizeof( buf ), fmt, ap );
1245 CHAR *record = NULL;
1259 while ( (ptr = ptr->
next) )
1261 if ( skip_unset && ! ptr->
was_set ) {
1264 if ( ! ptr->
cvar ) {
int XLALReadConfigSTRINGVariable(CHAR **varp, LALParsedDataFile *cfgdata, const CHAR *secName, const CHAR *varName, BOOLEAN *wasRead)
String parser for config-file: can read config-variables of the form VARIABLE [=:] VALUE.
static const size_t prefix
char * XLALStringAppendFmt(char *s, const char *fmt,...)
Append the formatted string 'fmt' to the string 's', which is reallocated with XLALRealloc() to the r...
int LALgetopt_long(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
#define required_argument
#define optional_argument
int XLALPrintWarning(const char *fmt,...)
int XLALPrintError(const char *fmt,...)
static double f(double theta, double y, double xi)
int XLALParseDataFile(LALParsedDataFile **cfgdata, const CHAR *path)
Parse an ASCII data-file into a pre-cleaned array of lines.
UINT4Vector * XLALConfigFileGetUnreadEntries(const LALParsedDataFile *cfgdata)
Return a list of unread config-file entries, NULL if none found (without error).
void XLALDestroyParsedDataFile(LALParsedDataFile *cfgdata)
Free memory associated with a LALParsedDataFile structure.
unsigned char BOOLEAN
Boolean logical type, see Headers LAL(Atomic)Datatypes.h for more details.
#define XLAL_NUM_ELEM(x)
MACRO which gives the number of elements in a fixed-size array.
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.
char * XLALStringDuplicate(const char *s)
Like strdup but uses LAL allocation routines (free with LALFree).
char * XLALStringAppend(char *s, const char *append)
Like strcat but dynamically reallocates string with LALRealloc.
char * XLALStringReplaceChar(char *s, const int from, const int to)
Return the string 's' with all characters 'from' replaced with 'to'.
char * XLALVCSInfoString(const LALVCSInfoList vcs_list, const int verbose, const char *prefix)
Generate a multi-line string containing VCS and build information for a library and its dependencies,...
const LALVCSInfo *const LALVCSInfoList[16]
NULL-terminated list of VCS and build information structures
void XLALDestroyStringVector(LALStringVector *vect)
XLAL-interface: Free a string-vector ;)
void XLALDestroyUINT4Vector(UINT4Vector *vector)
void XLALDestroyINT4Vector(INT4Vector *vector)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
#define XLAL_CHECK(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns an integ...
#define XLAL_CHECK_VOID(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns void.
#define XLAL_CHECK_FAIL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true by jumping to a XLAL_FAIL label.
#define XLAL_CHECK_NULL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a pointe...
@ XLAL_ENOMEM
Memory allocation error.
@ XLAL_SUCCESS
Success return value (not an error number)
@ XLAL_EFAULT
Invalid pointer.
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
@ XLAL_EERR
Internal error.
@ XLAL_EINVAL
Invalid argument.
@ XLAL_EFAILED
Generic failure.
@ XLAL_FAILURE
Failure return value (not an error number)
Vector of type INT4, see DATATYPE-Vector types for more details.
This structure is returned by XLALParseDataFile() and holds the contents of an ASCII data-file in a p...
TokenList * lines
list of pre-parsed data-file lines
Vector of type CHAR*, ie 'strings', see DATATYPE-Vector types for more details.
struct tagLALUserVariable * next
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Vector of type REAL8, see DATATYPE-Vector types for more details.
CHAR ** tokens
A list of pointers to the individual tokens; the elements tokens[0..nTokens-1] point to tokens,...
Vector of type UINT4, see DATATYPE-Vector types for more details.
UINT4 length
Number of elements in array.
UINT4 * data
Pointer to the data array.
Possible choices the user may select for an enumeration or bitflag.