You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
9.2 KiB

  1. /****************************/
  2. /* readschematicnetlist.cpp */
  3. /****************************/
  4. /* Read a nelist type Eeschema or OrcadPCB2 and build the component list
  5. * Manages the lines like :
  6. * ( XXXXXX VALEUR|(pin1,pin2,...=newalim) ID VALEUR
  7. */
  8. #include "fctsys.h"
  9. #include "wxstruct.h"
  10. #include "common.h"
  11. #include "confirm.h"
  12. #include "kicad_string.h"
  13. #include "macros.h"
  14. #include "cvpcb.h"
  15. #include "protos.h"
  16. #include "cvstruct.h"
  17. #include "richio.h"
  18. #define SEPARATEUR '|' /* Separator character in NetList */
  19. static int ReadPinConnection( FILE_LINE_READER& aNetlistReader, COMPONENT* CurrentCmp );
  20. static int ReadFootprintFilterList( FILE_LINE_READER& aNetlistReader, COMPONENT_LIST& aComponentsList );
  21. /* Sort the list alphabetically by component and and returns
  22. * a pointer to the 1st element of list */
  23. #define BUFFER_CHAR_SIZE 1024 // Size of buffers used to store netlist data
  24. /**
  25. * Function ReadSchematicNetlist
  26. * Read a Eeschema (or OrcadPCB) netlist
  27. * like:
  28. * # EESchema Netlist Version 1.1 created 15/5/2008-12:09:21
  29. * (
  30. * ( /32568D1E $noname JP1 CONN_8X2 {Lib=CONN_8X2}
  31. * ( 1 GND )
  32. * ( 2 /REF10 )
  33. * ( 3 GND )
  34. * ( 4 /REF11 )
  35. * ( 5 GND )
  36. * ( 6 /REF7 )
  37. * ( 7 GND )
  38. * ( 8 /REF9 )
  39. * ( 9 GND )
  40. * ( 10 /REF6 )
  41. * ( 11 GND )
  42. * ( 12 /REF8 )
  43. * ( 13 GND )
  44. * ( 14 /REF4 )
  45. * ( 15 GND )
  46. * ( 16 /REF5 )
  47. * )
  48. * ( /325679C1 $noname RR1 9x1K {Lib=RR9}
  49. * ( 1 VCC )
  50. * ( 2 /REF5 )
  51. * ( 3 /REF4 )
  52. * ( 4 /REF8 )
  53. * ( 5 /REF6 )
  54. * ( 6 /REF9 )
  55. * ( 7 /REF7 )
  56. * ( 8 /REF11 )
  57. * ( 9 /REF10 )
  58. * ( 10 ? )
  59. * )
  60. * )
  61. * *
  62. * { Allowed footprints by component:
  63. * $component R5
  64. * R?
  65. * SM0603
  66. * SM0805
  67. * $endlist
  68. * $component C2
  69. * SM*
  70. * C?
  71. * C1-1
  72. * $endlist
  73. * $endfootprintlist
  74. * }
  75. */
  76. int WinEDA_CvpcbFrame::ReadSchematicNetlist()
  77. {
  78. char alim[1024];
  79. int idx, jj, k, l;
  80. char cbuffer[BUFFER_CHAR_SIZE]; /* temporary storage */
  81. char* ptchar;
  82. COMPONENT* Cmp;
  83. FILE* source;
  84. m_modified = false;
  85. m_isEESchemaNetlist = false;
  86. /* Clear components buffer */
  87. if( !m_components.empty() )
  88. {
  89. m_components.clear();
  90. }
  91. source = wxFopen( m_NetlistFileName.GetFullPath(), wxT( "rt" ) );
  92. if( source == 0 )
  93. {
  94. DisplayError( this, _( "File <" ) + m_NetlistFileName.GetFullPath() +
  95. _( "> not found" ) );
  96. return -1;
  97. }
  98. FILE_LINE_READER netlistReader( source, BUFFER_CHAR_SIZE );
  99. char* Line = netlistReader;
  100. /* Read the file header (must be "( { OrCAD PCB" or "({ OrCAD PCB" )
  101. * or "# EESchema Netlist"
  102. */
  103. netlistReader.ReadLine( );
  104. /* test for netlist type PCB2 */
  105. idx = strnicmp( Line, "( {", 3 );
  106. if( idx != 0 )
  107. idx = strnicmp( Line, "({", 2 );
  108. if( idx != 0 )
  109. {
  110. idx = strnicmp( Line, "# EESchema", 7 ); /* net type EESchema */
  111. if( idx == 0 )
  112. m_isEESchemaNetlist = true;
  113. }
  114. if( idx != 0 )
  115. {
  116. wxString msg, Lineconv = CONV_FROM_UTF8( Line );
  117. msg.Printf( _( "Unknown file format <%s>" ), Lineconv.GetData() );
  118. DisplayError( this, msg );
  119. fclose( source );
  120. return -3;
  121. }
  122. SetStatusText( _( "Netlist Format: EESchema" ), 0 );
  123. /* Read the netlist */
  124. for( ; ; )
  125. {
  126. /* Search the beginning of a component description */
  127. if( netlistReader.ReadLine( ) == 0 )
  128. break;
  129. /* Remove blanks */
  130. idx = 0;
  131. while( Line[idx] == ' ' )
  132. idx++;
  133. /* remove empty lines : */
  134. if( Line[idx] < ' ' )
  135. continue;
  136. if( strnicmp( &Line[idx], "{ Allowed footprints", 20 ) == 0 )
  137. {
  138. ReadFootprintFilterList( netlistReader, m_components );
  139. continue;
  140. }
  141. if( strnicmp( &Line[idx], "( ", 2 ) != 0 )
  142. continue;
  143. /*******************************/
  144. /* Component description found */
  145. /*******************************/
  146. Cmp = new COMPONENT(); // Creates the new component storage
  147. while( Line[idx] != ' ' )
  148. idx++;
  149. while( Line[idx] == ' ' )
  150. idx++;
  151. /* idx points the beginning of the schematic time stamp */
  152. jj = 0;
  153. while( Line[idx] != ' ' && Line[idx] )
  154. cbuffer[jj++] = Line[idx++];
  155. cbuffer[jj] = 0;
  156. Cmp->m_TimeStamp = CONV_FROM_UTF8(cbuffer);
  157. /* search val/ref.lib */
  158. while( Line[idx] == ' ' )
  159. idx++;
  160. /* idx points the component value.
  161. * Read value */
  162. ptchar = strstr( &Line[idx], " " ); // Search end of value field (space)
  163. if( ptchar == 0 )
  164. {
  165. wxString msg;
  166. msg.Printf( _( "Netlist error: %s" ), Line );
  167. DisplayError( this, msg );
  168. k = 0;
  169. }
  170. else
  171. k = ptchar - Line;
  172. for( jj = 0; idx < k; idx++ )
  173. {
  174. if( Line[idx] == SEPARATEUR )
  175. break;
  176. cbuffer[jj++] = Line[idx];
  177. }
  178. cbuffer[jj] = 0;
  179. // Copy footprint name:
  180. if( m_isEESchemaNetlist && (strnicmp( cbuffer, "$noname", 7 ) != 0) )
  181. Cmp->m_Module = CONV_FROM_UTF8(cbuffer);
  182. if( (Line[++idx] == '(') && (Line[k - 1] == ')' ) )
  183. {
  184. idx++; l = 0;
  185. while( k - 1 > idx )
  186. alim[l++] = Line[idx++];
  187. }
  188. else
  189. idx = k;
  190. /* Search component reference */
  191. while( Line[idx] != ' ' && Line[idx] )
  192. idx++;
  193. /* goto end of value field */
  194. while( Line[idx] == ' ' && Line[idx] )
  195. idx++;
  196. /* goto beginning of reference */
  197. for( jj = 0; ; idx++ )
  198. {
  199. if( Line[idx] == ' ' || Line[idx] == 0)
  200. break;
  201. cbuffer[jj++] = Line[idx];
  202. }
  203. cbuffer[jj] = 0;
  204. Cmp->m_Reference = CONV_FROM_UTF8(cbuffer);
  205. /* Search component value */
  206. while( Line[idx] == ' ' && Line[idx] )
  207. idx++;
  208. /** goto beginning of value */
  209. for( jj = 0 ; ; idx++ )
  210. {
  211. if( (Line[idx] == ' ') || (Line[idx] == '\n') || (Line[idx] == '\r') || Line[idx] == 0)
  212. break;
  213. cbuffer[jj++] = Line[idx];
  214. }
  215. cbuffer[jj] = 0;
  216. Cmp->m_Value = CONV_FROM_UTF8(cbuffer);
  217. m_components.push_back( Cmp );
  218. ReadPinConnection( netlistReader, Cmp );
  219. }
  220. fclose( source );
  221. m_components.sort();
  222. return 0;
  223. }
  224. int ReadFootprintFilterList( FILE_LINE_READER& aNetlistReader, COMPONENT_LIST& aComponentsList )
  225. {
  226. char* Line = aNetlistReader;
  227. wxString CmpRef;
  228. COMPONENT* Cmp = NULL;
  229. for( ; ; )
  230. {
  231. if( aNetlistReader.ReadLine( ) == 0 )
  232. break;
  233. if( strnicmp( Line, "$endlist", 8 ) == 0 )
  234. {
  235. Cmp = NULL;
  236. continue;
  237. }
  238. if( strnicmp( Line, "$endfootprintlist", 4 ) == 0 )
  239. return 0;
  240. if( strnicmp( Line, "$component", 10 ) == 0 ) // New component ref found
  241. {
  242. CmpRef = CONV_FROM_UTF8( Line + 11 );
  243. CmpRef.Trim( true );
  244. CmpRef.Trim( false );
  245. /* Search the new component in list */
  246. BOOST_FOREACH( COMPONENT & component, aComponentsList )
  247. {
  248. Cmp = &component;
  249. if( Cmp->m_Reference == CmpRef )
  250. break;
  251. }
  252. }
  253. else if( Cmp )
  254. {
  255. wxString fp = CONV_FROM_UTF8( Line + 1 );
  256. fp.Trim( false );
  257. fp.Trim( true );
  258. Cmp->m_FootprintFilter.Add( fp );
  259. }
  260. }
  261. return 1;
  262. }
  263. int ReadPinConnection( FILE_LINE_READER& aNetlistReader, COMPONENT* Cmp )
  264. {
  265. int i, jj;
  266. char* Line = aNetlistReader;
  267. char cbuffer[BUFFER_CHAR_SIZE];
  268. for( ; ; )
  269. {
  270. /* Find beginning of description. */
  271. for( ; ; )
  272. {
  273. if( aNetlistReader.ReadLine( ) == 0 )
  274. return -1;
  275. /* Remove blanks from the beginning of the line. */
  276. i = 0; while( Line[i] == ' ' )
  277. i++;
  278. while( Line[i] == '(' )
  279. i++;
  280. while( Line[i] == ' ' )
  281. i++;
  282. /* remove empty lines : */
  283. if( Line[i] < ' ' )
  284. continue;
  285. /* End of description? */
  286. if( Line[i] == ')' )
  287. return 0;
  288. PIN * Pin = new PIN();
  289. /* Read pin name, usually 4 letters */
  290. for( jj = 0; ; i++ )
  291. {
  292. if( Line[i] == ' ' || Line[i] == 0 )
  293. break;
  294. cbuffer[jj++] = Line[i];
  295. }
  296. cbuffer[jj] = 0;
  297. Pin->m_Number = CONV_FROM_UTF8(cbuffer);
  298. /* Read netname */
  299. while( Line[i] == ' ' )
  300. i++;
  301. for( jj = 0; ; i++ )
  302. {
  303. if( Line[i] == ' ' || Line[i] == '\n' || Line[i] == '\r' || Line[i] == 0 )
  304. break;
  305. cbuffer[jj++] = Line[i];
  306. }
  307. cbuffer[jj] = 0;
  308. Pin->m_Net = CONV_FROM_UTF8(cbuffer);
  309. Cmp->m_Pins.push_back( Pin );
  310. }
  311. }
  312. }