Skip to content

Commit

Permalink
#341 Tests+fixes (objectmgmt, build system)+resolver '.'
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Sep 16, 2015
1 parent 0d2f594 commit 9b14fb4
Show file tree
Hide file tree
Showing 18 changed files with 407 additions and 79 deletions.
18 changes: 16 additions & 2 deletions build/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,28 @@
INCLUDE ||= []
INCLUDE << "#{ENV['CORTO_HOME']}/include/corto/#{VERSION}/components"

generate = true
if defined? GENERATED_SOURCES then
# Don't generate project file if GENERATED_SOURCES is set, which implies that
# a subclass of component already is taking responsibility for code generation
# This could've been handled by the rake rules, which could see that, based on
# timestamps of the __load.c and packages.txt files regeneration is not needed.
# However, since file timestamps are only accurate up to a second, and tasks
# are run much faster in sequence (fortunately) the build system is not always
# capable to correctly derive the rules.
generate = false
end

GENERATED_SOURCES ||= []
GENERATED_SOURCES <<
".corto/#{TARGET}__load.c"

file ".corto/#{TARGET}__load.c" => [".corto/packages.txt", ".corto/components.txt"] do
verbose(false)
sh "mkdir -p .corto"
sh "corto pp --name #{TARGET} -g c_project --attr component=true"
if generate then
sh "mkdir -p .corto"
sh "corto pp --name #{TARGET} -g c_project --attr component=true"
end
end

task :prebuild => ".corto/#{TARGET}__load.c"
Expand Down
4 changes: 3 additions & 1 deletion build/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

TARGET = PACKAGE.split("::").last

PP_PRELOAD ||= []
GENERATED_SOURCES ||= []

GENERATED_SOURCES <<
Expand Down Expand Up @@ -46,9 +47,10 @@

file "include/#{TARGET}__type.h" => [GENFILE, ".corto/packages.txt", ".corto/components.txt"] do
verbose(false)
preload = PP_PRELOAD.join(" ")
sh "mkdir -p .corto"
sh "touch .corto/#{TARGET}__wrapper.c"
ret = system "corto pp #{GENFILE} --scope #{PACKAGE} --prefix #{PREFIX} --lang c"
ret = sh "corto pp #{preload} #{GENFILE} --scope #{PACKAGE} --prefix #{PREFIX} --lang c"
if !ret then
sh "rm include/#{TARGET}__type.h"
abort "\033[1;31m[ build failed ]\033[0;49m"
Expand Down
4 changes: 3 additions & 1 deletion generators/c/project/src/c_project.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ static cx_int16 c_projectGenerateMainHeaderFile(cx_generator g) {
g_fileWrite(file, "#endif\n");
g_fileWrite(file, "#endif\n\n");

g_fileClose(file);

return 0;
error:
return -1;
Expand Down Expand Up @@ -215,7 +217,7 @@ cx_int16 corto_genMain(cx_generator g) {
goto error;
}

if (g_getCurrent(g)) {
if (g->objects) {
if(c_projectGenerateDepMakefile(g)) {
goto error;
}
Expand Down
108 changes: 54 additions & 54 deletions packages/corto/lang/src/cx__bootstrap.h

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/corto/lang/src/cx_bitmask.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ cx_int16 _cx_bitmask_init(cx_bitmask this) {
/* $begin(::corto::lang::bitmask::init) */
cx_primitive(this)->kind = CX_BITMASK;
cx_primitive(this)->width = CX_WIDTH_32;
cx_setref(&cx_type(this)->defaultType, cx_constant_o);
return cx_primitive_init((cx_primitive)this);
/* $end */
}
4 changes: 2 additions & 2 deletions packages/corto/lang/src/cx_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static cx_bool cx_class_checkInterfaceCompatibility(cx_class this, cx_interface
}
} else {
cx_id id, id2;
cx_error("class '%s' is missing implementation for function '%s'", cx_fullname(this, id), cx_fullname(m_interface, id2));
cx_seterr("class '%s' is missing implementation for function '%s'", cx_fullname(this, id), cx_fullname(m_interface, id2));
compatible = FALSE;
}
}
Expand Down Expand Up @@ -242,7 +242,7 @@ cx_int16 _cx_class_construct(cx_class this) {

/* This will bind methods of potential base-class which is necessary before validating
* whether this class correctly (fully) implements its interface. */
result = cx_struct_construct(cx_struct(this));
result = cx_struct_construct(this);

/* Create interface vector */
if (!result) {
Expand Down
1 change: 0 additions & 1 deletion packages/corto/lang/src/cx_enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ cx_int16 _cx_enum_init(cx_enum this) {
/* $begin(::corto::lang::enum::init) */
cx_primitive(this)->kind = CX_ENUM;
cx_primitive(this)->width = CX_WIDTH_32;
cx_setref(&cx_type(this)->defaultType, cx_constant_o);
return cx_primitive_init((cx_primitive)this);
/* $end */
}
6 changes: 3 additions & 3 deletions packages/corto/lang/src/cx_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ cx_function* cx_vtableLookup(cx_vtable* vtable, cx_string member, cx_int32* i_ou

/* Searching backwards will ensure that when the member-string contains no arguments and the
* vtable has multiple matches, the most specific function is selected. */
for (i=vtable->length-1; i>=0 && d; i--) {
for (i = vtable->length - 1; i >= 0 && d; i--) {
if (buffer[i]) {
if (cx_overload(buffer[i], member, &d_t)) {
goto error;
Expand Down Expand Up @@ -409,6 +409,7 @@ cx_int16 _cx_interface_bindMethod(cx_interface this, cx_method method) {

/* vtableLookup failed (probably due to a failed overloading request) */
if (i == -1) {
cx_seterr("method lookup error for '%s'", cx_nameof(method));
goto error;
}

Expand All @@ -427,7 +428,7 @@ cx_int16 _cx_interface_bindMethod(cx_interface this, cx_method method) {
cx_setref(virtual, method);
} else {
cx_id id, id2;
cx_error("definition of method '%s' conflicts with existing method '%s'", cx_fullname(method, id), cx_fullname(*virtual, id2));
cx_seterr("definition of method '%s' conflicts with existing method '%s'", cx_fullname(method, id), cx_fullname(*virtual, id2));
goto error;
}
}
Expand Down Expand Up @@ -553,7 +554,6 @@ cx_int16 _cx_interface_init(cx_interface this) {
/* $begin(::corto::lang::interface::init) */
cx_type(this)->reference = TRUE;
cx_type(this)->kind = CX_COMPOSITE;
cx_setref(&cx_type(this)->defaultType, cx_member_o);
this->kind = CX_INTERFACE;
return cx_type_init(cx_type(this));
/* $end */
Expand Down
32 changes: 21 additions & 11 deletions packages/corto/lang/src/cx_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,8 +1338,13 @@ cx_string cx_fullname(cx_object o, cx_id buffer) {
depth = 0;

if (!o) {
*buffer = '\0';
return buffer;
cx_seterr("no object provided");
return NULL;
}

if (!buffer) {
cx_seterr("no buffer provided");
return NULL;
}

if (!cx_checkAttr(o, CX_ATTR_SCOPED)) {
Expand Down Expand Up @@ -1405,12 +1410,21 @@ cx_string cx_relname(cx_object from, cx_object o, cx_id buffer) {
cx_assert(from != NULL, "relname called with NULL for parameter 'from'.");
cx_assert(o != NULL, "relname called with NULL for parameter 'to'.");

if (from == root_o) {
cx_fullname(o, buffer);
if (from == o) {
strcpy(buffer, ".");
} else if (from == root_o) {
cx_id buff;
cx_fullname(o, buff);
strcpy(buffer, buff + 2);
} else {
cx_scopeStack(from, from_s, &from_i);
cx_scopeStack(o, o_s, &o_i);

if (from_i > o_i) {
cx_seterr("origin is not in path of object");
return NULL;
}

from_i--;
o_i--;
while(from_s[from_i] == o_s[o_i]) {
Expand Down Expand Up @@ -1517,7 +1531,6 @@ cx_uint16 cx__destruct(cx_object o) {
cx__deinitWritable(o);
}

/* Remove from anonymous cache */
if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
cx__deinitScope(o);
} else {
Expand Down Expand Up @@ -1820,13 +1833,9 @@ void cx_drop(cx_object o) {
iter = cx_llIter(walkData.objects);
while(cx_iterHasNext(&iter)) {
collected = cx_iterNext(&iter);
cx_release(collected);
cx_delete(collected);
/* Double free - because cx_drop itself introduced a keep. */
if (cx_checkAttr(collected, CX_ATTR_SCOPED)) {
cx_delete(collected);
} else {
cx_release(collected);
}
cx_release(collected);
}
cx_llFree(walkData.objects);
}
Expand Down Expand Up @@ -3240,6 +3249,7 @@ cx_int16 cx_overload(cx_object object, cx_string requested, cx_int32* distance)
*distance = -1;
return 0;
error:
cx_seterr("invalid query '%s'", requested);
return -1;
}

Expand Down
5 changes: 5 additions & 0 deletions packages/corto/lang/src/cx_resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ cx_object cx_resolve(cx_object _scope, cx_string str) {
return NULL;
}

if ((str[0] == '.') && (str[1] == '\0')) {
cx_claim(_scope);
return _scope;
}

if (*str == '<') {
return cx_resolveAddress(str);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/corto/lang/src/cx_string_deser.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ static cx_string cx_string_deserParse(cx_string str, struct cx_string_deserIndex
cx_string cx_string_deser(cx_string str, cx_string_deser_t* data) {
cx_char *ptr;
cx_bool createdNew = FALSE;
cx_bool typeProvided = TRUE;

{
cx_id buffer;
Expand All @@ -547,7 +546,6 @@ cx_string cx_string_deser(cx_string str, cx_string_deser_t* data) {
/* If no type is found, reset ptr */
if ((ch != '{')) {
ptr = str;
typeProvided = FALSE;
} else {
cx_object type;

Expand Down
2 changes: 1 addition & 1 deletion packages/corto/lang/src/cx_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ cx_int16 _cx_struct_construct(cx_struct this) {
/* Set size of self */
cx_type(this)->size = size;

return cx_interface_construct(cx_interface(this));
return cx_interface_construct(this);
error:
return -1;
/* $end */
Expand Down
75 changes: 75 additions & 0 deletions packages/corto/lang/test/src/test_Fullname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* test_Fullname.c
*
* This file contains the implementation for the generated interface.
*
* Don't mess with the begin and end tags, since these will ensure that modified
* code in interface functions isn't replaced when code is re-generated.
*/

#define test_LIB
#include "test.h"

/* ::test::Fullname::tc_null() */
cx_void _test_Fullname_tc_null(test_Fullname this) {
/* $begin(::test::Fullname::tc_null) */
cx_id id;

id[0] = 'a';
cx_string result = cx_fullname(NULL, id);
test_assert(result == NULL);
test_assert(id[0] == 'a');
cx_string err = cx_lasterr();
test_assert(err != NULL);
test_assert(!strcmp(err, "no object provided"));

/* $end */
}

/* ::test::Fullname::tc_nullBuffer() */
cx_void _test_Fullname_tc_nullBuffer(test_Fullname this) {
/* $begin(::test::Fullname::tc_nullBuffer) */

cx_string result = cx_fullname(this, NULL);
test_assert(result == NULL);
cx_string err = cx_lasterr();
test_assert(err != NULL);
test_assert(!strcmp(err, "no buffer provided"));

/* $end */
}

/* ::test::Fullname::tc_onelevel() */
cx_void _test_Fullname_tc_onelevel(test_Fullname this) {
/* $begin(::test::Fullname::tc_onelevel) */
cx_id id;

cx_string result = cx_fullname(corto_o, id);
test_assert(result == id);
test_assert(!strcmp(result, "::corto"));

/* $end */
}

/* ::test::Fullname::tc_root() */
cx_void _test_Fullname_tc_root(test_Fullname this) {
/* $begin(::test::Fullname::tc_root) */
cx_id id;

cx_string result = cx_fullname(root_o, id);
test_assert(result == id);
test_assert(!strcmp(result, "::"));

/* $end */
}

/* ::test::Fullname::tc_twolevels() */
cx_void _test_Fullname_tc_twolevels(test_Fullname this) {
/* $begin(::test::Fullname::tc_twolevels) */
cx_id id;

cx_string result = cx_fullname(corto_lang_o, id);
test_assert(result == id);
test_assert(!strcmp(result, "::corto::lang"));

/* $end */
}
Loading

0 comments on commit 9b14fb4

Please sign in to comment.