1# MIT License 2# 3# Copyright The SCons Foundation 4# 5# Permission is hereby granted, free of charge, to any person obtaining 6# a copy of this software and associated documentation files (the 7# "Software"), to deal in the Software without restriction, including 8# without limitation the rights to use, copy, modify, merge, publish, 9# distribute, sublicense, and/or sell copies of the Software, and to 10# permit persons to whom the Software is furnished to do so, subject to 11# the following conditions: 12# 13# The above copyright notice and this permission notice shall be included 14# in all copies or substantial portions of the Software. 15# 16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 17# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 18# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24"""The SCons warnings framework.""" 25 26import sys 27 28import SCons.Errors 29 30class SConsWarning(SCons.Errors.UserError): 31 pass 32 33class WarningOnByDefault(SConsWarning): 34 pass 35 36 37# NOTE: If you add a new warning class, add it to the man page, too! 38# Not all warnings are defined here, some are defined in the location of use 39 40class TargetNotBuiltWarning(SConsWarning): # Should go to OnByDefault 41 pass 42 43class CacheVersionWarning(WarningOnByDefault): 44 pass 45 46class CacheWriteErrorWarning(SConsWarning): 47 pass 48 49class CorruptSConsignWarning(WarningOnByDefault): 50 pass 51 52class DependencyWarning(SConsWarning): 53 pass 54 55class DevelopmentVersionWarning(WarningOnByDefault): 56 pass 57 58class DuplicateEnvironmentWarning(WarningOnByDefault): 59 pass 60 61class FutureReservedVariableWarning(WarningOnByDefault): 62 pass 63 64class LinkWarning(WarningOnByDefault): 65 pass 66 67class MisleadingKeywordsWarning(WarningOnByDefault): 68 pass 69 70class MissingSConscriptWarning(WarningOnByDefault): 71 pass 72 73class NoObjectCountWarning(WarningOnByDefault): 74 pass 75 76class NoParallelSupportWarning(WarningOnByDefault): 77 pass 78 79class ReservedVariableWarning(WarningOnByDefault): 80 pass 81 82class StackSizeWarning(WarningOnByDefault): 83 pass 84 85class VisualCMissingWarning(WarningOnByDefault): 86 pass 87 88# Used when MSVC_VERSION and MSVS_VERSION do not point to the 89# same version (MSVS_VERSION is deprecated) 90class VisualVersionMismatch(WarningOnByDefault): 91 pass 92 93class VisualStudioMissingWarning(SConsWarning): 94 pass 95 96class FortranCxxMixWarning(LinkWarning): 97 pass 98 99 100# Deprecation warnings 101 102class FutureDeprecatedWarning(SConsWarning): 103 pass 104 105class DeprecatedWarning(SConsWarning): 106 pass 107 108class MandatoryDeprecatedWarning(DeprecatedWarning): 109 pass 110 111 112# Special case; base always stays DeprecatedWarning 113class PythonVersionWarning(DeprecatedWarning): 114 pass 115 116class DeprecatedSourceCodeWarning(FutureDeprecatedWarning): 117 pass 118 119class TaskmasterNeedsExecuteWarning(DeprecatedWarning): 120 pass 121 122class DeprecatedOptionsWarning(MandatoryDeprecatedWarning): 123 pass 124 125class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning): 126 pass 127 128class DeprecatedMissingSConscriptWarning(DeprecatedWarning): 129 pass 130 131 132# The below is a list of 2-tuples. The first element is a class object. 133# The second element is true if that class is enabled, false if it is disabled. 134_enabled = [] 135 136# If set, raise the warning as an exception 137_warningAsException = False 138 139# If not None, a function to call with the warning 140_warningOut = None 141 142def suppressWarningClass(clazz): 143 """Suppresses all warnings of type clazz or derived from clazz.""" 144 _enabled.insert(0, (clazz, False)) 145 146def enableWarningClass(clazz): 147 """Enables all warnings of type clazz or derived from clazz.""" 148 _enabled.insert(0, (clazz, True)) 149 150def warningAsException(flag=True): 151 """Set global _warningAsExeption flag. 152 153 Args: 154 flag: value to set warnings-as-exceptions to [default: True] 155 156 Returns: 157 The previous value. 158 """ 159 global _warningAsException 160 old = _warningAsException 161 _warningAsException = flag 162 return old 163 164def warn(clazz, *args): 165 """Issue a warning, accounting for SCons rules. 166 167 Check if warnings for this class are enabled. 168 If warnings are treated as exceptions, raise exception. 169 Use the global warning-emitter _warningOut, which allows selecting 170 different ways of presenting a traceback (see Script/Main.py) 171 """ 172 warning = clazz(args) 173 for cls, flag in _enabled: 174 if isinstance(warning, cls): 175 if flag: 176 if _warningAsException: 177 raise warning 178 179 if _warningOut: 180 _warningOut(warning) 181 break 182 183def process_warn_strings(arguments): 184 """Process requests to enable/disable warnings. 185 186 The requests are strings passed to the --warn option or the 187 SetOption('warn') function. 188 189 An argument to this option should be of the form "warning-class" 190 or "no-warning-class". The warning class is munged and has 191 the suffix "Warning" added in order to get an actual class name 192 from the classes above, which we need to pass to the 193 {enable,disable}WarningClass() functions. 194 195 For example, "deprecated" will enable the DeprecatedWarning class. 196 "no-dependency" will disable the DependencyWarning class. 197 198 As a special case, --warn=all and --warn=no-all will enable or 199 disable (respectively) the base class of all SCons warnings. 200 """ 201 202 def _classmunge(s): 203 """Convert a warning argument to SConsCase. 204 205 The result is CamelCase, except "Scons" is changed to "SCons" 206 """ 207 s = s.replace("-", " ").title().replace(" ", "") 208 return s.replace("Scons", "SCons") 209 210 for arg in arguments: 211 enable = True 212 if arg.startswith("no-"): 213 enable = False 214 arg = arg[len("no-") :] 215 if arg == 'all': 216 class_name = "SConsWarning" 217 else: 218 class_name = _classmunge(arg) + 'Warning' 219 try: 220 clazz = globals()[class_name] 221 except KeyError: 222 sys.stderr.write("No warning type: '%s'\n" % arg) 223 else: 224 if enable: 225 enableWarningClass(clazz) 226 elif issubclass(clazz, MandatoryDeprecatedWarning): 227 fmt = "Can not disable mandataory warning: '%s'\n" 228 sys.stderr.write(fmt % arg) 229 else: 230 suppressWarningClass(clazz) 231 232# Local Variables: 233# tab-width:4 234# indent-tabs-mode:nil 235# End: 236# vim: set expandtab tabstop=4 shiftwidth=4: 237