Initial Commit V2 (Used code from OBWB8m Data Parser)
This commit is contained in:
17
.project
Normal file
17
.project
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>SiteParser</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
60
HTMLExecuteFormConverter.cpp
Normal file
60
HTMLExecuteFormConverter.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
#include "HTMLExecuteFormConverter.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void Execute_ParseFromHTML( const String argName, const String arg, execute_t* structure ) {
|
||||
|
||||
Serial.printf("'%s' with associated value '%s'\n", argName, arg);
|
||||
char key[sizeof(argName)];
|
||||
argName.toCharArray(key, sizeof(key));
|
||||
int32_t tempVar = -1;
|
||||
uint32_t value = 0;
|
||||
|
||||
if (sscanf(key, "%*[^_]_%d", &tempVar) <= 0) {
|
||||
return;
|
||||
} else {
|
||||
value = tempVar;
|
||||
}
|
||||
|
||||
switch (key[0]) {
|
||||
case 'v':
|
||||
switch (key[1]) {
|
||||
case '1':
|
||||
switch (key[2]) {
|
||||
case '_':
|
||||
switch (value) {
|
||||
case 1:
|
||||
structure->Command = (ExecuteCommand_t) arg.toInt(); // need to prevent overflows
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} //Execute_ParseFromHTML
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
String Execute_ParseToHTML(execute_t* structure) {
|
||||
JsonDocument doc;
|
||||
|
||||
doc["v1_1"] = structure->Command;
|
||||
|
||||
|
||||
String output;
|
||||
|
||||
doc.shrinkToFit(); // optional, releases unused memory
|
||||
|
||||
serializeJson(doc, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
20
HTMLExecuteFormConverter.h
Normal file
20
HTMLExecuteFormConverter.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _HTMLEXECUTEFORMCONVERTER
|
||||
#define _HTMLEXECUTEFORMCONVERTER
|
||||
|
||||
#include <WString.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "STM32 Shared Structs/execute.h"
|
||||
|
||||
|
||||
void Execute_ParseFromHTML(const String argName, const String arg, execute_t* structure);
|
||||
|
||||
String Execute_ParseToHTML( execute_t* structure );
|
||||
|
||||
|
||||
#endif
|
||||
2044
HTMLFormConverter.cpp
Normal file
2044
HTMLFormConverter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
20
HTMLFormConverter.h
Normal file
20
HTMLFormConverter.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _HTMLFORMCONVERTER
|
||||
#define _HTMLFORMCONVERTER
|
||||
|
||||
#include <WString.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "STM32 Shared Structs/config.h"
|
||||
|
||||
|
||||
void Config_ParseFromHTML(const String argName, const String arg, config_t* structure);
|
||||
|
||||
String Config_ParseToHTML( config_t* structure );
|
||||
|
||||
|
||||
#endif
|
||||
151
HTMLStatusParser.cpp
Normal file
151
HTMLStatusParser.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
#include "HTMLStatusParser.h"
|
||||
#include <ArduinoJson.h>
|
||||
String Status_ParseToHTML(status_t* structure) {
|
||||
JsonDocument doc;
|
||||
|
||||
doc["v0_1"] = structure->chval[0].Status;
|
||||
doc["v1_1"] = structure->chval[0].Lambda;
|
||||
doc["v2_1"] = structure->chval[0].AFR;
|
||||
doc["v0_2"] = structure->chval[1].Status;
|
||||
doc["v1_2"] = structure->chval[1].Lambda;
|
||||
doc["v2_2"] = structure->chval[1].AFR;
|
||||
doc["v0_3"] = structure->chval[2].Status;
|
||||
doc["v1_3"] = structure->chval[2].Lambda;
|
||||
doc["v2_3"] = structure->chval[2].AFR;
|
||||
doc["v0_4"] = structure->chval[3].Status;
|
||||
doc["v1_4"] = structure->chval[3].Lambda;
|
||||
doc["v2_4"] = structure->chval[3].AFR;
|
||||
doc["v0_5"] = structure->chval[4].Status;
|
||||
doc["v1_5"] = structure->chval[4].Lambda;
|
||||
doc["v2_5"] = structure->chval[4].AFR;
|
||||
doc["v0_6"] = structure->chval[5].Status;
|
||||
doc["v1_6"] = structure->chval[5].Lambda;
|
||||
doc["v2_6"] = structure->chval[5].AFR;
|
||||
doc["v0_7"] = structure->chval[6].Status;
|
||||
doc["v1_7"] = structure->chval[6].Lambda;
|
||||
doc["v2_7"] = structure->chval[6].AFR;
|
||||
doc["v0_8"] = structure->chval[7].Status;
|
||||
doc["v1_8"] = structure->chval[7].Lambda;
|
||||
doc["v2_8"] = structure->chval[7].AFR;
|
||||
|
||||
|
||||
String output;
|
||||
|
||||
doc.shrinkToFit(); // optional, releases unused memory
|
||||
|
||||
serializeJson(doc, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
String Status_AllParseToHTML(status_t* structure) {
|
||||
JsonDocument doc;
|
||||
|
||||
doc["v0_1"] = structure->chval[0].Status;
|
||||
doc["v1_1"] = structure->chval[0].Lambda;
|
||||
doc["v2_1"] = structure->chval[0].AFR;
|
||||
doc["v0_2"] = structure->chval[1].Status;
|
||||
doc["v1_2"] = structure->chval[1].Lambda;
|
||||
doc["v2_2"] = structure->chval[1].AFR;
|
||||
doc["v0_3"] = structure->chval[2].Status;
|
||||
doc["v1_3"] = structure->chval[2].Lambda;
|
||||
doc["v2_3"] = structure->chval[2].AFR;
|
||||
doc["v0_4"] = structure->chval[3].Status;
|
||||
doc["v1_4"] = structure->chval[3].Lambda;
|
||||
doc["v2_4"] = structure->chval[3].AFR;
|
||||
doc["v0_5"] = structure->chval[4].Status;
|
||||
doc["v1_5"] = structure->chval[4].Lambda;
|
||||
doc["v2_5"] = structure->chval[4].AFR;
|
||||
doc["v0_6"] = structure->chval[5].Status;
|
||||
doc["v1_6"] = structure->chval[5].Lambda;
|
||||
doc["v2_6"] = structure->chval[5].AFR;
|
||||
doc["v0_7"] = structure->chval[6].Status;
|
||||
doc["v1_7"] = structure->chval[6].Lambda;
|
||||
doc["v2_7"] = structure->chval[6].AFR;
|
||||
doc["v0_8"] = structure->chval[7].Status;
|
||||
doc["v1_8"] = structure->chval[7].Lambda;
|
||||
doc["v2_8"] = structure->chval[7].AFR;
|
||||
doc["v4_1"] = structure->chdiag[0].Rtag;
|
||||
doc["v5_1"] = structure->chdiag[0].HtrV;
|
||||
doc["v6_1"] = structure->chdiag[0].HtrIavg;
|
||||
doc["v7_1"] = structure->chdiag[0].HtrP;
|
||||
doc["v8_1"] = structure->chdiag[0].HtrDutyPct;
|
||||
doc["v9_1"] = structure->chdiag[0].Ip_mA;
|
||||
doc["v10_1"] = structure->chdiag[0].Vs_volts;
|
||||
doc["v11_1"] = structure->chdiag[0].Vs_ohms;
|
||||
doc["v4_2"] = structure->chdiag[1].Rtag;
|
||||
doc["v5_2"] = structure->chdiag[1].HtrV;
|
||||
doc["v6_2"] = structure->chdiag[1].HtrIavg;
|
||||
doc["v7_2"] = structure->chdiag[1].HtrP;
|
||||
doc["v8_2"] = structure->chdiag[1].HtrDutyPct;
|
||||
doc["v9_2"] = structure->chdiag[1].Ip_mA;
|
||||
doc["v10_2"] = structure->chdiag[1].Vs_volts;
|
||||
doc["v11_2"] = structure->chdiag[1].Vs_ohms;
|
||||
doc["v4_3"] = structure->chdiag[2].Rtag;
|
||||
doc["v5_3"] = structure->chdiag[2].HtrV;
|
||||
doc["v6_3"] = structure->chdiag[2].HtrIavg;
|
||||
doc["v7_3"] = structure->chdiag[2].HtrP;
|
||||
doc["v8_3"] = structure->chdiag[2].HtrDutyPct;
|
||||
doc["v9_3"] = structure->chdiag[2].Ip_mA;
|
||||
doc["v10_3"] = structure->chdiag[2].Vs_volts;
|
||||
doc["v11_3"] = structure->chdiag[2].Vs_ohms;
|
||||
doc["v4_4"] = structure->chdiag[3].Rtag;
|
||||
doc["v5_4"] = structure->chdiag[3].HtrV;
|
||||
doc["v6_4"] = structure->chdiag[3].HtrIavg;
|
||||
doc["v7_4"] = structure->chdiag[3].HtrP;
|
||||
doc["v8_4"] = structure->chdiag[3].HtrDutyPct;
|
||||
doc["v9_4"] = structure->chdiag[3].Ip_mA;
|
||||
doc["v10_4"] = structure->chdiag[3].Vs_volts;
|
||||
doc["v11_4"] = structure->chdiag[3].Vs_ohms;
|
||||
doc["v4_5"] = structure->chdiag[4].Rtag;
|
||||
doc["v5_5"] = structure->chdiag[4].HtrV;
|
||||
doc["v6_5"] = structure->chdiag[4].HtrIavg;
|
||||
doc["v7_5"] = structure->chdiag[4].HtrP;
|
||||
doc["v8_5"] = structure->chdiag[4].HtrDutyPct;
|
||||
doc["v9_5"] = structure->chdiag[4].Ip_mA;
|
||||
doc["v10_5"] = structure->chdiag[4].Vs_volts;
|
||||
doc["v11_5"] = structure->chdiag[4].Vs_ohms;
|
||||
doc["v4_6"] = structure->chdiag[5].Rtag;
|
||||
doc["v5_6"] = structure->chdiag[5].HtrV;
|
||||
doc["v6_6"] = structure->chdiag[5].HtrIavg;
|
||||
doc["v7_6"] = structure->chdiag[5].HtrP;
|
||||
doc["v8_6"] = structure->chdiag[5].HtrDutyPct;
|
||||
doc["v9_6"] = structure->chdiag[5].Ip_mA;
|
||||
doc["v10_6"] = structure->chdiag[5].Vs_volts;
|
||||
doc["v11_6"] = structure->chdiag[5].Vs_ohms;
|
||||
doc["v4_7"] = structure->chdiag[6].Rtag;
|
||||
doc["v5_7"] = structure->chdiag[6].HtrV;
|
||||
doc["v6_7"] = structure->chdiag[6].HtrIavg;
|
||||
doc["v7_7"] = structure->chdiag[6].HtrP;
|
||||
doc["v8_7"] = structure->chdiag[6].HtrDutyPct;
|
||||
doc["v9_7"] = structure->chdiag[6].Ip_mA;
|
||||
doc["v10_7"] = structure->chdiag[6].Vs_volts;
|
||||
doc["v11_7"] = structure->chdiag[6].Vs_ohms;
|
||||
doc["v4_8"] = structure->chdiag[7].Rtag;
|
||||
doc["v5_8"] = structure->chdiag[7].HtrV;
|
||||
doc["v6_8"] = structure->chdiag[7].HtrIavg;
|
||||
doc["v7_8"] = structure->chdiag[7].HtrP;
|
||||
doc["v8_8"] = structure->chdiag[7].HtrDutyPct;
|
||||
doc["v9_8"] = structure->chdiag[7].Ip_mA;
|
||||
doc["v10_8"] = structure->chdiag[7].Vs_volts;
|
||||
doc["v11_8"] = structure->chdiag[7].Vs_ohms;
|
||||
doc["v12_1"] = structure->internal.V3v3;
|
||||
doc["v13_1"] = structure->internal.Mon5v;
|
||||
doc["v14_1"] = structure->internal.TempDegC;
|
||||
|
||||
|
||||
String output;
|
||||
|
||||
doc.shrinkToFit(); // optional, releases unused memory
|
||||
|
||||
serializeJson(doc, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
19
HTMLStatusParser.h
Normal file
19
HTMLStatusParser.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _HTMLSTATUSPARSER
|
||||
#define _HTMLSTATUSPARSER
|
||||
|
||||
#include <WString.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "STM32 Shared Structs/status.h"
|
||||
|
||||
|
||||
String Status_ParseToHTML( status_t* structure );
|
||||
String Status_AllParseToHTML( status_t* structure );
|
||||
|
||||
|
||||
#endif
|
||||
15
STMFirmware.h
Normal file
15
STMFirmware.h
Normal file
File diff suppressed because one or more lines are too long
126
compiled.h
Normal file
126
compiled.h
Normal file
File diff suppressed because one or more lines are too long
370
initializeHTTP.cpp
Normal file
370
initializeHTTP.cpp
Normal file
@@ -0,0 +1,370 @@
|
||||
//
|
||||
//
|
||||
// Created by Jakob Oberbuchner's Generator
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include "initializeHTTP.h"
|
||||
|
||||
#include "compiled.h"
|
||||
void initializeServerHTTP_GET(AsyncWebServer *server_) {
|
||||
|
||||
// Must have Index page for this to work
|
||||
server_->on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_indexhtml, sizeof(a_indexhtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_indexhtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
|
||||
server_->on("/networkSetup.js", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", a_networkSetupjs, sizeof(a_networkSetupjs));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_networkSetupjs));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Update.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_Updatehtml, sizeof(a_Updatehtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Updatehtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_indexhtml, sizeof(a_indexhtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_indexhtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/default-image-3.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesdefaultimage3jpg, sizeof(a_imagesdefaultimage3jpg));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesdefaultimage3jpg));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/default-image-4.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesdefaultimage4jpg, sizeof(a_imagesdefaultimage4jpg));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesdefaultimage4jpg));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/OberbuiltLogoMod.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesOberbuiltLogoModpng, sizeof(a_imagesOberbuiltLogoModpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesOberbuiltLogoModpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/default-image.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesdefaultimagejpg, sizeof(a_imagesdefaultimagejpg));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesdefaultimagejpg));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/Custom/MinusBox.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesCustomMinusBoxpng, sizeof(a_imagesCustomMinusBoxpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesCustomMinusBoxpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/Custom/x.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesCustomxpng, sizeof(a_imagesCustomxpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesCustomxpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/Custom/AddBox.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesCustomAddBoxpng, sizeof(a_imagesCustomAddBoxpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesCustomAddBoxpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/Custom/Arrow.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesCustomArrowpng, sizeof(a_imagesCustomArrowpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesCustomArrowpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/images/Custom/checkmark.png", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/jpg", a_imagesCustomcheckmarkpng, sizeof(a_imagesCustomcheckmarkpng));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_imagesCustomcheckmarkpng));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Update.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_Updatecss, sizeof(a_Updatecss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Updatecss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/login.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// Accessible without login!!
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_logincss, sizeof(a_logincss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_logincss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/nicepage.js", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", a_nicepagejs, sizeof(a_nicepagejs));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_nicepagejs));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/index.js", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", a_indexjs, sizeof(a_indexjs));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_indexjs));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Reboot.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_Reboothtml, sizeof(a_Reboothtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Reboothtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/index.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_indexcss, sizeof(a_indexcss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_indexcss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Live-Data.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_LiveDatahtml, sizeof(a_LiveDatahtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_LiveDatahtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Reboot.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_Rebootcss, sizeof(a_Rebootcss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Rebootcss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Commands.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
if(!request->authenticate(http_username, http_password)) { return request->requestAuthentication(); } AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_Commandshtml, sizeof(a_Commandshtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Commandshtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/networkSetup.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_networkSetuphtml, sizeof(a_networkSetuphtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_networkSetuphtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/nicepage.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_nicepagecss, sizeof(a_nicepagecss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_nicepagecss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Live-Data.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_LiveDatacss, sizeof(a_LiveDatacss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_LiveDatacss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/chart.umd.min.js", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", a_chartumdminjs, sizeof(a_chartumdminjs));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_chartumdminjs));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Commands.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
if(!request->authenticate(http_username, http_password)) { return request->requestAuthentication(); } AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_Commandscss, sizeof(a_Commandscss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Commandscss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/Settings.html", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", a_Settingshtml, sizeof(a_Settingshtml));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_Settingshtml));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/networkSetup.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css", a_networkSetupcss, sizeof(a_networkSetupcss));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_networkSetupcss));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server_->on("/jquery.js", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (!authenticateLogin(request)) return; // Make sure the user requesting this has logged in
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/javascript", a_jqueryjs, sizeof(a_jqueryjs));
|
||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||
response->addHeader("Connection", "close");
|
||||
response->addHeader("Cache-Control", "max-age=30"); // 30 second cache life
|
||||
response->setContentLength(sizeof(a_jqueryjs));
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void initializeServerHTTP_POST(AsyncWebServer *server_, bool* requiresRestart) {
|
||||
|
||||
server_->on("/UpdateFirmware", HTTP_POST, [requiresRestart](AsyncWebServerRequest *request) {
|
||||
parse_a_Updatehtml_FirmwareUpdater_POST(request);
|
||||
request->send(204);
|
||||
*requiresRestart = true;
|
||||
},
|
||||
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
//Add redirection?
|
||||
if (!index) {
|
||||
Serial.printf("Updating: %s\n", filename.c_str());
|
||||
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
if (Update.write(data, len) != len) {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
if (final) {
|
||||
if (!Update.end(true)) {
|
||||
Update.printError(Serial);
|
||||
} else {
|
||||
Serial.println("Update complete! Needs a Restart.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
server_->on("/FactoryReset", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
if (parse_a_Updatehtml_resetform_POST(request)) {
|
||||
request->send(204);
|
||||
} else {
|
||||
request->send(500); //Internal server error, indicates the post was not successful
|
||||
}
|
||||
});
|
||||
|
||||
server_->on("/Settings", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
if (parse_a_indexhtml_Config_POST(request)) {
|
||||
request->send(204);
|
||||
} else {
|
||||
request->send(500); //Internal server error, indicates the post was not successful
|
||||
}
|
||||
});
|
||||
|
||||
server_->on("/Execute", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
if (parse_a_Commandshtml_Execute_POST(request)) {
|
||||
request->send(204);
|
||||
} else {
|
||||
request->send(500); //Internal server error, indicates the post was not successful
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
25
initializeHTTP.h
Normal file
25
initializeHTTP.h
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef __initializeServerHTTP_GET_cpp
|
||||
#define __initializeServerHTTP_GET_cpp
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
#include <Update.h>
|
||||
|
||||
#include "Misc_Classes.hpp"
|
||||
|
||||
void initializeServerHTTP_GET(AsyncWebServer *server_);
|
||||
void initializeServerHTTP_POST(AsyncWebServer *server_, bool* requiresRestart);
|
||||
|
||||
bool parse_a_Updatehtml_FirmwareUpdater_POST (AsyncWebServerRequest *request);
|
||||
bool parse_a_Updatehtml_resetform_POST (AsyncWebServerRequest *request);
|
||||
bool parse_a_indexhtml_Config_POST (AsyncWebServerRequest *request);
|
||||
bool parse_a_Commandshtml_Execute_POST (AsyncWebServerRequest *request);
|
||||
|
||||
#endif
|
||||
26
initializeHTTPWeak.cpp
Normal file
26
initializeHTTPWeak.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
//
|
||||
// This File was generated or modified by Jakob A. Oberbuchner's Generator/Intrepreter (2025)
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
|
||||
bool parse_a_Updatehtml_FirmwareUpdater_POST (AsyncWebServerRequest *request) __attribute__((weak));
|
||||
bool parse_a_Updatehtml_FirmwareUpdater_POST (AsyncWebServerRequest *request) { return true; }
|
||||
|
||||
|
||||
bool parse_a_Updatehtml_resetform_POST (AsyncWebServerRequest *request) __attribute__((weak));
|
||||
bool parse_a_Updatehtml_resetform_POST (AsyncWebServerRequest *request) { return true; }
|
||||
|
||||
|
||||
bool parse_a_indexhtml_Config_POST (AsyncWebServerRequest *request) __attribute__((weak));
|
||||
bool parse_a_indexhtml_Config_POST (AsyncWebServerRequest *request) { return true; }
|
||||
|
||||
|
||||
bool parse_a_Commandshtml_Execute_POST (AsyncWebServerRequest *request) __attribute__((weak));
|
||||
bool parse_a_Commandshtml_Execute_POST (AsyncWebServerRequest *request) { return true; }
|
||||
|
||||
|
||||
243
src/CHeaderParser.java
Normal file
243
src/CHeaderParser.java
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* Jakob A. Oberbuchner April, 24, 2025
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Stack;
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CHeaderParser {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
C_Type type1 = C_Type.valueOfTypeName("struct");
|
||||
|
||||
C_Type type2 = C_Type.valueOfTypeName("uint16_t");
|
||||
|
||||
C_Type type3 = C_Type.valueOfTypeName("float");
|
||||
|
||||
|
||||
System.out.println(type1);
|
||||
System.out.println(type2);
|
||||
System.out.println(type3);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<C_DataStructure> parseHeader(String file) {
|
||||
|
||||
ArrayList<C_DataStructure> data = new ArrayList<C_DataStructure>();
|
||||
|
||||
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader( new FileReader(file));
|
||||
|
||||
Stack<C_DataStructure> structureStack = new Stack<C_DataStructure>();
|
||||
|
||||
Stack<ParseState> stateStack = new Stack<ParseState>();
|
||||
|
||||
String nextLine = null;
|
||||
|
||||
while((nextLine = reader.readLine()) != null) {
|
||||
nextLine = nextLine.strip().replace("\t", "");
|
||||
|
||||
//typedef enum { bps125K, bps250K, bps500K, bps1M } CANbps_t;
|
||||
//typedef struct config_s
|
||||
//uint8_t NumPackets; // 1-16 (determines how many Broadcast[x] are displayed)
|
||||
//} config_t;
|
||||
|
||||
String[] tokens = nextLine.split(" ", 2);
|
||||
if (tokens.length == 0) {
|
||||
continue; //nothing for us
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < tokens.length; i++) {
|
||||
String current = tokens[i];
|
||||
|
||||
switch (stateStack.peek()) {
|
||||
case Looking:
|
||||
case null:
|
||||
//General, looking for next thing
|
||||
|
||||
break;
|
||||
|
||||
case OpenBracket:
|
||||
if (current == "{") {
|
||||
stateStack.pop();
|
||||
// stateStack.add(ParseState.Looking);
|
||||
} else {
|
||||
System.out.println("NOT open bracket BADDDD");
|
||||
}
|
||||
break;
|
||||
|
||||
case CloseBracket:
|
||||
|
||||
break;
|
||||
|
||||
case EnumVariables:
|
||||
break;
|
||||
|
||||
case Name:
|
||||
break;
|
||||
|
||||
case Type:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tokens[0]) {
|
||||
case "{":
|
||||
|
||||
break;
|
||||
|
||||
case "}":
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
C_Type type = C_Type.valueOfTypeName(tokens[0].strip());
|
||||
|
||||
switch (type) {
|
||||
case Typedef:
|
||||
|
||||
case Enum:
|
||||
case Struct:
|
||||
// structureStack.
|
||||
break;
|
||||
|
||||
case null:
|
||||
|
||||
break;
|
||||
|
||||
default: //Any other type
|
||||
|
||||
}
|
||||
|
||||
if (type != null && tokens.length >= 2) {
|
||||
String name = tokens[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return data;
|
||||
}//parseHeader
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum ParseState {
|
||||
Looking, Type, Name, OpenBracket, CloseBracket, EnumVariables
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class C_DataStructure {
|
||||
private C_Type type;
|
||||
private String name;
|
||||
private String typedefName;
|
||||
private ArrayList<C_DataStructure> subStructures;
|
||||
|
||||
|
||||
public C_DataStructure( ) {
|
||||
this.type = null;
|
||||
this.name = null;
|
||||
this.typedefName = null;
|
||||
this.subStructures = new ArrayList<C_DataStructure>();
|
||||
}
|
||||
|
||||
|
||||
public C_Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(C_Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return (typedefName != null) ? typedefName : name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setTypedefName(String name) {
|
||||
this.typedefName = name;
|
||||
}
|
||||
|
||||
public void addSubStructure(C_DataStructure subStructure) {
|
||||
this.subStructures.add(subStructure);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
enum C_Type {
|
||||
Struct("struct"), Enum("enum"), Typedef("typedef"),
|
||||
Int64("int64_t"), Int32("int32_t"), Int16("int16_t"), Int8("int8_t"),
|
||||
UInt64("uint64_t"), UInt32("uint32_t"), UInt16("uint16_t"), UInt8("uint8_t"),
|
||||
Float("float"), Double("double"); //Union
|
||||
|
||||
public final String typeName;
|
||||
|
||||
C_Type(String typeName) {
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public static C_Type valueOfTypeName(String label) {
|
||||
for (C_Type e : values()) {
|
||||
if (e.typeName.equals(label)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String toString( ) {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
}
|
||||
1083
src/Converters/C_Swift_Converter.java
Normal file
1083
src/Converters/C_Swift_Converter.java
Normal file
File diff suppressed because it is too large
Load Diff
527
src/Converters/Converter.java
Normal file
527
src/Converters/Converter.java
Normal file
@@ -0,0 +1,527 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
package Converters;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Stack;
|
||||
|
||||
import IDGenerator.IDPrefix;
|
||||
import IDGenerator.TagParser;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Converter {
|
||||
|
||||
|
||||
private static void printVariable(Variable var, String tabs) {
|
||||
|
||||
System.out.println(tabs + var.getName() );
|
||||
if (var instanceof TreeVariable) {
|
||||
TreeVariable tree = ((TreeVariable) var);
|
||||
for(int j = 0; j < tree.getBranches().size(); j++) {
|
||||
printVariable(tree.getBranches().get(j), "\t" + tabs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<Variable> parseCHeader(String file) {
|
||||
|
||||
ArrayList<Variable> parsedVariables = new ArrayList<Variable>(); //When completed parsing from the stack they go here
|
||||
|
||||
parseInputFile(file, parsedVariables);
|
||||
|
||||
// for(int i = 0; i < parsedVariables.size(); i++) {
|
||||
// printVariable(parsedVariables.get(i), "");
|
||||
// }
|
||||
|
||||
return parsedVariables;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* @return void
|
||||
*/
|
||||
// public static void main( String[] args ) {
|
||||
//
|
||||
// ArrayList<Variable> parsedVariables = new ArrayList<Variable>(); //When completed parsing from the stack they go here
|
||||
//
|
||||
//
|
||||
// /* Open the file to be parsed */
|
||||
// parseInputFile(args[0], parsedVariables);
|
||||
// /* close the parsed file */
|
||||
//
|
||||
//
|
||||
// /* open the file for HTML generation */
|
||||
// generateHTMLFile(args[1], parsedVariables);
|
||||
// /* close the HTML generated file */
|
||||
//
|
||||
//
|
||||
// /* open the file for HTML interpreted by C */
|
||||
// generateCinterpreterFile(args[2], parsedVariables);
|
||||
// /* close the file for HTML interpreted by C */
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parseStack Takes the last item in the stack and adds it to the encompassing tree
|
||||
* @param parsedVariables If the stack has no more trees to add to then the Variable is added here.
|
||||
* @return void
|
||||
*/
|
||||
private static void popTopStack(Stack<TreeVariable> parseStack, ArrayList<Variable> parsedVariables) {
|
||||
|
||||
TreeVariable value = parseStack.pop();
|
||||
|
||||
if (parseStack.isEmpty()) {
|
||||
parsedVariables.add(value);
|
||||
|
||||
} else {
|
||||
//Search for the next tree
|
||||
TreeVariable trunk = parseStack.peek();
|
||||
value.setTrunk(trunk);
|
||||
trunk.addBranch(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uses '}' and ';' to find the name between them
|
||||
* @param text
|
||||
* @return String, null if no name found
|
||||
*/
|
||||
private static String findName(String text) {
|
||||
if (text == null) { return null; }
|
||||
String name = null;
|
||||
|
||||
name = text.replaceAll(".*\\}|\\;.*", "").strip();
|
||||
|
||||
name = name.replaceAll("\\[.*?\\]", "").strip(); //Remove any array indicator like myName[12]
|
||||
|
||||
if (name.length() == 0)
|
||||
return null;
|
||||
else
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Uses '[' and ']' to find the array size between them
|
||||
* @param text
|
||||
* @return Integer, null if no array size is found
|
||||
*/
|
||||
private static Integer findArraySize(String text) {
|
||||
if (text == null) { return null; }
|
||||
Integer size = null;
|
||||
|
||||
int startIndex = text.indexOf('[');
|
||||
int endIndex = text.lastIndexOf(']');
|
||||
|
||||
if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
|
||||
size = Integer.parseInt(text.substring(startIndex + 1, endIndex));
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the first non-whitespace char in a string
|
||||
* @param text
|
||||
* @return Character
|
||||
*/
|
||||
private static Character getFirstChar(String text) {
|
||||
|
||||
Character firstChar = null;
|
||||
for(int c = 0; c < text.length(); c++) {
|
||||
if ( !Character.isWhitespace(text.charAt(c)) ) {
|
||||
firstChar = text.charAt(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return firstChar;
|
||||
}
|
||||
|
||||
private static String findVarName( String text ) {
|
||||
|
||||
text = text.replace(";", "").strip();
|
||||
|
||||
if (text.length() == 0)
|
||||
return null;
|
||||
|
||||
String[] tokens = text.split(" ");
|
||||
|
||||
if (tokens.length < 2) //Must have type and name
|
||||
return null;
|
||||
|
||||
return tokens[tokens.length - 1];
|
||||
}
|
||||
|
||||
|
||||
private static void parseInputFile(String fileName, ArrayList<Variable> parsedVariables) {
|
||||
try {
|
||||
Stack<TreeVariable> parseStack = new Stack<TreeVariable>();
|
||||
ParseMode mode = ParseMode.DefaultMode;
|
||||
//open file
|
||||
BufferedReader input = new BufferedReader( new FileReader(fileName));
|
||||
String line = input.readLine();
|
||||
|
||||
|
||||
//loop for each line
|
||||
while (line != null) { //Parsing Loop
|
||||
line = line.replaceAll("\\s+", " ").strip();
|
||||
|
||||
if (line.length() == 0) {
|
||||
line = input.readLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] data = line.replace("typedef", "").split("//");
|
||||
|
||||
if (getFirstChar(line) == '#') { //Skip lines with #... for now
|
||||
line = input.readLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (data.length == 0) {
|
||||
line = input.readLine();
|
||||
continue;
|
||||
|
||||
|
||||
} else if ( data[0].contains("}") ) {
|
||||
String name = findName(data[0]); //Check if there is a name for the struct or enum
|
||||
if ( name != null )
|
||||
parseStack.peek().setName(name); // Set the name of the top item
|
||||
|
||||
if (data.length > 1)
|
||||
TagParser.modifyVarTags(parseStack.peek(), data[1]);
|
||||
|
||||
|
||||
Integer arraySize = findArraySize(data[0]); //Check if the item is an array
|
||||
|
||||
if (arraySize != null)
|
||||
parseStack.peek().setArraySize(arraySize);
|
||||
|
||||
|
||||
popTopStack(parseStack, parsedVariables);
|
||||
line = input.readLine();
|
||||
mode = ParseMode.DefaultMode; //Set back to default mode, NOTE: enums cannot have anything defined in it
|
||||
continue; // Skip normal parsing of this line
|
||||
|
||||
|
||||
} else if (data[0].contains("struct") || data[0].contains("enum")) {
|
||||
|
||||
String name = "NotNamedYet";
|
||||
|
||||
String[] parts = data[0].split(" ");
|
||||
if (parts.length > 1 && !parts[1].contains("{") && !(parts[1].length() > 0))
|
||||
name = parts[1];
|
||||
|
||||
TreeVariable value;
|
||||
if (data[0].contains("struct")) {
|
||||
value = new TreeVariable(name, Ctype.Struct, null);
|
||||
|
||||
} else {
|
||||
value = new TreeVariable(name, Ctype.Enum, null);
|
||||
mode = ParseMode.EnumMode;
|
||||
}
|
||||
|
||||
if (data.length > 1)
|
||||
TagParser.modifyVarTags(value, data[1]); //If there is comments
|
||||
|
||||
// value.setSuperName(name);
|
||||
parseStack.push( value );
|
||||
line = input.readLine();
|
||||
continue; // Skip normal parsing of this line
|
||||
}
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case DefaultMode:
|
||||
|
||||
Ctype type = findCtype( data[0], parsedVariables );
|
||||
String name = findVarName(data[0]);
|
||||
Integer arraySize = findArraySize(data[0]);
|
||||
|
||||
|
||||
if ( type != null && name != null) {
|
||||
if (type == Ctype.Enum || type == Ctype.Struct) {
|
||||
|
||||
String[] tokens = data[0].split(" ");
|
||||
TreeVariable value = null;
|
||||
|
||||
for(int i = 0; i < parsedVariables.size(); i++) { //Find the matching struct or enum
|
||||
if (parsedVariables.get(i).getName().matches(tokens[tokens.length - 2])) { //If name of a previously defined type == type name for this one
|
||||
value = (TreeVariable) (parsedVariables.get(i).deepCopy());
|
||||
|
||||
if (value != null) {
|
||||
value.setSuperName(value.getName());
|
||||
value.setName(name);
|
||||
|
||||
if (data.length > 1) { //Make sure there are comments on this line
|
||||
TagParser.modifyVarTags(value, data[1]);
|
||||
}
|
||||
|
||||
if (arraySize != null)
|
||||
value.setArraySize(arraySize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parseStack.peek().addBranch(value);
|
||||
|
||||
} else {
|
||||
Variable newVar = new Variable(type, name);
|
||||
|
||||
if (data.length > 1) //Make sure there are comments on this line
|
||||
TagParser.modifyVarTags(newVar, data[1]);
|
||||
|
||||
if (arraySize != null)
|
||||
newVar.setArraySize(arraySize);
|
||||
|
||||
parseStack.peek().addBranch(newVar);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EnumMode:
|
||||
Long value = findEnumValue( data[0] );
|
||||
String ename = findEnumName( data[0] );
|
||||
EnumItemVariable eVar = new EnumItemVariable(ename, value);
|
||||
|
||||
if (data.length > 1) //Make sure there are comments on this line
|
||||
TagParser.modifyVarTags(eVar, data[1]);
|
||||
|
||||
if ( value != null && ename != null && !eVar.htmlIsHidden() )
|
||||
parseStack.peek().addBranch(eVar);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//In loop check for first non space char is #
|
||||
//Parse modes - Enum, Struct, primitive variables
|
||||
line = input.readLine();
|
||||
}
|
||||
|
||||
|
||||
if (!parseStack.isEmpty()) {
|
||||
System.out.println("ERROR: Parsing Stack did not get emptied.");
|
||||
}
|
||||
|
||||
|
||||
//close file
|
||||
input.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void generateHTMLFile(String fileName, ArrayList<Variable> parsedVariables) {
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter output = new PrintWriter( new FileWriter(fileName) );
|
||||
|
||||
output.println("<form name='CONFIGform' method='post' action=''>\n<ul class='tree'>");
|
||||
Variable.addIndent();
|
||||
|
||||
for(int i = 0; i < parsedVariables.size(); i++) {
|
||||
output.println(parsedVariables.get(i).generateHTML(""));
|
||||
}
|
||||
|
||||
output.println("</ul>\n<br><br><br><input type='submit' name='Set' value='Set CONFIG'>\n</form>");
|
||||
|
||||
output.close();
|
||||
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(ioe.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void generateCinterpreterFile(String fileName, ArrayList<Variable> parsedVariables) {
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter output = new PrintWriter( new FileWriter(fileName) );
|
||||
|
||||
output.println("<form name='CONFIGform' method='post' action=''>\n<ul class='tree'>");
|
||||
Variable.addIndent();
|
||||
|
||||
for(int i = 0; i < parsedVariables.size(); i++) {
|
||||
output.println(parsedVariables.get(i).generateHTML(""));
|
||||
}
|
||||
|
||||
output.println("</ul>\n<br><br><br><input type='submit' name='Set' value='Set CONFIG'>\n</form>");
|
||||
|
||||
output.close();
|
||||
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(ioe.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static Long findEnumValue(String text) {
|
||||
String[] tokens = text.replace(",", "").split(" ");
|
||||
|
||||
if (tokens.length < 3)
|
||||
return null;
|
||||
|
||||
long value = hexStringToLong(tokens[2].strip());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private static String findEnumName(String text) {
|
||||
String[] tokens = text.split(" ");
|
||||
|
||||
if (tokens.length < 3)
|
||||
return null;
|
||||
|
||||
return tokens[0].strip();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static Ctype findCtype(String text, ArrayList<Variable> parsedVariables) {
|
||||
|
||||
text = text.strip();
|
||||
|
||||
if (text.length() == 0)
|
||||
return null;
|
||||
|
||||
String[] tokens = text.split(" ");
|
||||
|
||||
if (tokens.length < 2)
|
||||
return null;
|
||||
|
||||
Ctype type = null;
|
||||
|
||||
switch (tokens[tokens.length - 2]) {
|
||||
case "uint8_t":
|
||||
type = Ctype.UInt8;
|
||||
break;
|
||||
|
||||
case "uint16_t":
|
||||
type = Ctype.UInt16;
|
||||
break;
|
||||
|
||||
case "uint32_t":
|
||||
type = Ctype.UInt32;
|
||||
break;
|
||||
|
||||
case "uint64_t":
|
||||
type = Ctype.UInt64;
|
||||
break;
|
||||
|
||||
case "int8_t":
|
||||
type = Ctype.Int8;
|
||||
break;
|
||||
|
||||
case "int16_t":
|
||||
type = Ctype.Int16;
|
||||
break;
|
||||
|
||||
case "int32_t":
|
||||
type = Ctype.Int32;
|
||||
break;
|
||||
|
||||
case "int64_t":
|
||||
type = Ctype.Int64;
|
||||
break;
|
||||
|
||||
case "float":
|
||||
type = Ctype.Float;
|
||||
break;
|
||||
|
||||
case "double":
|
||||
type = Ctype.Double;
|
||||
break;
|
||||
|
||||
case "char":
|
||||
type = Ctype.Char;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
for(int i = 0; i < parsedVariables.size(); i++) {
|
||||
if (parsedVariables.get(i).getName().matches(tokens[tokens.length - 2])) {
|
||||
type = parsedVariables.get(i).getType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
System.out.println("ERROR: Cannot find associated type for '" + text + "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return type;
|
||||
}//findCtype()
|
||||
|
||||
|
||||
public static Long hexStringToLong (String hex) {
|
||||
long value = -1;
|
||||
|
||||
try {
|
||||
value = Long.decode(hex);
|
||||
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.out.println(nfe.getMessage());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum ParseMode {
|
||||
EnumMode, DefaultMode
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Parsing modes
|
||||
*
|
||||
* # - Defines, ignore Includes others...
|
||||
* enum - Sets values for enum according to what is equals
|
||||
* variable - finds associated Type, structs get added to stack, primitives get added to top struct in stack
|
||||
* 1) Pre-defined primitives, like uint8_t, float, etc...
|
||||
* 2) User-defined variables like structures and enums
|
||||
*/
|
||||
|
||||
50
src/Converters/Ctype.java
Normal file
50
src/Converters/Ctype.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package Converters;
|
||||
|
||||
public enum Ctype {
|
||||
// Void,
|
||||
Double, Float,
|
||||
Int, Int64, Int32, Int16, Int8,
|
||||
UInt, UInt64, UInt32, UInt16, UInt8,
|
||||
Char, //CharPtr,
|
||||
Enum, EnumItem,
|
||||
Struct;
|
||||
// Union,
|
||||
// UserDefined
|
||||
|
||||
public String getCString( ) {
|
||||
switch(this) {
|
||||
case Char:
|
||||
return "char";
|
||||
|
||||
case Double:
|
||||
return "double";
|
||||
case Float:
|
||||
return "float";
|
||||
|
||||
case Int:
|
||||
return "int";
|
||||
case Int16:
|
||||
return "int16_t";
|
||||
case Int32:
|
||||
return "int32_t";
|
||||
case Int64:
|
||||
return "int64_t";
|
||||
case Int8:
|
||||
return "int8_t";
|
||||
|
||||
case UInt:
|
||||
return "unsigned int";
|
||||
case UInt16:
|
||||
return "uint16_t";
|
||||
case UInt32:
|
||||
return "uint32_t";
|
||||
case UInt64:
|
||||
return "uint64_t";
|
||||
case UInt8:
|
||||
return "uint8_t";
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/Converters/EnumItemVariable.java
Normal file
68
src/Converters/EnumItemVariable.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package Converters;
|
||||
|
||||
|
||||
public class EnumItemVariable extends Variable {
|
||||
private long enumValue;
|
||||
|
||||
/* Constructor */
|
||||
public EnumItemVariable(String name, long enumValue) {
|
||||
super(name);
|
||||
this.enumValue = enumValue;
|
||||
}
|
||||
|
||||
|
||||
/* Getters and Setters */
|
||||
public long getEnumValue() {
|
||||
return enumValue;
|
||||
}
|
||||
|
||||
public void setEnumValue(long enumValue) {
|
||||
this.enumValue = enumValue;
|
||||
}
|
||||
|
||||
|
||||
public boolean htmlIsHidden( ) {
|
||||
if (super.getHTMLType() != null)
|
||||
return super.getHTMLType().isHidden();
|
||||
else
|
||||
return false; //enum items by default are shown
|
||||
}
|
||||
|
||||
/* Class Methods */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generates the HTML code for an enum item.
|
||||
*/
|
||||
@Override
|
||||
public String generateHTML( String tabs, boolean selected ) {
|
||||
String html = "";
|
||||
html = tabs + super.getIndentation() + "<option value='%d'%s>%s</option>\n".formatted(enumValue, selected ? " selected" : "", super.getFormatedName());
|
||||
|
||||
// html = super.getIndentation() + "<input type='radio' id='%d' name='%s'><label for='%d'>%s</label>\n".formatted(enumValue, ("x" + super.getVarNum()), enumValue, super.getName());
|
||||
// html = "<input type='radio' id='" + enumValue + "' name='param6'><label for='1'>OPTA</label>";
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Variable deepCopy() {
|
||||
EnumItemVariable copy = new EnumItemVariable(super.getName(), enumValue); //Also creates a new VarNum
|
||||
copy.setArraySize(getArraySize());
|
||||
copy.setSuperName(getSuperName());
|
||||
copy.setLinkedName(getLinkedName());
|
||||
copy.setDisplayName(getDisplayName());
|
||||
copy.setHTMLType(getHTMLType());
|
||||
copy.setDecimalPlaces(getDecimalPlaces());
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "EnumItemVariable, " + getName() + ", value: " + enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
190
src/Converters/HTMLType.java
Normal file
190
src/Converters/HTMLType.java
Normal file
@@ -0,0 +1,190 @@
|
||||
package Converters;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
||||
public class HTMLType {
|
||||
|
||||
public static final String UpperBoundKey = "Upper Bound";
|
||||
public static final String LowerBoundKey = "Lower Bound";
|
||||
public static final String StepKey = "Step";
|
||||
|
||||
// public static final String variableStartString = "var";
|
||||
|
||||
private Type type = null;
|
||||
private Dictionary<String, String> arguments = null;
|
||||
|
||||
public HTMLType(Type type) {
|
||||
this.arguments = new Hashtable<>();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public HTMLType() {
|
||||
this.arguments = new Hashtable<>();
|
||||
this.type = null;
|
||||
}
|
||||
|
||||
public Dictionary<String, String> getArgs( ) {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public void addArg(String key, String value) {
|
||||
arguments.put(key, value);
|
||||
}
|
||||
|
||||
public String getArg(String key) {
|
||||
return arguments.get(key);
|
||||
}
|
||||
|
||||
public boolean isHidden( ) {
|
||||
return type == Type.Hidden;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
Checkbox, Number, Password, Radio, Range, Text, Dropdown,
|
||||
RealTime, //RealTime is only used for data exchange and NOT supported for Forms
|
||||
Hidden; //Not shown or sent to the web server
|
||||
}
|
||||
|
||||
public boolean isLiveData( ) {
|
||||
return this.type == Type.RealTime;
|
||||
}
|
||||
|
||||
|
||||
public String getVarHTML(Variable var, String tabs) {
|
||||
String html = "";
|
||||
|
||||
switch (var.getType()) {
|
||||
case Enum:
|
||||
TreeVariable treeVarE;
|
||||
if (var instanceof TreeVariable) {
|
||||
treeVarE = (TreeVariable)var;
|
||||
} else {
|
||||
System.out.println("ERROR:\t The type for '" + var.getName() + "' in getVarHTML() is not a TreeVariable as it needs to be for Enum Type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (this.type) {
|
||||
case Hidden:
|
||||
break;
|
||||
|
||||
case Radio:
|
||||
System.out.println("WARNING: Enum Radio Button class is not implemented Yet, defaulting to Dropdown...");
|
||||
|
||||
default: //Default is the same as Drop down
|
||||
System.out.println("INFO:\t HTML type not correct/specified for '" + var.getName() + "' in getVarHTML(), defaulting to dropdown.");
|
||||
case Dropdown:
|
||||
html = tabs + Variable.getIndentation( ) + "<div class=\"u-form-group u-form-select u-label-left label-alignment-vertical u-form-group-" + var.getVarNum() + "\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <label for=\"" + var.getHTMLID() + "\" class=\"u-label custom-label\">" + var.getFormatedName() + "</label>\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <div class=\"u-form-select-wrapper\" style=\"min-width: 20ch;\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <select id=\"" + var.getHTMLID() + "\" name=\"" + var.getHTMLID() + "\" class=\"u-border-1 u-border-grey-30 u-input u-input-rectangle u-white\">\n";
|
||||
// + tabs + Variable.getIndentation( ) + " <select id=\"" + var.getHTMLID() + "\" name=\"" + var.getFormatedName() + "\" class=\"u-border-1 u-border-grey-30 u-input u-input-rectangle u-white\">\n";
|
||||
|
||||
for(int i = 0; i < treeVarE.getBranches().size(); i++) {
|
||||
if (treeVarE.getBranches().get(i) instanceof EnumItemVariable) { //ONLY allow enum items in this section
|
||||
html += treeVarE.getBranches().get(i).generateHTML(tabs + Variable.getIndentation( ) + " ", i == 0); //Only select the first option
|
||||
}
|
||||
}
|
||||
|
||||
html += tabs + Variable.getIndentation( ) + " </select>\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <img class=\"custom-caret u-caret\" x=\"0px\" y=\"0px\" width=\"16px\" height=\"16px\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " </div>\n"
|
||||
+ tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case Struct:
|
||||
TreeVariable treeVarS;
|
||||
if (var instanceof TreeVariable) {
|
||||
treeVarS = (TreeVariable)var;
|
||||
} else {
|
||||
System.out.println("ERROR:\t The type for '" + var.getName() + "' in getVarHTML() is not a TreeVariable as it needs to be for Struct Type.");
|
||||
return "";
|
||||
}
|
||||
//
|
||||
for(int i = 0; i < treeVarS.getBranches().size(); i++) {
|
||||
html += treeVarS.getBranches().get(i).generateHTML(tabs + Variable.getIndentation( ) + " ");
|
||||
}
|
||||
|
||||
// html += tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
break;
|
||||
|
||||
case EnumItem:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
//NOTE: u-label-left or u-label-top for labels on top or left of the input
|
||||
switch (this.type) {
|
||||
case Checkbox:
|
||||
html = tabs + Variable.getIndentation( ) + "<div class=\"u-form-checkbox u-form-group u-label-left u-form-group-" + var.getVarNum() + "\">"
|
||||
+ tabs + Variable.getIndentation( ) + " <input type=\"checkbox\" id=\"" + var.getHTMLID() + "\" name=\"" + var.getHTMLID() + "\" value=\"On\" class=\"u-field-input\">"
|
||||
+ tabs + Variable.getIndentation( ) + " <label for=\"" + var.getHTMLID() + "\" class=\"u-field-label\">" + var.getFormatedName() + "</label>"
|
||||
+ tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
break;
|
||||
|
||||
case Number:
|
||||
html = tabs + Variable.getIndentation( ) + "<div class=\"u-form-group u-form-number u-label-left u-form-number-layout-number label-alignment-vertical u-form-group-" + var.getVarNum() + "\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <label for=\"" + var.getHTMLID() + "\" class=\"u-label\">" + var.getFormatedName() + "</label>\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <div class=\"u-input-row\" data-value=\"0\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <input value=\"" + var.getLowerBound() + "\" min=\"" + var.getLowerBound() + "\" max=\"" + var.getUpperBound() + "\" step=\"" + var.getStep() + "\" type=\"number\" placeholder=\"\" id=\"" + var.getHTMLID() + "\" name=\"" + var.getHTMLID() + "\" class=\"u-input u-number\" style=\"width: 16ch;\">\n"
|
||||
// + tabs + Variable.getIndentation( ) + " <input value=\"" + var.getLowerBound() + "\" min=\"" + var.getLowerBound() + "\" max=\"" + var.getUpperBound() + "\" step=\"" + var.getStep() + "\" type=\"number\" placeholder=\"\" id=\"" + var.getHTMLID() + "\" name=\"number-" + var.getVarNum() + "\" class=\"u-input u-number\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " </div>\n"
|
||||
+ tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
break;
|
||||
|
||||
case Password:
|
||||
System.out.println("WARNING: generateHTML(), 'password' not implemented");
|
||||
// html = tabs + getIndentation( ) +
|
||||
break;
|
||||
|
||||
|
||||
case Range:
|
||||
html = tabs + Variable.getIndentation( ) + "<div class=\"u-form-group u-form-number u-label-left u-form-number-layout-number label-alignment-vertical u-form-group-" + var.getVarNum() + "\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <label for=\"" + var.getHTMLID() + "\" class=\"u-label\">" + var.getFormatedName() + "</label>\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <div class=\"u-input-row\" data-value=\"0\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <input value=\"" + var.getLowerBound() + "\" min=\"" + var.getLowerBound() + "\" max=\"" + var.getUpperBound() + "\" step=\"" + var.getStep() + "\" type=\"range\" placeholder=\"\" id=\"" + var.getHTMLID() + "\" name=\"" + var.getHTMLID() + "\" class=\"u-input u-number\">\n"
|
||||
// + tabs + Variable.getIndentation( ) + " <input value=\"" + var.getLowerBound() + "\" min=\"" + var.getLowerBound() + "\" max=\"" + var.getUpperBound() + "\" step=\"" + var.getStep() + "\" type=\"range\" placeholder=\"\" id=\"" + var.getHTMLID() + "\" name=\"number-" + var.getVarNum() + "\" class=\"u-input u-number\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " </div>\n"
|
||||
+ tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
break;
|
||||
|
||||
case Text:
|
||||
html = tabs + Variable.getIndentation( ) + "<div class=\"u-form-group u-form-textarea u-label-left u-form-group-" + var.getVarNum() + "\">\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <label for=\"" + var.getHTMLID() + "\" class=\"u-label\">" + var.getFormatedName() + "</label>\n"
|
||||
+ tabs + Variable.getIndentation( ) + " <input rows=\"1\" cols=\"35\" maxlength=\"35\" id=\"" + var.getHTMLID() + "\" name=\"" + var.getHTMLID() + "\" class=\"u-border-1 u-border-grey-30 u-input u-input-rectangle u-white\" type=\"text\" disabled>\n" //NOTE this disables user from modifying this
|
||||
// + tabs + Variable.getIndentation( ) + " <input rows=\"1\" cols=\"35\" maxlength=\"35\" id=\"" + var.getHTMLID() + "\" name=\"textarea-" + var.getVarNum() + "\" class=\"u-border-1 u-border-grey-30 u-input u-input-rectangle u-white\" type=\"text\" disabled>\n" //NOTE this disables user from modifying this
|
||||
+ tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
break;
|
||||
|
||||
|
||||
case Radio:
|
||||
System.out.println("WARNING: generateHTML(), 'radio' not implemented for " + var.getName());
|
||||
break;
|
||||
|
||||
case Dropdown:
|
||||
System.out.println("WARNING: generateHTML(), 'dropdown' not implemented for " + var.getName());
|
||||
break;
|
||||
|
||||
case RealTime:
|
||||
System.out.println("ERROR:\t generateHTML(), 'realTime' NOT ALLOWED for " + var.getName());
|
||||
break;
|
||||
|
||||
case Hidden:
|
||||
//Does not generate HTML code
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
47
src/Converters/Testing.java
Normal file
47
src/Converters/Testing.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package Converters;
|
||||
|
||||
public class Testing {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// String[] input = {"TestIn.txt", "TestOut.swift"}; //older version
|
||||
// String[] input = {"TestIn.txt", ""};
|
||||
// String[] input = {"Test2.txt", ""};
|
||||
String[] input = {"config.h", ""};
|
||||
|
||||
// C_Swift_Converter.main(input);
|
||||
|
||||
// Converter.main(input);
|
||||
Converter.parseCHeader("config.h");
|
||||
|
||||
// String code = "Hello 0x0001 next 0x1234";
|
||||
|
||||
// while(code.contains("0x")) {
|
||||
// int inx = code.indexOf("0x");
|
||||
// int end = code.indexOf("\\s+", inx);
|
||||
//
|
||||
// Pattern p = Pattern.compile("\\s+"); // insert your pattern here
|
||||
// Matcher m = p.matcher(code.substring(inx));
|
||||
// if (m.find()) {
|
||||
// end = m.start();
|
||||
// } else {
|
||||
// end = -1;
|
||||
// }
|
||||
//
|
||||
// int value = 0;
|
||||
//
|
||||
// if (end > 0) {
|
||||
// value = Integer.parseInt(code.substring(inx+2, inx+end), 16); //Convert from hex
|
||||
// code = code.substring(0, inx) + value + code.substring(inx+end);
|
||||
// } else {
|
||||
// value = Integer.parseInt(code.substring(inx+2), 16); //Convert from hex
|
||||
// code = code.substring(0, inx) + value;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// System.out.println(code);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
484
src/Converters/TreeVariable.java
Normal file
484
src/Converters/TreeVariable.java
Normal file
@@ -0,0 +1,484 @@
|
||||
package Converters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TreeVariable extends Variable { //Used for Enumerations and Structures
|
||||
private TreeVariable trunk;
|
||||
private ArrayList<Variable> branches;
|
||||
|
||||
private UUID uuid = UUID.randomUUID(); //Used for Linking
|
||||
|
||||
/* Constructor */
|
||||
public TreeVariable(String name, Ctype type, TreeVariable trunk) {
|
||||
super(type, name);
|
||||
this.branches = new ArrayList<Variable>();
|
||||
this.trunk = trunk;
|
||||
}
|
||||
|
||||
|
||||
/* Getters and Setters */
|
||||
public String getUUIDString( ) {
|
||||
return uuid.toString();
|
||||
}
|
||||
|
||||
public String getHTMLID( ) {
|
||||
if (getType() != Ctype.Struct) {
|
||||
return super.getHTMLID();
|
||||
} else {
|
||||
return uuid.toString(); //Not used by the ESP32 getter and setter
|
||||
}
|
||||
}
|
||||
|
||||
public TreeVariable getTrunk() {
|
||||
return this.trunk;
|
||||
}
|
||||
|
||||
public void setTrunk(TreeVariable trunk) {
|
||||
this.trunk = trunk;
|
||||
}
|
||||
|
||||
public ArrayList<Variable> getBranches( ) {
|
||||
return this.branches;
|
||||
}
|
||||
|
||||
//Overrides the Variable.setArraySize()
|
||||
public void setArraySize( int arraySize ) {
|
||||
|
||||
ArrayList<Variable> array = new ArrayList<Variable>();
|
||||
setVarNum(); //Change the location of the variable number
|
||||
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
array.add(this.deepCopy());
|
||||
}
|
||||
|
||||
super.setArray(array);
|
||||
super.setPlainArraySize(arraySize); //ONLY sets the arraySize, NOTHING with varNums or spans
|
||||
|
||||
// if (arraySize > 0) {
|
||||
// IDPrefix.removeAllScatch(this);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/* Class Methods */
|
||||
|
||||
public void addBranch(Variable branch) {
|
||||
this.branches.add(branch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String generateJSEnumHelper(String prefix) {
|
||||
return generateJSEnumHelper( null, prefix );
|
||||
}
|
||||
|
||||
public String generateJSEnumHelper( String functionName, String prefix ) {
|
||||
if (super.getType() != Ctype.Enum) { return ""; } //make sure its an enum
|
||||
|
||||
String enumDef = prefix + "const " + this.getDisplayName() + " = Object.freeze({\n";
|
||||
|
||||
String funcDef = prefix + "//returns a string\n";
|
||||
if (functionName == null) {
|
||||
funcDef = prefix + "function parse_" + this.getName() + "(value, id) {\n";
|
||||
} else {
|
||||
funcDef = prefix + "function " + functionName + "(value, id) {\n";
|
||||
}
|
||||
|
||||
// String funcDef = "//returns a string\n"
|
||||
// + "function parseStatus(statusValue) {\n";
|
||||
|
||||
funcDef += prefix + " switch (value) {\n";
|
||||
|
||||
for(int i = 0; i < this.branches.size(); i++) { //Iterate over the branches
|
||||
if (branches.get(i) instanceof EnumItemVariable) {
|
||||
EnumItemVariable enumItem = (EnumItemVariable) branches.get(i);
|
||||
|
||||
enumDef += prefix + "\t\"%s\": %d,\n".formatted(enumItem.getDisplayName(), enumItem.getEnumValue());
|
||||
|
||||
funcDef += prefix + "\tcase %s[\"%s\"]:\n".formatted(this.getDisplayName(), enumItem.getDisplayName())
|
||||
+ prefix + "\t\treturn \"%s\";\n".formatted(enumItem.getDisplayName());
|
||||
}
|
||||
}//for
|
||||
|
||||
enumDef += prefix + "});\n\n";
|
||||
|
||||
funcDef += prefix + "\tdefault:\n"
|
||||
+ prefix + "\t\treturn \"\";\n"
|
||||
+ prefix + "\t}\n"
|
||||
+ prefix + "}\n";
|
||||
|
||||
|
||||
return enumDef + funcDef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generates the HTML code that displays the value and each branch as drop down lists.
|
||||
* @param selected: true if the title should be hidden, or indented again
|
||||
*/
|
||||
public String generateHTML( String tabs, boolean selected ) {
|
||||
if (this.getHTMLType() == null) {
|
||||
System.out.println("WARNING: generateHTML() for '" + super.getName() + "' Has no set HTML type.");
|
||||
return "";
|
||||
} else if (htmlIsHidden()) {
|
||||
return "";
|
||||
} else {
|
||||
String htmlString = "";
|
||||
|
||||
if (super.getArraySize() > 0) {
|
||||
htmlString += tabs + Variable.getIndentation( ) + "<details id=\"" + getUUIDString() + "\"class=\"array-details\">\n"; //Creates details view with a css class
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <summary class=\"array-summary indented-section\">" + this.getFormatedName() + " (" + this.getArraySize() + ")" + "</summary>\n";
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <ol>\n"; //Crate Ordered list for each item in the array
|
||||
|
||||
ArrayList<Variable> array = getArray();
|
||||
for(int i = 0; i < array.size(); i++) { //Add in special list open and close ability
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <div id=\"" + ((TreeVariable)array.get(i)).getUUIDString() + "\" class=\"indented-section\">\n"; //before the list item so the ordered list number is closer to the html code
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <li>\n"; //Start of the list Item
|
||||
htmlString += array.get(i).generateHTML(tabs + " ", true);
|
||||
htmlString += tabs + Variable.getIndentation( ) + " </li>\n"; //End of the list Item
|
||||
htmlString += tabs + Variable.getIndentation( ) + " </div>\n";
|
||||
}//for
|
||||
htmlString += tabs + Variable.getIndentation( ) + " </ol>\n"; //end of ordered list
|
||||
htmlString += tabs + Variable.getIndentation( ) + "</details>\n";
|
||||
|
||||
} else {
|
||||
if (!selected && super.getType() != Ctype.Enum) {
|
||||
htmlString = tabs + Variable.getIndentation( ) + "<p class=\"u-form-group u-form-text u-label-left u-text structure-title\">" + this.getFormatedName() + "</p>\n";
|
||||
}
|
||||
if (super.getType() != Ctype.Enum && !selected)
|
||||
htmlString += tabs + Variable.getIndentation( ) + "<div class=\"indented-section\">\n";
|
||||
|
||||
htmlString += this.getHTMLType().getVarHTML(this, tabs + ""); //This does not have an array and is plainly displayed
|
||||
|
||||
if (super.getType() != Ctype.Enum && !selected)
|
||||
htmlString += tabs + Variable.getIndentation( ) + "</div>\n";
|
||||
}
|
||||
|
||||
return htmlString;
|
||||
}
|
||||
} //generateHTML
|
||||
|
||||
|
||||
|
||||
public String generateCGetCase( String tabs, VariableDirectoryPath path ) {
|
||||
return generateCGetCase(tabs, path, -1);
|
||||
}
|
||||
|
||||
|
||||
public String generateCGetCase( String tabs, VariableDirectoryPath path, int arrayIndex ) {
|
||||
if (super.getHTMLType() == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null HTML type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (super.getType() == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null CType type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
String caseString = "";
|
||||
|
||||
switch(super.getType()) {
|
||||
|
||||
case Struct: //NOTE: This does not actually allow the struct to be copied but the components inside of it
|
||||
|
||||
if (this.getArraySize() > 0) {
|
||||
for(int i = 0; i < this.getArraySize(); i++) {
|
||||
for(int j = 0; j < branches.size(); j++) {
|
||||
caseString += ((TreeVariable) this.getArray().get(i)).branches.get(j).generateCGetCase(tabs, path.add(this, arrayIndex), i);
|
||||
}
|
||||
}//for
|
||||
} else {
|
||||
for(int i = 0; i < branches.size(); i++) {
|
||||
caseString += branches.get(i).generateCGetCase(tabs, path.add(this, arrayIndex));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
caseString += super.generateCGetCase(tabs, path, arrayIndex); //The super class handles enums
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return caseString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void resetVarNum() {
|
||||
switch (super.getType()) {
|
||||
case Struct:
|
||||
if (this.getArraySize() > 0) {
|
||||
for(int i = 0; i < this.getArraySize(); i++) {
|
||||
for(int j = 0; j < branches.size(); j++) {
|
||||
((TreeVariable) this.getArray().get(i)).branches.get(j).resetVarNum();
|
||||
}
|
||||
}//for
|
||||
} else {
|
||||
for(int i = 0; i < branches.size(); i++) {
|
||||
branches.get(i).resetVarNum();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
if (this.getArraySize() > 0) {
|
||||
for(int i = 0; i < this.getArraySize(); i++) {
|
||||
this.getArray().get(i).setVarNum();
|
||||
}//for
|
||||
} else {
|
||||
super.setVarNum();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path ) {
|
||||
// return this.generateArduinoJSONSet(tabs, path, -1);
|
||||
// }
|
||||
|
||||
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path, int arrayIndex, boolean forLiveData ) {
|
||||
if (super.getHTMLType() == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null HTML type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (super.getType() == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null CType type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
String caseString = "";
|
||||
|
||||
switch(super.getType()) {
|
||||
|
||||
case Struct: //NOTE: This does not actually allow the struct to be copied but the components inside of it
|
||||
|
||||
if (this.getArraySize() > 0) {
|
||||
for(int i = 0; i < this.getArraySize(); i++) {
|
||||
for(int j = 0; j < branches.size(); j++) {
|
||||
caseString += ((TreeVariable) this.getArray().get(i)).branches.get(j).generateArduinoJSONSet(tabs, path.add(this, arrayIndex), i, forLiveData);
|
||||
}
|
||||
}//for
|
||||
} else {
|
||||
for(int i = 0; i < branches.size(); i++) {
|
||||
caseString += branches.get(i).generateArduinoJSONSet(tabs, path.add(this, arrayIndex), forLiveData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
caseString += super.generateArduinoJSONSet(tabs, path, arrayIndex, forLiveData); //The super class handles enums
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return caseString;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class NumberLink {
|
||||
Variable controller = null;
|
||||
Variable slave = null;
|
||||
|
||||
private String pendingName = null;
|
||||
private boolean pendingIsSlave = true;
|
||||
|
||||
public NumberLink(Variable var, String pendingName, boolean pendingIsSlave) {
|
||||
this.pendingIsSlave = pendingIsSlave;
|
||||
this.pendingName = pendingName;
|
||||
if (pendingIsSlave) {
|
||||
this.controller = var;
|
||||
} else {
|
||||
this.slave = var;
|
||||
}
|
||||
}
|
||||
|
||||
public NumberLink(Variable controller, Variable slave) {
|
||||
this.controller = controller;
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Variable getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
public Variable getSlave() {
|
||||
return slave;
|
||||
}
|
||||
|
||||
|
||||
public String getControllerName() {
|
||||
if (controller != null)
|
||||
return controller.getName();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getSlaveName() {
|
||||
if (controller != null)
|
||||
return controller.getName();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSlave(Variable slave) {
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
public String getPendingName() {
|
||||
return pendingName;
|
||||
}
|
||||
|
||||
public boolean isPendingSlave() {
|
||||
return this.pendingIsSlave;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is only for Structures
|
||||
*/
|
||||
public String generateLinkJavaScript(String spacer) {
|
||||
if (getType() != Ctype.Struct) { return ""; }
|
||||
|
||||
String js = "";
|
||||
|
||||
if (getArraySize() > 0) {
|
||||
ArrayList<Variable> array = getArray();
|
||||
for(int i = 0; i < array.size(); i++) {
|
||||
js += ((TreeVariable) array.get(i)).generateLinkJavaScript(spacer);
|
||||
}
|
||||
|
||||
} else {
|
||||
//This is not an Array
|
||||
|
||||
Queue<Variable> queue = new LinkedList<>();
|
||||
queue.addAll(branches);
|
||||
|
||||
Variable next = null;
|
||||
|
||||
ArrayList<NumberLink> pendingLinks = new ArrayList<>();
|
||||
ArrayList<NumberLink> confirmedLinks = new ArrayList<>();
|
||||
|
||||
|
||||
while ((next = queue.poll()) != null) {
|
||||
|
||||
if (next.getArraySize() > 0) {
|
||||
for(int i = 0; i < pendingLinks.size(); i++) {
|
||||
NumberLink link = pendingLinks.get(i);
|
||||
if (link.isPendingSlave() && link.getPendingName().equals(next.getName())) {
|
||||
link.setSlave(next);
|
||||
confirmedLinks.add(link);
|
||||
pendingLinks.remove(i);
|
||||
break; //exit for loop
|
||||
}
|
||||
}//for loop
|
||||
|
||||
} else {
|
||||
String linkName = next.getLinkedName();
|
||||
|
||||
if (linkName != null) {
|
||||
pendingLinks.add(new NumberLink(next, linkName, true));
|
||||
}
|
||||
}
|
||||
|
||||
//check if the next is a Structure, then check its children
|
||||
if (next.getType() == Ctype.Struct) {
|
||||
js += ((TreeVariable) next).generateLinkJavaScript(spacer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(int i = 0; i < confirmedLinks.size(); i++) {
|
||||
Variable controller = confirmedLinks.get(i).getController();
|
||||
Variable slave = confirmedLinks.get(i).getSlave();
|
||||
|
||||
String uuidName = "item" + controller.getHTMLID().replace("-", "");
|
||||
|
||||
js += spacer + "const " + uuidName + " = document.getElementById(\"" + controller.getHTMLID() + "\");\n"
|
||||
+ spacer + uuidName + ".addEventListener(\"change\", (event) => {\n"
|
||||
+ spacer + "\tconst newValue = Number(event.target.value);\n";
|
||||
|
||||
ArrayList<Variable> array = slave.getArray();
|
||||
|
||||
for(int j = 0; j < array.size(); j++) {
|
||||
// js += spacer + "\tdocument.getElementById(\"" + array.get(j).getHTMLID() + "\").style.visibility = newValue > " + j + " ? 'visible' : 'hidden';\n";
|
||||
js += spacer + "\tdocument.getElementById(\"" + array.get(j).getHTMLID() + "\").hidden = !(newValue > " + j + ");\n";
|
||||
}
|
||||
|
||||
js += spacer + "});\n"
|
||||
+ spacer + uuidName + ".dispatchEvent(new Event('change', { bubbles: true }));\n\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return js;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// public TreeVariable makeCopy( ) {
|
||||
// TreeVariable newTree = new TreeVariable(super.getName(), super.getType(), this.getTrunk());
|
||||
// newTree.setArraySize(getArraySize());
|
||||
// newTree.setSuperName(getSuperName());
|
||||
// newTree.setLinkedName(getLinkedName());
|
||||
// newTree.setDisplayName(getDisplayName());
|
||||
// newTree.setHTMLType(getHTMLType());
|
||||
// newTree.setDecimalPlaces(getDecimalPlaces());
|
||||
// newTree.branches = this.branches;
|
||||
//
|
||||
// return newTree;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
public Variable deepCopy() {
|
||||
|
||||
TreeVariable copy = new TreeVariable(getName(), getType(), trunk);
|
||||
copy.setSuperName(getSuperName());
|
||||
copy.setLinkedName(getLinkedName());
|
||||
copy.setDisplayName(getDisplayName());
|
||||
copy.setHTMLType(getHTMLType());
|
||||
copy.setDecimalPlaces(getDecimalPlaces());
|
||||
|
||||
// if (getArraySize() > 0) {
|
||||
//// getPrefixID().resetCounter();
|
||||
// CPath.resetSubPrefixes(this);
|
||||
// }
|
||||
|
||||
copy.setPrefixID(getPrefixID());
|
||||
|
||||
for(int i = 0; i < this.branches.size(); i++) {
|
||||
copy.branches.add(branches.get(i).deepCopy());
|
||||
}
|
||||
|
||||
copy.setArraySize(super.getArraySize());
|
||||
return copy;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "TreeVariable: " + getName() + "";
|
||||
}
|
||||
|
||||
}
|
||||
660
src/Converters/Variable.java
Normal file
660
src/Converters/Variable.java
Normal file
@@ -0,0 +1,660 @@
|
||||
package Converters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import IDGenerator.IDPrefix;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class Variable {
|
||||
|
||||
public static long varCounter; //Counts the number of inputs into a form, to prevent IDs from overlapping
|
||||
|
||||
private static final String defaultStep = "1"; //Used for range, number etc.. HTML code
|
||||
private static final String defaultUpperBound = "100"; //Used for range, number etc.. HTML code
|
||||
private static final String defaultLowerBound = "0"; //Used for range, number etc.. HTML code
|
||||
private static final int numVariablesDefault = 1; //Must art at 1
|
||||
|
||||
private static long numVariables = numVariablesDefault;
|
||||
private static int indentCounter = 0; //Indentation counter
|
||||
private static String indents = ""; //Actual indentation String
|
||||
|
||||
|
||||
private IDPrefix prefixID = null;
|
||||
private String htmlID = null;
|
||||
private VariableDirectoryPath cPath = null;
|
||||
|
||||
private HTMLType htmlType;
|
||||
private Ctype type;
|
||||
private int numberDecimals = -1; //Only used for display only and Floats/Doubles
|
||||
private String linkedName = null;
|
||||
|
||||
private String name;
|
||||
private String displayName = null; //If null name is used
|
||||
private String superName = ""; //Only used for enums, Structs where this is the actual name of the type
|
||||
|
||||
private long varNum = 0L; //The number of this variable (used for HTML and C exchange)
|
||||
private int arraySize = 0; // <= 0 means not an array and standard logic applies, > 0 means you must apply array logics
|
||||
private ArrayList<Variable> array = new ArrayList<Variable>();
|
||||
|
||||
/* Constructor */
|
||||
public Variable(Ctype type, String name) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
||||
this.htmlType = new HTMLType(HTMLType.Type.Text); //default to text
|
||||
setVarNum();
|
||||
}
|
||||
|
||||
public Variable(Ctype type, String name, int arraySize) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.htmlType = new HTMLType(HTMLType.Type.Text); //default to text
|
||||
|
||||
if (arraySize > 0) { //Create copies of this type for the arraySize
|
||||
this.setArraySize(arraySize);
|
||||
} else {
|
||||
this.arraySize = 0;
|
||||
setVarNum();
|
||||
}
|
||||
}
|
||||
|
||||
//For EnumItem ONLY
|
||||
public Variable(String name) {
|
||||
this.name = name;
|
||||
this.type = Ctype.EnumItem;
|
||||
this.htmlType = null;
|
||||
}
|
||||
|
||||
public void setVarNum( ) {
|
||||
if (array.size() > 0) {
|
||||
for(int i = 0; i < array.size(); i++) {
|
||||
array.get(i).setVarNum();
|
||||
}
|
||||
} else {
|
||||
this.varNum = numVariables;
|
||||
numVariables++;
|
||||
}
|
||||
}
|
||||
|
||||
public static String removeSuffix(String str, String suffix) {
|
||||
if (str != null && suffix != null && str.endsWith(suffix)) {
|
||||
return str.substring(0, str.length() - suffix.length());
|
||||
}
|
||||
return str; // Return original string if suffix is not found or inputs are null
|
||||
}
|
||||
|
||||
static String toTitleCase(String input) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Arrays.stream(input.split("\\s+"))
|
||||
.map(word -> Character.toUpperCase(word.charAt(0)) + word.substring(1))
|
||||
.collect(Collectors.joining(" "));
|
||||
}
|
||||
|
||||
/* Getters and Setters */
|
||||
public String getHTMLID( ) {
|
||||
if (htmlID != null) {
|
||||
return htmlID;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IDPrefix getPrefixID() {
|
||||
return prefixID;
|
||||
}
|
||||
|
||||
public void setPrefixID(IDPrefix prefixID) {
|
||||
this.prefixID = prefixID;
|
||||
if (prefixID != null) {
|
||||
this.htmlID = prefixID.getNextID(this);
|
||||
} else {
|
||||
this.htmlID = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setHTMLID(String newID) {
|
||||
this.htmlID = newID;
|
||||
}
|
||||
|
||||
public String getLinkedName( ) {
|
||||
return this.linkedName;
|
||||
}
|
||||
|
||||
public void setLinkedName( String name ) {
|
||||
this.linkedName = name;
|
||||
}
|
||||
|
||||
public ArrayList<Variable> getArray( ) {
|
||||
return this.array;
|
||||
}
|
||||
|
||||
public void setArray( ArrayList<Variable> array ) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public int getDecimalPlaces( ) {
|
||||
return numberDecimals;
|
||||
}
|
||||
|
||||
public void setDecimalPlaces(int decimalPlaces) {
|
||||
this.numberDecimals = decimalPlaces;
|
||||
}
|
||||
|
||||
public boolean htmlIsHidden( ) {
|
||||
if (htmlType != null)
|
||||
return htmlType.isHidden();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public Ctype getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Ctype type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setSuperName(String superName) {
|
||||
this.superName = superName;
|
||||
}
|
||||
|
||||
public String getSuperName( ) {
|
||||
return superName;
|
||||
}
|
||||
|
||||
public HTMLType getHTMLType() {
|
||||
return htmlType;
|
||||
}
|
||||
|
||||
public void setHTMLType(HTMLType htmlType) {
|
||||
this.htmlType = htmlType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
if (displayName != null)
|
||||
return displayName;
|
||||
else
|
||||
return getFormatedName();
|
||||
}
|
||||
|
||||
public int getArraySize( ) {
|
||||
return arraySize;
|
||||
}
|
||||
|
||||
public void setPlainArraySize( int arraySize ) {
|
||||
this.arraySize = arraySize;
|
||||
}
|
||||
|
||||
public void setArraySize( int arraySize ) {
|
||||
|
||||
this.array = new ArrayList<Variable>();
|
||||
setVarNum(); //Change the location of the variable number
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
array.add(this.deepCopy());
|
||||
}
|
||||
this.arraySize = arraySize;
|
||||
|
||||
// if (arraySize > 0) {
|
||||
// IDPrefix.removeAllScatch(this);
|
||||
// }
|
||||
}
|
||||
|
||||
public String getFormatedName() {
|
||||
if (displayName == null) {
|
||||
String newName = removeSuffix(removeSuffix(name, "_t"), "_s").replace("_", " ").toLowerCase(); //remove _s OR _t from the name
|
||||
return toTitleCase(newName);
|
||||
} else {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//Ignores null values
|
||||
public void setDisplayName(String displayName) {
|
||||
if (displayName != null) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
|
||||
public String getStep() {
|
||||
String step = htmlType.getArg(HTMLType.StepKey);
|
||||
return step != null ? step : defaultStep;
|
||||
}
|
||||
|
||||
public String getUpperBound() {
|
||||
String bound = htmlType.getArg(HTMLType.UpperBoundKey);
|
||||
return bound != null ? bound : defaultUpperBound;
|
||||
}
|
||||
|
||||
public String getLowerBound() {
|
||||
String bound = htmlType.getArg(HTMLType.LowerBoundKey);
|
||||
return bound != null ? bound : defaultLowerBound;
|
||||
}
|
||||
|
||||
|
||||
public long getVarNum() {
|
||||
return this.varNum;
|
||||
}
|
||||
|
||||
public static String getIndentation( ) {
|
||||
return indents;
|
||||
}
|
||||
|
||||
public static void addIndent() {
|
||||
indentCounter++;
|
||||
indents += "\t";
|
||||
}
|
||||
|
||||
public static void removeIndent() {
|
||||
if (indentCounter > 0) {
|
||||
indentCounter--;
|
||||
indents = "\t".repeat(indentCounter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Class Methods */
|
||||
|
||||
private String getMin( ) {
|
||||
String value = null;
|
||||
|
||||
switch (this.type) {
|
||||
case Double:
|
||||
value = "-1.7976931348623157e308";
|
||||
break;
|
||||
|
||||
case Float:
|
||||
value = "-3.4028235E38";
|
||||
break;
|
||||
|
||||
case Int8:
|
||||
value = "-128";
|
||||
break;
|
||||
|
||||
case Int16:
|
||||
value = "-32,768";
|
||||
break;
|
||||
|
||||
case Int:
|
||||
case Int32:
|
||||
value = "-2147483648";
|
||||
break;
|
||||
|
||||
case Int64:
|
||||
value = "-9223372036854775808";
|
||||
break;
|
||||
|
||||
default:
|
||||
value = "0";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private String getMax( ) {
|
||||
String value = null;
|
||||
|
||||
switch (this.type) {
|
||||
case Double:
|
||||
value = "1.7976931348623157e308";
|
||||
break;
|
||||
|
||||
case Float:
|
||||
value = "3.4028235E38";
|
||||
break;
|
||||
|
||||
case Int8:
|
||||
value = "127";
|
||||
break;
|
||||
|
||||
case Int16:
|
||||
value = "32,767";
|
||||
break;
|
||||
|
||||
case Int:
|
||||
case Int32:
|
||||
value = "2147483647";
|
||||
break;
|
||||
|
||||
case Int64:
|
||||
value = "9223372036854775807";
|
||||
break;
|
||||
|
||||
case Char:
|
||||
case UInt8:
|
||||
value = "255";
|
||||
break;
|
||||
|
||||
case UInt16:
|
||||
value = "65535";
|
||||
break;
|
||||
|
||||
case UInt:
|
||||
case UInt32:
|
||||
value = "4294967295";
|
||||
break;
|
||||
|
||||
case UInt64:
|
||||
value = "18446744073709551615";
|
||||
break;
|
||||
|
||||
default:
|
||||
value = "0";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public String generateHTML( String tabs ) {
|
||||
return generateHTML(tabs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the HTML code that displays the value.
|
||||
* @param selected: Used only for enums where one item must be selected first OR used to display struct titles
|
||||
*/
|
||||
public String generateHTML( String tabs, boolean selected ) {
|
||||
if (htmlType == null) {
|
||||
System.out.println("'generateHTML' for " + getName() + " has null HTML type.");
|
||||
return "";
|
||||
} else if (htmlIsHidden()) {
|
||||
return "";
|
||||
} else {
|
||||
String htmlString = "";
|
||||
|
||||
if (this.arraySize > 0) {
|
||||
System.out.println("WARNING: generateHTML() for arrays is not yet tested or complete (Dont forget to create custom CSS)");
|
||||
htmlString += tabs + Variable.getIndentation( ) + "<details>\n";
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <summary>" + this.getFormatedName() + "</summary>\n";
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <ul>\n";
|
||||
for(int i = 0; i < arraySize; i++) { //Add in special list open and close ability
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <li>\n";
|
||||
htmlString += array.get(i).generateHTML(tabs + " ");
|
||||
htmlString += tabs + Variable.getIndentation( ) + " <li>\n";
|
||||
}//for
|
||||
htmlString += tabs + Variable.getIndentation( ) + " </ul>\n";
|
||||
htmlString += tabs + Variable.getIndentation( ) + "</details>\n";
|
||||
|
||||
} else {
|
||||
htmlString = htmlType.getVarHTML(this, tabs); //This does not have an array and is plainly displayed
|
||||
}
|
||||
return htmlString;
|
||||
}
|
||||
} //generateHTML
|
||||
|
||||
|
||||
|
||||
|
||||
public String generateCGetCase( String tabs, VariableDirectoryPath path ) {
|
||||
return this.generateCGetCase(tabs, path, -1);
|
||||
}
|
||||
|
||||
public String generateCGetCase( String tabs, VariableDirectoryPath path, int arrayIndex ) {
|
||||
if (htmlType == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null HTML type.");
|
||||
return "";
|
||||
} else if (htmlType.isHidden()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (this.type == null) {
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has null CType type.");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
String caseString = "";
|
||||
|
||||
|
||||
switch(this.type) {
|
||||
case Char:
|
||||
System.out.println("WARN: 'generateCGetCase()' not tested Char yet.");
|
||||
break;
|
||||
|
||||
case Double:
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateCGetCase(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "case " + varNum + ":\n"
|
||||
+ tabs + "\t" + path.add(this, arrayIndex) + " = arg.toDouble();\n"
|
||||
+ tabs + "\tbreak;\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case Float:
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateCGetCase(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "case " + varNum + ":\n"
|
||||
+ tabs + "\t" + path.add(this, arrayIndex) + " = arg.toFloat();\n"
|
||||
+ tabs + "\tbreak;\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case Int:
|
||||
case Int64:
|
||||
case Int32:
|
||||
case Int16:
|
||||
case Int8:
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateCGetCase(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "case " + varNum + ":\n"
|
||||
+ tabs + "\t" + path.add(this, arrayIndex) + " = (" + this.type.getCString() + ") arg.toInt();\n"
|
||||
+ tabs + "\tbreak;\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case UInt:
|
||||
case UInt64:
|
||||
case UInt32:
|
||||
case UInt16:
|
||||
case UInt8:
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateCGetCase(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "case " + varNum + ":\n"
|
||||
+ tabs + "\t" + path.add(this, arrayIndex) + " = (" + this.type.getCString() + ") arg.toInt(); //Should I add in something to prevent negative numbers (for uintxx_t)?\n"
|
||||
+ tabs + "\tbreak;\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateCGetCase(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "case " + varNum + ":\n"
|
||||
+ tabs + "\t" + path.add(this, arrayIndex) + " = (" + this.getSuperName() + ") arg.toInt(); //Should I add in something to prevent negative numbers (for uintxx_t)?\n"
|
||||
+ tabs + "\tbreak;\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case Struct:
|
||||
case EnumItem:
|
||||
default:
|
||||
System.out.println("WARN: 'generateCGetCase()' for " + getName() + " has a CType that is not supported in this format.");
|
||||
break;
|
||||
}
|
||||
|
||||
return caseString;
|
||||
}
|
||||
|
||||
|
||||
public String getVariableTransofrmer_C(String variableName ) {
|
||||
if (this.arraySize > 0) {
|
||||
System.out.println("WARNING: Cannot get transformer for array");
|
||||
return "'Cannot get transformer for array.'";
|
||||
}
|
||||
|
||||
String transform = "";
|
||||
|
||||
switch (this.type) {
|
||||
case UInt:
|
||||
case UInt64:
|
||||
case UInt32:
|
||||
case UInt16:
|
||||
case UInt8:
|
||||
transform = "(%s) %s.toInt(); //Add in something to prevent negative numbers (for uintxx_t)? AND Also prevent overflows".formatted(type.getCString(), variableName);
|
||||
break;
|
||||
|
||||
case Int:
|
||||
case Int64:
|
||||
case Int32:
|
||||
case Int16:
|
||||
case Int8:
|
||||
transform = "(%s) %s.toInt(); // need to prevent overflows".formatted(type.getCString(), variableName);
|
||||
break;
|
||||
|
||||
case Enum:
|
||||
transform = "(%s) %s.toInt(); // need to prevent overflows".formatted(this.getSuperName(), variableName);
|
||||
break;
|
||||
|
||||
case Double:
|
||||
transform = "(%s) %s.toDouble(); // need to prevent overflows".formatted(type.getCString(), variableName);
|
||||
break;
|
||||
|
||||
case Float:
|
||||
transform = "(%s) %s.toFloat(); // need to prevent overflows".formatted(type.getCString(), variableName);
|
||||
break;
|
||||
|
||||
case Char:
|
||||
System.out.println("WARN: 'getVariableTransofrmer_C()' not tested Char yet.");
|
||||
break;
|
||||
|
||||
case Struct:
|
||||
case EnumItem:
|
||||
default:
|
||||
System.out.println("WARN: 'getVariableTransofrmer_C()' for " + getName() + " has a CType that is not supported in this format.");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path ) {
|
||||
return this.generateArduinoJSONSet(tabs, path, -1);
|
||||
}
|
||||
|
||||
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path, int arrayIndex ) {
|
||||
return this.generateArduinoJSONSet(tabs, path, arrayIndex, false);
|
||||
}
|
||||
|
||||
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path, boolean forLiveData ) {
|
||||
return this.generateArduinoJSONSet(tabs, path, -1, forLiveData);
|
||||
}
|
||||
|
||||
public String generateArduinoJSONSet( String tabs, VariableDirectoryPath path, int arrayIndex, boolean forLiveData ) {
|
||||
if (this.getType() == null) {
|
||||
System.out.println("WARN: 'generateArduinoJSONSet()' for " + getName() + " has null CType type.");
|
||||
return "";
|
||||
} else if (htmlType.isHidden()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String caseString = "";
|
||||
if (!forLiveData || (forLiveData && this.getHTMLType().isLiveData()) ) { //Only get the case if it is not live data, or its live data with a valid HTMLType (RealTime)
|
||||
if (this.arraySize > 0) {
|
||||
for(int i = 0; i < arraySize; i++) {
|
||||
caseString += array.get(i).generateArduinoJSONSet(tabs, path, i);
|
||||
}//for
|
||||
} else {
|
||||
caseString = tabs + "doc[\"" + getHTMLID() + "\"] = " + path.add(this, arrayIndex) + ";\n";
|
||||
}
|
||||
|
||||
}
|
||||
return caseString;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String getLinkShowHideJS(String prefix, int index) {
|
||||
return prefix + "document.getElementById(\"" + getHTMLID() + "\").style.visibility = newValue > " + index + " ? 'visible' : 'hidden';\n";
|
||||
}
|
||||
|
||||
|
||||
public void setCPath(VariableDirectoryPath path) {
|
||||
this.cPath = path;
|
||||
}
|
||||
|
||||
public String getCPathString( ) {
|
||||
if (cPath == null) {
|
||||
return "";
|
||||
} else {
|
||||
return cPath.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setDefaultVarNum() {
|
||||
Variable.numVariables = numVariablesDefault;
|
||||
}
|
||||
|
||||
public void resetVarNum() {
|
||||
// Variable.numVariables = numVariablesDefault;
|
||||
// Variable.numVariables
|
||||
this.setVarNum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not copy the cPath, because creating a copy can change location it was found in
|
||||
* @return
|
||||
*/
|
||||
public Variable deepCopy() {
|
||||
Variable copy = new Variable(type, name); //Also creates a new VarNum
|
||||
copy.setArraySize(arraySize);
|
||||
copy.setSuperName(superName);
|
||||
copy.setLinkedName(linkedName);
|
||||
copy.setDisplayName(displayName);
|
||||
copy.setHTMLType(htmlType);
|
||||
copy.setDecimalPlaces(numberDecimals);
|
||||
copy.setPrefixID(getPrefixID());
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Variable: " + getName() + "";
|
||||
}
|
||||
|
||||
}
|
||||
85
src/Converters/VariableDirectoryPath.java
Normal file
85
src/Converters/VariableDirectoryPath.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package Converters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
class VariableAndIndex {
|
||||
public Variable variable;
|
||||
public int index;
|
||||
|
||||
public VariableAndIndex(Variable variable, int index) {
|
||||
this.variable = variable;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getName( ) {
|
||||
return variable.getName();
|
||||
}
|
||||
|
||||
public String getIndexString() {
|
||||
return (index >= 0 ? "[" + index + "]" : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class VariableDirectoryPath {
|
||||
private String start = null;
|
||||
private ArrayList<VariableAndIndex> path = new ArrayList<VariableAndIndex>();
|
||||
|
||||
public VariableDirectoryPath(String start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public void addVariable(Variable var) {
|
||||
addVariable(var, -1);
|
||||
}
|
||||
|
||||
public void addVariable(Variable var, int arrayIndex) {
|
||||
path.add(new VariableAndIndex(var, arrayIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a variable to the tree, arrayIndex of -1 indicates it is not in an array
|
||||
* @param var
|
||||
* @param arrayIndex
|
||||
* @return
|
||||
*/
|
||||
public VariableDirectoryPath add(Variable var, int arrayIndex) {
|
||||
VariableDirectoryPath vdp = new VariableDirectoryPath(start);
|
||||
for(int i = 0; i < path.size(); i++) {
|
||||
vdp.path.add(this.path.get(i));
|
||||
}
|
||||
vdp.addVariable(var, arrayIndex);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String toString() {
|
||||
String pathString = "";
|
||||
|
||||
if (start != null) {
|
||||
pathString = start;
|
||||
}
|
||||
|
||||
for(int i = 0; i < path.size(); i++) {
|
||||
if (i <= path.size() - 2) {
|
||||
String arrayIndex = path.get(i + 1) != null ? path.get(i + 1).getIndexString() : "";
|
||||
pathString += path.get(i).getName() + arrayIndex + ".";
|
||||
} else {
|
||||
pathString += path.get(i).getName(); //Last item
|
||||
}
|
||||
}
|
||||
|
||||
return pathString;
|
||||
}
|
||||
|
||||
|
||||
// public VariableDirectoryPath copy() {
|
||||
// VariableDirectoryPath vdp = new VariableDirectoryPath();
|
||||
//
|
||||
// vdp.add();
|
||||
// return vdp;
|
||||
// }
|
||||
}
|
||||
22
src/Converters/javaTesting.java
Normal file
22
src/Converters/javaTesting.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package Converters;
|
||||
|
||||
public class javaTesting {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
Integer myInt = 0;
|
||||
|
||||
System.out.println(myInt);
|
||||
changer(myInt);
|
||||
System.out.println(myInt);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void changer(Integer value) {
|
||||
value = value + 3;
|
||||
}
|
||||
}
|
||||
120
src/GZIP_Compressor.java
Normal file
120
src/GZIP_Compressor.java
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
|
||||
public class GZIP_Compressor {
|
||||
|
||||
|
||||
// public static byte[] compressGzipFile(File file) {
|
||||
//
|
||||
//
|
||||
// try {
|
||||
// FileInputStream fis = new FileInputStream(file);
|
||||
//// FileOutputStream fos = new FileOutputStream(gzipFile);
|
||||
// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
// GZIPOutputStream gzipOS = new GZIPOutputStream(byteArrayOutputStream);
|
||||
//
|
||||
// byte[] buffer = new byte[1024];
|
||||
// int len;
|
||||
//
|
||||
// while((len = fis.read(buffer)) != -1){
|
||||
//// gzipOS.write(buffer, 0, len);
|
||||
// gzipOS.write(buffer);
|
||||
// }
|
||||
// //close resources
|
||||
// gzipOS.close();
|
||||
// fis.close();
|
||||
//
|
||||
// return byteArrayOutputStream.toByteArray();
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public static byte[] compress(File file) throws IOException {
|
||||
if (file == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
|
||||
DataInputStream reader = new DataInputStream(new FileInputStream(file));
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
|
||||
// gzipOutputStream.write(text.getBytes(StandardCharsets.UTF_8));
|
||||
gzipOutputStream.write(reader.readAllBytes());
|
||||
}
|
||||
reader.close();
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte[] compress(String text) throws IOException {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
|
||||
gzipOutputStream.write(text.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String originalText = "This is a sample text to be compressed.";
|
||||
// try {
|
||||
// byte[] compressedData = compress(originalText);
|
||||
// System.out.println("Original text: " + originalText);
|
||||
// System.out.println("Compressed data size: " + compressedData.length + " bytes");
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
class GzipCompression {
|
||||
|
||||
public static byte[] compress(String text) throws IOException {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
|
||||
gzipOutputStream.write(text.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String originalText = "This is a sample text to be compressed.";
|
||||
try {
|
||||
byte[] compressedData = compress(originalText);
|
||||
System.out.println("Original text: " + originalText);
|
||||
System.out.println("Compressed data size: " + compressedData.length + " bytes");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
43
src/HTML_Form_Generator/HTMLFormGenerator.java
Normal file
43
src/HTML_Form_Generator/HTMLFormGenerator.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package HTML_Form_Generator;
|
||||
|
||||
import Converters.TreeVariable;
|
||||
import Converters.Variable;
|
||||
|
||||
|
||||
public class HTMLFormGenerator {
|
||||
|
||||
|
||||
/**
|
||||
* This function is designed specifically for nicepage forms
|
||||
* @param var
|
||||
* @return
|
||||
*/
|
||||
public static String makeFormBody( Variable var ) {
|
||||
|
||||
// String submitLabel = "Submit";
|
||||
String spacer = "\t\t\t\t";
|
||||
|
||||
String body = var.generateHTML(spacer) + "\n";
|
||||
|
||||
// body += spacer + "<div class=\"u-align-left u-form-group u-form-submit\">\n"
|
||||
// + spacer + " <a href=\"#\" class=\"u-btn u-btn-submit u-button-style u-btn-1\">" + submitLabel + "</a>\n"
|
||||
// + spacer + " <input type=\"submit\" value=\"submit\" class=\"u-form-control-hidden\">\n"
|
||||
// + spacer + "</div>";
|
||||
if (var instanceof TreeVariable) {
|
||||
body += spacer + "<script>\n"
|
||||
+ ((TreeVariable) var).generateLinkJavaScript(spacer + "\t")
|
||||
+ spacer + "</script>\n";
|
||||
// System.out.println(((TreeVariable) var).generateLinkJavaScript(spacer + "\t"));
|
||||
}
|
||||
|
||||
// Optional Message to display after the form was submitted.
|
||||
// body += " <div class=\"u-form-send-message u-form-send-success\">Settings have been updated!</div>\n"
|
||||
// + " <div class=\"u-form-send-error u-form-send-message\">Unable to send the Message??</div>\n"
|
||||
// + " <input type=\"hidden\" value=\"\" name=\"recaptchaResponse\">";
|
||||
|
||||
System.out.println("'makeFormBody()' Not sure what will happen if you have multiple forms on the same page... in regaurds to HTML ids");
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
236
src/IDGenerator/CHTMLExchange.java
Normal file
236
src/IDGenerator/CHTMLExchange.java
Normal file
@@ -0,0 +1,236 @@
|
||||
package IDGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
|
||||
public class CHTMLExchange {
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// ArrayList<IDPrefix> prefixes = new ArrayList<IDPrefix>();
|
||||
// try {
|
||||
// prefixes.add(new IDPrefix("bb"));
|
||||
// prefixes.add(new IDPrefix("aa"));
|
||||
// prefixes.add(new IDPrefix("bac"));
|
||||
// prefixes.add(new IDPrefix("baa"));
|
||||
// prefixes.add(new IDPrefix("aaaa"));
|
||||
//
|
||||
// prefixes.add(new IDPrefix("a"));
|
||||
//// prefixes.add(new IDPrefix("aa"));
|
||||
// prefixes.add(new IDPrefix("aaa"));
|
||||
//// prefixes.add(new IDPrefix("aaaa"));
|
||||
// prefixes.add(new IDPrefix("aaa1"));
|
||||
//
|
||||
//
|
||||
// IDPrefix pre = new IDPrefix("12b");
|
||||
// pre.getNextID(new Variable(Ctype.Double, "myVar1"));
|
||||
// pre.getNextID(new Variable(Ctype.Float, "myVar2"));
|
||||
// pre.getNextID(new Variable(Ctype.UInt16, "myVar3"));
|
||||
// prefixes.add(pre);
|
||||
// } catch (PrefixException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// parseVariables_C(prefixes);
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
private static enum ParseVariablesState {
|
||||
Initial, CheckNext, CreateSwitch, CreateCase, CreateUnderscore, CloseCase, CloseSwitch, Final, Exit
|
||||
}
|
||||
|
||||
|
||||
private static String AddIndent(String indent) {
|
||||
return indent + "\t";
|
||||
}
|
||||
|
||||
private static String RemoveIndent(String indent) {
|
||||
return indent.substring(0, indent.length() - 1);
|
||||
}
|
||||
|
||||
private static String removeLast(String str) {
|
||||
return str.substring(0, str.length() - 1);
|
||||
}
|
||||
|
||||
|
||||
public static String parseVariables_C(ArrayList<IDPrefix> prefixes, String functionName, String structureName) {
|
||||
/*
|
||||
* const String arg: the value that will be setting to the variable
|
||||
* uint32_t value: for absd_12 is 12, a1_3 is 3, etc..
|
||||
* const char *key
|
||||
*/
|
||||
// make nested switch statments for all values sharing same first letters, then second, etc... until the underscore
|
||||
|
||||
prefixes.sort(null); //use compareTo method defined for the IDPrefix
|
||||
|
||||
String cCode = "";
|
||||
|
||||
Queue<IDPrefix> queue = new LinkedList<IDPrefix>();
|
||||
queue.addAll(prefixes);
|
||||
ParseVariablesState state = ParseVariablesState.Initial;
|
||||
|
||||
String indent = "";
|
||||
String currentCase = "";
|
||||
|
||||
IDPrefix current = null;
|
||||
|
||||
int i = 0; //nested switch counter
|
||||
boolean getNext = false;
|
||||
|
||||
if (queue.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
while(state != ParseVariablesState.Exit) {
|
||||
|
||||
switch (state) {
|
||||
case Initial:
|
||||
current = queue.poll(); //get next item
|
||||
if (currentCase.isEmpty()) {
|
||||
currentCase = current.getPrefix();
|
||||
} else {
|
||||
System.out.println("ERROR: In parseVariables switch(state). (state = Fresh)");
|
||||
}
|
||||
|
||||
cCode += indent + "void %s( const String argName, const String arg, %s* structure ) {\n\n".formatted(functionName, structureName);
|
||||
indent = AddIndent(indent);
|
||||
|
||||
cCode += indent + "Serial.printf(\"'%s' with associated value '%s'\\n\", argName, arg);\n"
|
||||
+ indent + "char key[sizeof(argName)];\n"
|
||||
+ indent + "argName.toCharArray(key, sizeof(key));\n"
|
||||
+ indent + "int32_t tempVar = -1;\n"
|
||||
+ indent + "uint32_t value = 0;\n\n"
|
||||
+ indent + "if (sscanf(key, \"%*[^_]_%d\", &tempVar) <= 0) {\n" //This line tells it to read until an underscore see help: https://stackoverflow.com/questions/7969201/sscanf-format-c
|
||||
+ indent + " return;\n"
|
||||
+ indent + "} else {\n"
|
||||
+ indent + " value = tempVar;\n"
|
||||
+ indent + "}\n\n";
|
||||
|
||||
i = 0;
|
||||
state = ParseVariablesState.CreateSwitch;
|
||||
break;
|
||||
|
||||
|
||||
case CreateSwitch:
|
||||
cCode += indent + "switch (key[%d]) {\n".formatted(i);
|
||||
indent = AddIndent(indent);
|
||||
i++;
|
||||
if (i <= currentCase.length()) {
|
||||
state = ParseVariablesState.CreateCase;
|
||||
} else {
|
||||
state = ParseVariablesState.CreateUnderscore;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CreateCase:
|
||||
cCode += RemoveIndent(indent) + "case '%c':\n".formatted(currentCase.charAt(i-1));
|
||||
state = ParseVariablesState.CheckNext;
|
||||
break;
|
||||
|
||||
|
||||
case CreateUnderscore:
|
||||
cCode += RemoveIndent(indent) + "case '_':\n"
|
||||
+ indent + "switch (value) {\n";
|
||||
|
||||
ArrayList<IDPrefix.VariablePair> pairs = current.getVariablePairs();
|
||||
for(int j = 0; j < pairs.size(); j++) {
|
||||
cCode += indent + "case %d:\n".formatted(pairs.get(j).value)
|
||||
+ indent + "\t%s = %s\n".formatted(pairs.get(j).var.getCPathString(), pairs.get(j).var.getVariableTransofrmer_C("arg"))
|
||||
// + indent + "\t%s = %s;\n".formatted(pairs.get(j).var.getCPathString(), "some value")
|
||||
+ indent + "\tbreak;\n";
|
||||
}
|
||||
|
||||
cCode += indent + "}\n";
|
||||
getNext = true;
|
||||
state = ParseVariablesState.CloseCase;
|
||||
break;
|
||||
|
||||
|
||||
case CheckNext:
|
||||
if (getNext) {
|
||||
if (queue.isEmpty()) {
|
||||
current = null;
|
||||
state = ParseVariablesState.CloseCase;
|
||||
state = ParseVariablesState.CloseSwitch;
|
||||
} else {
|
||||
current = queue.poll();
|
||||
}
|
||||
getNext = false;
|
||||
|
||||
} else if (current == null) {
|
||||
if (i == 0) {
|
||||
state = ParseVariablesState.Final;
|
||||
} else {
|
||||
state = ParseVariablesState.CloseCase;
|
||||
}
|
||||
|
||||
} else if (i <= currentCase.length()) {
|
||||
state = ParseVariablesState.CreateSwitch;
|
||||
|
||||
} else if (!current.getPrefix().startsWith(currentCase)) {
|
||||
state = ParseVariablesState.CloseCase;
|
||||
|
||||
} else if (current.getPrefix().equals(currentCase)) {
|
||||
state = ParseVariablesState.CreateUnderscore;
|
||||
|
||||
} else if (current.getPrefix().startsWith(currentCase)) {
|
||||
currentCase = current.getPrefix();
|
||||
state = ParseVariablesState.CreateCase;
|
||||
|
||||
} else {
|
||||
// System.out.println(cCode);
|
||||
state = ParseVariablesState.Final;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CloseCase:
|
||||
cCode += indent + "break;\n";
|
||||
state = ParseVariablesState.CloseSwitch;
|
||||
break;
|
||||
|
||||
|
||||
case CloseSwitch:
|
||||
indent = RemoveIndent(indent);
|
||||
cCode += indent + "}\n";
|
||||
i--;
|
||||
if (current == null) {
|
||||
state = ParseVariablesState.CheckNext;
|
||||
} else {
|
||||
cCode += indent + "break;\n";
|
||||
currentCase = removeLast(currentCase);
|
||||
state = ParseVariablesState.CheckNext;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case Final:
|
||||
indent = RemoveIndent(indent);
|
||||
// cCode += indent + "} //End of switch(key[0])\n";
|
||||
cCode += indent + "} //%s\n".formatted(functionName);
|
||||
state = ParseVariablesState.Exit;
|
||||
break;
|
||||
|
||||
|
||||
case Exit: //DO nothing here
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
System.out.println("\n You idiot forgot to add the case for: ParseVariablesState state = " + state + "\n");
|
||||
break;
|
||||
}//switch (state)
|
||||
|
||||
}//while
|
||||
|
||||
return cCode;
|
||||
}
|
||||
|
||||
}
|
||||
178
src/IDGenerator/CPath.java
Normal file
178
src/IDGenerator/CPath.java
Normal file
@@ -0,0 +1,178 @@
|
||||
package IDGenerator;
|
||||
|
||||
import Converters.Ctype;
|
||||
import Converters.EnumItemVariable;
|
||||
import Converters.TreeVariable;
|
||||
import Converters.Variable;
|
||||
import Converters.VariableDirectoryPath;
|
||||
|
||||
public class CPath {
|
||||
|
||||
/**
|
||||
* Call IDPrefix.resetAll() before this function for proper prefix setting
|
||||
* @param var
|
||||
*/
|
||||
public static void setCPaths(Variable var) {
|
||||
if (var instanceof TreeVariable) {
|
||||
TreeVariable treeVar = (TreeVariable) var;
|
||||
for(int i = 0; i < treeVar.getBranches().size(); i++) {
|
||||
setCPaths(treeVar.getBranches().get(i), new VariableDirectoryPath("structure->"), -1);
|
||||
}
|
||||
} else {
|
||||
System.out.println("WARNING: CPath.setCPaths() Variable `" + var.getName() + "` is not a TreeVariable. Thus it will not set the paths.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Also sets the IDPrefix for all of the ones it encounters
|
||||
* @param var
|
||||
* @param path
|
||||
* @param arrayIndex
|
||||
*/
|
||||
private static void setCPaths(Variable var, VariableDirectoryPath path, int arrayIndex) {
|
||||
|
||||
if (var instanceof EnumItemVariable) {
|
||||
System.out.println("CPath.setCPaths Variable var is not allowed to be an EnumItemVariable.");
|
||||
|
||||
} else if (var instanceof TreeVariable) {
|
||||
TreeVariable treeVar = (TreeVariable) var;
|
||||
|
||||
if (treeVar.getArraySize() > 0) {
|
||||
for(int i = 0; i < treeVar.getArraySize(); i++) {
|
||||
TreeVariable arrayVar = (TreeVariable) treeVar.getArray().get(i);
|
||||
for(int j = 0; j < arrayVar.getBranches().size(); j++) {
|
||||
setCPaths(arrayVar.getBranches().get(j), path.add(arrayVar, arrayIndex), i);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (treeVar.getType() == Ctype.Enum) {
|
||||
//Return like a normal variable
|
||||
var.setPrefixID(var.getPrefixID());
|
||||
var.setCPath(path.add(var, arrayIndex));
|
||||
|
||||
} else {//Not an array
|
||||
for(int i = 0; i < treeVar.getBranches().size(); i++) {
|
||||
setCPaths(treeVar.getBranches().get(i), path.add(var, arrayIndex), -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
if (var.getArraySize() > 0) {
|
||||
for(int i = 0; i < var.getArraySize(); i++) {
|
||||
setCPaths(var.getArray().get(i), path, i);
|
||||
}
|
||||
|
||||
} else { //Not an array
|
||||
var.setCPath(path.add(var, arrayIndex));
|
||||
var.setPrefixID(var.getPrefixID());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void resetPrefix(Variable var) {
|
||||
if (var.getPrefixID() != null) {
|
||||
var.getPrefixID().resetCounter();
|
||||
var.setHTMLID(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetSubPrefixes( Variable var ) {
|
||||
resetPrefix(var);
|
||||
|
||||
if (var instanceof TreeVariable) {
|
||||
TreeVariable treeVar = (TreeVariable) var;
|
||||
if (treeVar.getArraySize() > 0) {
|
||||
for(int i = 0; i < treeVar.getArraySize(); i++) {
|
||||
resetSubPrefixes(treeVar.getArray().get(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(int i = 0; i < treeVar.getBranches().size(); i++) {
|
||||
resetSubPrefixes(treeVar.getBranches().get(i));
|
||||
}
|
||||
} else {
|
||||
if (var.getArraySize() > 0) {
|
||||
for(int i = 0; i < var.getArraySize(); i++) {
|
||||
resetSubPrefixes(var.getArray().get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//// private static void setCPaths(Variable var, VariableDirectoryPath path) {
|
||||
//// setCPaths(var, path, -1);
|
||||
////}
|
||||
//
|
||||
//private static void resetPrefix(Variable var) {
|
||||
// if (var.getPrefixID() != null) {
|
||||
//// if (var.getPrefixID().getVariablePairs().size() > 0) {
|
||||
//// var.getPrefixID().resetCounter();
|
||||
//// }
|
||||
// var.getPrefixID().resetCounter();
|
||||
// }
|
||||
//}
|
||||
//
|
||||
////private static void removePrefix(Variable var) {
|
||||
//// if (var.getPrefixID() != null) {
|
||||
//// var.getPrefixID().remove(var);
|
||||
//// }
|
||||
////}
|
||||
//
|
||||
//
|
||||
// public static void setPrefixes( Variable var ) {
|
||||
// if (var instanceof TreeVariable) { setPrefixes((TreeVariable)var); return; }
|
||||
// else if (var instanceof EnumItemVariable) { setPrefixes((EnumItemVariable)var); return; }
|
||||
//
|
||||
// if (var.getArraySize() > 0) {
|
||||
// resetPrefix(var);
|
||||
//
|
||||
// for(int i = 0; i < var.getArray().size(); i++) {
|
||||
// TreeVariable avar = (TreeVariable) var.getArray().get(i);
|
||||
// setPrefixes(avar);
|
||||
// }
|
||||
// } else {
|
||||
// var.setPrefixID(var.getPrefixID());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static void setPrefixes( TreeVariable treeVar ) {
|
||||
// if (treeVar.getArraySize() > 0) {
|
||||
// resetPrefix(treeVar);
|
||||
// for(int i = 0; i < treeVar.getArray().size(); i++) {
|
||||
// TreeVariable var = (TreeVariable) treeVar.getArray().get(i);
|
||||
// setPrefixes(var);
|
||||
//
|
||||
//// for(int j = 0; j < var.getBranches().size(); j++) {
|
||||
//// setPrefixes(var.getBranches().get(j));
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// } else if (treeVar.getType() == Ctype.Enum) {
|
||||
// treeVar.setPrefixID(treeVar.getPrefixID());
|
||||
//
|
||||
// } else {
|
||||
// resetPrefix(treeVar);
|
||||
// for(int i = 0; i < treeVar.getBranches().size(); i++) {
|
||||
// setPrefixes(treeVar.getBranches().get(i));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static void setPrefixes( EnumItemVariable eVar ) {
|
||||
// System.out.println("ERROR: setPrefixes(EnumItemVariable eVar ) should not get here");
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
200
src/IDGenerator/IDPrefix.java
Normal file
200
src/IDGenerator/IDPrefix.java
Normal file
@@ -0,0 +1,200 @@
|
||||
package IDGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import Converters.TreeVariable;
|
||||
import Converters.Variable;
|
||||
|
||||
|
||||
|
||||
|
||||
public class IDPrefix implements Comparable<IDPrefix> {
|
||||
private static final String gapString = "_"; //Do not change, it is in other locations
|
||||
private static final ArrayList<ArrayList<IDPrefix>> existing = new ArrayList<>();
|
||||
|
||||
private ArrayList<VariablePair> variablePairs = new ArrayList<>();
|
||||
private String prefix = null;
|
||||
private int internalCount = 0;
|
||||
|
||||
|
||||
public IDPrefix( String prefix ) throws PrefixException {
|
||||
if (existingContainsPrefix(prefix)) {
|
||||
throw new PrefixException("PrefixException: Prefix '" + prefix + "'was previously created.");
|
||||
} else {
|
||||
this.prefix = prefix;
|
||||
getExisting().add(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static ArrayList<IDPrefix> getExisting( ) {
|
||||
if (existing.size() <= 0) {
|
||||
existing.add(new ArrayList<IDPrefix>());
|
||||
}
|
||||
return existing.getLast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array for the prefixes to be created under, saves the old one
|
||||
*/
|
||||
public static void startNewSection() {
|
||||
existing.add(new ArrayList<IDPrefix>());
|
||||
}
|
||||
|
||||
// public void remove(Variable var) {
|
||||
// boolean found = false;
|
||||
// for(int i = 0; i < variablePairs.size(); i++) {
|
||||
// if (found) {
|
||||
// variablePairs.get(i).value--;
|
||||
// variablePairs.get(i).var.setHTMLID( getIDString(variablePairs.get(i).value) );
|
||||
//
|
||||
// } else if (variablePairs.get(i).var == var) {
|
||||
// variablePairs.remove(i);
|
||||
// internalCount--;
|
||||
// i--;
|
||||
// var.setHTMLID(null);
|
||||
// found = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }//remove()
|
||||
|
||||
|
||||
// public static void removeAllScatch( Variable var ) {
|
||||
//
|
||||
// if (var.getPrefixID() != null) {
|
||||
// var.getPrefixID().remove(var);
|
||||
// }
|
||||
//
|
||||
// if (var instanceof TreeVariable) {
|
||||
// TreeVariable treeVar = (TreeVariable) var;
|
||||
//
|
||||
// if (treeVar.getArraySize() > 0) {
|
||||
// for(int i = 0; i < treeVar.getBranches().size(); i++) {
|
||||
// removeAllScatch(treeVar.getBranches().get(i));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// if (var.getArraySize() > 0) {
|
||||
//// for(int i = 0; i < var.getArraySize(); i++) {
|
||||
//// removeAllScatch(var.getArray().get(i));
|
||||
//// }
|
||||
// //Should just erase this prefix if it exits
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public static void resetAll( ) {
|
||||
for(int i = 0; i < getExisting().size(); i++) {
|
||||
resetAll(getExisting().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private static void resetAll(IDPrefix prefix) {
|
||||
prefix.internalCount = 0;
|
||||
prefix.variablePairs.forEach((pair) -> {
|
||||
pair.var.setHTMLID(null);
|
||||
});
|
||||
prefix.variablePairs.removeAll(prefix.variablePairs);
|
||||
}
|
||||
|
||||
|
||||
private String getIDString( int count ) {
|
||||
return prefix + gapString + (count);
|
||||
}
|
||||
|
||||
public String getNextID(Variable var) {
|
||||
variablePairs.add(new VariablePair(var, ++internalCount)); //Increment count before saving
|
||||
return getIDString(internalCount);
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void resetCounter() {
|
||||
this.internalCount = 0;
|
||||
this.variablePairs.removeAll(variablePairs); //remove all pairs
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayList<VariablePair> getVariablePairs() {
|
||||
return (ArrayList<VariablePair>) variablePairs.clone();
|
||||
}
|
||||
|
||||
|
||||
private boolean existingContainsPrefix(String prefix) {
|
||||
int i = -1;
|
||||
while ((++i) < getExisting().size()) { //Start with index 0 to last index
|
||||
if (getExisting().get(i).prefix.equals(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//existingContainsPrefix
|
||||
|
||||
|
||||
public class PrefixException extends Exception {
|
||||
private static final long serialVersionUID = 1974522L;
|
||||
public PrefixException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
public PrefixException(String errorMessage, Throwable err) {
|
||||
super(errorMessage, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class VariablePair {
|
||||
Variable var = null;
|
||||
int value = 0;
|
||||
|
||||
public VariablePair(Variable var, int value) {
|
||||
this.var = var;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}//class VariablePair
|
||||
|
||||
|
||||
/**
|
||||
* Compares two IDPrefix `prefix` variables lexicographically. Uses String.compareTo() method but also aaaa goes before aaa
|
||||
*/
|
||||
public int compareTo(IDPrefix other) {
|
||||
int retVal = 0;
|
||||
int maxSize = Math.min(this.prefix.length(), other.prefix.length());
|
||||
int i = -1;
|
||||
|
||||
while(retVal == 0 && (++i) < maxSize) {
|
||||
retVal = this.prefix.charAt(i) - other.prefix.charAt(i);
|
||||
}
|
||||
|
||||
if (retVal == 0) {
|
||||
return other.prefix.length() - this.prefix.length();
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public String toString( ) {
|
||||
return "IDPrefix: `" + prefix + "`";// "` with " + internalCount + " Items";
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArrayList<IDPrefix> getAllPrefixes() {
|
||||
return (ArrayList<IDPrefix>) getExisting().clone();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
392
src/IDGenerator/TagParser.java
Normal file
392
src/IDGenerator/TagParser.java
Normal file
@@ -0,0 +1,392 @@
|
||||
package IDGenerator;
|
||||
|
||||
import Converters.Ctype;
|
||||
import Converters.HTMLType;
|
||||
import Converters.Variable;
|
||||
import IDGenerator.IDPrefix.PrefixException;
|
||||
|
||||
public class TagParser {
|
||||
|
||||
|
||||
public static final String tagPrefixID = "prefixID"; //Every variable that will in HTML MUST HAVE IT
|
||||
|
||||
//NOTE all these tags will have $$_tag_$$, two '$' before and after
|
||||
public static final String tagHidden = "hidden"; //Not shown or sent to the web server
|
||||
//For the following a Variable can have any combination of these
|
||||
public static final String tagDisplayName = "name";
|
||||
public static final String tagShownDecimals = "decimalPlaces"; //This is only used for display ONLY, not for get/set
|
||||
public static final String tagNumberLink = "numberLink"; //Used to link a number input to an array to show and hide elements
|
||||
|
||||
//For the following a variable can only be one of these
|
||||
public static final String tagCheckbox = "checkbox";
|
||||
public static final String tagNumber = "number";
|
||||
public static final String tagPassword = "password";
|
||||
public static final String tagRadio = "radio";
|
||||
public static final String tagRange = "range";
|
||||
public static final String tagText = "text"; //Change this so that modifying it does not change the
|
||||
public static final String tagDropdown = "dropdown";
|
||||
public static final String tagRealTime = "realTimeVar"; //ONLY used for specific function and is not valid for the forms
|
||||
// public static final String tagColor = ""; //Only if need to set colors??
|
||||
// public static final String tagButton = ""; //Not sure what to use for
|
||||
// public static final String tagDate = "";
|
||||
// public static final String tagEmail = "";
|
||||
// public static final String tagFile = "";
|
||||
// public static final String tagHidden = ""; //NOT secure, can be visible in source editors
|
||||
// public static final String tagImage = "";
|
||||
// public static final String tagMonth = "";
|
||||
// public static final String tagReset = ""; //NOT sure about this one
|
||||
// public static final String tagSearch = "";
|
||||
// public static final String tagSubmit = "";
|
||||
// public static final String tagTel = "";
|
||||
// public static final String tagTime = "";
|
||||
// public static final String tagURL = "";
|
||||
// public static final String tagWeek = "";
|
||||
|
||||
private static final String markerTag = "$$"; //Must be before and after the tag and its arguments
|
||||
|
||||
private static class IntegerHolder {
|
||||
public int value;
|
||||
public IntegerHolder(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/* Getters and Setters */
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "IntegerHolder: " + value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param text
|
||||
* @param endIndex changes to the index after the last `markerTag`
|
||||
* @return null if no tag string found
|
||||
*/
|
||||
private static String getNextTag(String text, IntegerHolder endIndex) {
|
||||
int firstIndex = text.indexOf(markerTag, endIndex.getValue());
|
||||
|
||||
if (firstIndex != -1) {
|
||||
int secondIndex = text.indexOf(markerTag, firstIndex + markerTag.length());
|
||||
|
||||
if (secondIndex != -1) {
|
||||
endIndex.setValue(secondIndex + markerTag.length());
|
||||
return text.substring(firstIndex + markerTag.length(), secondIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Tag is defined as a string between two $, i.e. hello blah blah $$theTag,arg1,arg2$$
|
||||
* @param text
|
||||
* @return null if no tag found, otherwise the tag and other arguments separated by a comma
|
||||
*/
|
||||
private static String[] findTagItems(String text) {
|
||||
if (text == null) { return null; }
|
||||
|
||||
int firstTrigger = -1;
|
||||
int lastTrigger = -1;
|
||||
|
||||
for(int i = 0; i < text.length() - 1; i++) {
|
||||
if (firstTrigger < 0) {
|
||||
if ((text.charAt(i) == '$') && (text.charAt(i+1) == '$')) {
|
||||
firstTrigger = i;
|
||||
}
|
||||
|
||||
} else if (lastTrigger < 0) {
|
||||
if ((text.charAt(i) == '$') && (text.charAt(i+1) == '$')) {
|
||||
lastTrigger = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastTrigger < 0 || firstTrigger < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] arguments = text.substring(firstTrigger, lastTrigger+2).replace("$", "").split(",");
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// private static HTMLType findHTMLTag(String text) {
|
||||
//
|
||||
// HTMLType type = null;
|
||||
// String[] arguments = findTagItems(text);
|
||||
//
|
||||
// if (arguments == null) {
|
||||
// //There are no tags in 'text'
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// //Check for other arguments
|
||||
// String tag = "";
|
||||
//
|
||||
// if (arguments.length > 0) {
|
||||
// tag = arguments[0]; //The first argument is always the tag
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// switch (tag) {
|
||||
// case tagCheckbox:
|
||||
// type = new HTMLType(HTMLType.Type.Checkbox);
|
||||
// break;
|
||||
//
|
||||
// case tagNumber:
|
||||
// type = new HTMLType(HTMLType.Type.Number);
|
||||
// //Check for other items
|
||||
//
|
||||
// switch (arguments.length) {
|
||||
// default:
|
||||
// case 4:
|
||||
// type.addArg(HTMLType.StepKey, arguments[3]);
|
||||
// case 3:
|
||||
// type.addArg(HTMLType.UpperBoundKey, arguments[2]);
|
||||
// case 2:
|
||||
// type.addArg(HTMLType.LowerBoundKey, arguments[1]);
|
||||
// break;
|
||||
//
|
||||
// //Do not support 1 or 0 arguments
|
||||
// case 1:
|
||||
// case 0:
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case tagPassword:
|
||||
// type = new HTMLType(HTMLType.Type.Password);
|
||||
// break;
|
||||
//
|
||||
// case tagRadio:
|
||||
// type = new HTMLType(HTMLType.Type.Radio);
|
||||
// break;
|
||||
//
|
||||
// case tagRange:
|
||||
// type = new HTMLType(HTMLType.Type.Range);
|
||||
//
|
||||
// //Check for other items
|
||||
// switch (arguments.length) {
|
||||
// default:
|
||||
// case 4:
|
||||
// type.addArg(HTMLType.StepKey, arguments[3]);
|
||||
//
|
||||
// case 3: //must have both lower and upper bound
|
||||
// type.addArg(HTMLType.UpperBoundKey, arguments[2]);
|
||||
// type.addArg(HTMLType.LowerBoundKey, arguments[1]);
|
||||
// break;
|
||||
//
|
||||
// //Do not support 2 or 1 or 0 arguments
|
||||
// case 2:
|
||||
// case 1:
|
||||
// case 0:
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
//
|
||||
// case tagText:
|
||||
// type = new HTMLType(HTMLType.Type.Text);
|
||||
// break;
|
||||
//
|
||||
// case tagDropdown:
|
||||
// type = new HTMLType(HTMLType.Type.Dropdown);
|
||||
// break;
|
||||
//
|
||||
// case tagRealTime:
|
||||
// type = new HTMLType(HTMLType.Type.RealTime);
|
||||
// break;
|
||||
//
|
||||
// case tagHidden:
|
||||
// type = new HTMLType(HTMLType.Type.Hidden);
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// //Nothing
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return type;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
public static void modifyVarTags(Variable var, String text) {
|
||||
if (var == null) { return; }
|
||||
|
||||
IntegerHolder tagLocation = new IntegerHolder(0);
|
||||
String tag = getNextTag(text, tagLocation);
|
||||
String[] tagArgs = null;
|
||||
if (tag != null) {
|
||||
tagArgs = tag.split(",");
|
||||
}
|
||||
|
||||
while (tagArgs != null) {
|
||||
|
||||
if (tagArgs.length > 0) {
|
||||
switch (tagArgs[0]) {
|
||||
case tagPrefixID:
|
||||
if (tagArgs.length > 1) {
|
||||
try {
|
||||
var.setPrefixID(new IDPrefix(tagArgs[1].strip()));
|
||||
} catch (PrefixException e) {
|
||||
System.out.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case tagDisplayName:
|
||||
if (tagArgs.length > 1) {
|
||||
var.setDisplayName(tagArgs[1].strip());
|
||||
}
|
||||
break;
|
||||
|
||||
case tagShownDecimals:
|
||||
if (tagArgs.length > 1) {
|
||||
String strInt = tagArgs[1].strip();
|
||||
try {
|
||||
var.setDecimalPlaces(Integer.parseInt(strInt));
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.out.println("WARNING: tagShownDecimals has incorrect number of decimal places to show. (for `" + var.getName() + "`)\n\t" + nfe.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case tagNumberLink:
|
||||
if (tagArgs.length > 1) {
|
||||
var.setLinkedName(tagArgs[1].strip());
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
/* HTML Tags */
|
||||
|
||||
case tagHidden:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Hidden));
|
||||
break;
|
||||
|
||||
case tagCheckbox:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Checkbox));
|
||||
break;
|
||||
|
||||
case tagNumber:
|
||||
HTMLType numbertype = new HTMLType(HTMLType.Type.Number);
|
||||
//Check for other items
|
||||
|
||||
switch (tagArgs.length) {
|
||||
default:
|
||||
case 4:
|
||||
numbertype.addArg(HTMLType.StepKey, tagArgs[3]);
|
||||
case 3:
|
||||
numbertype.addArg(HTMLType.UpperBoundKey, tagArgs[2]);
|
||||
case 2:
|
||||
numbertype.addArg(HTMLType.LowerBoundKey, tagArgs[1]);
|
||||
break;
|
||||
|
||||
//Do not support 1 or 0 arguments
|
||||
case 1:
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
var.setHTMLType(numbertype);
|
||||
break;
|
||||
|
||||
|
||||
case tagPassword:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Password));
|
||||
break;
|
||||
|
||||
case tagRadio:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Radio));
|
||||
break;
|
||||
|
||||
case tagRange:
|
||||
HTMLType rangetype = new HTMLType(HTMLType.Type.Range);
|
||||
|
||||
//Check for other items
|
||||
switch (tagArgs.length) {
|
||||
default:
|
||||
case 4:
|
||||
rangetype.addArg(HTMLType.StepKey, tagArgs[3]);
|
||||
|
||||
case 3: //must have both lower and upper bound
|
||||
rangetype.addArg(HTMLType.UpperBoundKey, tagArgs[2]);
|
||||
rangetype.addArg(HTMLType.LowerBoundKey, tagArgs[1]);
|
||||
break;
|
||||
|
||||
//Do not support 2 or 1 or 0 arguments
|
||||
case 2:
|
||||
case 1:
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
var.setHTMLType(rangetype);
|
||||
break;
|
||||
|
||||
case tagText:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Text));
|
||||
break;
|
||||
|
||||
case tagDropdown:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.Dropdown));
|
||||
break;
|
||||
|
||||
case tagRealTime:
|
||||
var.setHTMLType(new HTMLType(HTMLType.Type.RealTime));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tag = getNextTag(text, tagLocation);
|
||||
if (tag != null) {
|
||||
tagArgs = tag.split(",");
|
||||
} else {
|
||||
tagArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
}//modifyVarTags()
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
4457
src/JavaCC_CParser/CParser.java
Normal file
4457
src/JavaCC_CParser/CParser.java
Normal file
File diff suppressed because it is too large
Load Diff
597
src/JavaCC_CParser/CParser.jj
Normal file
597
src/JavaCC_CParser/CParser.jj
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
|
||||
C grammar definition for use with JavaCC
|
||||
Contributed by Doug South (dsouth@squirrel.com.au) 21/3/97
|
||||
|
||||
This parser assumes that the C source file has been preprocessed : all
|
||||
#includes have been included and all macros have been expanded. I accomplish
|
||||
this with "gcc -P -E <source file> > <output file>".
|
||||
|
||||
There is a problem with compiler specific types, such as __signed, __const,
|
||||
__inline__, etc. These types can be added as typedef types before the parser
|
||||
is run on a file. See main() for an example. I have also found a strange little
|
||||
compiler specific "type" if you can call it that. It is __attribute__, but it
|
||||
does not seem to be used as a type. I found that just deleting the __attribute__
|
||||
and the following "offensive" code works.
|
||||
|
||||
This grammar also prints out all the types defined while parsing the file. This
|
||||
is done via a call to printTypes() when the parser is complete. If you do not want
|
||||
this, just comment out the printTypes() method call in the production rule
|
||||
TranslationUnit(), which BTW is the root node for parsing a C source file.
|
||||
|
||||
I have not in anyway extensively tested this grammar, in fact it is barely tested,
|
||||
but I imagine it is better to have a starting point for a C grammar other than from
|
||||
scratch. It has not been optimized in anyway, my main aim was to get a parser that
|
||||
works. Lookahead may not be optimum at choice points and may even be insufficient at
|
||||
times. I choose to err on the side of not optimum if I made a choice at all.
|
||||
|
||||
If you use this grammar, I would appreciate hearing from you. I will try to maintain
|
||||
this grammar to the best of my ability, but at this point in time, this is only a side
|
||||
hobby (unless someone wants to pay me for doing JavaCC work!). In that regards, I am
|
||||
interested in hearing bugs and comments.
|
||||
|
||||
TODO:
|
||||
|
||||
Insert the appropriate code to enable C source trees from this grammar.
|
||||
|
||||
=============================================
|
||||
3/2/06: Modified by Tom Copeland
|
||||
- STRING_LITERAL now handles embedded escaped newlines, thanks to J.Chris Findlay for the patch
|
||||
- Works with JavaCC 4.0
|
||||
- Preprocessor directives are now simply SKIP'd, so no need to run C files through GCC first
|
||||
|
||||
*/
|
||||
|
||||
PARSER_BEGIN(CParser)
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CParser{
|
||||
|
||||
// Hastable for storing typedef types
|
||||
private static Set types = new HashSet();
|
||||
|
||||
// Stack for determining when the parser
|
||||
// is parsing a typdef definition.
|
||||
private static Stack typedefParsingStack = new Stack();
|
||||
|
||||
// Returns true if the given string is
|
||||
// a typedef type.
|
||||
private static boolean isType(String type){
|
||||
return types.contains(type);
|
||||
}
|
||||
|
||||
// Add a typedef type to those already defined
|
||||
private static void addType(String type){
|
||||
types.add(type);
|
||||
}
|
||||
|
||||
// Prints out all the types used in parsing the c source
|
||||
private static void printTypes(){
|
||||
for (Iterator i = types.iterator(); i.hasNext();) {
|
||||
System.out.println(i.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Run the parser
|
||||
public static void main ( String args [ ] ) {
|
||||
CParser parser ;
|
||||
|
||||
// Hack to include type "special types"
|
||||
types.add("__signed__");
|
||||
types.add("__const");
|
||||
types.add("__inline__");
|
||||
types.add("__signed");
|
||||
|
||||
if(args.length == 0){
|
||||
System.out.println("C Parser Version 0.1Alpha: Reading from standard input . . .");
|
||||
parser = new CParser(System.in);
|
||||
}
|
||||
else if(args.length == 1){
|
||||
System.out.println("C Parser Version 0.1Alpha: Reading from file " + args[0] + " . . ." );
|
||||
try {
|
||||
parser = new CParser(new java.io.FileInputStream(args[0]));
|
||||
}
|
||||
catch(java.io.FileNotFoundException e){
|
||||
System.out.println("C Parser Version 0.1: File " + args[0] + " not found.");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println("C Parser Version 0.1Alpha: Usage is one of:");
|
||||
System.out.println(" java CParser < inputfile");
|
||||
System.out.println("OR");
|
||||
System.out.println(" java CParser inputfile");
|
||||
return ;
|
||||
}
|
||||
try {
|
||||
parser.TranslationUnit();
|
||||
System.out.println("C Parser Version 0.1Alpha: Java program parsed successfully.");
|
||||
}
|
||||
catch(ParseException e){
|
||||
System.out.println("C Parser Version 0.1Alpha: Encountered errors during parse.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PARSER_END(CParser)
|
||||
|
||||
SKIP : {
|
||||
" "
|
||||
| "\t"
|
||||
| "\n"
|
||||
| "\r"
|
||||
| <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")>
|
||||
| <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
|
||||
| "#" : PREPROCESSOR_OUTPUT
|
||||
}
|
||||
|
||||
<PREPROCESSOR_OUTPUT> SKIP:
|
||||
{
|
||||
"\n" : DEFAULT
|
||||
}
|
||||
|
||||
<PREPROCESSOR_OUTPUT> MORE:
|
||||
{
|
||||
"\\\n"
|
||||
|
|
||||
"\\\r\n"
|
||||
|
|
||||
< ~[] >
|
||||
}
|
||||
|
||||
|
||||
TOKEN : {
|
||||
<INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? | <HEX_LITERAL> (["l","L"])? | <OCTAL_LITERAL> (["l","L"])?>
|
||||
| <#DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*>
|
||||
| <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+>
|
||||
| <#OCTAL_LITERAL: "0" (["0"-"7"])*>
|
||||
| <FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]>
|
||||
| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
|
||||
| <CHARACTER_LITERAL: "\'" (~["\'","\\","\n","\r"] | "\\" (["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"])) "\'">
|
||||
| <STRING_LITERAL: "\"" ( ~["\"","\\","\n","\r"] | "\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"] | ( ["\n","\r"] | "\r\n")))* "\"">
|
||||
}
|
||||
|
||||
TOKEN : {
|
||||
<CONTINUE: "continue"> |
|
||||
<VOLATILE: "volatile"> |
|
||||
<REGISTER: "register"> |
|
||||
<UNSIGNED: "unsigned"> |
|
||||
<TYPEDEF: "typedef"> |
|
||||
<DFLT: "default"> |
|
||||
<DOUBLE: "double"> |
|
||||
<SIZEOF: "sizeof"> |
|
||||
<SWITCH: "switch"> |
|
||||
<RETURN: "return"> |
|
||||
<EXTERN: "extern"> |
|
||||
<STRUCT: "struct"> |
|
||||
<STATIC: "static"> |
|
||||
<SIGNED: "signed"> |
|
||||
<WHILE: "while"> |
|
||||
<BREAK: "break"> |
|
||||
<UNION: "union"> |
|
||||
<CONST: "const"> |
|
||||
<FLOAT: "float"> |
|
||||
<SHORT: "short"> |
|
||||
<ELSE: "else"> |
|
||||
<CASE: "case"> |
|
||||
<LONG: "long"> |
|
||||
<ENUM: "enum"> |
|
||||
<AUTO: "auto"> |
|
||||
<VOID: "void"> |
|
||||
<CHAR: "char"> |
|
||||
<GOTO: "goto"> |
|
||||
<FOR: "for"> |
|
||||
<INT: "int"> |
|
||||
<IF: "if"> |
|
||||
<DO: "do">
|
||||
}
|
||||
|
||||
TOKEN : {
|
||||
<IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*>
|
||||
| <#LETTER: ["$","A"-"Z","_","a"-"z"]>
|
||||
| <#DIGIT: ["0"-"9"]>
|
||||
}
|
||||
|
||||
void TranslationUnit() : {}
|
||||
{
|
||||
(ExternalDeclaration())+
|
||||
{printTypes();}
|
||||
}
|
||||
|
||||
void ExternalDeclaration() : {}
|
||||
{
|
||||
( LOOKAHEAD( FunctionDefinition() ) FunctionDefinition() | Declaration())
|
||||
}
|
||||
|
||||
void FunctionDefinition() : {}
|
||||
{
|
||||
[LOOKAHEAD(DeclarationSpecifiers()) DeclarationSpecifiers()] Declarator() [ DeclarationList() ]
|
||||
CompoundStatement()
|
||||
}
|
||||
|
||||
void Declaration() : {}
|
||||
{
|
||||
DeclarationSpecifiers() [ InitDeclaratorList() ] ";"
|
||||
}
|
||||
|
||||
void DeclarationList() : {}
|
||||
{
|
||||
( LOOKAHEAD(Declaration()) Declaration() )+
|
||||
}
|
||||
|
||||
void DeclarationSpecifiers() : {}
|
||||
{
|
||||
StorageClassSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
|
||||
DeclarationSpecifiers() ] |
|
||||
TypeSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
|
||||
DeclarationSpecifiers() ] |
|
||||
TypeQualifier() [ LOOKAHEAD(DeclarationSpecifiers())
|
||||
DeclarationSpecifiers() ]
|
||||
}
|
||||
|
||||
void StorageClassSpecifier() : {}
|
||||
{
|
||||
( <AUTO> | <REGISTER> | <STATIC> | <EXTERN> | <TYPEDEF>
|
||||
{
|
||||
typedefParsingStack.push(Boolean.TRUE);
|
||||
} )
|
||||
}
|
||||
|
||||
void TypeSpecifier() : {}
|
||||
{
|
||||
( <VOID> | <CHAR> | <SHORT> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | <SIGNED> |
|
||||
<UNSIGNED> | StructOrUnionSpecifier() | EnumSpecifier() | LOOKAHEAD( { isType(getToken(1).image) } )TypedefName() )
|
||||
}
|
||||
|
||||
void TypeQualifier() : {}
|
||||
{
|
||||
( <CONST> | <VOLATILE> )
|
||||
}
|
||||
|
||||
void StructOrUnionSpecifier() : {}
|
||||
{
|
||||
{
|
||||
typedefParsingStack.push(Boolean.FALSE);
|
||||
}
|
||||
|
||||
StructOrUnion() ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" StructDeclarationList() "}" | <IDENTIFIER> )
|
||||
|
||||
{
|
||||
typedefParsingStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void StructOrUnion() : {}
|
||||
{
|
||||
( <STRUCT> | <UNION> )
|
||||
}
|
||||
|
||||
void StructDeclarationList() : {}
|
||||
{
|
||||
(StructDeclaration())+
|
||||
}
|
||||
|
||||
void InitDeclaratorList() : {}
|
||||
{
|
||||
InitDeclarator() ("," InitDeclarator())*
|
||||
{
|
||||
// Finished with a typedefDeclaration??
|
||||
if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
|
||||
typedefParsingStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitDeclarator() : {}
|
||||
{
|
||||
Declarator() [ "=" Initializer() ]
|
||||
}
|
||||
|
||||
void StructDeclaration() : {}
|
||||
{
|
||||
SpecifierQualifierList() StructDeclaratorList() ";"
|
||||
}
|
||||
|
||||
void SpecifierQualifierList() : {}
|
||||
{
|
||||
TypeSpecifier() [ LOOKAHEAD(SpecifierQualifierList())
|
||||
SpecifierQualifierList() ]|
|
||||
TypeQualifier() [ LOOKAHEAD(SpecifierQualifierList())
|
||||
SpecifierQualifierList() ]
|
||||
}
|
||||
|
||||
void StructDeclaratorList() : {}
|
||||
{
|
||||
StructDeclarator() ( "," StructDeclarator() )*
|
||||
}
|
||||
|
||||
void StructDeclarator() : {}
|
||||
{
|
||||
( LOOKAHEAD(3) Declarator() | [ Declarator() ] ":" ConstantExpression() )
|
||||
}
|
||||
|
||||
void EnumSpecifier() : {}
|
||||
{
|
||||
<ENUM> ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" EnumeratorList() "}" | <IDENTIFIER> )
|
||||
}
|
||||
|
||||
void EnumeratorList() : {}
|
||||
{
|
||||
Enumerator() ("," Enumerator())*
|
||||
}
|
||||
|
||||
void Enumerator() : {}
|
||||
{
|
||||
<IDENTIFIER> [ "=" ConstantExpression() ]
|
||||
}
|
||||
|
||||
void Declarator() : {}
|
||||
{
|
||||
[ Pointer() ] DirectDeclarator()
|
||||
}
|
||||
|
||||
void DirectDeclarator() : { Token t;}
|
||||
{
|
||||
( t = <IDENTIFIER>
|
||||
|
||||
{ if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
|
||||
addType(t.image);
|
||||
}
|
||||
}
|
||||
| "(" Declarator() ")" )
|
||||
|
||||
{ typedefParsingStack.push( Boolean.FALSE ); }
|
||||
|
||||
( "[" [ ConstantExpression() ] "]" |
|
||||
LOOKAHEAD(3) "(" ParameterTypeList() ")" |
|
||||
"(" [ IdentifierList() ] ")" )*
|
||||
{ typedefParsingStack.pop(); }
|
||||
}
|
||||
|
||||
void Pointer() : {}
|
||||
{
|
||||
"*" [ TypeQualifierList() ] [ Pointer() ]
|
||||
}
|
||||
|
||||
void TypeQualifierList() : {}
|
||||
{
|
||||
(TypeQualifier())+
|
||||
}
|
||||
|
||||
void ParameterTypeList() : {}
|
||||
{
|
||||
ParameterList() ["," "..." ]
|
||||
}
|
||||
|
||||
void ParameterList() : {}
|
||||
{
|
||||
ParameterDeclaration() (LOOKAHEAD(2) "," ParameterDeclaration())*
|
||||
}
|
||||
|
||||
void ParameterDeclaration() : {}
|
||||
{
|
||||
DeclarationSpecifiers() ( LOOKAHEAD(Declarator()) Declarator() | [ AbstractDeclarator() ] )
|
||||
}
|
||||
|
||||
void IdentifierList() : {}
|
||||
{
|
||||
<IDENTIFIER> ("," <IDENTIFIER>)*
|
||||
}
|
||||
|
||||
void Initializer() : {}
|
||||
{
|
||||
( AssignmentExpression() |
|
||||
"{" InitializerList() [","] "}" )
|
||||
}
|
||||
|
||||
void InitializerList() : {}
|
||||
{
|
||||
Initializer() (LOOKAHEAD(2) "," Initializer())*
|
||||
}
|
||||
|
||||
void TypeName() : {}
|
||||
{
|
||||
SpecifierQualifierList() [ AbstractDeclarator() ]
|
||||
|
||||
}
|
||||
|
||||
void AbstractDeclarator() : {}
|
||||
{
|
||||
( LOOKAHEAD(3) Pointer() |
|
||||
[Pointer()] DirectAbstractDeclarator() )
|
||||
}
|
||||
|
||||
void DirectAbstractDeclarator() : {}
|
||||
{
|
||||
( LOOKAHEAD(2) "(" AbstractDeclarator() ")" |
|
||||
"[" [ConstantExpression()] "]" |
|
||||
"(" [ParameterTypeList()] ")" )
|
||||
|
||||
( "[" [ ConstantExpression() ] "]" | "(" [ ParameterTypeList() ] ")" )*
|
||||
}
|
||||
|
||||
void TypedefName() : {}
|
||||
{
|
||||
<IDENTIFIER>
|
||||
}
|
||||
|
||||
void Statement() : {}
|
||||
{
|
||||
( LOOKAHEAD(2) LabeledStatement() |
|
||||
ExpressionStatement() |
|
||||
CompoundStatement() |
|
||||
SelectionStatement() |
|
||||
IterationStatement() |
|
||||
JumpStatement() )
|
||||
}
|
||||
|
||||
void LabeledStatement() : {}
|
||||
{
|
||||
( <IDENTIFIER> ":" Statement() |
|
||||
<CASE> ConstantExpression() ":" Statement() |
|
||||
<DFLT> ":" Statement() )
|
||||
}
|
||||
|
||||
void ExpressionStatement() : {}
|
||||
{
|
||||
[ Expression() ] ";"
|
||||
}
|
||||
|
||||
void CompoundStatement() : {}
|
||||
{
|
||||
"{" [ LOOKAHEAD(DeclarationList()) DeclarationList() ]
|
||||
[ StatementList() ]
|
||||
"}"
|
||||
}
|
||||
|
||||
void StatementList() : {}
|
||||
{
|
||||
(Statement())+
|
||||
}
|
||||
|
||||
void SelectionStatement() : {}
|
||||
{
|
||||
( <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(2) <ELSE> Statement() ] |
|
||||
<SWITCH> "(" Expression() ")" Statement() )
|
||||
}
|
||||
|
||||
void IterationStatement() : {}
|
||||
{
|
||||
( <WHILE> "(" Expression() ")" Statement() |
|
||||
<DO> Statement() <WHILE> "(" Expression() ")" ";" |
|
||||
<FOR> "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement() )
|
||||
}
|
||||
|
||||
void JumpStatement() : {}
|
||||
{
|
||||
( <GOTO> <IDENTIFIER> ";" |
|
||||
<CONTINUE> ";" |
|
||||
<BREAK> ";" |
|
||||
<RETURN> [ Expression() ] ";" )
|
||||
}
|
||||
|
||||
void Expression() : {}
|
||||
{
|
||||
AssignmentExpression() ( "," AssignmentExpression() )*
|
||||
}
|
||||
|
||||
void AssignmentExpression() : {}
|
||||
{
|
||||
LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() |
|
||||
LOOKAHEAD(3) ConditionalExpression()
|
||||
}
|
||||
|
||||
void AssignmentOperator() : {}
|
||||
{
|
||||
( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" )
|
||||
}
|
||||
|
||||
void ConditionalExpression() : {}
|
||||
{
|
||||
LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ]
|
||||
}
|
||||
|
||||
void ConstantExpression() : {}
|
||||
{
|
||||
ConditionalExpression()
|
||||
}
|
||||
|
||||
void LogicalORExpression() : {}
|
||||
{
|
||||
LogicalANDExpression() [ "||" LogicalORExpression() ]
|
||||
}
|
||||
|
||||
void LogicalANDExpression() : {}
|
||||
{
|
||||
InclusiveORExpression() [ "&&" LogicalANDExpression() ]
|
||||
}
|
||||
|
||||
void InclusiveORExpression() : {}
|
||||
{
|
||||
ExclusiveORExpression() [ "|" InclusiveORExpression() ]
|
||||
}
|
||||
|
||||
void ExclusiveORExpression() : {}
|
||||
{
|
||||
ANDExpression() [ "^" ExclusiveORExpression() ]
|
||||
}
|
||||
|
||||
void ANDExpression() : {}
|
||||
{
|
||||
EqualityExpression() [ "&" ANDExpression() ]
|
||||
}
|
||||
|
||||
void EqualityExpression() : {}
|
||||
{
|
||||
RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]
|
||||
}
|
||||
|
||||
void RelationalExpression() : {}
|
||||
{
|
||||
ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ]
|
||||
}
|
||||
|
||||
void ShiftExpression() : {}
|
||||
{
|
||||
AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ]
|
||||
}
|
||||
|
||||
void AdditiveExpression() : {}
|
||||
{
|
||||
MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ]
|
||||
}
|
||||
|
||||
void MultiplicativeExpression() : {}
|
||||
{
|
||||
CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ]
|
||||
}
|
||||
|
||||
void CastExpression() : {}
|
||||
{
|
||||
( LOOKAHEAD("(" TypeName() ")" CastExpression() ) "(" TypeName() ")" CastExpression() |
|
||||
UnaryExpression() )
|
||||
}
|
||||
|
||||
void UnaryExpression() : {}
|
||||
{
|
||||
( LOOKAHEAD(3) PostfixExpression() |
|
||||
"++" UnaryExpression() |
|
||||
"--" UnaryExpression() |
|
||||
UnaryOperator() CastExpression() |
|
||||
<SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )
|
||||
}
|
||||
|
||||
void UnaryOperator() : {}
|
||||
{
|
||||
( "&" | "*" | "+" | "-" | "~" | "!" )
|
||||
}
|
||||
|
||||
void PostfixExpression() : {}
|
||||
{
|
||||
PrimaryExpression() ( "[" Expression() "]" |
|
||||
"(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" |
|
||||
"." <IDENTIFIER> |
|
||||
"->" <IDENTIFIER> |
|
||||
"++" |
|
||||
"--" )*
|
||||
}
|
||||
|
||||
void PrimaryExpression() : {}
|
||||
{
|
||||
( <IDENTIFIER> |
|
||||
Constant() |
|
||||
"(" Expression() ")" )
|
||||
}
|
||||
|
||||
void ArgumentExpressionList() : {}
|
||||
{
|
||||
AssignmentExpression() ( "," AssignmentExpression() )*
|
||||
}
|
||||
|
||||
void Constant() : {}
|
||||
{
|
||||
<INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL>
|
||||
}
|
||||
|
||||
209
src/JavaCC_CParser/CParserConstants.java
Normal file
209
src/JavaCC_CParser/CParserConstants.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. CParserConstants.java */
|
||||
package JavaCC_CParser;
|
||||
|
||||
/**
|
||||
* Token literal values and constants.
|
||||
* Generated by org.javacc.parser.OtherFilesGen#start()
|
||||
*/
|
||||
public interface CParserConstants {
|
||||
|
||||
/** End of File. */
|
||||
int EOF = 0;
|
||||
/** RegularExpression Id. */
|
||||
int INTEGER_LITERAL = 12;
|
||||
/** RegularExpression Id. */
|
||||
int DECIMAL_LITERAL = 13;
|
||||
/** RegularExpression Id. */
|
||||
int HEX_LITERAL = 14;
|
||||
/** RegularExpression Id. */
|
||||
int OCTAL_LITERAL = 15;
|
||||
/** RegularExpression Id. */
|
||||
int FLOATING_POINT_LITERAL = 16;
|
||||
/** RegularExpression Id. */
|
||||
int EXPONENT = 17;
|
||||
/** RegularExpression Id. */
|
||||
int CHARACTER_LITERAL = 18;
|
||||
/** RegularExpression Id. */
|
||||
int STRING_LITERAL = 19;
|
||||
/** RegularExpression Id. */
|
||||
int CONTINUE = 20;
|
||||
/** RegularExpression Id. */
|
||||
int VOLATILE = 21;
|
||||
/** RegularExpression Id. */
|
||||
int REGISTER = 22;
|
||||
/** RegularExpression Id. */
|
||||
int UNSIGNED = 23;
|
||||
/** RegularExpression Id. */
|
||||
int TYPEDEF = 24;
|
||||
/** RegularExpression Id. */
|
||||
int DFLT = 25;
|
||||
/** RegularExpression Id. */
|
||||
int DOUBLE = 26;
|
||||
/** RegularExpression Id. */
|
||||
int SIZEOF = 27;
|
||||
/** RegularExpression Id. */
|
||||
int SWITCH = 28;
|
||||
/** RegularExpression Id. */
|
||||
int RETURN = 29;
|
||||
/** RegularExpression Id. */
|
||||
int EXTERN = 30;
|
||||
/** RegularExpression Id. */
|
||||
int STRUCT = 31;
|
||||
/** RegularExpression Id. */
|
||||
int STATIC = 32;
|
||||
/** RegularExpression Id. */
|
||||
int SIGNED = 33;
|
||||
/** RegularExpression Id. */
|
||||
int WHILE = 34;
|
||||
/** RegularExpression Id. */
|
||||
int BREAK = 35;
|
||||
/** RegularExpression Id. */
|
||||
int UNION = 36;
|
||||
/** RegularExpression Id. */
|
||||
int CONST = 37;
|
||||
/** RegularExpression Id. */
|
||||
int FLOAT = 38;
|
||||
/** RegularExpression Id. */
|
||||
int SHORT = 39;
|
||||
/** RegularExpression Id. */
|
||||
int ELSE = 40;
|
||||
/** RegularExpression Id. */
|
||||
int CASE = 41;
|
||||
/** RegularExpression Id. */
|
||||
int LONG = 42;
|
||||
/** RegularExpression Id. */
|
||||
int ENUM = 43;
|
||||
/** RegularExpression Id. */
|
||||
int AUTO = 44;
|
||||
/** RegularExpression Id. */
|
||||
int VOID = 45;
|
||||
/** RegularExpression Id. */
|
||||
int CHAR = 46;
|
||||
/** RegularExpression Id. */
|
||||
int GOTO = 47;
|
||||
/** RegularExpression Id. */
|
||||
int FOR = 48;
|
||||
/** RegularExpression Id. */
|
||||
int INT = 49;
|
||||
/** RegularExpression Id. */
|
||||
int IF = 50;
|
||||
/** RegularExpression Id. */
|
||||
int DO = 51;
|
||||
/** RegularExpression Id. */
|
||||
int IDENTIFIER = 52;
|
||||
/** RegularExpression Id. */
|
||||
int LETTER = 53;
|
||||
/** RegularExpression Id. */
|
||||
int DIGIT = 54;
|
||||
|
||||
/** Lexical state. */
|
||||
int DEFAULT = 0;
|
||||
/** Lexical state. */
|
||||
int PREPROCESSOR_OUTPUT = 1;
|
||||
|
||||
/** Literal token values. */
|
||||
String[] tokenImage = {
|
||||
"<EOF>",
|
||||
"\" \"",
|
||||
"\"\\t\"",
|
||||
"\"\\n\"",
|
||||
"\"\\r\"",
|
||||
"<token of kind 5>",
|
||||
"<token of kind 6>",
|
||||
"\"#\"",
|
||||
"\"\\n\"",
|
||||
"\"\\\\\\n\"",
|
||||
"\"\\\\\\r\\n\"",
|
||||
"<token of kind 11>",
|
||||
"<INTEGER_LITERAL>",
|
||||
"<DECIMAL_LITERAL>",
|
||||
"<HEX_LITERAL>",
|
||||
"<OCTAL_LITERAL>",
|
||||
"<FLOATING_POINT_LITERAL>",
|
||||
"<EXPONENT>",
|
||||
"<CHARACTER_LITERAL>",
|
||||
"<STRING_LITERAL>",
|
||||
"\"continue\"",
|
||||
"\"volatile\"",
|
||||
"\"register\"",
|
||||
"\"unsigned\"",
|
||||
"\"typedef\"",
|
||||
"\"default\"",
|
||||
"\"double\"",
|
||||
"\"sizeof\"",
|
||||
"\"switch\"",
|
||||
"\"return\"",
|
||||
"\"extern\"",
|
||||
"\"struct\"",
|
||||
"\"static\"",
|
||||
"\"signed\"",
|
||||
"\"while\"",
|
||||
"\"break\"",
|
||||
"\"union\"",
|
||||
"\"const\"",
|
||||
"\"float\"",
|
||||
"\"short\"",
|
||||
"\"else\"",
|
||||
"\"case\"",
|
||||
"\"long\"",
|
||||
"\"enum\"",
|
||||
"\"auto\"",
|
||||
"\"void\"",
|
||||
"\"char\"",
|
||||
"\"goto\"",
|
||||
"\"for\"",
|
||||
"\"int\"",
|
||||
"\"if\"",
|
||||
"\"do\"",
|
||||
"<IDENTIFIER>",
|
||||
"<LETTER>",
|
||||
"<DIGIT>",
|
||||
"\";\"",
|
||||
"\"{\"",
|
||||
"\"}\"",
|
||||
"\",\"",
|
||||
"\"=\"",
|
||||
"\":\"",
|
||||
"\"(\"",
|
||||
"\")\"",
|
||||
"\"[\"",
|
||||
"\"]\"",
|
||||
"\"*\"",
|
||||
"\"...\"",
|
||||
"\"*=\"",
|
||||
"\"/=\"",
|
||||
"\"%=\"",
|
||||
"\"+=\"",
|
||||
"\"-=\"",
|
||||
"\"<<=\"",
|
||||
"\">>=\"",
|
||||
"\"&=\"",
|
||||
"\"^=\"",
|
||||
"\"|=\"",
|
||||
"\"?\"",
|
||||
"\"||\"",
|
||||
"\"&&\"",
|
||||
"\"|\"",
|
||||
"\"^\"",
|
||||
"\"&\"",
|
||||
"\"==\"",
|
||||
"\"!=\"",
|
||||
"\"<\"",
|
||||
"\">\"",
|
||||
"\"<=\"",
|
||||
"\">=\"",
|
||||
"\"<<\"",
|
||||
"\">>\"",
|
||||
"\"+\"",
|
||||
"\"-\"",
|
||||
"\"/\"",
|
||||
"\"%\"",
|
||||
"\"++\"",
|
||||
"\"--\"",
|
||||
"\"~\"",
|
||||
"\"!\"",
|
||||
"\".\"",
|
||||
"\"->\"",
|
||||
};
|
||||
|
||||
}
|
||||
1373
src/JavaCC_CParser/CParserTokenManager.java
Normal file
1373
src/JavaCC_CParser/CParserTokenManager.java
Normal file
File diff suppressed because it is too large
Load Diff
195
src/JavaCC_CParser/ParseException.java
Normal file
195
src/JavaCC_CParser/ParseException.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 7.0 */
|
||||
/* JavaCCOptions:KEEP_LINE_COLUMN=true */
|
||||
package JavaCC_CParser;
|
||||
|
||||
/**
|
||||
* This exception is thrown when parse errors are encountered.
|
||||
* You can explicitly create objects of this exception type by
|
||||
* calling the method generateParseException in the generated
|
||||
* parser.
|
||||
*
|
||||
* You can modify this class to customize your error reporting
|
||||
* mechanisms so long as you retain the public fields.
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* The end of line string for this machine.
|
||||
*/
|
||||
protected static String EOL = System.getProperty("line.separator", "\n");
|
||||
|
||||
/**
|
||||
* This constructor is used by the method "generateParseException"
|
||||
* in the generated parser. Calling this constructor generates
|
||||
* a new object of this type with the fields "currentToken",
|
||||
* "expectedTokenSequences", and "tokenImage" set.
|
||||
*/
|
||||
public ParseException(Token currentTokenVal,
|
||||
int[][] expectedTokenSequencesVal,
|
||||
String[] tokenImageVal
|
||||
)
|
||||
{
|
||||
super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
|
||||
currentToken = currentTokenVal;
|
||||
expectedTokenSequences = expectedTokenSequencesVal;
|
||||
tokenImage = tokenImageVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following constructors are for use by you for whatever
|
||||
* purpose you can think of. Constructing the exception in this
|
||||
* manner makes the exception behave in the normal way - i.e., as
|
||||
* documented in the class "Throwable". The fields "errorToken",
|
||||
* "expectedTokenSequences", and "tokenImage" do not contain
|
||||
* relevant information. The JavaCC generated code does not use
|
||||
* these constructors.
|
||||
*/
|
||||
|
||||
public ParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** Constructor with message. */
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the last token that has been consumed successfully. If
|
||||
* this object has been created due to a parse error, the token
|
||||
* following this token will (therefore) be the first error token.
|
||||
*/
|
||||
public Token currentToken;
|
||||
|
||||
/**
|
||||
* Each entry in this array is an array of integers. Each array
|
||||
* of integers represents a sequence of tokens (by their ordinal
|
||||
* values) that is expected at this point of the parse.
|
||||
*/
|
||||
public int[][] expectedTokenSequences;
|
||||
|
||||
/**
|
||||
* This is a reference to the "tokenImage" array of the generated
|
||||
* parser within which the parse error occurred. This array is
|
||||
* defined in the generated ...Constants interface.
|
||||
*/
|
||||
public String[] tokenImage;
|
||||
|
||||
/**
|
||||
* It uses "currentToken" and "expectedTokenSequences" to generate a parse
|
||||
* error message and returns it. If this object has been created
|
||||
* due to a parse error, and you do not catch it (it gets thrown
|
||||
* from the parser) the correct error message
|
||||
* gets displayed.
|
||||
*/
|
||||
private static String initialise(Token currentToken,
|
||||
int[][] expectedTokenSequences,
|
||||
String[] tokenImage) {
|
||||
|
||||
StringBuilder expected = new StringBuilder();
|
||||
int maxSize = 0;
|
||||
for (int i = 0; i < expectedTokenSequences.length; i++) {
|
||||
if (maxSize < expectedTokenSequences[i].length) {
|
||||
maxSize = expectedTokenSequences[i].length;
|
||||
}
|
||||
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
|
||||
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
|
||||
}
|
||||
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
|
||||
expected.append("...");
|
||||
}
|
||||
expected.append(EOL).append(" ");
|
||||
}
|
||||
String retval = "Encountered \"";
|
||||
Token tok = currentToken.next;
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
if (i != 0) retval += " ";
|
||||
if (tok.kind == 0) {
|
||||
retval += tokenImage[0];
|
||||
break;
|
||||
}
|
||||
retval += " " + tokenImage[tok.kind];
|
||||
retval += " \"";
|
||||
retval += add_escapes(tok.image);
|
||||
retval += " \"";
|
||||
tok = tok.next;
|
||||
}
|
||||
if (currentToken.next != null) {
|
||||
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
|
||||
}
|
||||
retval += "." + EOL;
|
||||
|
||||
|
||||
if (expectedTokenSequences.length == 0) {
|
||||
// Nothing to add here
|
||||
} else {
|
||||
if (expectedTokenSequences.length == 1) {
|
||||
retval += "Was expecting:" + EOL + " ";
|
||||
} else {
|
||||
retval += "Was expecting one of:" + EOL + " ";
|
||||
}
|
||||
retval += expected.toString();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to convert raw characters to their escaped version
|
||||
* when these raw version cannot be used as part of an ASCII
|
||||
* string literal.
|
||||
*/
|
||||
static String add_escapes(String str) {
|
||||
StringBuilder retval = new StringBuilder();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=de3ddfc6669ad4ae8d41fff7ccf6fbb7 (do not edit this line) */
|
||||
476
src/JavaCC_CParser/SimpleCharStream.java
Normal file
476
src/JavaCC_CParser/SimpleCharStream.java
Normal file
@@ -0,0 +1,476 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 7.0 */
|
||||
/* JavaCCOptions:STATIC=true,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package JavaCC_CParser;
|
||||
|
||||
/**
|
||||
* An implementation of interface CharStream, where the stream is assumed to
|
||||
* contain only ASCII characters (without unicode processing).
|
||||
*/
|
||||
|
||||
public class SimpleCharStream
|
||||
{
|
||||
/** Whether parser is static. */
|
||||
public static final boolean staticFlag = true;
|
||||
static int bufsize;
|
||||
static int available;
|
||||
static int tokenBegin;
|
||||
/** Position in buffer. */
|
||||
static public int bufpos = -1;
|
||||
static protected int bufline[];
|
||||
static protected int bufcolumn[];
|
||||
|
||||
static protected int column = 0;
|
||||
static protected int line = 1;
|
||||
|
||||
static protected boolean prevCharIsCR = false;
|
||||
static protected boolean prevCharIsLF = false;
|
||||
|
||||
static protected java.io.Reader inputStream;
|
||||
|
||||
static protected char[] buffer;
|
||||
static protected int maxNextCharInd = 0;
|
||||
static protected int inBuf = 0;
|
||||
static protected int tabSize = 1;
|
||||
static protected boolean trackLineColumn = true;
|
||||
|
||||
static public void setTabSize(int i) { tabSize = i; }
|
||||
static public int getTabSize() { return tabSize; }
|
||||
|
||||
|
||||
|
||||
static protected void ExpandBuff(boolean wrapAround)
|
||||
{
|
||||
char[] newbuffer = new char[bufsize + 2048];
|
||||
int newbufline[] = new int[bufsize + 2048];
|
||||
int newbufcolumn[] = new int[bufsize + 2048];
|
||||
|
||||
try
|
||||
{
|
||||
if (wrapAround)
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos -= tokenBegin);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new Error(t.getMessage());
|
||||
}
|
||||
|
||||
|
||||
bufsize += 2048;
|
||||
available = bufsize;
|
||||
tokenBegin = 0;
|
||||
}
|
||||
|
||||
static protected void FillBuff() throws java.io.IOException
|
||||
{
|
||||
if (maxNextCharInd == available)
|
||||
{
|
||||
if (available == bufsize)
|
||||
{
|
||||
if (tokenBegin > 2048)
|
||||
{
|
||||
bufpos = maxNextCharInd = 0;
|
||||
available = tokenBegin;
|
||||
}
|
||||
else if (tokenBegin < 0)
|
||||
bufpos = maxNextCharInd = 0;
|
||||
else
|
||||
ExpandBuff(false);
|
||||
}
|
||||
else if (available > tokenBegin)
|
||||
available = bufsize;
|
||||
else if ((tokenBegin - available) < 2048)
|
||||
ExpandBuff(true);
|
||||
else
|
||||
available = tokenBegin;
|
||||
}
|
||||
|
||||
int i;
|
||||
try {
|
||||
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
|
||||
{
|
||||
inputStream.close();
|
||||
throw new java.io.IOException();
|
||||
}
|
||||
else
|
||||
maxNextCharInd += i;
|
||||
return;
|
||||
}
|
||||
catch(java.io.IOException e) {
|
||||
--bufpos;
|
||||
backup(0);
|
||||
if (tokenBegin == -1)
|
||||
tokenBegin = bufpos;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Start. */
|
||||
static public char BeginToken() throws java.io.IOException
|
||||
{
|
||||
tokenBegin = -1;
|
||||
char c = readChar();
|
||||
tokenBegin = bufpos;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static protected void UpdateLineColumn(char c)
|
||||
{
|
||||
column++;
|
||||
|
||||
if (prevCharIsLF)
|
||||
{
|
||||
prevCharIsLF = false;
|
||||
line += (column = 1);
|
||||
}
|
||||
else if (prevCharIsCR)
|
||||
{
|
||||
prevCharIsCR = false;
|
||||
if (c == '\n')
|
||||
{
|
||||
prevCharIsLF = true;
|
||||
}
|
||||
else
|
||||
line += (column = 1);
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r' :
|
||||
prevCharIsCR = true;
|
||||
break;
|
||||
case '\n' :
|
||||
prevCharIsLF = true;
|
||||
break;
|
||||
case '\t' :
|
||||
column--;
|
||||
column += (tabSize - (column % tabSize));
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
bufline[bufpos] = line;
|
||||
bufcolumn[bufpos] = column;
|
||||
}
|
||||
|
||||
/** Read a character. */
|
||||
static public char readChar() throws java.io.IOException
|
||||
{
|
||||
if (inBuf > 0)
|
||||
{
|
||||
--inBuf;
|
||||
|
||||
if (++bufpos == bufsize)
|
||||
bufpos = 0;
|
||||
|
||||
return buffer[bufpos];
|
||||
}
|
||||
|
||||
if (++bufpos >= maxNextCharInd)
|
||||
FillBuff();
|
||||
|
||||
char c = buffer[bufpos];
|
||||
|
||||
UpdateLineColumn(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndColumn
|
||||
*/
|
||||
@Deprecated
|
||||
static public int getColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndLine
|
||||
*/
|
||||
@Deprecated
|
||||
static public int getLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/** Get token end column number. */
|
||||
static public int getEndColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/** Get token end line number. */
|
||||
static public int getEndLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
/** Get token beginning column number. */
|
||||
static public int getBeginColumn() {
|
||||
return bufcolumn[tokenBegin];
|
||||
}
|
||||
|
||||
/** Get token beginning line number. */
|
||||
static public int getBeginLine() {
|
||||
return bufline[tokenBegin];
|
||||
}
|
||||
|
||||
/** Backup a number of characters. */
|
||||
static public void backup(int amount) {
|
||||
|
||||
inBuf += amount;
|
||||
if ((bufpos -= amount) < 0)
|
||||
bufpos += bufsize;
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
if (inputStream != null)
|
||||
throw new Error("\n ERROR: Second call to the constructor of a static SimpleCharStream.\n" +
|
||||
" You must either use ReInit() or set the JavaCC option STATIC to false\n" +
|
||||
" during the generation of this class.");
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.Reader dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
if (buffer == null || buffersize != buffer.length)
|
||||
{
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
prevCharIsLF = prevCharIsCR = false;
|
||||
tokenBegin = inBuf = maxNextCharInd = 0;
|
||||
bufpos = -1;
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.Reader dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
this(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
public SimpleCharStream(java.io.InputStream dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(dstream, encoding, 1, 1, 4096);
|
||||
}
|
||||
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
|
||||
int startcolumn) throws java.io.UnsupportedEncodingException
|
||||
{
|
||||
ReInit(dstream, encoding, startline, startcolumn, 4096);
|
||||
}
|
||||
/** Reinitialise. */
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
/** Get token literal value. */
|
||||
static public String GetImage()
|
||||
{
|
||||
if (bufpos >= tokenBegin)
|
||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
|
||||
else
|
||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
|
||||
new String(buffer, 0, bufpos + 1);
|
||||
}
|
||||
|
||||
/** Get the suffix. */
|
||||
static public char[] GetSuffix(int len)
|
||||
{
|
||||
char[] ret = new char[len];
|
||||
|
||||
if ((bufpos + 1) >= len)
|
||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
|
||||
len - bufpos - 1);
|
||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Reset buffer when finished. */
|
||||
static public void Done()
|
||||
{
|
||||
buffer = null;
|
||||
bufline = null;
|
||||
bufcolumn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to adjust line and column numbers for the start of a token.
|
||||
*/
|
||||
static public void adjustBeginLineColumn(int newLine, int newCol)
|
||||
{
|
||||
int start = tokenBegin;
|
||||
int len;
|
||||
|
||||
if (bufpos >= tokenBegin)
|
||||
{
|
||||
len = bufpos - tokenBegin + inBuf + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
|
||||
}
|
||||
|
||||
int i = 0, j = 0, k = 0;
|
||||
int nextColDiff = 0, columnDiff = 0;
|
||||
|
||||
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
|
||||
{
|
||||
bufline[j] = newLine;
|
||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
columnDiff = nextColDiff;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
bufline[j] = newLine++;
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
|
||||
while (i++ < len)
|
||||
{
|
||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
|
||||
bufline[j] = newLine++;
|
||||
else
|
||||
bufline[j] = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
line = bufline[j];
|
||||
column = bufcolumn[j];
|
||||
}
|
||||
static boolean getTrackLineColumn() { return trackLineColumn; }
|
||||
static void setTrackLineColumn(boolean tlc) { trackLineColumn = tlc; }
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=d21c3936098cd2248ef43da8b436fd21 (do not edit this line) */
|
||||
132
src/JavaCC_CParser/Token.java
Normal file
132
src/JavaCC_CParser/Token.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. Token.java Version 7.0 */
|
||||
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COLUMN=true,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package JavaCC_CParser;
|
||||
|
||||
/**
|
||||
* Describes the input token stream.
|
||||
*/
|
||||
|
||||
public class Token implements java.io.Serializable {
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* An integer that describes the kind of this token. This numbering
|
||||
* system is determined by JavaCCParser, and a table of these numbers is
|
||||
* stored in the file ...Constants.java.
|
||||
*/
|
||||
public int kind;
|
||||
|
||||
/** The line number of the first character of this Token. */
|
||||
public int beginLine;
|
||||
/** The column number of the first character of this Token. */
|
||||
public int beginColumn;
|
||||
/** The line number of the last character of this Token. */
|
||||
public int endLine;
|
||||
/** The column number of the last character of this Token. */
|
||||
public int endColumn;
|
||||
|
||||
/**
|
||||
* The string image of the token.
|
||||
*/
|
||||
public String image;
|
||||
|
||||
/**
|
||||
* A reference to the next regular (non-special) token from the input
|
||||
* stream. If this is the last token from the input stream, or if the
|
||||
* token manager has not read tokens beyond this one, this field is
|
||||
* set to null. This is true only if this token is also a regular
|
||||
* token. Otherwise, see below for a description of the contents of
|
||||
* this field.
|
||||
*/
|
||||
public Token next;
|
||||
|
||||
/**
|
||||
* This field is used to access special tokens that occur prior to this
|
||||
* token, but after the immediately preceding regular (non-special) token.
|
||||
* If there are no such special tokens, this field is set to null.
|
||||
* When there are more than one such special token, this field refers
|
||||
* to the last of these special tokens, which in turn refers to the next
|
||||
* previous special token through its specialToken field, and so on
|
||||
* until the first special token (whose specialToken field is null).
|
||||
* The next fields of special tokens refer to other special tokens that
|
||||
* immediately follow it (without an intervening regular token). If there
|
||||
* is no such token, this field is null.
|
||||
*/
|
||||
public Token specialToken;
|
||||
|
||||
/**
|
||||
* An optional attribute value of the Token.
|
||||
* Tokens which are not used as syntactic sugar will often contain
|
||||
* meaningful values that will be used later on by the compiler or
|
||||
* interpreter. This attribute value is often different from the image.
|
||||
* Any subclass of Token that actually wants to return a non-null value can
|
||||
* override this method as appropriate.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* No-argument constructor
|
||||
*/
|
||||
public Token() {}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image.
|
||||
*/
|
||||
public Token(int kind)
|
||||
{
|
||||
this(kind, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new token for the specified Image and Kind.
|
||||
*/
|
||||
public Token(int kind, String image)
|
||||
{
|
||||
this.kind = kind;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image.
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Token object, by default. However, if you want, you
|
||||
* can create and return subclass objects based on the value of ofKind.
|
||||
* Simply add the cases to the switch for all those special cases.
|
||||
* For example, if you have a subclass of Token called IDToken that
|
||||
* you want to create if ofKind is ID, simply add something like :
|
||||
*
|
||||
* case MyParserConstants.ID : return new IDToken(ofKind, image);
|
||||
*
|
||||
* to the following switch statement. Then you can cast matchedToken
|
||||
* variable to the appropriate type and use sit in your lexical actions.
|
||||
*/
|
||||
public static Token newToken(int ofKind, String image)
|
||||
{
|
||||
switch(ofKind)
|
||||
{
|
||||
default : return new Token(ofKind, image);
|
||||
}
|
||||
}
|
||||
|
||||
public static Token newToken(int ofKind)
|
||||
{
|
||||
return newToken(ofKind, null);
|
||||
}
|
||||
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=093f73b266edc0ed6a424fcd3b5446d1 (do not edit this line) */
|
||||
147
src/JavaCC_CParser/TokenMgrError.java
Normal file
147
src/JavaCC_CParser/TokenMgrError.java
Normal file
@@ -0,0 +1,147 @@
|
||||
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 7.0 */
|
||||
/* JavaCCOptions: */
|
||||
package JavaCC_CParser;
|
||||
|
||||
/** Token Manager Error. */
|
||||
public class TokenMgrError extends Error
|
||||
{
|
||||
|
||||
/**
|
||||
* The version identifier for this Serializable class.
|
||||
* Increment only if the <i>serialized</i> form of the
|
||||
* class changes.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/*
|
||||
* Ordinals for various reasons why an Error of this type can be thrown.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lexical error occurred.
|
||||
*/
|
||||
public static final int LEXICAL_ERROR = 0;
|
||||
|
||||
/**
|
||||
* An attempt was made to create a second instance of a static token manager.
|
||||
*/
|
||||
public static final int STATIC_LEXER_ERROR = 1;
|
||||
|
||||
/**
|
||||
* Tried to change to an invalid lexical state.
|
||||
*/
|
||||
public static final int INVALID_LEXICAL_STATE = 2;
|
||||
|
||||
/**
|
||||
* Detected (and bailed out of) an infinite loop in the token manager.
|
||||
*/
|
||||
public static final int LOOP_DETECTED = 3;
|
||||
|
||||
/**
|
||||
* Indicates the reason why the exception is thrown. It will have
|
||||
* one of the above 4 values.
|
||||
*/
|
||||
int errorCode;
|
||||
|
||||
/**
|
||||
* Replaces unprintable characters by their escaped (or unicode escaped)
|
||||
* equivalents in the given string
|
||||
*/
|
||||
protected static final String addEscapes(String str) {
|
||||
StringBuilder retval = new StringBuilder();
|
||||
char ch;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
switch (str.charAt(i))
|
||||
{
|
||||
case '\b':
|
||||
retval.append("\\b");
|
||||
continue;
|
||||
case '\t':
|
||||
retval.append("\\t");
|
||||
continue;
|
||||
case '\n':
|
||||
retval.append("\\n");
|
||||
continue;
|
||||
case '\f':
|
||||
retval.append("\\f");
|
||||
continue;
|
||||
case '\r':
|
||||
retval.append("\\r");
|
||||
continue;
|
||||
case '\"':
|
||||
retval.append("\\\"");
|
||||
continue;
|
||||
case '\'':
|
||||
retval.append("\\\'");
|
||||
continue;
|
||||
case '\\':
|
||||
retval.append("\\\\");
|
||||
continue;
|
||||
default:
|
||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
|
||||
String s = "0000" + Integer.toString(ch, 16);
|
||||
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
|
||||
} else {
|
||||
retval.append(ch);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return retval.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a detailed message for the Error when it is thrown by the
|
||||
* token manager to indicate a lexical error.
|
||||
* Parameters :
|
||||
* EOFSeen : indicates if EOF caused the lexical error
|
||||
* lexState : lexical state in which this error occurred
|
||||
* errorLine : line number when the error occurred
|
||||
* errorColumn : column number when the error occurred
|
||||
* errorAfter : prefix that was seen before this error occurred
|
||||
* curchar : the offending character
|
||||
* Note: You can customize the lexical error message by modifying this method.
|
||||
*/
|
||||
protected static String LexicalErr(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, int curChar) {
|
||||
return("Lexical error at line " + //
|
||||
errorLine + ", column " + //
|
||||
errorColumn + ". Encountered: " + //
|
||||
(EOFSeen ? "<EOF>" : ("'" + addEscapes(String.valueOf(curChar)) + "' (" + curChar + "),")) + //
|
||||
(errorAfter == null || errorAfter.length() == 0 ? "" : " after prefix \"" + addEscapes(errorAfter) + "\"")) + //
|
||||
(lexState == 0 ? "" : " (in lexical state " + lexState + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* You can also modify the body of this method to customize your error messages.
|
||||
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
|
||||
* of end-users concern, so you can return something like :
|
||||
*
|
||||
* "Internal Error : Please file a bug report .... "
|
||||
*
|
||||
* from this method for such cases in the release version of your parser.
|
||||
*/
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructors of various flavors follow.
|
||||
*/
|
||||
|
||||
/** No arg constructor. */
|
||||
public TokenMgrError() {
|
||||
}
|
||||
|
||||
/** Constructor with message and reason. */
|
||||
public TokenMgrError(String message, int reason) {
|
||||
super(message);
|
||||
errorCode = reason;
|
||||
}
|
||||
|
||||
/** Full Constructor. */
|
||||
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, int curChar, int reason) {
|
||||
this(LexicalErr(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=a4febed657c4dc3b56056b602e429de4 (do not edit this line) */
|
||||
468
src/JavaScripts.java
Normal file
468
src/JavaScripts.java
Normal file
@@ -0,0 +1,468 @@
|
||||
|
||||
public class JavaScripts {
|
||||
|
||||
public static String getAllOtherJSLiveData(String prefix) {
|
||||
String retVal =
|
||||
prefix + "//MARK: File Logger\n"
|
||||
+ prefix + "const fileSizeText = document.querySelector(\".logging-file-size\");\n"
|
||||
+ prefix + "const fileSize = fileSizeText.querySelector(\".size\");\n"
|
||||
+ prefix + "const fileSizeUnits = fileSizeText.querySelector(\".units\");\n"
|
||||
+ prefix + "const saveLoggingInfo = document.getElementById('loggingCheckbox');\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "var logStreamController = undefined;\n"
|
||||
+ prefix + "var logStream = undefined;\n"
|
||||
+ prefix + "var logBlobSize = undefined;\n"
|
||||
+ prefix + "var sizeUpdater = undefined;\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const csvKeys = Object.keys(statusObject);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function getHeader() { //Creates a csv header for the log file\n"
|
||||
+ prefix + " var line = \"recNum\";\n"
|
||||
+ prefix + " csvKeys.forEach(key => {\n"
|
||||
+ prefix + " line += \",\" + key;\n"
|
||||
+ prefix + " });\n"
|
||||
+ prefix + " line += \"\\n\";\n"
|
||||
+ prefix + " return line;\n"
|
||||
+ prefix + "};\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const stringEncoder = new TextEncoder();\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function logStreamEnqueueString(string) {\n"
|
||||
+ prefix + " if (logStreamController !== undefined) {\n"
|
||||
+ prefix + " const array = stringEncoder.encode(string);\n"
|
||||
+ prefix + " logBlobSize += array.length;\n"
|
||||
+ prefix + " logStreamController.enqueue(array);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function setSize(bytes) {\n"
|
||||
+ prefix + " const numBytes = Number(bytes);\n"
|
||||
+ prefix + " if (numBytes > 1024*1024) {\n"
|
||||
+ prefix + " fileSize.innerHTML = (numBytes / 1024 / 1024).toFixed(1);\n"
|
||||
+ prefix + " fileSizeUnits.innerHTML = 'MiB';\n"
|
||||
+ prefix + " } else if (numBytes > 1024) {\n"
|
||||
+ prefix + " fileSize.innerHTML = (numBytes / 1024).toFixed(1);\n"
|
||||
+ prefix + " fileSizeUnits.innerHTML = 'KiB';\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " fileSize.innerHTML = numBytes;\n"
|
||||
+ prefix + " fileSizeUnits.innerHTML = 'B';\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function streamData(number, data) {\n"
|
||||
+ prefix + " if (data !== undefined) {\n"
|
||||
+ prefix + " //parse data into csv line\n"
|
||||
+ prefix + " var line = String(number);\n"
|
||||
+ prefix + " csvKeys.forEach(key => {\n"
|
||||
+ prefix + " if (data.hasOwnProperty(key)) {\n"
|
||||
+ prefix + " line += \",\" + data[key];\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " line += \",\";\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " });\n"
|
||||
+ prefix + " line += \"\\n\";\n"
|
||||
+ prefix + " logStreamEnqueueString(line);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function createStream( ) {\n"
|
||||
+ prefix + " logStream = new ReadableStream({\n"
|
||||
+ prefix + " start(controller) {\n"
|
||||
+ prefix + " logStreamController = controller;\n"
|
||||
+ prefix + " logBlobSize = 0;\n"
|
||||
+ prefix + " logStreamEnqueueString(getHeader());\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " sizeUpdater = setInterval(() => {\n"
|
||||
+ prefix + " if (logStreamController === undefined) {\n"
|
||||
+ prefix + " setSize(0);\n"
|
||||
+ prefix + " clearInterval(sizeUpdater);\n"
|
||||
+ prefix + " } else if (logBlobSize > 50*1024*1024) {\n"
|
||||
+ prefix + " console.log(\"Logging: Max size reached for this file\");\n"
|
||||
+ prefix + " closeStream();\n"
|
||||
+ prefix + " clearInterval(sizeUpdater);\n"
|
||||
+ prefix + " downloadLogFile();\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " setSize(logBlobSize);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }, 500); // Enqueue a chunk every half second\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " this.cancel = () => {\n"
|
||||
+ prefix + " clearInterval(sizeUpdater);\n"
|
||||
+ prefix + " console.log('Logging: Stream cancelled!');\n"
|
||||
+ prefix + " };\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " pull(controller) { },\n"
|
||||
+ prefix + " cancel() {\n"
|
||||
+ prefix + " // The cleanup logic defined in 'start' will be executed here.\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " });\n"
|
||||
+ prefix + "};\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function closeStream( ) {\n"
|
||||
+ prefix + " if (logStreamController != undefined) {\n"
|
||||
+ prefix + " logStreamController.close();\n"
|
||||
+ prefix + " logStreamController = undefined;\n"
|
||||
+ prefix + " logStream = undefined;\n"
|
||||
+ prefix + " logBlobSize = undefined;\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "async function downloadLogFile() {\n"
|
||||
+ prefix + " //Create the stream for the blob\n"
|
||||
+ prefix + " createStream();\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " try {\n"
|
||||
+ prefix + " // Convert ReadableStream to Blob\n"
|
||||
+ prefix + " const blob = await new Response(logStream).blob();\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + " // Create a Blob URL\n"
|
||||
+ prefix + " const fileURL = URL.createObjectURL(blob);\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + " // Create a download link\n"
|
||||
+ prefix + " const downloadLink = document.createElement('a');\n"
|
||||
+ prefix + " downloadLink.href = fileURL;\n"
|
||||
+ prefix + " downloadLink.download = \"obwb8m-Log.csv\";\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " // Append and click the link to trigger download\n"
|
||||
+ prefix + " document.body.appendChild(downloadLink);\n"
|
||||
+ prefix + " downloadLink.click();\n"
|
||||
+ prefix + " console.log(fileURL);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " // Clean up the Blob URL\n"
|
||||
+ prefix + " URL.revokeObjectURL(fileURL);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " // Remove the download link\n"
|
||||
+ prefix + " document.body.removeChild(downloadLink);\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + " } catch (error) {\n"
|
||||
+ prefix + " console.error('Error downloading file:', error);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//MARK: Non-Generated\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//Status string list\n"
|
||||
+ prefix + "const SENSOR_DISABLED = parse_WBSensorStatus_t(0, null);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//Chart js stuff\n"
|
||||
+ prefix + "const statusCTX = document.getElementById('LambdaChart');\n"
|
||||
+ prefix + "const afrCTX = document.getElementById('AFRChart');\n"
|
||||
+ prefix + "window.labelCounter = 0;\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//Diagnostic stuff\n"
|
||||
+ prefix + "const diagnosticCheckbox = document.getElementById(\"diagnosticCheckbox\");\n"
|
||||
+ prefix + "const diagnosticInfo = document.querySelector(\".diagnostic-info\");\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "diagnosticCheckbox.addEventListener('change', () => {\n"
|
||||
+ prefix + " diagnosticInfo.style.display = diagnosticCheckbox.checked ? \"block\" : \"none\";\n"
|
||||
+ prefix + "});\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const updateSensorVisibility = (sensorItem, chart) => {\n"
|
||||
+ prefix + " if (sensorItem !== null) {\n"
|
||||
+ prefix + " const statusValue = sensorItem.querySelector(\".sensor-status\").querySelector(\".value\").innerHTML;\n"
|
||||
+ prefix + " const sensorName = sensorItem.querySelector(\".sensor-name\").id;\n"
|
||||
+ prefix + " const showDataset = statusValue !== SENSOR_DISABLED;\n"
|
||||
+ prefix + " const datasetIndex = chart.data.datasets.findIndex(item => item.label === sensorName); //output -1 if not found\n"
|
||||
+ prefix + " if (datasetIndex >= 0) {\n"
|
||||
+ prefix + " chart.setDatasetVisibility(datasetIndex, showDataset);\n"
|
||||
+ prefix + " chart.update(); //updates the chart with the new visibility setting\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "};\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//------------------------ Setup ------------------------//\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + "const data = () => {\n"
|
||||
+ prefix + " return {\n"
|
||||
+ prefix + " //labels: [1, 2, 3, 4, 5, 6],\n"
|
||||
+ prefix + " labels: [],\n"
|
||||
+ prefix + " datasets: [\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " //data: [101, 102, 95, 83, 87, 78],\n"
|
||||
+ prefix + " label: 'Sensor 1',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 2',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 3',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 4',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 5',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 6',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 7',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " {\n"
|
||||
+ prefix + " label: 'Sensor 8',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " ]//datasets\n"
|
||||
+ prefix + " };\n"
|
||||
+ prefix + "};\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + "//------------------------ Config ------------------------//\n"
|
||||
+ prefix + "const chartConfig = (title, xLabel, yLabel, ) => {\n"
|
||||
+ prefix + " return {\n"
|
||||
+ prefix + " type: 'line',\n"
|
||||
+ prefix + " data: data(),\n"
|
||||
+ prefix + " options: {\n"
|
||||
+ prefix + " responsive: true,\n"
|
||||
+ prefix + " // animation: true, //causes slower data transfer\n"
|
||||
+ prefix + " animation: false,\n"
|
||||
+ prefix + " scales: {\n"
|
||||
+ prefix + " x: {\n"
|
||||
+ prefix + " title: {\n"
|
||||
+ prefix + " display: xLabel == undefined ? false : true,\n"
|
||||
+ prefix + " text: xLabel,\n"
|
||||
+ prefix + " font: {\n"
|
||||
+ prefix + " size: 20\n"
|
||||
+ prefix + " }//font\n"
|
||||
+ prefix + " },//title\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " y: {\n"
|
||||
+ prefix + " title: {\n"
|
||||
+ prefix + " display: yLabel == undefined ? false : true,\n"
|
||||
+ prefix + " text: yLabel,\n"
|
||||
+ prefix + " font: {\n"
|
||||
+ prefix + " size: 20\n"
|
||||
+ prefix + " }//font\n"
|
||||
+ prefix + " },//title \n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " },//scales\n"
|
||||
+ prefix + " plugins: {\n"
|
||||
+ prefix + " tooltip: {\n"
|
||||
+ prefix + " intersect: false,\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " legend: {\n"
|
||||
+ prefix + " position: 'top',\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " title: {\n"
|
||||
+ prefix + " display: title == undefined ? false : true,\n"
|
||||
+ prefix + " text: title,\n"
|
||||
+ prefix + " font: {\n"
|
||||
+ prefix + " size: 20\n"
|
||||
+ prefix + " },//font\n"
|
||||
+ prefix + " }//title\n"
|
||||
+ prefix + " },//plugins\n"
|
||||
+ prefix + " elements: {\n"
|
||||
+ prefix + " point: {\n"
|
||||
+ prefix + " radius: 0,\n"
|
||||
+ prefix + " hitRadius: 10,\n"
|
||||
+ prefix + " // boarderWidth: 4,\n"
|
||||
+ prefix + " },\n"
|
||||
+ prefix + " // line: {\n"
|
||||
+ prefix + " // tension: 0\n"
|
||||
+ prefix + " // },\n"
|
||||
+ prefix + " },//elements\n"
|
||||
+ prefix + " },//options\n"
|
||||
+ prefix + " };\n"
|
||||
+ prefix + "};"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "window.LambdaChart = new Chart(statusCTX, chartConfig(\"Lambda\", undefined, \"Lambda (Units)\"));\n"
|
||||
+ prefix + "window.AFRChart = new Chart(afrCTX, chartConfig(\"AFR\", undefined, \"AFR (Units)\"));\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//MARK: ONLY do this initially for now\n"
|
||||
+ prefix + "const sensorList = document.querySelector(\".sensor-status-list\");\n"
|
||||
+ prefix + "const sensors = sensorList.querySelectorAll('.sensor-item'); //Get list of all sensor-items\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//Get the first data then wait until finsihed to check the visibilities\n"
|
||||
+ prefix + "requestStatus().then(() => { //NOTE recording should be false otherwise starts infinite loop\n"
|
||||
+ prefix + " sensors.forEach((child) => {\n"
|
||||
+ prefix + " updateSensorVisibility(child, window.LambdaChart);\n"
|
||||
+ prefix + " updateSensorVisibility(child, window.AFRChart);\n"
|
||||
+ prefix + " });\n"
|
||||
+ prefix + "});\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function addData(data, key, dataset) {\n"
|
||||
+ prefix + " if (data.hasOwnProperty(key)) {\n"
|
||||
+ prefix + " dataset.data.push(data[key]);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function updateSenorItem(data, key, id) {\n"
|
||||
+ prefix + " if (data.hasOwnProperty(key)) {\n"
|
||||
+ prefix + " const item = document.getElementById(id);\n"
|
||||
+ prefix + " if (item !== null) {\n"
|
||||
+ prefix + " if (item.classList.contains('sensor-status')) {\n"
|
||||
+ prefix + " item.querySelector(\".value\").innerHTML = parse_WBSensorStatus_t(data[key]);\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " item.querySelector(\".value\").innerHTML = data[key];\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function addLiveData(value, id, chartName, datasetIndex) {\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " //Add the data to the dataset\n"
|
||||
+ prefix + " if (window[chartName] !== undefined) {\n"
|
||||
+ prefix + " const dataset = window[chartName].data.datasets[datasetIndex];\n"
|
||||
+ prefix + " if (dataset !== null) {\n"
|
||||
+ prefix + " dataset.data.push(value);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " //Update the html to see\n"
|
||||
+ prefix + " const item = document.getElementById(id);\n"
|
||||
+ prefix + " if (item !== null) {\n"
|
||||
+ prefix + " item.querySelector(\".value\").innerHTML = value;\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function enableClearButton( enable ) {\n"
|
||||
+ prefix + " const buttonBox = document.querySelector(\".clear-box\")\n"
|
||||
+ prefix + " if (buttonBox !== null) {\n"
|
||||
+ prefix + " buttonBox.style.display = enable ? \"block\" : \"none\";\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const clearDataset = (dataset) => {\n"
|
||||
+ prefix + " while(dataset.data.length > 0) {\n"
|
||||
+ prefix + " dataset.data.pop();\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "};\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const deleteLabels = (chart) => {\n"
|
||||
+ prefix + " chart.data.labels.splice(0);\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function clearData( ) {\n"
|
||||
+ prefix + " LambdaChart.data.datasets.forEach(clearDataset);\n"
|
||||
+ prefix + " deleteLabels(LambdaChart);\n"
|
||||
+ prefix + " LambdaChart.update();\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " AFRChart.data.datasets.forEach(clearDataset);\n"
|
||||
+ prefix + " deleteLabels(AFRChart);\n"
|
||||
+ prefix + " AFRChart.update();\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " labelCounter = 0;\n"
|
||||
+ prefix + " enableClearButton(false);\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "const recordingButton = document.getElementById('StartStopButton');\n"
|
||||
+ prefix + "const refreshTitle = document.getElementById('refreshTitle');\n"
|
||||
+ prefix + "const refreshValue = document.getElementById('refreshRate');\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "let recording = false;\n"
|
||||
+ prefix + "let lastRefresh = Date.now(); //times are in milliseconds\n"
|
||||
+ prefix + "let refreshTimeQueue = []; //implemented using an array, shift = dequeue, push = enqueue, length gives size\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "recordingButton.addEventListener('click', (event) => {\n"
|
||||
+ prefix + " recording = !recording; //toggle recording\n"
|
||||
+ prefix + " recordingButton.innerHTML = recording ? 'Stop Recording' : 'Start Recording'; //Change the text reflecting current state\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " if (recording) {\n"
|
||||
+ prefix + " requestStatus();\n"
|
||||
+ prefix + " if (saveLoggingInfo.checked) {\n"
|
||||
+ prefix + " downloadLogFile();\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " closeStream();\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "});\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "saveLoggingInfo.addEventListener('click', () => {\n"
|
||||
+ prefix + " if (saveLoggingInfo.checked && recording) {\n"
|
||||
+ prefix + " downloadLogFile();\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " closeStream();\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "});\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "function updateRefreshRate() {\n"
|
||||
+ prefix + " const savedNum = 20;\n"
|
||||
+ prefix + " lastRefresh = Date.now();\n"
|
||||
+ prefix + " let longestTime = lastRefresh;\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " refreshTimeQueue.push(lastRefresh);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " if (refreshTimeQueue.length > 1) {\n"
|
||||
+ prefix + " while (refreshTimeQueue.length > savedNum) {\n"
|
||||
+ prefix + " longestTime = refreshTimeQueue.shift();\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " if (refreshTimeQueue.length <= savedNum) {\n"
|
||||
+ prefix + " longestTime = refreshTimeQueue[0];\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " refreshValue.innerHTML = (refreshTimeQueue.length * 1000 / (lastRefresh - longestTime)).toFixed(1); // f = 1/T, and 1 ms = 1000 Hz\n"
|
||||
+ prefix + " } else {\n"
|
||||
+ prefix + " refreshValue.innerHTML = 0;\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "async function requestStatus() {\n"
|
||||
+ prefix + " do {\n"
|
||||
+ prefix + " const url = diagnosticCheckbox.checked ? \"/statusDiagnostic.json\" : \"/status.json\";\n"
|
||||
+ prefix + " try {\n"
|
||||
+ prefix + " const response = await fetch(url);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " if (!response.ok)\n"
|
||||
+ prefix + " throw new Error(`HTTP error! status: ${response.status}`);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " const data = await response.json();\n"
|
||||
+ prefix + " parseVariables(data);\n"
|
||||
+ prefix + " updateRefreshRate();\n"
|
||||
+ prefix + " enableClearButton(true);\n"
|
||||
+ prefix + " if (saveLoggingInfo.checked)\n"
|
||||
+ prefix + " streamData(window.labelCounter, data);\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + " } catch (error) {\n"
|
||||
+ prefix + " console.error('Error fetching data:', error);\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " } while (recording);\n"
|
||||
+ prefix + "}\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "\n"
|
||||
+ prefix + "//data is a json object\n"
|
||||
+ prefix + "async function parseVariables(dataObject) {\n"
|
||||
+ prefix + " //update chart number of labels\n"
|
||||
+ prefix + " window.LambdaChart.data.labels.push(window.labelCounter); //Add the label for the data\n"
|
||||
+ prefix + " window.AFRChart.data.labels.push(window.labelCounter); //Add the label for the data\n"
|
||||
+ prefix + " window.labelCounter++; //increase label counter for next label\n"
|
||||
+ prefix + " \n"
|
||||
+ prefix + " const entries = Object.entries(dataObject);\n"
|
||||
+ prefix + " for (let [key,value] of entries) {\n"
|
||||
+ prefix + " if (statusObject.hasOwnProperty(key)) {\n"
|
||||
+ prefix + " const item = document.getElementById(key);\n"
|
||||
+ prefix + " if (item !== null) {\n"
|
||||
+ prefix + " item.querySelector(\".value\").innerHTML = statusObject[key](value, key); //use predefined function\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }\n"
|
||||
+ prefix + " }//for loop\n"
|
||||
+ prefix + " //update chart\n"
|
||||
+ prefix + " window.LambdaChart.update();\n"
|
||||
+ prefix + " window.AFRChart.update();\n"
|
||||
+ prefix + "}//parseVariable\n";
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
220
src/Sitemap.java
Normal file
220
src/Sitemap.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Jakob Oberbuchner 2025
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Sitemap {
|
||||
|
||||
public ArrayList<Webpage> pageList;
|
||||
// usual getters and setters
|
||||
|
||||
// public Sitemap( ) {
|
||||
// this.pageList = new ArrayList<Webpage>();
|
||||
// }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param path: a URL path to the file
|
||||
* @param name: name of the file ie. "sitemap.xml"
|
||||
*/
|
||||
public Sitemap(String path, String name) {
|
||||
this.pageList = new ArrayList<Webpage>();
|
||||
|
||||
try {
|
||||
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
WebsiteHandler websiteHandler = new WebsiteHandler(this);
|
||||
|
||||
//Goes through the file, and parses the data
|
||||
saxParser.parse(path + "/sitemap.xml", websiteHandler);
|
||||
|
||||
// Sitemap result = websiteHandler.getSitemap(); //Returns this
|
||||
|
||||
// ArrayList<Webpage> pages = result.getPageList();
|
||||
|
||||
|
||||
// for(int i = 0; i < pageList.size(); i++) {
|
||||
// Webpage articleOne = pageList.get(i);
|
||||
// System.out.println(articleOne.getURL());
|
||||
// System.out.println(articleOne.getLastModified());
|
||||
// System.out.println();
|
||||
// }
|
||||
|
||||
|
||||
} catch (ParserConfigurationException e) {
|
||||
System.out.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (SAXException e) {
|
||||
System.out.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println("Cannot open or find the sitemap.xml file!!!!!");
|
||||
System.out.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<Webpage> getPageList() {
|
||||
return pageList;
|
||||
}
|
||||
|
||||
public void setPageList(ArrayList<Webpage> pageList) {
|
||||
this.pageList = pageList;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * @param args: args[0] the URL to the folder containing the sitemap.xml
|
||||
// */
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// try {
|
||||
//
|
||||
// SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
// SAXParser saxParser = factory.newSAXParser();
|
||||
// WebsiteHandler websiteHandler = new WebsiteHandler();
|
||||
//
|
||||
// //Goes through the file, and parses the data
|
||||
// saxParser.parse(args[0] + "sitemap.xml", websiteHandler);
|
||||
//
|
||||
// Website result = websiteHandler.getWebsite();
|
||||
//
|
||||
// ArrayList<Webpage> pages = result.getPageList();
|
||||
//
|
||||
// for(int i = 0; i < pages.size(); i++) {
|
||||
// Webpage articleOne = pages.get(i);
|
||||
// System.out.println(articleOne.getURL());
|
||||
// System.out.println(articleOne.getLastModified());
|
||||
// System.out.println();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// } catch (ParserConfigurationException e) {
|
||||
// System.out.println(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
//
|
||||
// } catch (SAXException e) {
|
||||
// System.out.println(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// System.out.println("Cannot open or find the sitemap.xml file!!!!!");
|
||||
// System.out.println(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }//main
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//class Website {
|
||||
// public ArrayList<Webpage> pageList;
|
||||
// // usual getters and setters
|
||||
//
|
||||
// public Website() {
|
||||
// this.pageList = new ArrayList<Webpage>();
|
||||
// }
|
||||
//
|
||||
// public ArrayList<Webpage> getPageList() {
|
||||
// return pageList;
|
||||
// }
|
||||
//
|
||||
// public void setPageList(ArrayList<Webpage> pageList) {
|
||||
// this.pageList = pageList;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
|
||||
class WebsiteHandler extends DefaultHandler {
|
||||
|
||||
private static final String LOCATION = "loc";
|
||||
private static final String URL = "url";
|
||||
private static final String LASTMODIFIED = "lastmod";
|
||||
// private static final String CONTENT = "content";
|
||||
|
||||
private Sitemap sitemap;
|
||||
private StringBuilder elementValue;
|
||||
|
||||
public WebsiteHandler( Sitemap sitemap ) {
|
||||
this.sitemap = sitemap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
if (elementValue == null) {
|
||||
elementValue = new StringBuilder();
|
||||
} else {
|
||||
elementValue.append(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
// sitemap = new Sitemap();
|
||||
//Do nothing for now
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String lName, String qName, Attributes attr) throws SAXException {
|
||||
switch (qName) {
|
||||
case URL:
|
||||
sitemap.pageList.add(new Webpage());
|
||||
break;
|
||||
case LOCATION:
|
||||
elementValue = new StringBuilder();
|
||||
break;
|
||||
case LASTMODIFIED:
|
||||
elementValue = new StringBuilder();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
switch (qName) {
|
||||
case LOCATION:
|
||||
latestpage().setURL(elementValue.toString());
|
||||
break;
|
||||
case LASTMODIFIED:
|
||||
latestpage().setLastModified(elementValue.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Webpage latestpage() {
|
||||
ArrayList<Webpage> pageList = sitemap.pageList;
|
||||
int latestArticleIndex = pageList.size() - 1;
|
||||
return pageList.get(latestArticleIndex);
|
||||
}
|
||||
|
||||
public Sitemap getSitemap() {
|
||||
return sitemap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
145
src/Webpage.java
Normal file
145
src/Webpage.java
Normal file
@@ -0,0 +1,145 @@
|
||||
import java.io.File;
|
||||
|
||||
|
||||
enum WebpageType {
|
||||
CSS,
|
||||
HTML,
|
||||
JS,
|
||||
IMAGE;
|
||||
|
||||
public final static String[] supportedExtensions = {".css", ".html", ".js", ".jpg", ".jpeg", ".png"};
|
||||
private final static String[] supportedImageExtensions = {".jpg", ".jpeg", ".png"};
|
||||
private String imageExtension = ".jpg";
|
||||
|
||||
public String getExtensionName() {
|
||||
switch (this) {
|
||||
case CSS:
|
||||
return "css";
|
||||
case HTML:
|
||||
return "html";
|
||||
case JS:
|
||||
return "javascript";
|
||||
case IMAGE:
|
||||
return imageExtension.replace(".", "");
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static WebpageType getType(String extension) {
|
||||
WebpageType type = null;
|
||||
|
||||
if (extension.length() <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (extension.charAt(0) != '.') {
|
||||
extension = "." + extension;
|
||||
}
|
||||
|
||||
switch ( extension ) {
|
||||
case ".css":
|
||||
type = CSS;
|
||||
break;
|
||||
|
||||
case ".html":
|
||||
type = HTML;
|
||||
break;
|
||||
|
||||
case ".js":
|
||||
type = JS;
|
||||
break;
|
||||
|
||||
default:
|
||||
for(int i = 0; i < supportedImageExtensions.length; i++) {
|
||||
if (supportedImageExtensions[i].equals(extension)) {
|
||||
type = IMAGE;
|
||||
type.imageExtension = extension;
|
||||
break;
|
||||
}
|
||||
}//for
|
||||
}
|
||||
|
||||
return type;
|
||||
}//getType
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class Webpage {
|
||||
private String url;
|
||||
private String lastModified;
|
||||
private WebpageType type = WebpageType.HTML;
|
||||
private File file;
|
||||
private boolean requireLogin = true; // True if the user can only access this page after log in
|
||||
private boolean passwordProtected = false; //If true the user must enter a specific password to gain access
|
||||
|
||||
public Webpage( ) {
|
||||
this.url = null;
|
||||
this.lastModified = null;
|
||||
}
|
||||
|
||||
public Webpage(String url, File file) {
|
||||
this.url = url;
|
||||
this.lastModified = null;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public Webpage(String url, String lastModified) {
|
||||
this.url = url;
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public void setProtected(boolean protectedFile) {
|
||||
this.passwordProtected = protectedFile;
|
||||
}
|
||||
|
||||
public void setRequireLogin(boolean required) {
|
||||
this.requireLogin = required;
|
||||
}
|
||||
|
||||
public boolean loginRequired() {
|
||||
return this.requireLogin;
|
||||
}
|
||||
|
||||
public boolean isPasswordProtected() {
|
||||
return this.passwordProtected;
|
||||
}
|
||||
|
||||
public String getURLNoExt() {
|
||||
return url.substring(0, url.lastIndexOf("."));
|
||||
// return url;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
// usual getters and setters
|
||||
public String getURL() {
|
||||
return url;
|
||||
}
|
||||
public void setURL(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
public String getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
public void setLastModified(String lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public String getVariableName( ) {
|
||||
return "a_" + url.replaceAll("\\W", ""); //Remove non-word characters from the string
|
||||
}
|
||||
|
||||
public void setType(WebpageType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public WebpageType getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
1666
src/WebsiteParser.java
Normal file
1666
src/WebsiteParser.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user