static INT UartpOpen ( IN IO_CHANNEL channel, OUT IO_DEVICE* device ) { if (ChannelCom1 == channel) { device->readTaskId = WhoIs(UART_COM1_READ_NAME); ASSERT(SUCCESSFUL(device->readTaskId)); device->writeTaskId = WhoIs(UART_COM1_WRITE_NAME); ASSERT(SUCCESSFUL(device->writeTaskId)); return 0; } else if (ChannelCom2 == channel) { device->readTaskId = WhoIs(UART_COM2_READ_NAME); ASSERT(SUCCESSFUL(device->readTaskId)); device->writeTaskId = WhoIs(UART_COM2_WRITE_NAME); ASSERT(SUCCESSFUL(device->writeTaskId)); return 0; } else { ASSERT(FALSE); return -1; } }
/*=gfunc find_file * * what: locate a file in the search path * exparg: file-name, name of file with text * exparg: @suffix @ file suffix to try, too @ opt @ * * doc: * * AutoGen has a search path that it uses to locate template and definition * files. This function will search the same list for @file{file-name}, both * with and without the @file{.suffix}, if provided. =*/ SCM ag_scm_find_file(SCM file, SCM suffix) { SCM res = SCM_UNDEFINED; if (! AG_SCM_STRING_P(file)) scm_wrong_type_arg(FIND_FILE_NAME, 1, file); { char z[ AG_PATH_MAX+1 ]; char const * pz = ag_scm2zchars(file, "file-name"); /* * The suffix is optional. If provided, it will be a string. */ if (AG_SCM_STRING_P(suffix)) { char* apz[2]; apz[0] = (char *)ag_scm2zchars(suffix, "file suffix"); apz[1] = NULL; if (SUCCESSFUL(findFile(pz, z, (char const **)apz, NULL))) res = AG_SCM_STR02SCM(z); } else if (SUCCESSFUL(findFile(pz, z, NULL, NULL))) res = AG_SCM_STR02SCM(z); } return res; }
/*=export_func optionResetOpt * private: * * what: Reset the value of an option * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * This code will cause another option to be reset to its initial state. * For example, --reset=foo will cause the --foo option to be reset. =*/ void optionResetOpt( tOptions* pOpts, tOptDesc* pOD ) { static ag_bool reset_active = AG_FALSE; tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED); char const * pzArg = pOD->optArg.argString; tSuccess succ; if (reset_active) return; if ( (! HAS_originalOptArgArray(pOpts)) || (pOpts->originalOptArgCookie == NULL)) { fputs(zResetNotConfig, stderr); _exit(EX_SOFTWARE); } if ((pzArg == NULL) || (*pzArg == NUL)) { fputs(zNoResetArg, stderr); pOpts->pUsageProc(pOpts, EXIT_FAILURE); /* NOTREACHED */ assert(0 == 1); } reset_active = AG_TRUE; if (pzArg[1] == NUL) { if (*pzArg == '*') { optionResetEverything(pOpts); reset_active = AG_FALSE; return; } succ = shortOptionFind(pOpts, (tAoUC)*pzArg, &opt_state); if (! SUCCESSFUL(succ)) { fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg); pOpts->pUsageProc(pOpts, EXIT_FAILURE); /* NOTREACHED */ assert(0 == 1); } } else { succ = longOptionFind(pOpts, (char *)pzArg, &opt_state); if (! SUCCESSFUL(succ)) { fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg); pOpts->pUsageProc(pOpts, EXIT_FAILURE); /* NOTREACHED */ assert(0 == 1); } } /* * We've found the indicated option. Turn off all non-persistent * flags because we're forcing the option back to its initialized state. * Call any callout procedure to handle whatever it needs to. * Finally, clear the reset flag, too. */ optionReset(pOpts, opt_state.pOD); reset_active = AG_FALSE; }
/*=export_func optionProcess * * what: this is the main option processing routine * * arg: + tOptions* + opts + program options descriptor + * arg: + int + a_ct + program arg count + * arg: + char** + a_v + program arg vector + * * ret_type: int * ret_desc: the count of the arguments processed * * doc: * * This is the main entry point for processing options. It is intended * that this procedure be called once at the beginning of the execution of * a program. Depending on options selected earlier, it is sometimes * necessary to stop and restart option processing, or to select completely * different sets of options. This can be done easily, but you generally * do not want to do this. * * The number of arguments processed always includes the program name. * If one of the arguments is "--", then it is counted and the processing * stops. If an error was encountered and errors are to be tolerated, then * the returned value is the index of the argument causing the error. * A hyphen by itself ("-") will also cause processing to stop and will * @emph{not} be counted among the processed arguments. A hyphen by itself * is treated as an operand. Encountering an operand stops option * processing. * * err: Errors will cause diagnostics to be printed. @code{exit(3)} may * or may not be called. It depends upon whether or not the options * were generated with the "allow-errors" attribute, or if the * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. =*/ int optionProcess(tOptions * opts, int a_ct, char ** a_v) { if (! SUCCESSFUL(validate_struct(opts, a_v[0]))) ao_bug(zbad_data_msg); /* * Establish the real program name, the program full path, * and do all the presetting the first time thru only. */ if (! ao_initialize(opts, a_ct, a_v)) return 0; /* * IF we are (re)starting, * THEN reset option location */ if (opts->curOptIdx <= 0) { opts->curOptIdx = 1; opts->pzCurOpt = NULL; } if (! SUCCESSFUL(regular_opts(opts))) return (int)opts->origArgCt; /* * IF there were no errors * AND we have RC/INI files * AND there is a request to save the files * THEN do that now before testing for conflicts. * (conflicts are ignored in preset options) */ switch (opts->specOptIdx.save_opts) { case 0: case NO_EQUIVALENT: break; default: { tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts; if (SELECTED_OPT(od)) { optionSaveFile(opts); option_exits(EXIT_SUCCESS); } } } /* * IF we are checking for errors, * THEN look for too few occurrences of required options */ if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0) && (! is_consistent(opts))) (*opts->pUsageProc)(opts, EXIT_FAILURE); return (int)opts->curOptIdx; }
static VOID SwitchpTask() { SWITCH_DIRECTION directions[NUM_SWITCHES]; VERIFY(SUCCESSFUL(RegisterAs(SWITCH_SERVER_NAME))); IO_DEVICE com1; VERIFY(SUCCESSFUL(Open(UartDevice, ChannelCom1, &com1))); for (UINT i = 0; i < NUM_SWITCHES; i++) { UCHAR sw = SwitchpFromIndex(i); VERIFY(SUCCESSFUL(SwitchpDirection(&com1, sw, SwitchCurved))); directions[i] = SwitchCurved; ShowSwitchDirection(i, sw, SwitchCurved); } VERIFY(SUCCESSFUL(SwitchpDisableSolenoid(&com1))); while (1) { INT senderId; SWITCH_REQUEST request; VERIFY(SUCCESSFUL(Receive(&senderId, &request, sizeof(request)))); switch(request.type) { case SetDirectionRequest: { VERIFY(SUCCESSFUL(SwitchpDirection(&com1, request.sw, request.direction))); VERIFY(SUCCESSFUL(SwitchpDisableSolenoid(&com1))); UINT switchIndex = SwitchpToIndex(request.sw); directions[switchIndex] = request.direction; VERIFY(SUCCESSFUL(Reply(senderId, NULL, 0))); ShowSwitchDirection(switchIndex, request.sw, request.direction); break; } case GetDirectionRequest: { UINT switchIndex = SwitchpToIndex(request.sw); SWITCH_DIRECTION direction = directions[switchIndex]; VERIFY(SUCCESSFUL(Reply(senderId, &direction, sizeof(direction)))); break; } } } }
/** * scan the command line for immediate action options. * This is only called the first time through. */ LOCAL tSuccess doImmediateOpts(tOptions* pOpts) { pOpts->curOptIdx = 1; /* start by skipping program name */ pOpts->pzCurOpt = NULL; /* * Examine all the options from the start. We process any options that * are marked for immediate processing. */ for (;;) { tOptState optState = OPTSTATE_INITIALIZER(PRESET); switch (nextOption(pOpts, &optState)) { case FAILURE: goto failed_option; case PROBLEM: return SUCCESS; /* no more args */ case SUCCESS: break; } /* * IF this is an immediate-attribute option, then do it. */ if (! DO_IMMEDIATELY(optState.flags)) continue; if (! SUCCESSFUL(handle_opt(pOpts, &optState))) break; } failed_option:; if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); return FAILURE; }
/** * Process all the options from our current position onward. (This allows * interspersed options and arguments for the few non-standard programs that * require it.) Thus, do not rewind option indexes because some programs * choose to re-invoke after a non-option. */ LOCAL tSuccess doRegularOpts(tOptions* pOpts) { for (;;) { tOptState optState = OPTSTATE_INITIALIZER(DEFINED); switch (nextOption(pOpts, &optState)) { case FAILURE: goto failed_option; case PROBLEM: return SUCCESS; /* no more args */ case SUCCESS: break; } /* * IF this is an immediate action option, * THEN skip it (unless we are supposed to do it a second time). */ if (! DO_NORMALLY(optState.flags)) { if (! DO_SECOND_TIME(optState.flags)) continue; optState.pOD->optOccCt--; /* don't count this repetition */ } if (! SUCCESSFUL(handle_opt(pOpts, &optState))) break; } failed_option:; if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); return FAILURE; }
INT SwitchGetDirection ( IN INT sw, OUT SWITCH_DIRECTION* direction ) { INT result; UINT index = SwitchpToIndex(sw); if (index < NUM_SWITCHES) { result = WhoIs(SWITCH_SERVER_NAME); if (SUCCESSFUL(result)) { INT switchServerId = result; SWITCH_REQUEST request = { GetDirectionRequest, (UCHAR) sw }; result = Send(switchServerId, &request, sizeof(request), direction, sizeof(*direction)); } } else { result = -1; } return result; }
SCM ag_scm_string_ends_with_p(SCM text, SCM substr) { char* pzText = ag_scm2zchars(text, "text to match"); char* pzSubstr = ag_scm2zchars(substr, "match expr"); return (SUCCESSFUL(Select_Compare_End(pzText, pzSubstr))) ? SCM_BOOL_T : SCM_BOOL_F; }
SCM ag_scm_string_starts_eqv_p(SCM text, SCM substr) { char* pzText = ag_scm2zchars(text, "text to match"); char* pzSubstr = ag_scm2zchars(substr, "match expr"); return (SUCCESSFUL(Select_Equivalent_Start(pzText, pzSubstr))) ? SCM_BOOL_T : SCM_BOOL_F; }
VOID InputParserCreateTask ( VOID ) { VERIFY(SUCCESSFUL(Create(Priority9, InputParserpTask))); }
/** * Starting with the current directory, search the directory * list trying to find the base template file name. */ LOCAL tTemplate * loadTemplate(char const * pzFileName, char const * referrer) { static tmap_info_t mapInfo; static char zRealFile[ AG_PATH_MAX ]; /* * Find the template file somewhere */ { static char const * const apzSfx[] = { "tpl", "agl", NULL }; if (! SUCCESSFUL(findFile(pzFileName, zRealFile, apzSfx, referrer))) { errno = ENOENT; AG_CANT("map data file", pzFileName); } } /* * Make sure the specified file is a regular file. * Make sure the output time stamp is at least as recent. */ { struct stat stbf; if (stat(zRealFile, &stbf) != 0) AG_CANT("stat file", pzFileName); if (! S_ISREG(stbf.st_mode)) { errno = EINVAL; AG_CANT("not regular file", pzFileName); } if (outTime <= stbf.st_mtime) outTime = stbf.st_mtime + 1; } text_mmap(zRealFile, PROT_READ|PROT_WRITE, MAP_PRIVATE, &mapInfo); if (TEXT_MMAP_FAILED_ADDR(mapInfo.txt_data)) AG_ABEND(aprf("Could not open template '%s'", zRealFile)); if (pfDepends != NULL) append_source_name(zRealFile); /* * Process the leading pseudo-macro. The template proper * starts immediately after it. */ { tMacro * pSaveMac = pCurMacro; tTemplate * pRes; pCurMacro = NULL; pRes = digest_pseudo_macro(&mapInfo, zRealFile); pCurMacro = pSaveMac; text_munmap(&mapInfo); return pRes; } }
/*=export_func optionVendorOption * private: * * what: Process a vendor option * arg: + tOptions * + pOpts + program options descriptor + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + * * doc: * For POSIX specified utilities, the options are constrained to the options, * @xref{config attributes, Program Configuration}. AutoOpts clients should * never specify this directly. It gets referenced when the option * definitions contain a "vendor-opt" attribute. =*/ void optionVendorOption(tOptions * pOpts, tOptDesc * pOD) { tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); char const * vopt_str = pOD->optArg.argString; if (pOpts <= OPTPROC_EMIT_LIMIT) return; if ((pOD->fOptState & OPTST_RESET) != 0) return; if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) opt_st.flags = OPTST_DEFINED; if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0) || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) { fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); /* NOTREACHED */ _exit(EXIT_FAILURE); /* to be certain */ } /* * See if we are in immediate handling state. */ if (pOpts->fOptSet & OPTPROC_IMMEDIATE) { /* * See if the enclosed option is okay with that state. */ if (DO_IMMEDIATELY(opt_st.flags)) (void)handle_opt(pOpts, &opt_st); } else { /* * non-immediate direction. * See if the enclosed option is okay with that state. */ if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags)) (void)handle_opt(pOpts, &opt_st); } }
/*=export_func optionFileLoad * * what: Load the locatable config files, in order * * arg: + tOptions* + pOpts + program options descriptor + * arg: + char const* + pzProg + program name + * * ret_type: int * ret_desc: 0 -> SUCCESS, -1 -> FAILURE * * doc: * * This function looks in all the specified directories for a configuration * file ("rc" file or "ini" file) and processes any found twice. The first * time through, they are processed in reverse order (last file first). At * that time, only "immediate action" configurables are processed. For * example, if the last named file specifies not processing any more * configuration files, then no more configuration files will be processed. * Such an option in the @strong{first} named directory will have no effect. * * Once the immediate action configurables have been handled, then the * directories are handled in normal, forward order. In that way, later * config files can override the settings of earlier config files. * * See the AutoOpts documentation for a thorough discussion of the * config file format. * * Configuration files not found or not decipherable are simply ignored. * * err: Returns the value, "-1" if the program options descriptor * is out of date or indecipherable. Otherwise, the value "0" will * always be returned. =*/ int optionFileLoad( tOptions* pOpts, char const* pzProgram ) { if (! SUCCESSFUL( validateOptionsStruct( pOpts, pzProgram ))) return -1; pOpts->pzProgName = pzProgram; internalFileLoad( pOpts ); return 0; }
/*=gfunc tpl_file * * what: get the template file name * * exparg: full_path, include full path to file, optonal * * doc: Returns the name of the current template file. * If @code{#t} is passed in as an argument, then the template * file is hunted for in the template search path. Otherwise, * just the unadorned name. =*/ SCM ag_scm_tpl_file(SCM full) { if (AG_SCM_BOOL_P(full) && AG_SCM_NFALSEP(full)) { static char const * const sfx[] = { "tpl", NULL }; char z[AG_PATH_MAX]; if (SUCCESSFUL(findFile(pzTemplFileName, z, sfx, NULL))) return AG_SCM_STR02SCM(z); } return AG_SCM_STR02SCM((char*)(void*)pzTemplFileName); }
/** * check for preset values from a config files or envrionment variables * * @param[in,out] opts the structure with the option names to check */ static tSuccess do_presets(tOptions * opts) { tOptDesc * od = NULL; if (! SUCCESSFUL(immediate_opts(opts))) return FAILURE; /* * IF this option set has a --save-opts option, then it also * has a --load-opts option. See if a command line option has disabled * option presetting. */ if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT) && (opts->specOptIdx.save_opts != 0)) { od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; if (DISABLED_OPT(od)) return SUCCESS; } /* * Until we return from this procedure, disable non-presettable opts */ opts->fOptSet |= OPTPROC_PRESETTING; /* * IF there are no config files, * THEN do any environment presets and leave. */ if (opts->papzHomeList == NULL) { env_presets(opts, ENV_ALL); } else { env_presets(opts, ENV_IMM); /* * Check to see if environment variables have disabled presetting. */ if ((od != NULL) && ! DISABLED_OPT(od)) intern_file_load(opts); /* * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment * variable options. Only the loading of .rc files. */ env_presets(opts, ENV_NON_IMM); } opts->fOptSet &= ~OPTPROC_PRESETTING; return SUCCESS; }
static VOID InputParserpTask ( VOID ) { IO_DEVICE com2Device; VERIFY(SUCCESSFUL(Open(UartDevice, ChannelCom2, &com2Device))); CHAR buffer[256]; INT i; while (1) { for (i = 0; i < sizeof(buffer); i++) { buffer[i] = '\0'; } i = 0; while (i < sizeof(buffer)) { CHAR c = ReadChar(&com2Device); ShowKeyboardChar(c); if (c == '\r') { break; } if (c == '\b') { if (i > 0) { buffer[--i] = '\0'; } } else { buffer[i++] = c; } } InputParserpParseCommand(buffer, i); } }
/* * nextOption * * Find the option descriptor and option argument (if any) for the * next command line argument. DO NOT modify the descriptor. Put * all the state in the state argument so that the option can be skipped * without consequence (side effect). */ static tSuccess nextOption(tOptions* pOpts, tOptState* pOptState) { { tSuccess res; res = findOptDesc(pOpts, pOptState); if (! SUCCESSFUL(res)) return res; } if ( ((pOptState->flags & OPTST_DEFINED) != 0) && ((pOptState->pOD->fOptState & OPTST_NO_COMMAND) != 0)) { fprintf(stderr, zNotCmdOpt, pOptState->pOD->pz_Name); return FAILURE; } pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK); /* * Figure out what to do about option arguments. An argument may be * required, not associated with the option, or be optional. We detect the * latter by examining for an option marker on the next possible argument. * Disabled mode option selection also disables option arguments. */ { enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE; tSuccess res; if ((pOptState->flags & OPTST_DISABLED) != 0) arg_type = ARG_NONE; else if (OPTST_GET_ARGTYPE(pOptState->flags) == OPARG_TYPE_NONE) arg_type = ARG_NONE; else if (pOptState->flags & OPTST_ARG_OPTIONAL) arg_type = ARG_MAY; else arg_type = ARG_MUST; switch (arg_type) { case ARG_MUST: res = next_opt_arg_must(pOpts, pOptState); break; case ARG_MAY: res = next_opt_arg_may( pOpts, pOptState); break; case ARG_NONE: res = next_opt_arg_none(pOpts, pOptState); break; } return res; } }
/*=export_func optionFileLoad * * what: Load the locatable config files, in order * * arg: + tOptions* + pOpts + program options descriptor + * arg: + char const* + pzProg + program name + * * ret_type: int * ret_desc: 0 -> SUCCESS, -1 -> FAILURE * * doc: * * This function looks in all the specified directories for a configuration * file ("rc" file or "ini" file) and processes any found twice. The first * time through, they are processed in reverse order (last file first). At * that time, only "immediate action" configurables are processed. For * example, if the last named file specifies not processing any more * configuration files, then no more configuration files will be processed. * Such an option in the @strong{first} named directory will have no effect. * * Once the immediate action configurables have been handled, then the * directories are handled in normal, forward order. In that way, later * config files can override the settings of earlier config files. * * See the AutoOpts documentation for a thorough discussion of the * config file format. * * Configuration files not found or not decipherable are simply ignored. * * err: Returns the value, "-1" if the program options descriptor * is out of date or indecipherable. Otherwise, the value "0" will * always be returned. =*/ int optionFileLoad(tOptions* pOpts, char const* pzProgram) { if (! SUCCESSFUL(validateOptionsStruct(pOpts, pzProgram))) return -1; { char const ** pp = (char const **)(void *)&(pOpts->pzProgName); *pp = pzProgram; } internalFileLoad(pOpts); return 0; }
VOID UartCreateTasks() { // Register with the I/O framework VERIFY(SUCCESSFUL(IoRegisterDriver(UartDevice, UartpOpen))); // Create the uart I/O servers VERIFY(SUCCESSFUL(IoCreateReadTask(Priority29, UartCom1ReceiveEvent, UartpCom1Read, UART_COM1_READ_NAME))); VERIFY(SUCCESSFUL(IoCreateWriteTask(Priority29, UartCom1TransmitEvent, UartpCom1Write, UART_COM1_WRITE_NAME))); VERIFY(SUCCESSFUL(IoCreateReadTask(Priority11, UartCom2ReceiveEvent, UartpCom2Read, UART_COM2_READ_NAME))); VERIFY(SUCCESSFUL(IoCreateWriteTask(Priority11, UartCom2TransmitEvent, UartpCom2Write, UART_COM2_WRITE_NAME))); }
VOID InitOsTasks ( VOID ) { // Initialize RTOS IdleCreateTask(); NameServerCreateTask(); ShutdownCreateTask(); ClockServerCreateTask(); IoCreateTask(); UartCreateTasks(); VERIFY(SUCCESSFUL(Create(LowestUserPriority, InitUserTasks))); }
/** * Find the option descriptor and option argument (if any) for the * next command line argument. DO NOT modify the descriptor. Put * all the state in the state argument so that the option can be skipped * without consequence (side effect). * * @param opts the program option descriptor * @param o_st the state of the next found option */ LOCAL tSuccess next_opt(tOptions * opts, tOptState * o_st) { { tSuccess res = find_opt(opts, o_st); if (! SUCCESSFUL(res)) return res; } if ( ((o_st->flags & OPTST_DEFINED) != 0) && ((o_st->pOD->fOptState & OPTST_NO_COMMAND) != 0)) { fprintf(stderr, zNotCmdOpt, o_st->pOD->pz_Name); return FAILURE; } return get_opt_arg(opts, o_st); }
SCM ag_scm_string_contains_eqv_p(SCM text, SCM substr) { static char const zSrch[] = "search string"; char* pzSubstr; SCM res; AGDUPSTR(pzSubstr, ag_scm2zchars( substr, zSrch ), "substring"); upString(pzSubstr); if (SUCCESSFUL(Select_Equivalent(ag_scm2zchars(text, "sample text"), pzSubstr))) res = SCM_BOOL_T; else res = SCM_BOOL_F; AGFREE((void*)pzSubstr); return res; }
/*=export_func optionFileLoad * * what: Load the locatable config files, in order * * arg: + tOptions * + opts + program options descriptor + * arg: + char const * + prog + program name + * * ret_type: int * ret_desc: 0 -> SUCCESS, -1 -> FAILURE * * doc: * * This function looks in all the specified directories for a configuration * file ("rc" file or "ini" file) and processes any found twice. The first * time through, they are processed in reverse order (last file first). At * that time, only "immediate action" configurables are processed. For * example, if the last named file specifies not processing any more * configuration files, then no more configuration files will be processed. * Such an option in the @strong{first} named directory will have no effect. * * Once the immediate action configurables have been handled, then the * directories are handled in normal, forward order. In that way, later * config files can override the settings of earlier config files. * * See the AutoOpts documentation for a thorough discussion of the * config file format. * * Configuration files not found or not decipherable are simply ignored. * * err: Returns the value, "-1" if the program options descriptor * is out of date or indecipherable. Otherwise, the value "0" will * always be returned. =*/ int optionFileLoad(tOptions * opts, char const * prog) { if (! SUCCESSFUL(validate_struct(opts, prog))) return -1; /* * The pointer to the program name is "const". However, the * structure is in writable memory, so we coerce the address * of this pointer to point to writable memory. */ { char const ** pp = VOIDP(&(opts->pzProgName)); *pp = prog; } intern_file_load(opts); return 0; }
/** * scan the command line for immediate action options. * This is only called the first time through. * While this procedure is active, the OPTPROC_IMMEDIATE is true. * * @param pOpts program options descriptor * @returns SUCCESS or FAILURE */ LOCAL tSuccess immediate_opts(tOptions * opts) { tSuccess res; opts->fOptSet |= OPTPROC_IMMEDIATE; opts->curOptIdx = 1; /* start by skipping program name */ opts->pzCurOpt = NULL; /* * Examine all the options from the start. We process any options that * are marked for immediate processing. */ for (;;) { tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); res = next_opt(opts, &opt_st); switch (res) { case FAILURE: goto failed_option; case PROBLEM: res = SUCCESS; goto leave; case SUCCESS: break; } /* * IF this is an immediate-attribute option, then do it. */ if (! DO_IMMEDIATELY(opt_st.flags)) continue; if (! SUCCESSFUL(handle_opt(opts, &opt_st))) break; } failed_option:; if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) (*opts->pUsageProc)(opts, EXIT_FAILURE); leave: opts->fOptSet &= ~OPTPROC_IMMEDIATE; return res; }
/** * AutoOpts initialization * * @param[in,out] opts the structure to initialize * @param[in] a_ct program argument count * @param[in] a_v program argument vector */ LOCAL bool ao_initialize(tOptions * opts, int a_ct, char ** a_v) { if ((opts->fOptSet & OPTPROC_INITDONE) != 0) return true; opts->origArgCt = (unsigned int)a_ct; opts->origArgVect = a_v; opts->fOptSet |= OPTPROC_INITDONE; if (HAS_pzPkgDataDir(opts)) program_pkgdatadir = opts->pzPkgDataDir; if (! SUCCESSFUL(do_presets(opts))) return false; /* * IF option name conversion was suppressed but it is not suppressed * for the command line, then it's time to translate option names. * Usage text will not get retranslated. */ if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) && (opts->pTransProc != NULL) && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) ) { opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; (*opts->pTransProc)(); } if ((opts->fOptSet & OPTPROC_REORDER) != 0) optionSort(opts); opts->curOptIdx = 1; opts->pzCurOpt = NULL; return true; }
static VOID InputParserpParseCommand ( IN STRING buffer, IN INT bufferLength ) { INT arg1 = 0; CHAR arg1Buffer[12]; arg1Buffer[11] = '\0'; INT arg2 = 0; CHAR arg2Buffer[12]; arg2Buffer[11] = '\0'; CHAR token[12]; INT read = RtStrConsumeToken(&buffer, token, sizeof(token)); if (read == 0) { return; } if (RtStrEqual(token, "tr")) { read = RtStrConsumeToken(&buffer, arg1Buffer, sizeof(arg1Buffer)); if (read && RT_SUCCESS(RtAtoi(arg1Buffer, &arg1))) { read = RtStrConsumeToken(&buffer, arg2Buffer, sizeof(arg2Buffer)); if (read && RT_SUCCESS(RtAtoi(arg2Buffer, &arg2))) { if (RtStrIsWhitespace(buffer)) { TrainSetSpeed(arg1, arg2); } } } } else if (RtStrEqual(token, "sw")) { read = RtStrConsumeToken(&buffer, arg1Buffer, sizeof(arg1Buffer)); if (read && RT_SUCCESS(RtAtoi(arg1Buffer, &arg1))) { SWITCH_DIRECTION direction = SwitchCurved; read = RtStrConsumeToken(&buffer, arg2Buffer, sizeof(arg2Buffer)); if (read == 1 && InputParserpGetSwitchDirection(arg2Buffer[0], &direction)) { if (RtStrIsWhitespace(buffer)) { SwitchSetDirection(arg1, direction); } } } } else if (RtStrEqual(token, "rv")) { read = RtStrConsumeToken(&buffer, arg1Buffer, sizeof(arg1Buffer)); if (read && RT_SUCCESS(RtAtoi(arg1Buffer, &arg1))) { if (RtStrIsWhitespace(buffer)) { TrainReverse(arg1); } } } else if(RtStrEqual(token, "rt")) { read = RtStrConsumeToken(&buffer, arg1Buffer, sizeof(arg1Buffer)); if(read && RT_SUCCESS(RtAtoi(arg1Buffer, &arg1))) { if(RtStrIsWhitespace(buffer)) { VERIFY(SUCCESSFUL(TrainDestinationForever(arg1))); } } } else if (RtStrEqual(token, "go")) { read = RtStrConsumeToken(&buffer, arg1Buffer, sizeof(arg1Buffer)); if (read && RT_SUCCESS(RtAtoi(arg1Buffer, &arg1))) { read = RtStrConsumeToken(&buffer, arg2Buffer, sizeof(arg2Buffer)); if (read && RT_SUCCESS(RtAtoi(&arg2Buffer[1], &arg2))) { if(RtStrIsWhitespace(buffer)) { SENSOR sensor = { arg2Buffer[0], arg2 }; LOCATION location; location.node = TrackFindSensor(&sensor); location.distancePastNode = 0; VERIFY(SUCCESSFUL(TrainDestinationOnce(arg1, &location))); } } } } else if (RtStrEqual(token, "q")) { if (RtStrIsWhitespace(buffer)) { Shutdown(); } } }
/* * 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; } }
/** * This directive will insert definitions from another file into * the current collection. If the file name is adorned with * double quotes or angle brackets (as in a C program), then the * include is ignored. */ char * doDir_include(directive_enum_t id, char const * dir, char * scan_next) { static char const * const apzSfx[] = { DIRECT_INC_DEF_SFX, NULL }; scan_ctx_t * new_ctx; size_t inc_sz; char full_name[ AG_PATH_MAX + 1 ]; (void)id; dir = SPN_WHITESPACE_CHARS(dir); /* * Ignore C-style includes. This allows "C" files to be processed * for their "#define"s. */ if ((*dir == '"') || (*dir == '<')) return scan_next; if (! SUCCESSFUL( find_file(dir, full_name, apzSfx, cctx->scx_fname))) { errno = ENOENT; fswarn("search for", cctx->scx_fname); return scan_next; } /* * Make sure the specified file is a regular file and we can get * the correct size for it. */ inc_sz = file_size(full_name); if (inc_sz == 0) return scan_next; /* * Get the space for the output data and for context overhead. * This is an extra allocation and copy, but easier than rewriting * 'loadData()' for this special context. */ { size_t sz = sizeof(scan_ctx_t) + 4 + inc_sz; new_ctx = (scan_ctx_t *)AGALOC(sz, "inc def head"); memset(VOIDP(new_ctx), 0, sz); new_ctx->scx_line = 1; } /* * Link it into the context stack */ cctx->scx_scan = scan_next; new_ctx->scx_next = cctx; cctx = new_ctx; AGDUPSTR(new_ctx->scx_fname, full_name, "def file"); new_ctx->scx_scan = new_ctx->scx_data = scan_next = (char *)(new_ctx + 1); /* * Read all the data. Usually in a single read, but loop * in case multiple passes are required. */ { FILE * fp = fopen(full_name, "r" FOPEN_TEXT_FLAG); char * pz = scan_next; if (fp == NULL) AG_CANT(DIRECT_INC_CANNOT_OPEN, full_name); if (dep_fp != NULL) add_source_file(full_name); do { size_t rdct = fread(VOIDP(pz), (size_t)1, inc_sz, fp); if (rdct == 0) AG_CANT(DIRECT_INC_CANNOT_READ, full_name); pz += rdct; inc_sz -= rdct; } while (inc_sz > 0); fclose(fp); *pz = NUL; } return scan_next; }
/*=export_func optionProcess * * what: this is the main option processing routine * * arg: + tOptions* + pOpts + program options descriptor + * arg: + int + argc + program arg count + * arg: + char** + argv + program arg vector + * * ret_type: int * ret_desc: the count of the arguments processed * * doc: * * This is the main entry point for processing options. It is intended * that this procedure be called once at the beginning of the execution of * a program. Depending on options selected earlier, it is sometimes * necessary to stop and restart option processing, or to select completely * different sets of options. This can be done easily, but you generally * do not want to do this. * * The number of arguments processed always includes the program name. * If one of the arguments is "--", then it is counted and the processing * stops. If an error was encountered and errors are to be tolerated, then * the returned value is the index of the argument causing the error. * A hyphen by itself ("-") will also cause processing to stop and will * @emph{not} be counted among the processed arguments. A hyphen by itself * is treated as an operand. Encountering an operand stops option * processing. * * err: Errors will cause diagnostics to be printed. @code{exit(3)} may * or may not be called. It depends upon whether or not the options * were generated with the "allow-errors" attribute, or if the * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. =*/ int optionProcess(tOptions * pOpts, int argCt, char ** argVect) { if (! SUCCESSFUL(validateOptionsStruct(pOpts, argVect[0]))) exit(EX_SOFTWARE); /* * Establish the real program name, the program full path, * and do all the presetting the first time thru only. */ if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) { pOpts->origArgCt = argCt; pOpts->origArgVect = argVect; pOpts->fOptSet |= OPTPROC_INITDONE; if (HAS_pzPkgDataDir(pOpts)) program_pkgdatadir = pOpts->pzPkgDataDir; if (! SUCCESSFUL(doPresets(pOpts))) return 0; /* * IF option name conversion was suppressed but it is not suppressed * for the command line, then it's time to translate option names. * Usage text will not get retranslated. */ if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0) && (pOpts->pTransProc != NULL) && ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) ) { pOpts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; (*pOpts->pTransProc)(); } if ((pOpts->fOptSet & OPTPROC_REORDER) != 0) optionSort(pOpts); pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; } /* * IF we are (re)starting, * THEN reset option location */ else if (pOpts->curOptIdx <= 0) { pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; } if (! SUCCESSFUL(doRegularOpts(pOpts))) return pOpts->origArgCt; /* * IF there were no errors * AND we have RC/INI files * AND there is a request to save the files * THEN do that now before testing for conflicts. * (conflicts are ignored in preset options) */ if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) && (pOpts->specOptIdx.save_opts != 0)) { tOptDesc* pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts; if (SELECTED_OPT(pOD)) { optionSaveFile(pOpts); exit(EXIT_SUCCESS); } } /* * IF we are checking for errors, * THEN look for too few occurrences of required options */ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { if (checkConsistency(pOpts) != 0) (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); } return pOpts->curOptIdx; }