Commit 244c1acd authored by Sergio Costas's avatar Sergio Costas

Merge branch 'separate_code'

parents b5dd96eb 147d3788
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
#!/usr/bin/env python3
# Copyright 2017 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of CRUST
#
# CRUST is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License.
#
# CRUST is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
class crust_definitions(object):
version = "0.1a1"
# when a variable hasn't been assigned yet
VALUE_UNINITIALIZED = 0
# when a variable has been initialized to a non NULL value
VALUE_NULL = 1
# when a variable has been initialized to a NULL value
VALUE_NOT_NULL = 2
# when a variable has been initialized to a value that can be NULL or not NULL
VALUE_NOT_NULL_OR_NULL = 3
# when a variable NOT NULL is presumed to have been freed after have been passed on to a function
VALUE_FREED = 4
# when a variable NULL_OR_NOT_NULL is presumed to have been freed after have been passed on to a function
VALUE_FREED_OR_NULL = 5
# the variable is global, so it is presumed that, when used, it is INITIALIZED_OR_NULL, and when assigned is FREED
VALUE_GLOBAL = 6
# the variable is a function
VALUE_FUNCTION = 7
CONDITION_FALSE = 0
CONDITION_TRUE = 1
CONDITION_FALSE_TRUE = 2
MSG_NORMAL = 0
MSG_WARNING = 1
MSG_ERROR = 2
MSG_CRITICAL = 3
TYPE_NO_MATTER = 0
TYPE_NO_CRUST = 1
TYPE_CRUST = 2
state_str = ["VALUE_UNINITIALIZED", "VALUE_NULL", "VALUE_NOT_NULL", "VALUE_NOT_NULL_OR_NULL", "VALUE_FREED", "VALUE_FREED_OR_NULL", "VALUE_GLOBAL", "VALUE_FUNCTION" ]
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/env python3
# Copyright 2017 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of CRUST
#
# CRUST is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License.
#
# CRUST is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from ctypes import *
from crust import tokens
import sys
import subprocess
import gettext
import glob
import os
import pkg_resources
import copy
from crust.crust_definitions import crust_definitions
_ = gettext.gettext
class crust_open(crust_definitions):
""" Manages the source file to be read """
def __init__(self, headerpath, libpath):
self.id_counter = 0
with open(headerpath, "r") as header:
do_process = False
self.fields = []
for line in header.readlines():
line = line.strip()
if line == "":
continue
if line == "struct AST {":
do_process = True
continue
if line == "};":
do_process = False
break
if not do_process:
continue
line = line.replace(";", "")
if line.startswith("int "):
ctype = c_int
name = line[4:].strip()
elif line.startswith("char *"):
ctype = c_char_p
name = line[6:].strip()
elif line.startswith("bool "):
ctype = c_bool
name = line[5:].strip()
elif line.startswith("struct AST *"):
ctype = POINTER(self.AST_leaf)
name = line[12:].strip()
elif line.startswith("long long int"):
ctype = c_int64
name = line[13:].strip()
elif line.startswith("double"):
ctype = c_double
name = line[6:].strip()
else:
print("Unknown type '{:s}'".format(line))
sys.exit(0)
self.fields.append( (name, ctype) )
try:
self.AST_leaf._fields_ = self.fields[:]
except:
pass
cdll.LoadLibrary(libpath)
self.libcrust = CDLL(libpath)
self.libcrust.parse_file.restype = POINTER(self.AST_leaf)
self.libcrust.parse_file.argtypes = [c_bool, c_char_p]
self.libcrust.parse_data.restype = POINTER(self.AST_leaf)
self.libcrust.parse_data.argtypes = [c_bool, c_char_p, c_void_p, c_int]
self.libcrust.set_debug_values.argtypes = [c_int, c_int]
class VarNotFoundException(Exception):
pass
class FunctionNotFoundException(Exception):
pass
class AST_leaf(Structure):
pass
class AST_node(object):
def __init__(self):
super().__init__()
self.status = crust_definitions.VALUE_UNINITIALIZED
self.init_line = None
self.type = ""
self.name = ""
self.line = -1
self.next = None
self.intval = 0
self.floatval = 0.0
self.uid = None
def copy(self):
retval = crust_open.AST_node()
for element in self.__dict__:
setattr(retval, element, getattr(self, element))
return retval
def __str__(self):
first = True
salida = ""
for element in self.__dict__:
if not first:
salida += ", "
first = False
dato = getattr(self, element)
salida += "{:s}: ".format(element)
if dato is None:
salida += "None"
continue
if isinstance(dato, list):
salida += "pointer"
continue
salida += str(dato)
return salida
def read_file(self, filename, verbose, includes, defines, include_files, disable_cpp = False, write_preprocesed = None):
self.filename = os.path.abspath(filename)
if disable_cpp:
with open(filename,"r") as source_file:
datacode = ""
for line in source_file.readlines():
line = line.strip()
if line == "":
datacode += "\n"
continue
datacode += line+"\n"
datacode = datacode.encode("latin-1")
else:
params = ["cpp", filename, "-DENABLE_CRUST_TAGS -DENABLE_CRUST"]
for p in includes:
params.append("-I{:s}".format(p))
for p in defines:
params.append("-D{:s}".format(p))
for p in include_files:
params.append("-include")
params.append(p)
rv = subprocess.run(params, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if (rv.returncode != 0):
print (rv.stderr.decode("utf-8"))
return None
datacode = rv.stdout
datasize = len(datacode)
if write_preprocesed is not None:
with open(write_preprocesed,"wb") as preproc:
preproc.write(datacode)
retval = self.libcrust.parse_data(c_bool(verbose), c_char_p(filename.encode("utf8")), datacode, datasize)
if retval:
tree = self._fix_tree(retval)
retval = None
self.libcrust.free_all()
else:
sys.exit(-1)
return tree
def _fix_tree(self, node):
""" Creates a list with each statement in order, ready to be "executed" """
retval = []
while(node):
node = node.contents
newnode = self.AST_node()
for element in self.fields:
name = element[0]
data = getattr(node, name)
if data is not None:
if (name == "type"):
data = tokens.tokens.get_token(data)
if data == "END_BLOCK":
newnode.uid = self.id_counter
self.id_counter += 1
elif isinstance(data, bytes):
data = data.decode("utf8")
elif isinstance(data, POINTER(self.AST_leaf)):
if name == "next":
data = None
elif (name == "function_params"):
tmpdata = self._fix_tree(data)
if tmpdata is not None:
data = []
# if this node is a function call or a function definition, ensure
# that there is always a list here, even if it has no params
for tmp in tmpdata:
if tmp.type != "EMPTY_DECLARATOR":
data.append(tmp)
else:
data = None
else:
data = self._fix_tree(data)
setattr(newnode, element[0], data)
retval.append(newnode)
node = node.next
if len(retval) == 0:
retval = None
return retval
......@@ -1007,6 +1007,9 @@ class Test(unittest.TestCase):
def test244ReturnVoidPointer2(self):
self._generic_test("unitest/test244.c", [ (crust.crust.MSG_ERROR, "Function '{:s}' expects a return value, but the code exited without it", 'function_name') ])
def test245AssignBorrowedToBorrowed(self):
self._all_fine_test("unitest/test245.c")
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
typedef __crust__ unsigned char *crust_t;
#define NULL ((void *)0)
crust_t __crust_borrow__ function1();
void function2(crust_t __crust_borrow__);
void main() {
__crust_borrow__ crust_t var1;
__crust_borrow__ crust_t var2;
var1 = function1(); // Valid
var2 = var1; // since both are borrowed, this assignment doesn't invalidates var1
function2(var1);
function2(var1);
function2(var2);
function2(var2);
}
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