// // StdParse::ParseStringVNode // // Parses a string VNode, NULL if error // VNode* StdParse::ParseStringVNode(TBuf *tBuf) { // Allow empty strings Bool empty = FALSE; // Store string delimiter char delim[2]; // Accept the start of the string literal tBuf->NextToken(); // Insert string delimiter delim[0] = *tBuf->lastToken; // Insert null terminator delim[1] = '\0'; // Start reading the string constant tBuf->ReadConstant(*delim); // Read in string switch (tBuf->NextToken()) { // Copy string, then accept closing symbol case TR_OK: tBuf->Accept(delim); break; // Must have been an empty string case TR_PUN: tBuf->Expect(delim); empty = TRUE; break; // This should be caught in tBuf case TR_EOF: ERR_FATAL(("Unexpected return code")); default: ERR_FATAL(("Missing case")); } // Create the new VNode VNode *newNode = new VNode; newNode->SetupString(empty ? "" : tBuf->prevToken); return (newNode); }
// // ParseAssignment // // Parse an item value assignment // Bool CmdParse::ParseAssignment(void *context, VarSys::VarItem *item) { ASSERT(item); // Peek at the next token switch (tBuf.PeekToken()) { case TR_OK: break; case TR_PUN: { switch (*tBuf.peekToken) { case '=': tBuf.AcceptPunct(); break; case ';': return (FALSE); break; } break; } case TR_EOF: return (FALSE); break; default: ERR_FATAL(("Missing case")); } // Allow editing in a development build #ifdef DEVELOPMENT // But give a warning if (item->flags & VarSys::NOEDIT) { CON_ERR(("Warning! Can not be modified in a release build")) } #else // Check that this item can be edited from the console if (item->flags & VarSys::NOEDIT) { tBuf.TokenError("This item can not be modified"); } #endif VNode *node; // See if we are assigning one var to another if (ParseVarAssignment(context, item)) { return (TRUE); } // Parse the VNode data if ((node = StdParse::ParseAtomicVNode(&tBuf)) == NULL) { // Convert a single identifier to a string value if (tBuf.PeekToken() == TR_OK) { tBuf.AcceptIdent(); node = new VNode; node->SetupString(tBuf.lastToken); } else { tBuf.TokenError("Invalid value"); } } // Assign the new value switch (item->type) { // Changing an integer item case VarSys::VI_INTEGER: switch (node->aType) { case VNode::AT_INTEGER: item->SetInteger(node->GetInteger()); break; case VNode::AT_FPOINT: item->SetInteger((S32)node->GetFPoint()); break; default: delete node; tBuf.TokenError("Expected %s value", VarSys::GetTypeString(item->type)); } break; // Changing a floating point item case VarSys::VI_FPOINT: switch (node->aType) { case VNode::AT_INTEGER: item->SetFloat((F32)node->GetInteger()); break; case VNode::AT_FPOINT: item->SetFloat(node->GetFPoint()); break; default: delete node; tBuf.TokenError("Expected %s value", VarSys::GetTypeString(item->type)); } break; // Changing a string item case VarSys::VI_STRING: switch (node->aType) { case VNode::AT_STRING: item->SetStr(node->GetString()); break; default: delete node; tBuf.TokenError("Expected %s value", VarSys::GetTypeString(item->type)); } break; // Unable to change this type of item default : delete node; tBuf.TokenError("Unable to modify items of this type"); } // Delete the temporary VNode delete node; // Success return (TRUE); }