📄 load.c
字号:
/* * $Id: load.c,v 4.20 2007/02/04 22:17:39 bkorb Exp $ * Time-stamp: "2007-02-04 11:54:57 bkorb" * * This file contains the routines that deal with processing text strings * for options, either from a NUL-terminated string passed in or from an * rc/ini file. *//* * Automated Options copyright 1992-2007 Bruce Korb * * Automated Options is free software. * You may redistribute it and/or modify it under the terms of the * GNU General Public License, as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * Automated Options is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Automated Options. See the file "COPYING". If not, * write to: The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * As a special exception, Bruce Korb gives permission for additional * uses of the text contained in his release of AutoOpts. * * The exception is that, if you link the AutoOpts library with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the AutoOpts library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by Bruce Korb under * the name AutoOpts. If you copy code from other sources under the * General Public License into a copy of AutoOpts, as the General Public * License permits, the exception does not apply to the code that you add * in this way. To avoid misleading anyone as to the status of such * modified files, you must delete this exception notice from them. * * If you write modifications of your own for AutoOpts, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. */tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED;/* = = = START-STATIC-FORWARD = = = *//* static forward declarations maintained by :mkfwd */static ag_boolinsertProgramPath( char* pzBuf, int bufSize, tCC* pzName, tCC* pzProgPath );static ag_boolinsertEnvVal( char* pzBuf, int bufSize, tCC* pzName, tCC* pzProgPath );static char*assembleArgValue( char* pzTxt, tOptionLoadMode mode );/* = = = END-STATIC-FORWARD = = = *//*=export_func optionMakePath * private: * * what: translate and construct a path * arg: + char* + pzBuf + The result buffer + * arg: + int + bufSize + The size of this buffer + * arg: + char const* + pzName + The input name + * arg: + char const* + pzProgPath + The full path of the current program + * * ret-type: ag_bool * ret-desc: AG_TRUE if the name was handled, otherwise AG_FALSE. * If the name does not start with ``$'', then it is handled * simply by copying the input name to the output buffer and * resolving the name with either @code{canonicalize_file_name(3GLIBC)} * or @code{realpath(3C)}. * * doc: * * This routine will copy the @code{pzName} input name into the @code{pzBuf} * output buffer, carefully not exceeding @code{bufSize} bytes. If the * first character of the input name is a @code{'$'} character, then there * is special handling: * @* * @code{$$} is replaced with the directory name of the @code{pzProgPath}, * searching @code{$PATH} if necessary. * @* * @code{$@} is replaced with the AutoGen package data installation directory * (aka @code{pkgdatadir}). * @* * @code{$NAME} is replaced by the contents of the @code{NAME} environment * variable. If not found, the search fails. * * Please note: both @code{$$} and @code{$NAME} must be at the start of the * @code{pzName} string and must either be the entire string or be followed * by the @code{'/'} (backslash on windows) character. * * err: @code{AG_FALSE} is returned if: * @* * @bullet{} The input name exceeds @code{bufSize} bytes. * @* * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string * and the next character is not '/'. * @* * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@} * was specified. * @* * @bullet{} @code{NAME} is not a known environment variable * @* * @bullet{} @code{canonicalize_file_name} or @code{realpath} return * errors (cannot resolve the resulting path).=*/ag_booloptionMakePath( char* pzBuf, int bufSize, tCC* pzName, tCC* pzProgPath ){ size_t name_len = strlen( pzName );# ifndef PKGDATADIR# define PKGDATADIR ""# endif tSCC pkgdatadir[] = PKGDATADIR; ag_bool res = AG_TRUE; if (bufSize <= name_len) return AG_FALSE; /* * IF not an environment variable, just copy the data */ if (*pzName != '$') { tCC* pzS = pzName; char* pzD = pzBuf; int ct = bufSize; for (;;) { if ( (*(pzD++) = *(pzS++)) == NUL) break; if (--ct <= 0) return AG_FALSE; } } /* * IF the name starts with "$$", then it must be "$$" or * it must start with "$$/". In either event, replace the "$$" * with the path to the executable and append a "/" character. */ else switch (pzName[1]) { case NUL: return AG_FALSE; case '$': res = insertProgramPath( pzBuf, bufSize, pzName, pzProgPath ); break; case '@': if (pkgdatadir[0] == NUL) return AG_FALSE; if (name_len + sizeof (pkgdatadir) > bufSize) return AG_FALSE; strcpy(pzBuf, pkgdatadir); strcpy(pzBuf + sizeof(pkgdatadir) - 1, pzName + 2); break; default: res = insertEnvVal( pzBuf, bufSize, pzName, pzProgPath ); } if (! res) return AG_FALSE;#if defined(HAVE_CANONICALIZE_FILE_NAME) { char* pz = canonicalize_file_name(pzBuf); if (pz == NULL) return AG_FALSE; if (strlen(pz) < bufSize) strcpy(pzBuf, pz); free(pz); }#elif defined(HAVE_REALPATH) { char z[ PATH_MAX+1 ]; if (realpath( pzBuf, z ) == NULL) return AG_FALSE; if (strlen(z) < bufSize) strcpy( pzBuf, z ); }#endif return AG_TRUE;}static ag_boolinsertProgramPath( char* pzBuf, int bufSize, tCC* pzName, tCC* pzProgPath ){ tCC* pzPath; tCC* pz; int skip = 2; switch (pzName[2]) { case DIRCH: skip = 3; case NUL: break; default: return AG_FALSE; } /* * See if the path is included in the program name. * If it is, we're done. Otherwise, we have to hunt * for the program using "pathfind". */ if (strchr( pzProgPath, DIRCH ) != NULL) pzPath = pzProgPath; else { pzPath = pathfind( getenv( "PATH" ), (char*)pzProgPath, "rx" ); if (pzPath == NULL) return AG_FALSE; } pz = strrchr( pzPath, DIRCH ); /* * IF we cannot find a directory name separator, * THEN we do not have a path name to our executable file. */ if (pz == NULL) return AG_FALSE; pzName += skip; /* * Concatenate the file name to the end of the executable path. * The result may be either a file or a directory. */ if ((pz - pzPath)+1 + strlen(pzName) >= bufSize) return AG_FALSE; memcpy( pzBuf, pzPath, (size_t)((pz - pzPath)+1) ); strcpy( pzBuf + (pz - pzPath) + 1, pzName ); /* * If the "pzPath" path was gotten from "pathfind()", then it was * allocated and we need to deallocate it. */ if (pzPath != pzProgPath) free( (void*)pzPath ); return AG_TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -