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
|
||||
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,11 +537,20 @@ 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:
|
||||
raise InterpreterException('compiles method takes exactly one argument.')
|
||||
|
@ -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…
Reference in New Issue