* 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.
This commit is contained in:
parent
0fc7d7c127
commit
ceb6ad1a72
|
@ -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
|
||||||
|
|
|
@ -13,7 +13,7 @@ set(COMMON_SRCS
|
||||||
bezier_curves.cpp
|
bezier_curves.cpp
|
||||||
block_commande.cpp
|
block_commande.cpp
|
||||||
class_marker_base.cpp
|
class_marker_base.cpp
|
||||||
class_plotter.cpp
|
class_plotter.cpp
|
||||||
class_undoredo_container.cpp
|
class_undoredo_container.cpp
|
||||||
common.cpp
|
common.cpp
|
||||||
common_plot_functions.cpp
|
common_plot_functions.cpp
|
||||||
|
@ -24,13 +24,14 @@ set(COMMON_SRCS
|
||||||
confirm.cpp
|
confirm.cpp
|
||||||
copy_to_clipboard.cpp
|
copy_to_clipboard.cpp
|
||||||
dialog_display_info_HTML_base.cpp
|
dialog_display_info_HTML_base.cpp
|
||||||
dialog_load_error.cpp
|
dialog_load_error.cpp
|
||||||
dcsvg.cpp
|
dcsvg.cpp
|
||||||
displlst.cpp
|
displlst.cpp
|
||||||
dlist.cpp
|
dlist.cpp
|
||||||
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
|
||||||
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 @@
|
||||||
#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 ) );
|
||||||
#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 )
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
@ -40,13 +41,13 @@ wxString SetMsg( const wxString& msg )
|
||||||
* Perhaps depending on wxWidgets versions
|
* Perhaps depending on wxWidgets versions
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
wxString message;
|
wxString message;
|
||||||
|
|
||||||
#if 1 /* Windows */
|
#if 1 /* Windows */
|
||||||
message = wxT( "\n" );
|
message = wxT( "\n" );
|
||||||
#endif
|
#endif
|
||||||
message << msg;
|
message << msg;
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,116 +55,116 @@ wxString SetMsg( const wxString& msg )
|
||||||
void InitKiCadAbout( wxAboutDialogInfo& info )
|
void InitKiCadAbout( wxAboutDialogInfo& info )
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{
|
{
|
||||||
/* Set name and title */
|
/* Set name and title */
|
||||||
info.SetName( wxGetApp().GetTitle() );
|
info.SetName( wxGetApp().GetTitle() );
|
||||||
|
|
||||||
/* Set description */
|
/* Set description */
|
||||||
wxString description;
|
wxString description;
|
||||||
|
|
||||||
/* KiCad build version */
|
/* KiCad build version */
|
||||||
description << ( _T( "Build: " ) ) << GetAboutBuildVersion();
|
description << ( _T( "Build: " ) ) << GetAboutBuildVersion();
|
||||||
|
|
||||||
/* Print for wxversion */
|
/* Print for wxversion */
|
||||||
description << ( wxT( "\n\nwxWidgets " ) )
|
description << ( wxT( "\n\nwxWidgets " ) )
|
||||||
<< wxMAJOR_VERSION
|
<< wxMAJOR_VERSION
|
||||||
<< wxT( "." )
|
<< wxT( "." )
|
||||||
<< wxMINOR_VERSION << wxT( "." )
|
<< wxMINOR_VERSION << wxT( "." )
|
||||||
<< wxRELEASE_NUMBER
|
<< wxRELEASE_NUMBER
|
||||||
|
|
||||||
/* Show Unicode or Ansi version */
|
/* Show Unicode or Ansi version */
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
<< ( wxT( " Unicode " ) );
|
<< ( wxT( " Unicode " ) );
|
||||||
# else
|
# else
|
||||||
<< ( wxT( " Ansi " ) );
|
<< ( wxT( " Ansi " ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* Check Operating System *
|
* Check Operating System *
|
||||||
**************************/
|
**************************/
|
||||||
#if defined __WINDOWS__
|
#if defined __WINDOWS__
|
||||||
description << ( wxT( "on Windows" ) );
|
description << ( wxT( "on Windows" ) );
|
||||||
|
|
||||||
/* Check for wxMAC */
|
/* Check for wxMAC */
|
||||||
# elif defined __WXMAC__
|
# elif defined __WXMAC__
|
||||||
description << ( wxT( "on Macintosh" ) );
|
description << ( wxT( "on Macintosh" ) );
|
||||||
|
|
||||||
/* Linux 64 bits */
|
/* Linux 64 bits */
|
||||||
# elif defined _LP64 && __LINUX__
|
# elif defined _LP64 && __LINUX__
|
||||||
description << ( wxT( "on 64 Bits GNU/Linux" ) );
|
description << ( wxT( "on 64 Bits GNU/Linux" ) );
|
||||||
|
|
||||||
/* Linux 32 bits */
|
/* Linux 32 bits */
|
||||||
# elif defined __LINUX__
|
# elif defined __LINUX__
|
||||||
description << ( wxT( "on 32 Bits GNU/Linux" ) );
|
description << ( wxT( "on 32 Bits GNU/Linux" ) );
|
||||||
|
|
||||||
/* OpenBSD */
|
/* OpenBSD */
|
||||||
# elif defined __OpenBSD__
|
# elif defined __OpenBSD__
|
||||||
description << ( wxT ("on OpenBSD") );
|
description << ( wxT ("on OpenBSD") );
|
||||||
|
|
||||||
/* FreeBSD */
|
/* FreeBSD */
|
||||||
# elif defined __FreeBSD__
|
# elif defined __FreeBSD__
|
||||||
description << ( wxT ("on FreeBSD") );
|
description << ( wxT ("on FreeBSD") );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Websites */
|
/* Websites */
|
||||||
description << wxT( "\n\nKiCad on the web\n\n" );
|
description << wxT( "\n\nKiCad on the web\n\n" );
|
||||||
description << wxT( "http://iut-tice.ujf-grenoble.fr/kicad \n" );
|
description << wxT( "http://iut-tice.ujf-grenoble.fr/kicad \n" );
|
||||||
description << wxT( "http://kicad.sourceforge.net \n" );
|
description << wxT( "http://kicad.sourceforge.net \n" );
|
||||||
description << wxT( "http://www.kicadlib.org" );
|
description << wxT( "http://www.kicadlib.org" );
|
||||||
|
|
||||||
/* Set the complete about description */
|
/* Set the complete about description */
|
||||||
info.SetDescription( description );
|
info.SetDescription( description );
|
||||||
|
|
||||||
/* Set copyright dialog */
|
/* Set copyright dialog */
|
||||||
info.SetCopyright( _T( "(C) 1992-2009 KiCad Developers Team" ) );
|
info.SetCopyright( _T( "(C) 1992-2009 KiCad Developers Team" ) );
|
||||||
|
|
||||||
/* Set license dialog */
|
/* Set license dialog */
|
||||||
info.SetLicence( wxString::FromAscii
|
info.SetLicence( wxString::FromAscii
|
||||||
( "The complete KiCad EDA Suite is released under the\n"
|
( "The complete KiCad EDA Suite is released under the\n"
|
||||||
"GNU General Public License version 2.\n"
|
"GNU General Public License version 2.\n"
|
||||||
"See <http://www.gnu.org/licenses/> for more information."
|
"See <http://www.gnu.org/licenses/> for more information."
|
||||||
));
|
));
|
||||||
|
|
||||||
/* Add developers */
|
/* Add developers */
|
||||||
info.AddDeveloper( wxT( "Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) );
|
info.AddDeveloper( wxT( "Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Dick Hollenbeck <dick@softplc.com>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Dick Hollenbeck <dick@softplc.com>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Hauptmech <hauptmech@gmail.com>") ) );
|
info.AddDeveloper( SetMsg( wxT( "Hauptmech <hauptmech@gmail.com>") ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Jonas Diemer <diemer@gmx.de>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Jonas Diemer <diemer@gmx.de>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "KBool Library <http://boolean.klaasholwerda.nl/bool.html>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "KBool Library <http://boolean.klaasholwerda.nl/bool.html>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Lorenzo <lomarcan@tin.it>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Lorenzo <lomarcan@tin.it>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Marco Serantoni <marco.serantoni@gmail.com>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Marco Serantoni <marco.serantoni@gmail.com>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Rok Markovic <rok@kanardia.eu>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Rok Markovic <rok@kanardia.eu>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Tim Hanson <sideskate@gmail.com>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Tim Hanson <sideskate@gmail.com>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Vesa Solonen <vesa.solonen@hut.fi>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Vesa Solonen <vesa.solonen@hut.fi>" ) ) );
|
||||||
info.AddDeveloper( SetMsg( wxT( "Wayne Stambaugh <stambaughw@verizon.net>" ) ) );
|
info.AddDeveloper( SetMsg( wxT( "Wayne Stambaugh <stambaughw@verizon.net>" ) ) );
|
||||||
|
|
||||||
/* Add document writers*/
|
/* Add document writers*/
|
||||||
info.AddDocWriter( wxT( "Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) );
|
info.AddDocWriter( wxT( "Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) );
|
||||||
info.AddDocWriter( SetMsg( wxT( "Igor Plyatov <plyatov@gmail.com>" ) ) );
|
info.AddDocWriter( SetMsg( wxT( "Igor Plyatov <plyatov@gmail.com>" ) ) );
|
||||||
|
|
||||||
/* Add translators */
|
/* Add translators */
|
||||||
info.AddTranslator( wxT( "Czech (CZ) Martin Kratoška <martin@ok1rr.com>" ) );
|
info.AddTranslator( wxT( "Czech (CZ) Martin Kratoška <martin@ok1rr.com>" ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Dutch (NL) Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Dutch (NL) Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "French (FR) Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "French (FR) Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Polish (PL) Mateusz Skowroński <skowri@gmail.com>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Polish (PL) Mateusz Skowroński <skowri@gmail.com>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Portuguese (PT) Renie Marquet <reniemarquet@uol.com.br>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Portuguese (PT) Renie Marquet <reniemarquet@uol.com.br>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Russian (RU) Igor Plyatov <plyatov@gmail.com>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Russian (RU) Igor Plyatov <plyatov@gmail.com>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Spanish (ES) Pedro Martin del Valle <pkicad@yahoo.es>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Spanish (ES) Pedro Martin del Valle <pkicad@yahoo.es>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Spanish (ES) Iñigo Zuluaga <inigo_zuluaga@yahoo.es>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Spanish (ES) Iñigo Zuluaga <inigo_zuluaga@yahoo.es>" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "German (DE) Rafael Sokolowski <rafael.sokolowski@web.de>" ) ) );
|
info.AddTranslator( SetMsg( wxT( "German (DE) Rafael Sokolowski <rafael.sokolowski@web.de>" ) ) );
|
||||||
|
|
||||||
/* TODO are these all russian translators, placed them here now TODO
|
/* TODO are these all russian translators, placed them here now TODO
|
||||||
TODO or else align them below other language maintainer with mail adres TODO*/
|
TODO or else align them below other language maintainer with mail adres TODO*/
|
||||||
info.AddTranslator( SetMsg( wxT( "\nRemy Halvick" ) ) );
|
info.AddTranslator( SetMsg( wxT( "\nRemy Halvick" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "David Briscoe" ) ) );
|
info.AddTranslator( SetMsg( wxT( "David Briscoe" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Dominique Laigle" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Dominique Laigle" ) ) );
|
||||||
info.AddTranslator( SetMsg( wxT( "Paul Burke" ) ) );
|
info.AddTranslator( SetMsg( wxT( "Paul Burke" ) ) );
|
||||||
|
|
||||||
/* Add programm credits for icons */
|
/* Add programm credits for icons */
|
||||||
info.AddArtist( wxT( "Icons by Iñigo Zuluagaz <inigo_zuluaga@yahoo.es>" ) );
|
info.AddArtist( wxT( "Icons by Iñigo Zuluagaz <inigo_zuluaga@yahoo.es>" ) );
|
||||||
info.AddArtist( SetMsg( wxT( "3D modules by Renie Marquet <reniemarquet@uol.com.br>" ) ) );
|
info.AddArtist( SetMsg( wxT( "3D modules by Renie Marquet <reniemarquet@uol.com.br>" ) ) );
|
||||||
info.AddArtist( SetMsg( wxT( "3D modules by Christophe Boschat <nox454@hotmail.fr>" ) ) );
|
info.AddArtist( SetMsg( wxT( "3D modules by Christophe Boschat <nox454@hotmail.fr>" ) ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 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
|
||||||
|
|
|
@ -0,0 +1,404 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 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 <cstdio>
|
||||||
|
#include <cstdlib> // bsearch()
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
|
||||||
|
#include "dsnlexer.h"
|
||||||
|
|
||||||
|
#include "fctsys.h"
|
||||||
|
#include "pcbnew.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int compare( const void* a1, const void* a2 )
|
||||||
|
{
|
||||||
|
const KEYWORD* k1 = (const KEYWORD*) a1;
|
||||||
|
const KEYWORD* k2 = (const KEYWORD*) a2;
|
||||||
|
|
||||||
|
int ret = strcmp( k1->name, k2->name );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----<DSNLEXER>-------------------------------------------------------------
|
||||||
|
|
||||||
|
DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename,
|
||||||
|
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) :
|
||||||
|
reader( aFile, 4096 )
|
||||||
|
|
||||||
|
{
|
||||||
|
keywords = aKeywordTable;
|
||||||
|
keywordCount = aKeywordCount;
|
||||||
|
|
||||||
|
curTok = DSN_NONE;
|
||||||
|
stringDelimiter = '"';
|
||||||
|
filename = aFilename;
|
||||||
|
|
||||||
|
space_in_quoted_tokens = true;
|
||||||
|
|
||||||
|
// "start" should never change until we change the reader. The DSN
|
||||||
|
// format spec supports an include file mechanism but we can add that later
|
||||||
|
// using a std::stack to hold a stack of LINE_READERs to track nesting.
|
||||||
|
start = (char*) reader;
|
||||||
|
|
||||||
|
limit = start;
|
||||||
|
next = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DSNLEXER::findToken( const std::string& tok )
|
||||||
|
{
|
||||||
|
// convert to lower case once, this should be faster than using strcasecmp()
|
||||||
|
// for each test in compare().
|
||||||
|
lowercase.clear();
|
||||||
|
|
||||||
|
for( std::string::const_iterator iter = tok.begin(); iter!=tok.end(); ++iter )
|
||||||
|
lowercase += (char) tolower( *iter );
|
||||||
|
|
||||||
|
KEYWORD search;
|
||||||
|
|
||||||
|
search.name = lowercase.c_str();
|
||||||
|
|
||||||
|
// a boost hashtable might be a few percent faster, depending on
|
||||||
|
// hashtable size and quality of the hash function.
|
||||||
|
|
||||||
|
const KEYWORD* findings = (const KEYWORD*) bsearch( &search,
|
||||||
|
keywords, keywordCount,
|
||||||
|
sizeof(KEYWORD), compare );
|
||||||
|
if( findings )
|
||||||
|
return findings->token;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* DSNLEXER::Syntax( int aTok )
|
||||||
|
{
|
||||||
|
const char* ret;
|
||||||
|
|
||||||
|
switch( aTok )
|
||||||
|
{
|
||||||
|
case DSN_NONE:
|
||||||
|
ret = "NONE";
|
||||||
|
break;
|
||||||
|
case DSN_QUOTE_DEF:
|
||||||
|
ret = "quoted text delimiter";
|
||||||
|
break;
|
||||||
|
case DSN_DASH:
|
||||||
|
ret = "-";
|
||||||
|
break;
|
||||||
|
case DSN_SYMBOL:
|
||||||
|
ret = "symbol";
|
||||||
|
break;
|
||||||
|
case DSN_NUMBER:
|
||||||
|
ret = "number";
|
||||||
|
break;
|
||||||
|
case DSN_RIGHT:
|
||||||
|
ret = ")";
|
||||||
|
break;
|
||||||
|
case DSN_LEFT:
|
||||||
|
ret = "(";
|
||||||
|
break;
|
||||||
|
case DSN_STRING:
|
||||||
|
ret = "quoted string";
|
||||||
|
break;
|
||||||
|
case DSN_EOF:
|
||||||
|
ret = "end of file";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = "???";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* DSNLEXER::GetTokenText( int aTok )
|
||||||
|
{
|
||||||
|
const char* ret;
|
||||||
|
|
||||||
|
if( aTok < 0 )
|
||||||
|
{
|
||||||
|
return Syntax( aTok );
|
||||||
|
}
|
||||||
|
else if( (unsigned) aTok < keywordCount )
|
||||||
|
{
|
||||||
|
ret = keywords[aTok].name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = "token too big";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw (IOError)
|
||||||
|
{
|
||||||
|
aText << wxT(" ") << _("in file") << wxT(" \"") << filename
|
||||||
|
<< wxT("\" ") << _("on line") << wxT(" ") << reader.LineNumber()
|
||||||
|
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset;
|
||||||
|
|
||||||
|
throw IOError( aText );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function isspace
|
||||||
|
* strips the upper bits of the int to ensure the value passed to ::isspace() is
|
||||||
|
* in the range of 0-255
|
||||||
|
*/
|
||||||
|
static inline bool isSpace( int cc )
|
||||||
|
{
|
||||||
|
// make sure int passed to ::isspace() is 0-255
|
||||||
|
return ::isspace( cc & 0xff );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DSNLEXER::NextTok() throw (IOError)
|
||||||
|
{
|
||||||
|
char* cur = next;
|
||||||
|
char* head = cur;
|
||||||
|
|
||||||
|
prevTok = curTok;
|
||||||
|
|
||||||
|
if( curTok != DSN_EOF )
|
||||||
|
{
|
||||||
|
if( cur >= limit )
|
||||||
|
{
|
||||||
|
L_read:
|
||||||
|
int len = readLine();
|
||||||
|
if( len == 0 )
|
||||||
|
{
|
||||||
|
curTok = DSN_EOF;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = start;
|
||||||
|
|
||||||
|
// skip leading whitespace
|
||||||
|
while( cur<limit && isSpace(*cur) )
|
||||||
|
++cur;
|
||||||
|
|
||||||
|
// if the first non-blank character is #, this line is a comment.
|
||||||
|
if( cur<limit && *cur=='#' )
|
||||||
|
goto L_read;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// skip leading whitespace
|
||||||
|
while( cur<limit && isSpace(*cur) )
|
||||||
|
++cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cur >= limit )
|
||||||
|
goto L_read;
|
||||||
|
|
||||||
|
// switching the string_quote character
|
||||||
|
if( prevTok == DSN_STRING_QUOTE )
|
||||||
|
{
|
||||||
|
static const wxString errtxt( _("String delimiter must be a single character of ', \", or $"));
|
||||||
|
|
||||||
|
char cc = *cur;
|
||||||
|
switch( cc )
|
||||||
|
{
|
||||||
|
case '\'':
|
||||||
|
case '$':
|
||||||
|
case '"':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ThrowIOError( errtxt, CurOffset() );
|
||||||
|
}
|
||||||
|
|
||||||
|
curText.clear();
|
||||||
|
curText += cc;
|
||||||
|
|
||||||
|
head = cur+1;
|
||||||
|
|
||||||
|
if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
|
||||||
|
{
|
||||||
|
ThrowIOError( errtxt, CurOffset() );
|
||||||
|
}
|
||||||
|
|
||||||
|
curTok = DSN_QUOTE_DEF;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *cur == '(' )
|
||||||
|
{
|
||||||
|
curText.clear();
|
||||||
|
curText += *cur;
|
||||||
|
|
||||||
|
curTok = DSN_LEFT;
|
||||||
|
head = cur+1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *cur == ')' )
|
||||||
|
{
|
||||||
|
curText.clear();
|
||||||
|
curText += *cur;
|
||||||
|
|
||||||
|
curTok = DSN_RIGHT;
|
||||||
|
head = cur+1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the dash out of a <pin_reference> which is embedded for example
|
||||||
|
like: U2-14 or "U2"-"14"
|
||||||
|
This is detectable by a non-space immediately preceeding the dash.
|
||||||
|
*/
|
||||||
|
if( *cur == '-' && cur>start && !isSpace( cur[-1] ) )
|
||||||
|
{
|
||||||
|
head = cur+1;
|
||||||
|
curText.clear();
|
||||||
|
curText += '-';
|
||||||
|
curTok = DSN_DASH;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle DSN_NUMBER
|
||||||
|
if( strchr( "+-.0123456789", *cur ) )
|
||||||
|
{
|
||||||
|
head = cur+1;
|
||||||
|
while( head<limit && strchr( ".0123456789", *head ) )
|
||||||
|
++head;
|
||||||
|
|
||||||
|
if( (head<limit && isSpace(*head)) || *head==')' || *head=='(' || head==limit )
|
||||||
|
{
|
||||||
|
curText.clear();
|
||||||
|
curText.append( cur, head );
|
||||||
|
curTok = DSN_NUMBER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else it was something like +5V, fall through below
|
||||||
|
}
|
||||||
|
|
||||||
|
// a quoted string
|
||||||
|
if( *cur == stringDelimiter )
|
||||||
|
{
|
||||||
|
++cur; // skip over the leading delimiter: ",', or $
|
||||||
|
|
||||||
|
head = cur;
|
||||||
|
|
||||||
|
while( head<limit && !isStringTerminator( *head ) )
|
||||||
|
++head;
|
||||||
|
|
||||||
|
if( head >= limit )
|
||||||
|
{
|
||||||
|
wxString errtxt(_("Un-terminated delimited string") );
|
||||||
|
ThrowIOError( errtxt, CurOffset() );
|
||||||
|
}
|
||||||
|
|
||||||
|
curText.clear();
|
||||||
|
curText.append( cur, head );
|
||||||
|
|
||||||
|
++head; // skip over the trailing delimiter
|
||||||
|
|
||||||
|
curTok = DSN_STRING;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe it is a token we will find in the token table.
|
||||||
|
// If not, then call it a DSN_SYMBOL.
|
||||||
|
{
|
||||||
|
head = cur+1;
|
||||||
|
while( head<limit && !isSpace( *head ) && *head!=')' && *head!='(' )
|
||||||
|
++head;
|
||||||
|
|
||||||
|
curText.clear();
|
||||||
|
curText.append( cur, head );
|
||||||
|
|
||||||
|
int found = findToken( curText );
|
||||||
|
|
||||||
|
if( found != -1 )
|
||||||
|
curTok = found;
|
||||||
|
|
||||||
|
else if( 0 == curText.compare( "string_quote" ) )
|
||||||
|
curTok = DSN_STRING_QUOTE;
|
||||||
|
|
||||||
|
else // unrecogized token, call it a symbol
|
||||||
|
curTok = DSN_SYMBOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: // single point of exit, no returns elsewhere please.
|
||||||
|
|
||||||
|
curOffset = cur - start;
|
||||||
|
|
||||||
|
next = head;
|
||||||
|
|
||||||
|
// printf("tok:\"%s\"\n", curText.c_str() );
|
||||||
|
return curTok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 && defined(STANDALONE)
|
||||||
|
|
||||||
|
// stand alone testing
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
|
||||||
|
// wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") );
|
||||||
|
wxString filename( wxT("/tmp/testdesigns/test.dsn") );
|
||||||
|
|
||||||
|
FILE* fp = wxFopen( filename, wxT("r") );
|
||||||
|
|
||||||
|
if( !fp )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "unable to open file \"%s\"\n",
|
||||||
|
(const char*) filename.mb_str() );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this won't compile without a token table.
|
||||||
|
DSNLEXER lexer( fp, filename );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int tok;
|
||||||
|
while( (tok = lexer.NextTok()) != DSN_EOF )
|
||||||
|
{
|
||||||
|
printf( "%-3d %s\n", tok, lexer.CurText() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOError ioe )
|
||||||
|
{
|
||||||
|
printf( "%s\n", (const char*) ioe.errorText.mb_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fp );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,201 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* 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 _DSNLEXER_H
|
||||||
|
#define _DSNLEXER_H
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "fctsys.h"
|
||||||
|
#include "pcbnew.h"
|
||||||
|
|
||||||
|
#include "richio.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct KEYWORD
|
||||||
|
* holds a keyword string and its unique integer token.
|
||||||
|
*/
|
||||||
|
struct KEYWORD
|
||||||
|
{
|
||||||
|
const char* name; ///< unique keyword.
|
||||||
|
int token; ///< a zero based index into an array of KEYWORDs
|
||||||
|
};
|
||||||
|
|
||||||
|
// something like this macro can be used to help initialize a KEYWORD table.
|
||||||
|
// see SPECCTRA_DB::keywords[] as an example.
|
||||||
|
|
||||||
|
//#define TOKDEF(x) { #x, T_##x }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum DSN_SYNTAX_T
|
||||||
|
* lists all the DSN lexer's tokens that are supported in lexing. It is up
|
||||||
|
* to the parser if it wants also to support them.
|
||||||
|
*/
|
||||||
|
enum DSN_SYNTAX_T {
|
||||||
|
DSN_NONE = -10,
|
||||||
|
DSN_STRING_QUOTE = -9,
|
||||||
|
DSN_QUOTE_DEF = -8,
|
||||||
|
DSN_DASH = -7,
|
||||||
|
DSN_SYMBOL = -6,
|
||||||
|
DSN_NUMBER = -5,
|
||||||
|
DSN_RIGHT = -4, // right bracket, ')'
|
||||||
|
DSN_LEFT = -3, // left bracket, '('
|
||||||
|
DSN_STRING = -2, // a quoted string, stripped of the quotes
|
||||||
|
DSN_EOF = -1, // special case for end of file
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DLEXER
|
||||||
|
* implements a lexical analyzer for the SPECCTRA DSN file format. It
|
||||||
|
* reads lexical tokens from the current LINE_READER through the NextTok()
|
||||||
|
* function. The NextTok() function returns one of the DSN_T values.
|
||||||
|
*/
|
||||||
|
class DSNLEXER
|
||||||
|
{
|
||||||
|
char* next;
|
||||||
|
char* start;
|
||||||
|
char* limit;
|
||||||
|
|
||||||
|
LINE_READER reader;
|
||||||
|
int stringDelimiter;
|
||||||
|
bool space_in_quoted_tokens; ///< blank spaces within quoted strings
|
||||||
|
|
||||||
|
wxString filename;
|
||||||
|
int prevTok; ///< curTok from previous NextTok() call.
|
||||||
|
int curOffset; ///< offset within current line of the current token
|
||||||
|
|
||||||
|
int curTok; ///< the current token obtained on last NextTok()
|
||||||
|
std::string curText; ///< the text of the current token
|
||||||
|
std::string lowercase; ///< a scratch buf holding token in lowercase
|
||||||
|
|
||||||
|
const KEYWORD* keywords;
|
||||||
|
unsigned keywordCount;
|
||||||
|
|
||||||
|
|
||||||
|
int readLine() throw (IOError)
|
||||||
|
{
|
||||||
|
int len = reader.ReadLine();
|
||||||
|
|
||||||
|
next = start;
|
||||||
|
limit = start + len;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function findToken
|
||||||
|
* takes a string and looks up the string in the list of expected
|
||||||
|
* tokens.
|
||||||
|
*
|
||||||
|
* @param tok A string holding the token text to lookup, in an
|
||||||
|
* unpredictable case: uppercase or lowercase
|
||||||
|
* @return int - DSN_T or -1 if argument string is not a recognized token.
|
||||||
|
*/
|
||||||
|
int findToken( const std::string& tok );
|
||||||
|
|
||||||
|
bool isStringTerminator( char cc )
|
||||||
|
{
|
||||||
|
if( !space_in_quoted_tokens && cc==' ' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( cc == stringDelimiter )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor DSNLEXER
|
||||||
|
* intializes a DSN lexer and prepares to read from aFile which
|
||||||
|
* is already open and has aFilename.
|
||||||
|
*
|
||||||
|
* @param aKeywordTable is an array of KEYWORDS holding \a aKeywordCount. This
|
||||||
|
* token table need not contain the lexer separators such as '(' ')', etc.
|
||||||
|
* @param aKeywordTable is the count of tokens in aKeywordTable.
|
||||||
|
*/
|
||||||
|
DSNLEXER( FILE* aFile, const wxString& aFilename,
|
||||||
|
const KEYWORD* aKeywordTable, unsigned aKeywordCount );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetStringDelimiter
|
||||||
|
* changes the string delimiter from the default " to some other character
|
||||||
|
* and returns the old value.
|
||||||
|
* @param aStringDelimiter The character in lowest 8 bits.
|
||||||
|
* @return int - The old delimiter in the lowest 8 bits.
|
||||||
|
*/
|
||||||
|
int SetStringDelimiter( int aStringDelimiter )
|
||||||
|
{
|
||||||
|
int old = stringDelimiter;
|
||||||
|
stringDelimiter = aStringDelimiter;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetSpaceInQuotedTokens
|
||||||
|
* changes the setting controlling whether a space in a quoted string is
|
||||||
|
* a terminator.
|
||||||
|
* @param val If true, means
|
||||||
|
*/
|
||||||
|
bool SetSpaceInQuotedTokens( bool val )
|
||||||
|
{
|
||||||
|
bool old = space_in_quoted_tokens;
|
||||||
|
space_in_quoted_tokens = val;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function NextTok
|
||||||
|
* returns the next token found in the input file or T_EOF when reaching
|
||||||
|
* the end of file.
|
||||||
|
* @return int - the type of token found next.
|
||||||
|
* @throw IOError - only if the LINE_READER throws it.
|
||||||
|
*/
|
||||||
|
int NextTok() throw (IOError);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ThrowIOError
|
||||||
|
* encapsulates the formatting of an error message which contains the exact
|
||||||
|
* location within the input file of something the caller is rejecting.
|
||||||
|
*/
|
||||||
|
void ThrowIOError( wxString aText, int charOffset ) throw (IOError);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetTokenString
|
||||||
|
* returns the C string representation of a DSN_T value.
|
||||||
|
*/
|
||||||
|
const char* GetTokenText( int aTok );
|
||||||
|
|
||||||
|
static const char* Syntax( int aTok );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurText
|
||||||
|
* returns a pointer to the current token's text.
|
||||||
|
*/
|
||||||
|
const char* CurText()
|
||||||
|
{
|
||||||
|
return curText.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurTok
|
||||||
|
* returns whatever NextTok() returned the last time it was called.
|
||||||
|
*/
|
||||||
|
int CurTok()
|
||||||
|
{
|
||||||
|
return curTok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurLineNumber
|
||||||
|
* returns the current line number within my LINE_READER
|
||||||
|
*/
|
||||||
|
int CurLineNumber()
|
||||||
|
{
|
||||||
|
return reader.LineNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurFilename
|
||||||
|
* returns the current input filename.
|
||||||
|
* @return const wxString& - the filename.
|
||||||
|
*/
|
||||||
|
const wxString& CurFilename()
|
||||||
|
{
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PrevTok
|
||||||
|
* returns whatever NextTok() returned the 2nd to last time it was called.
|
||||||
|
*/
|
||||||
|
int PrevTok()
|
||||||
|
{
|
||||||
|
return prevTok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CurOffset
|
||||||
|
* returns the char offset within the current line, using a 1 based index.
|
||||||
|
* @return int - a one based index into the current line.
|
||||||
|
*/
|
||||||
|
int CurOffset()
|
||||||
|
{
|
||||||
|
return curOffset + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _DSNLEXER_H
|
|
@ -0,0 +1,265 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
# 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})
|
||||||
|
|
856
pcbnew/dsn.cpp
856
pcbnew/dsn.cpp
|
@ -1,856 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 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 <cstdio>
|
|
||||||
#include <cstdlib> // bsearch()
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
|
|
||||||
#include "dsn.h"
|
|
||||||
|
|
||||||
#include "fctsys.h"
|
|
||||||
#include "pcbnew.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class LEXER
|
|
||||||
* implements a lexical analyzer for the SPECCTRA DSN file format. It
|
|
||||||
* reads lexical tokens from the current LINE_READER through the NextTok()
|
|
||||||
* function. The NextTok() function returns one of the DSN_T values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
namespace DSN {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Struct KEYWORD
|
|
||||||
* holds a string and a DSN_T
|
|
||||||
*/
|
|
||||||
struct KEYWORD
|
|
||||||
{
|
|
||||||
const char* name;
|
|
||||||
// int token;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//#define TOKDEF(x) { #x, T_##x }
|
|
||||||
#define TOKDEF(x) { #x }
|
|
||||||
|
|
||||||
|
|
||||||
// This MUST be sorted alphabetically, and also so MUST enum DSN_T {} be alphabetized.
|
|
||||||
// These MUST all be lower case because of the conversion to lowercase in findToken().
|
|
||||||
const static KEYWORD tokens[] = {
|
|
||||||
TOKDEF(absolute),
|
|
||||||
TOKDEF(added),
|
|
||||||
TOKDEF(add_group),
|
|
||||||
TOKDEF(add_pins),
|
|
||||||
TOKDEF(allow_antenna),
|
|
||||||
TOKDEF(allow_redundant_wiring),
|
|
||||||
TOKDEF(amp),
|
|
||||||
TOKDEF(ancestor),
|
|
||||||
TOKDEF(antipad),
|
|
||||||
TOKDEF(aperture_type),
|
|
||||||
TOKDEF(array),
|
|
||||||
TOKDEF(attach),
|
|
||||||
TOKDEF(attr),
|
|
||||||
TOKDEF(average_pair_length),
|
|
||||||
TOKDEF(back),
|
|
||||||
TOKDEF(base_design),
|
|
||||||
TOKDEF(bbv_ctr2ctr),
|
|
||||||
TOKDEF(bend_keepout),
|
|
||||||
TOKDEF(bond),
|
|
||||||
TOKDEF(both),
|
|
||||||
TOKDEF(bottom),
|
|
||||||
TOKDEF(bottom_layer_sel),
|
|
||||||
TOKDEF(boundary),
|
|
||||||
TOKDEF(brickpat),
|
|
||||||
TOKDEF(bundle),
|
|
||||||
TOKDEF(bus),
|
|
||||||
TOKDEF(bypass),
|
|
||||||
TOKDEF(capacitance_resolution),
|
|
||||||
TOKDEF(capacitor),
|
|
||||||
TOKDEF(case_sensitive),
|
|
||||||
TOKDEF(cct1),
|
|
||||||
TOKDEF(cct1a),
|
|
||||||
TOKDEF(center_center),
|
|
||||||
TOKDEF(checking_trim_by_pin),
|
|
||||||
TOKDEF(circ),
|
|
||||||
TOKDEF(circle),
|
|
||||||
TOKDEF(circuit),
|
|
||||||
TOKDEF(class),
|
|
||||||
TOKDEF(class_class),
|
|
||||||
TOKDEF(classes),
|
|
||||||
TOKDEF(clear),
|
|
||||||
TOKDEF(clearance),
|
|
||||||
TOKDEF(cluster),
|
|
||||||
TOKDEF(cm),
|
|
||||||
TOKDEF(color),
|
|
||||||
TOKDEF(colors),
|
|
||||||
TOKDEF(comment),
|
|
||||||
TOKDEF(comp),
|
|
||||||
TOKDEF(comp_edge_center),
|
|
||||||
TOKDEF(comp_order),
|
|
||||||
TOKDEF(component),
|
|
||||||
TOKDEF(composite),
|
|
||||||
TOKDEF(conductance_resolution),
|
|
||||||
TOKDEF(conductor),
|
|
||||||
TOKDEF(conflict),
|
|
||||||
TOKDEF(connect),
|
|
||||||
TOKDEF(constant),
|
|
||||||
TOKDEF(contact),
|
|
||||||
TOKDEF(control),
|
|
||||||
TOKDEF(corner),
|
|
||||||
TOKDEF(corners),
|
|
||||||
TOKDEF(cost),
|
|
||||||
TOKDEF(created_time),
|
|
||||||
TOKDEF(cross),
|
|
||||||
TOKDEF(crosstalk_model),
|
|
||||||
TOKDEF(current_resolution),
|
|
||||||
TOKDEF(delete_pins),
|
|
||||||
TOKDEF(deleted),
|
|
||||||
TOKDEF(deleted_keepout),
|
|
||||||
TOKDEF(delta),
|
|
||||||
TOKDEF(diagonal),
|
|
||||||
TOKDEF(direction),
|
|
||||||
TOKDEF(directory),
|
|
||||||
TOKDEF(discrete),
|
|
||||||
TOKDEF(effective_via_length),
|
|
||||||
TOKDEF(elongate_keepout),
|
|
||||||
TOKDEF(exclude),
|
|
||||||
TOKDEF(expose),
|
|
||||||
TOKDEF(extra_image_directory),
|
|
||||||
TOKDEF(family),
|
|
||||||
TOKDEF(family_family),
|
|
||||||
TOKDEF(family_family_spacing),
|
|
||||||
TOKDEF(fanout),
|
|
||||||
TOKDEF(farad),
|
|
||||||
TOKDEF(file),
|
|
||||||
TOKDEF(fit),
|
|
||||||
TOKDEF(fix),
|
|
||||||
TOKDEF(flip_style),
|
|
||||||
TOKDEF(floor_plan),
|
|
||||||
TOKDEF(footprint),
|
|
||||||
TOKDEF(forbidden),
|
|
||||||
TOKDEF(force_to_terminal_point),
|
|
||||||
TOKDEF(forgotten),
|
|
||||||
TOKDEF(free),
|
|
||||||
TOKDEF(fromto),
|
|
||||||
TOKDEF(front),
|
|
||||||
TOKDEF(front_only),
|
|
||||||
TOKDEF(gap),
|
|
||||||
TOKDEF(gate),
|
|
||||||
TOKDEF(gates),
|
|
||||||
TOKDEF(generated_by_freeroute),
|
|
||||||
TOKDEF(global),
|
|
||||||
TOKDEF(grid),
|
|
||||||
TOKDEF(group),
|
|
||||||
TOKDEF(group_set),
|
|
||||||
TOKDEF(guide),
|
|
||||||
TOKDEF(hard),
|
|
||||||
TOKDEF(height),
|
|
||||||
TOKDEF(high),
|
|
||||||
TOKDEF(history),
|
|
||||||
TOKDEF(horizontal),
|
|
||||||
TOKDEF(host_cad),
|
|
||||||
TOKDEF(host_version),
|
|
||||||
TOKDEF(image),
|
|
||||||
TOKDEF(image_conductor),
|
|
||||||
TOKDEF(image_image),
|
|
||||||
TOKDEF(image_image_spacing),
|
|
||||||
TOKDEF(image_outline_clearance),
|
|
||||||
TOKDEF(image_set),
|
|
||||||
TOKDEF(image_type),
|
|
||||||
TOKDEF(inch),
|
|
||||||
TOKDEF(include),
|
|
||||||
TOKDEF(include_pins_in_crosstalk),
|
|
||||||
TOKDEF(inductance_resolution),
|
|
||||||
TOKDEF(insert),
|
|
||||||
TOKDEF(instcnfg),
|
|
||||||
TOKDEF(inter_layer_clearance),
|
|
||||||
TOKDEF(jumper),
|
|
||||||
TOKDEF(junction_type),
|
|
||||||
TOKDEF(keepout),
|
|
||||||
TOKDEF(kg),
|
|
||||||
TOKDEF(kohm),
|
|
||||||
TOKDEF(large),
|
|
||||||
TOKDEF(large_large),
|
|
||||||
TOKDEF(layer),
|
|
||||||
TOKDEF(layer_depth),
|
|
||||||
TOKDEF(layer_noise_weight),
|
|
||||||
TOKDEF(layer_pair),
|
|
||||||
TOKDEF(layer_rule),
|
|
||||||
TOKDEF(length),
|
|
||||||
TOKDEF(length_amplitude),
|
|
||||||
TOKDEF(length_factor),
|
|
||||||
TOKDEF(length_gap),
|
|
||||||
TOKDEF(library),
|
|
||||||
TOKDEF(library_out),
|
|
||||||
TOKDEF(limit),
|
|
||||||
TOKDEF(limit_bends),
|
|
||||||
TOKDEF(limit_crossing),
|
|
||||||
TOKDEF(limit_vias),
|
|
||||||
TOKDEF(limit_way),
|
|
||||||
TOKDEF(linear),
|
|
||||||
TOKDEF(linear_interpolation),
|
|
||||||
TOKDEF(load),
|
|
||||||
TOKDEF(lock_type),
|
|
||||||
TOKDEF(logical_part),
|
|
||||||
TOKDEF(logical_part_mapping),
|
|
||||||
TOKDEF(low),
|
|
||||||
TOKDEF(match_fromto_delay),
|
|
||||||
TOKDEF(match_fromto_length),
|
|
||||||
TOKDEF(match_group_delay),
|
|
||||||
TOKDEF(match_group_length),
|
|
||||||
TOKDEF(match_net_delay),
|
|
||||||
TOKDEF(match_net_length),
|
|
||||||
TOKDEF(max_delay),
|
|
||||||
TOKDEF(max_len),
|
|
||||||
TOKDEF(max_length),
|
|
||||||
TOKDEF(max_noise),
|
|
||||||
TOKDEF(max_restricted_layer_length),
|
|
||||||
TOKDEF(max_stagger),
|
|
||||||
TOKDEF(max_stub),
|
|
||||||
TOKDEF(max_total_delay),
|
|
||||||
TOKDEF(max_total_length),
|
|
||||||
TOKDEF(max_total_vias),
|
|
||||||
TOKDEF(medium),
|
|
||||||
TOKDEF(mhenry),
|
|
||||||
TOKDEF(mho),
|
|
||||||
TOKDEF(microvia),
|
|
||||||
TOKDEF(mid_driven),
|
|
||||||
TOKDEF(mil),
|
|
||||||
TOKDEF(min_gap),
|
|
||||||
TOKDEF(mirror),
|
|
||||||
TOKDEF(mirror_first),
|
|
||||||
TOKDEF(mixed),
|
|
||||||
TOKDEF(mm),
|
|
||||||
TOKDEF(negative_diagonal),
|
|
||||||
TOKDEF(net),
|
|
||||||
TOKDEF(net_number),
|
|
||||||
TOKDEF(net_out),
|
|
||||||
TOKDEF(net_pin_changes),
|
|
||||||
TOKDEF(nets),
|
|
||||||
TOKDEF(network),
|
|
||||||
TOKDEF(network_out),
|
|
||||||
TOKDEF(no),
|
|
||||||
TOKDEF(noexpose),
|
|
||||||
TOKDEF(noise_accumulation),
|
|
||||||
TOKDEF(noise_calculation),
|
|
||||||
TOKDEF(normal),
|
|
||||||
TOKDEF(object_type),
|
|
||||||
TOKDEF(off),
|
|
||||||
TOKDEF(off_grid),
|
|
||||||
TOKDEF(offset),
|
|
||||||
TOKDEF(on),
|
|
||||||
TOKDEF(open),
|
|
||||||
TOKDEF(opposite_side),
|
|
||||||
TOKDEF(order),
|
|
||||||
TOKDEF(orthogonal),
|
|
||||||
TOKDEF(outline),
|
|
||||||
TOKDEF(overlap),
|
|
||||||
TOKDEF(pad),
|
|
||||||
TOKDEF(pad_pad),
|
|
||||||
TOKDEF(padstack),
|
|
||||||
TOKDEF(pair),
|
|
||||||
TOKDEF(parallel),
|
|
||||||
TOKDEF(parallel_noise),
|
|
||||||
TOKDEF(parallel_segment),
|
|
||||||
TOKDEF(parser),
|
|
||||||
TOKDEF(part_library),
|
|
||||||
TOKDEF(path),
|
|
||||||
TOKDEF(pcb),
|
|
||||||
TOKDEF(permit_orient),
|
|
||||||
TOKDEF(permit_side),
|
|
||||||
TOKDEF(physical),
|
|
||||||
TOKDEF(physical_part_mapping),
|
|
||||||
TOKDEF(piggyback),
|
|
||||||
TOKDEF(pin),
|
|
||||||
TOKDEF(pin_allow),
|
|
||||||
TOKDEF(pin_cap_via),
|
|
||||||
TOKDEF(pin_via_cap),
|
|
||||||
TOKDEF(pin_width_taper),
|
|
||||||
TOKDEF(pins),
|
|
||||||
TOKDEF(pintype),
|
|
||||||
TOKDEF(place),
|
|
||||||
TOKDEF(place_boundary),
|
|
||||||
TOKDEF(place_control),
|
|
||||||
TOKDEF(place_keepout),
|
|
||||||
TOKDEF(place_rule),
|
|
||||||
TOKDEF(placement),
|
|
||||||
TOKDEF(plan),
|
|
||||||
TOKDEF(plane),
|
|
||||||
TOKDEF(pn),
|
|
||||||
TOKDEF(point),
|
|
||||||
TOKDEF(polyline_path), // used by freerouting.com
|
|
||||||
TOKDEF(polygon),
|
|
||||||
TOKDEF(position),
|
|
||||||
TOKDEF(positive_diagonal),
|
|
||||||
TOKDEF(power),
|
|
||||||
TOKDEF(power_dissipation),
|
|
||||||
TOKDEF(power_fanout),
|
|
||||||
TOKDEF(prefix),
|
|
||||||
TOKDEF(primary),
|
|
||||||
TOKDEF(priority),
|
|
||||||
TOKDEF(property),
|
|
||||||
TOKDEF(protect),
|
|
||||||
TOKDEF(qarc),
|
|
||||||
TOKDEF(quarter),
|
|
||||||
TOKDEF(radius),
|
|
||||||
TOKDEF(ratio),
|
|
||||||
TOKDEF(ratio_tolerance),
|
|
||||||
TOKDEF(rect),
|
|
||||||
TOKDEF(reduced),
|
|
||||||
TOKDEF(region),
|
|
||||||
TOKDEF(region_class),
|
|
||||||
TOKDEF(region_class_class),
|
|
||||||
TOKDEF(region_net),
|
|
||||||
TOKDEF(relative_delay),
|
|
||||||
TOKDEF(relative_group_delay),
|
|
||||||
TOKDEF(relative_group_length),
|
|
||||||
TOKDEF(relative_length),
|
|
||||||
TOKDEF(reorder),
|
|
||||||
TOKDEF(reroute_order_viols),
|
|
||||||
TOKDEF(resistance_resolution),
|
|
||||||
TOKDEF(resistor),
|
|
||||||
TOKDEF(resolution),
|
|
||||||
TOKDEF(restricted_layer_length_factor),
|
|
||||||
TOKDEF(room),
|
|
||||||
TOKDEF(rotate),
|
|
||||||
TOKDEF(rotate_first),
|
|
||||||
TOKDEF(round),
|
|
||||||
TOKDEF(roundoff_rotation),
|
|
||||||
TOKDEF(route),
|
|
||||||
TOKDEF(route_to_fanout_only),
|
|
||||||
TOKDEF(routes),
|
|
||||||
TOKDEF(routes_include),
|
|
||||||
TOKDEF(rule),
|
|
||||||
TOKDEF(same_net_checking),
|
|
||||||
TOKDEF(sample_window),
|
|
||||||
TOKDEF(saturation_length),
|
|
||||||
TOKDEF(sec),
|
|
||||||
TOKDEF(secondary),
|
|
||||||
TOKDEF(self),
|
|
||||||
TOKDEF(sequence_number),
|
|
||||||
TOKDEF(session),
|
|
||||||
TOKDEF(set_color),
|
|
||||||
TOKDEF(set_pattern),
|
|
||||||
TOKDEF(shape),
|
|
||||||
TOKDEF(shield),
|
|
||||||
TOKDEF(shield_gap),
|
|
||||||
TOKDEF(shield_loop),
|
|
||||||
TOKDEF(shield_tie_down_interval),
|
|
||||||
TOKDEF(shield_width),
|
|
||||||
TOKDEF(side),
|
|
||||||
TOKDEF(signal),
|
|
||||||
TOKDEF(site),
|
|
||||||
TOKDEF(small),
|
|
||||||
TOKDEF(smd),
|
|
||||||
TOKDEF(snap),
|
|
||||||
TOKDEF(snap_angle),
|
|
||||||
TOKDEF(soft),
|
|
||||||
TOKDEF(source),
|
|
||||||
TOKDEF(space_in_quoted_tokens),
|
|
||||||
TOKDEF(spacing),
|
|
||||||
TOKDEF(spare),
|
|
||||||
TOKDEF(spiral_via),
|
|
||||||
TOKDEF(square),
|
|
||||||
TOKDEF(stack_via),
|
|
||||||
TOKDEF(stack_via_depth),
|
|
||||||
TOKDEF(standard),
|
|
||||||
TOKDEF(starburst),
|
|
||||||
TOKDEF(status),
|
|
||||||
TOKDEF(string_quote),
|
|
||||||
TOKDEF(structure),
|
|
||||||
TOKDEF(structure_out),
|
|
||||||
TOKDEF(subgate),
|
|
||||||
TOKDEF(subgates),
|
|
||||||
TOKDEF(substituted),
|
|
||||||
TOKDEF(such),
|
|
||||||
TOKDEF(suffix),
|
|
||||||
TOKDEF(super_placement),
|
|
||||||
TOKDEF(supply),
|
|
||||||
TOKDEF(supply_pin),
|
|
||||||
TOKDEF(swapping),
|
|
||||||
TOKDEF(switch_window),
|
|
||||||
TOKDEF(system),
|
|
||||||
TOKDEF(tandem_noise),
|
|
||||||
TOKDEF(tandem_segment),
|
|
||||||
TOKDEF(tandem_shield_overhang),
|
|
||||||
TOKDEF(terminal),
|
|
||||||
TOKDEF(terminator),
|
|
||||||
TOKDEF(term_only),
|
|
||||||
TOKDEF(test),
|
|
||||||
TOKDEF(test_points),
|
|
||||||
TOKDEF(testpoint),
|
|
||||||
TOKDEF(threshold),
|
|
||||||
TOKDEF(time_length_factor),
|
|
||||||
TOKDEF(time_resolution),
|
|
||||||
TOKDEF(tjunction),
|
|
||||||
TOKDEF(tolerance),
|
|
||||||
TOKDEF(top),
|
|
||||||
TOKDEF(topology),
|
|
||||||
TOKDEF(total),
|
|
||||||
TOKDEF(track_id),
|
|
||||||
TOKDEF(turret),
|
|
||||||
TOKDEF(type),
|
|
||||||
TOKDEF(um),
|
|
||||||
TOKDEF(unassigned),
|
|
||||||
TOKDEF(unconnects),
|
|
||||||
TOKDEF(unit),
|
|
||||||
TOKDEF(up),
|
|
||||||
TOKDEF(use_array),
|
|
||||||
TOKDEF(use_layer),
|
|
||||||
TOKDEF(use_net),
|
|
||||||
TOKDEF(use_via),
|
|
||||||
TOKDEF(value),
|
|
||||||
TOKDEF(vertical),
|
|
||||||
TOKDEF(via),
|
|
||||||
TOKDEF(via_array_template),
|
|
||||||
TOKDEF(via_at_smd),
|
|
||||||
TOKDEF(via_keepout),
|
|
||||||
TOKDEF(via_number),
|
|
||||||
TOKDEF(via_rotate_first),
|
|
||||||
TOKDEF(via_site),
|
|
||||||
TOKDEF(via_size),
|
|
||||||
TOKDEF(virtual_pin),
|
|
||||||
TOKDEF(volt),
|
|
||||||
TOKDEF(voltage_resolution),
|
|
||||||
TOKDEF(was_is),
|
|
||||||
TOKDEF(way),
|
|
||||||
TOKDEF(weight),
|
|
||||||
TOKDEF(width),
|
|
||||||
TOKDEF(window),
|
|
||||||
TOKDEF(wire),
|
|
||||||
TOKDEF(wire_keepout),
|
|
||||||
TOKDEF(wires),
|
|
||||||
TOKDEF(wires_include),
|
|
||||||
TOKDEF(wiring),
|
|
||||||
TOKDEF(write_resolution),
|
|
||||||
TOKDEF(x),
|
|
||||||
TOKDEF(xy),
|
|
||||||
TOKDEF(y),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int compare( const void* a1, const void* a2 )
|
|
||||||
{
|
|
||||||
const KEYWORD* k1 = (const KEYWORD*) a1;
|
|
||||||
const KEYWORD* k2 = (const KEYWORD*) a2;
|
|
||||||
|
|
||||||
int ret = strcmp( k1->name, k2->name );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----<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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----<LEXER>-------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
LEXER::LEXER( FILE* aFile, const wxString& aFilename ) :
|
|
||||||
reader( aFile, 4096 )
|
|
||||||
{
|
|
||||||
curTok = T_END;
|
|
||||||
stringDelimiter = '"';
|
|
||||||
filename = aFilename;
|
|
||||||
|
|
||||||
space_in_quoted_tokens = true;
|
|
||||||
|
|
||||||
// "start" should never change until we change the reader. The DSN
|
|
||||||
// format spec supports an include file mechanism but we can add that later
|
|
||||||
// using a std::stack to hold a stack of LINE_READERs to track nesting.
|
|
||||||
start = (char*) reader;
|
|
||||||
|
|
||||||
limit = start;
|
|
||||||
next = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int LEXER::findToken( const std::string& tok )
|
|
||||||
{
|
|
||||||
// convert to lower case once, this should be faster than using strcasecmp()
|
|
||||||
// for each test in compare().
|
|
||||||
lowercase.clear();
|
|
||||||
|
|
||||||
for( std::string::const_iterator iter = tok.begin(); iter!=tok.end(); ++iter )
|
|
||||||
lowercase += (char) tolower( *iter );
|
|
||||||
|
|
||||||
KEYWORD search;
|
|
||||||
search.name = lowercase.c_str();
|
|
||||||
|
|
||||||
const KEYWORD* findings = (const KEYWORD*) bsearch( &search,
|
|
||||||
tokens, sizeof(tokens)/sizeof(tokens[0]),
|
|
||||||
sizeof(KEYWORD), compare );
|
|
||||||
if( findings )
|
|
||||||
// return findings->token;
|
|
||||||
return findings - tokens;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char* LEXER::GetTokenText( DSN_T aTok )
|
|
||||||
{
|
|
||||||
const char* ret;
|
|
||||||
|
|
||||||
if( aTok < 0 )
|
|
||||||
{
|
|
||||||
switch( aTok )
|
|
||||||
{
|
|
||||||
case T_NONE:
|
|
||||||
ret = "NONE";
|
|
||||||
break;
|
|
||||||
case T_QUOTE_DEF:
|
|
||||||
ret = "quoted text delimiter";
|
|
||||||
break;
|
|
||||||
case T_DASH:
|
|
||||||
ret = "-";
|
|
||||||
break;
|
|
||||||
case T_SYMBOL:
|
|
||||||
ret = "symbol";
|
|
||||||
break;
|
|
||||||
case T_NUMBER:
|
|
||||||
ret = "number";
|
|
||||||
break;
|
|
||||||
case T_RIGHT:
|
|
||||||
ret = ")";
|
|
||||||
break;
|
|
||||||
case T_LEFT:
|
|
||||||
ret = "(";
|
|
||||||
break;
|
|
||||||
case T_STRING:
|
|
||||||
ret = "quoted string";
|
|
||||||
break;
|
|
||||||
case T_EOF:
|
|
||||||
ret = "end of file";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = "???";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = tokens[aTok].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxString LEXER::GetTokenString( DSN_T aTok )
|
|
||||||
{
|
|
||||||
wxString ret;
|
|
||||||
|
|
||||||
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LEXER::ThrowIOError( wxString aText, int charOffset ) throw (IOError)
|
|
||||||
{
|
|
||||||
aText << wxT(" ") << _("in file") << wxT(" \"") << filename
|
|
||||||
<< wxT("\" ") << _("on line") << wxT(" ") << reader.LineNumber()
|
|
||||||
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset;
|
|
||||||
|
|
||||||
throw IOError( aText );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function isspace
|
|
||||||
* strips the upper bits of the int to ensure the value passed to ::isspace() is
|
|
||||||
* in the range of 0-255
|
|
||||||
*/
|
|
||||||
static inline bool isSpace( int cc )
|
|
||||||
{
|
|
||||||
// make sure int passed to ::isspace() is 0-255
|
|
||||||
return ::isspace( cc & 0xff );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DSN_T LEXER::NextTok() throw (IOError)
|
|
||||||
{
|
|
||||||
char* cur = next;
|
|
||||||
char* head = cur;
|
|
||||||
|
|
||||||
prevTok = curTok;
|
|
||||||
|
|
||||||
if( curTok != T_EOF )
|
|
||||||
{
|
|
||||||
if( cur >= limit )
|
|
||||||
{
|
|
||||||
L_read:
|
|
||||||
int len = readLine();
|
|
||||||
if( len == 0 )
|
|
||||||
{
|
|
||||||
curTok = T_EOF;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = start;
|
|
||||||
|
|
||||||
// skip leading whitespace
|
|
||||||
while( cur<limit && isSpace(*cur) )
|
|
||||||
++cur;
|
|
||||||
|
|
||||||
// if the first non-blank character is #, this line is a comment.
|
|
||||||
if( cur<limit && *cur=='#' )
|
|
||||||
goto L_read;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// skip leading whitespace
|
|
||||||
while( cur<limit && isSpace(*cur) )
|
|
||||||
++cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cur >= limit )
|
|
||||||
goto L_read;
|
|
||||||
|
|
||||||
// switching the string_quote character
|
|
||||||
if( prevTok == T_string_quote )
|
|
||||||
{
|
|
||||||
static const wxString errtxt( _("String delimiter must be a single character of ', \", or $"));
|
|
||||||
|
|
||||||
char cc = *cur;
|
|
||||||
switch( cc )
|
|
||||||
{
|
|
||||||
case '\'':
|
|
||||||
case '$':
|
|
||||||
case '"':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
|
||||||
}
|
|
||||||
|
|
||||||
curText.clear();
|
|
||||||
curText += cc;
|
|
||||||
|
|
||||||
head = cur+1;
|
|
||||||
|
|
||||||
if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
|
|
||||||
{
|
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
|
||||||
}
|
|
||||||
|
|
||||||
curTok = T_QUOTE_DEF;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *cur == '(' )
|
|
||||||
{
|
|
||||||
curText.clear();
|
|
||||||
curText += *cur;
|
|
||||||
|
|
||||||
curTok = T_LEFT;
|
|
||||||
head = cur+1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *cur == ')' )
|
|
||||||
{
|
|
||||||
curText.clear();
|
|
||||||
curText += *cur;
|
|
||||||
|
|
||||||
curTok = T_RIGHT;
|
|
||||||
head = cur+1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the dash out of a <pin_reference> which is embedded for example
|
|
||||||
like: U2-14 or "U2"-"14"
|
|
||||||
This is detectable by a non-space immediately preceeding the dash.
|
|
||||||
*/
|
|
||||||
if( *cur == '-' && cur>start && !isSpace( cur[-1] ) )
|
|
||||||
{
|
|
||||||
head = cur+1;
|
|
||||||
curText.clear();
|
|
||||||
curText += '-';
|
|
||||||
curTok = T_DASH;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle T_NUMBER
|
|
||||||
if( strchr( "+-.0123456789", *cur ) )
|
|
||||||
{
|
|
||||||
head = cur+1;
|
|
||||||
while( head<limit && strchr( ".0123456789", *head ) )
|
|
||||||
++head;
|
|
||||||
|
|
||||||
if( (head<limit && isSpace(*head)) || *head==')' || *head=='(' || head==limit )
|
|
||||||
{
|
|
||||||
curText.clear();
|
|
||||||
curText.append( cur, head );
|
|
||||||
curTok = T_NUMBER;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// else it was something like +5V, fall through below
|
|
||||||
}
|
|
||||||
|
|
||||||
// a quoted string
|
|
||||||
if( *cur == stringDelimiter )
|
|
||||||
{
|
|
||||||
++cur; // skip over the leading delimiter: ",', or $
|
|
||||||
|
|
||||||
head = cur;
|
|
||||||
|
|
||||||
while( head<limit && !isStringTerminator( *head ) )
|
|
||||||
++head;
|
|
||||||
|
|
||||||
if( head >= limit )
|
|
||||||
{
|
|
||||||
wxString errtxt(_("Un-terminated delimited string") );
|
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
|
||||||
}
|
|
||||||
|
|
||||||
curText.clear();
|
|
||||||
curText.append( cur, head );
|
|
||||||
|
|
||||||
++head; // skip over the trailing delimiter
|
|
||||||
|
|
||||||
curTok = T_STRING;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// a token we hope to find in the tokens[] array. If not, then
|
|
||||||
// call it a T_SYMBOL.
|
|
||||||
{
|
|
||||||
head = cur+1;
|
|
||||||
while( head<limit && !isSpace( *head ) && *head!=')' && *head!='(' )
|
|
||||||
++head;
|
|
||||||
|
|
||||||
curText.clear();
|
|
||||||
curText.append( cur, head );
|
|
||||||
|
|
||||||
int found = findToken( curText );
|
|
||||||
|
|
||||||
if( found != -1 )
|
|
||||||
curTok = (DSN_T) found;
|
|
||||||
|
|
||||||
else // unrecogized token, call it a symbol
|
|
||||||
curTok = T_SYMBOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit: // single point of exit
|
|
||||||
|
|
||||||
curOffset = cur - start;
|
|
||||||
|
|
||||||
next = head;
|
|
||||||
|
|
||||||
// printf("tok:\"%s\"\n", curText.c_str() );
|
|
||||||
|
|
||||||
return curTok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace DSN
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0 && defined(STANDALONE)
|
|
||||||
|
|
||||||
// stand alone testing
|
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
|
||||||
{
|
|
||||||
|
|
||||||
// wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") );
|
|
||||||
wxString filename( wxT("/tmp/testdesigns/test.dsn") );
|
|
||||||
|
|
||||||
FILE* fp = wxFopen( filename, wxT("r") );
|
|
||||||
|
|
||||||
if( !fp )
|
|
||||||
{
|
|
||||||
fprintf( stderr, "unable to open file \"%s\"\n",
|
|
||||||
(const char*) filename.mb_str() );
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
DSN::LEXER lexer( fp, filename );
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int tok;
|
|
||||||
while( (tok = lexer.NextTok()) != DSN::T_EOF )
|
|
||||||
{
|
|
||||||
printf( "%-3d %s\n", tok, lexer.CurText() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch( DSN::IOError ioe )
|
|
||||||
{
|
|
||||||
printf( "%s\n", (const char*) ioe.errorText.mb_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose( fp );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
725
pcbnew/dsn.h
725
pcbnew/dsn.h
|
@ -1,725 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 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 _DSN_H
|
|
||||||
#define _DSN_H
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "fctsys.h"
|
|
||||||
#include "pcbnew.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DSN {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enum DSN_T
|
|
||||||
* lists all the DSN lexer's tokens that are supported in lexing. It is up
|
|
||||||
* to the parser if it wants also to support them.
|
|
||||||
*/
|
|
||||||
enum DSN_T {
|
|
||||||
|
|
||||||
// the first few are special (the uppercase ones)
|
|
||||||
T_NONE = -9,
|
|
||||||
T_QUOTE_DEF = -8,
|
|
||||||
T_DASH = -7,
|
|
||||||
T_SYMBOL = -6,
|
|
||||||
T_NUMBER = -5,
|
|
||||||
T_RIGHT = -4, // right bracket, ')'
|
|
||||||
T_LEFT = -3, // left bracket, '('
|
|
||||||
T_STRING = -2, // a quoted string, stripped of the quotes
|
|
||||||
T_EOF = -1, // special case for end of file
|
|
||||||
|
|
||||||
// from here down, this list segment should be coordinated with the
|
|
||||||
// const static KEYWORD tokens[] array in dsn.cpp, and must be sorted
|
|
||||||
// alphabetically. Remember that '_' is less than any alpha character
|
|
||||||
// according to ASCII.
|
|
||||||
|
|
||||||
T_absolute, // this one should be == zero
|
|
||||||
T_added,
|
|
||||||
T_add_group,
|
|
||||||
T_add_pins,
|
|
||||||
T_allow_antenna,
|
|
||||||
T_allow_redundant_wiring,
|
|
||||||
T_amp,
|
|
||||||
T_ancestor,
|
|
||||||
T_antipad,
|
|
||||||
T_aperture_type,
|
|
||||||
T_array,
|
|
||||||
T_attach,
|
|
||||||
T_attr,
|
|
||||||
T_average_pair_length,
|
|
||||||
T_back,
|
|
||||||
T_base_design,
|
|
||||||
T_bbv_ctr2ctr,
|
|
||||||
T_bend_keepout,
|
|
||||||
T_bond,
|
|
||||||
T_both,
|
|
||||||
T_bottom,
|
|
||||||
T_bottom_layer_sel,
|
|
||||||
T_boundary,
|
|
||||||
T_brickpat,
|
|
||||||
T_bundle,
|
|
||||||
T_bus,
|
|
||||||
T_bypass,
|
|
||||||
T_capacitance_resolution,
|
|
||||||
T_capacitor,
|
|
||||||
T_case_sensitive,
|
|
||||||
T_cct1,
|
|
||||||
T_cct1a,
|
|
||||||
T_center_center,
|
|
||||||
T_checking_trim_by_pin,
|
|
||||||
T_circ,
|
|
||||||
T_circle,
|
|
||||||
T_circuit,
|
|
||||||
T_class,
|
|
||||||
T_class_class,
|
|
||||||
T_classes,
|
|
||||||
T_clear,
|
|
||||||
T_clearance,
|
|
||||||
T_cluster,
|
|
||||||
T_cm,
|
|
||||||
T_color,
|
|
||||||
T_colors,
|
|
||||||
T_comment,
|
|
||||||
T_comp,
|
|
||||||
T_comp_edge_center,
|
|
||||||
T_comp_order,
|
|
||||||
T_component,
|
|
||||||
T_composite,
|
|
||||||
T_conductance_resolution,
|
|
||||||
T_conductor,
|
|
||||||
T_conflict,
|
|
||||||
T_connect,
|
|
||||||
T_constant,
|
|
||||||
T_contact,
|
|
||||||
T_control,
|
|
||||||
T_corner,
|
|
||||||
T_corners,
|
|
||||||
T_cost,
|
|
||||||
T_created_time,
|
|
||||||
T_cross,
|
|
||||||
T_crosstalk_model,
|
|
||||||
T_current_resolution,
|
|
||||||
T_delete_pins,
|
|
||||||
T_deleted,
|
|
||||||
T_deleted_keepout,
|
|
||||||
T_delta,
|
|
||||||
T_diagonal,
|
|
||||||
T_direction,
|
|
||||||
T_directory,
|
|
||||||
T_discrete,
|
|
||||||
T_effective_via_length,
|
|
||||||
T_elongate_keepout,
|
|
||||||
T_exclude,
|
|
||||||
T_expose,
|
|
||||||
T_extra_image_directory,
|
|
||||||
T_family,
|
|
||||||
T_family_family,
|
|
||||||
T_family_family_spacing,
|
|
||||||
T_fanout,
|
|
||||||
T_farad,
|
|
||||||
T_file,
|
|
||||||
T_fit,
|
|
||||||
T_fix,
|
|
||||||
T_flip_style,
|
|
||||||
T_floor_plan,
|
|
||||||
T_footprint,
|
|
||||||
T_forbidden,
|
|
||||||
T_force_to_terminal_point,
|
|
||||||
T_free,
|
|
||||||
T_forgotten,
|
|
||||||
T_fromto,
|
|
||||||
T_front,
|
|
||||||
T_front_only,
|
|
||||||
T_gap,
|
|
||||||
T_gate,
|
|
||||||
T_gates,
|
|
||||||
T_generated_by_freeroute,
|
|
||||||
T_global,
|
|
||||||
T_grid,
|
|
||||||
T_group,
|
|
||||||
T_group_set,
|
|
||||||
T_guide,
|
|
||||||
T_hard,
|
|
||||||
T_height,
|
|
||||||
T_high,
|
|
||||||
T_history,
|
|
||||||
T_horizontal,
|
|
||||||
T_host_cad,
|
|
||||||
T_host_version,
|
|
||||||
T_image,
|
|
||||||
T_image_conductor,
|
|
||||||
T_image_image,
|
|
||||||
T_image_image_spacing,
|
|
||||||
T_image_outline_clearance,
|
|
||||||
T_image_set,
|
|
||||||
T_image_type,
|
|
||||||
T_inch,
|
|
||||||
T_include,
|
|
||||||
T_include_pins_in_crosstalk,
|
|
||||||
T_inductance_resolution,
|
|
||||||
T_insert,
|
|
||||||
T_instcnfg,
|
|
||||||
T_inter_layer_clearance,
|
|
||||||
T_jumper,
|
|
||||||
T_junction_type,
|
|
||||||
T_keepout,
|
|
||||||
T_kg,
|
|
||||||
T_kohm,
|
|
||||||
T_large,
|
|
||||||
T_large_large,
|
|
||||||
T_layer,
|
|
||||||
T_layer_depth,
|
|
||||||
T_layer_noise_weight,
|
|
||||||
T_layer_pair,
|
|
||||||
T_layer_rule,
|
|
||||||
T_length,
|
|
||||||
T_length_amplitude,
|
|
||||||
T_length_factor,
|
|
||||||
T_length_gap,
|
|
||||||
T_library,
|
|
||||||
T_library_out,
|
|
||||||
T_limit,
|
|
||||||
T_limit_bends,
|
|
||||||
T_limit_crossing,
|
|
||||||
T_limit_vias,
|
|
||||||
T_limit_way,
|
|
||||||
T_linear,
|
|
||||||
T_linear_interpolation,
|
|
||||||
T_load,
|
|
||||||
T_lock_type,
|
|
||||||
T_logical_part,
|
|
||||||
T_logical_part_mapping,
|
|
||||||
T_low,
|
|
||||||
T_match_fromto_delay,
|
|
||||||
T_match_fromto_length,
|
|
||||||
T_match_group_delay,
|
|
||||||
T_match_group_length,
|
|
||||||
T_match_net_delay,
|
|
||||||
T_match_net_length,
|
|
||||||
T_max_delay,
|
|
||||||
T_max_len,
|
|
||||||
T_max_length,
|
|
||||||
T_max_noise,
|
|
||||||
T_max_restricted_layer_length,
|
|
||||||
T_max_stagger,
|
|
||||||
T_max_stub,
|
|
||||||
T_max_total_delay,
|
|
||||||
T_max_total_length,
|
|
||||||
T_max_total_vias,
|
|
||||||
T_medium,
|
|
||||||
T_mhenry,
|
|
||||||
T_mho,
|
|
||||||
T_microvia,
|
|
||||||
T_mid_driven,
|
|
||||||
T_mil,
|
|
||||||
T_min_gap,
|
|
||||||
T_mirror,
|
|
||||||
T_mirror_first,
|
|
||||||
T_mixed,
|
|
||||||
T_mm,
|
|
||||||
T_negative_diagonal,
|
|
||||||
T_net,
|
|
||||||
T_net_number,
|
|
||||||
T_net_out,
|
|
||||||
T_net_pin_changes,
|
|
||||||
T_nets,
|
|
||||||
T_network,
|
|
||||||
T_network_out,
|
|
||||||
T_no,
|
|
||||||
T_noexpose,
|
|
||||||
T_noise_accumulation,
|
|
||||||
T_noise_calculation,
|
|
||||||
T_normal,
|
|
||||||
T_object_type,
|
|
||||||
T_off,
|
|
||||||
T_off_grid,
|
|
||||||
T_offset,
|
|
||||||
T_on,
|
|
||||||
T_open,
|
|
||||||
T_opposite_side,
|
|
||||||
T_order,
|
|
||||||
T_orthogonal,
|
|
||||||
T_outline,
|
|
||||||
T_overlap,
|
|
||||||
T_pad,
|
|
||||||
T_pad_pad,
|
|
||||||
T_padstack,
|
|
||||||
T_pair,
|
|
||||||
T_parallel,
|
|
||||||
T_parallel_noise,
|
|
||||||
T_parallel_segment,
|
|
||||||
T_parser,
|
|
||||||
T_part_library,
|
|
||||||
T_path,
|
|
||||||
T_pcb,
|
|
||||||
T_permit_orient,
|
|
||||||
T_permit_side,
|
|
||||||
T_physical,
|
|
||||||
T_physical_part_mapping,
|
|
||||||
T_piggyback,
|
|
||||||
T_pin,
|
|
||||||
T_pin_allow,
|
|
||||||
T_pin_cap_via,
|
|
||||||
T_pin_via_cap,
|
|
||||||
T_pin_width_taper,
|
|
||||||
T_pins,
|
|
||||||
T_pintype,
|
|
||||||
T_place,
|
|
||||||
T_place_boundary,
|
|
||||||
T_place_control,
|
|
||||||
T_place_keepout,
|
|
||||||
T_place_rule,
|
|
||||||
T_placement,
|
|
||||||
T_plan,
|
|
||||||
T_plane,
|
|
||||||
T_pn,
|
|
||||||
T_point,
|
|
||||||
T_polyline_path,
|
|
||||||
T_polygon,
|
|
||||||
T_position,
|
|
||||||
T_positive_diagonal,
|
|
||||||
T_power,
|
|
||||||
T_power_dissipation,
|
|
||||||
T_power_fanout,
|
|
||||||
T_prefix,
|
|
||||||
T_primary,
|
|
||||||
T_priority,
|
|
||||||
T_property,
|
|
||||||
T_protect,
|
|
||||||
T_qarc,
|
|
||||||
T_quarter,
|
|
||||||
T_radius,
|
|
||||||
T_ratio,
|
|
||||||
T_ratio_tolerance,
|
|
||||||
T_rect,
|
|
||||||
T_reduced,
|
|
||||||
T_region,
|
|
||||||
T_region_class,
|
|
||||||
T_region_class_class,
|
|
||||||
T_region_net,
|
|
||||||
T_relative_delay,
|
|
||||||
T_relative_group_delay,
|
|
||||||
T_relative_group_length,
|
|
||||||
T_relative_length,
|
|
||||||
T_reorder,
|
|
||||||
T_reroute_order_viols,
|
|
||||||
T_resistance_resolution,
|
|
||||||
T_resistor,
|
|
||||||
T_resolution,
|
|
||||||
T_restricted_layer_length_factor,
|
|
||||||
T_room,
|
|
||||||
T_rotate,
|
|
||||||
T_rotate_first,
|
|
||||||
T_round,
|
|
||||||
T_roundoff_rotation,
|
|
||||||
T_route,
|
|
||||||
T_route_to_fanout_only,
|
|
||||||
T_routes,
|
|
||||||
T_routes_include,
|
|
||||||
T_rule,
|
|
||||||
T_same_net_checking,
|
|
||||||
T_sample_window,
|
|
||||||
T_saturation_length,
|
|
||||||
T_sec,
|
|
||||||
T_secondary,
|
|
||||||
T_self,
|
|
||||||
T_sequence_number,
|
|
||||||
T_session,
|
|
||||||
T_set_color,
|
|
||||||
T_set_pattern,
|
|
||||||
T_shape,
|
|
||||||
T_shield,
|
|
||||||
T_shield_gap,
|
|
||||||
T_shield_loop,
|
|
||||||
T_shield_tie_down_interval,
|
|
||||||
T_shield_width,
|
|
||||||
T_side,
|
|
||||||
T_signal,
|
|
||||||
T_site,
|
|
||||||
T_small,
|
|
||||||
T_smd,
|
|
||||||
T_snap,
|
|
||||||
T_snap_angle,
|
|
||||||
T_soft,
|
|
||||||
T_source,
|
|
||||||
T_space_in_quoted_tokens,
|
|
||||||
T_spacing,
|
|
||||||
T_spare,
|
|
||||||
T_spiral_via,
|
|
||||||
T_square,
|
|
||||||
T_stack_via,
|
|
||||||
T_stack_via_depth,
|
|
||||||
T_standard,
|
|
||||||
T_starburst,
|
|
||||||
T_status,
|
|
||||||
T_string_quote,
|
|
||||||
T_structure,
|
|
||||||
T_structure_out,
|
|
||||||
T_subgate,
|
|
||||||
T_subgates,
|
|
||||||
T_substituted,
|
|
||||||
T_such,
|
|
||||||
T_suffix,
|
|
||||||
T_super_placement,
|
|
||||||
T_supply,
|
|
||||||
T_supply_pin,
|
|
||||||
T_swapping,
|
|
||||||
T_switch_window,
|
|
||||||
T_system,
|
|
||||||
T_tandem_noise,
|
|
||||||
T_tandem_segment,
|
|
||||||
T_tandem_shield_overhang,
|
|
||||||
T_terminal,
|
|
||||||
T_terminator,
|
|
||||||
T_term_only,
|
|
||||||
T_test,
|
|
||||||
T_test_points,
|
|
||||||
T_testpoint,
|
|
||||||
T_threshold,
|
|
||||||
T_time_length_factor,
|
|
||||||
T_time_resolution,
|
|
||||||
T_tjunction,
|
|
||||||
T_tolerance,
|
|
||||||
T_top,
|
|
||||||
T_topology,
|
|
||||||
T_total,
|
|
||||||
T_track_id,
|
|
||||||
T_turret,
|
|
||||||
T_type,
|
|
||||||
T_um,
|
|
||||||
T_unassigned,
|
|
||||||
T_unconnects,
|
|
||||||
T_unit,
|
|
||||||
T_up,
|
|
||||||
T_use_array,
|
|
||||||
T_use_layer,
|
|
||||||
T_use_net,
|
|
||||||
T_use_via,
|
|
||||||
T_value,
|
|
||||||
T_vertical,
|
|
||||||
T_via,
|
|
||||||
T_via_array_template,
|
|
||||||
T_via_at_smd,
|
|
||||||
T_via_keepout,
|
|
||||||
T_via_number,
|
|
||||||
T_via_rotate_first,
|
|
||||||
T_via_site,
|
|
||||||
T_via_size,
|
|
||||||
T_virtual_pin,
|
|
||||||
T_volt,
|
|
||||||
T_voltage_resolution,
|
|
||||||
T_was_is,
|
|
||||||
T_way,
|
|
||||||
T_weight,
|
|
||||||
T_width,
|
|
||||||
T_window,
|
|
||||||
T_wire,
|
|
||||||
T_wire_keepout,
|
|
||||||
T_wires,
|
|
||||||
T_wires_include,
|
|
||||||
T_wiring,
|
|
||||||
T_write_resolution,
|
|
||||||
T_x,
|
|
||||||
T_xy,
|
|
||||||
T_y,
|
|
||||||
T_END // just a sentinel, not a token
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Struct IOError
|
|
||||||
* is a class used to hold an error message and may be thrown from the LEXER.
|
|
||||||
*/
|
|
||||||
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 LEXER
|
|
||||||
* implements a lexical analyzer for the SPECCTRA DSN file format. It
|
|
||||||
* reads lexical tokens from the current LINE_READER through the NextTok()
|
|
||||||
* function. The NextTok() function returns one of the DSN_T values.
|
|
||||||
*/
|
|
||||||
class LEXER
|
|
||||||
{
|
|
||||||
char* next;
|
|
||||||
char* start;
|
|
||||||
char* limit;
|
|
||||||
|
|
||||||
LINE_READER reader;
|
|
||||||
int stringDelimiter;
|
|
||||||
bool space_in_quoted_tokens; ///< blank spaces within quoted strings
|
|
||||||
|
|
||||||
wxString filename;
|
|
||||||
DSN_T prevTok; ///< curTok from previous NextTok() call.
|
|
||||||
int curOffset; ///< offset within current line of the current token
|
|
||||||
|
|
||||||
DSN_T curTok; ///< the current token obtained on last NextTok()
|
|
||||||
std::string curText; ///< the text of the current token
|
|
||||||
std::string lowercase; ///< a scratch buf holding token in lowercase
|
|
||||||
|
|
||||||
|
|
||||||
int readLine() throw (IOError)
|
|
||||||
{
|
|
||||||
int len = reader.ReadLine();
|
|
||||||
|
|
||||||
next = start;
|
|
||||||
limit = start + len;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function findToken
|
|
||||||
* takes a string and looks up the string in the list of expected
|
|
||||||
* tokens.
|
|
||||||
*
|
|
||||||
* @param tok A string holding the token text to lookup, in an
|
|
||||||
* unpredictable case: uppercase or lowercase
|
|
||||||
* @return int - DSN_T or -1 if argument string is not a recognized token.
|
|
||||||
*/
|
|
||||||
int findToken( const std::string& tok );
|
|
||||||
|
|
||||||
bool isStringTerminator( char cc )
|
|
||||||
{
|
|
||||||
if( !space_in_quoted_tokens && cc==' ' )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if( cc == stringDelimiter )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
LEXER( FILE* aFile, const wxString& aFilename );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function SetStringDelimiter
|
|
||||||
* changes the string delimiter from the default " to some other character
|
|
||||||
* and returns the old value.
|
|
||||||
* @param aStringDelimiter The character in lowest 8 bits.
|
|
||||||
* @return int - The old delimiter in the lowest 8 bits.
|
|
||||||
*/
|
|
||||||
int SetStringDelimiter( int aStringDelimiter )
|
|
||||||
{
|
|
||||||
int old = stringDelimiter;
|
|
||||||
stringDelimiter = aStringDelimiter;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function SetSpaceInQuotedTokens
|
|
||||||
* changes the setting controlling whether a space in a quoted string is
|
|
||||||
* a terminator.
|
|
||||||
* @param val If true, means
|
|
||||||
*/
|
|
||||||
bool SetSpaceInQuotedTokens( bool val )
|
|
||||||
{
|
|
||||||
bool old = space_in_quoted_tokens;
|
|
||||||
space_in_quoted_tokens = val;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function NextTok
|
|
||||||
* returns the next token found in the input file or T_EOF when reaching
|
|
||||||
* the end of file.
|
|
||||||
* @return DSN_T - the type of token found next.
|
|
||||||
* @throw IOError - only if the LINE_READER throws it.
|
|
||||||
*/
|
|
||||||
DSN_T NextTok() throw (IOError);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function ThrowIOError
|
|
||||||
* encapsulates the formatting of an error message which contains the exact
|
|
||||||
* location within the input file of something the caller is rejecting.
|
|
||||||
*/
|
|
||||||
void ThrowIOError( wxString aText, int charOffset ) throw (IOError);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetTokenString
|
|
||||||
* returns the wxString representation of a DSN_T value.
|
|
||||||
*/
|
|
||||||
static wxString GetTokenString( DSN_T aTok );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetTokenString
|
|
||||||
* returns the C string representation of a DSN_T value.
|
|
||||||
*/
|
|
||||||
static const char* GetTokenText( DSN_T aTok );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CurText
|
|
||||||
* returns a pointer to the current token's text.
|
|
||||||
*/
|
|
||||||
const char* CurText()
|
|
||||||
{
|
|
||||||
return curText.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CurTok
|
|
||||||
* returns whatever NextTok() returned the last time it was called.
|
|
||||||
*/
|
|
||||||
DSN_T CurTok()
|
|
||||||
{
|
|
||||||
return curTok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CurLineNumber
|
|
||||||
* returns the current line number within my LINE_READER
|
|
||||||
*/
|
|
||||||
int CurLineNumber()
|
|
||||||
{
|
|
||||||
return reader.LineNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CurFilename
|
|
||||||
* returns the current input filename.
|
|
||||||
* @return const wxString& - the filename.
|
|
||||||
*/
|
|
||||||
const wxString& CurFilename()
|
|
||||||
{
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function PrevTok
|
|
||||||
* returns whatever NextTok() returned the 2nd to last time it was called.
|
|
||||||
*/
|
|
||||||
DSN_T PrevTok()
|
|
||||||
{
|
|
||||||
return prevTok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CurOffset
|
|
||||||
* returns the char offset within the current line, using a 1 based index.
|
|
||||||
* @return int - a one based index into the current line.
|
|
||||||
*/
|
|
||||||
int CurOffset()
|
|
||||||
{
|
|
||||||
return curOffset + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace DSN
|
|
||||||
|
|
||||||
#endif // _DSN_H
|
|
|
@ -47,20 +47,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "specctra.h"
|
#include "specctra.h"
|
||||||
|
#include "common.h" // IsOK() & EDA_FileSelector()
|
||||||
|
|
||||||
#include <wx/ffile.h>
|
#include <wx/ffile.h>
|
||||||
|
|
||||||
|
|
||||||
// To build the DSN beautifier and unit tester, simply uncomment this and then
|
// To build the DSN beautifier and unit tester, simply uncomment this and then
|
||||||
// use CMake's makefile to build target "specctra_test".
|
// use CMake's makefile to build target "specctra_test".
|
||||||
#define STANDALONE // define "stand alone, i.e. unit testing"
|
//#define SPECCTRA_TEST // define for "stand alone, i.e. unit testing"
|
||||||
|
|
||||||
|
|
||||||
#if defined(STANDALONE)
|
#if defined(SPECCTRA_TEST)
|
||||||
#define EDA_BASE // build_version.h behavior
|
#define EDA_BASE // build_version.h behavior
|
||||||
#undef COMMON_GLOBL
|
#undef COMMON_GLOBL
|
||||||
#define COMMON_GLOBL // build_version.h behavior
|
#define COMMON_GLOBL // build_version.h behavior
|
||||||
|
@ -72,11 +73,445 @@ namespace DSN {
|
||||||
|
|
||||||
#define NESTWIDTH 2 ///< how many spaces per nestLevel
|
#define NESTWIDTH 2 ///< how many spaces per nestLevel
|
||||||
|
|
||||||
|
#define TOKDEF(x) { #x, T_##x }
|
||||||
|
|
||||||
|
// This MUST be sorted alphabetically, and the order of enum DSN_T {} be
|
||||||
|
// identially alphabetized. These MUST all be lower case because of the
|
||||||
|
// conversion to lowercase in findToken().
|
||||||
|
const KEYWORD SPECCTRA_DB::keywords[] = {
|
||||||
|
|
||||||
|
// Note that TOKDEF(string_quote) has been moved to the
|
||||||
|
// DSNLEXER, and DSN_SYNTAX_T enum, and the string for it is "string_quote".
|
||||||
|
|
||||||
|
TOKDEF(absolute),
|
||||||
|
TOKDEF(added),
|
||||||
|
TOKDEF(add_group),
|
||||||
|
TOKDEF(add_pins),
|
||||||
|
TOKDEF(allow_antenna),
|
||||||
|
TOKDEF(allow_redundant_wiring),
|
||||||
|
TOKDEF(amp),
|
||||||
|
TOKDEF(ancestor),
|
||||||
|
TOKDEF(antipad),
|
||||||
|
TOKDEF(aperture_type),
|
||||||
|
TOKDEF(array),
|
||||||
|
TOKDEF(attach),
|
||||||
|
TOKDEF(attr),
|
||||||
|
TOKDEF(average_pair_length),
|
||||||
|
TOKDEF(back),
|
||||||
|
TOKDEF(base_design),
|
||||||
|
TOKDEF(bbv_ctr2ctr),
|
||||||
|
TOKDEF(bend_keepout),
|
||||||
|
TOKDEF(bond),
|
||||||
|
TOKDEF(both),
|
||||||
|
TOKDEF(bottom),
|
||||||
|
TOKDEF(bottom_layer_sel),
|
||||||
|
TOKDEF(boundary),
|
||||||
|
TOKDEF(brickpat),
|
||||||
|
TOKDEF(bundle),
|
||||||
|
TOKDEF(bus),
|
||||||
|
TOKDEF(bypass),
|
||||||
|
TOKDEF(capacitance_resolution),
|
||||||
|
TOKDEF(capacitor),
|
||||||
|
TOKDEF(case_sensitive),
|
||||||
|
TOKDEF(cct1),
|
||||||
|
TOKDEF(cct1a),
|
||||||
|
TOKDEF(center_center),
|
||||||
|
TOKDEF(checking_trim_by_pin),
|
||||||
|
TOKDEF(circ),
|
||||||
|
TOKDEF(circle),
|
||||||
|
TOKDEF(circuit),
|
||||||
|
TOKDEF(class),
|
||||||
|
TOKDEF(class_class),
|
||||||
|
TOKDEF(classes),
|
||||||
|
TOKDEF(clear),
|
||||||
|
TOKDEF(clearance),
|
||||||
|
TOKDEF(cluster),
|
||||||
|
TOKDEF(cm),
|
||||||
|
TOKDEF(color),
|
||||||
|
TOKDEF(colors),
|
||||||
|
TOKDEF(comment),
|
||||||
|
TOKDEF(comp),
|
||||||
|
TOKDEF(comp_edge_center),
|
||||||
|
TOKDEF(comp_order),
|
||||||
|
TOKDEF(component),
|
||||||
|
TOKDEF(composite),
|
||||||
|
TOKDEF(conductance_resolution),
|
||||||
|
TOKDEF(conductor),
|
||||||
|
TOKDEF(conflict),
|
||||||
|
TOKDEF(connect),
|
||||||
|
TOKDEF(constant),
|
||||||
|
TOKDEF(contact),
|
||||||
|
TOKDEF(control),
|
||||||
|
TOKDEF(corner),
|
||||||
|
TOKDEF(corners),
|
||||||
|
TOKDEF(cost),
|
||||||
|
TOKDEF(created_time),
|
||||||
|
TOKDEF(cross),
|
||||||
|
TOKDEF(crosstalk_model),
|
||||||
|
TOKDEF(current_resolution),
|
||||||
|
TOKDEF(delete_pins),
|
||||||
|
TOKDEF(deleted),
|
||||||
|
TOKDEF(deleted_keepout),
|
||||||
|
TOKDEF(delta),
|
||||||
|
TOKDEF(diagonal),
|
||||||
|
TOKDEF(direction),
|
||||||
|
TOKDEF(directory),
|
||||||
|
TOKDEF(discrete),
|
||||||
|
TOKDEF(effective_via_length),
|
||||||
|
TOKDEF(elongate_keepout),
|
||||||
|
TOKDEF(exclude),
|
||||||
|
TOKDEF(expose),
|
||||||
|
TOKDEF(extra_image_directory),
|
||||||
|
TOKDEF(family),
|
||||||
|
TOKDEF(family_family),
|
||||||
|
TOKDEF(family_family_spacing),
|
||||||
|
TOKDEF(fanout),
|
||||||
|
TOKDEF(farad),
|
||||||
|
TOKDEF(file),
|
||||||
|
TOKDEF(fit),
|
||||||
|
TOKDEF(fix),
|
||||||
|
TOKDEF(flip_style),
|
||||||
|
TOKDEF(floor_plan),
|
||||||
|
TOKDEF(footprint),
|
||||||
|
TOKDEF(forbidden),
|
||||||
|
TOKDEF(force_to_terminal_point),
|
||||||
|
TOKDEF(forgotten),
|
||||||
|
TOKDEF(free),
|
||||||
|
TOKDEF(fromto),
|
||||||
|
TOKDEF(front),
|
||||||
|
TOKDEF(front_only),
|
||||||
|
TOKDEF(gap),
|
||||||
|
TOKDEF(gate),
|
||||||
|
TOKDEF(gates),
|
||||||
|
TOKDEF(generated_by_freeroute),
|
||||||
|
TOKDEF(global),
|
||||||
|
TOKDEF(grid),
|
||||||
|
TOKDEF(group),
|
||||||
|
TOKDEF(group_set),
|
||||||
|
TOKDEF(guide),
|
||||||
|
TOKDEF(hard),
|
||||||
|
TOKDEF(height),
|
||||||
|
TOKDEF(high),
|
||||||
|
TOKDEF(history),
|
||||||
|
TOKDEF(horizontal),
|
||||||
|
TOKDEF(host_cad),
|
||||||
|
TOKDEF(host_version),
|
||||||
|
TOKDEF(image),
|
||||||
|
TOKDEF(image_conductor),
|
||||||
|
TOKDEF(image_image),
|
||||||
|
TOKDEF(image_image_spacing),
|
||||||
|
TOKDEF(image_outline_clearance),
|
||||||
|
TOKDEF(image_set),
|
||||||
|
TOKDEF(image_type),
|
||||||
|
TOKDEF(inch),
|
||||||
|
TOKDEF(include),
|
||||||
|
TOKDEF(include_pins_in_crosstalk),
|
||||||
|
TOKDEF(inductance_resolution),
|
||||||
|
TOKDEF(insert),
|
||||||
|
TOKDEF(instcnfg),
|
||||||
|
TOKDEF(inter_layer_clearance),
|
||||||
|
TOKDEF(jumper),
|
||||||
|
TOKDEF(junction_type),
|
||||||
|
TOKDEF(keepout),
|
||||||
|
TOKDEF(kg),
|
||||||
|
TOKDEF(kohm),
|
||||||
|
TOKDEF(large),
|
||||||
|
TOKDEF(large_large),
|
||||||
|
TOKDEF(layer),
|
||||||
|
TOKDEF(layer_depth),
|
||||||
|
TOKDEF(layer_noise_weight),
|
||||||
|
TOKDEF(layer_pair),
|
||||||
|
TOKDEF(layer_rule),
|
||||||
|
TOKDEF(length),
|
||||||
|
TOKDEF(length_amplitude),
|
||||||
|
TOKDEF(length_factor),
|
||||||
|
TOKDEF(length_gap),
|
||||||
|
TOKDEF(library),
|
||||||
|
TOKDEF(library_out),
|
||||||
|
TOKDEF(limit),
|
||||||
|
TOKDEF(limit_bends),
|
||||||
|
TOKDEF(limit_crossing),
|
||||||
|
TOKDEF(limit_vias),
|
||||||
|
TOKDEF(limit_way),
|
||||||
|
TOKDEF(linear),
|
||||||
|
TOKDEF(linear_interpolation),
|
||||||
|
TOKDEF(load),
|
||||||
|
TOKDEF(lock_type),
|
||||||
|
TOKDEF(logical_part),
|
||||||
|
TOKDEF(logical_part_mapping),
|
||||||
|
TOKDEF(low),
|
||||||
|
TOKDEF(match_fromto_delay),
|
||||||
|
TOKDEF(match_fromto_length),
|
||||||
|
TOKDEF(match_group_delay),
|
||||||
|
TOKDEF(match_group_length),
|
||||||
|
TOKDEF(match_net_delay),
|
||||||
|
TOKDEF(match_net_length),
|
||||||
|
TOKDEF(max_delay),
|
||||||
|
TOKDEF(max_len),
|
||||||
|
TOKDEF(max_length),
|
||||||
|
TOKDEF(max_noise),
|
||||||
|
TOKDEF(max_restricted_layer_length),
|
||||||
|
TOKDEF(max_stagger),
|
||||||
|
TOKDEF(max_stub),
|
||||||
|
TOKDEF(max_total_delay),
|
||||||
|
TOKDEF(max_total_length),
|
||||||
|
TOKDEF(max_total_vias),
|
||||||
|
TOKDEF(medium),
|
||||||
|
TOKDEF(mhenry),
|
||||||
|
TOKDEF(mho),
|
||||||
|
TOKDEF(microvia),
|
||||||
|
TOKDEF(mid_driven),
|
||||||
|
TOKDEF(mil),
|
||||||
|
TOKDEF(min_gap),
|
||||||
|
TOKDEF(mirror),
|
||||||
|
TOKDEF(mirror_first),
|
||||||
|
TOKDEF(mixed),
|
||||||
|
TOKDEF(mm),
|
||||||
|
TOKDEF(negative_diagonal),
|
||||||
|
TOKDEF(net),
|
||||||
|
TOKDEF(net_number),
|
||||||
|
TOKDEF(net_out),
|
||||||
|
TOKDEF(net_pin_changes),
|
||||||
|
TOKDEF(nets),
|
||||||
|
TOKDEF(network),
|
||||||
|
TOKDEF(network_out),
|
||||||
|
TOKDEF(no),
|
||||||
|
TOKDEF(noexpose),
|
||||||
|
TOKDEF(noise_accumulation),
|
||||||
|
TOKDEF(noise_calculation),
|
||||||
|
TOKDEF(normal),
|
||||||
|
TOKDEF(object_type),
|
||||||
|
TOKDEF(off),
|
||||||
|
TOKDEF(off_grid),
|
||||||
|
TOKDEF(offset),
|
||||||
|
TOKDEF(on),
|
||||||
|
TOKDEF(open),
|
||||||
|
TOKDEF(opposite_side),
|
||||||
|
TOKDEF(order),
|
||||||
|
TOKDEF(orthogonal),
|
||||||
|
TOKDEF(outline),
|
||||||
|
TOKDEF(overlap),
|
||||||
|
TOKDEF(pad),
|
||||||
|
TOKDEF(pad_pad),
|
||||||
|
TOKDEF(padstack),
|
||||||
|
TOKDEF(pair),
|
||||||
|
TOKDEF(parallel),
|
||||||
|
TOKDEF(parallel_noise),
|
||||||
|
TOKDEF(parallel_segment),
|
||||||
|
TOKDEF(parser),
|
||||||
|
TOKDEF(part_library),
|
||||||
|
TOKDEF(path),
|
||||||
|
TOKDEF(pcb),
|
||||||
|
TOKDEF(permit_orient),
|
||||||
|
TOKDEF(permit_side),
|
||||||
|
TOKDEF(physical),
|
||||||
|
TOKDEF(physical_part_mapping),
|
||||||
|
TOKDEF(piggyback),
|
||||||
|
TOKDEF(pin),
|
||||||
|
TOKDEF(pin_allow),
|
||||||
|
TOKDEF(pin_cap_via),
|
||||||
|
TOKDEF(pin_via_cap),
|
||||||
|
TOKDEF(pin_width_taper),
|
||||||
|
TOKDEF(pins),
|
||||||
|
TOKDEF(pintype),
|
||||||
|
TOKDEF(place),
|
||||||
|
TOKDEF(place_boundary),
|
||||||
|
TOKDEF(place_control),
|
||||||
|
TOKDEF(place_keepout),
|
||||||
|
TOKDEF(place_rule),
|
||||||
|
TOKDEF(placement),
|
||||||
|
TOKDEF(plan),
|
||||||
|
TOKDEF(plane),
|
||||||
|
TOKDEF(pn),
|
||||||
|
TOKDEF(point),
|
||||||
|
TOKDEF(polyline_path), // used by freerouting.com
|
||||||
|
TOKDEF(polygon),
|
||||||
|
TOKDEF(position),
|
||||||
|
TOKDEF(positive_diagonal),
|
||||||
|
TOKDEF(power),
|
||||||
|
TOKDEF(power_dissipation),
|
||||||
|
TOKDEF(power_fanout),
|
||||||
|
TOKDEF(prefix),
|
||||||
|
TOKDEF(primary),
|
||||||
|
TOKDEF(priority),
|
||||||
|
TOKDEF(property),
|
||||||
|
TOKDEF(protect),
|
||||||
|
TOKDEF(qarc),
|
||||||
|
TOKDEF(quarter),
|
||||||
|
TOKDEF(radius),
|
||||||
|
TOKDEF(ratio),
|
||||||
|
TOKDEF(ratio_tolerance),
|
||||||
|
TOKDEF(rect),
|
||||||
|
TOKDEF(reduced),
|
||||||
|
TOKDEF(region),
|
||||||
|
TOKDEF(region_class),
|
||||||
|
TOKDEF(region_class_class),
|
||||||
|
TOKDEF(region_net),
|
||||||
|
TOKDEF(relative_delay),
|
||||||
|
TOKDEF(relative_group_delay),
|
||||||
|
TOKDEF(relative_group_length),
|
||||||
|
TOKDEF(relative_length),
|
||||||
|
TOKDEF(reorder),
|
||||||
|
TOKDEF(reroute_order_viols),
|
||||||
|
TOKDEF(resistance_resolution),
|
||||||
|
TOKDEF(resistor),
|
||||||
|
TOKDEF(resolution),
|
||||||
|
TOKDEF(restricted_layer_length_factor),
|
||||||
|
TOKDEF(room),
|
||||||
|
TOKDEF(rotate),
|
||||||
|
TOKDEF(rotate_first),
|
||||||
|
TOKDEF(round),
|
||||||
|
TOKDEF(roundoff_rotation),
|
||||||
|
TOKDEF(route),
|
||||||
|
TOKDEF(route_to_fanout_only),
|
||||||
|
TOKDEF(routes),
|
||||||
|
TOKDEF(routes_include),
|
||||||
|
TOKDEF(rule),
|
||||||
|
TOKDEF(same_net_checking),
|
||||||
|
TOKDEF(sample_window),
|
||||||
|
TOKDEF(saturation_length),
|
||||||
|
TOKDEF(sec),
|
||||||
|
TOKDEF(secondary),
|
||||||
|
TOKDEF(self),
|
||||||
|
TOKDEF(sequence_number),
|
||||||
|
TOKDEF(session),
|
||||||
|
TOKDEF(set_color),
|
||||||
|
TOKDEF(set_pattern),
|
||||||
|
TOKDEF(shape),
|
||||||
|
TOKDEF(shield),
|
||||||
|
TOKDEF(shield_gap),
|
||||||
|
TOKDEF(shield_loop),
|
||||||
|
TOKDEF(shield_tie_down_interval),
|
||||||
|
TOKDEF(shield_width),
|
||||||
|
TOKDEF(side),
|
||||||
|
TOKDEF(signal),
|
||||||
|
TOKDEF(site),
|
||||||
|
TOKDEF(small),
|
||||||
|
TOKDEF(smd),
|
||||||
|
TOKDEF(snap),
|
||||||
|
TOKDEF(snap_angle),
|
||||||
|
TOKDEF(soft),
|
||||||
|
TOKDEF(source),
|
||||||
|
TOKDEF(space_in_quoted_tokens),
|
||||||
|
TOKDEF(spacing),
|
||||||
|
TOKDEF(spare),
|
||||||
|
TOKDEF(spiral_via),
|
||||||
|
TOKDEF(square),
|
||||||
|
TOKDEF(stack_via),
|
||||||
|
TOKDEF(stack_via_depth),
|
||||||
|
TOKDEF(standard),
|
||||||
|
TOKDEF(starburst),
|
||||||
|
TOKDEF(status),
|
||||||
|
TOKDEF(structure),
|
||||||
|
TOKDEF(structure_out),
|
||||||
|
TOKDEF(subgate),
|
||||||
|
TOKDEF(subgates),
|
||||||
|
TOKDEF(substituted),
|
||||||
|
TOKDEF(such),
|
||||||
|
TOKDEF(suffix),
|
||||||
|
TOKDEF(super_placement),
|
||||||
|
TOKDEF(supply),
|
||||||
|
TOKDEF(supply_pin),
|
||||||
|
TOKDEF(swapping),
|
||||||
|
TOKDEF(switch_window),
|
||||||
|
TOKDEF(system),
|
||||||
|
TOKDEF(tandem_noise),
|
||||||
|
TOKDEF(tandem_segment),
|
||||||
|
TOKDEF(tandem_shield_overhang),
|
||||||
|
TOKDEF(terminal),
|
||||||
|
TOKDEF(terminator),
|
||||||
|
TOKDEF(term_only),
|
||||||
|
TOKDEF(test),
|
||||||
|
TOKDEF(test_points),
|
||||||
|
TOKDEF(testpoint),
|
||||||
|
TOKDEF(threshold),
|
||||||
|
TOKDEF(time_length_factor),
|
||||||
|
TOKDEF(time_resolution),
|
||||||
|
TOKDEF(tjunction),
|
||||||
|
TOKDEF(tolerance),
|
||||||
|
TOKDEF(top),
|
||||||
|
TOKDEF(topology),
|
||||||
|
TOKDEF(total),
|
||||||
|
TOKDEF(track_id),
|
||||||
|
TOKDEF(turret),
|
||||||
|
TOKDEF(type),
|
||||||
|
TOKDEF(um),
|
||||||
|
TOKDEF(unassigned),
|
||||||
|
TOKDEF(unconnects),
|
||||||
|
TOKDEF(unit),
|
||||||
|
TOKDEF(up),
|
||||||
|
TOKDEF(use_array),
|
||||||
|
TOKDEF(use_layer),
|
||||||
|
TOKDEF(use_net),
|
||||||
|
TOKDEF(use_via),
|
||||||
|
TOKDEF(value),
|
||||||
|
TOKDEF(vertical),
|
||||||
|
TOKDEF(via),
|
||||||
|
TOKDEF(via_array_template),
|
||||||
|
TOKDEF(via_at_smd),
|
||||||
|
TOKDEF(via_keepout),
|
||||||
|
TOKDEF(via_number),
|
||||||
|
TOKDEF(via_rotate_first),
|
||||||
|
TOKDEF(via_site),
|
||||||
|
TOKDEF(via_size),
|
||||||
|
TOKDEF(virtual_pin),
|
||||||
|
TOKDEF(volt),
|
||||||
|
TOKDEF(voltage_resolution),
|
||||||
|
TOKDEF(was_is),
|
||||||
|
TOKDEF(way),
|
||||||
|
TOKDEF(weight),
|
||||||
|
TOKDEF(width),
|
||||||
|
TOKDEF(window),
|
||||||
|
TOKDEF(wire),
|
||||||
|
TOKDEF(wire_keepout),
|
||||||
|
TOKDEF(wires),
|
||||||
|
TOKDEF(wires_include),
|
||||||
|
TOKDEF(wiring),
|
||||||
|
TOKDEF(write_resolution),
|
||||||
|
TOKDEF(x),
|
||||||
|
TOKDEF(xy),
|
||||||
|
TOKDEF(y),
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned SPECCTRA_DB::keywordCount = DIM(SPECCTRA_DB::keywords);
|
||||||
|
|
||||||
|
|
||||||
//-----<SPECCTRA_DB>-------------------------------------------------
|
//-----<SPECCTRA_DB>-------------------------------------------------
|
||||||
|
|
||||||
#if !defined(STANDALONE)
|
const char* SPECCTRA_DB::TokenName( int aTok )
|
||||||
|
{
|
||||||
|
const char* ret;
|
||||||
|
|
||||||
|
if( (unsigned) aTok < keywordCount )
|
||||||
|
{
|
||||||
|
ret = keywords[aTok].name;
|
||||||
|
}
|
||||||
|
else if( aTok < 0 )
|
||||||
|
{
|
||||||
|
return DSNLEXER::Syntax( aTok );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = "token too big";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetTokenText( int aTok )
|
||||||
|
{
|
||||||
|
return SPECCTRA_DB::TokenName( aTok );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString SPECCTRA_DB::GetTokenString( int aTok )
|
||||||
|
{
|
||||||
|
wxString ret;
|
||||||
|
|
||||||
|
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SPECCTRA_TEST)
|
||||||
|
|
||||||
void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
|
void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
|
||||||
{
|
{
|
||||||
|
@ -131,7 +566,7 @@ void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
|
||||||
void SPECCTRA_DB::expecting( DSN_T aTok ) throw( IOError )
|
void SPECCTRA_DB::expecting( DSN_T aTok ) throw( IOError )
|
||||||
{
|
{
|
||||||
wxString errText( _("Expecting") );
|
wxString errText( _("Expecting") );
|
||||||
errText << wxT(" ") << LEXER::GetTokenString( aTok );
|
errText << wxT(" ") << GetTokenString( aTok );
|
||||||
lexer->ThrowIOError( errText, lexer->CurOffset() );
|
lexer->ThrowIOError( errText, lexer->CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +580,7 @@ void SPECCTRA_DB::expecting( const char* text ) throw( IOError )
|
||||||
void SPECCTRA_DB::unexpected( DSN_T aTok ) throw( IOError )
|
void SPECCTRA_DB::unexpected( DSN_T aTok ) throw( IOError )
|
||||||
{
|
{
|
||||||
wxString errText( _("Unexpected") );
|
wxString errText( _("Unexpected") );
|
||||||
errText << wxT(" ") << LEXER::GetTokenString( aTok );
|
errText << wxT(" ") << GetTokenString( aTok );
|
||||||
lexer->ThrowIOError( errText, lexer->CurOffset() );
|
lexer->ThrowIOError( errText, lexer->CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +594,7 @@ void SPECCTRA_DB::unexpected( const char* text ) throw( IOError )
|
||||||
|
|
||||||
DSN_T SPECCTRA_DB::nextTok()
|
DSN_T SPECCTRA_DB::nextTok()
|
||||||
{
|
{
|
||||||
DSN_T ret = lexer->NextTok();
|
DSN_T ret = (DSN_T) lexer->NextTok();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +633,7 @@ DSN_T SPECCTRA_DB::needSYMBOL() throw( IOError )
|
||||||
|
|
||||||
DSN_T SPECCTRA_DB::needSYMBOLorNUMBER() throw( IOError )
|
DSN_T SPECCTRA_DB::needSYMBOLorNUMBER() throw( IOError )
|
||||||
{
|
{
|
||||||
DSN_T tok = nextTok();
|
DSN_T tok = nextTok();
|
||||||
if( !isSymbol( tok ) && tok!=T_NUMBER )
|
if( !isSymbol( tok ) && tok!=T_NUMBER )
|
||||||
expecting( "symbol|number" );
|
expecting( "symbol|number" );
|
||||||
return tok;
|
return tok;
|
||||||
|
@ -206,11 +641,11 @@ DSN_T SPECCTRA_DB::needSYMBOLorNUMBER() throw( IOError )
|
||||||
|
|
||||||
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IOError )
|
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IOError )
|
||||||
{
|
{
|
||||||
DSN_T tok;
|
DSN_T tok;
|
||||||
|
|
||||||
static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
|
static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
|
||||||
|
|
||||||
if( !isSymbol( lexer->CurTok() ) )
|
if( !isSymbol( (DSN_T) lexer->CurTok() ) )
|
||||||
expecting( pin_def );
|
expecting( pin_def );
|
||||||
|
|
||||||
// case for: A12-14, i.e. no wrapping quotes. This should be a single
|
// case for: A12-14, i.e. no wrapping quotes. This should be a single
|
||||||
|
@ -329,7 +764,7 @@ void SPECCTRA_DB::LoadPCB( const wxString& filename ) throw( IOError )
|
||||||
delete lexer;
|
delete lexer;
|
||||||
lexer = 0;
|
lexer = 0;
|
||||||
|
|
||||||
lexer = new LEXER( file.fp(), filename );
|
lexer = new DSNLEXER( file.fp(), filename, SPECCTRA_DB::keywords, SPECCTRA_DB::keywordCount );
|
||||||
|
|
||||||
if( nextTok() != T_LEFT )
|
if( nextTok() != T_LEFT )
|
||||||
expecting( T_LEFT );
|
expecting( T_LEFT );
|
||||||
|
@ -359,7 +794,7 @@ void SPECCTRA_DB::LoadSESSION( const wxString& filename ) throw( IOError )
|
||||||
delete lexer;
|
delete lexer;
|
||||||
lexer = 0;
|
lexer = 0;
|
||||||
|
|
||||||
lexer = new LEXER( file.fp(), filename );
|
lexer = new DSNLEXER( file.fp(), filename, SPECCTRA_DB::keywords, SPECCTRA_DB::keywordCount );
|
||||||
|
|
||||||
if( nextTok() != T_LEFT )
|
if( nextTok() != T_LEFT )
|
||||||
expecting( T_LEFT );
|
expecting( T_LEFT );
|
||||||
|
@ -508,7 +943,7 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
|
||||||
tok = nextTok();
|
tok = nextTok();
|
||||||
switch( tok )
|
switch( tok )
|
||||||
{
|
{
|
||||||
case T_string_quote:
|
case T_STRING_QUOTE:
|
||||||
tok = nextTok();
|
tok = nextTok();
|
||||||
if( tok != T_QUOTE_DEF )
|
if( tok != T_QUOTE_DEF )
|
||||||
expecting( T_QUOTE_DEF );
|
expecting( T_QUOTE_DEF );
|
||||||
|
@ -1200,7 +1635,7 @@ void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth ) throw( IOError )
|
||||||
|
|
||||||
void SPECCTRA_DB::doTOKPROP( TOKPROP* growth ) throw( IOError )
|
void SPECCTRA_DB::doTOKPROP( TOKPROP* growth ) throw( IOError )
|
||||||
{
|
{
|
||||||
DSN_T tok = nextTok();
|
DSN_T tok = nextTok();
|
||||||
|
|
||||||
if( tok<0 )
|
if( tok<0 )
|
||||||
unexpected( lexer->CurText() );
|
unexpected( lexer->CurText() );
|
||||||
|
@ -2613,9 +3048,6 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
|
||||||
int bracketNesting = 1; // we already saw the opening T_LEFT
|
int bracketNesting = 1; // we already saw the opening T_LEFT
|
||||||
DSN_T tok = T_NONE;
|
DSN_T tok = T_NONE;
|
||||||
|
|
||||||
builder += '(';
|
|
||||||
builder += lexer->CurText();
|
|
||||||
|
|
||||||
while( bracketNesting!=0 && tok!=T_EOF )
|
while( bracketNesting!=0 && tok!=T_EOF )
|
||||||
{
|
{
|
||||||
tok = nextTok();
|
tok = nextTok();
|
||||||
|
@ -2628,7 +3060,9 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
|
||||||
|
|
||||||
if( bracketNesting >= 1 )
|
if( bracketNesting >= 1 )
|
||||||
{
|
{
|
||||||
if( lexer->PrevTok() != T_LEFT && tok!=T_RIGHT )
|
DSN_T prevTok = (DSN_T) lexer->PrevTok();
|
||||||
|
|
||||||
|
if( prevTok!=T_LEFT && prevTok!=T_circuit && tok!=T_RIGHT )
|
||||||
builder += ' ';
|
builder += ' ';
|
||||||
|
|
||||||
if( tok==T_STRING )
|
if( tok==T_STRING )
|
||||||
|
@ -2644,9 +3078,8 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
|
||||||
// to bracketNesting == 0, then save the builder and break;
|
// to bracketNesting == 0, then save the builder and break;
|
||||||
if( bracketNesting == 0 )
|
if( bracketNesting == 0 )
|
||||||
{
|
{
|
||||||
builder += ')';
|
growth->circuit.push_back( builder );
|
||||||
growth->circuit.push_back( builder );
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2656,7 +3089,7 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unexpected( lexer->CurText() );
|
unexpected( lexer->CurText() );
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
tok = nextTok();
|
tok = nextTok();
|
||||||
|
@ -3518,41 +3951,6 @@ int SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
||||||
{
|
{
|
||||||
|
@ -3627,91 +4025,6 @@ PCB* SPECCTRA_DB::MakePCB()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----<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 )
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----<ELEM>---------------------------------------------------------------
|
//-----<ELEM>---------------------------------------------------------------
|
||||||
|
|
||||||
ELEM::ELEM( DSN_T aType, ELEM* aParent ) :
|
ELEM::ELEM( DSN_T aType, ELEM* aParent ) :
|
||||||
|
@ -3725,6 +4038,10 @@ ELEM::~ELEM()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* ELEM::Name() const
|
||||||
|
{
|
||||||
|
return SPECCTRA_DB::TokenName( type );
|
||||||
|
}
|
||||||
|
|
||||||
UNIT_RES* ELEM::GetUnits() const
|
UNIT_RES* ELEM::GetUnits() const
|
||||||
{
|
{
|
||||||
|
@ -3737,7 +4054,7 @@ UNIT_RES* ELEM::GetUnits() const
|
||||||
|
|
||||||
void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
{
|
{
|
||||||
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
|
out->Print( nestLevel, "(%s\n", Name() );
|
||||||
|
|
||||||
FormatContents( out, nestLevel+1 );
|
FormatContents( out, nestLevel+1 );
|
||||||
|
|
||||||
|
@ -3903,7 +4220,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
{
|
{
|
||||||
useMultiLine = true;
|
useMultiLine = true;
|
||||||
|
|
||||||
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
|
out->Print( nestLevel, "(%s %s%s%s\n", Name(),
|
||||||
quote, component_id.c_str(), quote );
|
quote, component_id.c_str(), quote );
|
||||||
|
|
||||||
out->Print( nestLevel+1, "%s", "" );
|
out->Print( nestLevel+1, "%s", "" );
|
||||||
|
@ -3912,7 +4229,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
{
|
{
|
||||||
useMultiLine = false;
|
useMultiLine = false;
|
||||||
|
|
||||||
out->Print( nestLevel, "(%s %s%s%s", LEXER::GetTokenText( Type() ),
|
out->Print( nestLevel, "(%s %s%s%s", Name(),
|
||||||
quote, component_id.c_str(), quote );
|
quote, component_id.c_str(), quote );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3920,7 +4237,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
{
|
{
|
||||||
out->Print( 0, " %.6g %.6g", vertex.x, vertex.y );
|
out->Print( 0, " %.6g %.6g", vertex.x, vertex.y );
|
||||||
|
|
||||||
out->Print( 0, " %s", LEXER::GetTokenText( side ) );
|
out->Print( 0, " %s", GetTokenText( side ) );
|
||||||
|
|
||||||
out->Print( 0, " %.6g", rotation );
|
out->Print( 0, " %.6g", rotation );
|
||||||
}
|
}
|
||||||
|
@ -3929,13 +4246,13 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
|
|
||||||
if( mirror != T_NONE )
|
if( mirror != T_NONE )
|
||||||
{
|
{
|
||||||
out->Print( 0, "%s(mirror %s)", space, LEXER::GetTokenText( mirror ) );
|
out->Print( 0, "%s(mirror %s)", space, GetTokenText( mirror ) );
|
||||||
space = "";
|
space = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if( status != T_NONE )
|
if( status != T_NONE )
|
||||||
{
|
{
|
||||||
out->Print( 0, "%s(status %s)", space, LEXER::GetTokenText( status ) );
|
out->Print( 0, "%s(status %s)", space, GetTokenText( status ) );
|
||||||
space = "";
|
space = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3967,8 +4284,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
out->Print( nestLevel+1, ")\n" );
|
out->Print( nestLevel+1, ")\n" );
|
||||||
}
|
}
|
||||||
if( lock_type != T_NONE )
|
if( lock_type != T_NONE )
|
||||||
out->Print( nestLevel+1, "(lock_type %s)\n",
|
out->Print( nestLevel+1, "(lock_type %s)\n", GetTokenText(lock_type) );
|
||||||
LEXER::GetTokenText(lock_type) );
|
|
||||||
if( rules )
|
if( rules )
|
||||||
rules->Format( out, nestLevel+1 );
|
rules->Format( out, nestLevel+1 );
|
||||||
|
|
||||||
|
@ -3986,8 +4302,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
{
|
{
|
||||||
if( lock_type != T_NONE )
|
if( lock_type != T_NONE )
|
||||||
{
|
{
|
||||||
out->Print( 0, "%s(lock_type %s)", space,
|
out->Print( 0, "%s(lock_type %s)", space, GetTokenText(lock_type) );
|
||||||
LEXER::GetTokenText(lock_type) );
|
|
||||||
space = "";
|
space = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4002,16 +4317,17 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||||
out->Print( 0, ")\n" );
|
out->Print( 0, ")\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace DSN
|
} // namespace DSN
|
||||||
|
|
||||||
|
|
||||||
// unit test this source file
|
// unit test this source file. You can use the beautifiers below to output
|
||||||
|
// exactly what you read in but beautified and without #comments. This can
|
||||||
#if defined(STANDALONE)
|
// then be used along with program 'diff' to test the parsing and formatting
|
||||||
|
// of every element. You may have to run the first output back through to
|
||||||
|
// get two files that should match, the 2nd and 3rd outputs.
|
||||||
|
|
||||||
|
|
||||||
#include "common.h" // IsOK() & EDA_FileSelector()
|
#if defined(SPECCTRA_TEST)
|
||||||
|
|
||||||
using namespace DSN;
|
using namespace DSN;
|
||||||
|
|
||||||
|
@ -4035,8 +4351,8 @@ int main( int argc, char** argv )
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
db.LoadPCB( filename );
|
// db.LoadPCB( filename );
|
||||||
// db.LoadSESSION( filename );
|
db.LoadSESSION( filename );
|
||||||
}
|
}
|
||||||
catch( IOError ioe )
|
catch( IOError ioe )
|
||||||
{
|
{
|
||||||
|
@ -4048,18 +4364,25 @@ int main( int argc, char** argv )
|
||||||
fprintf( stderr, "loaded OK\n" );
|
fprintf( stderr, "loaded OK\n" );
|
||||||
|
|
||||||
// export what we read in, making this test program basically a beautifier
|
// export what we read in, making this test program basically a beautifier
|
||||||
// db.ExportSESSION( wxT("/tmp/export.ses") );
|
// hose the beautified DSN file to stdout. If an exception occurred,
|
||||||
// db.ExportPCB( wxT("/tmp/export.dsn") );
|
// we will be outputting only a portion of what we wanted to read in.
|
||||||
|
|
||||||
DSN::PCB* pcb = db.GetPCB();
|
|
||||||
|
|
||||||
// hose the beautified DSN file to stdout.
|
|
||||||
db.SetFILE( stdout );
|
db.SetFILE( stdout );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// export a PCB
|
||||||
|
DSN::PCB* pcb = db.GetPCB();
|
||||||
pcb->Format( &db, 0 );
|
pcb->Format( &db, 0 );
|
||||||
|
|
||||||
|
#else
|
||||||
|
// export a SESSION file.
|
||||||
|
DSN::SESSION* ses = db.GetSESSION();
|
||||||
|
ses->Format( &db, 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
SetLocaleTo_Default( ); // revert to the current locale
|
SetLocaleTo_Default( ); // revert to the current locale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
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
|
||||||
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
|
||||||
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 )
|
||||||
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()
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue