/* ================ CmdSystemEx::ExecuteCmd ================ */ void CmdSystemEx::ExecuteCmd( const char *buf, bool force ) { if( !buf[0] ) return; char ch[2] = {'\0', '\0'}; StringList list; String temp; bool inquote = false; int i; for ( i=0; buf[i] != '\0'; i++ ) { if ( buf[i] == '\n' || (!inquote && buf[i] == ';') ) { if ( temp.IsEmpty() ) continue; else if ( inquote ) { temp += "\""; inquote = false; } list.Append(temp); temp.Clear(); continue; } if ( buf[i] == '\"' ) inquote = !inquote; ch[0] = buf[i]; temp += ch; } if ( !temp.IsEmpty() ) { if ( inquote ) { temp += "\""; inquote = false; } list.Append(temp); } if ( force ) { int num = list.Num(); for ( i=0; i<num; i++ ) ExecuteSingleCmd( list[i].c_str() ); } else { int num = list.Num(); for ( i=0; i<num; i++ ) cmdQueue.Push( list[i] ); } }
void Complete( const CmdArgs &args, argCompletionCB_t callback ) const { int num, i; StringList fullList; const DictEx<ConsoleCmd> &cmdList = CmdSystemObject.GetCommandList(); num = cmdList.Num(); for( i = 0; i < num; i++ ) fullList.Append( cmdList.GetKey(i) ); const DictEx<CVarDataEx> &cvarDataList = cvarSystemEx->GetCVarDataList(); num = cvarDataList.Num(); for( i = 0; i < num; i++ ) fullList.Append( cvarDataList.GetKey(i) ); fullList.Sort( StringListICmp, true ); num = fullList.Num(); Format complete( "$* $*" ); for( i = 0; i < num; i++ ) { callback( complete << args.Argv( 0 ) << fullList[i] ); complete.Reset(); } }
StringList For::Evaluate(EvaluationContext& context) { // get the loop variable -- we ignore all but the first element of the // variable list const StringList& variables = fVariable->Evaluate(context); if (variables.IsEmpty()) return StringList::False(); // look for a local variable StringList* variableValue = context.LocalScope()->Lookup(variables.Head()); if (variableValue == NULL) { // no local variable -- check for a global one variableValue = context.GlobalVariables()->Lookup(variables.Head()); if (variableValue == NULL) { // no existing global variable either -- create one variableValue = &context.GlobalVariables()->LookupOrCreate( variables.Head()); } } // perform the for loop StringList result; const StringList& list = fList->Evaluate(context); for (StringList::Iterator it = list.GetIterator(); it.HasNext();) { // assign the variable variableValue->Clear(); variableValue->Append(it.Next()); // execute the block result = fBlock->Evaluate(context); // handle jump conditions switch (context.GetJumpCondition()) { case JUMP_CONDITION_NONE: break; case JUMP_CONDITION_BREAK: context.SetJumpCondition(JUMP_CONDITION_NONE); return result; case JUMP_CONDITION_CONTINUE: context.SetJumpCondition(JUMP_CONDITION_NONE); break; case JUMP_CONDITION_RETURN: case JUMP_CONDITION_JUMP_TO_EOF: case JUMP_CONDITION_EXIT: return result; } } return result; }
StringList StringListOperations::Apply(const StringList& inputList, size_t maxSize, const behavior::Behavior& behavior) const { if (!HasOperations()) return inputList.SubList(0, maxSize); uint32_t operations = fOperations; bool hasSelectorOperation = (operations & PATH_PART_SELECTOR_MASK) != 0; bool hasPathPartOperation = hasSelectorOperation || (operations & (PATH_PART_REPLACER_MASK | TO_PARENT_DIRECTORY)) != 0; if (hasPathPartOperation && !hasSelectorOperation) { // Only replacer operations. Continue as if all path parts are selected. operations |= PATH_PART_SELECTOR_MASK; } // If a join shall be performed before to-upper/to-lower, we simply convert // the join parameter first and join as usual afterwards. String joinParameterBuffer; StringPart joinParameter = fJoinParameter; if (!joinParameter.IsEmpty() && (operations & (TO_UPPER | TO_LOWER)) != 0 && behavior.GetJoinCaseOperator() == behavior::Behavior::JOIN_BEFORE_CASE_OPERATOR) { joinParameterBuffer = joinParameter; if ((operations & TO_UPPER) != 0) joinParameterBuffer.ToUpper(); else joinParameterBuffer.ToLower(); joinParameter = joinParameterBuffer; } StringList resultList; StringBuffer buffer; const StringList& list = inputList.IsEmpty() && (operations & REPLACE_EMPTY) != 0 ? StringList(String(fEmptyParameter)) : inputList; size_t count = std::min(list.Size(), maxSize); for (size_t i = 0; i < count; i++) { String string = list.ElementAt(i); size_t bufferSizeBeforeElement = buffer.Length(); // If any of the file name/path part selectors/replacers need to be // applied, we disassemble the string, make the modifications, and // reassemble it. if (hasPathPartOperation) { Path::Parts parts(string); if ((operations & REPLACE_GRIST) != 0) parts.SetGrist(fGristParameter); else if ((operations & SELECT_GRIST) == 0) parts.UnsetGrist(); if ((operations & REPLACE_ROOT) != 0) parts.SetRoot(fRootParameter); else if ((operations & SELECT_ROOT) == 0) parts.UnsetRoot(); if ((operations & REPLACE_DIRECTORY) != 0) parts.SetDirectory(fDirectoryParameter); else if ((operations & SELECT_DIRECTORY) == 0) parts.UnsetDirectory(); if ((operations & REPLACE_BASE_NAME) != 0) parts.SetBaseName(fBaseNameParameter); else if ((operations & SELECT_BASE_NAME) == 0) parts.UnsetBaseName(); if ((operations & REPLACE_SUFFIX) != 0) parts.SetSuffix(fSuffixParameter); else if ((operations & SELECT_SUFFIX) == 0) parts.UnsetSuffix(); if ((operations & REPLACE_ARCHIVE_MEMBER) != 0) parts.SetArchiveMember(fArchiveMemberParameter); else if ((operations & SELECT_ARCHIVE_MEMBER) == 0) parts.UnsetArchiveMember(); if ((operations & TO_PARENT_DIRECTORY) != 0) { parts.UnsetBaseName(); parts.UnsetSuffix(); parts.UnsetArchiveMember(); } parts.GetPath(buffer, behavior); } else buffer += string; if ((operations & TO_UPPER) != 0) { char* toConvert = buffer.Data() + bufferSizeBeforeElement; char* end = buffer.Data() + buffer.Length(); std::transform(toConvert, end, toConvert, ::toupper); } else if ((operations & TO_LOWER) != 0) { char* toConvert = buffer.Data() + bufferSizeBeforeElement; char* end = buffer.Data() + buffer.Length(); std::transform(toConvert, end, toConvert, ::tolower); } if ((operations & JOIN) != 0) { if (i + 1 < count) buffer += joinParameter; } else { resultList.Append(buffer); buffer = StringPart(); } } if ((operations & JOIN) != 0 && count > 0) { // Append the joined value, if we're not emulating the broken behavior // of jam. if (behavior.GetBrokenSubscriptJoin() == behavior::Behavior::NO_BROKEN_SUBSCRIPT_JOIN || count == list.Size()) { resultList.Append(buffer); } } return resultList; }
/* ================ CmdSystemEx::CompleteCmd ================ */ const char *CmdSystemEx::CompleteCmd( const char *buf, argCompletionCB_t callback ) { static String returnBuffer; if ( !buf ) return ""; completionBuffer = buf; completionBuffer.StripLeadingWhitespaces(); if ( completionBuffer.IsEmpty() ) return ""; int bufLen = completionBuffer.Length(); completionList.Clear(); int i; if( completionBuffer.Find(" ") != String::INVALID_POSITION ) { CmdArgs args(buf); OG_ASSERT( args.Argc() > 0 ); // Find the command and call its completion func const char *arg0 = args.Argv(0); i = cmdList.Find( arg0 ); if ( i != -1 ) { if ( cmdList[i].completion ) cmdList[i].completion->Complete(args, CompletionCallback); } else cvarSystemEx->CompleteCVar( args, CompletionCallback ); } else { // Find all commands that start with buf for( i = cmdList.MatchPrefix( buf, bufLen ); i != -1; i = cmdList.MatchPrefix( buf, bufLen, i ) ) completionList.Append( cmdList.GetKey(i) ); // Find all cvars that start with buf cvarSystemEx->CompleteCVar(buf, bufLen, completionList); } if ( completionList.IsEmpty() ) return completionBuffer.c_str(); int numEntries = completionList.Num(); // Only one option, so return it straight if ( numEntries == 1 ) return completionList[0].c_str(); // Convert to lowercase for faster comparison, then strip the input and calculate the shortest length int shortest = 1023; String lowerBuf = completionBuffer; lowerBuf.ToLower(); StringList newList; for( i=0; i<numEntries; i++ ) { newList.Append( completionList[i] ); newList[i].ToLower(); newList[i].StripLeadingOnce(lowerBuf.c_str()); if ( newList[i].Length() < shortest ) shortest = newList[i].Length(); } returnBuffer.Clear(); if ( shortest == 0 ) completionList[0].Left( completionBuffer.Length(), returnBuffer ); else { // Find the first not matching char int pos; const String &firstStr = newList[0]; for( pos=0; pos<shortest; pos++ ) { // Check if all chars at this position match for( i=1; i<numEntries; i++ ) { if ( firstStr.Cmpn( newList[i].c_str(), pos ) != 0 ) break; } // One did not match if ( i < numEntries ) break; } completionList[0].Left( completionBuffer.Length()+pos-1, returnBuffer ); } // Send the list back and print it in the console Console::Print( Format( "]$*\n" ) << returnBuffer ); Format complete( " $*\n" ); for( i=0; i<numEntries; i++ ) { if ( callback ) callback( completionList[i].c_str() ); Console::Print( complete << completionList[i] ); complete.Reset(); } return returnBuffer.c_str(); }