Can detect sizes of expressions.
This commit is contained in:
parent
3872cd024e
commit
ae62e8ca11
|
@ -41,8 +41,10 @@ def do_replacement(regex, line, confdata):
|
||||||
pass
|
pass
|
||||||
elif isinstance(var, nodes.StringStatement):
|
elif isinstance(var, nodes.StringStatement):
|
||||||
var = var.get_value()
|
var = var.get_value()
|
||||||
|
elif isinstance(var, int):
|
||||||
|
var = str(var)
|
||||||
else:
|
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:
|
else:
|
||||||
var = ''
|
var = ''
|
||||||
line = line.replace('@' + varname + '@', var)
|
line = line.replace('@' + varname + '@', var)
|
||||||
|
|
|
@ -133,6 +133,35 @@ class CCompiler():
|
||||||
pass
|
pass
|
||||||
return p.returncode == 0
|
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']
|
cxx_suffixes = ['cc', 'cpp', 'cxx', 'hh', 'hpp', 'hxx']
|
||||||
|
|
||||||
class CXXCompiler(CCompiler):
|
class CXXCompiler(CCompiler):
|
||||||
|
|
|
@ -537,11 +537,20 @@ class CompilerHolder(InterpreterObject):
|
||||||
self.compiler = compiler
|
self.compiler = compiler
|
||||||
self.methods.update({'compiles': self.compiles_method,
|
self.methods.update({'compiles': self.compiles_method,
|
||||||
'get_id': self.get_id_method,
|
'get_id': self.get_id_method,
|
||||||
|
'sizeof': self.sizeof_method,
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_id_method(self, args, kwargs):
|
def get_id_method(self, args, kwargs):
|
||||||
return self.compiler.get_id()
|
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):
|
def compiles_method(self, args, kwargs):
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
raise InterpreterException('compiles method takes exactly one argument.')
|
raise InterpreterException('compiles method takes exactly one argument.')
|
||||||
|
@ -944,6 +953,7 @@ class Interpreter():
|
||||||
isinstance(value, str) or\
|
isinstance(value, str) or\
|
||||||
isinstance(value, nodes.BoolStatement) or\
|
isinstance(value, nodes.BoolStatement) or\
|
||||||
isinstance(value, nodes.IntStatement) or\
|
isinstance(value, nodes.IntStatement) or\
|
||||||
|
isinstance(value, int) or \
|
||||||
isinstance(value, list):
|
isinstance(value, list):
|
||||||
return True
|
return True
|
||||||
return False
|
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…
Reference in New Issue