Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

nameChecks.c File Reference

#include "lclintMacros.nf"
#include "basic.h"
#include "nameChecks.h"
#include "reservedNames.nf"

Go to the source code of this file.

Defines

#define excludeFlagCodes(m_c)
#define end_excludeFlagCodes   }}
#define NRESERVEDNAMES   201
#define NCPPNAMES   39

Functions

void checkPrefix (uentry ue)
void checkGlobalName (uentry ue)
void checkLocalName ( uentry ue)
bool checkCppName (cstring name, fileloc loc)
bool checkAnsiName (cstring name, fileloc loc)
void checkParamNames (uentry ue)


Define Documentation

#define NCPPNAMES   39
 

Definition at line 1127 of file nameChecks.c.

#define NRESERVEDNAMES   201
 

Definition at line 1124 of file nameChecks.c.

#define end_excludeFlagCodes   }}
 

Definition at line 78 of file nameChecks.c.

#define excludeFlagCodes( m_c )
 

Initializer:

\
  { int m_i = 0; while (flagcode_isValid (excludeCodes[m_i])) \
      { flagcode m_c = excludeCodes[m_i]; m_i++;

Definition at line 74 of file nameChecks.c.

Referenced by checkPrefix().


Function Documentation

bool checkAnsiName ( cstring name,
fileloc loc )
 

Definition at line 1160 of file nameChecks.c.

Referenced by uentry_checkName().

01161 {
01162   bool hasError = FALSE;
01163   int length = cstring_length (name);
01164   char fchar = (length >= 1) ? cstring_firstChar (name) : '\0';
01165   char schar = (length >= 2) ? cstring_secondChar (name) : '\0';
01166   char tchar = (length >= 3) ? cstring_getChar (name, 3) : '\0';
01167   char rchar = (length >= 4) ? cstring_getChar (name, 4) : '\0';
01168 
01169   /* 
01170   ** reservedNames
01171   **   taken from Linden, "Expert C Programming", p. 126-8. 
01172   **   invariant:  must be sorted (case-insensitive, lexicographically)
01173   **               must end with NULL
01174   */
01175 
01176   static ob_mstring reservedNames[NRESERVEDNAMES] =
01177     { 
01178 # include "reservedNames.nf"
01179     } ;
01180 
01181   if (fileloc_isSystemFile (loc) || fileloc_isBuiltin (loc))
01182     {
01183       return FALSE;  /* no errors for system files */
01184     }
01185 
01186 # if 0
01187   {
01188     int i = 0;
01189     char *lastname = NULL;
01190     char *name;
01191     
01192     while ((name = reservedNames[i]) != NULL)
01193       {
01194         llassertprint (lastname == NULL
01195                        || strcmp (name, lastname) > 0,
01196                        ("%s / %s", lastname, name));
01197         lastname = name;
01198         i++;
01199       }
01200     
01201     nreservedNames = i - 1;
01202   }
01203 # endif
01204   
01205   if (cstring_isDefined (cstring_bsearch (name, &reservedNames[0],
01206                                           NRESERVEDNAMES)))
01207     {
01208       return (optgenerror
01209               (FLG_ANSIRESERVED,
01210                message ("Name %s is reserved for the standard library",
01211                         name),
01212                loc));
01213     }
01214 
01215   if (fchar == '_')
01216     {
01217       hasError = optgenerror
01218         (FLG_ANSIRESERVED,
01219          message 
01220          ("Name %s is in the implementation name space (any identifier "
01221           "beginning with underscore)", 
01222           name),
01223          loc);
01224     }
01225 
01226   /*
01227   ** 4.13.1 Errors <errno.h>
01228   **
01229   ** Macros that begin with E and a digit or E and an uppercase letter ...
01230   */
01231 
01232   else if (fchar == 'E' && (isdigit ((int) schar) 
01233                             || isupper ((int) schar)))
01234     {
01235       hasError = optgenerror
01236         (FLG_ANSIRESERVED,
01237          message 
01238          ("Name %s is reserved for future ANSI library extensions. "
01239           "Macros beginning with E and a digit or uppercase letter "
01240           "may be added to <errno.h>. (See ANSI, Section 4.13.1)",
01241           name),
01242          loc);
01243     }
01244   
01245   /*
01246   ** 4.13.2 Character Handling <ctype.h>
01247   **
01248   ** Function names that begin with either "is" or "to" and a lowercase letter ...
01249   */
01250 
01251   else if (((fchar == 'i' && schar == 's') 
01252             || (fchar == 't' && schar == 'o'))
01253            && (islower ((int) tchar)))
01254     {
01255       hasError = optgenerror
01256         (FLG_ANSIRESERVED,
01257          message
01258          ("Name %s is reserved for future ANSI library extensions.  "
01259           "Functions beginning with \"is\" or \"to\" and a lowercase "
01260           "letter may be added to <ctype.h>. (See ANSI, Section 4.13.2)",
01261           name),
01262          loc);
01263     }
01264   
01265   /*
01266   ** 4.13.3 Localization <locale.h>
01267   **
01268   ** Macros that begin with LC_ and an uppercase letter ...
01269   */
01270 
01271   else if (length >= 4 
01272            && ((fchar == 'L')
01273                && (schar == 'C')
01274                && (tchar == '_'))
01275            && (isupper ((int) rchar)))
01276     {
01277       hasError = optgenerror
01278         (FLG_ANSIRESERVED,
01279          message
01280          ("Name %s is reserved for future ANSI library extensions.  "
01281           "Macros beginning with \"LC_\" and an uppercase letter may "
01282           "be added to <locale.h>. (See ANSI, Section 4.13.3)",
01283           name),
01284          loc);
01285     }
01286   
01287   /*
01288   ** 4.13.4 Mathematics <math.h>
01289   **
01290   ** The names of all existing functions declared in the <math.h> header, 
01291   ** suffixed with f or l...
01292   */
01293 
01294   else if ((cstring_lastChar (name) == 'f' || cstring_lastChar (name) == 'l')
01295            && 
01296            (((length == 4)
01297              && ((cstring_equalPrefix (name, "cos") ||
01298                   cstring_equalPrefix (name, "sin") ||
01299                   cstring_equalPrefix (name, "tan") ||
01300                   cstring_equalPrefix (name, "exp") ||
01301                   cstring_equalPrefix (name, "log") ||
01302                   cstring_equalPrefix (name, "pow"))))
01303             || ((length == 5)
01304                 && ((cstring_equalPrefix (name, "acos") ||
01305                      cstring_equalPrefix (name, "asin") ||
01306                      cstring_equalPrefix (name, "atan") ||
01307                      cstring_equalPrefix (name, "cosh") ||
01308                      cstring_equalPrefix (name, "sinh") ||
01309                      cstring_equalPrefix (name, "sqrt") ||
01310                      cstring_equalPrefix (name, "ceil") ||
01311                      cstring_equalPrefix (name, "fabs") ||
01312                      cstring_equalPrefix (name, "fmod") ||
01313                      cstring_equalPrefix (name, "tanh") ||
01314                      cstring_equalPrefix (name, "modf"))))
01315             || ((length == 6)
01316                 && ((cstring_equalPrefix (name, "atan2") ||
01317                      cstring_equalPrefix (name, "floor") ||
01318                      cstring_equalPrefix (name, "frexp") ||
01319                      cstring_equalPrefix (name, "ldexp") ||
01320                      cstring_equalPrefix (name, "log10"))))))
01321     {
01322       hasError = optgenerror
01323         (FLG_ANSIRESERVED,
01324          message
01325          ("Name %s is reserved for future ANSI library extensions.  "
01326           "The names of all existing functions in <math.h> suffixed "
01327           "with 'f' or 'l' may be added to <math.h>. (See ANSI, Section 4.13.4)",
01328           name),
01329          loc);
01330     }
01331   
01332   /*
01333   ** 4.13.5 Signal Handling <signal.h>
01334   **
01335   ** Macros that begin with either SIG or SIG_ and an uppercase letter or...
01336   */
01337 
01338   else if (fchar == 'S' && schar == 'I' && tchar == 'G'
01339            && ((rchar == '_' && ((length >= 5 
01340                                   && isupper ((int) cstring_getChar (name, 5)))))
01341                || (isupper ((int) rchar))))
01342     {
01343       hasError = optgenerror
01344         (FLG_ANSIRESERVED,
01345          message
01346          ("Name %s is reserved for future ANSI library extensions.  "
01347           "Macros that begin with SIG and an uppercase letter or SIG_ "
01348           "and an uppercase letter may be added to "
01349           "<signal.h>. (See ANSI, Section 4.13.5)",
01350           name),
01351          loc);
01352     }
01353   
01354   /*
01355   ** 4.13.6 Input/Output <stdio.h>
01356   **
01357   ** (nothing to check)
01358   */
01359 
01360   /*
01361   ** 4.13.7 General Utilities <stdlib.h>
01362   **
01363   ** Functions names that begin with str and a lowercase letter may be added to <stdlib.h>.
01364   */
01365 
01366   else if (fchar == 's' && schar == 't' && tchar == 'r' 
01367            && (islower ((int) rchar)))
01368     {
01369       hasError = optgenerror
01370         (FLG_ANSIRESERVED,
01371          message
01372          ("Name %s is reserved for future ANSI library extensions.  "
01373           "Functions that begin with \"str\" and a lowercase letter "
01374           "may be added to <stdlib.h> or <string.h>. (See ANSI, Section 4.13.7)",
01375           name),
01376          loc);
01377     }
01378   
01379   /*
01380   ** 4.13.8 String Handling <string.h>
01381   **
01382   ** Function names that begin with str, mem, or wcs and a lowercase letter ...
01383   **
01384   ** (Note: already checked "str" above.)
01385   */
01386 
01387   else if (((fchar == 'm' && schar == 'e' && tchar == 'm')
01388             || (fchar == 'w' && schar == 'c' && tchar == 's'))
01389            && (islower ((int) rchar)))
01390     {
01391       hasError = optgenerror
01392         (FLG_ANSIRESERVED,
01393          message
01394          ("Name %s is reserved for future ANSI library extensions.  "
01395           "Functions that begin with \"mem\" or \"wcs\" and a "
01396           "lowercase letter letter may be added to <string.h>. (See ANSI, Section 4.13.8)",
01397           name),
01398          loc);
01399     }
01400   else
01401     {
01402       ;
01403     }
01404 
01405   return hasError;
01406 }

bool checkCppName ( cstring name,
fileloc loc )
 

Definition at line 1129 of file nameChecks.c.

Referenced by uentry_checkName().

01130 {
01131   static ob_mstring cppNames[NCPPNAMES] =
01132     {
01133       "and", "and_eq", "asm", 
01134       "bitand", "bitor", "bool", /* gasp: "bool", is special for lclint */
01135       "catch", "class", "compl", "const_class",
01136       "delete", "dynamic_cast", "false", "friend",
01137       "inline", "mutable", "namespace", "new",
01138       "not", "not_eq",
01139       "operator", "or", "or_eq", "overload",
01140       "private", "protected", "public",
01141       "reinterpret_cast", "static_cast",
01142       "template", "this", "throw", "true", "try",
01143       "typeid", "using", "virtual", "xor", "xor_eq"
01144       } ;
01145   
01146   if (cstring_isDefined (cstring_bsearch (name, &cppNames[0],
01147                                           NCPPNAMES)))
01148     {
01149       return (optgenerror
01150               (FLG_CPPNAMES,
01151                message ("Name %s is a keyword or reserved word in C++",
01152                         name),
01153                loc));
01154     }
01155 
01156   return FALSE;
01157 }

void checkGlobalName ( uentry ue )
 

Definition at line 1098 of file nameChecks.c.

Referenced by uentry_checkName().

01099 {
01100   if (!uentry_isStatic (ue) && uentry_hasName (ue))
01101     {
01102       checkNationalName (ue);
01103     }
01104   else
01105     {
01106       ;
01107     }
01108 }

void checkLocalName ( uentry ue )
 

Definition at line 1111 of file nameChecks.c.

Referenced by uentry_checkName().

01112 {
01113   ;
01114 }

void checkParamNames ( uentry ue )
 

Definition at line 1408 of file nameChecks.c.

Referenced by processNamedDecl().

01409 {
01410   cstring fpfx = context_getString (FLG_DECLPARAMPREFIX);
01411   bool noformal = context_getFlag (FLG_DECLPARAMNAME);
01412 
01413   llassert (uentry_isFunction (ue));
01414   
01415   if (cstring_isDefined (fpfx) || noformal)
01416     {
01417       uentryList params = uentry_getParams (ue);
01418       
01419       uentryList_elements (params, p)
01420         {
01421           if (uentry_hasName (p))
01422             {
01423               if (noformal && !cstring_isDefined (fpfx))
01424                 {
01425                   if (optgenerror
01426                       (FLG_DECLPARAMNAME, 
01427                        message ("Declaration parameter has name: %q",
01428                                 uentry_getName (p)),
01429                        uentry_whereLast (p)))
01430                     {
01431                       uentry_setHasNameError (p);
01432                     }
01433                 }
01434               else
01435                 {
01436                   cstring pname = uentry_getName (p);
01437                   
01438                   if (!cstring_equalPrefix (pname, cstring_toCharsSafe (fpfx)))
01439                     {
01440                       if (context_getFlag (FLG_NAMECHECKS))
01441                         {
01442                           if (optgenerror
01443                               (FLG_DECLPARAMPREFIX, 
01444                                message ("Declaration parameter name %s does not begin "
01445                                         "with protoparamprefix (%s)",
01446                                         pname, fpfx),
01447                                uentry_whereLast (p)))
01448                             {
01449                               uentry_setHasNameError (p);
01450                             }
01451                         }
01452                     }
01453                   cstring_free (pname);
01454                 }
01455             }
01456         } end_uentryList_elements ;
01457     }
01458 }

void checkPrefix ( uentry ue )
 

Definition at line 242 of file nameChecks.c.

Referenced by uentry_checkName().

00243 {
00244   cstring name = cstring_undefined;
00245   flagcode flag;
00246 
00247   if (uentry_isExpandedMacro (ue))
00248     {
00249       flag = FLG_UNCHECKEDMACROPREFIX;
00250     }
00251   else if (uentry_isAnyTag (ue))
00252     {
00253       flag = FLG_TAGPREFIX;
00254     }
00255   else if (uentry_isEnumConstant (ue))
00256     {
00257       flag = FLG_ENUMPREFIX;
00258     }
00259   else if (uentry_isDatatype (ue))
00260     {
00261       flag = FLG_TYPEPREFIX;
00262     }
00263   else if (uentry_isFileStatic (ue))
00264     {
00265       flag = FLG_FILESTATICPREFIX;
00266     }
00267   else if (uentry_isGlobal (ue))
00268     {
00269       flag = FLG_GLOBPREFIX;
00270     }
00271   else if (uentry_isVariable (ue))
00272     {
00273       if (uentry_isRefParam (ue))
00274         {
00275           return; /* already checked param */
00276         }
00277 
00278       if (context_inMacro ())
00279         {
00280           if (uentry_isAnyParam (ue))
00281             {
00282               if (uentry_isYield (ue))
00283                 {
00284                   flag = FLG_MACROVARPREFIX;
00285                 }
00286               else
00287                 {
00288                   flag = FLG_LOCALPREFIX;
00289                 }
00290             }
00291           else
00292             {
00293               flag = FLG_MACROVARPREFIX;
00294             }
00295         }
00296       else
00297         {
00298           flag = FLG_LOCALPREFIX;
00299         }
00300     }
00301   else if (uentry_isConstant (ue))
00302     {
00303       flag = FLG_CONSTPREFIX;
00304     }
00305   else if (uentry_isIter (ue))
00306     {
00307       flag = FLG_ITERPREFIX;
00308     }
00309   else if (uentry_isExported (ue))
00310     {
00311       flag = FLG_EXTERNALPREFIX;
00312     }
00313   else
00314     {
00315       llcontbug (message ("What is it: %q", uentry_unparseFull (ue)));
00316       return;
00317     }
00318 
00319   if (flag == FLG_TYPEPREFIX || flag == FLG_GLOBPREFIX
00320       || flag == FLG_ENUMPREFIX || flag == FLG_CONSTPREFIX)
00321     {
00322       if (flag == FLG_ENUMPREFIX)
00323         {
00324           if (!context_getFlag (flag))
00325             {
00326               flag = FLG_CONSTPREFIX;
00327             }
00328         }
00329 
00330       if (!context_getFlag (flag))
00331         {
00332           flag = FLG_EXTERNALPREFIX;
00333         }
00334     }
00335 
00336   if (context_getFlag (flag))
00337     {
00338       name = uentry_getName (ue);
00339       
00340       
00341       if (!matchPrefix (name, context_getString (flag)))
00342         {
00343           if (optgenerror
00344               (flag,
00345                message ("%s %s name is not consistent with %s "
00346                         "namespace prefix \"%s\"",
00347                         uentry_ekindName (ue),
00348                         name,
00349                         namespaceName (flag),
00350                         context_getString (flag)),
00351                uentry_whereLast (ue)))
00352             {
00353               uentry_setHasNameError (ue);
00354             }
00355         }
00356     }  
00357 
00358   excludeFlagCodes (code)
00359     {
00360       bool check = FALSE;
00361 
00362       if (context_getFlag (code))
00363         {
00364           /*@-loopswitchbreak@*/
00365           switch (code)
00366             {
00367             case FLG_MACROVARPREFIXEXCLUDE:
00368               check = (flag != FLG_MACROVARPREFIX);
00369               break;
00370             case FLG_TAGPREFIXEXCLUDE:
00371               check = (flag != FLG_TAGPREFIX);
00372               break;
00373             case FLG_ENUMPREFIXEXCLUDE:
00374               check = (flag != FLG_ENUMPREFIX);
00375               break;
00376             case FLG_FILESTATICPREFIXEXCLUDE:
00377               check = (flag != FLG_FILESTATICPREFIX);
00378               break;
00379             case FLG_GLOBPREFIXEXCLUDE:
00380               check = (flag != FLG_GLOBPREFIX);
00381               break;
00382             case FLG_TYPEPREFIXEXCLUDE:
00383               check = (flag != FLG_TYPEPREFIX);
00384               break;
00385             case FLG_EXTERNALPREFIXEXCLUDE:
00386               check = (flag != FLG_EXTERNALPREFIX
00387                        && flag != FLG_GLOBPREFIX
00388                        && flag != FLG_TYPEPREFIX
00389                        && flag != FLG_UNCHECKEDMACROPREFIX);
00390               break;
00391             case FLG_UNCHECKEDMACROPREFIXEXCLUDE:
00392               check = (flag != FLG_UNCHECKEDMACROPREFIX);
00393               break;
00394             case FLG_LOCALPREFIXEXCLUDE:
00395               check = (flag != FLG_LOCALPREFIX);
00396               break;
00397             case FLG_CONSTPREFIXEXCLUDE:
00398               check = (flag != FLG_CONSTPREFIX);
00399               break;
00400             case FLG_ITERPREFIXEXCLUDE:
00401               check = (flag != FLG_ITERPREFIX);
00402               break;
00403             BADDEFAULT;
00404             }
00405           /*@=loopswitchbreak@*/
00406 
00407           if (check)
00408             {
00409               flagcode rcode = namespaceExcluded (code);
00410               cstring pstring = context_getString (rcode);
00411 
00412               if (cstring_isDefined (pstring))
00413                 {
00414                   if (cstring_isUndefined (name))
00415                     {
00416                       name = uentry_getName (ue);
00417                     }
00418                   
00419                   if (matchPrefix (name, context_getString (rcode)))
00420                     {
00421                       if (optgenerror
00422                           (code,
00423                            message
00424                            ("%s %s name is not a %s (it is a %s), "
00425                             "but matches the %s "
00426                             "namespace prefix \"%s\"",
00427                             uentry_ekindName (ue),
00428                             name,
00429                             namespaceName (rcode),
00430                             namespaceName (flag),
00431                             namespaceName (rcode),
00432                             context_getString (rcode)),
00433                            uentry_whereLast (ue)))
00434                         {
00435                           uentry_setHasNameError (ue);
00436                         }
00437                     }
00438                 }
00439             }
00440         } 
00441     } end_excludeFlagCodes ;
00442 
00443   cstring_free (name);
00444 }


Generated at Fri Nov 3 18:58:04 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000