/** * Return a log-string representing the <em>complete</em> user-input. * <em>NOTE:</em> we only record user-variables that have been set * by the user. */ CHAR * XLALUserVarGetLog ( UserVarLogFormat format /**< output format: return as config-file or command-line */ ) { XLAL_CHECK_NULL ( UVAR_vars.next != NULL, XLAL_EINVAL, "No UVAR memory allocated. Did you register any user-variables?" ); XLAL_CHECK_NULL ( format < UVAR_LOGFMT_LAST, XLAL_EINVAL ); CHAR *record = NULL; if ( format == UVAR_LOGFMT_CMDLINE ) { XLAL_CHECK_NULL ( (record = XLALStringAppend ( record, program_name)) != NULL, XLAL_EFUNC ); } LALUserVariable *ptr = &UVAR_vars; while ( (ptr = ptr->next) ) { if ( ! ptr->was_set ) { // skip unset variables continue; } CHAR *valstr; XLAL_CHECK_NULL ( (valstr = UserVarTypeMap [ ptr->type ].printer( ptr->varp )) != NULL, XLAL_EFUNC ); char append[256]; switch (format) { case UVAR_LOGFMT_CFGFILE: snprintf (append, sizeof(append), "%s = %s;\n", ptr->name, valstr); break; case UVAR_LOGFMT_CMDLINE: snprintf (append, sizeof(append), " --%s=%s", ptr->name, valstr); break; case UVAR_LOGFMT_PROCPARAMS: snprintf (append, sizeof(append), "--%s = %s :%s;", ptr->name, valstr, UserVarTypeMap[ptr->type].name ); break; default: XLAL_ERROR_NULL ( XLAL_EINVAL, "Unknown format for recording user-input: '%i'\n", format ); break; } // switch (format) XLAL_LAST_ELEM(append) = 0; XLAL_CHECK_NULL ( (record = XLALStringAppend (record, append)) != NULL, XLAL_EFUNC ); XLALFree (valstr); } // while ptr=ptr->next return record; } // XLALUserVarGetLog()
/// /// Parse a string representing an 'epoch' into an LIGOTimeGPS, allowing both GPS and MJD(TT) inputs, at ns accuracy. /// /// Allowed input string formats are "INT4.INT4[GPS|MJD]", where the optional postfix 'GPS' or 'MJD' indicates /// the time 'units', which defaults to GPS if no postfix is given. Note that MJD input is interpreted as MJD(TT), /// and translated into GPS using XLALTranslateStringMJDTTtoGPS(). /// This ignores initial whitespace, but throws an error on _any_ non-converted trailing characters (including whitespace) /// int XLALParseStringValueAsEPOCH ( LIGOTimeGPS *gps, ///< [out] return LIGOTimeGPS value const char *valString ///< [in] input string value ) { XLAL_CHECK ( (gps != NULL) && (valString != NULL ), XLAL_EINVAL ); char buf[256]; strncpy ( buf, valString, sizeof(buf)-1 ); XLAL_LAST_ELEM(buf) = 0; // ---------- first check if there's a postfix indicating the time 'units' (GPS or MJD): BOOLEAN is_gps; char *postfix; if ( (postfix = strstr ( buf, "MJD" )) != NULL ) { XLAL_CHECK ( postfix[3] == 0, XLAL_EINVAL, "Input '%s' contains trailing characters after units 'MJD': must be of form 'xxx.yyyMJD'\n", valString ); postfix[0] = 0; // cut off postfix is_gps = 0; } else if ( (postfix = strstr ( buf, "GPS" )) != NULL ) { XLAL_CHECK ( postfix[3] == 0, XLAL_EINVAL, "Input '%s' contains trailing characters after units 'GPS': must be of form 'xxx.yyy' or 'xxx.yyyGPS'\n", valString ); postfix[0] = 0; // cut off postfix is_gps = 1; } else // no postfix: default to 'GPS' units { is_gps = 1; } if ( is_gps ) { XLAL_CHECK ( XLALParseStringValueAsGPS ( gps, buf ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { XLAL_CHECK ( XLALTranslateStringMJDTTtoGPS ( gps, buf ) != NULL, XLAL_EFUNC ); } return XLAL_SUCCESS; } // XLALParseStringValueAsEPOCH()
/// /// Parse a string containing a floating-point number into integer and fractional part, such that val = valINT + valFrac. /// /// This is useful for parsing strings representing GPS or MJD times wihout loss of ns accuracy. /// int XLALParseStringValueAsINT4PlusFrac ( INT4 *valINT4, ///< [out] return INT4 integer part 'xxx' REAL8 *valFrac, ///< [out] return fractional part '0.yyyy' const char *valString ///< [in] input string value representing a floating-point number "xxx.yyyy" ) { XLAL_CHECK ( (valINT4 != NULL) && (valFrac != NULL) && (valString != NULL), XLAL_EINVAL ); XLAL_CHECK ( !isspace(valString[0]), XLAL_EINVAL, "No initial whitespace allowed in input string '%s'\n", valString ); char buf[256]; strncpy ( buf, valString, sizeof(buf)-1 ); XLAL_LAST_ELEM(buf) = 0; REAL8 sign = 1; if ( valString[0] == '-' ) { // that's why no initial whitespace is allowed in input string sign = -1; } char *point = strchr ( buf, '.' ); // is there a fractional part at all? If yes, parse it, if no, set to 0 if ( point != NULL ) { (*point) = 0; char fracString[256] = "0."; strcat ( fracString+2, point+1); XLAL_CHECK ( XLALParseStringValueAsREAL8 ( valFrac, fracString ) == XLAL_SUCCESS, XLAL_EFUNC ); (*valFrac) *= sign; // correct sign: must agree with integer part } else { (*valFrac) = 0; } // now parse integer part XLAL_CHECK ( XLALParseStringValueAsINT4 ( valINT4, buf ) == XLAL_SUCCESS, XLAL_EFUNC ); return XLAL_SUCCESS; } // XLALParseStringValueAsINT4PlusFrac()
/** * Assemble all help-info from uvars into a help-string. */ CHAR * XLALUserVarHelpString ( const CHAR *progname ) { XLAL_CHECK_NULL ( progname != NULL, XLAL_EINVAL ); XLAL_CHECK_NULL ( UVAR_vars.next != NULL, XLAL_EINVAL, "No UVAR memory allocated. Did you register any user-variables?\n" ); BOOLEAN showDeveloperOptions = (lalDebugLevel >= LALWARNING); // only output for lalDebugLevel >= warning BOOLEAN showDeprecatedOptions = (lalDebugLevel >= LALINFO); // only output for lalDebugLevel >= info // ---------- ZEROTH PASS: find longest long-option and type names, for proper output formatting LALUserVariable *ptr = &UVAR_vars; UINT4 nameFieldLen = 0; UINT4 typeFieldLen = 0; BOOLEAN haveDeveloperOptions = 0; BOOLEAN haveDeprecatedOptions = 0; while ( (ptr=ptr->next) != NULL ) { if (ptr->category == UVAR_CATEGORY_DEVELOPER) { haveDeveloperOptions = 1; } if ( ptr->category == UVAR_CATEGORY_DEPRECATED ) { haveDeprecatedOptions = 1; } if ( (ptr->category == UVAR_CATEGORY_DEVELOPER) && !showDeveloperOptions ) { continue; // skip developer options if not requested } if ( (ptr->category == UVAR_CATEGORY_DEPRECATED) && !showDeprecatedOptions ) { continue; // skip deprecated options if not requested } if ( ptr->category == UVAR_CATEGORY_DEFUNCT ) { continue; // always skip defunct options to hide them completely from help string } UINT4 len; // max variable name length if ( ptr->name != NULL ) { len = strlen ( ptr->name ); nameFieldLen = (len > nameFieldLen) ? len : nameFieldLen; } // max type name length len = strlen ( UserVarTypeMap[ptr->type].name ); typeFieldLen = (len > typeFieldLen) ? len : typeFieldLen; } // while ptr=ptr->next CHAR fmtStr[256]; // for building a dynamic format-string snprintf ( fmtStr, sizeof(fmtStr), " %%s --%%-%ds %%-%ds %%s [%%s]\n", nameFieldLen, typeFieldLen ); XLAL_LAST_ELEM(fmtStr)=0; CHAR defaultstr[256]; // for display of default-value CHAR strbuf[512]; CHAR *helpstr_regular = NULL; CHAR *helpstr_developer = NULL; CHAR *helpstr_deprecated = NULL; // ---------- provide header line: info about config-file reading snprintf (strbuf, sizeof(strbuf), "Usage: %s [@ConfigFile] [options], where options are:\n\n", progname); XLAL_LAST_ELEM(strbuf) = 0; XLAL_CHECK_NULL ( (helpstr_regular = XLALStringDuplicate ( strbuf )) != NULL, XLAL_EFUNC ); // ---------- MAIN LOOP: step through all user variables and add entry to appropriate help string ptr = &UVAR_vars; while ( (ptr=ptr->next) != NULL ) // header always empty { if ( ptr->category == UVAR_CATEGORY_REQUIRED ) { strcpy (defaultstr, "REQUIRED"); } else if ( ptr->category == UVAR_CATEGORY_HELP ) { strcpy ( defaultstr, ""); } else // write the current default-value into a string { CHAR *valstr; XLAL_CHECK_NULL ( (valstr = UserVarTypeMap [ ptr->type ].printer( ptr->varp )) != NULL, XLAL_EFUNC ); strncpy ( defaultstr, valstr, sizeof(defaultstr) ); // cut short for default-entry XLAL_LAST_ELEM(defaultstr) = 0; XLALFree (valstr); } CHAR optstr[10]; if (ptr->optchar != 0) { sprintf (optstr, "-%c,", ptr->optchar); } else { strcpy (optstr, " "); } snprintf ( strbuf, sizeof(strbuf), fmtStr, optstr, ptr->name ? ptr->name : "-NONE-", UserVarTypeMap[ptr->type].name, ptr->help ? ptr->help : "-NONE-", defaultstr ); XLAL_LAST_ELEM(strbuf) = 0; // now append new line to the appropriate helpstring switch ( ptr->category ) { case UVAR_CATEGORY_DEVELOPER: if ( showDeveloperOptions ) { helpstr_developer = XLALStringAppend ( helpstr_developer, strbuf ); } break; case UVAR_CATEGORY_DEPRECATED: if ( showDeprecatedOptions ) { helpstr_deprecated = XLALStringAppend ( helpstr_deprecated, strbuf ); } break; default: helpstr_regular = XLALStringAppend ( helpstr_regular, strbuf ); break; } // switch category } // while ptr=ptr->next CHAR *helpstr = NULL; XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_regular )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC ); // handle output of developer options, if requested if ( haveDeveloperOptions ) { if ( !showDeveloperOptions ) { const char *str = " ---------- Use help with lalDebugLevel >= warning to also see all 'developer' options ----------\n"; XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC ); } else { const char *str = " ---------- The following are 'developer'-options not useful for most users:----------\n\n"; XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_developer )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC ); } } // if haveDeveloperOptions // handle output of deprecated options, if requested if ( haveDeprecatedOptions ) { if ( !showDeprecatedOptions ) { const char *str = " ---------- Use help with lalDebugLevel >= info to also see deprecated options ----------\n"; XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC ); } else { const char *str = " ---------- The following are *DEPRECATED* options that shouldn't be used any more:----------\n\n"; XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_deprecated )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC ); } } // if haveDeprecatedOptions XLALFree ( helpstr_regular ); XLALFree ( helpstr_developer ); XLALFree ( helpstr_deprecated ); return helpstr; } // XLALUserVarHelpString()