def test_array(self): self.assertEqual( Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.int)), Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.int))) self.assertNotEqual( Val((Val("1", type_=CTypes.int), Val("2", type_=CTypes.int)), type_=CTypes.array(CTypes.int)), Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.int))) self.assertNotEqual( Val((Val("1", type_=CTypes.char), ), type_=CTypes.array(CTypes.int)), Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.int))) self.assertNotEqual( Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.int)), Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.char))) self.assertNotEqual( Val((Val("2", type_=CTypes.int), ), type_=CTypes.array(CTypes.char)), Val((Val("1", type_=CTypes.int), ), type_=CTypes.array(CTypes.char)))
def test_malloc_and_free_in_main(self): chunk_size = 1645 main_func = make_main0( Decl("chunk", type_=CTypes.ptr(CTypes.void), expr=libc.malloc(Val(chunk_size, type_=CTypes.size))), libc.free(Var("chunk")), # yeah, no NULL check :) Return(Val(0, type_=CTypes.int))) expected = ("#include <stdlib.h>", "int main(void) {", "void* chunk = malloc(1645);", "free(chunk);", "return 0;", "}") self.check_gen([[main_func]], expected)
def test_fflush_non_null_stream(self): main_func = make_main0( libc.fputs(Val("some things here", type_=CTypes.ptr(CTypes.char)), libc.stdout), Decl("res", type_=CTypes.int, expr=libc.fflush(libc.stdout)), libc.assert_(Expr(COps.eq, Var("res"), Val(0, type_=CTypes.int))), Return(Val(0, type_=CTypes.int))) expected = ("#include <assert.h>", "#include <stdio.h>", "int main(void) {", "fputs(\"some things here\", stdout);", "int res = fflush(stdout);", "assert(res == 0);", "return 0;", "}") self.check_gen([[main_func]], expected)
def test_assert(self): var_name = "v" main_func = make_main0( Decl(var_name, type_=CTypes.ptr(CTypes.void), expr=libc.malloc(Val(10, type_=CTypes.size))), libc.assert_(Expr(COps.neq, Var(var_name), Null)), libc.free(Var(var_name)), Return(Val(0, type_=CTypes.int))) expected = ("#include <assert.h>", "#include <stdlib.h>", "int main(void) {", "void* v = malloc(10);", "assert(v != NULL);", "free(v);", "return 0;", "}") self.check_gen([[main_func]], expected)
def test_ptr(self): self.assertEqual(Val("ab", type_=CTypes.ptr(CTypes.char)), Val("ab", type_=CTypes.ptr(CTypes.char))) self.assertNotEqual(Val("ab", type_=CTypes.ptr(CTypes.uint_fast8)), Val("ab", type_=CTypes.ptr(CTypes.char))) self.assertNotEqual(Val("ab", type_=CTypes.ptr(CTypes.uint_fast8)), Val("ac", type_=CTypes.ptr(CTypes.uint_fast8)))
def test_fflush_null_stream(self): # http://man7.org/linux/man-pages/man3/fflush.3.html: # > If the stream argument is NULL, fflush() flushes all # > open output streams. main_func = make_main0( libc.fputs(Val("some things here", type_=CTypes.ptr(CTypes.char)), libc.stdout), Decl("res", type_=CTypes.int, expr=libc.fflush(Null)), libc.assert_(Expr(COps.eq, Var("res"), Val(0, type_=CTypes.int))), Return(Val(0, type_=CTypes.int))) expected = ("#include <assert.h>", "#include <stdio.h>", "int main(void) {", "fputs(\"some things here\", stdout);", "int res = fflush(NULL);", "assert(res == 0);", "return 0;", "}") self.check_gen([[main_func]], expected)
def test_fputs(self): for name, stream in (("stdout", libc.stdout), ("stderr", libc.stderr)): with self.subTest(stream=stream): main_func = make_main0( Decl("res", type_=CTypes.int, expr=libc.fputs( Val("test", type_=CTypes.ptr(CTypes.char)), stream)), libc.assert_( Expr(COps.gte, Var("res"), Val(0, type_=CTypes.int))), Return(Val(0, type_=CTypes.int))) expected = ("#include <assert.h>", "#include <stdio.h>", "int main(void) {", "int res = fputs(\"test\", {});".format(name), "assert(res >= 0);", "return 0;", "}") self.check_gen([[main_func]], expected)
from adrian.cgen import CFuncDescr, CNameDescr, CTypes, includes malloc = CFuncDescr("malloc", rettype=CTypes.ptr(CTypes.void), args=(CTypes.size, ), includes=[includes.stdlib]) free = CFuncDescr("free", rettype=CTypes.void, args=(CTypes.ptr(CTypes.void), ), includes=[includes.stdlib]) # According to http://man7.org/linux/man-pages/man3/assert.3.html: # > In C89, expression is required to be of type int and undefined # > behavior results if it is not, but in C99 it may have any scalar type. assert_ = CFuncDescr("assert", rettype=CTypes.void, args=(CTypes.int, ), includes=[includes.assert_]) stdout = CNameDescr("stdout", type_=CTypes.ptr(CTypes.file), includes=[includes.stdio]) stderr = CNameDescr("stderr", type_=CTypes.ptr(CTypes.file), includes=[includes.stdio]) fputs = CFuncDescr("fputs", rettype=CTypes.int, args=(CTypes.ptr(CTypes.char), CTypes.ptr(CTypes.file)), includes=[includes.stdio])
def test_array(self): self.assertNotEqual(CTypes.array(CTypes.int, size="auto"), CTypes.array(CTypes.int)) self.assertEqual(CTypes.array(CTypes.int), CTypes.array(CTypes.int)) self.assertNotEqual(CTypes.array(CTypes.int), CTypes.array(CTypes.size)) self.assertEqual(CTypes.array(CTypes.int, size="auto"), CTypes.array(CTypes.int, size="auto")) self.assertNotEqual(CTypes.array(CTypes.int, size=3), CTypes.array(CTypes.int, size="auto")) self.assertEqual(CTypes.array(CTypes.int, size=3), CTypes.array(CTypes.int, size=3)) self.assertNotEqual(CTypes.array(CTypes.int, size=3), CTypes.array(CTypes.int, size=4))
def test_ptr(self): self.assertEqual(CTypes.ptr(CTypes.int), CTypes.ptr(CTypes.int)) self.assertNotEqual(CTypes.ptr(CTypes.size), CTypes.ptr(CTypes.int)) self.assertEqual(CTypes.ptr(CTypes.ptr(CTypes.size)), CTypes.ptr(CTypes.ptr(CTypes.size)))