mapnik/scons/scons-local-4.8.1/SCons/Tool/MSCommon/MSVC/Policy.py
2024-09-09 10:56:17 +01:00

330 lines
11 KiB
Python
Vendored

# MIT License
#
# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
Microsoft Visual C/C++ policy handlers.
Notes:
* The default msvc not found policy is that a warning is issued. This can be
changed globally via the function set_msvc_notfound_policy and/or through
the environment via the MSVC_NOTFOUND_POLICY construction variable.
* The default msvc script error policy is to suppress all msvc batch file
error messages. This can be changed globally via the function
set_msvc_scripterror_policy and/or through the environment via the
MSVC_SCRIPTERROR_POLICY construction variable.
"""
from collections import (
namedtuple,
)
from contextlib import (
contextmanager,
)
import SCons.Warnings
from ..common import (
debug,
)
from .Exceptions import (
MSVCArgumentError,
MSVCVersionNotFound,
MSVCScriptExecutionError,
)
from .Warnings import (
MSVCScriptExecutionWarning,
)
from . import Dispatcher
Dispatcher.register_modulename(__name__)
# MSVC_NOTFOUND_POLICY definition:
# error: raise exception
# warning: issue warning and continue
# ignore: continue
MSVC_NOTFOUND_POLICY_DEFINITION = namedtuple('MSVCNotFoundPolicyDefinition', [
'value',
'symbol',
])
MSVC_NOTFOUND_DEFINITION_LIST = []
MSVC_NOTFOUND_POLICY_INTERNAL = {}
MSVC_NOTFOUND_POLICY_EXTERNAL = {}
for policy_value, policy_symbol_list in [
(True, ['Error', 'Exception']),
(False, ['Warning', 'Warn']),
(None, ['Ignore', 'Suppress']),
]:
policy_symbol = policy_symbol_list[0].lower()
policy_def = MSVC_NOTFOUND_POLICY_DEFINITION(policy_value, policy_symbol)
MSVC_NOTFOUND_DEFINITION_LIST.append(policy_def)
MSVC_NOTFOUND_POLICY_INTERNAL[policy_symbol] = policy_def
for policy_symbol in policy_symbol_list:
MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol.lower()] = policy_def
MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol] = policy_def
MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol.upper()] = policy_def
# default definition
_MSVC_NOTFOUND_POLICY_DEF = MSVC_NOTFOUND_POLICY_INTERNAL['warning']
# MSVC_SCRIPTERROR_POLICY definition:
# error: raise exception
# warning: issue warning and continue
# ignore: continue
MSVC_SCRIPTERROR_POLICY_DEFINITION = namedtuple('MSVCBatchErrorPolicyDefinition', [
'value',
'symbol',
])
MSVC_SCRIPTERROR_DEFINITION_LIST = []
MSVC_SCRIPTERROR_POLICY_INTERNAL = {}
MSVC_SCRIPTERROR_POLICY_EXTERNAL = {}
for policy_value, policy_symbol_list in [
(True, ['Error', 'Exception']),
(False, ['Warning', 'Warn']),
(None, ['Ignore', 'Suppress']),
]:
policy_symbol = policy_symbol_list[0].lower()
policy_def = MSVC_SCRIPTERROR_POLICY_DEFINITION(policy_value, policy_symbol)
MSVC_SCRIPTERROR_DEFINITION_LIST.append(policy_def)
MSVC_SCRIPTERROR_POLICY_INTERNAL[policy_symbol] = policy_def
for policy_symbol in policy_symbol_list:
MSVC_SCRIPTERROR_POLICY_EXTERNAL[policy_symbol.lower()] = policy_def
MSVC_SCRIPTERROR_POLICY_EXTERNAL[policy_symbol] = policy_def
MSVC_SCRIPTERROR_POLICY_EXTERNAL[policy_symbol.upper()] = policy_def
# default definition
_MSVC_SCRIPTERROR_POLICY_DEF = MSVC_SCRIPTERROR_POLICY_INTERNAL['ignore']
def _msvc_notfound_policy_lookup(symbol):
try:
notfound_policy_def = MSVC_NOTFOUND_POLICY_EXTERNAL[symbol]
except KeyError:
err_msg = "Value specified for MSVC_NOTFOUND_POLICY is not supported: {}.\n" \
" Valid values are: {}".format(
repr(symbol),
', '.join([repr(s) for s in MSVC_NOTFOUND_POLICY_EXTERNAL.keys()])
)
raise MSVCArgumentError(err_msg)
return notfound_policy_def
def msvc_set_notfound_policy(MSVC_NOTFOUND_POLICY=None):
""" Set the default policy when MSVC is not found.
Args:
MSVC_NOTFOUND_POLICY:
string representing the policy behavior
when MSVC is not found or None
Returns:
The previous policy is returned when the MSVC_NOTFOUND_POLICY argument
is not None. The active policy is returned when the MSVC_NOTFOUND_POLICY
argument is None.
"""
global _MSVC_NOTFOUND_POLICY_DEF
prev_policy = _MSVC_NOTFOUND_POLICY_DEF.symbol
policy = MSVC_NOTFOUND_POLICY
if policy is not None:
_MSVC_NOTFOUND_POLICY_DEF = _msvc_notfound_policy_lookup(policy)
debug(
'prev_policy=%s, set_policy=%s, policy.symbol=%s, policy.value=%s',
repr(prev_policy), repr(policy),
repr(_MSVC_NOTFOUND_POLICY_DEF.symbol), repr(_MSVC_NOTFOUND_POLICY_DEF.value)
)
return prev_policy
def msvc_get_notfound_policy():
"""Return the active policy when MSVC is not found."""
debug(
'policy.symbol=%s, policy.value=%s',
repr(_MSVC_NOTFOUND_POLICY_DEF.symbol), repr(_MSVC_NOTFOUND_POLICY_DEF.value)
)
return _MSVC_NOTFOUND_POLICY_DEF.symbol
def msvc_notfound_handler(env, msg):
if env and 'MSVC_NOTFOUND_POLICY' in env:
# environment setting
notfound_policy_src = 'environment'
policy = env['MSVC_NOTFOUND_POLICY']
if policy is not None:
# user policy request
notfound_policy_def = _msvc_notfound_policy_lookup(policy)
else:
# active global setting
notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF
else:
# active global setting
notfound_policy_src = 'default'
policy = None
notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF
debug(
'source=%s, set_policy=%s, policy.symbol=%s, policy.value=%s',
notfound_policy_src, repr(policy), repr(notfound_policy_def.symbol), repr(notfound_policy_def.value)
)
if notfound_policy_def.value is None:
# ignore
pass
elif notfound_policy_def.value:
raise MSVCVersionNotFound(msg)
else:
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
@contextmanager
def msvc_notfound_policy_contextmanager(MSVC_NOTFOUND_POLICY=None):
""" Temporarily change the MSVC not found policy within a context.
Args:
MSVC_NOTFOUND_POLICY:
string representing the policy behavior
when MSVC is not found or None
"""
prev_policy = msvc_set_notfound_policy(MSVC_NOTFOUND_POLICY)
yield
msvc_set_notfound_policy(prev_policy)
def _msvc_scripterror_policy_lookup(symbol):
try:
scripterror_policy_def = MSVC_SCRIPTERROR_POLICY_EXTERNAL[symbol]
except KeyError:
err_msg = "Value specified for MSVC_SCRIPTERROR_POLICY is not supported: {}.\n" \
" Valid values are: {}".format(
repr(symbol),
', '.join([repr(s) for s in MSVC_SCRIPTERROR_POLICY_EXTERNAL.keys()])
)
raise MSVCArgumentError(err_msg)
return scripterror_policy_def
def msvc_set_scripterror_policy(MSVC_SCRIPTERROR_POLICY=None):
""" Set the default policy when msvc batch file execution errors are detected.
Args:
MSVC_SCRIPTERROR_POLICY:
string representing the policy behavior
when msvc batch file execution errors are detected or None
Returns:
The previous policy is returned when the MSVC_SCRIPTERROR_POLICY argument
is not None. The active policy is returned when the MSVC_SCRIPTERROR_POLICY
argument is None.
"""
global _MSVC_SCRIPTERROR_POLICY_DEF
prev_policy = _MSVC_SCRIPTERROR_POLICY_DEF.symbol
policy = MSVC_SCRIPTERROR_POLICY
if policy is not None:
_MSVC_SCRIPTERROR_POLICY_DEF = _msvc_scripterror_policy_lookup(policy)
debug(
'prev_policy=%s, set_policy=%s, policy.symbol=%s, policy.value=%s',
repr(prev_policy), repr(policy),
repr(_MSVC_SCRIPTERROR_POLICY_DEF.symbol), repr(_MSVC_SCRIPTERROR_POLICY_DEF.value)
)
return prev_policy
def msvc_get_scripterror_policy():
"""Return the active policy when msvc batch file execution errors are detected."""
debug(
'policy.symbol=%s, policy.value=%s',
repr(_MSVC_SCRIPTERROR_POLICY_DEF.symbol), repr(_MSVC_SCRIPTERROR_POLICY_DEF.value)
)
return _MSVC_SCRIPTERROR_POLICY_DEF.symbol
def msvc_scripterror_handler(env, msg):
if env and 'MSVC_SCRIPTERROR_POLICY' in env:
# environment setting
scripterror_policy_src = 'environment'
policy = env['MSVC_SCRIPTERROR_POLICY']
if policy is not None:
# user policy request
scripterror_policy_def = _msvc_scripterror_policy_lookup(policy)
else:
# active global setting
scripterror_policy_def = _MSVC_SCRIPTERROR_POLICY_DEF
else:
# active global setting
scripterror_policy_src = 'default'
policy = None
scripterror_policy_def = _MSVC_SCRIPTERROR_POLICY_DEF
debug(
'source=%s, set_policy=%s, policy.symbol=%s, policy.value=%s',
scripterror_policy_src, repr(policy), repr(scripterror_policy_def.symbol), repr(scripterror_policy_def.value)
)
if scripterror_policy_def.value is None:
# ignore
pass
elif scripterror_policy_def.value:
raise MSVCScriptExecutionError(msg)
else:
SCons.Warnings.warn(MSVCScriptExecutionWarning, msg)
@contextmanager
def msvc_scripterror_policy_contextmanager(MSVC_SCRIPTERROR_POLICY=None):
""" Temporarily change the msvc batch execution errors policy within a context.
Args:
MSVC_SCRIPTERROR_POLICY:
string representing the policy behavior
when msvc batch file execution errors are detected or None
"""
prev_policy = msvc_set_scripterror_policy(MSVC_SCRIPTERROR_POLICY)
yield
msvc_set_scripterror_policy(prev_policy)