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.

376 lines
9.3 KiB

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