/****************************/ /* readschematicnetlist.cpp */ /****************************/ /* Read a nelist type Eeschema or OrcadPCB2 and buid the component list * Manages the lines like : * ( XXXXXX VALEUR|(pin1,pin2,...=newalim) ID VALEUR */ #include "fctsys.h" #include "wxstruct.h" #include "common.h" #include "cvpcb.h" #include "protos.h" #define SEPARATEUR '|' /* caractere separateur dans netliste */ /* routines locales : */ static int ReadPinConnection( STORECMP* CurrentCmp ); #define BUFFER_CHAR_SIZE 1024 // Size of buffers used to store netlist datas /************************************************/ int WinEDA_CvpcbFrame::ReadSchematicNetlist() /************************************************/ { int i, j, k, l; char* LibName; char Line[BUFFER_CHAR_SIZE + 1]; char component_reference[BUFFER_CHAR_SIZE + 1]; /* buffer for component reference (U1, R4...) */ char schematic_timestamp[BUFFER_CHAR_SIZE + 1]; /* buffer for component time stamp */ char footprint_name[BUFFER_CHAR_SIZE + 1]; /* buffer for component footprint field */ char component_value[BUFFER_CHAR_SIZE + 1]; /* buffer for component values (470K, 22nF ...) */ char* ptchar; /* pointeur de service */ STORECMP* Cmp; modified = 0; Rjustify = 0; g_FlagEESchema = FALSE; /* Raz buffer et variable de gestion */ if( g_BaseListeCmp ) FreeMemoryComponants(); /* Ouverture du fichier source */ source = wxFopen( FFileName, wxT( "rt" ) ); if( source == 0 ) { wxString msg; msg.Printf( _( "File <%s> not found" ), FFileName.GetData() ); DisplayError( this, msg ); return -1; } /* Read the file header (must be "( { OrCAD PCB" or "({ OrCAD PCB" ) * or "# EESchema Netliste" */ fgets( Line, 255, source ); /* test for netlist type PCB2 */ i = strnicmp( Line, "( {", 3 ); if( i != 0 ) i = strnicmp( Line, "({", 2 ); if( i != 0 ) { i = strnicmp( Line, "# EESchema", 7 ); /* net type EESchema */ if( i == 0 ) g_FlagEESchema = TRUE; } if( i != 0 ) { wxString msg, Lineconv = CONV_FROM_UTF8( Line ); msg.Printf( _( "Unknown file format <%s>" ), Lineconv.GetData() ); DisplayError( this, msg ); fclose( source ); return -3; } SetStatusText( _( "Netlist Format: EESchema" ), 0 ); /* Read the netlit */ for( ; ; ) { /* Search the beginning of a component description */ if( fgets( Line, BUFFER_CHAR_SIZE, source ) == 0 ) break; /* Remove blanks */ i = 0; while( Line[i] == ' ' ) i++; /* remove empty lines : */ if( Line[i] < ' ' ) continue; if( strnicmp( &Line[i], "{ Allowed footprints", 20 ) == 0 ) { ReadFootprintFilterList( source ); continue; } if( strnicmp( &Line[i], "( ", 2 ) != 0 ) continue; /*******************************/ /* Component description found */ /*******************************/ while( Line[i] != ' ' ) i++; while( Line[i] == ' ' ) i++; /* i points the beginning of the schematic time stamp */ memset( schematic_timestamp, 0, sizeof(schematic_timestamp) ); j = 0; while( Line[i] != ' ' ) schematic_timestamp[j++] = Line[i++]; schematic_timestamp[j] = 0; /* search val/ref.lib */ while( Line[i] == ' ' ) i++; /* i points the component value */ LibName = Line + i; memset( component_reference, 0, sizeof(component_reference) ); memset( footprint_name, 0, sizeof(footprint_name) ); memset( component_value, 0, sizeof(component_value) ); memset( alim, 0, sizeof(alim) ); /* Read value */ ptchar = strstr( &Line[i], " " ); // Search end of value field (space) if( ptchar == 0 ) { wxString msg; msg.Printf( _( "Netlist error: %s" ), Line ); DisplayError( NULL, msg ); k = 0; } else k = ptchar - Line; for( j = 0; i < k; i++ ) { if( Line[i] == SEPARATEUR ) break; if( j < (int) (sizeof(footprint_name) - 1) ) footprint_name[j++] = Line[i]; } if( (Line[++i] == '(') && (Line[k - 1] == ')' ) ) { i++; l = 0; while( k - 1 > i ) alim[l++] = Line[i++]; } else i = k; /* Search component reference */ while( Line[i] != ' ' ) i++; /* goto end of value field */ while( Line[i] == ' ' ) i++; /* goto beginning of reference */ /* debut reference trouv‚ */ for( k = 0; k < (int) (sizeof(component_reference) - 1); i++, k++ ) { if( Line[i] <= ' ' ) break; component_reference[k] = Line[i]; } /* Search component value */ while( Line[i] == ' ' ) i++; /** goto beginning of value */ for( k = 0; k < (int) (sizeof(component_value) - 1); i++, k++ ) { if( Line[i] <= ' ' ) break; component_value[k] = Line[i]; } /* Store info for this component */ Cmp = new STORECMP(); Cmp->Pnext = g_BaseListeCmp; g_BaseListeCmp = Cmp; Cmp->m_Reference = CONV_FROM_UTF8( component_reference ); Cmp->m_Valeur = CONV_FROM_UTF8( component_value ); if( g_FlagEESchema ) /* copy footprint name: */ { if( strnicmp( LibName, "$noname", 7 ) != 0 ) { while( *LibName > ' ' ) { Cmp->m_Module.Append( *LibName ); LibName++; } } } Cmp->m_TimeStamp = CONV_FROM_UTF8( schematic_timestamp ); ReadPinConnection( Cmp ); nbcomp++; } fclose( source ); /* Alpabetic sorting : */ g_BaseListeCmp = TriListeComposantss( g_BaseListeCmp, nbcomp ); return 0; } /********************************************************/ int WinEDA_CvpcbFrame::ReadFootprintFilterList( FILE* f ) /********************************************************/ { char Line[BUFFER_CHAR_SIZE + 1]; wxString CmpRef; STORECMP* Cmp = NULL; for( ; ; ) { if( fgets( Line, BUFFER_CHAR_SIZE, source ) == 0 ) break; if( strnicmp( Line, "$endlist", 8 ) == 0 ) { Cmp = NULL; continue; } if( strnicmp( Line, "$endfootprintlist", 4 ) == 0 ) return 0; if( strnicmp( Line, "$component", 10 ) == 0 ) // New component ref found { CmpRef = CONV_FROM_UTF8( Line + 11 ); CmpRef.Trim( TRUE ); CmpRef.Trim( FALSE ); /* Search the new component in list */ for( Cmp = g_BaseListeCmp; Cmp != NULL; Cmp = Cmp->Pnext ) { if( Cmp->m_Reference == CmpRef ) break; } } else if( Cmp ) { wxString fp = CONV_FROM_UTF8( Line + 1 ); fp.Trim( FALSE ); fp.Trim( TRUE ); Cmp->m_FootprintFilter.Add( fp ); } } return 1; } /***********************************/ int ReadPinConnection( STORECMP* Cmp ) /***********************************/ { int i, jj; char numpin[BUFFER_CHAR_SIZE + 1], net[BUFFER_CHAR_SIZE + 1]; char Line[BUFFER_CHAR_SIZE + 1]; STOREPIN* Pin = NULL; STOREPIN** LastPin = &Cmp->m_Pins; for( ; ; ) { /* debut description trouv‚ */ for( ; ; ) { if( fgets( Line, BUFFER_CHAR_SIZE, source ) == 0 ) return -1; /* remove blanks from the beginning of the line */ i = 0; while( Line[i] == ' ' ) i++; while( Line[i] == '(' ) i++; while( Line[i] == ' ' ) i++; /* remove empty lines : */ if( Line[i] < ' ' ) continue; /* fin de description ? */ if( Line[i] == ')' ) return 0; memset( net, 0, sizeof(net) ); memset( numpin, 0, sizeof(numpin) ); /* Read pi name , 4 letters */ for( jj = 0; jj < 4; jj++, i++ ) { if( Line[i] == ' ' ) break; numpin[jj] = Line[i]; } /* Search for a net attribute */ if( reaffect( numpin, net ) != 0 ) { Pin = new STOREPIN(); *LastPin = Pin; LastPin = &Pin->Pnext; Pin->m_PinNum = CONV_FROM_UTF8( numpin ); Pin->m_PinNet = CONV_FROM_UTF8( net ); continue; } /* Read netname */ while( Line[i] == ' ' ) i++; for( jj = 0; jj < (int) sizeof(net) - 1; i++, jj++ ) { if( Line[i] <= ' ' ) break; net[jj] = Line[i]; } Pin = new STOREPIN(); *LastPin = Pin; LastPin = &Pin->Pnext; Pin->m_PinNum = CONV_FROM_UTF8( numpin ); Pin->m_PinNet = CONV_FROM_UTF8( net ); } } } /****************************************************************/ STORECMP* TriListeComposantss( STORECMP* BaseListe, int nbitems ) /****************************************************************/ /* Sort the component list( this is a linked list) * retourn the beginning of the list */ { STORECMP** bufferptr, * Item; int ii; if( nbitems <= 0 ) return NULL; bufferptr = (STORECMP**) MyZMalloc( (nbitems + 2) * sizeof(STORECMP*) ); for( ii = 1, Item = BaseListe; Item != NULL; Item = Item->Pnext, ii++ ) { bufferptr[ii] = Item; } /* Here: bufferptr[0] = NULL and bufferptr[nbitem+1] = NULL. * These 2 values are the first item back link, and the last item forward link */ qsort( bufferptr + 1, nbitems, sizeof(STORECMP*), ( int( * ) ( const void*, const void* ) )CmpCompare ); /* Update linked list */ for( ii = 1; ii <= nbitems; ii++ ) { Item = bufferptr[ii]; Item->m_Num = ii; Item->Pnext = bufferptr[ii + 1]; Item->Pback = bufferptr[ii - 1]; } return bufferptr[1]; } /****************************************/ int CmpCompare( void* mod1, void* mod2 ) /****************************************/ /* * Function compare() for qsort() : alphabetic sorting, with numbering order */ { int ii; STORECMP* pt1, * pt2; pt1 = *( (STORECMP**) mod1 ); pt2 = *( (STORECMP**) mod2 ); //FIXME: ii = StrNumICmp( (const wxChar*) pt1->m_Reference, (const wxChar*) pt2->m_Reference ); return ii; }