Commit e2a91641 authored by Sergio Costas's avatar Sergio Costas

Now manages direct calls to a function

parent d292075c
......@@ -11,6 +11,6 @@ if tree is None:
try:
variables,functions = lib.process_tree(tree)
lib.process_functions(tree,variables,functions)
except crusty.VarNotFoundException:
except crusty.crusty.VarNotFoundException:
pass
lib.print_errors()
......@@ -22,6 +22,8 @@ class crusty(object):
STATUS_FREED = 4
# the variable is global, so it is presumed that, when used, it is INITIALIZED_OR_NULL, and when assigned is FREED
STATUS_GLOBAL = 5
# the variable is a pointer to a function defined in this source file
STATUS_FUNCTION = 6
CONDITION_FALSE = 0
CONDITION_TRUE = 1
......@@ -221,6 +223,9 @@ class crusty(object):
variable = self._find_variable(var_container, var_name, line_number)
if variable["status"] == self.STATUS_GLOBAL:
return
if variable["status"] == self.STATUS_FUNCTION:
self._add_error(self.MSG_CRITICAL,"Trying to assign a value to the function name '{:s}' at line {:d}",str(var_name),line_number)
return
if (not force) and ((variable["properties"] & self.PROPERTY_CRUST_VARIABLE) != 0):
status = variable["status"]
if (status == crusty.STATUS_NOT_NULL) or (status == crusty.STATUS_NOT_NULL_OR_NULL):
......@@ -248,7 +253,7 @@ class crusty(object):
def _eval_condition(self,condition,var_container,function_container):
var_container = self._copy_container(var_container)
condition = condition[0]
print("Condicion: {:s}".format(condition.type))
#print("Condicion: {:s}".format(condition.type))
if (condition.type == "CONSTANT"):
if condition.intval == 0:
return [ (crusty.CONDITION_FALSE, var_container) ]
......@@ -502,6 +507,7 @@ class crusty(object):
for parameter in node.function_params:
parameters.append( self._get_variable_properties(parameter,True) )
function_container[node.name] = parameters
var_container[0][node.name] = { "properties":0, "status":crusty.STATUS_FUNCTION, "init_line": None, "pointer": 1, "enum": False }
continue
if node.type == "CRUSTY_DEBUG":
print("Debug: '{:s}'".format(str(var_container)))
......@@ -563,9 +569,6 @@ class crusty(object):
if len(options) > 1:
for option in options[1:]:
# create a new "execution thread" for each possible assignment value
newvar_container = option[1]
self._set_var_value(newvar_container,varname,option[0],node.line)
self._process_block(tree[counter+1:],newvar_container,function_container)
if (option[2] != self.TYPE_NO_MATTER) and (option[2] != this_is_crust):
if this_is_crust == self.TYPE_CRUST:
if option[3] is None:
......@@ -577,8 +580,9 @@ class crusty(object):
self._add_error(self.MSG_CRITICAL,"Assigning a crust pointer to the non-crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the crust pointer '{:s}' to the non-crust variable '{:s}' at line {:d}",option[3],varname,node.line)
var_container = options[0][1]
self._set_var_value(var_container,varname,options[0][0],node.line)
newvar_container = option[1]
self._set_var_value(newvar_container,varname,option[0],node.line)
self._process_block(tree[counter+1:],newvar_container,function_container)
if (options[0][2] != self.TYPE_NO_MATTER) and (options[0][2] != this_is_crust):
if this_is_crust == self.TYPE_CRUST:
if options[0][3] is None:
......@@ -590,6 +594,17 @@ class crusty(object):
self._add_error(self.MSG_CRITICAL,"Assigning a crust pointer to the non-crust variable '{:s}' at line {:d}",varname,node.line)
else:
self._add_error(self.MSG_CRITICAL,"Assigning the crust pointer '{:s}' to the non-crust variable '{:s}' at line {:d}",options[0][3],varname,node.line)
var_container = options[0][1]
self._set_var_value(var_container,varname,options[0][0],node.line)
continue
if node.type == "FUNCTION_CALL":
if (function_container[node.name][0] & self.PROPERTY_CRUST_VARIABLE) != 0:
self._add_error(self.MSG_ERROR,"Calling the function '{:s}' at line {:d}, but ignoring the crust-type return value",node.name,node.line)
options = self._eval_function_call(node,var_container,function_container)
if len(options) > 1:
for option in options[1:]:
self._process_block(tree[counter+1:],option[1],function_container)
var_container = options[0][1]
continue
# if node.type == "FOR":
# print("Tipo: {:s}; Nombre: {:s}".format(str(node.type),str(node.name)))
......
......@@ -125,7 +125,25 @@ class Test(unittest.TestCase):
self._all_fine_test("unitest/test26.c")
def testAssignNonCrustToCrust2(self):
self._generic_test("unitest/test27.c",True,crusty.crusty.MSG_CRITICAL,"Assigning a non-crust value to the crust variable '{:s}' at line {:d}","param",5)
self._generic_test("unitest/test27.c",False,crusty.crusty.MSG_CRITICAL,"Assigning a non-crust value to the crust variable '{:s}' at line {:d}","param",5)
def testCrustRetVal(self):
self._generic_test("unitest/test28.c",False,crusty.crusty.MSG_ERROR,"Calling the function '{:s}' at line {:d}, but ignoring the crust-type return value","function",5)
def testUseUninitialized2(self):
self._generic_test("unitest/test29.c",False,crusty.crusty.MSG_ERROR,"Parameter {:d} when calling function '{:s}' at line {:d} isn't initialized",1,"function",5)
def testUseFreed2(self):
self._generic_test("unitest/test30.c",False,crusty.crusty.MSG_ERROR,"Parameter {:d} when calling function '{:s}' at line {:d} was freed at line {:d}",1,"function",6,5)
def testPassedNonCrustyToCrusty2(self):
self._generic_test("unitest/test31.c",False,crusty.crusty.MSG_CRITICAL,"Expected a __crust_t__ variable at parameter {:d} when calling function '{:s}' at line {:d}, but passed non __crust_t__ variable",1,"function",6)
def testPassedCrustyToNonCrusty2(self):
self._generic_test("unitest/test32.c",True,crusty.crusty.MSG_CRITICAL,"Expected a non __crust_t__ variable at parameter {:d} when calling function '{:s}' at line {:d}, but passed a __crust_t__ variable",1,"function",6)
def testPassedOtherToCrusty2(self):
self._generic_test("unitest/test33.c",False,crusty.crusty.MSG_CRITICAL,"Expected a __crust_t__ variable at parameter {:d} when calling function '{:s}' at line {:d}",1,"function",5)
if __name__ == '__main__':
......
typedef __crust_t__ unsigned char *crust_t;
crust_t function(crust_t param3) {
function(NULL);
}
typedef __crust_t__ unsigned char *crust_t;
int function(crust_t param3) {
crust_t param4;
function(param4);
}
typedef __crust_t__ unsigned char *crust_t;
int function(crust_t param3) {
function(param3);
function(param3);
}
typedef __crust_t__ unsigned char *crust_t;
int function(crust_t param3) {
int *param = 1;
function(param);
}
typedef __crust_t__ unsigned char *crust_t;
int function(int param3) {
crust_t *param = NULL;
function(param);
}
typedef __crust_t__ unsigned char *crust_t;
int function(crust_t param3) {
function(2);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment