aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbackends.py4
-rwxr-xr-xenvironment.py29
-rwxr-xr-xinterpreter.py10
-rw-r--r--test cases/common/35 sizeof/config.h.in1
-rw-r--r--test cases/common/35 sizeof/meson.build11
-rw-r--r--test cases/common/35 sizeof/prog.c10
6 files changed, 64 insertions, 1 deletions
diff --git a/backends.py b/backends.py
index 13e00b1..9265ade 100755
--- a/backends.py
+++ b/backends.py
@@ -41,8 +41,10 @@ def do_replacement(regex, line, confdata):
pass
elif isinstance(var, nodes.StringStatement):
var = var.get_value()
+ elif isinstance(var, int):
+ var = str(var)
else:
- raise RuntimeError('Tried to replace a variable with something other than a string.')
+ raise RuntimeError('Tried to replace a variable with something other than a string or int.')
else:
var = ''
line = line.replace('@' + varname + '@', var)
diff --git a/environment.py b/environment.py
index e6c25aa..00cc4e4 100755
--- a/environment.py
+++ b/environment.py
@@ -133,6 +133,35 @@ class CCompiler():
pass
return p.returncode == 0
+ def sizeof(self, element):
+ templ = '''#include<stdio.h>
+int main(int argc, char **argv) {
+ printf("%%ld\\n", (long)(sizeof(%s)));
+ return 0;
+};
+'''
+ (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
+ exename = srcname + '.exe' # Is guaranteed to be executable on every platform.
+ os.close(fd)
+ ofile = open(srcname, 'w')
+ code = templ % element
+ ofile.write(code)
+ ofile.close()
+ commands = self.get_exelist()
+ commands.append(srcname)
+ commands += self.get_output_flags(exename)
+ p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0])#s, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ p.communicate()
+ os.remove(srcname)
+ if p.returncode != 0:
+ raise EnvironmentException('Could not compile sizeof test.')
+ pe = subprocess.Popen(exename, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ so = pe.communicate()[0]
+ os.remove(exename)
+ if pe.returncode != 0:
+ raise EnvironmentException('Could not run sizeof test binary.')
+ return int(so.decode())
+
cxx_suffixes = ['cc', 'cpp', 'cxx', 'hh', 'hpp', 'hxx']
class CXXCompiler(CCompiler):
diff --git a/interpreter.py b/interpreter.py
index 5153c2e..fdbeed1 100755
--- a/interpreter.py
+++ b/interpreter.py
@@ -537,10 +537,19 @@ class CompilerHolder(InterpreterObject):
self.compiler = compiler
self.methods.update({'compiles': self.compiles_method,
'get_id': self.get_id_method,
+ 'sizeof': self.sizeof_method,
})
def get_id_method(self, args, kwargs):
return self.compiler.get_id()
+
+ def sizeof_method(self, args, kwargs):
+ if len(args) != 1:
+ raise InterpreterException('Sizeof takes exactly one argument.')
+ string = args[0]
+ if not isinstance(string, str):
+ raise InterpreterException('Argument to sizeof must be a string.')
+ return self.compiler.sizeof(string)
def compiles_method(self, args, kwargs):
if len(args) != 1:
@@ -944,6 +953,7 @@ class Interpreter():
isinstance(value, str) or\
isinstance(value, nodes.BoolStatement) or\
isinstance(value, nodes.IntStatement) or\
+ isinstance(value, int) or \
isinstance(value, list):
return True
return False
diff --git a/test cases/common/35 sizeof/config.h.in b/test cases/common/35 sizeof/config.h.in
new file mode 100644
index 0000000..b5ed4ca
--- /dev/null
+++ b/test cases/common/35 sizeof/config.h.in
@@ -0,0 +1 @@
+#define INTSIZE @INTSIZE@
diff --git a/test cases/common/35 sizeof/meson.build b/test cases/common/35 sizeof/meson.build
new file mode 100644
index 0000000..af04b4d
--- /dev/null
+++ b/test cases/common/35 sizeof/meson.build
@@ -0,0 +1,11 @@
+project('sizeof', 'c')
+
+cc = meson.get_compiler('c')
+intsize = cc.sizeof('int')
+
+cd = configuration_data()
+cd.set('INTSIZE', intsize)
+configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
+
+e = executable('prog', 'prog.c', include_dirs : include_directories('.'))
+add_test('sizeof test', e)
diff --git a/test cases/common/35 sizeof/prog.c b/test cases/common/35 sizeof/prog.c
new file mode 100644
index 0000000..68e3462
--- /dev/null
+++ b/test cases/common/35 sizeof/prog.c
@@ -0,0 +1,10 @@
+#include"config.h"
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ if(INTSIZE != sizeof(int)) {
+ fprintf(stderr, "Mismatch: detected int size %d, actual size %d.\n", INTSIZE, (int)sizeof(int));
+ return 1;
+ }
+ return 0;
+}