diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | serd/serd.h | 5 | ||||
-rw-r--r-- | src/env.c | 14 | ||||
-rw-r--r-- | src/node.c | 28 | ||||
-rw-r--r-- | src/reader.c | 9 | ||||
-rw-r--r-- | src/serd_internal.h | 14 | ||||
-rw-r--r-- | src/serdi.c | 5 | ||||
-rw-r--r-- | src/string.c | 6 | ||||
-rw-r--r-- | src/uri.c | 18 | ||||
-rw-r--r-- | src/writer.c | 12 | ||||
-rw-r--r-- | tests/serd_test.c | 11 | ||||
-rw-r--r-- | wscript | 60 |
12 files changed, 111 insertions, 72 deletions
@@ -23,6 +23,7 @@ serd (UNRELEASED) unstable; urgency=low * Support Windows file://c:/foo URIs in serd_uri_to_path() on all platforms * Add serd_node_new_blob and serd_base64_decode for handling arbitrary binary data via base64 encoding. + * Support compilation as C++ under MSVC++. -- David Robillard <d@drobilla.net> (UNRELEASED) diff --git a/serd/serd.h b/serd/serd.h index b67ddd3d..06e0af43 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -21,13 +21,12 @@ #ifndef SERD_SERD_H #define SERD_SERD_H -#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #ifdef SERD_SHARED -# ifdef __WIN32__ +# ifdef _WIN32 # define SERD_LIB_IMPORT __declspec(dllimport) # define SERD_LIB_EXPORT __declspec(dllexport) # else @@ -45,6 +44,8 @@ #ifdef __cplusplus extern "C" { +#else +# include <stdbool.h> #endif /** @@ -17,7 +17,6 @@ #include "serd_internal.h" #include <assert.h> -#include <stdbool.h> #include <stdlib.h> #include <string.h> @@ -37,7 +36,7 @@ SERD_API SerdEnv* serd_env_new(const SerdNode* base_uri) { - SerdEnv* env = malloc(sizeof(struct SerdEnvImpl)); + SerdEnv* env = (SerdEnv*)malloc(sizeof(struct SerdEnvImpl)); env->prefixes = NULL; env->n_prefixes = 0; env->base_uri_node = SERD_NODE_NULL; @@ -117,8 +116,8 @@ serd_env_add(SerdEnv* env, prefix->uri = serd_node_copy(uri); serd_node_free(&old_prefix_uri); } else { - env->prefixes = realloc(env->prefixes, - (++env->n_prefixes) * sizeof(SerdPrefix)); + env->prefixes = (SerdPrefix*)realloc( + env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix)); env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name); env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri); } @@ -215,7 +214,8 @@ serd_env_expand(const SerdEnv* env, SerdChunk* uri_prefix, SerdChunk* uri_suffix) { - const uint8_t* const colon = memchr(qname->buf, ':', qname->n_bytes + 1); + const uint8_t* const colon = (const uint8_t*)memchr( + qname->buf, ':', qname->n_bytes + 1); if (!colon) { return SERD_ERR_BAD_ARG; // Illegal qname } @@ -246,8 +246,8 @@ serd_env_expand_node(const SerdEnv* env, } const size_t len = prefix.len + suffix.len; // FIXME: UTF-8? SerdNode ret = { NULL, len, len, 0, SERD_URI }; - ret.buf = malloc(ret.n_bytes + 1); - snprintf((char*)ret.buf, ret.n_bytes + 1, + ret.buf = (uint8_t*)malloc(ret.n_bytes + 1); + _snprintf((char*)ret.buf, ret.n_bytes + 1, "%s%s", prefix.buf, suffix.buf); return ret; } @@ -42,7 +42,7 @@ serd_node_copy(const SerdNode* node) } SerdNode copy = *node; - uint8_t* buf = malloc(copy.n_bytes + 1); + uint8_t* buf = (uint8_t*)malloc(copy.n_bytes + 1); memcpy(buf, node->buf, copy.n_bytes + 1); copy.buf = buf; return copy; @@ -122,7 +122,7 @@ serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out) } const size_t len = serd_uri_string_length(&abs_uri); - uint8_t* buf = malloc(len + 1); + uint8_t* buf = (uint8_t*)malloc(len + 1); SerdNode node = { buf, len, len, 0, SERD_URI }; // FIXME: UTF-8 @@ -144,12 +144,11 @@ SERD_API SerdNode serd_node_new_decimal(double d, unsigned frac_digits) { - const double abs_d = fabs(d); - const long int_digits = (long)fmax(1.0, ceil(log10(abs_d))); - char* buf = calloc(int_digits + frac_digits + 3, 1); - SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL }; - - const double int_part = floor(abs_d); + const double abs_d = fabs(d); + const unsigned int_digits = (unsigned)fmax(1.0, ceil(log10(abs_d))); + char* buf = (char*)calloc(int_digits + frac_digits + 3, 1); + SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL }; + const double int_part = floor(abs_d); // Point s to decimal point location char* s = buf + int_digits; @@ -159,8 +158,8 @@ serd_node_new_decimal(double d, unsigned frac_digits) } // Write integer part (right to left) - char* t = s - 1; - long dec = (long)int_part; + char* t = s - 1; + uint64_t dec = (uint64_t)int_part; do { *t-- = '0' + (dec % 10); } while ((dec /= 10) > 0); @@ -173,7 +172,7 @@ serd_node_new_decimal(double d, unsigned frac_digits) *s++ = '0'; node.n_bytes = node.n_chars = (s - buf); } else { - long frac = lrint(frac_part * pow(10, frac_digits)); + uint64_t frac = frac_part * pow(10.0, (int)frac_digits) + 0.5; s += frac_digits - 1; unsigned i = 0; @@ -198,7 +197,7 @@ serd_node_new_integer(long i) { long abs_i = labs(i); const long digits = (long)fmax(1.0, ceil(log10((double)abs_i + 1))); - char* buf = calloc(digits + 2, 1); + char* buf = (char*)calloc(digits + 2, 1); SerdNode node = { (const uint8_t*)buf, 0, 0, 0, SERD_LITERAL }; // Point s to the end @@ -222,7 +221,7 @@ serd_node_new_integer(long i) Base64 encoding table. @see <a href="http://tools.ietf.org/html/rfc3548#section-3">RFC3986 S3</a>. */ -static const uint8_t b64_map[64] = +static const uint8_t b64_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** @@ -244,7 +243,8 @@ SerdNode serd_node_new_blob(const void* buf, size_t size, bool wrap_lines) { const size_t len = ((size + 2) / 3) * 4 + (wrap_lines ? (size / 57) : 0); - SerdNode node = { calloc(1, len + 2), len, len, 0, SERD_LITERAL }; + SerdNode node = { (uint8_t*)calloc(1, len + 2), + len, len, 0, SERD_LITERAL }; for (size_t i = 0, j = 0; i < size; i += 3, j += 4) { uint8_t in[4] = { 0, 0, 0, 0 }; size_t n_in = MIN(3, size - i); diff --git a/src/reader.c b/src/reader.c index 38bae75f..60296b8f 100644 --- a/src/reader.c +++ b/src/reader.c @@ -19,7 +19,6 @@ #include <assert.h> #include <errno.h> #include <stdarg.h> -#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -450,7 +449,7 @@ read_utf8_character(SerdReader* reader, Ref dest, const uint8_t c) eat_byte_safe(reader, c)); } - char bytes[size]; + char bytes[4]; bytes[0] = eat_byte_safe(reader, c); // Check character validity @@ -1386,7 +1385,7 @@ serd_reader_new(SerdSyntax syntax, SerdEndSink end_sink) { const Cursor cur = { NULL, 0, 0 }; - SerdReader* me = malloc(sizeof(struct SerdReaderImpl)); + SerdReader* me = (SerdReader*)malloc(sizeof(struct SerdReaderImpl)); me->handle = handle; me->free_handle = free_handle; me->base_sink = base_sink; @@ -1454,7 +1453,7 @@ serd_reader_add_blank_prefix(SerdReader* reader, reader->bprefix = NULL; if (prefix) { reader->bprefix_len = strlen((const char*)prefix); - reader->bprefix = malloc(reader->bprefix_len + 1); + reader->bprefix = (uint8_t*)malloc(reader->bprefix_len + 1); memcpy(reader->bprefix, prefix, reader->bprefix_len + 1); } } @@ -1489,7 +1488,7 @@ serd_reader_read_file_handle(SerdReader* me, FILE* file, const uint8_t* name) me->cur = cur; me->from_file = true; me->eof = false; - me->read_buf = serd_bufalloc(SERD_PAGE_SIZE); + me->read_buf = (uint8_t*)serd_bufalloc(SERD_PAGE_SIZE); memset(me->read_buf, '\0', SERD_PAGE_SIZE); diff --git a/src/serd_internal.h b/src/serd_internal.h index ae5669a9..ba6b5d98 100644 --- a/src/serd_internal.h +++ b/src/serd_internal.h @@ -38,6 +38,14 @@ # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif +#ifndef fmax +static inline float +fmax(float a, float b) +{ + return (a < b) ? b : a; +} +#endif + /* File and Buffer Utilities */ static inline FILE* @@ -82,7 +90,7 @@ static inline SerdStack serd_stack_new(size_t size) { SerdStack stack; - stack.buf = malloc(size); + stack.buf = (uint8_t*)malloc(size); stack.buf_size = size; stack.size = SERD_STACK_BOTTOM; return stack; @@ -109,7 +117,7 @@ serd_stack_push(SerdStack* stack, size_t n_bytes) const size_t new_size = stack->size + n_bytes; if (stack->buf_size < new_size) { stack->buf_size *= 2; - stack->buf = realloc(stack->buf, stack->buf_size); + stack->buf = (uint8_t*)realloc(stack->buf, stack->buf_size); } uint8_t* const ret = (stack->buf + stack->size); stack->size = new_size; @@ -141,7 +149,7 @@ serd_bulk_sink_new(SerdSink sink, void* stream, size_t block_size) bsink.stream = stream; bsink.size = 0; bsink.block_size = block_size; - bsink.buf = serd_bufalloc(block_size); + bsink.buf = (uint8_t*)serd_bufalloc(block_size); return bsink; } diff --git a/src/serdi.c b/src/serdi.c index 569b1152..d49ec776 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -171,7 +171,7 @@ main(int argc, char** argv) FILE* out_fd = stdout; SerdEnv* env = serd_env_new(&base_uri_node); - SerdStyle output_style = 0; + int output_style = 0; if (output_syntax == SERD_NTRIPLES) { output_style |= SERD_STYLE_ASCII; } else { @@ -190,7 +190,8 @@ main(int argc, char** argv) } SerdWriter* writer = serd_writer_new( - output_syntax, output_style, env, &base_uri, serd_file_sink, out_fd); + output_syntax, (SerdStyle)output_style, + env, &base_uri, serd_file_sink, out_fd); if (chop_prefix) { serd_writer_chop_blank_prefix(writer, chop_prefix); diff --git a/src/string.c b/src/string.c index 902f5c42..650d10b1 100644 --- a/src/string.c +++ b/src/string.c @@ -119,7 +119,7 @@ serd_strtod(const char* str, char** endptr) for decoding, shifted up by 47 to be in the range of printable ASCII. A '$' is a placeholder for characters not in the base64 alphabet. */ -static const char b64_unmap[255] = +static const char b64_unmap[] = "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$" "$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$" "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" @@ -146,8 +146,8 @@ serd_base64_decode(const uint8_t* str, size_t len, size_t* size) void* buf = malloc((len * 3) / 4 + 2); *size = 0; for (size_t i = 0, j = 0; i < len; j += 3) { - uint8_t in[4] = "===="; - size_t n_in = 0; + uint8_t in[] = "===="; + size_t n_in = 0; for (; i < len && n_in < 4; ++n_in) { for (; i < len && !is_base64(str[i]); ++i) {} // Skip junk in[n_in] = str[i++]; @@ -22,12 +22,21 @@ // #define URI_DEBUG 1 +static inline bool +is_windows_path(const uint8_t* path) +{ + return is_alpha(path[0]) && (path[1] == ':' || path[1] == '|') + && (path[2] == '/' || path[2] == '\\'); +} + SERD_API const uint8_t* serd_uri_to_path(const uint8_t* uri) { - const uint8_t* path = NULL; - if (serd_uri_string_has_scheme(uri)) { + const uint8_t* path = uri; + if (uri[0] == '/' || is_windows_path(uri)) { + return uri; + } else if (serd_uri_string_has_scheme(uri)) { if (strncmp((const char*)uri, "file:", 5)) { fprintf(stderr, "Non-file URI `%s'\n", uri); return NULL; @@ -39,12 +48,9 @@ serd_uri_to_path(const uint8_t* uri) fprintf(stderr, "Invalid file URI `%s'\n", uri); return NULL; } - // Special case for awful Windows file URIs - if (is_alpha(path[1]) && path[2] == ':' && path[3] == '/') { + if (is_windows_path(path + 1)) { ++path; // Special case for terrible Windows file URIs } - } else { - path = uri; } return path; } diff --git a/src/writer.c b/src/writer.c index 60345463..26b06690 100644 --- a/src/writer.c +++ b/src/writer.c @@ -31,7 +31,7 @@ typedef struct { } WriteContext; static const WriteContext WRITE_CONTEXT_NULL = { - {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} + SERD_NODE_NULL, SERD_NODE_NULL, SERD_NODE_NULL }; struct SerdWriterImpl { @@ -72,7 +72,7 @@ copy_node(SerdNode* dst, const SerdNode* src) return; } if (!dst->buf || dst->n_bytes < src->n_bytes) { - dst->buf = realloc((char*)dst->buf, src->n_bytes + 1); + dst->buf = (uint8_t*)realloc((char*)dst->buf, src->n_bytes + 1); } dst->n_bytes = src->n_bytes; dst->n_chars = src->n_chars; @@ -217,9 +217,9 @@ serd_writer_write_delim(SerdWriter* writer, const uint8_t delim) } static void -reset_context(SerdWriter* writer, bool delete) +reset_context(SerdWriter* writer, bool del) { - if (delete) { + if (del) { serd_node_free(&writer->context.graph); serd_node_free(&writer->context.subject); serd_node_free(&writer->context.predicate); @@ -525,7 +525,7 @@ serd_writer_new(SerdSyntax syntax, void* stream) { const WriteContext context = WRITE_CONTEXT_NULL; - SerdWriter* writer = malloc(sizeof(struct SerdWriterImpl)); + SerdWriter* writer = (SerdWriter*)malloc(sizeof(SerdWriter)); writer->syntax = syntax; writer->style = style; writer->env = env; @@ -554,7 +554,7 @@ serd_writer_chop_blank_prefix(SerdWriter* writer, writer->bprefix = NULL; if (prefix) { writer->bprefix_len = strlen((const char*)prefix); - writer->bprefix = malloc(writer->bprefix_len + 1); + writer->bprefix = (uint8_t*)malloc(writer->bprefix_len + 1); memcpy(writer->bprefix, prefix, writer->bprefix_len + 1); } } diff --git a/tests/serd_test.c b/tests/serd_test.c index b94f7c1f..3c3855dc 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -150,7 +150,7 @@ main() // Test serd_node_new_blob for (size_t size = 0; size < 256; ++size) { - uint8_t* data = malloc(size); + uint8_t* data = (uint8_t*)malloc(size); for (size_t i = 0; i < size; ++i) { data[i] = (uint8_t)(rand() % 256); } @@ -164,7 +164,8 @@ main() } size_t out_size; - uint8_t* out = serd_base64_decode(blob.buf, blob.n_bytes, &out_size); + uint8_t* out = (uint8_t*)serd_base64_decode( + blob.buf, blob.n_bytes, &out_size); if (out_size != size) { fprintf(stderr, "error: Blob size %zu != %zu\n", out_size, size); return 1; @@ -369,18 +370,18 @@ main() // Test SerdReader and SerdWriter - const char* path = tmpnam(NULL); + const char* path = "serd_test.ttl"; FILE* fd = fopen(path, "w"); if (!fd) { fprintf(stderr, "Failed to open file %s\n", path); return 1; } - int* n_statements = malloc(sizeof(int)); + int* n_statements = (int*)malloc(sizeof(int)); *n_statements = 0; SerdWriter* writer = serd_writer_new( - SERD_TURTLE, 0, env, NULL, serd_file_sink, fd); + SERD_TURTLE, (SerdStyle)0, env, NULL, serd_file_sink, fd); if (!writer) { fprintf(stderr, "Failed to create writer\n"); return 1; @@ -1,5 +1,4 @@ #!/usr/bin/env python -import filecmp import glob import os import shutil @@ -47,7 +46,10 @@ def configure(conf): autowaf.configure(conf) autowaf.display_header('Serd Configuration') - conf.env.append_unique('CFLAGS', '-std=c99') + if conf.env['MSVC_COMPILER']: + conf.env.append_unique('CFLAGS', '-TP') + else: + conf.env.append_unique('CFLAGS', '-std=c99') conf.env['BUILD_TESTS'] = Options.options.build_tests conf.env['BUILD_UTILS'] = not Options.options.no_utils @@ -117,19 +119,25 @@ def build(bld): ''' libflags = [ '-fvisibility=hidden' ] + libs = [ 'm' ] + defines = [ '' ] if sys.platform == 'win32': libflags = [] + if bld.env['MSVC_COMPILER']: + libs = [] + defines = ['snprintf=_snprintf'] # Shared Library obj = bld(features = 'c cshlib', export_includes = ['.'], source = lib_source, includes = ['.', './src'], - lib = ['m'], + lib = libs, name = 'libserd', target = 'serd-%s' % SERD_MAJOR_VERSION, vnum = SERD_LIB_VERSION, install_path = '${LIBDIR}', + defines = defines, cflags = libflags + [ '-DSERD_SHARED', '-DSERD_INTERNAL' ]) @@ -139,15 +147,16 @@ def build(bld): export_includes = ['.'], source = lib_source, includes = ['.', './src'], - lib = ['m'], + lib = libs, name = 'libserd_static', target = 'serd-%s' % SERD_MAJOR_VERSION, vnum = SERD_LIB_VERSION, install_path = '${LIBDIR}', + defines = defines, cflags = [ '-DSERD_INTERNAL' ]) if bld.env['BUILD_TESTS']: - test_libs = ['m'] + test_libs = libs test_cflags = [''] if bld.is_defined('HAVE_GCOV'): test_libs += ['gcov'] @@ -161,6 +170,7 @@ def build(bld): name = 'libserd_profiled', target = 'serd_profiled', install_path = '', + defines = defines, cflags = test_cflags + ['-DSERD_INTERNAL']) # Unit test serdi @@ -171,6 +181,7 @@ def build(bld): lib = test_libs, target = 'serdi_static', install_path = '', + defines = defines, cflags = test_cflags) # Unit test program @@ -181,6 +192,7 @@ def build(bld): lib = test_libs, target = 'serd_test', install_path = '', + defines = defines, cflags = test_cflags) # Utilities @@ -257,6 +269,16 @@ def fix_docs(ctx): def upload_docs(ctx): os.system("rsync -ravz --delete -e ssh build/doc/html/ drobilla@drobilla.net:~/drobilla.net/docs/serd/") +def file_equals(patha, pathb, subst_from='', subst_to=''): + fa = open(patha, 'rU') + fb = open(pathb, 'rU') + for line in fa: + if line.replace(subst_from, subst_to) != fb.readline().replace(subst_from, subst_to): + return False + fa.close() + fb.close() + return True + def test(ctx): blddir = build_dir(ctx, 'tests') try: @@ -282,7 +304,7 @@ def test(ctx): autowaf.pre_test(ctx, APPNAME) - autowaf.run_tests(ctx, APPNAME, ['./serd_test'], dirs=['.']) + autowaf.run_tests(ctx, APPNAME, ['serd_test'], dirs=['.']) os.environ['PATH'] = '.' + os.pathsep + os.getenv('PATH') nul = os.devnull @@ -311,8 +333,9 @@ def test(ctx): commands = [] for test in good_tests: - base_uri = 'http://www.w3.org/2001/sw/DataAccess/df1/' + test - commands += [ 'serdi_static -f %s/%s \'%s\' > %s.out' % (srcdir, test, base_uri, test) ] + base_uri = 'http://www.w3.org/2001/sw/DataAccess/df1/' + test.replace('\\', '/') + commands += [ 'serdi_static -f "%s" "%s" > %s.out' % ( + os.path.join(srcdir, test), base_uri, test) ] autowaf.run_tests(ctx, APPNAME, commands, 0, name='good') @@ -321,21 +344,20 @@ def test(ctx): out_filename = test + '.out' if not os.access(out_filename, os.F_OK): Logs.pprint('RED', 'FAIL: %s output is missing' % test) - elif filecmp.cmp(srcdir + '/' + test.replace('.ttl', '.out'), - test + '.out', - False) != 1: + elif not file_equals(srcdir + '/' + test.replace('.ttl', '.out'), + test + '.out'): Logs.pprint('RED', 'FAIL: %s is incorrect' % out_filename) else: Logs.pprint('GREEN', 'Pass: %s' % test) commands = [] for test in bad_tests: - commands += [ 'serdi_static %s/%s \'http://www.w3.org/2001/sw/DataAccess/df1/%s\' > %s.out' % (srcdir, test, test, test) ] + commands += [ 'serdi_static "%s" "http://www.w3.org/2001/sw/DataAccess/df1/%s" > %s.out' % (os.path.join(srcdir, test), test.replace('\\', '/'), test) ] autowaf.run_tests(ctx, APPNAME, commands, 1, name='bad') thru_tests = good_tests - thru_tests.remove('tests/test-id.ttl') # IDs are mapped so files won't be identical + thru_tests.remove(os.path.join('tests', 'test-id.ttl')) # IDs are mapped so files won't be identical commands = [] num = 0 @@ -348,12 +370,12 @@ def test(ctx): flags += '-b' if (num % 5 == 0): flags += ' -f' - base_uri = 'http://www.w3.org/2001/sw/DataAccess/df1/' + test + base_uri = 'http://www.w3.org/2001/sw/DataAccess/df1/' + test.replace('\\', '/') out_filename = test + '.thru' commands += [ - '%s %s -i ntriples -o turtle -p foo %s/%s \'%s\' | %s -i turtle -o ntriples -c foo - \'%s\' | sed \'s/_:docid/_:genid/g\' > %s.thru' % ( + '%s %s -i ntriples -o turtle -p foo "%s" "%s" | %s -i turtle -o ntriples -c foo - "%s" > %s.thru' % ( 'serdi_static', flags.ljust(5), - srcdir, test, base_uri, + os.path.join(srcdir, test), base_uri, 'serdi_static', base_uri, test) ] autowaf.run_tests(ctx, APPNAME, commands, 0, name='turtle-round-trip') @@ -362,9 +384,9 @@ def test(ctx): out_filename = test + '.thru' if not os.access(out_filename, os.F_OK): Logs.pprint('RED', 'FAIL: %s output is missing' % test) - elif filecmp.cmp(srcdir + '/' + test.replace('.ttl', '.out'), - test + '.thru', - False) != 1: + elif not file_equals(srcdir + '/' + test.replace('.ttl', '.out'), + test + '.thru', + '_:docid', '_:genid'): Logs.pprint('RED', 'FAIL: %s is incorrect' % out_filename) else: Logs.pprint('GREEN', 'Pass: %s' % test) |