P4MergeData::P4MergeData( lua_State *_L, ClientUser *ui, ClientMerge *m, StrPtr &hint ) { this->L = _L; this->debug = 0; this->ui = ui; this->merger = m; this->hint = hint; // Extract (forcibly) the paths from the RPC buffer. StrPtr *t; if( ( t = ui->varList->GetVar( "baseName" ) ) ) base = t->Text(); if( ( t = ui->varList->GetVar( "yourName" ) ) ) yours = t->Text(); if( ( t = ui->varList->GetVar( "theirName" ) ) ) theirs = t->Text(); }
void SubmitCommand::OutputStat( StrDict* dict ) { if ( m_Changeset == NULL ) { return; } StrPtr* submittedChange = dict->GetVar( g_SubmittedChangeTag ); if ( submittedChange ) { m_Changeset->m_Id = submittedChange->Atoi(); } uint32_t numFiles = 0; StrPtr* openFiles = dict->GetVar( g_OpenFilesTag ); if ( openFiles ) { numFiles = openFiles->Atoi(); } for( uint32_t i = 0; i < numFiles; ++i ) { RCS::FilePtr file = new RCS::File(); StrPtr* depotFile = dict->GetVar( g_DepotFileTag, i ); if ( depotFile ) { bool converted = Helium::ConvertString( depotFile->Text(), file->m_DepotPath ); HELIUM_ASSERT( converted ); } StrPtr* revision = dict->GetVar( g_RevisionTag ); if ( revision ) { file->m_LocalRevision = revision->Atoi(); } StrPtr* action = dict->GetVar( g_ActionTag ); if ( action ) { tstring actionString; bool converted = Helium::ConvertString( action->Text(), actionString ); HELIUM_ASSERT( converted ); file->m_Operation = GetOperationEnum( actionString ); } } }
// Entering password void Prompt( const StrPtr &msg, StrBuf &buf, int noEcho ,Error *e ) { Conn().Log().Info() << "Prompted for password by server" << Endl; Conn().Log().Debug() << "Prompt: " << msg.Text() << Endl; buf.Set(m_Password.c_str()); Conn().VerboseLine("Prompted for password"); }
void CCmd_Password::OnPrompt( const StrPtr &msg, StrBuf &rsp, int noEcho, Error *e ) { CString message = CharToCString(msg.Text()); CString *csp; csp = (message.Find(_T("old")) != -1) ? &m_OldPwd : &m_NewPwd; rsp.Set(CharFromCString(*csp)); }
/* * In a script we don't really want the user to see a prompt, so we * (ab)use the SetInput() function to allow the caller to supply the * answer before the question is asked. */ void ClientUserLua::Prompt( const StrPtr &msg, StrBuf &rsp, int noEcho, Error *e ) { if ( P4LUADEBUG_CALLS ) fprintf( stderr, "[P4] Prompt(): %s\n", msg.Text() ); InputData( &rsp, e ); }
virtual void VRemoveVar(const StrPtr& var) override { auto found = stats_.find(var.Text()); if (found != stats_.end()) { stats_.erase(found); } }
// // Gets a protocol value // int P4ClientAPI::GetProtocol( const char * var ) { StrPtr *pv = client.GetProtocol( var ); if ( pv ) { lua_pushstring( L, pv->Text() ); return 1; } return 0; }
/* * In a script we don't really want the user to see a prompt, so we * (ab)use P4.input= to allow the caller to supply the * answer before the question is asked. */ void PythonClientUser::Prompt( const StrPtr &msg, StrBuf &rsp, int noEcho, Error *e ) { EnsurePythonLock guard; if ( P4PYDBG_CALLS ) cerr << "[P4] Prompt(): " << msg.Text() << endl; InputData( &rsp, e ); }
void ClientUserLua::InputData( StrBuf *strbuf, Error *e ) { if ( P4LUADEBUG_CALLS ) fprintf( stderr, "[P4] InputData(). Using supplied input\n" ); lua_rawgeti( L, LUA_REGISTRYINDEX, inputRef ); // input // Is it an array? if (lua_type( L, -1 ) == LUA_TTABLE ) { lua_rawgeti( L, -1, 1 ); // input input[1] if ( !lua_isnil( L, -1 ) ) { lua_getglobal( L, "table" ); // input input[1] table lua_getfield( L, -1, "remove" ); // input input[1] table remove lua_pushvalue( L, -4 ); // input input[1] table remove input lua_pushnumber( L, 1 ); // input input[1] table remove input 1 lua_call( L, 2, 0 ); // input input[1] table lua_pop( L, 1 ); // input input[1] } else { lua_pop( L, 1 ); } } if ( lua_isnil( L, -1 ) ) { // rb_warn( "[P4] Expected user input, found none. " // "Missing call to P4#input()?" ); lua_pop( L, 2 ); return; } if ( lua_istable( L, -1 ) ) { StrPtr * specDef = varList->GetVar( "specdef" ); specMgr->AddSpecDef( cmd.Text(), specDef->Text() ); specMgr->SpecToString( cmd.Text(), lua_gettop( L ), *strbuf, e ); return; } // Convert whatever's left into a string strbuf->Set( lua_tostring( L, -1 ) ); }
void PythonClientUser::InputData( StrBuf *strbuf, Error *e ) { EnsurePythonLock guard; if ( P4PYDBG_CALLS ) cerr << "[P4] InputData(). Using supplied input" << endl; PyObject * inval = input; if( PyTuple_Check(input) ) { inval = PyTuple_GetItem(input, 0); input = PyTuple_GetSlice(input, 1, PyTuple_Size(input)); } else if ( PyList_Check(input) ) { inval = PyList_GetItem(input, 0); input = PyList_GetSlice(input, 1, PyList_Size(input)); } if( inval == Py_None ) { PyErr_WarnEx( PyExc_UserWarning, "[P4] Expected user input, found none. " "Missing call to P4.input ?", 1 ); return; } if ( PyDict_Check( inval ) ) { StrPtr * specDef = varList->GetVar( "specdef" ); specMgr->AddSpecDef( cmd.Text(), specDef->Text() ); specMgr->SpecToString( cmd.Text(), inval, *strbuf, e ); return; } // Convert whatever's left into a string PyObject * str = PyObject_Str(inval); strbuf->Set( GetPythonString(str) ); Py_XDECREF(str); }
void P4Command::Prompt( const StrPtr &msg, StrBuf &buf, int noEcho ,Error *e ) { Conn().VerboseLine("Prompting..."); Conn().Log().Info() << "Default ClientUser Prompt(" << msg.Text() << ")\n"; }
void ClientUserLua::OutputStat( StrDict *values ) { StrPtr * spec = values->GetVar( "specdef" ); StrPtr * data = values->GetVar( "data" ); StrPtr * sf = values->GetVar( "specFormatted" ); StrDict * dict = values; SpecDataTable specData; Error e; // // Determine whether or not the data we've got contains a spec in one form // or another. 2000.1 -> 2005.1 servers supplied the form in a data variable // and we use the spec variable to parse the form. 2005.2 and later servers // supply the spec ready-parsed but set the 'specFormatted' variable to tell // the client what's going on. Either way, we need the specdef variable set // to enable spec parsing. // int isspec = spec && ( sf || data ); // // Save the spec definition for later // if( spec ) specMgr->AddSpecDef( cmd.Text(), spec->Text() ); // // Parse any form supplied in the 'data' variable and convert it into a // dictionary. // if( spec && data ) { // 2000.1 -> 2005.1 server's handle tagged form output by supplying the form // as text in the 'data' variable. We need to convert it to a dictionary // using the supplied spec. if( P4LUADEBUG_CALLS ) fprintf( stderr, "[P4] OutputStat() - parsing form\n" ); // Parse the form. Use the ParseNoValid() interface to prevent // errors caused by the use of invalid defaults for select items in // jobspecs. //#if P4APIVER_ID >= 513538 Spec s( spec->Text(), "", &e ); //#else //Spec s( spec->Text(), "" ); //#endif if( !e.Test() ) s.ParseNoValid( data->Text(), &specData, &e ); if( e.Test() ) { HandleError( &e ); return; } dict = specData.Dict(); } // // If what we've got is a parsed form, then we'll convert it to a P4::Spec // object. Otherwise it's a plain hash. // if( isspec ) { if( P4LUADEBUG_CALLS ) fprintf(stderr ,"[P4] OutputStat() - Converting to P4::Spec object\n"); results.AddOutput( specMgr->StrDictToSpec( dict, spec ) ); lua_pop( L, 1 ); } else { if( P4LUADEBUG_CALLS ) fprintf(stderr ,"[P4] OutputStat() - Converting to hash\n"); results.AddOutput( specMgr->StrDictToHash( dict ) ); lua_pop( L, 1 ); } }
void FStatCommand::OutputStat( StrDict *dict ) { HELIUM_ASSERT_MSG( m_File, ("No file info object to store file information to") ); if ( m_File->m_FileData & RCS::FileData::State ) { // file necessarily exists in the depot to have gotten here m_File->m_State |= RCS::FileStates::ExistsInDepot; } if ( m_File->m_FileData & RCS::FileData::DepotPath ) { bool converted = Helium::ConvertString( dict->GetVar( g_DepotFileTag )->Text(), m_File->m_DepotPath ); HELIUM_ASSERT( converted ); } if ( m_File->m_FileData & RCS::FileData::LocalPath ) { if ( dict->GetVar( g_ClientFileTag ) ) { bool converted = Helium::ConvertString( dict->GetVar( g_ClientFileTag )->Text(), m_File->m_LocalPath ); HELIUM_ASSERT( converted ); } } if ( m_File->m_FileData & RCS::FileData::Username ) { StrPtr* username = dict->GetVar( g_ActionOwnerTag ); if ( username ) { bool converted = Helium::ConvertString( username->Text(), m_File->m_Username ); HELIUM_ASSERT( converted ); } } if ( m_File->m_FileData & RCS::FileData::ChangesetId ) { StrPtr* changelist = dict->GetVar( g_ChangeTag ); if ( changelist ) { m_File->m_ChangesetId = changelist->Atoi(); if ( m_File->m_ChangesetId == 0 ) { m_File->m_ChangesetId = RCS::DefaultChangesetId; } } } if ( m_File->m_FileData & RCS::FileData::Operation ) { StrPtr* action = dict->GetVar( g_ActionTag ); if ( action ) { tstring actionString; bool converted = Helium::ConvertString( action->Text(), actionString ); HELIUM_ASSERT( converted ); m_File->m_Operation = GetOperationEnum( actionString ); if ( m_File->m_FileData & RCS::FileData::State ) { m_File->m_State |= RCS::FileStates::CheckedOutByMe; if ( m_File->m_Operation == RCS::Operations::Delete ) { m_File->m_State |= RCS::FileStates::LocalDeleted; } } } } if ( m_File->m_FileData & RCS::FileData::Actions && m_File->m_ActionData ) { StrPtr* otherOpen = dict->GetVar( g_OtherOpenTag ); if ( otherOpen ) { if ( m_File->m_FileData & RCS::FileData::State ) { m_File->m_State |= RCS::FileStates::CheckedOut; } int totalOpens = otherOpen->Atoi(); m_File->m_Actions.reserve( totalOpens ); for ( int i = 0; i < totalOpens; ++i ) { RCS::ActionPtr action = new RCS::Action( m_File->m_ActionData ); if ( action->m_ActionData & RCS::ActionData::Username || action->m_ActionData & RCS::ActionData::Client ) { StrPtr* userInfo = dict->GetVar( g_OtherOpenTag, i ); if ( userInfo != NULL ) { tstring otherUserInfo; bool converted = Helium::ConvertString( userInfo->Text(), otherUserInfo ); HELIUM_ASSERT( converted ); size_t atLocation = otherUserInfo.find( TXT( "@" ) ); if ( action->m_ActionData & RCS::ActionData::Username ) { action->m_Username = otherUserInfo.substr( 0, atLocation ); } if ( action->m_ActionData & RCS::ActionData::Client ) { action->m_Client = otherUserInfo.substr( atLocation + 1 ); } } } if ( action->m_ActionData & RCS::ActionData::ChangesetId ) { StrPtr* changeInfo = dict->GetVar( g_OtherChangeTag, i ); if ( changeInfo ) { action->m_ChangesetId = changeInfo->Atoi(); if ( action->m_ChangesetId == 0 ) { action->m_ChangesetId = RCS::DefaultChangesetId; } } } if ( action->m_ActionData & RCS::ActionData::Operation ) { StrPtr* actionInfo = dict->GetVar( g_OtherActionTag, i ); if ( actionInfo ) { tstring actionString; bool converted = Helium::ConvertString( actionInfo->Text(), actionString ); HELIUM_ASSERT( converted ); action->m_Operation = GetOperationEnum( actionString ); } } m_File->m_Actions.push_back( action ); } } } if ( m_File->m_Operation == RCS::Operations::Add ) { tstring fileType; bool converted = Helium::ConvertString( dict->GetVar( g_TypeTag )->Text(), fileType ); HELIUM_ASSERT( converted ); if ( m_File->m_FileData & RCS::FileData::FileType ) { m_File->m_FileType = GetFileType( fileType ); } if ( m_File->m_FileData & RCS::FileData::Flags ) { SetFlags( fileType, m_File ); } return; // out of info at this point } if ( m_File->m_FileData & RCS::FileData::LocalRevision ) { StrPtr* haveRev = dict->GetVar( g_HaveRevTag ); if ( haveRev ) { m_File->m_LocalRevision = haveRev->Atoi(); } } // If a file is deleted at head, it does not have a digest or size if ( m_File->m_FileData & RCS::FileData::Digest || m_File->m_FileData & RCS::FileData::Size ) { StrPtr* headAction = dict->GetVar( g_HeadActionTag ); if ( headAction ) { tstring actionString; bool converted = Helium::ConvertString( headAction->Text(), actionString ); HELIUM_ASSERT( converted ); if ( GetOperationEnum( actionString ) == RCS::Operations::Delete ) { if ( m_File->m_FileData & RCS::FileData::State ) { m_File->m_State |= RCS::FileStates::HeadDeleted; } } else { if ( m_File->m_FileData & RCS::FileData::Digest ) { StrPtr* digest = dict->GetVar( g_DigestTag ); if ( digest ) { bool converted = Helium::ConvertString( digest->Text(), m_File->m_Digest ); HELIUM_ASSERT( converted ); } } if ( m_File->m_FileData & RCS::FileData::Digest ) { StrPtr* size = dict->GetVar( g_FileSizeTag ); if ( size ) { m_File->m_Size = (u64) size->Atoi64(); } } } } } if ( m_File->m_FileData & RCS::FileData::FileType || m_File->m_FileData & RCS::FileData::Flags ) { StrPtr* headType = dict->GetVar( g_HeadTypeTag ); if ( headType ) { tstring fileType; bool converted = Helium::ConvertString( headType->Text(), fileType ); HELIUM_ASSERT( converted ); if ( m_File->m_FileData & RCS::FileData::FileType) { m_File->m_FileType = GetFileType( fileType ); } if ( m_File->m_FileData & RCS::FileData::Flags ) { SetFlags( fileType, m_File ); } } } if ( m_File->m_FileData & RCS::FileData::HeadModTime ) { StrPtr* headModTime = dict->GetVar( g_HeadModTimeTag ); if ( headModTime ) { m_File->m_HeadModTime = headModTime->Atoi(); } } if ( m_File->m_FileData & RCS::FileData::HeadRevision ) { StrPtr* headRevTag = dict->GetVar( g_HeadRevTag ); if ( headRevTag ) { m_File->m_HeadRevision = headRevTag->Atoi(); } } if ( m_File->m_FileData & RCS::FileData::HeadTime ) { StrPtr* headTimeTag = dict->GetVar( g_HeadTimeTag ); if ( headTimeTag ) { m_File->m_HeadTime = headTimeTag->Atoi(); } } }
void FileLogCommand::OutputStat( StrDict *dict ) { StrPtr* latestRevision = dict->GetVar( g_RevisionTag, 0 ); if ( latestRevision ) { u32 numRevisions = latestRevision->Atoi(); for( u32 i = 0; i < numRevisions; ++i ) { RCS::Revision* revision = new RCS::Revision(); revision->m_Revision = dict->GetVar( g_RevisionTag, i )->Atoi(); revision->m_ChangesetId = dict->GetVar( g_ChangeTag, i )->Atoi(); tstring actionString; bool converted = Helium::ConvertString( dict->GetVar( g_ActionTag, i )->Text(), actionString ); HELIUM_ASSERT( converted ); revision->m_Operation = GetOperationEnum( actionString ); tstring fileType; converted = Helium::ConvertString( dict->GetVar( g_TypeTag, i )->Text(), fileType ); HELIUM_ASSERT( converted ); revision->m_FileType = GetFileType( fileType ); revision->m_Time = (time_t) dict->GetVar( g_TimeTag, i )->Atoi(); converted = Helium::ConvertString( dict->GetVar( g_UserTag, i )->Text(), revision->m_Username ); HELIUM_ASSERT( converted ); converted = Helium::ConvertString( dict->GetVar( g_ClientTag, i )->Text(), revision->m_Client ); HELIUM_ASSERT( converted ); // This should not happen, but it has happened before when "move/delete" was added // to Perforce's vocabulary without our knowledge. HELIUM_ASSERT( revision->m_Operation != RCS::Operations::Unknown ); if ( revision->m_Operation != RCS::Operations::Delete && revision->m_Operation != RCS::Operations::Unknown ) { revision->m_Size = dict->GetVar( g_FileSizeTag, i )->Atoi64(); converted = Helium::ConvertString( dict->GetVar( g_DigestTag, i )->Text(), revision->m_Digest ); HELIUM_ASSERT( converted ); } converted = Helium::ConvertString( dict->GetVar( g_DescriptionTag, i )->Text(), revision->m_Description ); HELIUM_ASSERT( converted ); for ( u32 target = 0; target < PERFORCE_MAX_DICT_ENTRIES; ++target ) { StrPtr* how = dict->GetVar( g_HowTag, i, target ); if ( !how ) { break; } // Integration Actions // http://www.perforce.com/perforce/doc.current/manuals/cmdref/integrated.html if ( ( std::string( how->Text() ) == "branch into" ) || ( std::string( how->Text() ) == "add into" ) ) { RCS::File* targetInfo = new RCS::File(); converted = Helium::ConvertString( dict->GetVar( g_FileTag, i, target )->Text(), targetInfo->m_DepotPath ); HELIUM_ASSERT( converted ); revision->m_IntegrationTargets.push_back( targetInfo ); } else if ( ( std::string( how->Text() ) == "branch from" ) ) { RCS::File* targetInfo = new RCS::File(); converted = Helium::ConvertString( dict->GetVar( g_FileTag, i, target )->Text(), targetInfo->m_DepotPath ); HELIUM_ASSERT( converted ); revision->m_IntegrationOrigins.push_back( targetInfo ); } } m_File->m_Revisions.push_back( revision ); } } }
virtual void VSetVar(const StrPtr& var, const StrPtr& val) override { stats_[var.Text()] = val; }
void PythonClientUser::OutputStat( StrDict *values ) { EnsurePythonLock guard; StrPtr * spec = values->GetVar( "specdef" ); StrPtr * data = values->GetVar( "data" ); StrPtr * sf = values->GetVar( "specFormatted" ); StrDict * dict = values; SpecDataTable specData; Error e; // // Determine whether or not the data we've got contains a spec in one form // or another. 2000.1 -> 2005.1 servers supplied the form in a data variable // and we use the spec variable to parse the form. 2005.2 and later servers // supply the spec ready-parsed but set the 'specFormatted' variable to tell // the client what's going on. Either way, we need the specdef variable set // to enable spec parsing. // int isspec = spec && ( sf || data ); // // Save the spec definition for later // if( spec ) specMgr->AddSpecDef( cmd.Text(), spec->Text() ); // // Parse any form supplied in the 'data' variable and convert it into a // dictionary. // if( spec && data ) { // 2000.1 -> 2005.1 server's handle tagged form output by supplying the form // as text in the 'data' variable. We need to convert it to a dictionary // using the supplied spec. if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - parsing form" << endl; // Parse the form. Use the ParseNoValid() interface to prevent // errors caused by the use of invalid defaults for select items in // jobspecs. Spec s( spec->Text(), "", &e ); if( !e.Test() ) s.ParseNoValid( data->Text(), &specData, &e ); if( e.Test() ) { HandleError( &e ); return; } dict = specData.Dict(); } // // If what we've got is a parsed form, then we'll convert it to a P4::Spec // object. Otherwise it's a plain dict. // PyObject * r = 0; if( isspec ) { if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - Converting to P4::Spec object" << endl; r = specMgr->StrDictToSpec( dict, spec ); } else { if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - Converting to dict" << endl; r = specMgr->StrDictToDict( dict ); } ProcessOutput("outputStat", r ); }