瀏覽代碼

Merge pull request #5792 from ghalliday/issue11300

HPCC-11300 Add -wall and #option ('all', ...)

Reviewed-By: Jamie Noss <james.noss@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 年之前
父節點
當前提交
bd9ee7e52a

+ 13 - 3
ecl/eclcc/eclcc.cpp

@@ -1014,9 +1014,18 @@ void EclCC::processSingleQuery(EclCompileInstance & instance,
         Owned<IPropertyTreeIterator> iter = instance.srcArchive->getElements("OnWarning");
         ForEach(*iter)
         {
+            const char * name = iter->query().queryProp("@name");
             const char * option = iter->query().queryProp("@value");
-            if (!severityMapper->addCommandLineMapping(option))
-                return;
+            if (name)
+            {
+                if (!severityMapper->addMapping(name, option))
+                    return;
+            }
+            else
+            {
+                if (!severityMapper->addCommandLineMapping(option))
+                    return;
+            }
         }
     }
 
@@ -2066,7 +2075,8 @@ const char * const helpText[] = {
     "    -specs file   Read eclcc configuration from specified file",
     "!   -split m:n    Process a subset m of n input files (only with -b option)",
     "    -v --verbose  Output additional tracing information while compiling",
-    "    -wcode=level  Set the severity for a particular warning code",
+    "    -wxxxx=level  Set the severity for a particular warning code or category",
+    "!                 -wall sets default severity for all warnings",
     "!                 level=ignore|log|warning|error|fail",
     "    --version     Output version information",
     "!   --timings     Output additional timing information",

+ 1 - 1
ecl/hql/hqlerror.cpp

@@ -28,7 +28,7 @@ public:
     virtual StringBuffer &  errorMessage(StringBuffer & ret) const { return ret.append(msg); }
     virtual MessageAudience errorAudience() const { return MSGAUD_user; }
     virtual const char* getFilename() const { return filename; }
-    virtual WarnErrorCategory getCategory() const { return WECunknown; }
+    virtual WarnErrorCategory getCategory() const { return CategoryUnknown; }
     virtual int getLine() const { return lineno; }
     virtual int getColumn() const { return column; }
     virtual int getPosition() const { return position; }

+ 16 - 1
ecl/hql/hqlerror.hpp

@@ -39,7 +39,22 @@ inline bool isFatal(ErrorSeverity severity) { return severity == SeverityFatal;
 //TBD in a separate commit - add support for warnings to be associated with different categories
 enum WarnErrorCategory
 {
-    WECunknown,
+    CategoryCast,       // Suspicious casts between types or out of range values
+    CategoryConfuse,    // Likely to cause confusion
+    CategoryDeprecated, // deprecated features or syntax
+    CategoryEfficiency, // Something that is likely to be inefficient
+    CategoryFuture,     // Likely to cause problems in future versions
+    CategoryIgnored,    // Something that has no effect, or is ignored
+    CategoryIndex,      // Unusual indexing of datasets or strings
+    CategoryMistyped,   // Almost certainly mistyped
+    CategorySyntax,     // Invalid syntax which is painless to recover from
+    CategoryUnusual,    // Not strictly speaking an error, but highly unusual and likely to be a mistake
+    CategoryUnexpected, // Code that could be correct, but has the potential for unexpected behaviour
+
+    CategoryError,
+    CategoryAll,
+    CategoryUnknown,
+    CategoryMax,
 };
 
 interface HQL_API IECLError: public IException

+ 2 - 0
ecl/hql/hqlerrors.hpp

@@ -475,6 +475,7 @@
 #define HQLERR_AtmostFollowUnknownSubstr        3133
 #define HQLERR_AtmostLegacyMismatch             3134
 #define HQLERR_PropertyArgumentNotConstant      3135
+#define HQLERR_InvalidErrorCategory             3136
 
 #define HQLERR_DedupFieldNotFound_Text          "Field removed from dedup could not be found"
 #define HQLERR_CycleWithModuleDefinition_Text   "Module definition contains an illegal cycle/recursive definition %s"
@@ -512,6 +513,7 @@
 #define HQLERR_AtmostFollowUnknownSubstr_Text   "ATMOST [1..*] on an unknown length string must be last in the optional list"
 #define HQLERR_AtmostLegacyMismatch_Text        "Legacy JOIN condition on field[1..*] should be included in the optional fields"
 #define HQLERR_PropertyArgumentNotConstant_Text "The argument to attribute '%s' must be a constant"
+#define HQLERR_InvalidErrorCategory_Text        "Unrecognised ONWARNING category '%s'"
 
 /* parser error */
 #define ERR_PARSER_CANNOTRECOVER    3005  /* The parser can not recover from previous error(s) */

+ 8 - 1
ecl/hql/hqlgram.y

@@ -1506,7 +1506,14 @@ setMetaCommand
                         }
     | HASH_ONWARNING '(' expression ',' warningAction ')'
                         {
-                            parser->normalizeExpression($3, type_int, false);
+                            if (isNumericType($3.queryExprType()))
+                            {
+                                parser->normalizeExpression($3, type_int, false);
+                            }
+                            else
+                            {
+                                parser->normalizeExpression($3, type_string, false);
+                            }
                             $$.setExpr(createValue(no_setmeta, makeVoidType(), createAttribute(onWarningAtom), $3.getExpr(), $5.getExpr()), $1);
                         }
     ;

+ 87 - 8
ecl/hql/hqlutil.cpp

@@ -6465,6 +6465,35 @@ ErrorSeverity getSeverity(IAtom * name)
     return SeverityUnknown;
 }
 
+WarnErrorCategory getCategory(const char * category)
+{
+    if (strieq(category, "all"))
+        return CategoryAll;
+    if (strieq(category, "cast"))
+        return CategoryCast;
+    if (strieq(category, "confuse"))
+        return CategoryConfuse;
+    if (strieq(category, "deprecated"))
+        return CategoryDeprecated;
+    if (strieq(category, "efficiency"))
+        return CategoryEfficiency;
+    if (strieq(category, "future"))
+        return CategoryFuture;
+    if (strieq(category, "ignored"))
+        return CategoryIgnored;
+    if (strieq(category, "index"))
+        return CategoryIndex;
+    if (strieq(category, "mistype"))
+        return CategoryMistyped;
+    if (strieq(category, "syntax"))
+        return CategorySyntax;
+    if (strieq(category, "unusual"))
+        return CategoryUnusual;
+    if (strieq(category, "unexpected"))
+        return CategoryUnexpected;
+    return CategoryUnknown;
+}
+
 static ErrorSeverity getCheckSeverity(IAtom * name)
 {
     ErrorSeverity severity = getSeverity(name);
@@ -6491,6 +6520,8 @@ ErrorSeverityMapper::ErrorSeverityMapper(IErrorReceiver & _errorProcessor) : Ind
 {
     firstActiveMapping = 0;
     activeSymbol = NULL;
+    for (unsigned category = 0; category < CategoryMax; category++)
+        categoryAction[category] = SeverityUnknown;
 }
 
 
@@ -6506,7 +6537,10 @@ bool ErrorSeverityMapper::addCommandLineMapping(const char * mapping)
     const char * equals = strchr(mapping, '=');
     const char * value;
     if (equals)
+    {
         value = equals+1;
+        len = equals-mapping;
+    }
     else if (mapping[len-1] == '+')
     {
         len--;
@@ -6520,24 +6554,46 @@ bool ErrorSeverityMapper::addCommandLineMapping(const char * mapping)
     else
         value = "error";
 
+    StringAttr category(mapping, len);
+    return addMapping(category, value);
+ }
+
+bool ErrorSeverityMapper::addMapping(const char * category, const char * value)
+{
+    if (!category || !*category)
+    {
+        ERRLOG("Error: No warning category supplied");
+        return false;
+    }
+
+    //Ignore mappings with no action
+    if (!value || !*value)
+        return true;
+
     IAtom * action = createAtom(value);
-    if (getSeverity(action) == SeverityUnknown)
+    ErrorSeverity severity = getSeverity(action);
+    if (severity == SeverityUnknown)
     {
-        fprintf(stderr, "invalid warning severity '%s'\n", value);
+        ERRLOG("Error: Invalid warning severity '%s'", value);
         return false;
     }
 
-    if (isdigit(mapping[0]))
+    if (isdigit(*category))
     {
-        unsigned errorCode = atoi(mapping);
+        unsigned errorCode = atoi(category);
         addOnWarning(errorCode, action);
         return true;
     }
-    else
+
+    WarnErrorCategory cat = getCategory(category);
+    if (cat != CategoryUnknown)
     {
-        fprintf(stderr, "mapping doesn't specify a valid warning code '%s'\n", mapping);
-        return false;
+        categoryAction[cat] = severity;
+        return true;
     }
+
+    ERRLOG("Error: Mapping doesn't specify a valid warning code or category '%s'", category);
+    return false;
 }
 
 void ErrorSeverityMapper::addOnWarning(unsigned code, IAtom * action)
@@ -6547,7 +6603,23 @@ void ErrorSeverityMapper::addOnWarning(unsigned code, IAtom * action)
 
 void ErrorSeverityMapper::addOnWarning(IHqlExpression * setMetaExpr)
 {
-    severityMappings.append(*createAttribute(onWarningAtom, LINK(setMetaExpr->queryChild(1)), LINK(setMetaExpr->queryChild(2))));
+    IHqlExpression * code = setMetaExpr->queryChild(1);
+    IHqlExpression * action = setMetaExpr->queryChild(2);
+    if (isStringType(code->queryType()))
+    {
+        StringBuffer text;
+        getStringValue(text, code, NULL);
+        WarnErrorCategory cat = getCategory(text);
+        ErrorSeverity severity = getSeverity(action->queryName());
+        if (cat == CategoryUnknown)
+            throwError1(HQLERR_InvalidErrorCategory, text.str());
+
+        categoryAction[cat] = severity;
+    }
+    else
+    {
+        severityMappings.append(*createAttribute(onWarningAtom, LINK(code), LINK(action)));
+    }
 }
 
 unsigned ErrorSeverityMapper::processMetaAnnotation(IHqlExpression * expr)
@@ -6598,6 +6670,13 @@ IECLError * ErrorSeverityMapper::mapError(IECLError * error)
         ErrorSeverity newSeverity = getWarningAction(mappedError->errorCode(), severityMappings, firstActiveMapping, SeverityUnknown);
         if (newSeverity != SeverityUnknown)
             return mappedError->cloneSetSeverity(newSeverity);
+
+        WarnErrorCategory category = mappedError->getCategory();
+        if (categoryAction[category] != SeverityUnknown)
+            return mappedError->cloneSetSeverity(categoryAction[category]);
+
+        if (categoryAction[CategoryAll] != SeverityUnknown)
+            return mappedError->cloneSetSeverity(categoryAction[CategoryAll]);
     }
     return mappedError.getClear();
 }

+ 2 - 0
ecl/hql/hqlutil.hpp

@@ -554,6 +554,7 @@ public:
     virtual IECLError * mapError(IECLError * error);
 
     bool addCommandLineMapping(const char * mapping);
+    bool addMapping(const char * category, const char * value);
     void addOnWarning(unsigned code, IAtom * action);
     void addOnWarning(IHqlExpression * setMetaExpr);
     unsigned processMetaAnnotation(IHqlExpression * expr);
@@ -573,6 +574,7 @@ protected:
     IHqlExpression * activeSymbol;
     HqlExprArray severityMappings;
     unsigned firstActiveMapping;
+    ErrorSeverity categoryAction[CategoryMax];
 };
 
 extern HQL_API bool isGlobalOnWarning(IHqlExpression * expr);

+ 25 - 0
ecl/regress/bind2.ecl

@@ -0,0 +1,25 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#onwarning ('all', error);
+
+f(integer x, integer y) := (x * y);
+g(integer x, integer y, integer z) := f(x, y) + f(x, y) + 1;
+h(integer x, integer y) := g(x, y, 8) + g(x, y, 9);
+
+person := dataset('person', { unsigned8 person_id, string1 per_sex; }, thor);
+output(person,{h(1,3)},'out.d00');      // need to common up if parameters are insignificant

+ 25 - 0
ecl/regress/bind2e.ecl

@@ -0,0 +1,25 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#onwarning ('aloadofrubbish', error);
+
+f(integer x, integer y) := (x * y);
+g(integer x, integer y, integer z) := f(x, y) + f(x, y) + 1;
+h(integer x, integer y) := g(x, y, 8) + g(x, y, 9);
+
+person := dataset('person', { unsigned8 person_id, string1 per_sex; }, thor);
+output(person,{h(1,3)},'out.d00');      // need to common up if parameters are insignificant

+ 1 - 1
ecl/regress/issue9556a.eclxml

@@ -1,7 +1,7 @@
 <Archive legacyImport="0"
          legacyWhen="0">
  <Query attributePath="_local_directory_.temp"/>
- <OnWarning value="1006=ignore"/>
+ <OnWarning name="1006" value="ignore"/>
  <Module key="_local_directory_" name="_local_directory_">
   <Attribute key="temp" name="temp" sourcePath="temp.ecl">
    case(0,&apos;default&apos;);&#10;&#10;&#10;