#include "unsafe.qh"
#include "urllib.qc"
#include "vector.qh"
+#include "yenc.qh"
} \
} MACRO_END
+#define STRING_ITERATOR(this, s, i) \
+ string this##_s = s; \
+ int this##_i = i; \
+ MACRO_BEGIN MACRO_END
+
+#define STRING_ITERATOR_GET(this) str2chr(this##_s, this##_i++)
+
+#define FOREACH_CHAR(s, cond, body) \
+ MACRO_BEGIN \
+ { \
+ STRING_ITERATOR(iter, s, 0); \
+ int it; \
+ while ((it = STRING_ITERATOR_GET(iter)) > 0) \
+ { \
+ if (cond) { LAMBDA(body) } \
+ } \
+ } MACRO_END
+
#if defined(CSQC)
entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #402;
entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403;
#include "test.qh"
-float TEST_failed;
-float TEST_ok;
+int TEST_failed;
+bool TEST_ok;
void TEST_Fail(string cond)
{
TEST_ok = true;
}
-float TEST_RunAll()
+int TEST_RunAll_accumulated(int init);
+bool TEST_RunAll()
{
- int f = 0;
- float n = numentityfields();
- for (int i = 0; i < n; ++i)
- {
- string name = entityfieldname(i);
- if (substring(name, 0, 6) == "_TEST_")
- if (!TEST_Run(substring(name, 6, -1))) ++f;
- }
+ int f = TEST_RunAll_accumulated(0);
if (f)
{
LOG_INFOF("%d tests failed\n", f);
- return 1;
+ return true;
}
else
{
- LOG_INFOF("All tests OK\n", f);
- return 0;
+ LOG_INFO("All tests OK\n");
+ return false;
}
}
-float TEST_Run(string s)
+bool TEST_Run(string s)
{
LOG_INFOF("%s: testing...\n", s);
- TEST_failed = TEST_ok = 0;
+ TEST_failed = 0;
+ TEST_ok = false;
callfunction(strcat("_TEST_", s));
if (TEST_failed > 0)
{
LOG_INFOF("%s: %d items failed.\n", s, TEST_failed);
- return 0;
+ return false;
}
else if (!TEST_ok)
{
LOG_INFOF("%s: did not complete.\n", s);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
#ifndef TEST_H
#define TEST_H
-#define TEST_Check(cond) \
- MACRO_BEGIN \
- { \
- if (!(cond)) TEST_Fail( #cond); \
- } MACRO_END
+#define TEST(id) \
+ void _TEST_##id(); \
+ [[accumulate]] int TEST_RunAll_accumulated(int f) { \
+ if (!TEST_Run(#id)) ++f; \
+ return = f; \
+ } \
+ void _TEST_##id()
+
+#define TEST_Check(cond) MACRO_BEGIN { if (!(cond)) TEST_Fail(#cond); } MACRO_END
void TEST_OK();
void TEST_Fail(string cond);
-float TEST_RunAll();
-float TEST_Run(string test);
+bool TEST_RunAll();
+bool TEST_Run(string test);
+
#endif
--- /dev/null
+#ifndef YENC_H
+#define YENC_H
+
+#define yenc_single(c, ret) \
+ MACRO_BEGIN { \
+ int conv = c; \
+ conv += 42; \
+ if (conv >= 256) conv -= 256; \
+ switch (conv) \
+ { \
+ default: \
+ { \
+ string yenc_it = chr2str(conv); \
+ ret = yenc_it; \
+ break; \
+ } \
+ case '\0': \
+ case '\n': \
+ case '\r': \
+ case '=': \
+ { \
+ conv += 64; \
+ string yenc_it = chr2str('=', conv); \
+ ret = yenc_it; \
+ break; \
+ } \
+ } \
+ } MACRO_END
+
+#define ydec_single(stringiter, ret) \
+ MACRO_BEGIN { \
+ int conv = STRING_ITERATOR_GET(stringiter); \
+ bool esc = false; \
+ if (conv == '=') \
+ { \
+ esc = true; \
+ conv = STRING_ITERATOR_GET(stringiter); \
+ conv -= 64; \
+ } \
+ if (conv < 42) conv += 256; \
+ conv -= 42; \
+ ret = conv; \
+ } MACRO_END
+
+TEST(yEncDec)
+{
+ for (int i = 0; i < 255; ++i)
+ {
+ int expect = i;
+
+ string fragment;
+ yenc_single(expect, fragment);
+
+ int encdec;
+ STRING_ITERATOR(fragmentiterator, fragment, 0);
+ ydec_single(fragmentiterator, encdec);
+
+ TEST_Check(encdec == expect);
+ }
+ TEST_OK();
+}
+
+#endif
return sprintf(_("%s dB"), ftos_decimals(toDecibelOfSquare(fromDecibelOfSquare(v, me.valueMin), 0), me.valueDigits));
}
-void _TEST_XonoticDecibelsSlider()
+bool autocvar_test_XonoticDecibelsSlider = false;
+TEST(XonoticDecibelsSlider)
{
- float i;
- for(i = -400; i < 0; ++i)
+ if (!autocvar_test_XonoticDecibelsSlider) { TEST_OK(); return; }
+ for (int i = -400; i < 0; ++i)
{
float db = i * 0.1;
float v = fromDecibelOfSquare(db, -40);