Can detect sizes of expressions.

pull/15/head
Jussi Pakkanen 12 years ago
parent 3872cd024e
commit ae62e8ca11
  1. 4
      backends.py
  2. 29
      environment.py
  3. 10
      interpreter.py
  4. 1
      test cases/common/35 sizeof/config.h.in
  5. 11
      test cases/common/35 sizeof/meson.build
  6. 10
      test cases/common/35 sizeof/prog.c

@ -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)

@ -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):

@ -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

@ -0,0 +1 @@
#define INTSIZE @INTSIZE@

@ -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)

@ -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;
}
Loading…
Cancel
Save