colobot/src/CBot/stdlib/StringFunctions.cpp

297 lines
8.9 KiB
C++
Raw Normal View History

/*
* This file is part of the Colobot: Gold Edition source code
2016-02-13 13:11:30 +00:00
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
2015-08-22 14:40:02 +00:00
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
2012-08-08 00:01:06 +00:00
#include "CBot/stdlib/stdlib.h"
#include "CBot/CBot.h"
#include "CBot/CBotUtils.h"
2012-08-08 00:01:06 +00:00
#include <boost/algorithm/string.hpp>
2015-12-26 13:19:24 +00:00
namespace CBot
{
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrLen( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// no second parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ) { ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts the length of the stack
pResult->SetValInt( s.length() );
2012-08-08 20:35:17 +00:00
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// it takes a second parameter
2012-08-11 18:59:35 +00:00
pVar = pVar->GetNext();
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// which must be a number
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() > CBotTypDouble ) { ex = CBotErrBadNum ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// retrieves this number
2012-08-11 18:59:35 +00:00
int n = pVar->GetValInt();
2012-08-08 00:01:06 +00:00
if (n > static_cast<int>(s.length())) n = s.length();
if (n < 0) n = 0;
2012-08-08 20:35:17 +00:00
// no third parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ) { ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// takes the interesting part
s = s.substr(0, n);
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts on the stack
pResult->SetValString( s );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrRight( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// it takes a second parameter
2012-08-11 18:59:35 +00:00
pVar = pVar->GetNext();
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// which must be a number
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() > CBotTypDouble ) { ex = CBotErrBadNum ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// retrieves this number
2012-08-11 18:59:35 +00:00
int n = pVar->GetValInt();
2012-08-08 00:01:06 +00:00
if (n > static_cast<int>(s.length())) n = s.length();
if (n < 0) n = 0;
2012-08-08 20:35:17 +00:00
// no third parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ) { ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// takes the interesting part
s = s.substr(s.length()-n, std::string::npos);
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts on the stack
pResult->SetValString( s );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrMid( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 20:35:17 +00:00
// it takes a second parameter
2012-08-11 18:59:35 +00:00
pVar = pVar->GetNext();
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 20:35:17 +00:00
// which must be a number
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() > CBotTypDouble ) { ex = CBotErrBadNum ; return true; }
2012-08-08 20:35:17 +00:00
// retrieves this number
2012-08-11 18:59:35 +00:00
int n = pVar->GetValInt();
2012-08-08 20:35:17 +00:00
if (n > static_cast<int>(s.length())) n = s.length();
if (n < 0) n = 0;
2012-08-08 20:35:17 +00:00
// third parameter optional
2015-08-16 10:43:42 +00:00
if ( pVar->GetNext() != nullptr )
2012-08-08 20:35:17 +00:00
{
2012-08-11 18:59:35 +00:00
pVar = pVar->GetNext();
2012-08-08 20:35:17 +00:00
// which must be a number
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() > CBotTypDouble ) { ex = CBotErrBadNum ; return true; }
2012-08-08 20:35:17 +00:00
// retrieves this number
2012-08-11 18:59:35 +00:00
int l = pVar->GetValInt();
2012-08-08 20:35:17 +00:00
if (l > static_cast<int>(s.length())) l = s.length();
if (l < 0) l = 0;
2012-08-08 20:35:17 +00:00
// but no fourth parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ){ ex = CBotErrOverParam ; return true; }
2012-08-08 20:35:17 +00:00
// takes the interesting part
s = s.substr(n, l);
2012-08-08 20:35:17 +00:00
}
else
{
// takes the interesting part
s = s.substr(n);
2012-08-08 20:35:17 +00:00
}
// puts on the stack
pResult->SetValString( s );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// but no second parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ){ ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-11 18:59:35 +00:00
float val = GetNumFloat(s);
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts the value on the stack
pResult->SetValFloat( val );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// it takes a second parameter
2012-08-11 18:59:35 +00:00
pVar = pVar->GetNext();
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// retrieves this number
std::string s2 = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// no third parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ) { ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts the result on the stack
std::size_t res = s.find(s2);
pResult->SetValInt( res != std::string::npos ? res : -1 );
if ( res < 0 ) pResult->SetInit( CBotVar::InitType::IS_NAN );
2012-08-08 20:35:17 +00:00
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrUpper( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// but no second parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ){ ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
boost::to_upper(s);
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts the value on the stack
pResult->SetValString( s );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
bool rStrLower( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
{
2012-08-08 20:35:17 +00:00
// it takes a parameter
2015-12-20 18:01:03 +00:00
if ( pVar == nullptr ) { ex = CBotErrLowParam ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// to be a string
2015-12-20 18:01:03 +00:00
if ( pVar->GetType() != CBotTypString ) { ex = CBotErrBadString ; return true; }
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// get the contents of the string
std::string s = pVar->GetValString();
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// but no second parameter
2015-12-20 18:01:03 +00:00
if ( pVar->GetNext() != nullptr ){ ex = CBotErrOverParam ; return true; }
2012-08-08 00:01:06 +00:00
boost::to_lower(s);
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
// puts the value on the stack
pResult->SetValString( s );
return true;
2012-08-08 00:01:06 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2012-08-08 00:01:06 +00:00
void InitStringFunctions()
{
2012-08-08 20:35:17 +00:00
CBotProgram::AddFunction("strlen", rStrLen, cIntStr );
CBotProgram::AddFunction("strleft", rStrLeft, cStrStrInt );
CBotProgram::AddFunction("strright", rStrRight, cStrStrInt );
CBotProgram::AddFunction("strmid", rStrMid, cStrStrIntInt );
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
CBotProgram::AddFunction("strval", rStrVal, cFloatStr );
CBotProgram::AddFunction("strfind", rStrFind, cIntStrStr );
2012-08-08 00:01:06 +00:00
2012-08-08 20:35:17 +00:00
CBotProgram::AddFunction("strupper", rStrUpper, cStrStr );
CBotProgram::AddFunction("strlower", rStrLower, cStrStr );
2012-08-08 00:01:06 +00:00
}
2015-12-26 13:19:24 +00:00
} // namespace CBot