diff options
Diffstat (limited to 'utils/idftools/idf_helpers.cpp')
-rw-r--r-- | utils/idftools/idf_helpers.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/utils/idftools/idf_helpers.cpp b/utils/idftools/idf_helpers.cpp new file mode 100644 index 0000000..cad1852 --- /dev/null +++ b/utils/idftools/idf_helpers.cpp @@ -0,0 +1,323 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 Cirilo Bernardo + * + * 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 2 + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <cctype> +#include <iostream> +#include <sstream> + +#include <idf_common.h> +#include <idf_helpers.h> + +using namespace std; +using namespace IDF3; + +// fetch a line from the given input file and trim the ends +bool IDF3::FetchIDFLine( std::ifstream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos ) +{ + aLine = ""; + aFilePos = aModel.tellg(); + + if( aFilePos == -1 ) + return false; + + std::getline( aModel, aLine ); + + isComment = false; + + // A comment begins with a '#' and must be the first character on the line + if( aLine[0] == '#' ) + { + // opening '#' is stripped + isComment = true; + aLine.erase( aLine.begin() ); + } + + // strip leading and trailing spaces + while( !aLine.empty() && isspace( *aLine.begin() ) ) + aLine.erase( aLine.begin() ); + + while( !aLine.empty() && isspace( *aLine.rbegin() ) ) + aLine.erase( --aLine.end() ); + + // a comment line may be empty to improve human readability + if( aLine.empty() && !isComment ) + return false; + + return true; +} + + +// extract an IDF string and move the index to point to the character after the substring +bool IDF3::GetIDFString( const std::string& aLine, std::string& aIDFString, + bool& hasQuotes, int& aIndex ) +{ + // 1. drop all leading spaces + // 2. if the first character is '"', read until the next '"', + // otherwise read until the next space or EOL. + + std::ostringstream ostr; + + int len = aLine.length(); + int idx = aIndex; + + if( idx < 0 || idx >= len ) + return false; + + while( isspace( aLine[idx] ) && idx < len ) ++idx; + + if( idx == len ) + { + aIndex = idx; + return false; + } + + if( aLine[idx] == '"' ) + { + hasQuotes = true; + ++idx; + while( aLine[idx] != '"' && idx < len ) + ostr << aLine[idx++]; + + if( idx == len ) + { + ERROR_IDF << "unterminated quote mark in line:\n"; + std::cerr << "LINE: " << aLine << "\n"; + aIndex = idx; + return false; + } + + ++idx; + } + else + { + hasQuotes = false; + + while( !isspace( aLine[idx] ) && idx < len ) + ostr << aLine[idx++]; + + } + + aIDFString = ostr.str(); + aIndex = idx; + + return true; +} + + +// perform a comparison between a fixed token string and an input string. +// the token is assumed to be an upper case IDF token and the input string +// is data from an IDF file. Since IDF tokens are case-insensitive, we cannot +// assume anything about the case of the input string. +bool IDF3::CompareToken( const char* aTokenString, const std::string& aInputString ) +{ + std::string::size_type i, j; + std::string bigToken = aInputString; + j = aInputString.length(); + + for( i = 0; i < j; ++i ) + bigToken[i] = std::toupper( bigToken[i] ); + + if( !bigToken.compare( aTokenString ) ) + return true; + + return false; +} + + +// parse a string for an IDF3::KEY_OWNER +bool IDF3::ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner ) +{ + if( CompareToken( "UNOWNED", aToken ) ) + { + aOwner = UNOWNED; + return true; + } + else if( CompareToken( "ECAD", aToken ) ) + { + aOwner = ECAD; + return true; + } + else if( CompareToken( "MCAD", aToken ) ) + { + aOwner = MCAD; + return true; + } + + ERROR_IDF << "unrecognized IDF OWNER: '" << aToken << "'\n"; + + return false; +} + + +bool IDF3::ParseIDFLayer( const std::string& aToken, IDF3::IDF_LAYER& aLayer ) +{ + if( CompareToken( "TOP", aToken ) ) + { + aLayer = LYR_TOP; + return true; + } + else if( CompareToken( "BOTTOM", aToken ) ) + { + aLayer = LYR_BOTTOM; + return true; + } + else if( CompareToken( "BOTH", aToken ) ) + { + aLayer = LYR_BOTH; + return true; + } + else if( CompareToken( "INNER", aToken ) ) + { + aLayer = LYR_INNER; + return true; + } + else if( CompareToken( "ALL", aToken ) ) + { + aLayer = LYR_ALL; + return true; + } + + ERROR_IDF << "unrecognized IDF LAYER: '" << aToken << "'\n"; + + aLayer = LYR_INVALID; + return false; +} + + +bool IDF3::WriteLayersText( std::ofstream& aBoardFile, IDF3::IDF_LAYER aLayer ) +{ + switch( aLayer ) + { + case LYR_TOP: + aBoardFile << "TOP"; + break; + + case LYR_BOTTOM: + aBoardFile << "BOTTOM"; + break; + + case LYR_BOTH: + aBoardFile << "BOTH"; + break; + + case LYR_INNER: + aBoardFile << "INNER"; + break; + + case LYR_ALL: + aBoardFile << "ALL"; + break; + + default: + do{ + std::ostringstream ostr; + ostr << "invalid IDF layer: " << aLayer; + + throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) ); + } while( 0 ); + + break; + } + + return !aBoardFile.fail(); +} + + +std::string IDF3::GetPlacementString( IDF3::IDF_PLACEMENT aPlacement ) +{ + switch( aPlacement ) + { + case PS_UNPLACED: + return "UNPLACED"; + + case PS_PLACED: + return "PLACED"; + + case PS_MCAD: + return "MCAD"; + + case PS_ECAD: + return "ECAD"; + + default: + break; + } + + std::ostringstream ostr; + ostr << "[INVALID PLACEMENT VALUE]:" << aPlacement; + + return ostr.str(); +} + + +std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer ) +{ + switch( aLayer ) + { + case LYR_TOP: + return "TOP"; + + case LYR_BOTTOM: + return "BOTTOM"; + + case LYR_BOTH: + return "BOTH"; + + case LYR_INNER: + return "INNER"; + + case LYR_ALL: + return "ALL"; + + default: + break; + } + + std::ostringstream ostr; + ostr << "[INVALID LAYER VALUE]:" << aLayer; + + return ostr.str(); +} + +std::string IDF3::GetOwnerString( IDF3::KEY_OWNER aOwner ) +{ + switch( aOwner ) + { + case IDF3::UNOWNED: + return "UNOWNED"; + + case IDF3::MCAD: + return "MCAD"; + + case IDF3::ECAD: + return "ECAD"; + + default: + break; + } + + ostringstream ostr; + ostr << "UNKNOWN: " << aOwner; + + return ostr.str(); +} |