📄 load.c
字号:
static ag_boolinsertEnvVal( char* pzBuf, int bufSize, tCC* pzName, tCC* pzProgPath ){ char* pzDir = pzBuf; for (;;) { int ch = (int)*++pzName; if (! ISNAMECHAR( ch )) break; *(pzDir++) = (char)ch; } if (pzDir == pzBuf) return AG_FALSE; *pzDir = NUL; pzDir = getenv( pzBuf ); /* * Environment value not found -- skip the home list entry */ if (pzDir == NULL) return AG_FALSE; if (strlen( pzDir ) + 1 + strlen( pzName ) >= bufSize) return AG_FALSE; sprintf( pzBuf, "%s%s", pzDir, pzName ); return AG_TRUE;}LOCAL voidmungeString( char* pzTxt, tOptionLoadMode mode ){ char* pzE; if (mode == OPTION_LOAD_KEEP) return; if (isspace( (int)*pzTxt )) { char* pzS = pzTxt; char* pzD = pzTxt; while (isspace( (int)*++pzS )) ; while ((*(pzD++) = *(pzS++)) != NUL) ; pzE = pzD-1; } else pzE = pzTxt + strlen( pzTxt ); while ((pzE > pzTxt) && isspace( (int)pzE[-1] )) pzE--; *pzE = NUL; if (mode == OPTION_LOAD_UNCOOKED) return; switch (*pzTxt) { default: return; case '"': case '\'': break; } switch (pzE[-1]) { default: return; case '"': case '\'': break; } (void)ao_string_cook( pzTxt, NULL );}static char*assembleArgValue( char* pzTxt, tOptionLoadMode mode ){ tSCC zBrk[] = " \t:="; char* pzEnd = strpbrk( pzTxt, zBrk ); int space_break; /* * Not having an argument to a configurable name is okay. */ if (pzEnd == NULL) return pzTxt + strlen(pzTxt); /* * If we are keeping all whitespace, then the modevalue starts with the * character that follows the end of the configurable name, regardless * of which character caused it. */ if (mode == OPTION_LOAD_KEEP) { *(pzEnd++) = NUL; return pzEnd; } /* * If the name ended on a white space character, remember that * because we'll have to skip over an immediately following ':' or '=' * (and the white space following *that*). */ space_break = isspace((int)*pzEnd); *(pzEnd++) = NUL; while (isspace((int)*pzEnd)) pzEnd++; if (space_break && ((*pzEnd == ':') || (*pzEnd == '='))) while (isspace((int)*++pzEnd)) ; return pzEnd;}/* * 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 voidloadOptionLine( 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; }}/*=export_func optionLoadLine * * what: process a string for an option name and value * * arg: tOptions*, pOpts, program options descriptor * arg: char const*, pzLine, NUL-terminated text * * doc: * * This is a client program callable routine for setting options from, for * example, the contents of a file that they read in. Only one option may * appear in the text. It will be treated as a normal (non-preset) option. * * When passed a pointer to the option struct and a string, it will find * the option named by the first token on the string and set the option * argument to the remainder of the string. The caller must NUL terminate * the string. Any embedded new lines will be included in the option * argument. If the input looks like one or more quoted strings, then the * input will be "cooked". The "cooking" is identical to the string * formation used in AutoGen definition files (@pxref{basic expression}), * except that you may not use backquotes. * * err: Invalid options are silently ignored. Invalid option arguments * will cause a warning to print, but the function should return.=*/voidoptionLoadLine( tOptions* pOpts, tCC* pzLine ){ tOptState st = OPTSTATE_INITIALIZER(SET); char* pz; AGDUPSTR( pz, pzLine, "user option line" ); loadOptionLine( pOpts, &st, pz, DIRECTION_PROCESS, OPTION_LOAD_COOKED ); AGFREE( pz );}/* * Local Variables: * mode: C * c-file-style: "stroustrup" * indent-tabs-mode: nil * End: * end of autoopts/load.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -