Commit ceb6ad1a authored by dickelbeck's avatar dickelbeck

* Factored out the DSNLEXER class so it can be re-used more generally. The

    constructor takes a keyword table, so it can be used for arbitrary DSN
    syntax files of your own chosing.  Simply create an enum {} with all your
    unique tokens in it.  Then create a KEYWORD table.  See SPECCTRA_DB::keywords[].
    The reason you want an enum is to give the C++ debugger better type information
    so it can show symbolic integer symbols.
  * Factored out common richio.cpp and richio.h
    which is what DSNLEXER uses.
  * Fixed some minor issues with reading circuit descriptor from a *.dsn file.
parent 0fc7d7c1
...@@ -4,6 +4,21 @@ KiCad ChangeLog 2009 ...@@ -4,6 +4,21 @@ KiCad ChangeLog 2009
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.
2009-Dec-10 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++all
* Factored out the DSNLEXER class so it can be re-used more generally. The
constructor takes a keyword table, so it can be used for arbitrary DSN
syntax files of your own chosing. Simply create an enum {} with all your
unique tokens in it. Then create a KEYWORD table. See SPECCTRA_DB::keywords[].
The reason you want an enum is to give the C++ debugger better type information
so it can show symbolic integer symbols.
* Factored out common richio.cpp and richio.h
which is what DSNLEXER uses.
* Fixed some minor issues with reading circuit descriptor from a *.dsn file.
2009-Dec-6 UPDATE Dick Hollenbeck <dick@softplc.com> 2009-Dec-6 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++pcbnew & gerbview ++pcbnew & gerbview
......
...@@ -31,6 +31,7 @@ set(COMMON_SRCS ...@@ -31,6 +31,7 @@ set(COMMON_SRCS
drawframe.cpp drawframe.cpp
drawpanel.cpp drawpanel.cpp
drawtxt.cpp drawtxt.cpp
dsnlexer.cpp
edaappl.cpp edaappl.cpp
eda_dde.cpp eda_dde.cpp
eda_doc.cpp eda_doc.cpp
...@@ -41,6 +42,7 @@ set(COMMON_SRCS ...@@ -41,6 +42,7 @@ set(COMMON_SRCS
msgpanel.cpp msgpanel.cpp
projet_config.cpp projet_config.cpp
# pyhandler.cpp # pyhandler.cpp
richio.cpp
selcolor.cpp selcolor.cpp
string.cpp string.cpp
toolbars.cpp toolbars.cpp
......
...@@ -11,14 +11,6 @@ ...@@ -11,14 +11,6 @@
#define BUILD_VERSION "(2009-12-05-unstable)" #define BUILD_VERSION "(2009-12-05-unstable)"
#ifdef HAVE_SVN_VERSION
#include "version.h"
wxString g_BuildVersion( wxT( KICAD_SVN_VERSION ) );
#else
wxString g_BuildVersion( wxT( BUILD_VERSION ) );
#endif
#if defined(HAVE_SVN_VERSION) || defined(HAVE_SVN_REVISION) #if defined(HAVE_SVN_VERSION) || defined(HAVE_SVN_REVISION)
# include "version.h" # include "version.h"
#ifndef KICAD_ABOUT_VERSION #ifndef KICAD_ABOUT_VERSION
...@@ -30,6 +22,15 @@ wxString g_BuildAboutVersion( wxT( BUILD_VERSION ) ); ...@@ -30,6 +22,15 @@ wxString g_BuildAboutVersion( wxT( BUILD_VERSION ) );
#endif #endif
/** Function GetAboutBuildVersion()
* Return custom build date for about dialog
*/
wxString GetAboutBuildVersion()
{
return g_BuildAboutVersion;
}
/**********************************/ /**********************************/
wxString SetMsg( const wxString& msg ) wxString SetMsg( const wxString& msg )
/**********************************/ /**********************************/
......
...@@ -118,6 +118,17 @@ StructColors ColorRefs[NBCOLOR] = ...@@ -118,6 +118,17 @@ StructColors ColorRefs[NBCOLOR] =
}; };
#define BUILD_VERSION "(2009-12-05-unstable)"
#ifdef HAVE_SVN_VERSION
#include "version.h"
wxString g_BuildVersion( wxT( KICAD_SVN_VERSION ) );
#else
wxString g_BuildVersion( wxT( BUILD_VERSION ) );
#endif
/** Function GetBuildVersion() /** Function GetBuildVersion()
* Return the build date * Return the build date
*/ */
...@@ -127,15 +138,6 @@ wxString GetBuildVersion() ...@@ -127,15 +138,6 @@ wxString GetBuildVersion()
} }
/** Function GetAboutBuildVersion()
* Return custom build date for about dialog
*/
wxString GetAboutBuildVersion()
{
return g_BuildAboutVersion;
}
/** function SetLocaleTo_C_standard /** function SetLocaleTo_C_standard
* because kicad is internationalized, switch internalization to "C" standard * because kicad is internationalized, switch internalization to "C" standard
* i.e. uses the . (dot) as separator in print/read float numbers * i.e. uses the . (dot) as separator in print/read float numbers
......
This diff is collapsed.
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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
*/
#include <cstdarg>
#include "richio.h"
// This file defines 3 classes useful for working with DSN text files and is named
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
//-----<LINE_READER>------------------------------------------------------
LINE_READER::LINE_READER( FILE* aFile, unsigned aMaxLineLength )
{
fp = aFile;
lineNum = 0;
maxLineLength = aMaxLineLength;
// the real capacity is 10 bytes larger than requested.
capacity = aMaxLineLength + 10;
line = new char[capacity];
line[0] = '\0';
length = 0;
}
int LINE_READER::ReadLine() throw (IOError)
{
const char* p = fgets( line, capacity, fp );
if( !p )
{
line[0] = 0;
length = 0;
}
else
{
length = strlen( line );
if( length > maxLineLength )
throw IOError( _("Line length exceeded") );
++lineNum;
}
return length;
}
//-----<OUTPUTFORMATTER>----------------------------------------------------
// factor out a common GetQuoteChar
const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote_char )
{
// Include '#' so a symbol is not confused with a comment. We intend
// to wrap any symbol starting with a '#'.
// Our LEXER class handles comments, and comments appear to be an extension
// to the SPECCTRA DSN specification.
if( *wrapee == '#' )
return quote_char;
if( strlen(wrapee)==0 )
return quote_char;
bool isFirst = true;
for( ; *wrapee; ++wrapee, isFirst=false )
{
static const char quoteThese[] = "\t ()"
"%" // per Alfons of freerouting.net, he does not like this unquoted as of 1-Feb-2008
"{}" // guessing that these are problems too
;
// if the string to be wrapped (wrapee) has a delimiter in it,
// return the quote_char so caller wraps the wrapee.
if( strchr( quoteThese, *wrapee ) )
return quote_char;
if( !isFirst && '-' == *wrapee )
return quote_char;
}
return ""; // caller does not need to wrap, can use an unwrapped string.
}
//-----<STRINGFORMATTER>----------------------------------------------------
const char* STRINGFORMATTER::GetQuoteChar( const char* wrapee )
{
// for what we are using STRINGFORMATTER for at this time, we can return
// the nul string always.
return "";
// return OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, "\"" );
}
int STRINGFORMATTER::vprint( const char* fmt, va_list ap )
{
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
if( ret >= (int) buffer.size() )
{
buffer.reserve( ret+200 );
ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
}
if( ret > 0 )
mystring.append( (const char*) &buffer[0] );
return ret;
}
int STRINGFORMATTER::sprint( const char* fmt, ... )
{
va_list args;
va_start( args, fmt );
int ret = vprint( fmt, args);
va_end( args );
return ret;
}
int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
{
#define NESTWIDTH 2 ///< how many spaces per nestLevel
va_list args;
va_start( args, fmt );
int result = 0;
int total = 0;
for( int i=0; i<nestLevel; ++i )
{
result = sprint( "%*c", NESTWIDTH, ' ' );
if( result < 0 )
break;
total += result;
}
if( result<0 || (result=vprint( fmt, args ))<0 )
{
throw IOError( _("Error writing to STRINGFORMATTER") );
}
va_end( args );
total += result;
return total;
}
void STRINGFORMATTER::StripUseless()
{
std::string copy = mystring;
mystring.clear();
for( std::string::iterator i=copy.begin(); i!=copy.end(); ++i )
{
if( !isspace( *i ) && *i!=')' && *i!='(' && *i!='"' )
{
mystring += *i;
}
}
}
This diff is collapsed.
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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 RICHIO_H_
#define RICHIO_H_
// This file defines 3 classes useful for working with DSN text files and is named
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
#include <string>
#include <vector>
// I really did not want to be dependent on wxWidgets in richio
// but the errorText needs to be wide char so wxString rules.
#include <wx/wx.h>
#include <cstdio> // FILE
/**
* Struct IOError
* is a class used to hold an error message and may be used to throw exceptions
* containing meaningful error messages.
*/
struct IOError
{
wxString errorText;
IOError( const wxChar* aMsg ) :
errorText( aMsg )
{
}
IOError( const wxString& aMsg ) :
errorText( aMsg )
{
}
};
/**
* Class LINE_READER
* reads single lines of text into its buffer and increments a line number counter.
* It throws an exception if a line is too long.
*/
class LINE_READER
{
protected:
FILE* fp;
int lineNum;
unsigned maxLineLength;
unsigned length;
char* line;
unsigned capacity;
public:
/**
* Constructor LINE_READER
* takes an open FILE and the size of the desired line buffer.
* @param aFile An open file in "ascii" mode, not binary mode.
* @param aMaxLineLength The number of bytes to use in the line buffer.
*/
LINE_READER( FILE* aFile, unsigned aMaxLineLength );
~LINE_READER()
{
delete[] line;
}
/*
int CharAt( int aNdx )
{
if( (unsigned) aNdx < capacity )
return (char) (unsigned char) line[aNdx];
return -1;
}
*/
/**
* Function ReadLine
* reads a line of text into the buffer and increments the line number
* counter. If the line is larger than the buffer size, then an exception
* is thrown.
* @return int - The number of bytes read, 0 at end of file.
* @throw IOError only when a line is too long.
*/
int ReadLine() throw (IOError);
operator char* ()
{
return line;
}
int LineNumber()
{
return lineNum;
}
unsigned Length()
{
return length;
}
};
/**
* Class OUTPUTFORMATTER
* is an interface (abstract class) used to output ASCII text in a convenient
* way. The primary interface is printf() like but with support for indentation
* control. The destination of the 8 bit wide text is up to the implementer.
* If you want to output a wxString, then use CONV_TO_UTF8() on it before passing
* it as an argument to Print().
* <p>
* Since this is an abstract interface, only classes derived from this one
* will be the implementations.
*/
class OUTPUTFORMATTER
{
#if defined(__GNUG__) // The GNU C++ compiler defines this
// When used on a C++ function, we must account for the "this" pointer,
// so increase the STRING-INDEX and FIRST-TO_CHECK by one.
// See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html
// Then to get format checking during the compile, compile with -Wall or -Wformat
#define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
#else
#define PRINTF_FUNC // nothing
#endif
public:
/**
* Function Print
* formats and writes text to the output stream.
*
* @param nestLevel The multiple of spaces to preceed the output with.
* @param fmt A printf() style format string.
* @param ... a variable list of parameters that will get blended into
* the output under control of the format string.
* @return int - the number of characters output.
* @throw IOError, if there is a problem outputting, such as a full disk.
*/
virtual int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError ) = 0;
/**
* Function GetQuoteChar
* performs quote character need determination.
* It returns the quote character as a single character string for a given
* input wrapee string. If the wrappee does not need to be quoted,
* the return value is "" (the null string), such as when there are no
* delimiters in the input wrapee string. If you want the quote_char
* to be assuredly not "", then pass in "(" as the wrappee.
* <p>
* Implementations are free to override the default behavior, which is to
* call the static function of the same name.
* @param wrapee A string that might need wrapping on each end.
* @return const char* - the quote_char as a single character string, or ""
* if the wrapee does not need to be wrapped.
*/
virtual const char* GetQuoteChar( const char* wrapee ) = 0;
virtual ~OUTPUTFORMATTER() {}
/**
* Function GetQuoteChar
* performs quote character need determination according to the Specctra DSN
* specification.
* @param wrapee A string that might need wrapping on each end.
* @param quote_char A single character C string which provides the current
* quote character, should it be needed by the wrapee.
*
* @return const char* - the quote_char as a single character string, or ""
* if the wrapee does not need to be wrapped.
*/
static const char* GetQuoteChar( const char* wrapee, const char* quote_char );
};
/**
* Class STRINGFORMATTER
* implements OUTPUTFORMATTER to a memory buffer. After Print()ing the
* string is available through GetString()
*/
class STRINGFORMATTER : public OUTPUTFORMATTER
{
std::vector<char> buffer;
std::string mystring;
int sprint( const char* fmt, ... );
int vprint( const char* fmt, va_list ap );
public:
/**
* Constructor STRINGFORMATTER
* reserves space in the buffer
*/
STRINGFORMATTER( int aReserve = 300 ) :
buffer( aReserve, '\0' )
{
}
/**
* Function Clear
* clears the buffer and empties the internal string.
*/
void Clear()
{
mystring.clear();
}
/**
* Function StripUseless
* removes whitespace, '(', and ')' from the mystring.
*/
void StripUseless();
std::string GetString()
{
return mystring;
}
//-----<OUTPUTFORMATTER>------------------------------------------------
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
const char* GetQuoteChar( const char* wrapee );
//-----</OUTPUTFORMATTER>-----------------------------------------------
};
#endif // RICHIO_H_
...@@ -78,7 +78,6 @@ set(PCBNEW_SRCS ...@@ -78,7 +78,6 @@ set(PCBNEW_SRCS
dist.cpp dist.cpp
dragsegm.cpp dragsegm.cpp
drc.cpp drc.cpp
dsn.cpp
edgemod.cpp edgemod.cpp
edit.cpp edit.cpp
editedge.cpp editedge.cpp
...@@ -222,9 +221,9 @@ install(TARGETS pcbnew ...@@ -222,9 +221,9 @@ install(TARGETS pcbnew
# This one gets made only when testing. # This one gets made only when testing.
add_executable(dsntest EXCLUDE_FROM_ALL dsn.cpp) #add_executable(dsntest EXCLUDE_FROM_ALL dsn.cpp)
target_link_libraries(dsntest common ${wxWidgets_LIBRARIES}) #target_link_libraries(dsntest common ${wxWidgets_LIBRARIES})
# This one gets made only when testing. # This one gets made only when testing.
add_executable(specctra_test EXCLUDE_FROM_ALL specctra.cpp dsn.cpp) add_executable(specctra_test EXCLUDE_FROM_ALL specctra.cpp)
target_link_libraries(specctra_test common ${wxWidgets_LIBRARIES}) target_link_libraries(specctra_test common ${wxWidgets_LIBRARIES})
This diff is collapsed.
This diff is collapsed.
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -257,8 +257,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet ...@@ -257,8 +257,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet
shape = (SHAPE*) (*aPadstack)[0]; shape = (SHAPE*) (*aPadstack)[0];
DSN_T type = shape->shape->Type(); DSN_T type = shape->shape->Type();
if( type != T_circle ) if( type != T_circle )
ThrowIOError( _( "Unsupported via shape: \"%s\""), ThrowIOError( _( "Unsupported via shape: %s"),
GetChars( LEXER::GetTokenString( type ) ) ); GetChars( GetTokenString( type ) ) );
CIRCLE* circle = (CIRCLE*) shape->shape; CIRCLE* circle = (CIRCLE*) shape->shape;
int viaDiam = scale( circle->diameter, routeResolution ); int viaDiam = scale( circle->diameter, routeResolution );
...@@ -275,8 +275,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet ...@@ -275,8 +275,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet
shape = (SHAPE*) (*aPadstack)[0]; shape = (SHAPE*) (*aPadstack)[0];
DSN_T type = shape->shape->Type(); DSN_T type = shape->shape->Type();
if( type != T_circle ) if( type != T_circle )
ThrowIOError( _( "Unsupported via shape: \"%s\""), ThrowIOError( _( "Unsupported via shape: %s"),
GetChars( LEXER::GetTokenString( type ) ) ); GetChars( GetTokenString( type ) ) );
CIRCLE* circle = (CIRCLE*) shape->shape; CIRCLE* circle = (CIRCLE*) shape->shape;
int viaDiam = scale( circle->diameter, routeResolution ); int viaDiam = scale( circle->diameter, routeResolution );
...@@ -299,8 +299,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet ...@@ -299,8 +299,8 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet
shape = (SHAPE*) (*aPadstack)[i]; shape = (SHAPE*) (*aPadstack)[i];
DSN_T type = shape->shape->Type(); DSN_T type = shape->shape->Type();
if( type != T_circle ) if( type != T_circle )
ThrowIOError( _( "Unsupported via shape: \"%s\""), ThrowIOError( _( "Unsupported via shape: %s"),
GetChars( LEXER::GetTokenString( type ) ) ); GetChars( GetTokenString( type ) ) );
CIRCLE* circle = (CIRCLE*) shape->shape; CIRCLE* circle = (CIRCLE*) shape->shape;
...@@ -473,7 +473,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -473,7 +473,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() ); wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() );
ThrowIOError( ThrowIOError(
_("Unsupported wire shape: \"%s\" for net: \"%s\""), _("Unsupported wire shape: \"%s\" for net: \"%s\""),
LEXER::GetTokenString(shape).GetData(), DLEX::GetTokenString(shape).GetData(),
netId.GetData() netId.GetData()
); );
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment