S-expression in xnode.cpp
This commit is contained in:
parent
b615939120
commit
f285c8295b
|
@ -4,6 +4,19 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2010-Aug-7 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++common
|
||||
* add xnode.cpp and xnode.h which can be used to output either an XML or
|
||||
S-expression document file.
|
||||
* Add class STREAM_OUTPUTFORMATTER which is a richio class which can write
|
||||
to any of the wxOutputStream derivatives, such as file, socket, zip, tar.
|
||||
* Added netlist.keywords
|
||||
++eeschema
|
||||
* netform.cpp can now output S-expression OK, although I have it commented out
|
||||
pending the addition of a UI for it.
|
||||
|
||||
|
||||
2010-Aug-4 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++eeschema netform.cpp:
|
||||
|
|
|
@ -147,18 +147,7 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote
|
|||
}
|
||||
|
||||
|
||||
//-----<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 OUTPUTFORMATTER::vprint( const char* fmt, va_list ap ) throw( IOError )
|
||||
{
|
||||
int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );
|
||||
if( ret >= (int) buffer.size() )
|
||||
|
@ -168,13 +157,13 @@ int STRINGFORMATTER::vprint( const char* fmt, va_list ap )
|
|||
}
|
||||
|
||||
if( ret > 0 )
|
||||
mystring.append( (const char*) &buffer[0] );
|
||||
write( &buffer[0], ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int STRINGFORMATTER::sprint( const char* fmt, ... )
|
||||
int OUTPUTFORMATTER::sprint( const char* fmt, ... ) throw( IOError )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
@ -186,9 +175,8 @@ int STRINGFORMATTER::sprint( const char* fmt, ... )
|
|||
}
|
||||
|
||||
|
||||
int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
|
||||
int OUTPUTFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
|
||||
{
|
||||
|
||||
#define NESTWIDTH 2 ///< how many spaces per nestLevel
|
||||
|
||||
va_list args;
|
||||
|
@ -200,17 +188,14 @@ int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError
|
|||
|
||||
for( int i=0; i<nestLevel; ++i )
|
||||
{
|
||||
// no error checking needed, an exception indicates an error.
|
||||
result = sprint( "%*c", NESTWIDTH, ' ' );
|
||||
if( result < 0 )
|
||||
break;
|
||||
|
||||
total += result;
|
||||
}
|
||||
|
||||
if( result<0 || (result=vprint( fmt, args ))<0 )
|
||||
{
|
||||
throw IOError( _("Error writing to STRINGFORMATTER") );
|
||||
}
|
||||
// no error checking needed, an exception indicates an error.
|
||||
result = vprint( fmt, args );
|
||||
|
||||
va_end( args );
|
||||
|
||||
|
@ -219,6 +204,13 @@ int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError
|
|||
}
|
||||
|
||||
|
||||
//-----<STRINGFORMATTER>----------------------------------------------------
|
||||
|
||||
void STRINGFORMATTER::write( const char* aOutBuf, int aCount ) throw( IOError )
|
||||
{
|
||||
mystring.append( aOutBuf, aCount );
|
||||
}
|
||||
|
||||
void STRINGFORMATTER::StripUseless()
|
||||
{
|
||||
std::string copy = mystring;
|
||||
|
@ -234,3 +226,29 @@ void STRINGFORMATTER::StripUseless()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----<STREAM_OUTPUTFORMATTER>--------------------------------------
|
||||
|
||||
const char* STREAM_OUTPUTFORMATTER::GetQuoteChar( const char* wrapee )
|
||||
{
|
||||
return OUTPUTFORMATTER::GetQuoteChar( wrapee, quoteChar );
|
||||
}
|
||||
|
||||
|
||||
void STREAM_OUTPUTFORMATTER::write( const char* aOutBuf, int aCount ) throw( IOError )
|
||||
{
|
||||
int lastWrite;
|
||||
|
||||
// This might delay awhile if you were writing to say a socket, but for
|
||||
// a file it should only go through the loop once.
|
||||
for( int total = 0; total<aCount; total += lastWrite )
|
||||
{
|
||||
lastWrite = os.Write( aOutBuf, aCount ).LastWrite();
|
||||
|
||||
if( !os.IsOk() )
|
||||
{
|
||||
throw IOError( _( "OUTPUTSTREAM_OUTPUTFORMATTER write error" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,46 +24,77 @@
|
|||
|
||||
|
||||
#include "xnode.h"
|
||||
#include "macros.h"
|
||||
|
||||
|
||||
typedef wxXmlProperty XATTR;
|
||||
|
||||
void XNODE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
// output attributes first if they exist
|
||||
switch( GetType() )
|
||||
{
|
||||
case wxXML_ELEMENT_NODE:
|
||||
out->Print( nestLevel, "(%s", CONV_TO_UTF8( GetName() ) );
|
||||
FormatContents( out, nestLevel );
|
||||
if( GetNext() )
|
||||
out->Print( 0, ")\n" );
|
||||
else
|
||||
out->Print( 0, ")" );
|
||||
break;
|
||||
|
||||
// output children if they exist.
|
||||
|
||||
// output "contents" if it exists. Use quote need checker to wrap contents if needed.
|
||||
|
||||
// A good XML element will not have both children AND contents, usually one or the other.
|
||||
// children != attributes in the above statement.
|
||||
|
||||
// for( XNODE*...
|
||||
default:
|
||||
FormatContents( out, nestLevel );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XNODE::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
// overridden in ELEM_HOLDER
|
||||
}
|
||||
std::string utf8;
|
||||
const char* quote;
|
||||
|
||||
|
||||
void XATTR::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
// output attributes first if they exist
|
||||
for( XATTR* attr = (XATTR*) GetAttributes(); attr; attr = (XATTR*) attr->GetNext() )
|
||||
{
|
||||
utf8 = CONV_TO_UTF8( attr->GetValue() ); // capture the content
|
||||
quote = out->GetQuoteChar( utf8.c_str() );
|
||||
|
||||
// output children if they exist.
|
||||
out->Print( 0, " (%s %s%s%s)",
|
||||
// attr names should never need quoting, no spaces, we designed the file.
|
||||
CONV_TO_UTF8( attr->GetName() ),
|
||||
quote, utf8.c_str(), quote );
|
||||
}
|
||||
|
||||
// output "contents" if it exists. Use quote need checker to wrap contents if needed.
|
||||
// we only expect to have used one of two types here:
|
||||
switch( GetType() )
|
||||
{
|
||||
case wxXML_ELEMENT_NODE:
|
||||
|
||||
// A good XML element will not have both children AND contents, usually one or the other.
|
||||
// children != attributes in the above statement.
|
||||
// output children if they exist.
|
||||
for( XNODE* kid = (XNODE*) GetChildren(); kid; kid = (XNODE*) kid->GetNext() )
|
||||
{
|
||||
if( kid->GetType() != wxXML_TEXT_NODE )
|
||||
{
|
||||
if( kid == GetChildren() )
|
||||
out->Print( 0, "\n" );
|
||||
kid->Format( out, nestLevel+1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
kid->Format( out, 0 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// for( XNODE*...
|
||||
}
|
||||
case wxXML_TEXT_NODE:
|
||||
utf8 = CONV_TO_UTF8( GetContent() );
|
||||
quote = out->GetQuoteChar( utf8.c_str() );
|
||||
out->Print( 0, " %s%s%s", quote, utf8.c_str(), quote );
|
||||
break;
|
||||
|
||||
|
||||
void XATTR::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
|
||||
{
|
||||
// overridden in ELEM_HOLDER
|
||||
default:
|
||||
; // not supported
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -190,46 +190,45 @@ class EXPORT_HELP
|
|||
*/
|
||||
void writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
|
||||
|
||||
|
||||
/**
|
||||
* Function makeGenericRoot
|
||||
* builds the entire document tree for the generic export. This is factored
|
||||
* out here so we can write the tree in either S-expression file format
|
||||
* or in XML if we put the tree built here into a wxXmlDocument.
|
||||
*/
|
||||
XNODE* makeGenericRoot();
|
||||
XNODE* makeGenericRoot();
|
||||
|
||||
/**
|
||||
* Function makeGenericComponents
|
||||
* returns a sub-tree holding all the schematic components.
|
||||
*/
|
||||
XNODE* makeGenericComponents();
|
||||
XNODE* makeGenericComponents();
|
||||
|
||||
/**
|
||||
* Function makeGenericDesignHeader
|
||||
* fills out a project "design" header into an XML node.
|
||||
* @return XNODE* - the design header
|
||||
* @return XNODE* - the design header
|
||||
*/
|
||||
XNODE* makeGenericDesignHeader();
|
||||
XNODE* makeGenericDesignHeader();
|
||||
|
||||
/**
|
||||
* Function makeGenericLibParts
|
||||
* fills out an XML node with the unique library parts and returns it.
|
||||
*/
|
||||
XNODE* makeGenericLibParts();
|
||||
XNODE* makeGenericLibParts();
|
||||
|
||||
/**
|
||||
* Function makeGenericListOfNets
|
||||
* fills out an XML node with a list of nets and returns it.
|
||||
*/
|
||||
XNODE* makeGenericListOfNets();
|
||||
XNODE* makeGenericListOfNets();
|
||||
|
||||
/**
|
||||
* Function makeGenericLibraries
|
||||
* fills out an XML node with a list of used libraries and returns it.
|
||||
* Must have called makeGenericLibParts() before this function.
|
||||
*/
|
||||
XNODE* makeGenericLibraries();
|
||||
XNODE* makeGenericLibraries();
|
||||
|
||||
|
||||
public:
|
||||
|
@ -392,6 +391,12 @@ static bool sortPinsByNum( NETLIST_OBJECT* aPin1, NETLIST_OBJECT* aPin2 )
|
|||
return RefDesStringCompare( aPin1->GetPinNumText(), aPin2->GetPinNumText() ) < 0;
|
||||
}
|
||||
|
||||
static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 )
|
||||
{
|
||||
// return "lhs < rhs"
|
||||
return RefDesStringCompare( aPin1->GetNumber(), aPin2->GetNumber() ) < 0;
|
||||
}
|
||||
|
||||
|
||||
void EXPORT_HELP::sprintPinNetName( wxString* aResult,
|
||||
const wxString& aNetNameFormat, NETLIST_OBJECT* aPin )
|
||||
|
@ -577,7 +582,7 @@ static XNODE* node( const wxString& aName, const wxString& aTextualContent = wxE
|
|||
|
||||
XNODE* EXPORT_HELP::makeGenericDesignHeader()
|
||||
{
|
||||
XNODE* xdesign = node( wxT("design") );
|
||||
XNODE* xdesign = node( wxT("design") );
|
||||
char date[128];
|
||||
|
||||
DateAndTime( date );
|
||||
|
@ -616,17 +621,17 @@ XNODE* EXPORT_HELP::makeGenericDesignHeader()
|
|||
}
|
||||
|
||||
|
||||
XNODE* EXPORT_HELP::makeGenericLibraries()
|
||||
XNODE* EXPORT_HELP::makeGenericLibraries()
|
||||
{
|
||||
XNODE* xlibs = node( wxT( "libraries" ) ); // auto_ptr
|
||||
XNODE* xlibs = node( wxT( "libraries" ) ); // auto_ptr
|
||||
|
||||
for( std::set<void*>::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it )
|
||||
{
|
||||
CMP_LIBRARY* lib = (CMP_LIBRARY*) *it;
|
||||
XNODE* xlibrary;
|
||||
XNODE* xlibrary;
|
||||
|
||||
xlibs->AddChild( xlibrary = node( wxT( "library" ) ) );
|
||||
xlibrary->AddProperty( wxT( "logical" ), lib->GetLogicalName() );
|
||||
xlibrary->AddAttribute( wxT( "logical" ), lib->GetLogicalName() );
|
||||
xlibrary->AddChild( node( wxT( "uri" ), lib->GetFullFileName() ) );
|
||||
|
||||
// @todo: add more fun stuff here
|
||||
|
@ -636,7 +641,7 @@ XNODE* EXPORT_HELP::makeGenericLibraries()
|
|||
}
|
||||
|
||||
|
||||
XNODE* EXPORT_HELP::makeGenericLibParts()
|
||||
XNODE* EXPORT_HELP::makeGenericLibParts()
|
||||
{
|
||||
XNODE* xlibparts = node( wxT( "libparts" ) ); // auto_ptr
|
||||
wxString sLibpart = wxT( "libpart" );
|
||||
|
@ -651,7 +656,6 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
wxString sDescr = wxT( "description" );
|
||||
wxString sDocs = wxT( "docs" );
|
||||
|
||||
|
||||
LIB_PIN_LIST pinList;
|
||||
LIB_FIELD_LIST fieldList;
|
||||
|
||||
|
@ -666,8 +670,8 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
|
||||
XNODE* xlibpart;
|
||||
xlibparts->AddChild( xlibpart = node( sLibpart ) );
|
||||
xlibpart->AddProperty( sLib, library->GetLogicalName() );
|
||||
xlibpart->AddProperty( sPart, lcomp->GetName() );
|
||||
xlibpart->AddAttribute( sLib, library->GetLogicalName() );
|
||||
xlibpart->AddAttribute( sPart, lcomp->GetName() );
|
||||
|
||||
//----- show the important properties -------------------------
|
||||
if( !lcomp->GetDescription().IsEmpty() )
|
||||
|
@ -693,7 +697,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
{
|
||||
XNODE* xfield;
|
||||
xfields->AddChild( xfield = node( sField, fieldList[i].m_Text ) );
|
||||
xfield->AddProperty( sName, fieldList[i].m_Name );
|
||||
xfield->AddAttribute( sName, fieldList[i].m_Name );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,7 +705,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
pinList.clear();
|
||||
lcomp->GetPins( pinList, 0, 0 );
|
||||
|
||||
// sort the pin list here?
|
||||
sort( pinList.begin(), pinList.end(), sortPinsByNumber );
|
||||
|
||||
if( pinList.size() )
|
||||
{
|
||||
|
@ -713,7 +717,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
XNODE* pin;
|
||||
|
||||
pins->AddChild( pin = node( sPin ) );
|
||||
pin->AddProperty( sNum, pinList[i]->GetNumber() );
|
||||
pin->AddAttribute( sNum, pinList[i]->GetNumber() );
|
||||
|
||||
// caution: construction work site here, drive slowly
|
||||
}
|
||||
|
@ -724,7 +728,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts()
|
|||
}
|
||||
|
||||
|
||||
XNODE* EXPORT_HELP::makeGenericListOfNets()
|
||||
XNODE* EXPORT_HELP::makeGenericListOfNets()
|
||||
{
|
||||
XNODE* xnets = node( wxT( "nets" ) ); // auto_ptr if exceptions ever get used.
|
||||
wxString netCodeTxt;
|
||||
|
@ -796,25 +800,25 @@ XNODE* EXPORT_HELP::makeGenericListOfNets()
|
|||
{
|
||||
xnets->AddChild( xnet = node( sNet ) );
|
||||
netCodeTxt.Printf( sFmtd, netCode );
|
||||
xnet->AddProperty( sCode, netCodeTxt );
|
||||
xnet->AddProperty( sName, netName );
|
||||
xnet->AddAttribute( sCode, netCodeTxt );
|
||||
xnet->AddAttribute( sName, netName );
|
||||
}
|
||||
|
||||
XNODE* xnode;
|
||||
xnet->AddChild( xnode = node( sNode ) );
|
||||
xnode->AddProperty( sRef, ref );
|
||||
xnode->AddProperty( sPin, nitem->GetPinNumText() );
|
||||
xnode->AddAttribute( sRef, ref );
|
||||
xnode->AddAttribute( sPin, nitem->GetPinNumText() );
|
||||
}
|
||||
|
||||
return xnets;
|
||||
}
|
||||
|
||||
|
||||
XNODE* EXPORT_HELP::makeGenericRoot()
|
||||
XNODE* EXPORT_HELP::makeGenericRoot()
|
||||
{
|
||||
XNODE* xroot = node( wxT( "export" ) );
|
||||
|
||||
xroot->AddProperty( wxT( "version" ), wxT( "D" ) );
|
||||
xroot->AddAttribute( wxT( "version" ), wxT( "D" ) );
|
||||
|
||||
// add the "design" header
|
||||
xroot->AddChild( makeGenericDesignHeader() );
|
||||
|
@ -832,11 +836,11 @@ XNODE* EXPORT_HELP::makeGenericRoot()
|
|||
}
|
||||
|
||||
|
||||
XNODE* EXPORT_HELP::makeGenericComponents()
|
||||
XNODE* EXPORT_HELP::makeGenericComponents()
|
||||
{
|
||||
XNODE* xcomps = node( wxT( "components" ) );
|
||||
XNODE* xcomps = node( wxT( "components" ) );
|
||||
|
||||
wxString timeStamp;
|
||||
wxString timeStamp;
|
||||
|
||||
// some strings we need many times, but don't want to construct more
|
||||
// than once for performance. These are used within loops so the
|
||||
|
@ -844,25 +848,25 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
// they were in a nested scope.
|
||||
|
||||
// these are actually constructor invocations, not assignments as it appears:
|
||||
wxString sFields = wxT( "fields" );
|
||||
wxString sField = wxT( "field" );
|
||||
wxString sComponent = wxT( "comp" ); // use "part" ?
|
||||
wxString sName = wxT( "name" );
|
||||
wxString sRef = wxT( "ref" );
|
||||
wxString sPins = wxT( "pins" );
|
||||
wxString sPin = wxT( "pin" );
|
||||
wxString sValue = wxT( "value" );
|
||||
wxString sSheetPath = wxT( "sheetpath" );
|
||||
wxString sFootprint = wxT( "footprint" );
|
||||
wxString sDatasheet = wxT( "datasheet" );
|
||||
wxString sTStamp = wxT( "tstamp" );
|
||||
wxString sTStamps = wxT( "tstamps" );
|
||||
wxString sTSFmt = wxT( "%8.8lX" ); // comp->m_TimeStamp
|
||||
wxString sLibSource = wxT( "libsource" );
|
||||
wxString sLibPart = wxT( "libpart" );
|
||||
wxString sLib = wxT( "lib" );
|
||||
wxString sPart = wxT( "part" );
|
||||
wxString sNames = wxT( "names" );
|
||||
wxString sFields = wxT( "fields" );
|
||||
wxString sField = wxT( "field" );
|
||||
wxString sComponent = wxT( "comp" ); // use "part" ?
|
||||
wxString sName = wxT( "name" );
|
||||
wxString sRef = wxT( "ref" );
|
||||
wxString sPins = wxT( "pins" );
|
||||
wxString sPin = wxT( "pin" );
|
||||
wxString sValue = wxT( "value" );
|
||||
wxString sSheetPath = wxT( "sheetpath" );
|
||||
wxString sFootprint = wxT( "footprint" );
|
||||
wxString sDatasheet = wxT( "datasheet" );
|
||||
wxString sTStamp = wxT( "tstamp" );
|
||||
wxString sTStamps = wxT( "tstamps" );
|
||||
wxString sTSFmt = wxT( "%8.8lX" ); // comp->m_TimeStamp
|
||||
wxString sLibSource = wxT( "libsource" );
|
||||
wxString sLibPart = wxT( "libpart" );
|
||||
wxString sLib = wxT( "lib" );
|
||||
wxString sPart = wxT( "part" );
|
||||
wxString sNames = wxT( "names" );
|
||||
|
||||
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
@ -882,7 +886,7 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
|
||||
schItem = comp;
|
||||
|
||||
XNODE* xcomp; // current component being constructed
|
||||
XNODE* xcomp; // current component being constructed
|
||||
|
||||
// Output the component's elments in order of expected access frequency.
|
||||
// This may not always look best, but it will allow faster execution
|
||||
|
@ -890,7 +894,7 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
// an element.
|
||||
|
||||
xcomps->AddChild( xcomp = node( sComponent ) );
|
||||
xcomp->AddProperty( sRef, comp->GetRef( path ) );
|
||||
xcomp->AddAttribute( sRef, comp->GetRef( path ) );
|
||||
|
||||
xcomp->AddChild( node( sValue, comp->GetField( VALUE )->m_Text ) );
|
||||
|
||||
|
@ -905,7 +909,7 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
// container element if there are any <field>s.
|
||||
if( comp->GetFieldCount() > MANDATORY_FIELDS )
|
||||
{
|
||||
XNODE* xfields;
|
||||
XNODE* xfields;
|
||||
xcomp->AddChild( xfields = node( sFields ) );
|
||||
|
||||
for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
|
||||
|
@ -915,14 +919,14 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
// only output a field if non empty
|
||||
if( !f->m_Text.IsEmpty() )
|
||||
{
|
||||
XNODE* xfield;
|
||||
XNODE* xfield;
|
||||
xfields->AddChild( xfield = node( sField, f->m_Text ) );
|
||||
xfield->AddProperty( sName, f->m_Name );
|
||||
xfield->AddAttribute( sName, f->m_Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XNODE* xlibsource;
|
||||
XNODE* xlibsource;
|
||||
xcomp->AddChild( xlibsource = node( sLibSource ) );
|
||||
|
||||
// "logical" library name, which is in anticipation of a better search
|
||||
|
@ -930,13 +934,13 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
// is merely the library name minus path and extension.
|
||||
LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->m_ChipName );
|
||||
if( entry )
|
||||
xlibsource->AddProperty( sLib, entry->GetLibrary()->GetLogicalName() );
|
||||
xlibsource->AddProperty( sPart, comp->m_ChipName );
|
||||
xlibsource->AddAttribute( sLib, entry->GetLibrary()->GetLogicalName() );
|
||||
xlibsource->AddAttribute( sPart, comp->m_ChipName );
|
||||
|
||||
XNODE* xsheetpath;
|
||||
XNODE* xsheetpath;
|
||||
xcomp->AddChild( xsheetpath = node( sSheetPath ) );
|
||||
xsheetpath->AddProperty( sNames, path->PathHumanReadable() );
|
||||
xsheetpath->AddProperty( sTStamps, path->Path() );
|
||||
xsheetpath->AddAttribute( sNames, path->PathHumanReadable() );
|
||||
xsheetpath->AddAttribute( sTStamps, path->Path() );
|
||||
|
||||
timeStamp.Printf( sTSFmt, comp->m_TimeStamp );
|
||||
xcomp->AddChild( node( sTStamp, timeStamp ) );
|
||||
|
@ -946,10 +950,45 @@ XNODE* EXPORT_HELP::makeGenericComponents()
|
|||
return xcomps;
|
||||
}
|
||||
|
||||
#include <wx/wfstream.h> // wxFFileOutputStream
|
||||
|
||||
bool EXPORT_HELP::WriteGENERICNetList( WinEDA_SchematicFrame* frame, const wxString& aOutFileName )
|
||||
{
|
||||
#if 1
|
||||
#if 0
|
||||
|
||||
// this code seems to work now, for S-expression support.
|
||||
|
||||
bool rc = false;
|
||||
wxFFileOutputStream os( aOutFileName, wxT( "wt" ) );
|
||||
|
||||
if( !os.IsOk() )
|
||||
{
|
||||
L_error:
|
||||
wxString msg = _( "Failed to create file " ) + aOutFileName;
|
||||
DisplayError( frame, msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
XNODE* xroot = makeGenericRoot();
|
||||
|
||||
try
|
||||
{
|
||||
STREAM_OUTPUTFORMATTER outputFormatter( os );
|
||||
xroot->Format( &outputFormatter, 0 );
|
||||
}
|
||||
catch( IOError ioe )
|
||||
{
|
||||
delete xroot;
|
||||
goto L_error;
|
||||
}
|
||||
|
||||
delete xroot;
|
||||
rc = true;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
#elif 1
|
||||
// output the XML format netlist.
|
||||
wxXmlDocument xdoc;
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
code
|
||||
comp
|
||||
components
|
||||
datasheet
|
||||
date
|
||||
description
|
||||
design
|
||||
docs
|
||||
export
|
||||
field
|
||||
fields
|
||||
footprint
|
||||
lib
|
||||
libpart
|
||||
libraries
|
||||
library
|
||||
libsource
|
||||
name
|
||||
names
|
||||
net
|
||||
nets
|
||||
node
|
||||
num
|
||||
part
|
||||
pin
|
||||
pins
|
||||
ref
|
||||
sheetpath
|
||||
source
|
||||
tool
|
||||
tstamp
|
||||
tstamps
|
||||
uri
|
||||
value
|
||||
version
|
|
@ -148,14 +148,14 @@ public:
|
|||
/**
|
||||
* Function Rewind
|
||||
* a wrapper to the standard function rewind.
|
||||
* also clear the current line number
|
||||
* also clear the current line number
|
||||
*/
|
||||
void Rewind()
|
||||
{
|
||||
rewind( fp );
|
||||
lineNum = 0;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -201,17 +201,43 @@ public:
|
|||
|
||||
/**
|
||||
* 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
|
||||
* is an important interface (abstract) class used to output UTF8 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.
|
||||
* <p>
|
||||
* The implementer only has to implement the write() function, but can also optionaly
|
||||
* re-implement GetQuoteChar().
|
||||
* <p>
|
||||
* 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.
|
||||
* may actually be used.
|
||||
*/
|
||||
class OUTPUTFORMATTER
|
||||
{
|
||||
std::vector<char> buffer;
|
||||
|
||||
int sprint( const char* fmt, ... ) throw( IOError );
|
||||
int vprint( const char* fmt, va_list ap ) throw( IOError );
|
||||
|
||||
|
||||
protected:
|
||||
OUTPUTFORMATTER( int aReserve = 300 ) :
|
||||
buffer( aReserve, '\0' )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function write
|
||||
* should be coded in the interface implementation (derived) classes.
|
||||
*
|
||||
* @param aOutBuf is the start of a byte buffer to write.
|
||||
* @param aCount tells how many bytes to write.
|
||||
* @throw IOError, if there is a problem outputting, such as a full disk.
|
||||
*/
|
||||
virtual void write( const char* aOutBuf, int aCount ) throw( IOError ) = 0;
|
||||
|
||||
#if defined(__GNUG__) // The GNU C++ compiler defines this
|
||||
|
||||
|
@ -238,7 +264,7 @@ public:
|
|||
* @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;
|
||||
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
|
||||
|
||||
/**
|
||||
* Function GetQuoteChar
|
||||
|
@ -256,7 +282,10 @@ public:
|
|||
* @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 const char* GetQuoteChar( const char* wrapee )
|
||||
{
|
||||
return GetQuoteChar( wrapee, "\"" );
|
||||
}
|
||||
|
||||
virtual ~OUTPUTFORMATTER() {}
|
||||
|
||||
|
@ -283,12 +312,8 @@ public:
|
|||
*/
|
||||
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:
|
||||
|
||||
/**
|
||||
|
@ -296,11 +321,10 @@ public:
|
|||
* reserves space in the buffer
|
||||
*/
|
||||
STRINGFORMATTER( int aReserve = 300 ) :
|
||||
buffer( aReserve, '\0' )
|
||||
OUTPUTFORMATTER( aReserve )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Clear
|
||||
* clears the buffer and empties the internal string.
|
||||
|
@ -316,16 +340,47 @@ public:
|
|||
*/
|
||||
void StripUseless();
|
||||
|
||||
|
||||
std::string GetString()
|
||||
{
|
||||
return mystring;
|
||||
}
|
||||
|
||||
//-----<OUTPUTFORMATTER>------------------------------------------------
|
||||
protected:
|
||||
void write( const char* aOutBuf, int aCount ) throw( IOError );
|
||||
//-----</OUTPUTFORMATTER>-----------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class STREAM_OUTPUTFORMATTER
|
||||
* implements OUTPUTFORMATTER to a wxWidgets wxOutputStream. The stream is
|
||||
* neither opened nor closed by this class.
|
||||
*/
|
||||
class STREAM_OUTPUTFORMATTER : public OUTPUTFORMATTER
|
||||
{
|
||||
wxOutputStream& os;
|
||||
char quoteChar[2];
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor STREAM_OUTPUTFORMATTER
|
||||
* can take any number of wxOutputStream derivations, so it can write
|
||||
* to a file, socket, or zip file.
|
||||
*/
|
||||
STREAM_OUTPUTFORMATTER( wxOutputStream& aStream, char aQuoteChar = '"' ) :
|
||||
os( aStream )
|
||||
{
|
||||
quoteChar[0] = aQuoteChar;
|
||||
quoteChar[1] = 0;
|
||||
}
|
||||
|
||||
//-----<OUTPUTFORMATTER>------------------------------------------------
|
||||
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
|
||||
const char* GetQuoteChar( const char* wrapee );
|
||||
|
||||
protected:
|
||||
void write( const char* aOutBuf, int aCount ) throw( IOError );
|
||||
//-----</OUTPUTFORMATTER>-----------------------------------------------
|
||||
};
|
||||
|
||||
|
|
|
@ -25,55 +25,10 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include "richio.h"
|
||||
|
||||
// #define WXUSINGDLL
|
||||
#include <wx/xml/xml.h>
|
||||
|
||||
// These are classes for eXporting document trees, and thus have names
|
||||
// starting with X. They can export either in XML or S-expression format.
|
||||
|
||||
|
||||
/**
|
||||
* Class XATTR
|
||||
* holds an XML or S-expression attribute/child value. It is used for eXporting
|
||||
* a document tree in EITHER XML or S-expression.
|
||||
*/
|
||||
class XATTR : public wxXmlProperty // use wxXmlAttribute for wx >= 2.9
|
||||
{
|
||||
public:
|
||||
XATTR() :
|
||||
wxXmlProperty()
|
||||
{
|
||||
}
|
||||
|
||||
XATTR( const wxString& aName, const wxString& aValue ) :
|
||||
wxXmlProperty( aName, aValue )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* writes this object as UTF8 out to an OUTPUTFORMATTER as an S-expression
|
||||
* @param out The formatter to write to.
|
||||
* @param nestLevel A multiple of the number of spaces to preceed the output with.
|
||||
* @throw IOError if a system error writing the output, such as a full disk.
|
||||
*/
|
||||
virtual void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
|
||||
|
||||
|
||||
/**
|
||||
* Function FormatContents
|
||||
* writes the contents of object as UTF8 out to an OUTPUTFORMATTER as an S-expression
|
||||
* This is the same as Format() except that the outer wrapper is not included.
|
||||
* @param out The formatter to write to.
|
||||
* @param nestLevel A multiple of the number of spaces to preceed the output with.
|
||||
* @throw IOError if a system error writing the output, such as a full disk.
|
||||
*/
|
||||
virtual void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class XNODE
|
||||
|
@ -88,13 +43,11 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
XNODE( wxXmlNodeType aType, const wxString& aName, const wxString& aContent = wxEmptyString ) :
|
||||
wxXmlNode( NULL, aType, aName, aContent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Format
|
||||
* writes this object as UTF8 out to an OUTPUTFORMATTER as an S-expression
|
||||
|
@ -104,7 +57,6 @@ public:
|
|||
*/
|
||||
virtual void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
|
||||
|
||||
|
||||
/**
|
||||
* Function FormatContents
|
||||
* writes the contents of object as UTF8 out to an OUTPUTFORMATTER as an S-expression
|
||||
|
|
|
@ -52,7 +52,9 @@
|
|||
|
||||
#include "specctra.h"
|
||||
|
||||
#include <wx/ffile.h>
|
||||
//#include <wx/ffile.h>
|
||||
#include <wx/wfstream.h> // wxFFileOutputStream
|
||||
|
||||
|
||||
#include "build_version.h"
|
||||
|
||||
|
@ -3850,81 +3852,42 @@ void SPECCTRA_DB::doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IOError )
|
|||
}
|
||||
|
||||
|
||||
int SPECCTRA_DB::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 = fprintf( fp, "%*c", NESTWIDTH, ' ' );
|
||||
if( result < 0 )
|
||||
break;
|
||||
|
||||
total += result;
|
||||
}
|
||||
|
||||
if( result<0 || (result=vfprintf( fp, fmt, args ))<0 )
|
||||
{
|
||||
ThrowIOError( _("System file error writing to file \"%s\""), GetChars(filename) );
|
||||
}
|
||||
|
||||
va_end( args );
|
||||
|
||||
total += result;
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
|
||||
{
|
||||
return OUTPUTFORMATTER::GetQuoteChar( wrapee, quote_char.c_str() );
|
||||
}
|
||||
|
||||
|
||||
void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IOError )
|
||||
{
|
||||
fp = wxFopen( filename, wxT("w") );
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
ThrowIOError( _("Unable to open file \"%s\""), GetChars(filename) );
|
||||
}
|
||||
|
||||
if( pcb )
|
||||
{
|
||||
wxFFileOutputStream os( filename, wxT( "wt" ) );
|
||||
|
||||
if( !os.IsOk() )
|
||||
{
|
||||
ThrowIOError( _("Unable to open file \"%s\""), GetChars(filename) );
|
||||
}
|
||||
|
||||
STREAM_OUTPUTFORMATTER outputFormatter( os, quote_char[0] );
|
||||
|
||||
if( aNameChange )
|
||||
pcb->pcbname = CONV_TO_UTF8(filename);
|
||||
|
||||
pcb->Format( this, 0 );
|
||||
pcb->Format( &outputFormatter, 0 );
|
||||
}
|
||||
|
||||
// if an exception is thrown by Format, then ~SPECCTRA_DB() will close
|
||||
// the file.
|
||||
|
||||
fclose( fp );
|
||||
fp = 0;
|
||||
}
|
||||
|
||||
|
||||
void SPECCTRA_DB::ExportSESSION( wxString filename )
|
||||
{
|
||||
fp = wxFopen( filename, wxT("w") );
|
||||
|
||||
if( !fp )
|
||||
{
|
||||
ThrowIOError( _("Unable to open file \"%s\""), GetChars(filename) );
|
||||
}
|
||||
|
||||
if( session )
|
||||
session->Format( this, 0 );
|
||||
{
|
||||
wxFFileOutputStream os( filename, wxT( "wt" ) );
|
||||
|
||||
fclose( fp );
|
||||
fp = 0;
|
||||
if( !os.IsOk() )
|
||||
{
|
||||
ThrowIOError( _("Unable to open file \"%s\""), GetChars(filename) );
|
||||
}
|
||||
|
||||
STREAM_OUTPUTFORMATTER outputFormatter( os, quote_char[0] );
|
||||
|
||||
session->Format( &outputFormatter, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3970,7 +3970,7 @@ typedef boost::ptr_set<PADSTACK> PADSTACKSET;
|
|||
* Class SPECCTRA_DB
|
||||
* holds a DSN data tree, usually coming from a DSN file.
|
||||
*/
|
||||
class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||
class SPECCTRA_DB
|
||||
{
|
||||
/// specctra DSN keywords
|
||||
static const KEYWORD keywords[];
|
||||
|
@ -3979,13 +3979,8 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
|||
DSNLEXER* lexer;
|
||||
|
||||
PCB* pcb;
|
||||
|
||||
SESSION* session;
|
||||
|
||||
FILE* fp;
|
||||
|
||||
wxString filename;
|
||||
|
||||
std::string quote_char;
|
||||
|
||||
bool modulesAreFlipped;
|
||||
|
@ -4304,7 +4299,6 @@ public:
|
|||
lexer = 0;
|
||||
pcb = 0;
|
||||
session = 0;
|
||||
fp = 0;
|
||||
quote_char += '"';
|
||||
modulesAreFlipped = false;
|
||||
}
|
||||
|
@ -4316,18 +4310,8 @@ public:
|
|||
delete session;
|
||||
|
||||
deleteNETs();
|
||||
|
||||
if( fp )
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
|
||||
//-----<OUTPUTFORMATTER>-------------------------------------------------
|
||||
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError );
|
||||
|
||||
const char* GetQuoteChar( const char* wrapee );
|
||||
//-----</OUTPUTFORMATTER>------------------------------------------------
|
||||
|
||||
static const char* TokenName( int aToken );
|
||||
|
||||
|
||||
|
@ -4354,11 +4338,6 @@ public:
|
|||
}
|
||||
PCB* GetPCB() { return pcb; }
|
||||
|
||||
void SetFILE( FILE* aFile )
|
||||
{
|
||||
fp = aFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetSESSION
|
||||
* deletes any existing SESSION and replaces it with the given one.
|
||||
|
|
Loading…
Reference in New Issue