++richio:

* Deleted kicad_exceptions, because it required the big #include <wx/wx.h> and
    that was slowing down compiling.  Moved that stuff back into richio.h where
    it came from.
  * Enhanced IO_ERROR to format an errorText.
  * Added THROW_IO_ERROR() and THROW_PARSE_ERROR() macros to capture the
    the call site of the thrower.  If you have problems compiling, it is probably
    due to the definition of __LOC__ in richio.h.  Some compilers may not support
    __func__ in C++ yet.  Find a macro that identifies your compiler, and we can
    work out something in the #define of __LOC__.
This commit is contained in:
Dick Hollenbeck 2010-12-30 16:21:23 -06:00
commit 0ff5faaf23
13 changed files with 225 additions and 183 deletions

View File

@ -4,6 +4,19 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-Dec-28 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++richio:
* Deleted kicad_exceptions, because it required the big #include <wx/wx.h> and
that was slowing down compiling. Moved that stuff back into richio.h where
it came from.
* Enhanced IO_ERROR to format an errorText.
* Added THROW_IO_ERROR() and THROW_PARSE_ERROR() macros to capture the
the call site of the thrower. If you have problems compiling, it is probably
due to the definition of __LOC__ in richio.h. Some compilers may not support
__func__ in C++ yet. Find a macro that identifies your compiler, and we can
work out something in the #define of __LOC__.
2010-Dec-28 UPDATE Dick Hollenbeck <dick@softplc.com> 2010-Dec-28 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++new: ++new:

View File

@ -251,12 +251,14 @@ bool DSNLEXER::IsSymbol( int aTok )
void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw( IO_ERROR ) void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw( IO_ERROR )
{ {
// @todo convert this to THROW_PARSE_ERROR()
// append to aText, do not overwrite // append to aText, do not overwrite
aText << wxT(" ") << _("in") << wxT(" \"") << CurSource() aText << wxT(" ") << _("in") << wxT(" \"") << CurSource()
<< wxT("\" ") << _("on line") << wxT(" ") << reader->LineNumber() << wxT("\" ") << _("on line") << wxT(" ") << reader->LineNumber()
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset; << wxT(" ") << _("at offset") << wxT(" ") << charOffset;
throw IO_ERROR( aText ); THROW_IO_ERROR( aText );
} }

View File

@ -113,7 +113,7 @@ unsigned FILE_LINE_READER::ReadLine() throw( IO_ERROR )
length += strlen( line + length ); length += strlen( line + length );
if( length == maxLineLength ) if( length == maxLineLength )
throw IO_ERROR( _("Line length exceeded") ); THROW_IO_ERROR( _("Line length exceeded") );
// a normal line breaks here, once through while loop // a normal line breaks here, once through while loop
if( length+1 < capacity || line[length-1] == '\n' ) if( length+1 < capacity || line[length-1] == '\n' )
@ -164,7 +164,7 @@ unsigned STRING_LINE_READER::ReadLine() throw( IO_ERROR )
if( length ) if( length )
{ {
if( length >= maxLineLength ) if( length >= maxLineLength )
throw IO_ERROR( _("Line length exceeded") ); THROW_IO_ERROR( _("Line length exceeded") );
if( length+1 > capacity ) // +1 for terminating nul if( length+1 > capacity ) // +1 for terminating nul
expandCapacity( length+1 ); expandCapacity( length+1 );
@ -305,7 +305,7 @@ std::string OUTPUTFORMATTER::Quoted( const std::string& aWrapee ) throw( IO_ERRO
// a decision was made to make all S-expression strings be on a single // a decision was made to make all S-expression strings be on a single
// line. You can embed \n (human readable) in the text but not // line. You can embed \n (human readable) in the text but not
// '\n' which is 0x0a. // '\n' which is 0x0a.
throw IO_ERROR( _( "S-expression string has newline" ) ); THROW_IO_ERROR( _( "S-expression string has newline" ) );
} }
} }
@ -363,7 +363,7 @@ void STREAM_OUTPUTFORMATTER::write( const char* aOutBuf, int aCount ) throw( IO_
if( !os.IsOk() ) if( !os.IsOk() )
{ {
throw IO_ERROR( _( "OUTPUTSTREAM_OUTPUTFORMATTER write error" ) ); THROW_IO_ERROR( _( "OUTPUTSTREAM_OUTPUTFORMATTER write error" ) );
} }
} }
} }

View File

@ -17,25 +17,6 @@ class LIB_PIN;
class LIB_COMPONENT; class LIB_COMPONENT;
/**
* Holder of an error message and may be thrown from functions.
*/
struct Error
{
wxString errorText;
Error( const wxChar* aMsg ) :
errorText( aMsg )
{
}
Error( const wxString& aMsg ) :
errorText( aMsg )
{
}
};
/// A container for several SCH_FIELD items /// A container for several SCH_FIELD items
typedef std::vector<SCH_FIELD> SCH_FIELDS; typedef std::vector<SCH_FIELD> SCH_FIELDS;

View File

@ -1,92 +0,0 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* 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
*/
#ifndef KICAD_EXCEPTIONS_H_
#define KICAD_EXCEPTIONS_H_
/**
* @ingroup exception_types
* @{
*/
#include <wx/string.h>
#include <string>
/**
* Struct IO_ERROR
* is a class used to hold an error message and may be used to throw exceptions
* containing meaningful error messages.
* @author Dick Hollenbeck
*/
struct IO_ERROR
{
wxString errorText;
/**
* Constructor ( const wxChar* )
* handles the case where _() is passed as aMsg.
*/
IO_ERROR( const wxChar* aMsg ) :
errorText( aMsg )
{
}
IO_ERROR( const wxString& aMsg ) :
errorText( aMsg )
{
}
IO_ERROR( const std::string& aMsg ) :
errorText( wxConvertMB2WX( aMsg.c_str() ) )
{
}
};
/**
* Class PARSE_ERROR
* contains a filename or source description, a line number, a character offset,
* and an error message.
* @author Dick Hollenbeck
*/
struct PARSE_ERROR : public IO_ERROR
{
wxString source; ///< filename typically, or other source
int lineNumber;
int byteIndex; ///< char offset, starting from 1, into the problem line.
PARSE_ERROR( const wxString& aMsg, const wxString& aSource,
int aLineNumber, int aByteIndex ) :
IO_ERROR( aMsg ),
source( aSource ),
lineNumber( aLineNumber )
{
}
};
/** @} exception_types */
#endif // KICAD_EXCEPTIONS_H_

View File

@ -38,7 +38,134 @@
// but the errorText needs to be wide char so wxString rules. // but the errorText needs to be wide char so wxString rules.
#include <wx/wx.h> #include <wx/wx.h>
#include <cstdio> #include <cstdio>
#include <kicad_exceptions.h>
/**
* @ingroup exception_types
* @{
*/
#define IO_FORMAT _( "IO_ERROR: '%s'\n from %s : %s" )
#define PARSE_FORMAT _( "PARSE_ERROR: '%s' in input/source '%s', line %d, offset %d\n from %s : %s" )
// references:
// http://stackoverflow.com/questions/2670816/how-can-i-use-the-compile-time-constant-line-in-a-string
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
// use one of the following __LOC__ defs, depending on whether your
// compiler supports __func__ or not, and how it handles __LINE__
#define __LOC__ ((std::string(__func__) + " : ") + TOSTRING(__LINE__)).c_str()
//#define __LOC__ TOSTRING(__LINE__)
/// macro which captures the "call site" values of __FILE_ & __LOC__
#define THROW_IO_ERROR( msg ) throw IO_ERROR( __FILE__, __LOC__, msg )
/**
* Struct IO_ERROR
* is a class used to hold an error message and may be used to throw exceptions
* containing meaningful error messages.
* @author Dick Hollenbeck
*/
struct IO_ERROR // : std::exception
{
wxString errorText;
/**
* Constructor
*
* @param aThrowersFile is the __FILE__ preprocessor macro but generated
* at the source file of thrower.
*
* @param aThrowersLoc can be either a function name, such as __func__
* or a stringified __LINE__ preprocessor macro but generated
* at the source function of the thrower, or concatonation. Use macro
* THROW_IO_ERROR() to wrap a call to this constructor at the call site.
*
* @param aMsg is error text that will be streamed through wxString.Printf()
* using the format string IO_FORMAT above.
*/
IO_ERROR( const char* aThrowersFile,
const char* aThrowersLoc,
const wxString& aMsg )
{
init( aThrowersFile, aThrowersLoc, aMsg );
}
IO_ERROR( const char* aThrowersFile,
const char* aThrowersLoc,
const std::string& aMsg )
{
init( aThrowersFile, aThrowersLoc, wxString::FromUTF8( aMsg.c_str() ) );
}
/**
* handles the case where _() is passed as aMsg.
*/
IO_ERROR( const char* aThrowersFile,
const char* aThrowersLoc,
const wxChar* aMsg )
{
init( aThrowersFile, aThrowersLoc, wxString( aMsg ) );
}
void init( const char* aThrowersFile, const char* aThrowersLoc, const wxString& aMsg )
{
errorText.Printf( IO_FORMAT, aMsg.GetData(),
wxString::FromUTF8( aThrowersFile ).GetData(),
wxString::FromUTF8( aThrowersLoc ).GetData() );
}
IO_ERROR() {}
~IO_ERROR() throw ( /*none*/ ){}
};
#define THROW_PARSE_ERROR( msg, input, line, offset ) throw PARSE_ERROR( __FILE__, __LOC__, msg, input, line, offset )
/**
* Class PARSE_ERROR
* contains a filename or source description, a line number, a character offset,
* and an error message.
* @author Dick Hollenbeck
*/
struct PARSE_ERROR : public IO_ERROR
{
// wxString errorText is still public from IO_ERROR
int lineNumber; ///< at which line number, 1 based index.
int byteIndex; ///< at which character position within the line, 1 based index
PARSE_ERROR( const char* aThrowersFile, const char* aThrowersLoc,
const wxString& aMsg, const wxString& aSource,
int aLineNumber, int aByteIndex ) :
IO_ERROR()
{
init( aThrowersFile, aThrowersLoc, aMsg, aSource, aLineNumber, aByteIndex );
}
void init( const char* aThrowersFile, const char* aThrowersLoc,
const wxString& aMsg, const wxString& aSource,
int aLineNumber, int aByteIndex )
{
// save line and offset in binary for Sweet text editor, which will catch exceptions
lineNumber = aLineNumber;
byteIndex = aByteIndex;
// #define PARSE_FORMAT _( "PARSE_ERROR: %s in source %s, line %d, offset %d\nfrom cpp:%s func:%s" )
errorText.Printf( PARSE_FORMAT, aMsg.GetData(), aSource.GetData(),
aLineNumber, aByteIndex,
wxString::FromUTF8( aThrowersFile ).GetData(),
wxString::FromUTF8( aThrowersLoc ).GetData() );
}
~PARSE_ERROR() throw ( /*none*/ ){}
};
/** @} exception_types */
#define LINE_READER_LINE_DEFAULT_MAX 100000 #define LINE_READER_LINE_DEFAULT_MAX 100000

View File

@ -41,16 +41,10 @@
*/ */
#include <sch_dir_lib_source.h>
using namespace SCH;
#include <kicad_exceptions.h>
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -61,11 +55,8 @@ using namespace SCH;
#include <vector> #include <vector>
using namespace std; using namespace std;
/// This file extension is an implementation detail specific to this LIB_SOURCE #include <sch_dir_lib_source.h>
/// implementation, and to a corresponding LIB_SINK. using namespace SCH;
/// Core EESCHEMA should never have to see this.
#define SWEET_EXT ".part"
#define SWEET_EXTZ (sizeof(SWEET_EXT)-1)
/* __func__ is C99 prescribed, but just in case: /* __func__ is C99 prescribed, but just in case:
@ -318,7 +309,7 @@ void DIR_LIB_SOURCE::readString( STRING* aResult, const STRING& aFileName ) thro
{ {
STRING msg = strerror( errno ); STRING msg = strerror( errno );
msg += "; cannot open(O_RDONLY) file " + aFileName; msg += "; cannot open(O_RDONLY) file " + aFileName;
throw( IO_ERROR( msg ) ); THROW_IO_ERROR( msg );
} }
struct stat fs; struct stat fs;
@ -330,9 +321,14 @@ void DIR_LIB_SOURCE::readString( STRING* aResult, const STRING& aFileName ) thro
{ {
STRING msg = aFileName; STRING msg = aFileName;
msg += " seems too big. ( > 1 mbyte )"; msg += " seems too big. ( > 1 mbyte )";
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
#if 0
// I read somewhere on the Internet that std::string chars are not guaranteed
// (over time) to be contiguous in future implementations of C++, so this
// strategy is here for that eventuality. We buffer through readBuffer here.
// reuse same readBuffer, which is not thread safe, but the API // reuse same readBuffer, which is not thread safe, but the API
// is not advertising thread safe (yet, if ever). // is not advertising thread safe (yet, if ever).
if( (int) fs.st_size > (int) readBuffer.size() ) if( (int) fs.st_size > (int) readBuffer.size() )
@ -343,13 +339,27 @@ void DIR_LIB_SOURCE::readString( STRING* aResult, const STRING& aFileName ) thro
{ {
STRING msg = strerror( errno ); STRING msg = strerror( errno );
msg += "; cannot read file " + aFileName; msg += "; cannot read file " + aFileName;
throw( IO_ERROR( msg ) ); THROW_IO_ERROR( msg );
} }
// std::string chars are not guaranteed to be contiguous in
// future implementations of C++, so this is why we did not read into
// aResult directly.
aResult->assign( &readBuffer[0], count ); aResult->assign( &readBuffer[0], count );
#else
// read into the string directly
aResult->resize( fs.st_size );
int count = read( fw, &(*aResult)[0], fs.st_size );
if( count != (int) fs.st_size )
{
STRING msg = strerror( errno );
msg += "; cannot read file " + aFileName;
THROW_IO_ERROR( msg );
}
// test trailing nul is there, which should have been put there with resize() above
// printf( "'%s'\n", aResult->c_str() ); // checked OK.
#endif
} }
@ -371,7 +381,7 @@ DIR_LIB_SOURCE::DIR_LIB_SOURCE( const STRING& aDirectoryPath,
if( sourceURI.size() == 0 ) if( sourceURI.size() == 0 )
{ {
throw( IO_ERROR( STRING("aDirectoryPath cannot be empty") ) ); THROW_IO_ERROR( STRING("aDirectoryPath cannot be empty") );
} }
// remove any trailing separator, so we can add it back later without ambiguity // remove any trailing separator, so we can add it back later without ambiguity
@ -439,7 +449,7 @@ void DIR_LIB_SOURCE::ReadPart( STRING* aResult, const STRING& aPartName, const S
if( !useVersioning && (aRev.size() || rev) ) if( !useVersioning && (aRev.size() || rev) )
{ {
STRING msg = "this type 'dir' LIB_SOURCE not using 'useVersioning' option, cannot ask for a revision"; STRING msg = "this type 'dir' LIB_SOURCE not using 'useVersioning' option, cannot ask for a revision";
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
if( aRev.size() ) if( aRev.size() )
@ -462,7 +472,7 @@ void DIR_LIB_SOURCE::ReadPart( STRING* aResult, const STRING& aPartName, const S
if( it == partnames.end() ) // part not found if( it == partnames.end() ) // part not found
{ {
partName += " not found."; partName += " not found.";
throw IO_ERROR( partName ); THROW_IO_ERROR( partName );
} }
readString( aResult, makeFileName( partName ) ); readString( aResult, makeFileName( partName ) );
@ -482,7 +492,7 @@ void DIR_LIB_SOURCE::ReadPart( STRING* aResult, const STRING& aPartName, const S
{ {
partName.insert( partName.begin(), '\'' ); partName.insert( partName.begin(), '\'' );
partName += "' is not present without a revision."; partName += "' is not present without a revision.";
throw IO_ERROR( partName ); THROW_IO_ERROR( partName );
} }
readString( aResult, makeFileName( *it ) ); readString( aResult, makeFileName( *it ) );
@ -547,7 +557,7 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
{ {
STRING msg = strerror( errno ); STRING msg = strerror( errno );
msg += "; scanning directory " + curDir; msg += "; scanning directory " + curDir;
throw( IO_ERROR( msg ) ); THROW_IO_ERROR( msg );
} }
struct stat fs; struct stat fs;
@ -573,7 +583,7 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
{ {
STRING msg = partName; STRING msg = partName;
msg += " has already been encountered"; msg += " has already been encountered";
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
} }
@ -656,7 +666,7 @@ void DIR_LIB_SOURCE::Test( int argc, char** argv )
printf( "std::exception\n" ); printf( "std::exception\n" );
} }
catch( IO_ERROR ioe ) catch( IO_ERROR& ioe )
{ {
printf( "exception: %s\n", (const char*) ioe.errorText.ToUTF8() ) ); printf( "exception: %s\n", (const char*) ioe.errorText.ToUTF8() ) );
} }

View File

@ -26,11 +26,18 @@
#define DIR_LIB_SOURCE_H_ #define DIR_LIB_SOURCE_H_
#include <sch_lib.h>
#include <set> #include <set>
#include <vector> #include <vector>
#include <sch_lib.h>
/// This file extension is an implementation detail specific to this LIB_SOURCE
/// and to a corresponding LIB_SINK.
/// Core EESCHEMA should never have to see this.
#define SWEET_EXT ".part"
#define SWEET_EXTZ (sizeof(SWEET_EXT)-1)
/** /**
* struct BY_REV * struct BY_REV

View File

@ -26,7 +26,7 @@
#define SCH_LIB_H_ #define SCH_LIB_H_
#include <utf8.h> #include <utf8.h>
#include <kicad_exceptions.h> #include <richio.h>
namespace SCH { namespace SCH {

View File

@ -132,7 +132,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
msg += row->logicalName; msg += row->logicalName;
msg += '\''; msg += '\'';
msg += " is a duplicate logical lib name"; msg += " is a duplicate logical lib name";
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
} }
} }
@ -207,7 +207,7 @@ LIB* LIB_TABLE::lookupLib( const LPID& aLPID, LIB* aFallBackLib )
STRING msg = "lib table contains no logical lib '"; STRING msg = "lib table contains no logical lib '";
msg += aLPID.GetLogicalLib(); msg += aLPID.GetLogicalLib();
msg += '\''; msg += '\'';
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
if( !row->lib ) if( !row->lib )
@ -226,7 +226,7 @@ LIB* LIB_TABLE::lookupLib( const LPID& aLPID, LIB* aFallBackLib )
} }
STRING msg = "lookupLib() requires logicalLibName or a fallback lib"; STRING msg = "lookupLib() requires logicalLibName or a fallback lib";
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
@ -276,7 +276,7 @@ void LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR )
STRING msg = "cannot load unknown libType: '"; STRING msg = "cannot load unknown libType: '";
msg += libType; msg += libType;
msg += '\''; msg += '\'';
throw IO_ERROR( msg ); THROW_IO_ERROR( msg );
} }
} }
@ -342,9 +342,12 @@ bool LIB_TABLE::InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace )
void LIB_TABLE::Test() void LIB_TABLE::Test()
{ {
// the null string is not really a legal DSN token since any duplicated // A pair of double quotes alone, is not really a legal DSN token since
// double quote ("") is assumed to be a single double quote ("). // any duplicated double quote ("") is assumed to be a single double quote (")
// To pass an empty string, we can pass " " to (options " ") // in any DSN lexer.
// To pass an empty string, we can pass " " to (options " "), or if you passed
// """" this would show up as "" with quotes present in the parser. The parser
// probably doesn't want a pair of double quotes, strlen() = 2.
SCH_LIB_TABLE_LEXER slr( SCH_LIB_TABLE_LEXER slr(
"(lib_table \n" "(lib_table \n"
" (lib (logical www) (type http) (full_uri http://kicad.org/libs) (options \" \"))\n" " (lib (logical www) (type http) (full_uri http://kicad.org/libs) (options \" \"))\n"
@ -355,25 +358,12 @@ void LIB_TABLE::Test()
wxT( "inline text" ) // source wxT( "inline text" ) // source
); );
try
{
// read the "( lib_table" pair of tokens // read the "( lib_table" pair of tokens
slr.NextTok(); slr.NextTok();
slr.NextTok(); slr.NextTok();
// parse the rest of input to slr // parse the rest of input to slr
Parse( &slr ); Parse( &slr );
}
catch( std::exception& ex )
{
printf( "std::exception\n" );
}
catch( IO_ERROR& ioe )
{
printf( "exception: %s\n", (const char*) ioe.errorText.ToUTF8() );
}
STRING_FORMATTER sf; STRING_FORMATTER sf;
@ -404,25 +394,29 @@ void LIB_TABLE::Test()
printf( "logicalName: %s\n", it->c_str() ); printf( "logicalName: %s\n", it->c_str() );
} }
try
{
// find a part // find a part
LPID lpid( "meparts:tigers/ears/rev10" ); LPID lpid( "meparts:tigers/ears/rev10" );
LookupPart( lpid ); LookupPart( lpid );
} }
catch( IO_ERROR& ioe )
{
printf( "exception: %s\n", (const char*) ioe.errorText.ToUTF8() );
}
}
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
LIB_TABLE lib_table; LIB_TABLE lib_table;
try
{
// test exceptions:
// THROW_PARSE_ERROR( wxT("test problem"), wxT("input"), 23, 46 );
//THROW_IO_ERROR( wxT("io test") );
lib_table.Test(); lib_table.Test();
}
catch( IO_ERROR& ioe )
{
printf( "%s\n", (const char*) ioe.errorText.ToUTF8() );
}
return 0; return 0;
} }

View File

@ -184,7 +184,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
if( offset != -1 ) if( offset != -1 )
{ {
throw PARSE_ERROR( THROW_PARSE_ERROR(
_( "Illegal character found in LPID string" ), _( "Illegal character found in LPID string" ),
wxConvertMB2WX( aLPID.c_str() ), wxConvertMB2WX( aLPID.c_str() ),
0, 0,

View File

@ -26,7 +26,7 @@
#define SCH_LPID_H_ #define SCH_LPID_H_
#include <utf8.h> #include <utf8.h>
#include <kicad_exceptions.h> #include <richio.h>
namespace SCH { namespace SCH {

View File

@ -542,7 +542,7 @@ void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IO_ERROR )
errText.PrintfV( fmt, args ); errText.PrintfV( fmt, args );
va_end( args ); va_end( args );
throw IO_ERROR( errText ); THROW_IO_ERROR( errText );
} }