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.

236 lines
6.5 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. #include <pgm_base.h>
  29. using namespace TFIELD_T;
  30. const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx )
  31. {
  32. static void* locale = nullptr;
  33. static wxString referenceDefault;
  34. static wxString valueDefault;
  35. static wxString footprintDefault;
  36. static wxString datasheetDefault;
  37. static wxString fieldDefault;
  38. // Fetching translations can take a surprising amount of time when loading libraries,
  39. // so only do it when necessary.
  40. if( Pgm().GetLocale() != locale )
  41. {
  42. referenceDefault = _( "Reference" );
  43. valueDefault = _( "Value" );
  44. footprintDefault = _( "Footprint" );
  45. datasheetDefault = _( "Datasheet" );
  46. fieldDefault = _( "Field" );
  47. locale = Pgm().GetLocale();
  48. }
  49. // Fixed values for the first few default fields used by EESCHEMA
  50. // (mandatory fields)
  51. switch( aFieldNdx )
  52. {
  53. case REFERENCE:
  54. return referenceDefault; // The component reference, R1, C1, etc.
  55. case VALUE:
  56. return valueDefault; // The component value + name
  57. case FOOTPRINT:
  58. return footprintDefault; // The footprint for use with Pcbnew
  59. case DATASHEET:
  60. return datasheetDefault; // Link to a datasheet for component
  61. default:
  62. break;
  63. }
  64. // Other fields are use fields, give a default name:
  65. wxString fieldName = fieldDefault;
  66. fieldName << aFieldNdx;
  67. return fieldName;
  68. }
  69. void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const
  70. {
  71. out->Print( nestLevel, "(field (name %s)", out->Quotew( m_Name ).c_str() );
  72. if( m_Visible )
  73. out->Print( 0, " visible" );
  74. if( m_URL )
  75. out->Print( 0, " url" );
  76. out->Print( 0, ")\n" );
  77. }
  78. void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in )
  79. {
  80. T tok;
  81. in->NeedLEFT(); // begin (name ...)
  82. if( (tok = in->NextTok()) != T_name )
  83. in->Expecting( T_name );
  84. in->NeedSYMBOLorNUMBER();
  85. m_Name = FROM_UTF8( in->CurText() );
  86. in->NeedRIGHT(); // end (name ...)
  87. while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
  88. {
  89. // "visible" has no '(' prefix, "value" does, so T_LEFT is optional.
  90. if( tok == T_LEFT )
  91. tok = in->NextTok();
  92. switch( tok )
  93. {
  94. case T_value:
  95. // older format; silently skip
  96. in->NeedSYMBOLorNUMBER();
  97. in->NeedRIGHT();
  98. break;
  99. case T_visible:
  100. m_Visible = true;
  101. break;
  102. case T_url:
  103. m_URL = true;
  104. break;
  105. default:
  106. in->Expecting( "value|url|visible" );
  107. break;
  108. }
  109. }
  110. }
  111. void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel ) const
  112. {
  113. // We'll keep this general, and include the \n, even though the only known
  114. // use at this time will not want the newlines or the indentation.
  115. out->Print( nestLevel, "(templatefields" );
  116. for( unsigned i=0; i<m_Fields.size(); ++i )
  117. m_Fields[i].Format( out, nestLevel+1 );
  118. out->Print( 0, ")\n" );
  119. }
  120. void TEMPLATES::Parse( TEMPLATE_FIELDNAMES_LEXER* in )
  121. {
  122. T tok;
  123. while( ( tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
  124. {
  125. if( tok == T_LEFT )
  126. tok = in->NextTok();
  127. switch( tok )
  128. {
  129. case T_templatefields: // a token indicating class TEMPLATES.
  130. // Be flexible regarding the starting point of the TEMPLATE_FIELDNAMES_LEXER
  131. // stream. Caller may not have read the first two tokens out of the
  132. // stream: T_LEFT and T_templatefields, so ignore them if seen here.
  133. break;
  134. case T_field:
  135. {
  136. // instantiate on stack, so if exception is thrown,
  137. // destructor runs
  138. TEMPLATE_FIELDNAME field;
  139. field.Parse( in );
  140. // add the field
  141. AddTemplateFieldName( field );
  142. }
  143. break;
  144. default:
  145. in->Unexpected( in->CurText() );
  146. break;
  147. }
  148. }
  149. }
  150. int TEMPLATES::AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName )
  151. {
  152. // Ensure that the template fieldname does not match a fixed fieldname.
  153. for( int i=0; i<MANDATORY_FIELDS; ++i )
  154. {
  155. if( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) == aFieldName.m_Name )
  156. {
  157. return -1;
  158. }
  159. }
  160. // ensure uniqueness, overwrite any template fieldname by the same name.
  161. for( unsigned i=0; i<m_Fields.size(); ++i )
  162. {
  163. if( m_Fields[i].m_Name == aFieldName.m_Name )
  164. {
  165. // DBG( printf( "inserting template fieldname:'%s' at %d\n",
  166. // TO_UTF8( aFieldName.m_Name ), i ); )
  167. m_Fields[i] = aFieldName;
  168. return i; // return the container index
  169. }
  170. }
  171. // DBG(printf("appending template fieldname:'%s'\n", aFieldName.m_Name.utf8_str() );)
  172. // the name is legal and not previously added to the config container, append
  173. // it and return its index within the container.
  174. m_Fields.push_back( aFieldName );
  175. return m_Fields.size() - 1; // return the index of insertion.
  176. }
  177. const TEMPLATE_FIELDNAME* TEMPLATES::GetFieldName( const wxString& aName ) const
  178. {
  179. for( const TEMPLATE_FIELDNAME& field : m_Fields )
  180. {
  181. if( field.m_Name == aName )
  182. return &field;
  183. }
  184. return nullptr;
  185. }