kicad/eeschema/plugins/netlist_form_pads-pcb.cpp

359 lines
8.3 KiB
C++

/**********************************/
/* Netlist generator for pads-pcb */
/**********************************/
/* read the generic netlist created by eeschema and convert it to a pads-pcb form
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* Pads-pcb sample:
*PADS-PCB*
*PART*
* C1 CHIP_D
* C2 C1206
* C3 CHIP_B
* C4 CHIP_B
* D1 CHIP_B
* JP1 unknown
*
*NET*
*SIGNAL* N03791
* C3.1 R1.1 JP2.7 U1.3
*SIGNAL* VCC
* U2.14 Y1.8 JP5.2 U3.2 C1.1 U1.20 JP1.8 JP1.3
* C5.2 C6.1 C7.2 U1.7 Y1.7
*SIGNAL* N01384
* JP5.1 U1.1
*SIGNAL* N02594
*END*
*/
/* Generic netlist sample:
* $BeginNetlist
* $BeginComponentList
*
* $BeginComponent
* TimeStamp=32568D1E
* Footprint=
* Reference=JP1
* Value=CONN_8X2
* Libname=CONN_8X2
* $BeginPinList
* 1=GND
* 2=REF10_1
* 3=GND
* 4=REF11_1
* 5=GND
* 6=REF7_1
* 7=GND
* 8=REF9_1
* 9=GND
* 10=REF6_1
* 11=GND
* 12=REF8_1
* 13=GND
* 14=REF4_1
* 15=GND
* 16=REF5_1
* $EndPinList
* $EndComponent
*
* $BeginComponent
* TimeStamp=325679C1
* Footprint=
* Reference=RR1
* Value=9x1K
* Libref=RR9
* $BeginPinList
* 1=VCC
* 2=REF5_1
* 3=REF4_1
* 4=REF8_1
* 5=REF6_1
* 6=REF9_1
* 7=REF7_1
* 8=REF11_1
* 9=REF10_1
* 10=?
* $EndPinList
* $EndComponent
* $EndComponentList
*
* $BeginNets
* Net 0 ""
* Net 1 "GND"
* BUS1 31
* U3 19
* U3 10
* U3 1
* Net 172 ""
* BUS1 32
* Net 173 ""
* BUS1 30
* $EndNets
*
* $EndNetlist
*/
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine );
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
int AreStringsEqual( const char * src, const char * ref );
class ComponentDataClass
{
public:
char m_Reference[256];
char m_Value[256];
char m_Footprint[256];
char m_LibRef[256];
long m_TimeStamp;
public:
ComponentDataClass()
{
InitData();
}
void InitData()
{
m_TimeStamp = 0;
m_Reference[0] = 0;
m_Value[0] = 0;
m_Footprint[0] = 0;
m_LibRef[0] = 0;
}
};
/********************************/
int main( int argc, char** argv )
/********************************/
{
char* InputfileName, * OutputFilename;
FILE* InFile, * OutFile;
int LineNumber;
char Line[1024];
if( argc < 3 )
{
printf( "\nUsage; netlist_form_pads-pcb infile outfile\n" );
return -1;
}
InputfileName = argv[1];
OutputFilename = argv[2];
if( ( InFile = fopen( InputfileName, "rt" ) ) == NULL )
{
printf( "Failed to open file %s", InputfileName );
return -2;
}
if( ( OutFile = fopen( OutputFilename, "wt" ) ) == NULL )
{
printf( "Failed to create file %s", OutputFilename );
return -3;
}
/* Write header: */
fprintf( OutFile, "*PADS-PCB*\n*PART*\n" );
/* Read and write data lines */
while( GetLine( InFile, Line, &LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$BeginComponent" ) )
{
ReadAndWriteComponentDataSection( InFile, OutFile, &LineNumber );
continue;
}
if( AreStringsEqual( Line, "$BeginNets" ) )
{
fprintf( OutFile, "\n*NET*\n" );
ReadAndWriteNetsDataSection( InFile, OutFile, &LineNumber );
continue;
}
}
fprintf( OutFile, "*END*\n" );
fclose( InFile );
fclose( OutFile );
return 0;
}
/****************************************************************/
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber )
/****************************************************************/
/* Read the Components Section from the Generic Netlist and create Components section in Pads-Pcb format
* For the component section only reference and footprint are used.
* Create lines like:
* C1 CHIP_D
* C2 unknown
*/
{
char Line[1024];
class ComponentDataClass ComponentData;
char* ident, * data;
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$BeginPinList" ) )
{
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
if( AreStringsEqual( Line, "$EndPinList" ) )
break;
continue;
}
if( AreStringsEqual( Line, "$EndComponent" ) ) // Create the output for the component:
{
/* Create the line like: C2 unknown */
fprintf( OutFile, "%s ", ComponentData.m_Reference );
fprintf( OutFile, "%s\n",
strlen( ComponentData.m_Footprint ) ? ComponentData.m_Footprint : "unknown" );
return 0;
}
ident = strtok( Line, "=\n\r" );
data = strtok( NULL, "=\n\r" );
if( data == NULL )
continue;
if( AreStringsEqual( Line, "TimeStamp" ) )
{
ComponentData.m_TimeStamp = atol( data );
continue;
}
if( AreStringsEqual( Line, "Footprint" ) )
{
strncpy( ComponentData.m_Footprint, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Reference" ) )
{
strncpy( ComponentData.m_Reference, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Value" ) )
{
strncpy( ComponentData.m_Value, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Libref" ) )
{
strncpy( ComponentData.m_LibRef, data, 255 );
continue;
}
}
return 1;
}
/****************************************************************/
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber )
/****************************************************************/
/* Read the Nets Section from the Generic Netlist and create Nets section in Pads-Pcb format
* create info type:
*SIGNAL* N03791
* C3.1 R1.1 JP2.7 U1.3
*/
{
char Line[1024];
char* ident, * netnum, * netname, * pin;
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$EndNets" ) )
return 0;
ident = strtok( Line, " \n\r" );
if( AreStringsEqual( ident, "Net" ) )
{
netnum = strtok( NULL, " \n\r" );
netname = strtok( NULL, " \"\n\r" );
if( (netname == NULL) || strlen( netname ) == 0 )
{ // Create the line like: *SIGNAL* N03791
int num = atoi( netnum );
sprintf( Line, "N-%6.6d", num );
netname = Line;
}
fprintf( OutFile, "*SIGNAL* %s\n", netname );
}
else
{
// Create the line like: C3.1 R1.1 JP2.7 U1.3
pin = strtok( NULL, " \n\r" );
fprintf( OutFile, " %s.%s\n", ident, pin );
}
}
return 1;
}
/*****************************************************************/
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine )
/*****************************************************************/
/* Return a non empty line
* increment *LineNum for each read line
* Comment lines (starting by '#') are skipped
*/
{
do {
if( fgets( Line, SizeLine, File ) == NULL )
return NULL;
if( LineNum )
*LineNum += 1;
} while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r'
|| Line[0] == 0 );
strtok( Line, "\n\r" );
return Line;
}
/***************************************************/
int AreStringsEqual( const char * src, const char * ref )
/***************************************************/
/* Compare 2 strings (case insensitive),
* and return 1 (true) if equal or 0 (false) if different
* stricmp does the same job, but does not exist under all systems
*/
{
int match = 1;
while (src && ref )
{
unsigned char c1 = *src;
unsigned char c2 = *ref;
if ( c1 >= 'a' && c1 <= 'z' )
c1 += 'A' - 'a';
if ( c2 >= 'a' && c2 <= 'z' )
c2 += 'A' - 'a';
if ( c1 != c2 )
{
match = 0;
break;
}
if ( c1 == 0 || c2 == 0 )
break;
src++; ref++;
}
return match;
}