/** Finds variable in storage blocks of volatile and non-volatile storage areas. This code finds variable in storage blocks of volatile and non-volatile storage areas. If VariableName is an empty string, then we just return the first qualified variable without comparing VariableName and VendorGuid. @param[in] VariableName Name of the variable to be found. @param[in] VendorGuid Variable vendor GUID to be found. @param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for output of the variable found. @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL. @retval EFI_SUCCESS Variable successfully found. @retval EFI_NOT_FOUND Variable not found **/ EFI_STATUS EFIAPI VariableExLibFindVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT AUTH_VARIABLE_INFO *AuthVariableInfo ) { EFI_STATUS Status; VARIABLE_POINTER_TRACK Variable; AUTHENTICATED_VARIABLE_HEADER *AuthVariable; Status = FindVariable ( VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE ); if (EFI_ERROR (Status)) { AuthVariableInfo->Data = NULL; AuthVariableInfo->DataSize = 0; AuthVariableInfo->Attributes = 0; AuthVariableInfo->PubKeyIndex = 0; AuthVariableInfo->MonotonicCount = 0; AuthVariableInfo->TimeStamp = NULL; return Status; } AuthVariableInfo->DataSize = DataSizeOfVariable (Variable.CurrPtr); AuthVariableInfo->Data = GetVariableDataPtr (Variable.CurrPtr); AuthVariableInfo->Attributes = Variable.CurrPtr->Attributes; if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable.CurrPtr; AuthVariableInfo->PubKeyIndex = AuthVariable->PubKeyIndex; AuthVariableInfo->MonotonicCount = AuthVariable->MonotonicCount; AuthVariableInfo->TimeStamp = &AuthVariable->TimeStamp; } return EFI_SUCCESS; }
VariableSymbol* ReferenceCleanupPass::FindVariable(Expression* e) { LoadVariableExpression* lve = dynamic_cast<LoadVariableExpression*>(e) ; BinaryExpression* be = dynamic_cast<BinaryExpression*>(e) ; if (lve != NULL) { return lve->get_source() ; } if (be != NULL) { return FindVariable(be->get_source1()) ; } FormattedText tmpText ; e->print(tmpText) ; std::cout << tmpText.get_value() << std::endl ; return NULL ; }
/** Update the variable region with Variable information. @param[in] AuthVariableInfo Pointer AUTH_VARIABLE_INFO structure for input of the variable. @retval EFI_SUCCESS The update operation is success. @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_WRITE_PROTECTED Variable is write-protected. @retval EFI_OUT_OF_RESOURCES There is not enough resource. **/ EFI_STATUS EFIAPI VariableExLibUpdateVariable ( IN AUTH_VARIABLE_INFO *AuthVariableInfo ) { VARIABLE_POINTER_TRACK Variable; FindVariable (AuthVariableInfo->VariableName, AuthVariableInfo->VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); return UpdateVariable ( AuthVariableInfo->VariableName, AuthVariableInfo->VendorGuid, AuthVariableInfo->Data, AuthVariableInfo->DataSize, AuthVariableInfo->Attributes, AuthVariableInfo->PubKeyIndex, AuthVariableInfo->MonotonicCount, &Variable, AuthVariableInfo->TimeStamp ); }
static int AddVariable(EvalState *c, char *id, PVAL *pval) { Variable *var; /* find or add a variable */ if (!(var = FindVariable(c, id))) { size_t size = sizeof(Variable) + strlen(id); if (c->free + size > c->top) return FALSE; var = (Variable *)c->free; c->free += size; strcpy(var->name, id); var->next = c->variables; var->bound = FALSE; c->variables = var; } /* return the successfully */ pval->type = TYPE_VARIABLE; pval->v.var = var; return TRUE; }
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) { if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock) { // NOTE: we do not determine static use for individual blocks of an array TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped(); ASSERT(blockNode); TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion(); ASSERT(constantUnion); const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock(); InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); ASSERT(namedBlock); namedBlock->staticUse = true; unsigned int fieldIndex = constantUnion->getUConst(0); ASSERT(fieldIndex < namedBlock->fields.size()); namedBlock->fields[fieldIndex].staticUse = true; return false; } return true; }
/** Update platform mode. @param[in] VirtualMode The current calling mode for this function. @param[in] Global The context of this Extended SAL Variable Services Class call. @param[in] Mode SETUP_MODE or USER_MODE. **/ VOID UpdatePlatformMode ( IN BOOLEAN VirtualMode, IN ESAL_VARIABLE_GLOBAL *Global, IN UINT32 Mode ) { EFI_STATUS Status; VARIABLE_POINTER_TRACK Variable; UINT32 VarAttr; Status = FindVariable ( Global->VariableName[VirtualMode][VAR_SETUP_MODE], Global->GlobalVariableGuid[VirtualMode], &Variable, &Global->VariableGlobal[VirtualMode], Global->FvbInstance ); ASSERT_EFI_ERROR (Status); mPlatformMode = Mode; VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; Status = UpdateVariable ( Global->VariableName[VirtualMode][VAR_SETUP_MODE], Global->GlobalVariableGuid[VirtualMode], &mPlatformMode, sizeof(UINT8), VarAttr, 0, 0, VirtualMode, Global, &Variable ); ASSERT_EFI_ERROR (Status); }
int scope_run(SuperScopePrivate *priv, ScopeRunnable runnable) { RESULT result; SetVariableNumeric("n", priv->n); SetVariableNumeric("b", priv->b); SetVariableNumeric("x", priv->x); SetVariableNumeric("y", priv->y); SetVariableNumeric("i", priv->i); SetVariableNumeric("v", priv->v); SetVariableNumeric("w", priv->w); SetVariableNumeric("h", priv->h); SetVariableNumeric("red", priv->red); SetVariableNumeric("green", priv->green); SetVariableNumeric("blue", priv->blue); SetVariableNumeric("linesize", priv->linesize); SetVariableNumeric("skip", priv->skip); SetVariableNumeric("drawmode", priv->drawmode); SetVariableNumeric("t", priv->t); SetVariableNumeric("d", priv->d); switch(runnable) { case SCOPE_RUNNABLE_INIT: Eval(priv->init, &result); break; case SCOPE_RUNNABLE_BEAT: Eval(priv->beat, &result); break; case SCOPE_RUNNABLE_FRAME: Eval(priv->frame, &result); break; case SCOPE_RUNNABLE_POINT: Eval(priv->point, &result); break; } //(FindVariable("n"))->value = NULL; VARIABLE var; var.value = NULL; priv->n = R2N(FindVariable("n")->value); priv->b = R2N(FindVariable("b")->value); priv->x = R2N(FindVariable("x")->value); priv->y = R2N(FindVariable("y")->value); priv->i = R2N(FindVariable("i")->value); priv->v = R2N(FindVariable("v")->value); priv->w = R2N(FindVariable("w")->value); priv->h = R2N(FindVariable("h")->value); priv->red = R2N(FindVariable("red")->value); priv->green = R2N(FindVariable("green")->value); priv->blue = R2N(FindVariable("blue")->value); priv->linesize = R2N(FindVariable("linesize")->value); priv->skip = R2N(FindVariable("skip")->value); priv->drawmode = R2N(FindVariable("drawmode")->value); priv->t = R2N(FindVariable("t")->value); priv->d = R2N(FindVariable("d")->value); return 0; }
// We want to check whether a uniform/varying is statically used // because we only count the used ones in packing computing. // Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count // toward varying counting if they are statically used in a fragment // shader. void CollectVariables::visitSymbol(TIntermSymbol *symbol) { ASSERT(symbol != NULL); ShaderVariable *var = NULL; const TString &symbolName = symbol->getSymbol(); if (IsVarying(symbol->getQualifier())) { var = FindVariable(symbolName, mVaryings); } else if (symbol->getType().getBasicType() == EbtInterfaceBlock) { UNREACHABLE(); } else if (symbolName == "gl_DepthRange") { ASSERT(symbol->getQualifier() == EvqUniform); if (!mDepthRangeAdded) { Uniform info; const char kName[] = "gl_DepthRange"; info.name = kName; info.mappedName = kName; info.type = GL_STRUCT_ANGLEX; info.arraySize = 0; info.precision = GL_NONE; info.staticUse = true; ShaderVariable nearInfo; const char kNearName[] = "near"; nearInfo.name = kNearName; nearInfo.mappedName = kNearName; nearInfo.type = GL_FLOAT; nearInfo.arraySize = 0; nearInfo.precision = GL_HIGH_FLOAT; nearInfo.staticUse = true; ShaderVariable farInfo; const char kFarName[] = "far"; farInfo.name = kFarName; farInfo.mappedName = kFarName; farInfo.type = GL_FLOAT; farInfo.arraySize = 0; farInfo.precision = GL_HIGH_FLOAT; farInfo.staticUse = true; ShaderVariable diffInfo; const char kDiffName[] = "diff"; diffInfo.name = kDiffName; diffInfo.mappedName = kDiffName; diffInfo.type = GL_FLOAT; diffInfo.arraySize = 0; diffInfo.precision = GL_HIGH_FLOAT; diffInfo.staticUse = true; info.fields.push_back(nearInfo); info.fields.push_back(farInfo); info.fields.push_back(diffInfo); mUniforms->push_back(info); mDepthRangeAdded = true; } } else { switch (symbol->getQualifier()) { case EvqAttribute: case EvqVertexIn: var = FindVariable(symbolName, mAttribs); break; case EvqFragmentOut: var = FindVariable(symbolName, mOutputVariables); break; case EvqUniform: { const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); if (interfaceBlock) { InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); ASSERT(namedBlock); var = FindVariable(symbolName, &namedBlock->fields); // Set static use on the parent interface block here namedBlock->staticUse = true; } else { var = FindVariable(symbolName, mUniforms); } // It's an internal error to reference an undefined user uniform ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var); } break; case EvqFragCoord: if (!mFragCoordAdded) { Varying info; const char kName[] = "gl_FragCoord"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFragCoordAdded = true; } return; case EvqFrontFacing: if (!mFrontFacingAdded) { Varying info; const char kName[] = "gl_FrontFacing"; info.name = kName; info.mappedName = kName; info.type = GL_BOOL; info.arraySize = 0; info.precision = GL_NONE; info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFrontFacingAdded = true; } return; case EvqPointCoord: if (!mPointCoordAdded) { Varying info; const char kName[] = "gl_PointCoord"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC2; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPointCoordAdded = true; } return; case EvqInstanceID: if (!mInstanceIDAdded) { Attribute info; const char kName[] = "gl_InstanceID"; info.name = kName; info.mappedName = kName; info.type = GL_INT; info.arraySize = 0; info.precision = GL_HIGH_INT; // Defined by spec. info.staticUse = true; info.location = -1; mAttribs->push_back(info); mInstanceIDAdded = true; } return; case EvqPosition: if (!mPositionAdded) { Varying info; const char kName[] = "gl_Position"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_HIGH_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPositionAdded = true; } return; case EvqPointSize: if (!mPointSizeAdded) { Varying info; const char kName[] = "gl_PointSize"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPointSizeAdded = true; } return; case EvqLastFragData: if (!mLastFragDataAdded) { Varying info; const char kName[] = "gl_LastFragData"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = static_cast<const TVariable*>(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst(); info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mLastFragDataAdded = true; } return; case EvqFragColor: if (!mFragColorAdded) { Attribute info; const char kName[] = "gl_FragColor"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; mOutputVariables->push_back(info); mFragColorAdded = true; } return; case EvqFragData: if (!mFragDataAdded) { Attribute info; const char kName[] = "gl_FragData"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = static_cast<const TVariable *>( mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) ->getConstPointer() ->getIConst(); info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; mOutputVariables->push_back(info); mFragDataAdded = true; } return; case EvqFragDepthEXT: if (!mFragDepthEXTAdded) { Attribute info; const char kName[] = "gl_FragDepthEXT"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GLVariablePrecision(static_cast<const TVariable *>( mSymbolTable.findBuiltIn("gl_FragDepthEXT", 100)) ->getType()); info.staticUse = true; mOutputVariables->push_back(info); mFragDepthEXTAdded = true; } return; case EvqFragDepth: if (!mFragDepthAdded) { Attribute info; const char kName[] = "gl_FragDepth"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GL_HIGH_FLOAT; info.staticUse = true; mOutputVariables->push_back(info); mFragDepthAdded = true; } return; default: break; } } if (var) { var->staticUse = true; } }
/** Process variable with key exchange key for verification. @param[in] VariableName The name of Variable to be found. @param[in] VendorGuid The variable vendor GUID. @param[in] Data The data pointer. @param[in] DataSize The size of Data found. If size is less than the data, this value contains the required size. @param[in] VirtualMode The current calling mode for this function. @param[in] Global The context of this Extended SAL Variable Services Class call. @param[in] Variable The variable information which is used to keep track of variable usage. @param[in] Attributes The attribute value of the variable. @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_SECURITY_VIOLATION The variable did NOT pass the validation check carried out by the firmware. @retval EFI_SUCCESS The variable passed validation successfully. **/ EFI_STATUS ProcessVarWithKek ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN BOOLEAN VirtualMode, IN ESAL_VARIABLE_GLOBAL *Global, IN VARIABLE_POINTER_TRACK *Variable, IN UINT32 Attributes OPTIONAL ) { EFI_STATUS Status; VARIABLE_POINTER_TRACK KekVariable; EFI_SIGNATURE_LIST *KekList; EFI_SIGNATURE_DATA *KekItem; UINT32 KekCount; EFI_VARIABLE_AUTHENTICATION *CertData; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock; BOOLEAN IsFound; UINT32 Index; VARIABLE_HEADER VariableHeader; BOOLEAN Valid; KekList = NULL; ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); if (mPlatformMode == USER_MODE) { if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) { // // In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute. // return EFI_INVALID_PARAMETER; } CertData = (EFI_VARIABLE_AUTHENTICATION *) Data; CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData); if (Variable->CurrPtr != 0x0) { Valid = IsValidVariableHeader ( Variable->CurrPtr, Variable->Volatile, &Global->VariableGlobal[VirtualMode], Global->FvbInstance, &VariableHeader ); ASSERT (Valid); if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) { // // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION. // return EFI_SECURITY_VIOLATION; } } // // Get KEK database from variable. // Status = FindVariable ( Global->VariableName[VirtualMode][VAR_KEY_EXCHANGE_KEY], Global->GlobalVariableGuid[VirtualMode], &KekVariable, &Global->VariableGlobal[VirtualMode], Global->FvbInstance ); ASSERT_EFI_ERROR (Status); ZeroMem (Global->KeyList, MAX_KEYDB_SIZE); GetVariableDataPtr ( KekVariable.CurrPtr, KekVariable.Volatile, &Global->VariableGlobal[VirtualMode], Global->FvbInstance, (CHAR16 *) Global->KeyList ); // // Enumerate all Kek items in this list to verify the variable certificate data. // If anyone is authenticated successfully, it means the variable is correct! // KekList = (EFI_SIGNATURE_LIST *) Global->KeyList; IsFound = FALSE; KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize; KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize); for (Index = 0; Index < KekCount; Index++) { if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) { IsFound = TRUE; break; } KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize); } if (!IsFound) { return EFI_SECURITY_VIOLATION; } Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, CertBlock->PublicKey); if (!EFI_ERROR (Status)) { Status = UpdateVariable ( VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, 0, CertData->MonotonicCount, VirtualMode, Global, Variable ); } } else { // // If in setup mode, no authentication needed. // Status = UpdateVariable ( VariableName, VendorGuid, Data, DataSize, Attributes, 0, 0, VirtualMode, Global, Variable ); } return Status; }
/** Process variable with platform key for verification. @param[in] VariableName The name of Variable to be found. @param[in] VendorGuid The variable vendor GUID. @param[in] Data The data pointer. @param[in] DataSize The size of Data found. If size is less than the data, this value contains the required size. @param[in] VirtualMode The current calling mode for this function. @param[in] Global The context of this Extended SAL Variable Services Class call. @param[in] Variable The variable information which is used to keep track of variable usage. @param[in] Attributes The attribute value of the variable. @param[in] IsPk Indicates whether to process pk. @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation check carried out by the firmware. @retval EFI_SUCCESS The variable passed validation successfully. **/ EFI_STATUS ProcessVarWithPk ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN VOID *Data, IN UINTN DataSize, IN BOOLEAN VirtualMode, IN ESAL_VARIABLE_GLOBAL *Global, IN VARIABLE_POINTER_TRACK *Variable, IN UINT32 Attributes OPTIONAL, IN BOOLEAN IsPk ) { EFI_STATUS Status; VARIABLE_POINTER_TRACK PkVariable; EFI_SIGNATURE_LIST *OldPkList; EFI_SIGNATURE_DATA *OldPkData; EFI_VARIABLE_AUTHENTICATION *CertData; VARIABLE_HEADER VariableHeader; BOOLEAN Valid; OldPkList = NULL; ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { // // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute. // return EFI_INVALID_PARAMETER; } if (mPlatformMode == USER_MODE) { if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) { // // In user mode, PK and KEK should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute. // return EFI_INVALID_PARAMETER; } CertData = (EFI_VARIABLE_AUTHENTICATION *) Data; if (Variable->CurrPtr != 0x0) { Valid = IsValidVariableHeader ( Variable->CurrPtr, Variable->Volatile, &Global->VariableGlobal[VirtualMode], Global->FvbInstance, &VariableHeader ); ASSERT (Valid); if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) { // // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION. // return EFI_SECURITY_VIOLATION; } } // // Get platform key from variable. // Status = FindVariable ( Global->VariableName[VirtualMode][VAR_PLATFORM_KEY], Global->GlobalVariableGuid[VirtualMode], &PkVariable, &Global->VariableGlobal[VirtualMode], Global->FvbInstance ); ASSERT_EFI_ERROR (Status); ZeroMem (Global->KeyList, MAX_KEYDB_SIZE); GetVariableDataPtr ( PkVariable.CurrPtr, PkVariable.Volatile, &Global->VariableGlobal[VirtualMode], Global->FvbInstance, (CHAR16 *) Global->KeyList ); OldPkList = (EFI_SIGNATURE_LIST *) Global->KeyList; OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize); Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, OldPkData->SignatureData); if (!EFI_ERROR (Status)) { Status = UpdateVariable ( VariableName, VendorGuid, (UINT8*)Data + AUTHINFO_SIZE, DataSize - AUTHINFO_SIZE, Attributes, 0, CertData->MonotonicCount, VirtualMode, Global, Variable ); if (!EFI_ERROR (Status)) { // // If delete PK in user mode, need change to setup mode. // if ((DataSize == AUTHINFO_SIZE) && IsPk) { UpdatePlatformMode (VirtualMode, Global, SETUP_MODE); } } } } else { Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, 0, 0, VirtualMode, Global, Variable); // // If enroll PK in setup mode, need change to user mode. // if ((DataSize != 0) && IsPk) { UpdatePlatformMode (VirtualMode, Global, USER_MODE); } } return Status; }
/** Initializes for authenticated varibale service. @retval EFI_SUCCESS The function successfully executed. @retval EFI_OUT_OF_RESOURCES Failed to allocate enough memory resources. **/ EFI_STATUS AutenticatedVariableServiceInitialize ( VOID ) { EFI_STATUS Status; VARIABLE_POINTER_TRACK Variable; UINT8 VarValue; UINT32 VarAttr; UINTN DataSize; UINTN CtxSize; VARIABLE_HEADER VariableHeader; BOOLEAN Valid; ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); mVariableModuleGlobal->AuthenticatedVariableGuid[Physical] = &gEfiAuthenticatedVariableGuid; mVariableModuleGlobal->CertRsa2048Sha256Guid[Physical] = &gEfiCertRsa2048Sha256Guid; mVariableModuleGlobal->ImageSecurityDatabaseGuid[Physical] = &gEfiImageSecurityDatabaseGuid; // // Initialize hash context. // CtxSize = Sha256GetContextSize (); mVariableModuleGlobal->HashContext[Physical] = AllocateRuntimePool (CtxSize); ASSERT (mVariableModuleGlobal->HashContext[Physical] != NULL); // // Check "AuthVarKeyDatabase" variable's existence. // If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. // Status = FindVariable ( mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB], &gEfiAuthenticatedVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance ); if (Variable.CurrPtr == 0x0) { VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; VarValue = 0; mPubKeyNumber = 0; Status = UpdateVariable ( mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB], &gEfiAuthenticatedVariableGuid, &VarValue, sizeof(UINT8), VarAttr, 0, 0, FALSE, mVariableModuleGlobal, &Variable ); if (EFI_ERROR (Status)) { return Status; } } else { // // Load database in global variable for cache. // Valid = IsValidVariableHeader ( Variable.CurrPtr, Variable.Volatile, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance, &VariableHeader ); ASSERT (Valid); DataSize = DataSizeOfVariable (&VariableHeader); ASSERT (DataSize <= MAX_KEYDB_SIZE); GetVariableDataPtr ( Variable.CurrPtr, Variable.Volatile, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance, (CHAR16 *) mVariableModuleGlobal->PubKeyStore ); mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE); } // // Check "SetupMode" variable's existence. // If it doesn't exist, check PK database's existence to determine the value. // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. // Status = FindVariable ( mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE], &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance ); if (Variable.CurrPtr == 0x0) { Status = FindVariable ( mVariableModuleGlobal->VariableName[Physical][VAR_PLATFORM_KEY], &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance ); if (Variable.CurrPtr == 0x0) { mPlatformMode = SETUP_MODE; } else { mPlatformMode = USER_MODE; } VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; Status = UpdateVariable ( mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE], &gEfiGlobalVariableGuid, &mPlatformMode, sizeof(UINT8), VarAttr, 0, 0, FALSE, mVariableModuleGlobal, &Variable ); if (EFI_ERROR (Status)) { return Status; } } else { GetVariableDataPtr ( Variable.CurrPtr, Variable.Volatile, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance, (CHAR16 *) &mPlatformMode ); } // // Check "SignatureSupport" variable's existence. // If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. // Status = FindVariable ( EFI_SIGNATURE_SUPPORT_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal[Physical], mVariableModuleGlobal->FvbInstance ); if (Variable.CurrPtr == 0x0) { VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; Status = UpdateVariable ( EFI_SIGNATURE_SUPPORT_NAME, &gEfiGlobalVariableGuid, mSignatureSupport, SIGSUPPORT_NUM * sizeof(EFI_GUID), VarAttr, 0, 0, FALSE, mVariableModuleGlobal, &Variable ); } return Status; }
BOOL FASTCALL comProc_VarDeclare(U16 flags, S16 *brackCnt) { int cast,arraySize,elementsSize,braceCnt; S32 offset=-1,elementsEnd; S32 num; U16 varflags = 0; char *label=NULL; VAR *castvar=NULL; VAR *var=NULL,*pvar; BOOL VARSET, SEEKED = FALSE; if(!STRCMP(szTemp,"typedef")) { varflags |= VARFLAG_TYPECAST; GetNextWord(); } if(!STRCMP(szTemp,"shared")) { varflags |= VARFLAG_SHARED; GetNextWord(); } if((cast=IsVarCast(szTemp,&castvar))==VARCAST_NULL) { if(varflags&VARFLAG_TYPECAST) { error(ERR_NOTTYPECAST,szTemp); return TRUE; } return FALSE; } if(curVar&&(curVar->flags&VARFLAG_TYPECAST)) varflags |= VARFLAG_TYPECAST; for(;;) { if(!IsStringLabel(GetNextWord())) { error(ERR_BADLABEL,szTemp); sprintf(szTemp, "invlabel_%04X", invlabel++); } else { if(PRECOMPILING && IsLabelUsed(szTemp,curVar?curVar->childVars:vars)) sprintf(szTemp, "invlabel_%04X", invlabel++); } label = strdup(szTemp); if(PeekNextWord()[0]==':') { GetNextWord(); if(IsStrNum(GetNextWord())) { offset = ConfirmWord(StrToInt(szTemp)); varflags |= VARFLAG_FIXED; } else error(ERR_INTEXP); VARSET = TRUE; } else { if(varflags&VARFLAG_TYPECAST) VARSET = TRUE; else if(!curBank) fatal(FTL_VARNOTROMBANK); if(cast == VARCAST_STRUCT && !(varflags & VARFLAG_TYPECAST) && !PRECOMPILING) { offset = GetBankOffset(); VARSET = TRUE; } else VARSET = FALSE; } if(PRECOMPILING) { var = AddVariable(label, cast, castvar, varflags, offset); if(varflags&VARFLAG_TYPECAST) { if(curVar) { var->offset = VarSize(curVar); } } } else { var = FindVariable(curVar?curVar->childVars:(varflags&VARFLAG_TYPECAST)?typedefs:vars, label); if(!(var->flags&VARFLAG_TYPECAST) && (!(var->flags&VARFLAG_DEFCASTED) || cast!=VARCAST_STRUCT) && (var->offset==-1)) SetVarOffsets(var,GetBankOffset(),FALSE); } if(castvar) { var->size = castvar->size; } arraySize = 0; if(PeekNextWord()[0]=='[') { GetNextWord(); if(PeekNextWord()[0]==']') { arraySize=-1;//autosize GetNextWord(); } else { /* if(IsStrNum(szTemp)) { if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST))) { arraySize = ConfirmWord(StrToInt(szTemp)); var->arraySize = arraySize; } } else error(ERR_INTEXP); */ CompileImmediateInteger(0, &num, -1, 0); if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST))) { arraySize = ConfirmWord(num); var->arraySize = arraySize; } if(GetNextWord()[0]!=']') error(ERR_ARRAYENDEXP,szTemp); } } if(!(var->flags&VARFLAG_DEFCASTED) && (cast==VARCAST_STRUCT)) { SetCurVar(var); GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt); ReleaseCurVar(); } else { if(PeekNextWord()[0]=='=') { GetNextWord(); if(var->flags&VARFLAG_TYPECAST) { error(ERR_VARCASTASSIGN,label); SeekPastBraceBlock(); } else if(curBank->type==BANKTYPE_RAM) { error(ERR_VARDECLAREINRAM); SeekPastBraceBlock(); } else { elementsSize = 0; elementsEnd = (GetBankOffset()-curBank->org) + ((arraySize==-1)? var->size:var->size*arraySize); if(GetNextWord()[0]=='{') { if(!arraySize) { error(ERR_NOTARRAY,var->label); } braceCnt = 1; GetNextWord(); } else braceCnt = 0; do { braceCnt = CompileVarBody(flags,brackCnt, var, &elementsSize, braceCnt, cast); } while(braceCnt); if(!PRECOMPILING) { if(arraySize==-1) { arraySize=elementsSize/VarSize(var); SEEKED = TRUE; } else { if(elementsSize>VarSize(var)) error(ERR_ELEMENTSTOOLARGE,var->label,elementsSize-VarSize(var)); BankSeek(elementsEnd); SEEKED = TRUE; } var->arraySize = arraySize; } } } else { if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST) && !PRECOMPILING && !VARSET)) { if(arraySize==-1) arraySize = 1; if(arraySize!=0) var->arraySize = arraySize; if(!PRECOMPILING) { BankSeekFwd(VarSize(var)); SEEKED = TRUE; } } } if(((var->flags&VARFLAG_TYPECAST) && PRECOMPILING) || (!(var->flags&VARFLAG_TYPECAST) && !PRECOMPILING)) { // adjust all the var sizes for structs arraySize = VarSize(var); pvar = var->parent; while(pvar) { pvar->size += arraySize; pvar = pvar->parent; } } } if(!(var->flags&VARFLAG_TYPECAST) && (cast==VARCAST_STRUCT)) SetVarOffsets(var,offset,FALSE); // removed 2004-05-22, if problems occurs, check if(!SEEKED && (var->flags&(VARFLAG_TYPECAST|VARFLAG_DEFCASTED))==VARFLAG_DEFCASTED && (cast==VARCAST_STRUCT)) { CheckCurBank(); if((var->flags&VARFLAG_TYPECAST) || !PRECOMPILING) BankSeekFwd(VarSize(var)); } ssFree(label); if(PeekNextWord()[0]!=',') break; GetNextWord(); } return TRUE; }
/** Add public key in store and return its index. @param[in] VirtualMode The current calling mode for this function. @param[in] Global The context of this Extended SAL Variable Services Class call. @param[in] PubKey The input pointer to Public Key data. @return The index of new added item. **/ UINT32 AddPubKeyInStore ( IN BOOLEAN VirtualMode, IN ESAL_VARIABLE_GLOBAL *Global, IN UINT8 *PubKey ) { EFI_STATUS Status; BOOLEAN IsFound; UINT32 Index; VARIABLE_POINTER_TRACK Variable; UINT8 *Ptr; if (PubKey == NULL) { return 0; } Status = FindVariable ( Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB], Global->AuthenticatedVariableGuid[VirtualMode], &Variable, &Global->VariableGlobal[VirtualMode], Global->FvbInstance ); ASSERT_EFI_ERROR (Status); // // Check whether the public key entry does exist. // IsFound = FALSE; for (Ptr = Global->PubKeyStore, Index = 1; Index <= mPubKeyNumber; Index++) { if (CompareMem (Ptr, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) { IsFound = TRUE; break; } Ptr += EFI_CERT_TYPE_RSA2048_SIZE; } if (!IsFound) { // // Add public key in database. // if (mPubKeyNumber == MAX_KEY_NUM) { // // Notes: Database is full, need enhancement here, currently just return 0. // return 0; } CopyMem (Global->PubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE); Index = ++mPubKeyNumber; // // Update public key database variable. // Status = UpdateVariable ( Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB], Global->AuthenticatedVariableGuid[VirtualMode], Global->PubKeyStore, mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, 0, 0, VirtualMode, Global, &Variable ); ASSERT_EFI_ERROR (Status); } return Index; }
wxString MacroManager::DoExpand( const wxString& expression, IManager* manager, const wxString& project, bool applyEnv, const wxString& confToBuild) { wxString expandedString(expression); clCxxWorkspace* workspace = clCxxWorkspaceST::Get(); if(!manager) { manager = clGetManager(); } size_t retries = 0; wxString dummyname, dummfullname; while((retries < 5) && FindVariable(expandedString, dummyname, dummyname)) { ++retries; DollarEscaper de(expandedString); if(workspace) { expandedString.Replace(wxT("$(WorkspaceName)"), workspace->GetName()); ProjectPtr proj = workspace->GetProject(project); if(proj) { wxString prjBuildWd; wxString prjRunWd; wxString project_name(proj->GetName()); // make sure that the project name does not contain any spaces project_name.Replace(wxT(" "), wxT("_")); BuildConfigPtr bldConf = workspace->GetProjBuildConf(proj->GetName(), confToBuild); if(bldConf) { bool isCustom = bldConf->IsCustomBuild(); expandedString.Replace(wxT("$(ProjectOutputFile)"), bldConf->GetOutputFileName()); // An alias expandedString.Replace(wxT("$(OutputFile)"), bldConf->GetOutputFileName()); // When custom build project, use the working directory set in the // custom build tab, otherwise use the project file's path prjBuildWd = isCustom ? bldConf->GetCustomBuildWorkingDir() : proj->GetFileName().GetPath(); prjRunWd = bldConf->GetWorkingDirectory(); } expandedString.Replace(wxT("$(ProjectWorkingDirectory)"), prjBuildWd); expandedString.Replace(wxT("$(ProjectRunWorkingDirectory)"), prjRunWd); expandedString.Replace(wxT("$(ProjectPath)"), proj->GetFileName().GetPath()); expandedString.Replace(wxT("$(WorkspacePath)"), workspace->GetWorkspaceFileName().GetPath()); expandedString.Replace(wxT("$(ProjectName)"), project_name); if(bldConf) { expandedString.Replace(wxT("$(IntermediateDirectory)"), bldConf->GetIntermediateDirectory()); expandedString.Replace(wxT("$(ConfigurationName)"), bldConf->GetName()); expandedString.Replace(wxT("$(OutDir)"), bldConf->GetIntermediateDirectory()); } if(expandedString.Find(wxT("$(ProjectFiles)")) != wxNOT_FOUND) expandedString.Replace(wxT("$(ProjectFiles)"), proj->GetFiles()); if(expandedString.Find(wxT("$(ProjectFilesAbs)")) != wxNOT_FOUND) expandedString.Replace(wxT("$(ProjectFilesAbs)"), proj->GetFiles(true)); } } if(manager) { IEditor* editor = manager->GetActiveEditor(); if(editor) { wxFileName fn(editor->GetFileName()); expandedString.Replace(wxT("$(CurrentFileName)"), fn.GetName()); wxString fpath(fn.GetPath()); fpath.Replace(wxT("\\"), wxT("/")); expandedString.Replace(wxT("$(CurrentFilePath)"), fpath); expandedString.Replace(wxT("$(CurrentFileExt)"), fn.GetExt()); expandedString.Replace(wxT("$(CurrentFileFullName)"), fn.GetFullName()); wxString ffullpath(fn.GetFullPath()); ffullpath.Replace(wxT("\\"), wxT("/")); expandedString.Replace(wxT("$(CurrentFileFullPath)"), ffullpath); expandedString.Replace(wxT("$(CurrentSelection)"), editor->GetSelection()); if(expandedString.Find(wxT("$(CurrentSelectionRange)")) != wxNOT_FOUND) { int start = editor->GetSelectionStart(), end = editor->GetSelectionEnd(); wxString output = wxString::Format(wxT("%i:%i"), start, end); expandedString.Replace(wxT("$(CurrentSelectionRange)"), output); } } } // exapand common macros wxDateTime now = wxDateTime::Now(); expandedString.Replace(wxT("$(User)"), wxGetUserName()); expandedString.Replace(wxT("$(Date)"), now.FormatDate()); if(manager && applyEnv) { expandedString.Replace(wxT("$(CodeLitePath)"), manager->GetInstallDirectory()); // Apply the environment and expand the variables EnvSetter es(NULL, NULL, project, confToBuild); expandedString = manager->GetEnv()->ExpandVariables(expandedString, false); } } return expandedString; }
static BOOLEAN CheckArgumentForConstraintError( struct expr *expressionList, struct expr *lastOne, int i, struct FunctionDefinition *theFunction, struct lhsParseNode *theLHS) { int theRestriction; CONSTRAINT_RECORD *constraint1, *constraint2, *constraint3, *constraint4; struct lhsParseNode *theVariable; struct expr *tmpPtr; int rv = FALSE; /*=============================================================*/ /* Skip anything that isn't a variable or isn't an argument to */ /* a user defined function (i.e. deffunctions and generic have */ /* no constraint information so they aren't checked). */ /*=============================================================*/ if ((expressionList->type != SF_VARIABLE) || (theFunction == NULL)) { return (rv); } /*===========================================*/ /* Get the restrictions for the argument and */ /* convert them to a constraint record. */ /*===========================================*/ theRestriction = GetNthRestriction(theFunction,i); constraint1 = ArgumentTypeToConstraintRecord(theRestriction); /*================================================*/ /* Look for the constraint record associated with */ /* binding the variable in the LHS of the rule. */ /*================================================*/ theVariable = FindVariable((SYMBOL_HN *) expressionList->value,theLHS); if (theVariable != NULL) { if (theVariable->type == MF_VARIABLE) { constraint2 = GetConstraintRecord(); SetConstraintType(MULTIFIELD,constraint2); } else if (theVariable->constraints == NULL) { constraint2 = GetConstraintRecord(); } else { constraint2 = CopyConstraintRecord(theVariable->constraints); } } else { constraint2 = NULL; } /*================================================*/ /* Look for the constraint record associated with */ /* binding the variable on the RHS of the rule. */ /*================================================*/ constraint3 = FindBindConstraints((SYMBOL_HN *) expressionList->value); /*====================================================*/ /* Union the LHS and RHS variable binding constraints */ /* (the variable must satisfy one or the other). */ /*====================================================*/ constraint3 = UnionConstraints(constraint3,constraint2); /*====================================================*/ /* Intersect the LHS/RHS variable binding constraints */ /* with the function argument restriction constraints */ /* (the variable must satisfy both). */ /*====================================================*/ constraint4 = IntersectConstraints(constraint3,constraint1); /*====================================*/ /* Check for unmatchable constraints. */ /*====================================*/ if (UnmatchableConstraint(constraint4) && GetStaticConstraintChecking()) { PrintErrorID("RULECSTR",3,TRUE); PrintRouter(WERROR,"Previous variable bindings of ?"); PrintRouter(WERROR,ValueToString((SYMBOL_HN *) expressionList->value)); PrintRouter(WERROR," caused the type restrictions"); PrintRouter(WERROR,"\nfor argument #"); PrintLongInteger(WERROR,(long int) i); PrintRouter(WERROR," of the expression "); tmpPtr = lastOne->nextArg; lastOne->nextArg = NULL; PrintExpression(WERROR,lastOne); lastOne->nextArg = tmpPtr; PrintRouter(WERROR,"\nfound in the rule's RHS to be violated.\n"); rv = TRUE; } /*===========================================*/ /* Free the temporarily created constraints. */ /*===========================================*/ RemoveConstraint(constraint1); RemoveConstraint(constraint2); RemoveConstraint(constraint3); RemoveConstraint(constraint4); /*========================================*/ /* Return TRUE if unmatchable constraints */ /* were detected, otherwise FALSE. */ /*========================================*/ return(rv); }
void Expression::generate_code(FILE *o, const char *fmt, const std::string thisvar, std::set<std::string> important, std::set<std::string> *allvars, std::set<std::string> *myvars) { std::set<std::string> otherallvars, othermyvars; if (!allvars) allvars = &otherallvars; if (!myvars) myvars = &othermyvars; // Set of variables that need to be deleted. std::set<std::string> gridvars; std::set<std::string> recipvars; Expression e = *this; if (thisvar != "") e = FindNamedSubexpression(thisvar); //printf("Starting %s...\n", thisvar.c_str()); { // First, let's work out any "explicitly-named" subexpressions, common or not... std::string n = e.FindASubexpressionName(e.alias); Expression s = e.FindNamedSubexpression(n); //fprintf(o, "\t\t// Next to consider is %s (for %s)\n", n.c_str(), thisvar.c_str()); while (s.alias == n && n != "" && n != e.alias) { { Expression mysube = FindNamedSubexpression(n); if (mysube != s) { printf("Nasty situation with %s. The two options are:\n", n.c_str()); printf("a = %s\n", s.printme().c_str()); printf("b = %s\n", mysube.printme().c_str()); printf("alias of b is %s, and its name is %s compared with %s\n", mysube.alias.c_str(), mysube.name.c_str(), n.c_str()); exit(1); } } std::string a = "my_" + n; if (allvars->count(a)) { // need to make this thing unique... for (int varnum=0; true; varnum++) { std::ostringstream oss; oss << varnum; a = n + "_" + oss.str(); if (!allvars->count(a)) break; } } std::string myfmt = "\t\t" + (s.ctype() + (" " + a + " = %s; // explicitly-named\n")); //printf("I am having fun with %s", myfmt.c_str()); //printf("I am %s\n", e.printme().c_str()); //printf("%s is %s\n", a.c_str(), s.printme().c_str()); generate_code(o, myfmt.c_str(), n, important, allvars, myvars); fflush(o); if (s.typeIs("Grid")) gridvars.insert(a); if (s.typeIs("ReciprocalGrid")) recipvars.insert(a); if (!s.typeIs("double")) myvars->insert(a); allvars->insert(a); s = FindNamedSubexpression(n); // Find out if the expression has since changed... //fprintf(o, "// expression was %s\n", printme().c_str()); //fprintf(o, "// I eliminated %s\n", s.printme().c_str()); EliminateThisSubexpression(s, a); //fprintf(o, "// expression is now %s\n", printme().c_str()); // We need the following in order to update e with any changes // that generate_code might have made... if (thisvar != "") e = FindNamedSubexpression(thisvar); else e = *this; n = e.FindASubexpressionName(e.alias); s = e.FindNamedSubexpression(n); // Free unused variables... generate_free_code(o, myvars); } } //printf("All done with this one %s!\n", thisvar.c_str()); // I don't perform the following simplification, since it makes the // generated code harder to read, and also takes a fair amount of // time to perform... if (false) { // Second, let's see what double expressions we can simplify... std::set<std::string> doublevars; Expression s = e.FindDoubleSubexpression(); while (!s.kindIs("constant")) { std::string a = s.alias + "_v"; if (a == "_v") a = "d"; if (allvars->count(a)) { // need to make this thing unique... for (int varnum=0; true; varnum++) { std::ostringstream oss; oss << varnum; std::string newa = a + "_" + oss.str(); if (!allvars->count(newa)) { a = newa; break; } } } doublevars.insert(a); allvars->insert(a); e.EliminateThisSubexpression(s, a); EliminateThisSubexpression(s, a); fprintf(o, " const double %s = %s;\n", a.c_str(), s.printme().c_str()); s = e.FindDoubleSubexpression(); } } // Done simplifying double-valued expressions. Expression s = e.FindCommonSubexpression(); //Expression ssmaller = s; //ssmaller.ScalarFactor(); // This is s without any prefactor. // Use the smaller expression if it is more common. //if (e.CountThisSubexpression(ssmaller) > e.CountThisSubexpression(s)) s = ssmaller; // Let's lump in any "cheap" calculations we can get done at the same time! //if (e.CountThisSubexpression(e.EasyParentOfThisSubexpression(s)) >= e.CountThisSubexpression(s)) // s = e.EasyParentOfThisSubexpression(s); int counter = 0; while (s != e) { std::string a = s.alias + "_v"; if (a == "_v") { if (s.typeIs("ReciprocalGrid")) a = "recip"; else a = "var"; } if (allvars->count(a)) { // need to make this thing unique... for (int varnum=0; true; varnum++) { std::ostringstream oss; oss << varnum; std::string newa = a + "_" + oss.str(); if (!allvars->count(newa)) { a = newa; break; } } } //fprintf(o, " %s *%s_ptr = new %s(%s);\n", s.ctype(), a.c_str(), s.ctype(), s.printme().c_str()); //fprintf(o, " %s %s = *%s_ptr;\n", s.ctype(), a.c_str(), a.c_str()); if (s.typeIs("Grid")) gridvars.insert(a); if (s.typeIs("ReciprocalGrid")) recipvars.insert(a); if (!s.typeIs("double")) myvars->insert(a); allvars->insert(a); e.EliminateThisSubexpression(s, a); EliminateThisSubexpression(s, a); fprintf(o, " %s %s = %s;\n", s.ctype(), a.c_str(), s.printme().c_str()); fprintf(o, " //printf(\"Memory use %x is %%g with peak %%g\\n\", current_memory()/1024.0/1024, peak_memory()/1024.0/1024);\n", counter++); //fprintf(o, " // expr = %s\n", e.printme().c_str()); // Free unused variables... generate_free_code(o, myvars); for (std::set<std::string>::iterator i = gridvars.begin(); i != gridvars.end(); ++i) if (!FindVariable(*i)) gridvars.erase(i); for (std::set<std::string>::iterator i = recipvars.begin(); i != recipvars.end(); ++i) if (!FindVariable(*i)) recipvars.erase(i); bool have_changed = true; while (have_changed) { have_changed = false; // Now we look for a variable that could be simplified a bit... for (std::set<std::string>::iterator i = gridvars.begin(); i != gridvars.end(); ++i) { Expression easy = EasyParentOfThisSubexpression(Expression(*i), important); if (easy != Expression(*i)) { if (!easy.typeIs("Grid")) easy = EasyParentOfThisSubexpression(easy, important); if (easy.typeIs("Grid")) { //printf("I am reusing Grid variable %s!!!\n", i->c_str()); e.EliminateThisSubexpression(easy, *i); EliminateThisSubexpression(easy, *i); fprintf(o, " %s = %s; // We can reuse this variable\n", i->c_str(), easy.printme().c_str()); fprintf(o, " //printf(\"Memory use %x is %%g with peak %%g\\n\", current_memory()/1024.0/1024, peak_memory()/1024.0/1024);\n", counter++); //fprintf(o, " // expr = %s\n", e.printme().c_str()); fflush(o); have_changed = true; } } } for (std::set<std::string>::iterator i = recipvars.begin(); i != recipvars.end(); ++i) { Expression expi = Expression(*i).set_type("ReciprocalGrid"); Expression easy = EasyParentOfThisSubexpression(expi, important); if (easy != expi) { if (!easy.typeIs("ReciprocalGrid")) easy = EasyParentOfThisSubexpression(easy, important); if (easy.typeIs("ReciprocalGrid")) { //printf("I am reusing ReciprocalGrid variable %s!!!\n", i->c_str()); e.EliminateThisSubexpression(easy, *i); EliminateThisSubexpression(easy, *i); fprintf(o, " %s = %s; // We can reuse this variable\n", i->c_str(), easy.printme().c_str()); fprintf(o, " //printf(\"Memory use %x is %%g with peak %%g\\n\", current_memory()/1024.0/1024, peak_memory()/1024.0/1024);\n", counter++); //fprintf(o, " // expr = %s\n", e.printme().c_str()); fflush(o); have_changed = true; } } } // Free any newly unused variables... generate_free_code(o, myvars); for (std::set<std::string>::iterator i = gridvars.begin(); i != gridvars.end(); ++i) if (!FindVariable(*i)) gridvars.erase(i); for (std::set<std::string>::iterator i = recipvars.begin(); i != recipvars.end(); ++i) if (!FindVariable(*i)) recipvars.erase(i); } // Now pick our next subexpression! s = e.FindCommonSubexpression(); //Expression ssmaller = s; //ssmaller.ScalarFactor(); // This is s without any prefactor. // Use the smaller expression if it is more common. //if (e.CountThisSubexpression(ssmaller) > e.CountThisSubexpression(s)) s = ssmaller; // Let's lump in any "cheap" calculations we can get done at the same time! //if (e.CountThisSubexpression(e.EasyParentOfThisSubexpression(s)) >= e.CountThisSubexpression(s)) // s = e.EasyParentOfThisSubexpression(s); } int numvars = 0; for (int i=0; fmt[i]; i++) { if (fmt[i] == '%') numvars++; } if (numvars == 1) fprintf(o, fmt, e.printme().c_str()); else if (numvars == 2) fprintf(o, fmt, e.printme().c_str(), e.printme().c_str()); else { fprintf(o, "Looks like there is trouble here!\n"); fprintf(o, fmt, e.printme().c_str()); } fflush(o); }
/** Return the next variable name and GUID. This function is called multiple times to retrieve the VariableName and VariableGuid of all variables currently available in the system. On each call, the previous results are passed into the interface, and, on return, the interface returns the data for the next interface. When the entire variable list has been returned, EFI_NOT_FOUND is returned. @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName. On return, the size of the variable name buffer. @param VariableName On entry, a pointer to a null-terminated string that is the variable's name. On return, points to the next variable's null-terminated name string. @param VariableGuid On entry, a pointer to an EFI_GUID that is the variable's GUID. On return, a pointer to the next variable's GUID. @retval EFI_SUCCESS The variable was read successfully. @retval EFI_NOT_FOUND The variable could not be found. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting data. VariableNameSize is updated with the size required for the specified variable. @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or VariableNameSize is NULL. @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. **/ EFI_STATUS EFIAPI PeiGetNextVariableName ( IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VariableGuid ) { VARIABLE_STORE_TYPE Type; VARIABLE_POINTER_TRACK Variable; VARIABLE_POINTER_TRACK VariableInHob; VARIABLE_POINTER_TRACK VariablePtrTrack; UINTN VarNameSize; EFI_STATUS Status; VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; VARIABLE_HEADER *VariableHeader; VARIABLE_STORE_INFO StoreInfo; VARIABLE_STORE_INFO StoreInfoForNv; VARIABLE_STORE_INFO StoreInfoForHob; if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) { return EFI_INVALID_PARAMETER; } VariableHeader = NULL; Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { return Status; } if (VariableName[0] != 0) { // // If variable name is not NULL, get next variable // GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); } VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, &StoreInfoForHob); VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, &StoreInfoForNv); while (TRUE) { // // Switch from HOB to Non-Volatile. // while (!GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader)) { // // Find current storage index // for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) { if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) { break; } } ASSERT (Type < VariableStoreTypeMax); // // Switch to next storage // for (Type++; Type < VariableStoreTypeMax; Type++) { if (VariableStoreHeader[Type] != NULL) { break; } } // // Capture the case that // 1. current storage is the last one, or // 2. no further storage // if (Type == VariableStoreTypeMax) { return EFI_NOT_FOUND; } Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]); Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]); Variable.CurrPtr = Variable.StartPtr; GetVariableStore (Type, &StoreInfo); } if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { // // If it is a IN_DELETED_TRANSITION variable, // and there is also a same ADDED one at the same time, // don't return it. // Status = FindVariableEx ( &StoreInfo, GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), &VariablePtrTrack ); if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr != Variable.CurrPtr) { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); continue; } } // // Don't return NV variable when HOB overrides it // if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv])) ) { Status = FindVariableEx ( &StoreInfoForHob, GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), &VariableInHob ); if (!EFI_ERROR (Status)) { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); continue; } } VarNameSize = NameSizeOfVariable (VariableHeader, StoreInfo.AuthFlag); ASSERT (VarNameSize != 0); if (VarNameSize <= *VariableNameSize) { GetVariableNameOrData (&StoreInfo, (UINT8 *) GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), VarNameSize, (UINT8 *) VariableName); CopyMem (VariableGuid, GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), sizeof (EFI_GUID)); Status = EFI_SUCCESS; } else { Status = EFI_BUFFER_TOO_SMALL; } *VariableNameSize = VarNameSize; // // Variable is found // return Status; } else { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); } } }
void CPRApplication::ExecTree(ag::tree<CPRTreeNode*>* T,ag::list<DTVar*>* ExternalVars, char* retname) { try { ag::list<DTVar*> Local; //ag::list<CPRRestoreVarName*> ToRestore; if (ExternalVars!=NULL) { DTVar* q; rpnlist* rl; RPNStackElement* rse; DTVar* dv; for (ag::list<DTVar*>::member m=ExternalVars->head;m!=NULL;m=m->next) { Local.add_tail(m->data); } } OutVarList(&Local); bool was_ret=false; char* sq_s; if (T->data->tntType==tntFunction) {//if it's function, load arguments from stack to Local. search from the end int c=((ag::list<CPRTextDataType>*)(T->data->r1))->count(); int c_k=((DTMain*)(aStack.pop()->T))->toint(); if (c!=c_k) if (debugmode) std::cout<<"(WARNING) Params count is not equally to declaration\n"; ag::list<CPRTextDataType>::member pm=((ag::list<CPRTextDataType>*)(T->data->r1))->head; OutVarList(&Local); ag::list<DTVar*>::member m; for (int i=0;i<c;i++) { OutVarList(&Local); m=Local.add_tail(aStack.pop());// названия OutVarList(&Local); //CPRRestoreVarName* rvn=new CPRRestoreVarName; //rvn->mem=m; //rvn->name=new char[strlen(((DTMain*)(m->data->T))->sIdent)+1]; //strcpy(rvn->name,((DTMain*)(m->data->T))->sIdent); //rvn->name[strlen(rvn->name)]=0; //ToRestore.add_tail(rvn); ((DTMain*)(m->data->T))->sIdent=pm->data.str2; OutVarList(&Local); pm=pm->next; } OutVarList(&Local); std::string sq=T->data->text2; sq+="_result_"; // std::ostringstream si; // si << rand(); // sq+=si.str(); sq_s=new char[sq.size()+1]; strcpy(sq_s,sq.c_str()); sq_s[sq.size()]=0; DTVar* r=ParseDataTypeString(T->data->text,sq_s,NULL,&Local); Local.add_tail(r); }else { sq_s=retname; } OutVarList(&Local); ag::listmember< ag::tree<CPRTreeNode*>* >* p=(*T).childs.head; while (p!=NULL) { switch(p->data->data->tntType) { case tntDeclareVar: { //if (p->data->data->text3) if (debugmode) std::cout<<" : Declarating variable: "<<p->data->data->text<<", "<<p->data->data->text2; if (p->data->data->text3!=NULL) { if (debugmode) std::cout<<" = "<<p->data->data->text3; } if (debugmode) std::cout<<"; regular variable\n"; try { std::string rpnstr; /*rpnstr=p->data->data->text2; rpnstr+="=";*/ rpnstr+=(p->data->data->text3)?p->data->data->text3:""; DTVar* dtv=ParseDataTypeString(p->data->data->text,p->data->data->text2,//p->data->data->text3); NULL, NULL); Local.add_tail(dtv); rpnlist* rls; rls=MakePostfixFromInfix((char*)rpnstr.c_str()); RPNStackElement* rlsel=new RPNStackElement; rlsel->d=p->data->data->text2; rlsel->tp=rsetStr; rls->add_head(rlsel); rlsel=new RPNStackElement; rlsel->d=new char[3]; ((char*)rlsel->d)[0]='='; ((char*)rlsel->d)[1]=' '; ((char*)rlsel->d)[2]=0; rlsel->tp=rsetAct; rls->add_tail(rlsel); OutVarList(&Local); CalculateRPN(rls,&Local); OutVarList(&Local); if (debugmode) std::cout<<"variable was added to Local\n"; if (debugmode) std::cout<<((DTMain*)(dtv->T))->DTFullName()<<"\n"; }catch(char* k) { if (debugmode) std::cout<<"(Error): "<<k<<"\n"; } catch(const char* k) { if (debugmode) std::cout<<"(Error): "<<k<<"\n"; }; //((DTMain*)(dtv->T))->; OutVarList(&Local); break; } case tntDeclareFunc: { break; } case tntFunction: { break; } case tntIF: { ag::stack<DTVar*>* g= CalculateRPN((rpnlist*)p->data->data->r1, &Local); DTMain* if_ex=((DTMain*)(g->pop()->T)); if (if_ex->typeoftype()!=1) { char* qerr=new char[strlen("Result of expression at \"if\" must be integer type!")+1]; strcpy(qerr,"Result of expression at \"if\" must be integer type!"); qerr[strlen("Result of expression at \"if\" must be integer type!")]=0; throw qerr; } CPRTreeNodeType r; if (((DTIntegerTypes*)(if_ex))->toint()) r=tntIFTrue; else r=tntIFFalse; ag::tree<CPRTreeNode*>* call; for(ag::list<ag::tree<CPRTreeNode*>*>::member i=p->data->childs.head;i!=NULL;i=i->next) { if (i->data->data->tntType==r) { call=i->data; break; } } ExecTree(call,&Local,sq_s); break; } case tntWhileLoop: { bool bOk; do { ag::stack<DTVar*>* g= CalculateRPN((rpnlist*)p->data->data->r1, &Local); DTMain* if_ex=((DTMain*)(g->pop()->T)); if (if_ex->typeoftype()!=1) { char* qerr=new char[strlen("Result of expression at \"while\" must be integer type!")+1]; strcpy(qerr,"Result of expression at \"while\" must be integer type!"); qerr[strlen("Result of expression at \"while\" must be integer type!")]=0; throw qerr; } bOk=(((DTIntegerTypes*)(if_ex))->toint()); if (bOk) ExecTree(p->data,&Local,sq_s); }while (bOk); break; } case tntDoWhileLoop: { bool bOk; do { ExecTree(p->data,&Local,sq_s); ag::stack<DTVar*>* g= CalculateRPN((rpnlist*)p->data->data->r1, &Local); DTMain* if_ex=((DTMain*)(g->pop()->T)); if (if_ex->typeoftype()!=1) { char* qerr=new char[strlen("Result of expression at \"while\" must be integer type!")+1]; strcpy(qerr,"Result of expression at \"while\" must be integer type!"); qerr[strlen("Result of expression at \"while\" must be integer type!")]=0; throw qerr; } bOk=(((DTIntegerTypes*)(if_ex))->toint()); }while (bOk); break; } case tntForLoop: { bool bOk; do { ag::stack<DTVar*>* g= CalculateRPN((rpnlist*)p->data->data->r2, &Local); DTMain* if_ex=((DTMain*)(g->pop()->T)); if (if_ex->typeoftype()!=1) { char* qerr=new char[strlen("Result of expression at \"for\" must be integer type!")+1]; strcpy(qerr,"Result of expression at \"for\" must be integer type!"); qerr[strlen("Result of expression at \"for\" must be integer type!")]=0; throw qerr; } bOk=(((DTIntegerTypes*)(if_ex))->toint()); if (bOk) ExecTree(p->data,&Local,sq_s); }while (bOk); break; } case tntExpression: { CalculateRPN((rpnlist*)p->data->data->r1, &Local); break; } case tntReturn: { if (sq_s==NULL) throw "return is not allowed in this context"; ag::stack<DTVar*>* g= CalculateRPN((rpnlist*)p->data->data->r1, &Local); DTVar* ret_var=FindVariable(sq_s,&Local); DTMain* qw=(DTMain*)(g->pop()->T); DTMain* er=(DTMain*)(ret_var->T); CalculateAssignation(er,qw,&Local); aStack.push(ret_var); //if ((DTMain*)(ret_var->T)->typeoftype()==) return; break; } case tntDirective: { DTVar* g; if (debugmode) std::cout<<"#"<<p->data->data->text<<"\n"; CPRParser* pd=new CPRParser(p->data->data->text); pd->Next(); if (strcmp(pd->sCurrText,"pragma")==0) { pd->Next(); if (strcmp(pd->sCurrText,"out")==0) { pd->Next(); char* svar=pd->ReadIdent(); if (debugmode) std::cout<<"out("<<svar<<")\n"; DTVar* x=FindVariable(svar,&Local); if (x!=NULL) { if (debugmode) std::cout<<svar<<" = "<< (((DTMain*)(x->T))->tostring()) <<"\n"; }else { if (debugmode) std::cout<<svar<<" not found!"; } // for(ag::list<DTVar*>::member i=aVars.head;i!=NULL;i=i->next) // { // g=(DTVar*)(i->data); // if (((DTMain*)(g->T))->sIdent==NULL) continue; // if (strcmp((((DTMain*)(g->T))->sIdent),svar)==0) // { // if (debugmode) std::cout<<svar<<" = "<< (((DTMain*)(g->T))->tostring()) <<"\n"; // break; // }; // }; }; }; break; } }; p=p->next; }; if (T->data->tntType==tntFunction) aStack.push(FindVariable(sq_s,&Local)); // for (ag::list<CPRRestoreVarName*>::member m=ToRestore.head;m!=NULL;m=m->next) // { // ((DTMain*)(m->data->mem->data->T))->sIdent=m->data->name; // } }catch(char* k) { if (debugmode) std::cout<<"(Error): "<<k<<"\n"; } catch(const char* k) { if (debugmode) std::cout<<"(Error): "<<k<<"\n"; } }
static void ParseNativeVariable (FScanner &sc, PSymbolTable * symt, PClass *cls) { FExpressionType valuetype; if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { sc.ScriptMessage ("variables can only be imported by internal class and actor definitions!"); FScriptPosition::ErrorCounter++; } // Read the type and make sure it's int or float. sc.MustGetAnyToken(); switch (sc.TokenType) { case TK_Int: valuetype = VAL_Int; break; case TK_Float: valuetype = VAL_Float; break; case TK_Angle_t: valuetype = VAL_Angle; break; case TK_Fixed_t: valuetype = VAL_Fixed; break; case TK_Bool: valuetype = VAL_Bool; break; case TK_Identifier: valuetype = VAL_Object; // Todo: Object type sc.ScriptError("Object type variables not implemented yet!"); break; default: sc.ScriptError("Invalid variable type %s", sc.String); return; } sc.MustGetToken(TK_Identifier); FName symname = sc.String; if (sc.CheckToken('[')) { FxExpression *expr = ParseExpression (sc, cls); int maxelems = expr->EvalExpression(NULL).GetInt(); delete expr; sc.MustGetToken(']'); valuetype.MakeArray(maxelems); } sc.MustGetToken(';'); const FVariableInfo *vi = FindVariable(symname, cls); if (vi == NULL) { sc.ScriptError("Unknown native variable '%s'", symname.GetChars()); } PSymbolVariable *sym = new PSymbolVariable(symname); sym->offset = vi->address; // todo sym->ValueType = valuetype; sym->bUserVar = false; if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } }
int SetVariableValue(char *varName, char operator, char *varValues) { Variable v; char *item; FILE *fd; if ((v = FindVariable(varName)) == NULL) { v = NewVariable(varName); if (v == NULL) { cqpmessage(Error, "Out of memory."); return 0; } } switch (operator) { case '+': /* += operator: extend */ item = strtok(varValues, " \t\n"); while (item) { VariableAddItem(v, item); item = strtok(NULL, " \t\n"); } break; case '-': /* -= operator: substract */ item = strtok(varValues, " \t\n"); while (item) { VariableSubtractItem(v, item); item = strtok(NULL, " \t\n"); } break; case '=': /* = operator: absolute setting */ VariableDeleteItems(v); item = strtok(varValues, " \t\n"); while (item) { VariableAddItem(v, item); item = strtok(NULL, " \t\n"); } break; case '<': /* < operator: read from file */ VariableDeleteItems(v); if ((fd = open_file(varValues, "r"))) { int l; char s[CL_MAX_LINE_LENGTH]; while (fgets(s, CL_MAX_LINE_LENGTH, fd) != NULL) { l = strlen(s); if (l > 0 && s[l-1] == '\n') { /* strip trailing newline */ s[l-1] = '\0'; l--; } if (l > 0) VariableAddItem(v, s); } fclose(fd); } else { perror(varValues); cqpmessage(Warning, "Can't open %s: no such file or directory", varValues); return 0; } break; default: return 0; break; } return 1; }