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.

211 lines
5.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include <template_fieldnames.h>
  25. #include <dsnlexer.h>
  26. #include <fctsys.h>
  27. #include <macros.h>
  28. using namespace TFIELD_T;
  29. const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx )
  30. {
  31. // Fixed values for the first few default fields used by EESCHEMA
  32. // (mandatory fields)
  33. switch( aFieldNdx )
  34. {
  35. case REFERENCE:
  36. return _( "Reference" ); // The component reference, R1, C1, etc.
  37. case VALUE:
  38. return _( "Value" ); // The component value + name
  39. case FOOTPRINT:
  40. return _( "Footprint" ); // The footprint for use with Pcbnew
  41. case DATASHEET:
  42. return _( "Datasheet" ); // Link to a datasheet for component
  43. default:
  44. break;
  45. }
  46. // Other fields are use fields, give a default name:
  47. wxString fieldName = _( "Field" );
  48. fieldName << aFieldNdx;
  49. return fieldName;
  50. }
  51. void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
  52. {
  53. out->Print( nestLevel, "(field (name %s)", out->Quotew( m_Name ).c_str() );
  54. if( !m_Value.IsEmpty() )
  55. out->Print( 0, "(value %s)", out->Quotew( m_Value ).c_str() );
  56. if( m_Visible )
  57. out->Print( 0, " visible" );
  58. out->Print( 0, ")\n" );
  59. }
  60. void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR )
  61. {
  62. T tok;
  63. in->NeedLEFT(); // begin (name ...)
  64. if( (tok = in->NextTok()) != T_name )
  65. in->Expecting( T_name );
  66. in->NeedSYMBOLorNUMBER();
  67. m_Name = FROM_UTF8( in->CurText() );
  68. in->NeedRIGHT(); // end (name ...)
  69. while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
  70. {
  71. // "visible" has no '(' prefix, "value" does, so T_LEFT is optional.
  72. if( tok == T_LEFT )
  73. tok = in->NextTok();
  74. switch( tok )
  75. {
  76. case T_value:
  77. in->NeedSYMBOLorNUMBER();
  78. m_Value = FROM_UTF8( in->CurText() );
  79. in->NeedRIGHT();
  80. break;
  81. case T_visible:
  82. m_Visible = true;
  83. break;
  84. default:
  85. in->Expecting( "value|visible" );
  86. break;
  87. }
  88. }
  89. }
  90. void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
  91. {
  92. // We'll keep this general, and include the \n, even though the only known
  93. // use at this time will not want the newlines or the indentation.
  94. out->Print( nestLevel, "(templatefields" );
  95. for( unsigned i=0; i<m_Fields.size(); ++i )
  96. m_Fields[i].Format( out, nestLevel+1 );
  97. out->Print( 0, ")\n" );
  98. }
  99. void TEMPLATES::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR )
  100. {
  101. T tok;
  102. while( ( tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
  103. {
  104. if( tok == T_LEFT )
  105. tok = in->NextTok();
  106. switch( tok )
  107. {
  108. case T_templatefields: // a token indicating class TEMPLATES.
  109. // Be flexible regarding the starting point of the TEMPLATE_FIELDNAMES_LEXER
  110. // stream. Caller may not have read the first two tokens out of the
  111. // stream: T_LEFT and T_templatefields, so ignore them if seen here.
  112. break;
  113. case T_field:
  114. {
  115. // instantiate on stack, so if exception is thrown,
  116. // destructor runs
  117. TEMPLATE_FIELDNAME field;
  118. field.Parse( in );
  119. // add the field
  120. AddTemplateFieldName( field );
  121. }
  122. break;
  123. default:
  124. in->Unexpected( in->CurText() );
  125. break;
  126. }
  127. }
  128. }
  129. int TEMPLATES::AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName )
  130. {
  131. // Ensure that the template fieldname does not match a fixed fieldname.
  132. for( int i=0; i<MANDATORY_FIELDS; ++i )
  133. {
  134. if( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) == aFieldName.m_Name )
  135. {
  136. return -1;
  137. }
  138. }
  139. // ensure uniqueness, overwrite any template fieldname by the same name.
  140. for( unsigned i=0; i<m_Fields.size(); ++i )
  141. {
  142. if( m_Fields[i].m_Name == aFieldName.m_Name )
  143. {
  144. // DBG( printf( "inserting template fieldname:'%s' at %d\n",
  145. // TO_UTF8( aFieldName.m_Name ), i ); )
  146. m_Fields[i] = aFieldName;
  147. return i; // return the container index
  148. }
  149. }
  150. // DBG(printf("appending template fieldname:'%s'\n", aFieldName.m_Name.utf8_str() );)
  151. // the name is legal and not previously added to the config container, append
  152. // it and return its index within the container.
  153. m_Fields.push_back( aFieldName );
  154. return m_Fields.size() - 1; // return the index of insertion.
  155. }
  156. bool TEMPLATES::HasFieldName( const wxString& aName ) const
  157. {
  158. for( size_t i=0; i<m_Fields.size(); ++i )
  159. {
  160. if( m_Fields[i].m_Name == aName )
  161. return true;
  162. }
  163. return false;
  164. }