File: checkconfiguration.py

package info (click to toggle)
dune-common 2.10.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,824 kB
  • sloc: cpp: 52,256; python: 3,979; sh: 1,658; makefile: 17
file content (120 lines) | stat: -rw-r--r-- 5,728 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception

import logging
import os
import re
import subprocess

import dune.common.module

from dune.common.utility import buffer_to_str
from dune.generator import ConfigurationError, initializeDunePy

logger = logging.getLogger(__name__)

def _checkAndGetDunePyDir():
    # make sure dune-py is initialized before configuration is checked
    # in rare cases one might check the configuration before creating and configuring
    # the module. Checking the configuration can only be done after dune-py has been generated.
    initializeDunePy() # this will only do something if dune-py does not exist
    return dune.common.module.getDunePyDir()

def assertHave(identifier):
    '''check if an identifier is defined equal to 1 in the dune-py config.h file.
       use this to check if for example #define HAVE_DUNE_COMMON 1 is
       provided the config file by calling
       assertHave("HAVE_DUNE_COMMON")
    '''
    # the following simply will not work anymore - the issue is that the
    # approach used here requires dune-py to have already been setup before
    # calling 'assertHave' that is not guaranteed to be the case.
    # Possibly we can use the 'metadata' file instead.
    # We simply return for now
    raise RuntimeError("DEPRECATED USE OF assertHave")
    return
    config = os.path.join(_checkAndGetDunePyDir(), "config.h")
    if not os.path.isfile(config):
        raise ConfigurationError("dune-py not configured yet")

    matches = [match for match in [re.match(r'^[ ]*#define[ ]+' + identifier.strip() + '[ ]+1$', line) for line in open(config)] if match is not None]
    if not matches:
        matches = [match for match in [re.match(r'^[ ]*#define[ ]+' + identifier.strip() + '[ ]+ENABLE', line) for line in open(config)] if match is not None]
    if not matches:
        raise ConfigurationError(identifier + " is not set in dune-py's config.h")
    elif matches.__len__() > 1:
        raise ConfigurationError(identifier + " found multiple times in dune-py's config.h")
def assertCMakeHave(identifier):
    '''check if an identifier is defined equal to 1 in the dune-py config.h file.
       use this to check if for example #define HAVE_DUNE_COMMON 1 is
       provided the config file by calling
       assertHave("HAVE_DUNE_COMMON")

       Note: note that this depends on a dune-py having been completely
       configured so should be used with caution, e.g., avoid usage in any
       code executed during import of a dune module
    '''
    config = os.path.join(_checkAndGetDunePyDir(), "config.h")
    if not os.path.isfile(config):
        raise ConfigurationError("dune-py not configured yet")

    matches = [match for match in [re.match(r'^[ ]*#define[ ]+' + identifier.strip() + '[ ]+1$', line) for line in open(config)] if match is not None]
    if not matches:
        matches = [match for match in [re.match(r'^[ ]*#define[ ]+' + identifier.strip() + '[ ]+ENABLE', line) for line in open(config)] if match is not None]
    if not matches:
        raise ConfigurationError(identifier + " is not set in dune-py's config.h")
    elif matches.__len__() > 1:
        raise ConfigurationError(identifier + " found multiple times in dune-py's config.h")

def assertCMakeVariable(identifier,value,defaultFails):
    '''check if a variable in CMakeCache.txt in dune-py is defined and equal to 'value'
    '''
    cache = os.path.join(_checkAndGetDunePyDir(), "CMakeCache.txt")

    identifier = identifier.lower().strip()
    matches = [line.lower() for line in open(cache) if re.match(r'^[ ]*'+identifier+':+', line.lower()) is not None]
    if not matches and defaultFails:
        raise ConfigurationError(identifier + " default behavior is used in dune-py and that is not allowed")
    elif len(matches) > 1:
        raise ConfigurationError(identifier + " found multiple times in dune-py's config.h")
    elif matches:
        # check for bool on/off type variables:
        bools = {True:["on","true","1"], False:["off","false","0"]}
        if not [x for x in bools[value] if x in matches[0]]:
            raise ConfigurationError(identifier + " dune-py wrongly configured wrt "+identifier)

def preprocessorAssert(tests):
    '''perform preprocessore checks.
       A list of checks can be provided each should contain a pair, the
       first being the preprocessor check to perform (e.g. #if or #ifdef)
       and the second being the message to print if the check fails. The
       generated code is of the form:
          tests[i][0]
          #else
          test failed
          #endif
       so the first argument of each test has to make this piece of code
       valid C++ code assuming config.h is included.
    '''
    source = "#include <config.h>\nint main() {\n"
    i = 0
    for t in tests:
        source = source + t[0]+"\n#else\nreturn "+str(i+1)+";\n#endif\n"
        i += 1
    source = source + "return 0;\n}\n"

    from dune.generator import builder
    with open(os.path.join(builder.generated_dir, "generated_module.hh"), 'w') as out:
        out.write(source)
    builder.compile("generated_test")

    test_args = ["./generated_test"]
    test = subprocess.Popen(test_args, cwd=builder.generated_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = test.communicate()
    logger.debug(buffer_to_str(stdout))
    returncode = test.returncode

    if returncode > 0:
        logger.debug("failed testing:\n"+source)
        logger.critical("checking "+tests[returncode-1][0]+" failed: "+tests[returncode-1][1])
        raise ConfigurationError(tests[returncode-1][1])