/** * Load a configuration file. This may be invoked either from * scanning the "homerc" list, or from a specific file request. * (see "optionFileLoad()", the implementation for --load-opts) */ LOCAL void intern_file_load(tOptions * opts) { uint32_t svfl; int idx; int inc; char f_name[ AG_PATH_MAX+1 ]; if (opts->papzHomeList == NULL) return; svfl = opts->fOptSet; inc = DIRECTION_PRESET; /* * Never stop on errors in config files. */ opts->fOptSet &= ~OPTPROC_ERRSTOP; /* * Find the last RC entry (highest priority entry) */ for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ; /* * For every path in the home list, ... *TWICE* We start at the last * (highest priority) entry, work our way down to the lowest priority, * handling the immediate options. * Then we go back up, doing the normal options. */ for (;;) { struct stat sb; cch_t * path; /* * IF we've reached the bottom end, change direction */ if (idx < 0) { inc = DIRECTION_PROCESS; idx = 0; } path = opts->papzHomeList[ idx ]; /* * IF we've reached the top end, bail out */ if (path == NULL) break; idx += inc; if (! optionMakePath(f_name, (int)sizeof(f_name), path, opts->pzProgPath)) continue; /* * IF the file name we constructed is a directory, * THEN append the Resource Configuration file name * ELSE we must have the complete file name */ if (stat(f_name, &sb) != 0) continue; /* bogus name - skip the home list entry */ if (S_ISDIR(sb.st_mode)) { size_t len = strlen(f_name); size_t nln = strlen(opts->pzRcName) + 1; char * pz = f_name + len; if (len + 1 + nln >= sizeof(f_name)) continue; if (pz[-1] != DIRCH) *(pz++) = DIRCH; memcpy(pz, opts->pzRcName, nln); } file_preset(opts, f_name, inc); /* * IF we are now to skip config files AND we are presetting, * THEN change direction. We must go the other way. */ { tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; if (DISABLED_OPT(od) && PRESETTING(inc)) { idx -= inc; /* go back and reprocess current file */ inc = DIRECTION_PROCESS; } } } /* twice for every path in the home list, ... */ opts->fOptSet = svfl; }
/* * Load an option from a block of text. The text must start with the * configurable/option name and be followed by its associated value. * That value may be processed in any of several ways. See "tOptionLoadMode" * in autoopts.h. */ LOCAL void loadOptionLine( tOptions* pOpts, tOptState* pOS, char* pzLine, tDirection direction, tOptionLoadMode load_mode ) { while (isspace( (int)*pzLine )) pzLine++; { char* pzArg = assembleArgValue( pzLine, load_mode ); if (! SUCCESSFUL( longOptionFind( pOpts, pzLine, pOS ))) return; if (pOS->flags & OPTST_NO_INIT) return; pOS->pzOptArg = pzArg; } switch (pOS->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) { case 0: /* * The selected option has no immediate action. * THEREFORE, if the direction is PRESETTING * THEN we skip this option. */ if (PRESETTING(direction)) return; break; case OPTST_IMM: if (PRESETTING(direction)) { /* * We are in the presetting direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if disabled. */ if ((pOS->flags & OPTST_DISABLED) == 0) return; } else { /* * We are in the processing direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((pOS->flags & OPTST_DISABLED) != 0) return; } break; case OPTST_DISABLE_IMM: if (PRESETTING(direction)) { /* * We are in the presetting direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((pOS->flags & OPTST_DISABLED) != 0) return; } else { /* * We are in the processing direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if disabled. */ if ((pOS->flags & OPTST_DISABLED) == 0) return; } break; case OPTST_IMM|OPTST_DISABLE_IMM: /* * The selected option is always for immediate action. * THEREFORE, if the direction is PROCESSING * THEN we skip this option. */ if (PROCESSING(direction)) return; break; } /* * Fix up the args. */ if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { if (*pOS->pzOptArg != NUL) return; pOS->pzOptArg = NULL; } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { if (*pOS->pzOptArg == NUL) pOS->pzOptArg = NULL; else { AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" ); pOS->flags |= OPTST_ALLOC_ARG; } } else { if (*pOS->pzOptArg == NUL) pOS->pzOptArg = zNil; else { AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" ); pOS->flags |= OPTST_ALLOC_ARG; } } { tOptionLoadMode sv = option_load_mode; option_load_mode = load_mode; handleOption( pOpts, pOS ); option_load_mode = sv; } }
/** * Load an option from a block of text. The text must start with the * configurable/option name and be followed by its associated value. * That value may be processed in any of several ways. See "tOptionLoadMode" * in autoopts.h. * * @param[in,out] opts program options descriptor * @param[in,out] opt_state option processing state * @param[in,out] line source line with long option name in it * @param[in] direction current processing direction (preset or not) * @param[in] load_mode option loading mode (OPTION_LOAD_*) */ LOCAL void loadOptionLine( tOptions * opts, tOptState * opt_state, char * line, tDirection direction, tOptionLoadMode load_mode ) { line = SPN_LOAD_LINE_SKIP_CHARS(line); { char * arg = assemble_arg_val(line, load_mode); if (! SUCCESSFUL(opt_find_long(opts, line, opt_state))) return; if (opt_state->flags & OPTST_NO_INIT) return; opt_state->pzOptArg = arg; } switch (opt_state->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) { case 0: /* * The selected option has no immediate action. * THEREFORE, if the direction is PRESETTING * THEN we skip this option. */ if (PRESETTING(direction)) return; break; case OPTST_IMM: if (PRESETTING(direction)) { /* * We are in the presetting direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if disabled. */ if ((opt_state->flags & OPTST_DISABLED) == 0) return; } else { /* * We are in the processing direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((opt_state->flags & OPTST_DISABLED) != 0) return; } break; case OPTST_DISABLE_IMM: if (PRESETTING(direction)) { /* * We are in the presetting direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((opt_state->flags & OPTST_DISABLED) != 0) return; } else { /* * We are in the processing direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if disabled. */ if ((opt_state->flags & OPTST_DISABLED) == 0) return; } break; case OPTST_IMM|OPTST_DISABLE_IMM: /* * The selected option is always for immediate action. * THEREFORE, if the direction is PROCESSING * THEN we skip this option. */ if (PROCESSING(direction)) return; break; } /* * Fix up the args. */ if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) { if (*opt_state->pzOptArg != NUL) return; opt_state->pzOptArg = NULL; } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) { if (*opt_state->pzOptArg == NUL) opt_state->pzOptArg = NULL; else { AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); opt_state->flags |= OPTST_ALLOC_ARG; } } else { if (*opt_state->pzOptArg == NUL) opt_state->pzOptArg = zNil; else { AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); opt_state->flags |= OPTST_ALLOC_ARG; } } { tOptionLoadMode sv = option_load_mode; option_load_mode = load_mode; handle_opt(opts, opt_state); option_load_mode = sv; } }
/* internalFileLoad * * Load a configuration file. This may be invoked either from * scanning the "homerc" list, or from a specific file request. * (see "optionFileLoad()", the implementation for --load-opts) */ LOCAL void internalFileLoad( tOptions* pOpts ) { int idx; int inc = DIRECTION_PRESET; char zFileName[ AG_PATH_MAX+1 ]; if (pOpts->papzHomeList == NULL) return; /* * Find the last RC entry (highest priority entry) */ for (idx = 0; pOpts->papzHomeList[ idx+1 ] != NULL; ++idx) ; /* * For every path in the home list, ... *TWICE* We start at the last * (highest priority) entry, work our way down to the lowest priority, * handling the immediate options. * Then we go back up, doing the normal options. */ for (;;) { struct stat StatBuf; cch_t* pzPath; /* * IF we've reached the bottom end, change direction */ if (idx < 0) { inc = DIRECTION_PROCESS; idx = 0; } pzPath = pOpts->papzHomeList[ idx ]; /* * IF we've reached the top end, bail out */ if (pzPath == NULL) break; idx += inc; if (! optionMakePath( zFileName, (int)sizeof(zFileName), pzPath, pOpts->pzProgPath )) continue; /* * IF the file name we constructed is a directory, * THEN append the Resource Configuration file name * ELSE we must have the complete file name */ if (stat( zFileName, &StatBuf ) != 0) continue; /* bogus name - skip the home list entry */ if (S_ISDIR( StatBuf.st_mode )) { size_t len = strlen( zFileName ); char* pz; if (len + 1 + strlen( pOpts->pzRcName ) >= sizeof( zFileName )) continue; pz = zFileName + len; if (pz[-1] != DIRCH) *(pz++) = DIRCH; strcpy( pz, pOpts->pzRcName ); } filePreset( pOpts, zFileName, inc ); /* * IF we are now to skip config files AND we are presetting, * THEN change direction. We must go the other way. */ { tOptDesc * pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts+1; if (DISABLED_OPT(pOD) && PRESETTING(inc)) { idx -= inc; /* go back and reprocess current file */ inc = DIRECTION_PROCESS; } } } /* twice for every path in the home list, ... */ }
/** * See if the option is to be processed in the current scan direction * (-1 or +1). */ static bool direction_ok(opt_state_mask_t f, int dir) { if (dir == 0) return true; switch (f & (OPTST_IMM|OPTST_DISABLE_IMM)) { case 0: /* * The selected option has no immediate action. * THEREFORE, if the direction is PRESETTING * THEN we skip this option. */ if (PRESETTING(dir)) return false; break; case OPTST_IMM: if (PRESETTING(dir)) { /* * We are in the presetting direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if disabled. */ if ((f & OPTST_DISABLED) == 0) return false; } else { /* * We are in the processing direction with an option we handle * immediately for enablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((f & OPTST_DISABLED) != 0) return false; } break; case OPTST_DISABLE_IMM: if (PRESETTING(dir)) { /* * We are in the presetting direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if NOT disabled. */ if ((f & OPTST_DISABLED) != 0) return false; } else { /* * We are in the processing direction with an option we handle * immediately for disablement, but normally for disablement. * Therefore, skip if disabled. */ if ((f & OPTST_DISABLED) == 0) return false; } break; case OPTST_IMM|OPTST_DISABLE_IMM: /* * The selected option is always for immediate action. * THEREFORE, if the direction is PROCESSING * THEN we skip this option. */ if (PROCESSING(dir)) return false; break; } return true; }