/*=export_func configFileLoad * * what: parse a configuration file * arg: + char const* + fname + the file to load + * * ret_type: const tOptionValue* * ret_desc: An allocated, compound value structure * * doc: * This routine will load a named configuration file and parse the * text as a hierarchically valued option. The option descriptor * created from an option definition file is not used via this interface. * The returned value is "named" with the input file name and is of * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to * @code{optionGetValue()}, @code{optionNextValue()} and * @code{optionUnloadNested()}. * * err: * If the file cannot be loaded or processed, @code{NULL} is returned and * @var{errno} is set. It may be set by a call to either @code{open(2)} * @code{mmap(2)} or other file system calls, or it may be: * @itemize @bullet * @item * @code{ENOENT} - the file was not found. * @item * @code{ENOMSG} - the file was empty. * @item * @code{EINVAL} - the file contents are invalid -- not properly formed. * @item * @code{ENOMEM} - not enough memory to allocate the needed structures. * @end itemize =*/ const tOptionValue * configFileLoad(char const * fname) { tmap_info_t cfgfile; tOptionValue * res = NULL; tOptionLoadMode save_mode = option_load_mode; char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile); if (TEXT_MMAP_FAILED_ADDR(txt)) return NULL; /* errno is set */ option_load_mode = OPTION_LOAD_COOKED; res = optionLoadNested(txt, fname, strlen(fname)); if (res == NULL) { int err = errno; text_munmap(&cfgfile); errno = err; } else text_munmap(&cfgfile); option_load_mode = save_mode; return res; }
/** * 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; } }
/** * Load a file containing presetting information (a configuration file). */ static void file_preset(tOptions * opts, char const * fname, int dir) { tmap_info_t cfgfile; tOptState optst = OPTSTATE_INITIALIZER(PRESET); opt_state_mask_t st_flags = optst.flags; char * ftext = text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile); if (TEXT_MMAP_FAILED_ADDR(ftext)) return; if (dir == DIRECTION_CALLED) { st_flags = OPTST_DEFINED; dir = DIRECTION_PROCESS; } /* * IF this is called via "optionProcess", then we are presetting. * This is the default and the PRESETTING bit will be set. * If this is called via "optionFileLoad", then the bit is not set * and we consider stuff set herein to be "set" by the client program. */ if ((opts->fOptSet & OPTPROC_PRESETTING) == 0) st_flags = OPTST_SET; do { optst.flags = st_flags; ftext = SPN_WHITESPACE_CHARS(ftext); if (IS_VAR_FIRST_CHAR(*ftext)) { ftext = handle_cfg(opts, &optst, ftext, dir); } else switch (*ftext) { case '<': if (IS_VAR_FIRST_CHAR(ftext[1])) ftext = handle_struct(opts, &optst, ftext, dir); else switch (ftext[1]) { case '?': ftext = handle_directive(opts, ftext); break; case '!': ftext = handle_comment(ftext); break; case '/': ftext = strchr(ftext + 2, '>'); if (ftext++ != NULL) break; default: ftext = NULL; } if (ftext == NULL) goto all_done; break; case '[': ftext = handle_section(opts, ftext); break; case '#': ftext = strchr(ftext + 1, NL); break; default: goto all_done; /* invalid format */ } } while (ftext != NULL); all_done: text_munmap(&cfgfile); }
/* filePreset * * Load a file containing presetting information (a configuration file). */ static void filePreset( tOptions* pOpts, char const* pzFileName, int direction ) { tmap_info_t cfgfile; tOptState st = OPTSTATE_INITIALIZER(PRESET); char* pzFileText = text_mmap( pzFileName, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile ); if (TEXT_MMAP_FAILED_ADDR(pzFileText)) return; if (direction == DIRECTION_CALLED) { st.flags = OPTST_DEFINED; direction = DIRECTION_PROCESS; } /* * IF this is called via "optionProcess", then we are presetting. * This is the default and the PRESETTING bit will be set. * If this is called via "optionFileLoad", then the bit is not set * and we consider stuff set herein to be "set" by the client program. */ if ((pOpts->fOptSet & OPTPROC_PRESETTING) == 0) st.flags = OPTST_SET; do { while (isspace( (int)*pzFileText )) pzFileText++; if (isalpha( (int)*pzFileText )) { pzFileText = handleConfig( pOpts, &st, pzFileText, direction ); } else switch (*pzFileText) { case '<': if (isalpha( (int)pzFileText[1] )) pzFileText = handleStructure(pOpts, &st, pzFileText, direction); else switch (pzFileText[1]) { case '?': pzFileText = handleDirective( pOpts, pzFileText ); break; case '!': pzFileText = handleComment( pzFileText ); break; case '/': pzFileText = strchr( pzFileText+2, '>' ); if (pzFileText++ != NULL) break; default: goto all_done; } break; case '[': pzFileText = handleProgramSection( pOpts, pzFileText ); break; case '#': pzFileText = strchr( pzFileText+1, '\n' ); break; default: goto all_done; /* invalid format */ } } while (pzFileText != NULL); all_done: text_munmap( &cfgfile ); }