KiCad PCB EDA Suite
sexpr_parse.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
30 #include <sexpr/sexpr_parser.h>
31 
33 
34 #include <common.h>
35 #include <profile.h>
36 
37 #include <wx/cmdline.h>
38 
39 #include <fstream>
40 #include <iostream>
41 
42 
44 {
45 public:
46  QA_SEXPR_PARSER( bool aVerbose ) : m_verbose( aVerbose )
47  {
48  }
49 
50  bool Parse( std::istream& aStream )
51  {
52  // Don't let the parser handle stream reading - we don't want to
53  // see how long the disk IO takes. Read to memory first (event the
54  // biggest files will fit in)
55  const std::string sexpr_str( std::istreambuf_iterator<char>( aStream ), {} );
56 
57  PROF_COUNTER timer;
58  // Perform the parse
59  std::unique_ptr<SEXPR::SEXPR> sexpr( m_parser.Parse( sexpr_str ) );
60 
61  if( m_verbose )
62  std::cout << "S-Expression Parsing took " << timer.msecs() << "ms" << std::endl;
63 
64  return sexpr != nullptr;
65  }
66 
67 private:
68  bool m_verbose;
70 };
71 
72 static const wxCmdLineEntryDesc g_cmdLineDesc[] = {
73  {
74  wxCMD_LINE_SWITCH,
75  "h",
76  "help",
77  _( "displays help on the command line parameters" ).mb_str(),
78  wxCMD_LINE_VAL_NONE,
79  wxCMD_LINE_OPTION_HELP,
80  },
81  {
82  wxCMD_LINE_SWITCH,
83  "v",
84  "verbose",
85  _( "print parsing information" ).mb_str(),
86  },
87  {
88  wxCMD_LINE_PARAM,
89  nullptr,
90  nullptr,
91  _( "input file" ).mb_str(),
92  wxCMD_LINE_VAL_STRING,
93  wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
94  },
95  { wxCMD_LINE_NONE }
96 };
97 
98 
100 {
102 };
103 
104 
105 int sexpr_parser_func( int argc, char* argv[] )
106 {
107  wxCmdLineParser cl_parser( argc, argv );
108  cl_parser.SetDesc( g_cmdLineDesc );
109  cl_parser.AddUsageText( _( "Tests parsing of S-Expression files" ) );
110 
111  int cmd_parsed_ok = cl_parser.Parse();
112  if( cmd_parsed_ok != 0 )
113  {
114  // Help and invalid input both stop here
115  return ( cmd_parsed_ok == -1 ) ? KI_TEST::RET_CODES::OK : KI_TEST::RET_CODES::BAD_CMDLINE;
116  }
117 
118  const auto file_count = cl_parser.GetParamCount();
119  const bool verbose = cl_parser.Found( "verbose" );
120 
121  QA_SEXPR_PARSER qa_parser( verbose );
122 
123  bool ok = true;
124 
125  if( file_count == 0 )
126  {
127  // Parse the file provided on stdin - used by AFL to drive the
128  // program
129  qa_parser.Parse( std::cin );
130  }
131  else
132  {
133  // Parse 'n' files given on the command line
134  // (this is useful for input minimisation (e.g. afl-tmin) as
135  // well as manual testing
136  for( unsigned i = 0; i < file_count; i++ )
137  {
138  const auto filename = cl_parser.GetParam( i ).ToStdString();
139 
140  if( verbose )
141  std::cout << "Parsing: " << filename << std::endl;
142 
143  std::ifstream fin;
144  fin.open( filename );
145 
146  ok = ok && qa_parser.Parse( fin );
147  }
148  }
149 
150  if( !ok )
152 
153  return KI_TEST::RET_CODES::OK;
154 }
155 
156 
158  "sexpr_parser",
159  "Benchmark s-expression parsing",
161 } );
static bool registered
Tools can define their own statuses from here onwards.
double msecs(bool aSinceLast=false)
Definition: profile.h:143
#define OK
The command line was not correct for the tool.
static const wxCmdLineEntryDesc g_cmdLineDesc[]
Definition: sexpr_parse.cpp:72
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:44
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
std::unique_ptr< SEXPR > Parse(const std::string &aString)
SEXPR::PARSER m_parser
Definition: sexpr_parse.cpp:69
int sexpr_parser_func(int argc, char *argv[])
#define _(s)
Definition: 3d_actions.cpp:33
The common library.
bool Parse(std::istream &aStream)
Definition: sexpr_parse.cpp:50
QA_SEXPR_PARSER(bool aVerbose)
Definition: sexpr_parse.cpp:46
PARSER_RET_CODES
Definition: sexpr_parse.cpp:99