Browse Source

Parser is complete, and a test-suite was added

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
26 26
 /libfreetype-6.dll
27 27
 /libharfbuzz-0.dll
28 28
 /out.txt
29
+ntr-test-cfg.exe
30
+*.o

+ 6
- 0
Makefile View File

@@ -72,6 +72,12 @@ test-url.o: tests/testPrograms/URLtest.cpp
72 72
 ntr-run-tests: test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o
73 73
 	$(LINK) $(LDFLAGS) -o $@ test-url.o $(OBJDIR)/URL.o $(OBJDIR)/StringUtils.o $(LIBS)
74 74
 
75
+ntr-test-cfg: test-cfg.o $(OBJDIR)/CFGFileParser.o $(OBJDIR)/slre.o $(OBJDIR)/tlsf.o $(OBJDIR)/Murmur3.o
76
+	$(LINK) $(LDFLAGS) -o $@ $^ $(LIBS)
77
+
78
+test-cfg.o: tests/TestCFG.cpp
79
+	$(CXX) -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -Isrc $(INCPATH) -DDEBUG $(WARNINGS) -c -o $@ $<
80
+
75 81
 clean:
76 82
 	-@rm -rf $(OBJDIR) $(EXECUTABLE) 2>/dev/null || true
77 83
 

+ 7
- 1
NTMakefile View File

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

+ 8
- 4
src/CFGFileParser.cpp View File

@@ -10,7 +10,6 @@ CFGFileParser::CFGFileParser(const char* filename){
10 10
     cfg_file = fopen(filename, "rb"); // On NT, opening in text mode translates \n into \r\n
11 11
     stat(filename, cfg_fileinfo);
12 12
     buffer = static_cast<char*>(tlsf_malloc(cfg_fileinfo->st_size & INT_MAX));
13
-    cfg = new BrowserConfiguration();
14 13
     bytesRead = fread(buffer, sizeof(char) & INT_MAX, cfg_fileinfo->st_size & INT_MAX, cfg_file);
15 14
     if (!bytesRead) {
16 15
         std::cout << "no config" << std::endl;
@@ -18,6 +17,11 @@ CFGFileParser::CFGFileParser(const char* filename){
18 17
     fclose(cfg_file);
19 18
 }
20 19
 
20
+CFGFileParser::CFGFileParser(ntr::fast_string in_buf){
21
+    buffer = static_cast<char*>(tlsf_malloc(strlen(in_buf.c_str()) & INT_MAX));
22
+    strcpy(buffer, in_buf.c_str());
23
+}
24
+
21 25
 CFGFileParser::~CFGFileParser(){
22 26
     // clean up!
23 27
     // This buffer has been written to and co-opted by
@@ -47,8 +51,8 @@ bool CFGFileParser::ParseText() {
47 51
             token = strtok_r(nullptr, "\n", &tmp);
48 52
         }
49 53
         else if (!isalpha(token[0])){ // The leading character is NOT a #, ., <LF>, or a letter. NB: Leading numbers are also invalid.
50
-            printf("ERROR: Config file is invalid\n");
51
-            printf("%s\n",token);
54
+            printf("ERROR: Config file is invalid: ");
55
+            printf("\"%s\"\n",token);
52 56
             return false;
53 57
         }
54 58
         else {
@@ -57,7 +61,7 @@ bool CFGFileParser::ParseText() {
57 61
                 return false;
58 62
             }
59 63
             if (!slre_match(&regex, token, strlen(token), nullptr)){
60
-                printf("Invalid directive: %s\n", token); // regex matches DIREC[_]T[I1]VE:[token] but NOT directive:[token] - the directive MUST be all caps
64
+                printf("Invalid directive: \"%s\"\n", token); // regex matches DiReC[_]T[I1]VE:[token], it simply cannot start with a number or symbol.
61 65
                 return false;
62 66
             }
63 67
             // Config directive found, add to second-pass buffer

+ 3
- 0
src/CFGFileParser.h View File

@@ -24,7 +24,10 @@ struct BrowserConfiguration{
24 24
 
25 25
 class CFGFileParser {
26 26
 public:
27
+    // Opens config from external file.
27 28
     CFGFileParser(const char* filename);
29
+    // Opens config from memory.
30
+    CFGFileParser(ntr::fast_string in_buf);
28 31
     ~CFGFileParser();
29 32
     bool ParseText();
30 33
     void WriteConfig(BrowserConfiguration &config);

+ 4
- 1
src/netrunner.h View File

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

+ 78
- 0
tests/TestCFG.cpp View File

@@ -0,0 +1,78 @@
1
+#include "netrunner.h"
2
+#include "CFGFileParser.h"
3
+#ifdef _WIN32
4
+extern "C"{void init_heap();}
5
+#endif
6
+
7
+int main(void){
8
+    #ifdef _WIN32
9
+    init_heap();
10
+    #endif
11
+    
12
+    // test vectors
13
+    // This is our reference, should always be valid.
14
+    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.";
15
+
16
+    // Leading number.
17
+    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.";
18
+
19
+    // Lowercase letters. Also a valid directive.
20
+    ntr::fast_string buf3 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:[ssometext]\n# One more comment.";
21
+
22
+    // Unescaped comment.
23
+    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.";
24
+
25
+    // Old-style Lynx directive. Invalid here.
26
+    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.";
27
+
28
+    // Invalid leading character.
29
+    ntr::fast_string buf6 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\n^bad_directive:[ssometext]\n# One more comment.";
30
+    
31
+    // The casts LOOK useless, but they're not.
32
+    CFGFileParser test1(buf1);
33
+    CFGFileParser test2(buf2);
34
+    CFGFileParser test3(buf3);
35
+    CFGFileParser test4(buf4);
36
+    CFGFileParser test5(buf5);
37
+    CFGFileParser test6(buf6);
38
+
39
+    puts("CFG Parser Test for /ntr/\n<despair@netrunner.cc>\n");
40
+   
41
+    if (test1.ParseText()){
42
+        puts("Test 1 passed. This is the reference string.\n");
43
+    }
44
+    else{
45
+        puts("Test 1 FAILED!\n");
46
+    }
47
+    if (test2.ParseText()){
48
+        puts("Test 2 passed.\n");
49
+    }
50
+    else{
51
+        puts("Test 2 FAILED: see above\nDirectives must not begin with a number.\n");
52
+    }
53
+    if (test3.ParseText()){
54
+        puts("Test 3 passed. Mixed-case directives are valid.\n");
55
+    }
56
+    else{
57
+        puts("Test 3 FAILED: see above\n");
58
+    }
59
+    if (test4.ParseText()){
60
+        puts("Test 4 passed.\n");
61
+    }
62
+    else{
63
+        puts("Test 4 FAILED: see above\nA stray comment.\n");
64
+    }
65
+    if (test5.ParseText()){
66
+        puts("Test 5 passed.");
67
+    }
68
+    else{
69
+        puts("Test 5 FAILED: see above\nOld-style Lynx CFG directive. No longer valid here.\n");
70
+    }
71
+    if (test6.ParseText()){
72
+        puts("Test 6 passed.");
73
+    }
74
+    else{
75
+        puts("Test 6 FAILED: see above\nLeading non-alpha symbol\n");
76
+    }
77
+    return 0;
78
+}