// SPDX-License-Identifier: MIT
#include "Generator.hh"
#include <algorithm>
#include <cctype>
#include <iterator>
#include <map>
#include <sstream>
#include <utility>
using namespace ::std;
namespace fedem
{
namespace parser
{
Generator::Generator( )
{
// blank
}
Generator::~Generator( ) = default;
string Generator::generateFilename( string const& base, string const& ext ) const noexcept
{
return convertUpperCaseCamel( base ) + convertLowerCase( ext );
}
string Generator::generateHeaderGuard( string const& header ) const noexcept
{
string guard = getNamespacePath( );
if( ! guard.empty( ) )
{
guard.append( 1, '/' );
}
guard.append( header );
guard = replaceNonAlphanums( convertUpperCase( guard ), '_' );
auto pos = guard.find( "__" );
while( pos != string::npos )
{
guard.erase( pos, 1 );
pos = guard.find( "__" );
}
while ( !guard.empty() && guard[0] == '_' )
{
guard.erase( 0, 1 );
}
return guard;
}
string Generator::convertLowerCase( string const& base ) const noexcept
{
string str;
transform( base.begin( ), base.end( ),
back_inserter( str ),
[]( unsigned char c )
{ return tolower( c ); } );
return str;
}
string Generator::convertUpperCase( string const& base ) const noexcept
{
string str;
transform( base.begin( ), base.end( ),
back_inserter( str ),
[]( unsigned char c )
{ return toupper( c ); } );
return str;
}
string Generator::convertUpperCaseCamel( string const& base ) const noexcept
{
string str;
auto sourcePos = base.cbegin( );
bool capital = true;
while( sourcePos != base.cend( ) )
{
if( *sourcePos == '_' || *sourcePos == ' ' )
{
capital = true;
}
else
{
if( capital )
{
str.append( 1, static_cast< char >( toupper( static_cast< unsigned char >( *sourcePos ) ) ) );
}
else
{
str.append( 1, static_cast< char >( tolower( static_cast< unsigned char >( *sourcePos ) ) ) );
}
capital = false;
}
++sourcePos;
}
return str;
}
string Generator::convertLowerCaseCamel( string const& base ) const noexcept
{
string str = convertUpperCaseCamel( base );
if( ! str.empty( ) )
{
str[ 0 ] = static_cast< char >( tolower( static_cast< unsigned char >( str[ 0 ] ) ) );
}
return str;
}
string Generator::replaceNonAlphanums( string const& base, string::value_type const rch ) const noexcept
{
string str;
transform( base.begin( ), base.end( ),
back_inserter( str ),
[ rch ]( unsigned char c )
{ return isalnum( c ) ? c : static_cast< unsigned char >( rch ); } );
return str;
}
string Generator::removeNonAlphanums( string const& base ) const noexcept
{
string str;
copy_if( base.begin( ), base.end( ),
back_inserter( str ),
[]( unsigned char c )
{ return isalnum( c ); } );
return str;
}
string Generator::encodeCppString( string str ) noexcept
{
string rstr;
map< string::value_type, string > encodeMap {
{ '\a', "\\a" },
{ '\n', "\\n" },
{ '\r', "\\r" },
{ '\t', "\\t" },
{ '\v', "\\v" },
{ '\\', "\\\\" },
{ '\'', "\\\'" },
{ '\"', "\\\"" },
{ '\0', "\\0" }
};
for( auto const& chr : str )
{
auto pos = encodeMap.find( chr );
if( pos != encodeMap.end( ) )
{
rstr.append( pos->second );
}
else if( ! isprint( static_cast< unsigned char >( chr ) ) )
{
ostringstream convert;
convert.width( 3 );
convert.fill( '0' );
convert << oct << static_cast< unsigned int >( static_cast< unsigned char >( chr ) );
rstr.append( convert.str( ) );
}
else
{
rstr.append( 1, chr );
}
}
return rstr;
}
} // namespace parser
} // namespace fedem