Browse Source

Parser is complete, and a test-suite was added

master
despair 1 year ago
parent
commit
475a29e4cc
7 changed files with 108 additions and 6 deletions
  1. 2
    0
      .gitignore
  2. 6
    0
      Makefile
  3. 7
    1
      NTMakefile
  4. 8
    4
      src/CFGFileParser.cpp
  5. 3
    0
      src/CFGFileParser.h
  6. 4
    1
      src/netrunner.h
  7. 78
    0
      tests/TestCFG.cpp

+ 2
- 0
.gitignore View File

@@ -26,3 +26,5 @@ NetRunner2008.ncb
/libfreetype-6.dll
/libharfbuzz-0.dll
/out.txt
ntr-test-cfg.exe
*.o

+ 6
- 0
Makefile View File

@@ -72,6 +72,12 @@ test-url.o: tests/testPrograms/URLtest.cpp
ntr-run-tests: test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o
$(LINK) $(LDFLAGS) -o $@ test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o $(LIBS)

ntr-test-cfg: test-cfg.o $(OBJDIR)/CFGFileParser.o $(OBJDIR)/slre.o $(OBJDIR)/tlsf.o $(OBJDIR)/Murmur3.o
$(LINK) $(LDFLAGS) -o $@ $^ $(LIBS)

test-cfg.o: tests/TestCFG.cpp
$(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -Isrc $(INCPATH) -DDEBUG $(WARNINGS) -c -o $@ $<

clean:
-@rm -rf $(OBJDIR) $(EXECUTABLE) 2>/dev/null || true


+ 7
- 1
NTMakefile View File

@@ -102,11 +102,17 @@ $(DEPDIR)/%d: ;
.PRECIOUS: $(DEPDIR)/%.d
test-url.o: tests/testPrograms/URLtest.cpp
$(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) $(WARINGS) -c -o $@ $<
$(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) $(INCPATH) $(WARNINGS) -c -o $@ $<
test-cfg.o: tests/TestCFG.cpp
$(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -Isrc $(INCPATH) -DDEBUG $(WARNINGS) -c -o $@ $<
ntr-run-tests: test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o
$(LINK) $(LDFLAGS) -o $@ test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o $(LIBS)
ntr-test-cfg: test-cfg.o $(OBJDIR)/CFGFileParser.o $(OBJDIR)/slre.o $(OBJDIR)/tlsf.o $(OBJDIR)/Murmur3.o
$(LINK) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
-@rm -rf src/graphics/opengl/shaders/gen $(OBJDIR) $(EXECUTABLE) 2>/dev/null || true

+ 8
- 4
src/CFGFileParser.cpp View File

@@ -10,7 +10,6 @@ CFGFileParser::CFGFileParser(const char* filename){
cfg_file = fopen(filename, "rb"); // On NT, opening in text mode translates \n into \r\n
stat(filename, cfg_fileinfo);
buffer = static_cast<char*>(tlsf_malloc(cfg_fileinfo->st_size & INT_MAX));
cfg = new BrowserConfiguration();
bytesRead = fread(buffer, sizeof(char) & INT_MAX, cfg_fileinfo->st_size & INT_MAX, cfg_file);
if (!bytesRead) {
std::cout << "no config" << std::endl;
@@ -18,6 +17,11 @@ CFGFileParser::CFGFileParser(const char* filename){
fclose(cfg_file);
}

CFGFileParser::CFGFileParser(ntr::fast_string in_buf){
buffer = static_cast<char*>(tlsf_malloc(strlen(in_buf.c_str()) & INT_MAX));
strcpy(buffer, in_buf.c_str());
}

CFGFileParser::~CFGFileParser(){
// clean up!
// This buffer has been written to and co-opted by
@@ -47,8 +51,8 @@ bool CFGFileParser::ParseText() {
token = strtok_r(nullptr, "\n", &tmp);
}
else if (!isalpha(token[0])){ // The leading character is NOT a #, ., <LF>, or a letter. NB: Leading numbers are also invalid.
printf("ERROR: Config file is invalid\n");
printf("%s\n",token);
printf("ERROR: Config file is invalid: ");
printf("\"%s\"\n",token);
return false;
}
else {
@@ -57,7 +61,7 @@ bool CFGFileParser::ParseText() {
return false;
}
if (!slre_match(&regex, token, strlen(token), nullptr)){
printf("Invalid directive: %s\n", token); // regex matches DIREC[_]T[I1]VE:[token] but NOT directive:[token] - the directive MUST be all caps
printf("Invalid directive: \"%s\"\n", token); // regex matches DiReC[_]T[I1]VE:[token], it simply cannot start with a number or symbol.
return false;
}
// Config directive found, add to second-pass buffer

+ 3
- 0
src/CFGFileParser.h View File

@@ -24,7 +24,10 @@ struct BrowserConfiguration{

class CFGFileParser {
public:
// Opens config from external file.
CFGFileParser(const char* filename);
// Opens config from memory.
CFGFileParser(ntr::fast_string in_buf);
~CFGFileParser();
bool ParseText();
void WriteConfig(BrowserConfiguration &config);

+ 4
- 1
src/netrunner.h View File

@@ -1,4 +1,6 @@
// ©2008-2017 despair <despair@netrunner.cc>
#ifndef NETRUNNER_H
#define NETRUNNER_H
#include "Murmur3.h"
#include <string>
#include <unordered_map>
@@ -137,4 +139,5 @@ namespace ntr{
};
typedef std::unordered_map<fast_string,fast_string,StringHash,StringComparison,TLSFAlloc<std::pair<const fast_string, fast_string>>> stringmap;
}
}
#endif

+ 78
- 0
tests/TestCFG.cpp View File

@@ -0,0 +1,78 @@
#include "netrunner.h"
#include "CFGFileParser.h"
#ifdef _WIN32
extern "C"{void init_heap();}
#endif
int main(void){
#ifdef _WIN32
init_heap();
#endif
// test vectors
// This is our reference, should always be valid.
ntr::fast_string buf1 = "# This is a comment.\n.This is a formatting directive.\n# The following is a valid directive:\nHOMEPAGE:[http://motherfuckingwebsite.com]\n# Another comment.";
// Leading number.
ntr::fast_string buf2 = "# This is a comment.\n.This is a formatting directive.\n# Not a valid directive:\n4chan:[sometext here]\n# Still another comment.";
// Lowercase letters. Also a valid directive.
ntr::fast_string buf3 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:[ssometext]\n# One more comment.";
// Unescaped comment.
ntr::fast_string buf4 = "# A comment.\nUnescaped comment!\n# A valid comment.\n\n# The following directive is untouched, since the parser SHOULD have quit earlier:\nBUGURL:[http://rvx86.net]\n# One final comment.";
// Old-style Lynx directive. Invalid here.
ntr::fast_string buf5 = "# This is a comment.\n.This is a formatting directive.\n# The following is a valid directive in Lynx, but not for NetRunner:\nHOMEPAGE:http://motherfuckingwebsite.com\n# Another comment.";
// Invalid leading character.
ntr::fast_string buf6 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\n^bad_directive:[ssometext]\n# One more comment.";
// The casts LOOK useless, but they're not.
CFGFileParser test1(buf1);
CFGFileParser test2(buf2);
CFGFileParser test3(buf3);
CFGFileParser test4(buf4);
CFGFileParser test5(buf5);
CFGFileParser test6(buf6);
puts("CFG Parser Test for /ntr/\n<despair@netrunner.cc>\n");
if (test1.ParseText()){
puts("Test 1 passed. This is the reference string.\n");
}
else{
puts("Test 1 FAILED!\n");
}
if (test2.ParseText()){
puts("Test 2 passed.\n");
}
else{
puts("Test 2 FAILED: see above\nDirectives must not begin with a number.\n");
}
if (test3.ParseText()){
puts("Test 3 passed. Mixed-case directives are valid.\n");
}
else{
puts("Test 3 FAILED: see above\n");
}
if (test4.ParseText()){
puts("Test 4 passed.\n");
}
else{
puts("Test 4 FAILED: see above\nA stray comment.\n");
}
if (test5.ParseText()){
puts("Test 5 passed.");
}
else{
puts("Test 5 FAILED: see above\nOld-style Lynx CFG directive. No longer valid here.\n");
}
if (test6.ParseText()){
puts("Test 6 passed.");
}
else{
puts("Test 6 FAILED: see above\nLeading non-alpha symbol\n");
}
return 0;
}

Loading…
Cancel
Save