Code View

cparse / cparse-1.3.0.2 / src / cparse / Generator.cpp
// 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