Kajetan Johannes Hammerle 2 月之前
父节点
当前提交
5fd09d85dd

+ 4 - 4
CMakeLists.txt

@@ -18,11 +18,11 @@ set(SRC
     "src/Random.cpp"
     #"src/ReadLine.cpp"
     #"src/SpinLock.cpp"
-    #"src/Terminal.cpp"
+    "src/Terminal.cpp"
     "src/Test.cpp"
     #"src/Thread.cpp"
     "src/ToString.cpp"
-    #"src/Unicode.cpp"
+    "src/Unicode.cpp"
     "src/Utility.cpp"
     "src/Vector.cpp"
     #"src/View.cpp"
@@ -45,9 +45,9 @@ set(SRC_TESTS
     "test/modules/RandomTests.cpp"
     #"test/modules/ReadLineTests.cpp"
     #"test/modules/SpinLockTests.cpp"
-    #"test/modules/TerminalTests.cpp"
+    "test/modules/TerminalTests.cpp"
     "test/modules/TestTests.cpp"
-    #"test/modules/UnicodeTests.cpp"
+    "test/modules/UnicodeTests.cpp"
     "test/modules/UtilityTests.cpp"
     #"test/modules/VectorTests.cpp"
     #"test/modules/ViewTests.cpp"

+ 2 - 9
include/core/Array.hpp

@@ -5,15 +5,8 @@
 
 namespace Core {
     template<typename T, size_t N>
-    class Array final {
-        T data[N];
-
-    public:
-        constexpr Array() = default;
-
-        constexpr Array(const T& t) {
-            fill(t);
-        }
+    struct Array final {
+        T data[N] = {};
 
         constexpr void fill(const T& t) {
             for(size_t i = 0; i < N; i++) {

+ 27 - 25
include/core/Terminal.hpp

@@ -1,5 +1,5 @@
-#ifndef CORE_TERMINAL_H
-#define CORE_TERMINAL_H
+#ifndef CORE_TERMINAL_HPP
+#define CORE_TERMINAL_HPP
 
 #include "core/Types.hpp"
 #include "core/Vector.hpp"
@@ -87,32 +87,34 @@
 #define TERMINAL_KEY_SHIFT 0x4'0000'0000lu
 #define TERMINAL_KEY_ALT 0x8'0000'0000lu
 
-void enterAlternativeTerminal();
-void leaveAlternativeTerminal();
-Core::IntVector2 getTerminalSize();
-void clearTerminal();
-void clearTerminalLine();
+namespace Core {
+    void enterAlternativeTerminal();
+    void leaveAlternativeTerminal();
+    IntVector2 getTerminalSize();
+    void clearTerminal();
+    void clearTerminalLine();
 
-void hideCursor();
-void showCursor();
-void resetCursor();
-void moveCursorLeft(int i);
-void moveCursorRight(int i);
-void moveCursorUp(int i);
-void moveCursorDown(int i);
+    void hideCursor();
+    void showCursor();
+    void resetCursor();
+    void moveCursorLeft(int i);
+    void moveCursorRight(int i);
+    void moveCursorUp(int i);
+    void moveCursorDown(int i);
 
-bool enterRawTerminal();
-bool leaveRawTerminal();
-u64 getRawChar();
-bool isSpecialChar(u64 u);
+    bool enterRawTerminal();
+    bool leaveRawTerminal();
+    u64 getRawChar();
+    bool isSpecialChar(u64 u);
 
-typedef struct {
-    u64 key;
-    bool control;
-    bool shift;
-    bool alt;
-} SpecialChar;
+    struct SpecialChar {
+        u64 key = 0;
+        bool control = 0;
+        bool shift = 0;
+        bool alt = 0;
+    };
 
-SpecialChar convertToSpecialChar(u64 u);
+    SpecialChar convertToSpecialChar(u64 u);
+}
 
 #endif

+ 2 - 0
include/core/ToString.hpp

@@ -17,6 +17,8 @@ size_t toString(float v, char* s, size_t n);
 size_t toString(double v, char* s, size_t n);
 size_t toString(const char* v, char* s, size_t n);
 size_t toString(char* v, char* s, size_t n);
+size_t toString(const unsigned char* v, char* s, size_t n);
+size_t toString(unsigned char* v, char* s, size_t n);
 size_t toString(bool v, char* s, size_t n);
 
 template<typename T>

+ 12 - 10
include/core/Unicode.hpp

@@ -1,16 +1,18 @@
-#ifndef CORE_UNICODE_H
-#define CORE_UNICODE_H
+#ifndef CORE_UNICODE_HPP
+#define CORE_UNICODE_HPP
 
 #include "core/Types.hpp"
 
-typedef struct {
-    u8 data[4];
-    u32 length;
-} UTF8;
+namespace Core {
+    struct UTF8 {
+        u8 data[4] = {0};
+        u32 length = 0;
+    };
 
-UTF8 convertUnicodeToUTF8(u32 c);
-u32 convertUTF8toUnicode(UTF8 c);
-bool isUTF8Remainder(u8 c);
-u32 getUTF8Length(u8 c);
+    UTF8 convertUnicodeToUTF8(u32 c);
+    u32 convertUTF8toUnicode(UTF8 c);
+    bool isUTF8Remainder(u8 c);
+    u32 getUTF8Length(u8 c);
+}
 
 #endif

+ 45 - 42
src/Terminal.cpp

@@ -1,22 +1,24 @@
 #include "core/Terminal.hpp"
 
-#include <stdio.h>
+#include <cstdio>
+
 #include <sys/ioctl.h>
 #include <termios.h>
 #include <unistd.h>
 
+#include "core/Array.hpp"
 #include "core/Logger.hpp"
 #include "core/Unicode.hpp"
 
 #define ESC "\33["
 #define esc(s) fputs(ESC s, stdout)
 
-static struct termios originalTerminal;
+static termios originalTerminal;
 
-typedef struct {
-    const u8* path;
-    u64 mapping;
-} EscapeSequence;
+struct EscapeSequence {
+    const u8 path[16] = {};
+    u64 mapping = 0;
+};
 
 #define K_CTRL TERMINAL_KEY_CTRL
 #define K_SHIFT TERMINAL_KEY_SHIFT
@@ -47,7 +49,7 @@ typedef struct {
         u8"[1;" c "F", m | TERMINAL_KEY_END            \
     }
 
-static const EscapeSequence ESCAPE_SEQUENCES[] = {
+static const Core::Array<EscapeSequence, 175> ESCAPE_SEQUENCES = {{
     {u8"[A", TERMINAL_KEY_ARROW_UP},
     {u8"[B", TERMINAL_KEY_ARROW_DOWN},
     {u8"[C", TERMINAL_KEY_ARROW_RIGHT},
@@ -83,73 +85,73 @@ static const EscapeSequence ESCAPE_SEQUENCES[] = {
     KEYS_WITH_MODIFIER("6", K_CTRL | K_SHIFT),
     KEYS_WITH_MODIFIER("7", K_CTRL | K_ALT),
     KEYS_WITH_MODIFIER("8", K_CTRL | K_ALT | K_SHIFT),
-};
+}};
 
-void enterAlternativeTerminal() {
+void Core::enterAlternativeTerminal() {
     esc("?1049h");
 }
 
-void leaveAlternativeTerminal() {
+void Core::leaveAlternativeTerminal() {
     esc("?1049l");
 }
 
-void clearTerminal() {
+void Core::clearTerminal() {
     esc("2J");
 }
 
-IntVector2 getTerminalSize() {
-    struct winsize w;
+Core::IntVector2 Core::getTerminalSize() {
+    winsize w;
     if(ioctl(0, TIOCGWINSZ, &w)) {
-        return IV(0, 0);
+        return IntVector2(0, 0);
     }
-    return IV(w.ws_col, w.ws_row);
+    return IntVector2(w.ws_col, w.ws_row);
 }
 
-void clearTerminalLine() {
+void Core::clearTerminalLine() {
     esc("2K\r");
 }
 
-void hideCursor() {
+void Core::hideCursor() {
     esc("?25l");
 }
 
-void showCursor() {
+void Core::showCursor() {
     esc("?25h");
 }
 
-void resetCursor() {
+void Core::resetCursor() {
     esc("H");
 }
 
-void moveCursorLeft(int i) {
+void Core::moveCursorLeft(int i) {
     printf(ESC "%dD", i);
 }
 
-void moveCursorRight(int i) {
+void Core::moveCursorRight(int i) {
     printf(ESC "%dC", i);
 }
 
-void moveCursorUp(int i) {
+void Core::moveCursorUp(int i) {
     printf(ESC "%dA", i);
 }
 
-void moveCursorDown(int i) {
+void Core::moveCursorDown(int i) {
     printf(ESC "%dB", i);
 }
 
-bool enterRawTerminal() {
+bool Core::enterRawTerminal() {
     if(tcgetattr(STDIN_FILENO, &originalTerminal)) {
         return true;
     }
-    struct termios raw = originalTerminal;
-    raw.c_iflag &= ~(tcflag_t)(ICRNL | IXON);
-    raw.c_lflag &= ~(tcflag_t)(ECHO | ICANON | IEXTEN | ISIG);
+    termios raw = originalTerminal;
+    raw.c_iflag &= ~static_cast<tcflag_t>(ICRNL | IXON);
+    raw.c_lflag &= ~static_cast<tcflag_t>(ECHO | ICANON | IEXTEN | ISIG);
     raw.c_cc[VMIN] = 0;
     raw.c_cc[VTIME] = 0;
     return tcsetattr(STDIN_FILENO, TCSANOW, &raw);
 }
 
-bool leaveRawTerminal() {
+bool Core::leaveRawTerminal() {
     return tcsetattr(STDIN_FILENO, TCSAFLUSH, &originalTerminal);
 }
 
@@ -169,7 +171,8 @@ static bool couldMatch(const u8* s, const u8* e, size_t l) {
 }
 
 static u64 readEscapeSequence() {
-    u8 s[10] = {0};
+    constexpr size_t CHARS = 10;
+    u8 s[CHARS] = {0};
     s[0] = readChar();
     s[1] = readChar();
     if(s[1] == 0) {
@@ -178,35 +181,35 @@ static u64 readEscapeSequence() {
     size_t l = 2;
     while(true) {
         bool matchFound = false;
-        for(size_t i = 0; i < ARRAY_LENGTH(ESCAPE_SEQUENCES); i++) {
-            const EscapeSequence* e = ESCAPE_SEQUENCES + i;
-            if(couldMatch(s, e->path, l)) {
+        for(size_t i = 0; i < ESCAPE_SEQUENCES.getLength(); i++) {
+            const EscapeSequence& e = ESCAPE_SEQUENCES[i];
+            if(couldMatch(s, e.path, l)) {
                 matchFound = true;
-                if(e->path[l] == 0) {
-                    return e->mapping;
+                if(e.path[l] == 0) {
+                    return e.mapping;
                 }
             }
         }
-        if(!matchFound || l >= ARRAY_LENGTH(s)) {
+        if(!matchFound || l >= CHARS) {
             break;
         }
         s[l++] = readChar();
     }
-    REPORT(LOG_WARNING, "Unknown escape sequence starting with '%s'", s);
+    REPORT(LogLevel::WARNING, "Unknown escape sequence starting with '#'", s);
     return TERMINAL_KEY_UNKNOWN;
 }
 
 static u64 readUTF8() {
-    UTF8 u = {0};
+    Core::UTF8 u = {};
     u.data[0] = readChar();
-    u.length = getUTF8Length(u.data[0]);
+    u.length = Core::getUTF8Length(u.data[0]);
     for(u32 i = 1; i < u.length; i++) {
         u.data[i] = readChar();
     }
     return convertUTF8toUnicode(u);
 }
 
-u64 getRawChar() {
+u64 Core::getRawChar() {
     u64 c = readUTF8();
     if(c == 27) {
         return readEscapeSequence();
@@ -214,12 +217,12 @@ u64 getRawChar() {
     return c;
 }
 
-bool isSpecialChar(u64 u) {
+bool Core::isSpecialChar(u64 u) {
     return u >= TERMINAL_KEY_UNKNOWN;
 }
 
-SpecialChar convertToSpecialChar(u64 u) {
-    SpecialChar c = {0};
+Core::SpecialChar Core::convertToSpecialChar(u64 u) {
+    SpecialChar c;
     c.shift = TERMINAL_KEY_SHIFT & u;
     c.control = TERMINAL_KEY_CTRL & u;
     c.alt = TERMINAL_KEY_ALT & u;

+ 5 - 0
src/ToString.cpp

@@ -17,6 +17,7 @@ TO_STRING(unsigned long, "%lu")
 TO_STRING(unsigned long long, "%llu")
 TO_STRING(double, "%.2f")
 TO_STRING(const char*, "%s")
+TO_STRING(const unsigned char*, "%s")
 
 size_t toString(float v, char* s, size_t n) {
     int e = snprintf(s, n, "%.2f", static_cast<double>(v));
@@ -27,6 +28,10 @@ size_t toString(char* v, char* s, size_t n) {
     return toString(static_cast<const char*>(v), s, n);
 }
 
+size_t toString(unsigned char* v, char* s, size_t n) {
+    return toString(static_cast<const unsigned char*>(v), s, n);
+}
+
 size_t toString(bool v, char* s, size_t n) {
     int e = snprintf(s, n, "%s", v ? "true" : "false");
     return e < 0 ? 0 : static_cast<size_t>(e);

+ 5 - 5
src/Unicode.cpp

@@ -1,7 +1,7 @@
 #include "core/Unicode.hpp"
 
-UTF8 convertUnicodeToUTF8(u32 c) {
-    UTF8 u = {0};
+Core::UTF8 Core::convertUnicodeToUTF8(u32 c) {
+    UTF8 u = {};
     if(c >= 0x10000) {
         u.length = 4;
         u.data[0] = 0b1111'0000 | ((c >> 18) & 0b0000'0111);
@@ -24,7 +24,7 @@ UTF8 convertUnicodeToUTF8(u32 c) {
     return u;
 }
 
-u32 convertUTF8toUnicode(UTF8 c) {
+u32 Core::convertUTF8toUnicode(UTF8 c) {
     if(c.length == 4) {
         return ((c.data[0] & 0b0000'0111u) << 18) |
                ((c.data[1] & 0b0011'1111u) << 12) |
@@ -38,11 +38,11 @@ u32 convertUTF8toUnicode(UTF8 c) {
     return c.data[0];
 }
 
-bool isUTF8Remainder(u8 c) {
+bool Core::isUTF8Remainder(u8 c) {
     return (c & 0b1100'0000) == 0b1000'0000;
 }
 
-u32 getUTF8Length(u8 c) {
+u32 Core::getUTF8Length(u8 c) {
     if((c & 0b1111'1000) == 0b1111'0000) {
         return 4;
     } else if((c & 0b1111'0000) == 0b1110'0000) {

+ 7 - 10
test/Main.cpp

@@ -1,7 +1,6 @@
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-#include <threads.h>
+#include <clocale>
+#include <cstdio>
+#include <cstring>
 
 #include "Tests.hpp"
 #include "core/Logger.hpp"
@@ -53,11 +52,11 @@ int main(int argAmount, const char** args) {
             testTest();
             return 0;
         } else if(strcmp(args[i], "terminal") == 0) {
-            // testTerminal(true);
+            testTerminal(true);
             finalize();
             return 0;
         } else if(strcmp(args[i], "iterminal") == 0) {
-            // testInteractiveTerminal();
+            testInteractiveTerminal();
             return 0;
         }
     }
@@ -74,7 +73,6 @@ int main(int argAmount, const char** args) {
     testFile();
     // testFrustum();
     // testHashMap(light);
-    // testList(light);
     testMatrix();
     // testPlane();
     testQuaternion();
@@ -84,10 +82,9 @@ int main(int argAmount, const char** args) {
         // testReadLine();
     }
     // testSpinLock();
-    // testTerminal(!light);
-    // testUnicode();
+    testTerminal(!light);
+    testUnicode();
     testUtility(light);
-    // testVector();
     // testView();
 
     logLevel = LogLevel::WARNING;

+ 3 - 1
test/modules/ArrayTests.cpp

@@ -2,7 +2,7 @@
 #include "core/Array.hpp"
 #include "core/Test.hpp"
 
-template class Core::Array<size_t, 3>;
+template struct Core::Array<size_t, 3>;
 using TestArray = Core::Array<size_t, 3>;
 
 static void testToString1() {
@@ -11,6 +11,8 @@ static void testToString1() {
     a[1] = 243;
     a[2] = 423;
     TEST_STRING("[1, 243, 423]", a);
+    Core::Array<int, 3> b = {{1, 2, 3}};
+    TEST_STRING("[1, 2, 3]", b);
 }
 
 static void testToString2() {

+ 3 - 3
test/modules/RandomTests.cpp

@@ -30,7 +30,7 @@ static void testCoin(bool light) {
 static void testDistribution(bool light) {
     size_t limit = light ? 100'000 : 1'000'000;
     Random r(553);
-    Core::Array<int, 102> c(0);
+    Core::Array<int, 102> c;
     for(size_t i = 0; i < limit; i++) {
         c[r.nextSize(1, c.getLength() - 1)]++;
     }
@@ -57,7 +57,7 @@ static void testFloatAverage(bool light) {
 static void testFloatCoin(bool light) {
     int limit = light ? 100'000 : 1'000'000;
     Random r(5535);
-    Core::Array<int, 2> c(0);
+    Core::Array<int, 2> c;
     for(int i = 0; i < limit; i++) {
         c[r.nextFloat() < 0.5f]++;
     }
@@ -69,7 +69,7 @@ static void testFloatCoin(bool light) {
 static void testFloatDistribution(bool light) {
     int limit = light ? 100'000 : 1'000'000;
     Random r(553);
-    Core::Array<int, 102> c(0);
+    Core::Array<int, 102> c;
     for(int i = 0; i < limit; i++) {
         c[static_cast<size_t>(1.0f + r.nextFloat() * (c.getLength() - 2))]++;
     }

+ 41 - 40
test/modules/TerminalTests.cpp

@@ -1,75 +1,76 @@
 #include <stdio.h>
 
-#include "../Tests.h"
-#include "core/Logger.h"
-#include "core/Terminal.h"
-#include "core/Utility.h"
+#include "../Tests.hpp"
+#include "core/Logger.hpp"
+#include "core/Terminal.hpp"
+#include "core/Test.hpp"
+#include "core/Utility.hpp"
 
 #define KEY_CASE(key)           \
     case key: puts(#key); break
 
 void testTerminal(bool tty) {
-    IntVector2 size = getTerminalSize();
+    Core::IntVector2 size = Core::getTerminalSize();
     if(tty) {
-        TEST_TRUE(size.x > 0);
-        TEST_TRUE(size.y > 0);
-        TEST_FALSE(enterRawTerminal());
-        TEST_FALSE(leaveRawTerminal());
+        TEST_TRUE(size[0] > 0);
+        TEST_TRUE(size[1] > 0);
+        TEST_FALSE(Core::enterRawTerminal());
+        TEST_FALSE(Core::leaveRawTerminal());
     } else {
-        TEST_INT(0, size.x);
-        TEST_INT(0, size.y);
+        TEST(0, size[0]);
+        TEST(0, size[1]);
     }
 
-    enterAlternativeTerminal();
-    clearTerminal();
-    resetCursor();
+    Core::enterAlternativeTerminal();
+    Core::clearTerminal();
+    Core::resetCursor();
     LOG_ERROR("Not visible!");
-    leaveAlternativeTerminal();
+    Core::leaveAlternativeTerminal();
 
     LOG_ERROR("Not visible!");
-    moveCursorUp(2);
-    moveCursorDown(1);
-    moveCursorLeft(3);
-    moveCursorRight(3);
-    clearTerminalLine();
+    Core::moveCursorUp(2);
+    Core::moveCursorDown(1);
+    Core::moveCursorLeft(3);
+    Core::moveCursorRight(3);
+    Core::clearTerminalLine();
 
-    hideCursor();
-    showCursor();
+    Core::hideCursor();
+    Core::showCursor();
 
     u64 u = TERMINAL_KEY_F5 | TERMINAL_KEY_SHIFT;
-    TEST_TRUE(isSpecialChar(u));
-    SpecialChar s = convertToSpecialChar(u);
-    TEST_U64(TERMINAL_KEY_F5, s.key);
+    TEST_TRUE(Core::isSpecialChar(u));
+    Core::SpecialChar s = Core::convertToSpecialChar(u);
+    TEST(TERMINAL_KEY_F5, s.key);
     TEST_FALSE(s.alt);
     TEST_FALSE(s.control);
     TEST_TRUE(s.shift);
 }
 
 void testInteractiveTerminal(void) {
-    enterAlternativeTerminal();
+    Core::enterAlternativeTerminal();
 
-    resetCursor();
-    hideCursor();
+    Core::resetCursor();
+    Core::hideCursor();
     puts("Hi there");
     LOG_WARNING("This is a test");
-    IntVector2 v = getTerminalSize();
-    printf("%d %d\n", v.x, v.y);
-    clearTerminal();
-    resetCursor();
-    showCursor();
+    Core::IntVector2 v = Core::getTerminalSize();
+    printf("%d %d\n", v[0], v[1]);
+    Core::clearTerminal();
+    Core::resetCursor();
+    Core::showCursor();
     puts("the final!!!");
-    sleepMillis(500);
+    Core::sleepMillis(500);
 
-    enterRawTerminal();
+    Core::enterRawTerminal();
 
     while(true) {
-        u64 c = getRawChar();
+        u64 c = Core::getRawChar();
         if(c == 'q') {
             break;
         } else if(c == 0) {
             continue;
-        } else if(isSpecialChar(c)) {
-            SpecialChar sc = convertToSpecialChar(c);
+        } else if(Core::isSpecialChar(c)) {
+            Core::SpecialChar sc = Core::convertToSpecialChar(c);
             if(sc.shift) {
                 printf("SHIFT + ");
             }
@@ -108,7 +109,7 @@ void testInteractiveTerminal(void) {
         }
     }
 
-    leaveRawTerminal();
+    Core::leaveRawTerminal();
 
-    leaveAlternativeTerminal();
+    Core::leaveAlternativeTerminal();
 }

+ 7 - 6
test/modules/UnicodeTests.cpp

@@ -1,14 +1,15 @@
-#include "../Tests.h"
-#include "core/Unicode.h"
+#include "../Tests.hpp"
+#include "core/Test.hpp"
+#include "core/Unicode.hpp"
 
 void testUnicode(void) {
     for(u32 c = 0; c < 0x10FFFF; c += 50) {
-        UTF8 u = convertUnicodeToUTF8(c);
+        Core::UTF8 u = Core::convertUnicodeToUTF8(c);
         for(u32 k = 1; k < u.length; k++) {
-            TEST_TRUE(isUTF8Remainder(u.data[k]));
+            TEST_TRUE(Core::isUTF8Remainder(u.data[k]));
         }
         TEST_TRUE(u.length >= 1);
-        TEST_U32(u.length, getUTF8Length(u.data[0]));
-        TEST_U32(c, convertUTF8toUnicode(u));
+        TEST(u.length, Core::getUTF8Length(u.data[0]));
+        TEST(c, Core::convertUTF8toUnicode(u));
     }
 }