mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
690 lines
18 KiB
690 lines
18 KiB
/*** variable.c - Variable Manager
|
|
*
|
|
* Microsoft Confidential
|
|
* Copyright (C) Microsoft Corporation 1993-1994
|
|
* All Rights Reserved.
|
|
*
|
|
* Author:
|
|
* Benjamin W. Slivka
|
|
*
|
|
* History:
|
|
* 10-Aug-1993 bens Initial version
|
|
* 20-Aug-1993 bens Use MemStrDup to simplify VarCreate, VarSet
|
|
* 21-Aug-1993 bens Support multiple lists (no static data!)
|
|
* 08-Feb-1994 bens Set var.pvlist! Fix error cleanup in VarCreate.
|
|
* 03-Jun-1994 bens Add vflDEFINE support; Get/SetFlags
|
|
*
|
|
* Exported Functions:
|
|
* VarCloneList - Create an exact copy of a variable list
|
|
* VarCreate - Create a variable
|
|
* VarCreateList - Create a list of variables
|
|
* VarDelete - Delete existing variable
|
|
* VarDestroyList - Destroy a list of variables
|
|
* VarFind - See if variable exists
|
|
* VarFirstVar - Get first variable from list
|
|
* VarGetBool - Get value of boolean variable
|
|
* VarGetFlags - Get variable flags
|
|
* VarGetInt - Get value of int variable
|
|
* VarGetLong - Get value of long variable
|
|
* VarGetName - Get name of variable
|
|
* VarGetString - Get value of string variable
|
|
* VarNextVar - Get next variable
|
|
* VarSet - Set value of a variable (create if necessary)
|
|
* VarSetLong - Set long variable value (create if necessary)
|
|
* VarSetFlags - Set variable flags
|
|
*
|
|
* Internal Functions:
|
|
* findVar - See if variable exists
|
|
* isValidVarName - Checks validity of variable name
|
|
* setVarValue - Validate value, then update variable
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "types.h"
|
|
#include "asrt.h"
|
|
#include "error.h"
|
|
#include "mem.h"
|
|
#include "message.h"
|
|
#include "variable.h"
|
|
|
|
#include "variable.msg"
|
|
|
|
//** Empty definition, to avoid "chicken and the egg" problem
|
|
typedef struct VARLIST_t VARLIST; /* var */
|
|
typedef VARLIST *PVARLIST; /* vlist */
|
|
|
|
typedef struct VARIABLE_t {
|
|
#ifdef ASSERT
|
|
SIGNATURE sig; // structure signature sigVARIABLE
|
|
#endif
|
|
char *pszName; // variable name
|
|
char *pszValue; // current value
|
|
VARTYPE vtype; // variable type
|
|
VARFLAGS vfl; // special flags
|
|
PFNVCVALIDATE pfnvcv; // validation function
|
|
struct VARIABLE_t *pvarNext; // next variable
|
|
struct VARIABLE_t *pvarPrev; // previous variable
|
|
PVARLIST pvlist; // List containing this variable
|
|
} VARIABLE; /* var */
|
|
typedef VARIABLE *PVARIABLE; /* pvar */
|
|
|
|
#ifdef ASSERT
|
|
#define sigVARIABLE MAKESIG('V','A','R','$') // VARIABLE signature
|
|
#define AssertVar(pvar) AssertStructure(pvar,sigVARIABLE);
|
|
#else // !ASSERT
|
|
#define AssertVar(pvar)
|
|
#endif // !ASSERT
|
|
|
|
|
|
typedef struct VARLIST_t {
|
|
#ifdef ASSERT
|
|
SIGNATURE sig; // structure signature sigVARLIST
|
|
#endif
|
|
PVARIABLE pvarHead;
|
|
PVARIABLE pvarTail;
|
|
} VARLIST; /* vlist */
|
|
//typedef VARLIST *PVARLIST; /* pvlist */
|
|
#ifdef ASSERT
|
|
#define sigVARLIST MAKESIG('V','L','S','T') // VARLIST signature
|
|
#define AssertVList(pv) AssertStructure(pv,sigVARLIST);
|
|
#else // !ASSERT
|
|
#define AssertVList(pv)
|
|
#endif // !ASSERT
|
|
|
|
|
|
#define HVARfromPVAR(h) ((PVARIABLE)(h))
|
|
#define PVARfromHVAR(p) ((HVARIABLE)(p))
|
|
|
|
#define HVLfromPVL(h) ((PVARLIST)(h))
|
|
#define PVLfromHVL(p) ((HVARLIST)(p))
|
|
|
|
|
|
//** Function Prototypes
|
|
|
|
PVARIABLE findVar(PVARLIST pvlist, char *pszName, PERROR perr);
|
|
BOOL isValidVarName(char *pszName, PERROR perr);
|
|
BOOL setVarValue(PVARIABLE pvar, char *pszValue, PERROR perr);
|
|
|
|
|
|
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
//
|
|
// Exported Functions
|
|
//
|
|
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
|
|
|
|
/*** VarCreate - Create a variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARIABLE VarCreate(HVARLIST hvlist,
|
|
char *pszName,
|
|
char *pszValue,
|
|
VARTYPE vtype,
|
|
VARFLAGS vfl,
|
|
PFNVCVALIDATE pfnvcv,
|
|
PERROR perr)
|
|
{
|
|
char ach[cbMSG_MAX]; // message formatting buffer
|
|
PVARIABLE pvar;
|
|
PVARLIST pvlist;
|
|
|
|
pvlist = PVLfromHVL(hvlist);
|
|
AssertVList(pvlist);
|
|
|
|
//** Make sure variable name is legal
|
|
if (!isValidVarName(pszName,perr)) {
|
|
// Use error message from isValidVarName
|
|
return NULL;
|
|
}
|
|
|
|
//** Make sure variable does not already exist
|
|
if (findVar(pvlist,pszName, perr)) {
|
|
ErrSet(perr,pszPARERR_ALREADY_CREATED,"%s",pszName);
|
|
return NULL;
|
|
}
|
|
|
|
//** Create VARIABLE
|
|
ErrClear(perr); // Reset error state caused by findVar() failing above!
|
|
if (!(pvar = MemAlloc(sizeof(VARIABLE))))
|
|
goto error;
|
|
|
|
SetAssertSignature(pvar,sigVARIABLE);
|
|
pvar->pszName = NULL; // Make sure not to free garbage!
|
|
pvar->pszValue = NULL; // Make sure not to free garbage!
|
|
pvar->vtype = vtype;
|
|
pvar->vfl = vfl;
|
|
pvar->pfnvcv = pfnvcv;
|
|
|
|
//** Make copy of name
|
|
if (!(pvar->pszName = MemStrDup(pszName)))
|
|
goto error;
|
|
|
|
//** Validate and copy value
|
|
if (!setVarValue(pvar,pszValue,perr))
|
|
goto error;
|
|
|
|
//** Link variable into list
|
|
pvar->pvarNext = NULL; // Always last on list
|
|
pvar->pvarPrev = pvlist->pvarTail; // Always points to last variable on list
|
|
|
|
if (pvlist->pvarHead == NULL) {
|
|
pvlist->pvarHead = pvar;
|
|
pvlist->pvarTail = pvar;
|
|
}
|
|
else {
|
|
AssertVar(pvlist->pvarTail);
|
|
pvlist->pvarTail->pvarNext = pvar; // Add to end of list
|
|
pvlist->pvarTail = pvar; // New tail
|
|
}
|
|
|
|
//** Remember which list we are on!
|
|
pvar->pvlist = pvlist;
|
|
|
|
//** Success
|
|
return HVARfromPVAR(pvar);
|
|
|
|
error:
|
|
if (!pvar) {
|
|
if (!(pvar->pszName))
|
|
MemFree(pvar->pszName);
|
|
if (!(pvar->pszValue))
|
|
MemFree(pvar->pszValue);
|
|
MemFree(pvar);
|
|
}
|
|
if (!ErrIsError(perr)) {
|
|
// Only create error message if not already present
|
|
MsgSet(ach,pszPARERR_CREATING_VARIABLE,"%s",pszName);
|
|
ErrSet(perr,pszPARERR_OUT_OF_MEMORY,"%s",ach);
|
|
}
|
|
return NULL;
|
|
} /* VarCreate */
|
|
|
|
|
|
/*** VarDelete - Delete existing variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
void VarDelete(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
PVARLIST pvlist;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
pvlist = pvar->pvlist;
|
|
AssertVList(pvlist);
|
|
AssertVar(pvlist->pvarHead);
|
|
AssertVar(pvlist->pvarTail);
|
|
|
|
//** Free memory for variable name and value
|
|
if (pvar->pszName)
|
|
MemFree(pvar->pszName);
|
|
|
|
if (pvar->pszValue)
|
|
MemFree(pvar->pszValue);
|
|
|
|
//** Adjust forward list pointers
|
|
if (pvar->pvarPrev == NULL) { // At head of list
|
|
pvlist->pvarHead = pvar->pvarNext; // Remove from forward chain
|
|
}
|
|
else { // At middle or end of list
|
|
AssertVar(pvar->pvarPrev);
|
|
pvar->pvarPrev->pvarNext = pvar->pvarNext; // Remove from forward chain
|
|
}
|
|
|
|
//** Adjust backward list pointers
|
|
if (pvar->pvarNext == NULL) { // At tail of list
|
|
pvlist->pvarTail = pvar->pvarPrev; // Remove from backward chain
|
|
}
|
|
else {
|
|
AssertVar(pvar->pvarNext);
|
|
pvar->pvarNext->pvarPrev = pvar->pvarPrev; // Remove from backward chain
|
|
}
|
|
|
|
ClearAssertSignature(pvar);
|
|
MemFree(pvar);
|
|
} /* VarDelete *
|
|
|
|
|
|
/*** VarCreateList - Create a list of variables
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARLIST VarCreateList(PERROR perr)
|
|
{
|
|
PVARLIST pvlist;
|
|
|
|
if (!(pvlist = MemAlloc(sizeof(VARLIST)))) {
|
|
ErrSet(perr,pszPARERR_OUT_OF_MEMORY,"%s",pszPARERR_CREATING_VAR_LIST);
|
|
return NULL;
|
|
}
|
|
|
|
SetAssertSignature(pvlist,sigVARLIST);
|
|
pvlist->pvarHead = NULL; // Empty list
|
|
pvlist->pvarTail = NULL; // Empty list
|
|
|
|
return HVLfromPVL(pvlist);
|
|
} /* VarCreateList */
|
|
|
|
|
|
/*** VarCloneList - Create an exact copy of a variable list
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARLIST VarCloneList(HVARLIST hvlist, PERROR perr)
|
|
{
|
|
PVARIABLE pvar;
|
|
PVARLIST pvlistClone;
|
|
PVARLIST pvlist;
|
|
ERROR errDummy; // Don't care about result
|
|
|
|
pvlist = PVLfromHVL(hvlist);
|
|
AssertVList(pvlist);
|
|
|
|
//** Create list
|
|
if (!(pvlistClone = PVLfromHVL(VarCreateList(perr)))) {
|
|
return NULL;
|
|
}
|
|
|
|
//** Clone variables one at a time
|
|
for (pvar=pvlist->pvarHead; pvar != NULL; pvar = pvar->pvarNext) {
|
|
AssertVar(pvar);
|
|
if (!VarCreate(HVLfromPVL(pvlistClone),
|
|
pvar->pszName,
|
|
pvar->pszValue,
|
|
pvar->vtype,
|
|
pvar->vfl,
|
|
pvar->pfnvcv,
|
|
perr)) {
|
|
//** Variable create failed
|
|
//
|
|
VarDestroyList(HVLfromPVL(pvlistClone),&errDummy); // Toss partial clone
|
|
return NULL; // Failure
|
|
}
|
|
}
|
|
|
|
//** Clone was succesfull!
|
|
return HVLfromPVL(pvlistClone); // Success
|
|
} /* VarCloneList */
|
|
|
|
|
|
/*** VarDestroyList - Destroy a list of variables
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
BOOL VarDestroyList(HVARLIST hvlist, PERROR perr)
|
|
{
|
|
PVARIABLE pvar;
|
|
PVARIABLE pvarNext;
|
|
PVARLIST pvlist;
|
|
|
|
pvlist = PVLfromHVL(hvlist);
|
|
AssertVList(pvlist);
|
|
|
|
//NOTE:
|
|
//
|
|
// Calling VarDelete() is simple, but induces a great deal of
|
|
// overhead for all of the list management. A speedier solution
|
|
// would be to have both VarDelete() and this routine call a bare-bones
|
|
// worker routine to delete the VARIABLE. However, this routine is
|
|
// lightly used by Diamond, so this optimization is not important.
|
|
//
|
|
|
|
//** Free all of the variables
|
|
for (pvar=pvlist->pvarHead; pvar != NULL; ) {
|
|
AssertVar(pvar);
|
|
pvarNext = pvar->pvarNext; // Save next pvar before we free pvar!
|
|
VarDelete(HVARfromPVAR(pvar));
|
|
pvar = pvarNext; // Use it
|
|
}
|
|
|
|
ClearAssertSignature(pvlist);
|
|
|
|
//** Free the list itself
|
|
MemFree(pvlist);
|
|
|
|
return TRUE;
|
|
} /* VarDestroyList */
|
|
|
|
|
|
/*** VarSet - Set value of a variable (create if necessary)
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARIABLE VarSet(HVARLIST hvlist,
|
|
char *pszName,
|
|
char *pszValue,
|
|
PERROR perr)
|
|
{
|
|
HVARIABLE hvar;
|
|
PVARIABLE pvar;
|
|
|
|
hvar = VarFind(hvlist,pszName,perr);
|
|
//** If variable does not exist, create a simple string variable
|
|
if (hvar == NULL) { // Have to create it ourselves
|
|
hvar = VarCreate(hvlist, // list
|
|
pszName, // var name
|
|
"", // default value
|
|
vtypeSTR, // var type
|
|
vflNONE, // No flags
|
|
NULL, // No validation function
|
|
perr);
|
|
if (hvar == NULL) {
|
|
return FALSE; // Could not create variable
|
|
}
|
|
}
|
|
|
|
//** Set new value
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
if (!setVarValue(pvar,pszValue,perr)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//** Success
|
|
return HVARfromPVAR(pvar); // Success, return hvar
|
|
} /* VarSet */
|
|
|
|
|
|
/*** VarSetLong - Set long variable value (create if necessary)
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
BOOL VarSetLong(HVARLIST hvlist,
|
|
char *pszName,
|
|
long lValue,
|
|
PERROR perr)
|
|
{
|
|
char ach[20]; // Longest long is: 123456789012
|
|
// -1234567890.
|
|
|
|
_ltoa(lValue,ach,10); // Create a string version
|
|
return VarSet(hvlist,pszName,ach,perr) != NULL;
|
|
} /* VarSetLong() */
|
|
|
|
|
|
/*** VarFind - See if variable exists
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARIABLE VarFind(HVARLIST hvlist,
|
|
char *pszName,
|
|
PERROR perr)
|
|
{
|
|
PVARLIST pvlist;
|
|
|
|
pvlist = PVLfromHVL(hvlist);
|
|
AssertVList(pvlist);
|
|
|
|
//** Make sure variable name is legal
|
|
if (!isValidVarName(pszName,perr)) {
|
|
return NULL; // isValidVarName sets perr
|
|
}
|
|
|
|
//** Find variable
|
|
return HVARfromPVAR(findVar(pvlist, pszName, perr));
|
|
}
|
|
|
|
|
|
/*** VarGetBool - Get value of boolean variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
BOOL VarGetBool(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return atoi(pvar->pszValue);
|
|
} /* VarFind */
|
|
|
|
|
|
/*** VarGetInt - Get value of int variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
int VarGetInt(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return atoi(pvar->pszValue);
|
|
}
|
|
|
|
|
|
/*** VarGetLong - Get value of long variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
long VarGetLong(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return atol(pvar->pszValue);
|
|
}
|
|
|
|
|
|
/*** VarGetString - Get value of string variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
char *VarGetString(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return pvar->pszValue;
|
|
}
|
|
|
|
|
|
/*** VarSetFlags - Set variable flags
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
void VarSetFlags(HVARIABLE hvar,
|
|
VARFLAGS vfl)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
pvar->vfl = vfl;
|
|
} /* VarSetFlags() */
|
|
|
|
|
|
/*** VarGetFlags - Get variable flags
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
VARFLAGS VarGetFlags(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return pvar->vfl;
|
|
} /* VarGetFlags() */
|
|
|
|
|
|
/*** VarFirstVar - Get first variable from list
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARIABLE VarFirstVar(HVARLIST hvlist)
|
|
{
|
|
PVARLIST pvlist;
|
|
|
|
pvlist = PVLfromHVL(hvlist);
|
|
AssertVList(pvlist);
|
|
|
|
return HVARfromPVAR(pvlist->pvarHead);
|
|
} /* VarFirstVar() */
|
|
|
|
|
|
/*** VarNextVar - Get next variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
HVARIABLE VarNextVar(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return HVARfromPVAR(pvar->pvarNext);
|
|
} /* VarNextVar() */
|
|
|
|
|
|
/*** VarGetName - Get name of variable
|
|
*
|
|
* NOTE: See variable.h for entry/exit conditions.
|
|
*/
|
|
char *VarGetName(HVARIABLE hvar)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
pvar = PVARfromHVAR(hvar);
|
|
AssertVar(pvar);
|
|
|
|
return pvar->pszName;
|
|
} /* VarGetName() */
|
|
|
|
|
|
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
//
|
|
// Private Functions
|
|
//
|
|
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
|
|
|
|
|
|
/*** isValidVarName - Checks validity of variable name
|
|
*
|
|
* Entry:
|
|
* pszName - Variable name to check
|
|
* perr - ERROR structure
|
|
*
|
|
* Exit-Success:
|
|
* Returns TRUE.
|
|
*
|
|
* Exit-Failure:
|
|
* Returns FALSE; perr filled in with error.
|
|
*/
|
|
BOOL isValidVarName(char *pszName, PERROR perr)
|
|
{
|
|
//** Check name length
|
|
if (strlen(pszName) >= cbVAR_NAME_MAX) {
|
|
ErrSet(perr,pszPARERR_VAR_NAME_TOO_LONG,"%d%s",cbVAR_NAME_MAX,pszName);
|
|
return FALSE;
|
|
}
|
|
//** Check for invalid characters, especially chVAR!
|
|
//BUGBUG 10-Aug-1993 bens isValidVarName is incomplete
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*** findVar - See if variable exists
|
|
*
|
|
* Entry:
|
|
* pvlist - Variable list
|
|
* pszName - Variable name to look for
|
|
* perr - ERROR structure
|
|
*
|
|
* Exit-Success:
|
|
* Returns PVARIABLE, if variable exists.
|
|
*
|
|
* Exit-Failure:
|
|
* Returns NULL, variable does not exist.
|
|
* ERROR structure filled in with details of error.
|
|
*/
|
|
PVARIABLE findVar(PVARLIST pvlist, char *pszName, PERROR perr)
|
|
{
|
|
PVARIABLE pvar;
|
|
|
|
AssertVList(pvlist);
|
|
|
|
for (pvar=pvlist->pvarHead; pvar != NULL; pvar = pvar->pvarNext) {
|
|
AssertVar(pvar);
|
|
if (!_stricmp(pvar->pszName,pszName)) { // Got a match!
|
|
return pvar; // Return variable pointer
|
|
}
|
|
}
|
|
|
|
//** Did not find variable
|
|
ErrSet(perr,pszPARERR_VARIABLE_NOT_FOUND,"%s",pszName);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*** setVarValue - Validate value, then update variable
|
|
*
|
|
* Entry:
|
|
* pvar - Variable to update
|
|
* pszValue - New value
|
|
* perr - ERROR structure
|
|
*
|
|
* Exit-Success:
|
|
* Returns TRUE; variable updated
|
|
*
|
|
* Exit-Failure:
|
|
* Returns FALSE, variable not updated.
|
|
* ERROR structure filled in with details of error.
|
|
*/
|
|
BOOL setVarValue(PVARIABLE pvar, char *pszValue, PERROR perr)
|
|
{
|
|
char achValue[cbVAR_VALUE_MAX];
|
|
char achMsg[cbMSG_MAX];
|
|
char *psz;
|
|
|
|
AssertVar(pvar);
|
|
|
|
//** Check value length
|
|
if (strlen(pszValue) >= cbVAR_VALUE_MAX) {
|
|
ErrSet(perr,pszPARERR_VALUE_TOO_LONG,"%d%s",
|
|
cbVAR_VALUE_MAX,pvar->pszName);
|
|
return FALSE;
|
|
}
|
|
|
|
//** Check if new value is OK
|
|
if (pvar->pfnvcv == NULL) { // No validation function
|
|
strcpy(achValue,pszValue); // Value is fine
|
|
}
|
|
else if (!(pvar->pfnvcv)(HVLfromPVL(pvar->pvlist),
|
|
pvar->pszName,
|
|
pszValue,
|
|
achValue,
|
|
perr)) {
|
|
//** Something wrong with value; validation function set perr
|
|
return FALSE;
|
|
}
|
|
|
|
//** Set new value
|
|
psz = pvar->pszValue; // Remember original value
|
|
if (!(pvar->pszValue = MemStrDup(achValue))) {
|
|
pvar->pszValue = psz; // Restore original value
|
|
MsgSet(achMsg,pszPARERR_SETTING_VARIABLE,"%s",pvar->pszName);
|
|
ErrSet(perr,pszPARERR_OUT_OF_MEMORY,"%s",achMsg);
|
|
return FALSE;
|
|
}
|
|
|
|
//** Free old value
|
|
if (psz != NULL) // If old value exists
|
|
MemFree(psz); // Free old value
|
|
|
|
return TRUE;
|
|
} /* setVarValue() */
|