18#include "../base/Variant.h"
19#include "../base/PNode.h"
20#include "../base/grammar.tab.hpp"
22#include "../utility/PEBLPath.h"
23#include "../utility/PEBLUtility.h"
24#include "../utility/PError.h"
40#include "../base/FunctionMap.h"
41#include "../base/VariableMap.h"
42#include "../base/Evaluator.h"
43#include "../base/Loader.h"
44#include "../devices/PEventLoop.h"
61static const char* STANDARD_LIBRARIES[] = {
79 cout <<
"PEBL Validator - Syntax and Function Checker\n";
80 cout <<
"Usage: pebl-validator <file.pbl> [options]\n\n";
82 cout <<
" --json Output results as JSON\n";
83 cout <<
" --help Show this help message\n\n";
84 cout <<
"Exit codes:\n";
85 cout <<
" 0 = Valid syntax and all functions defined\n";
86 cout <<
" 1 = Invalid syntax or undefined functions\n";
87 cout <<
" 2 = Usage error\n\n";
88 cout <<
"Features:\n";
89 cout <<
" - Parses PEBL syntax without execution\n";
90 cout <<
" - Validates all function calls against standard libraries\n";
91 cout <<
" - Detects undefined functions\n";
96 cout <<
" \"file\": \"" << filename <<
"\",\n";
97 cout <<
" \"syntax_valid\": " << (
gSyntaxValid ?
"true" :
"false") <<
",\n";
98 cout <<
" \"errors\": [\n";
99 for (
size_t i = 0; i <
gErrors.size(); i++) {
103 while ((pos = msg.find(
'"', pos)) != string::npos) {
104 msg.replace(pos, 1,
"\\\"");
107 cout <<
" \"" << msg <<
"\"";
108 if (i <
gErrors.size() - 1) cout <<
",";
112 cout <<
" \"warnings\": [\n";
113 for (
size_t i = 0; i <
gWarnings.size(); i++) {
117 while ((pos = msg.find(
'\"', pos)) != string::npos) {
118 msg.replace(pos, 1,
"\\\"");
121 cout <<
" \"" << msg <<
"\"";
122 if (i <
gWarnings.size() - 1) cout <<
",";
130 cout <<
"PEBL Validator Results\n";
131 cout <<
"======================\n";
132 cout <<
"File: " << filename <<
"\n\n";
135 cout <<
"✓ Syntax: VALID\n";
137 cout <<
"✗ Syntax: INVALID\n";
141 cout <<
"\nErrors:\n";
142 for (
const auto& err :
gErrors) {
143 cout <<
" ✗ " << err <<
"\n";
148 cout <<
"\nWarnings:\n";
150 cout <<
" ⚠ " << warn <<
"\n";
156int main(
int argc,
char *argv[]) {
169 bool json_output =
false;
172 for (
int i = 1; i < argc; i++) {
173 string arg = argv[i];
174 if (arg ==
"--help") {
177 }
else if (arg ==
"--json") {
179 }
else if (filename.empty()) {
182 cerr <<
"Error: Unknown argument: " << arg <<
"\n";
188 if (filename.empty()) {
189 cerr <<
"Error: No file specified\n";
197 gErrors.push_back(
"File not found: " + filename);
207 std::list<std::string> files;
208 files.push_back(
"pebl-validator");
209 files.push_back(filename);
218 cerr <<
"Parsing user file: " << filename << endl;
223 gErrors.push_back(
"Parse failed - syntax error in file");
226 for (
int i = 0; STANDARD_LIBRARIES[i] !=
NULL; i++) {
229 cerr <<
"Loading library: " << STANDARD_LIBRARIES[i] << endl;
230 tmp =
parse(libpath.c_str());
233 head =
new OpNode(PEBL_FUNCTIONS,
head, tmp,
"INTERNAL PEBL STRUCTURE", -1);
239 cerr <<
"Validating functions..." << endl;
252 gErrors.push_back(
"Start() function must have exactly one parameter to receive command-line arguments (e.g., define Start(p))");
257 gWarnings.push_back(
"No Start() function found - PEBL scripts should define a Start() function as the entry point");
265 }
catch (
const std::runtime_error& e) {
276 }
catch (
const std::exception& e) {
278 gErrors.push_back(
string(
"Parse exception: ") + e.what());
286 gErrors.push_back(
"Validation failed - unknown error");
int main(int argc, char *argv[])
void PrintJSONResults(const string &filename)
void PrintTextResults(const string &filename)
vector< string > gWarnings
This class has got everything you need to evaluate stuff.
static const PNode * gEvalNode
static PCallStack gCallStack
static PEventLoop * mEventLoop
static VariableMap gGlobalVariableMap
static FunctionMap mFunctionMap
Initiate some static member data.
void LoadUserFunctions(OpNode *node)
void LoadLibraryFunctions()
void FindFunctions(const PNode *Node)
PNode * GetMainPEBLFunction()
std::string FindFile(const string &filename)
void Initialize(std::list< std::string >)
Variant FileExists(std::string path)