00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 # include "nameChecks.h"
00031
00032 static bool checkCzechName (uentry p_ue, flagcode p_czechflag, bool p_report)
00033 ;
00034
00035 static bool checkSlovakName (uentry p_ue, flagcode p_slovakflag, bool p_report)
00036 ;
00037
00038 static cstring czechPrefix (cstring name)
00039 {
00040 return (cstring_beforeChar (name, '_'));
00041 }
00042
00043 static cstring slovakPrefix (cstring name)
00044 {
00045 int i = 0;
00046
00047 cstring_chars (name, c)
00048 {
00049 if (isupper ((unsigned char) c))
00050 {
00051 return (cstring_prefix (name, i));
00052 }
00053 i++;
00054 } end_cstring_chars;
00055
00056 return cstring_undefined;
00057 }
00058
00059 static flagcode excludeCodes [] =
00060 {
00061 FLG_MACROVARPREFIXEXCLUDE,
00062 FLG_TAGPREFIXEXCLUDE,
00063 FLG_ENUMPREFIXEXCLUDE,
00064 FLG_FILESTATICPREFIXEXCLUDE,
00065 FLG_GLOBPREFIXEXCLUDE,
00066 FLG_TYPEPREFIXEXCLUDE,
00067 FLG_EXTERNALPREFIXEXCLUDE,
00068 FLG_UNCHECKEDMACROPREFIXEXCLUDE,
00069 FLG_LOCALPREFIXEXCLUDE,
00070 INVALID_FLAG
00071 } ;
00072
00073
00074 # define excludeFlagCodes(m_c) \
00075 { int m_i = 0; while (flagcode_isValid (excludeCodes[m_i])) \
00076 { flagcode m_c = excludeCodes[m_i]; m_i++;
00077
00078 # define end_excludeFlagCodes }}
00079
00080 static bool matchPrefixChar (int nc, int pc)
00081 {
00082 if (nc == pc)
00083 {
00084 return TRUE;
00085 }
00086 else
00087 {
00088 switch (pc)
00089 {
00090 case PFX_UPPERCASE:
00091 return isupper (nc);
00092 case PFX_LOWERCASE:
00093 return islower (nc);
00094 case PFX_ANY:
00095 return TRUE;
00096 case PFX_DIGIT:
00097 return isdigit (nc);
00098 case PFX_NOTUPPER:
00099 return !isupper (nc);
00100 case PFX_NOTLOWER:
00101 return !islower (nc);
00102 case PFX_ANYLETTER:
00103 return isalpha (nc);
00104 case PFX_ANYLETTERDIGIT:
00105 return (isdigit (nc) || isalpha (nc));
00106 default: return FALSE;
00107 }
00108 }
00109
00110 BADEXIT;
00111 }
00112
00113 static bool matchPrefix (cstring name, cstring prefix)
00114 {
00115 if (cstring_isUndefined (name)
00116 || cstring_isUndefined (prefix))
00117 {
00118 return TRUE;
00119 }
00120 else
00121 {
00122 int namelen = cstring_length (name);
00123 int last = (int) '\0';
00124 int n = 1;
00125
00126 cstring_chars (prefix, pc)
00127 {
00128 int nc;
00129
00130 if (pc == '*')
00131 {
00132 n++;
00133
00134
00135 while (n <= namelen)
00136 {
00137 nc = (int) cstring_getChar (name, n);
00138
00139 if (!matchPrefixChar (nc, last))
00140 {
00141 return FALSE;
00142 }
00143 n++;
00144 }
00145
00146 return TRUE;
00147 }
00148 else
00149 {
00150 if (n > namelen)
00151 {
00152 if ((cstring_length (prefix) >= n + 1)
00153 && cstring_getChar (prefix, n + 1) == '*')
00154 {
00155 return TRUE;
00156 }
00157 else
00158 {
00159 return FALSE;
00160 }
00161 }
00162
00163 nc = (int) cstring_getChar (name, n);
00164
00165 if (!matchPrefixChar (nc, (int) pc))
00166 {
00167 return FALSE;
00168 }
00169 }
00170
00171 last = (int) pc;
00172 n++;
00173 } end_cstring_chars;
00174
00175 return TRUE;
00176 }
00177 }
00178
00179 static flagcode
00180 namespaceExcluded (flagcode code)
00181 {
00182 switch (code)
00183 {
00184 case FLG_MACROVARPREFIXEXCLUDE:
00185 return (FLG_MACROVARPREFIX);
00186 case FLG_TAGPREFIXEXCLUDE:
00187 return (FLG_TAGPREFIX);
00188 case FLG_ENUMPREFIXEXCLUDE:
00189 return (FLG_ENUMPREFIX);
00190 case FLG_FILESTATICPREFIXEXCLUDE:
00191 return (FLG_FILESTATICPREFIX);
00192 case FLG_GLOBPREFIXEXCLUDE:
00193 return (FLG_GLOBPREFIX);
00194 case FLG_TYPEPREFIXEXCLUDE:
00195 return (FLG_TYPEPREFIX);
00196 case FLG_EXTERNALPREFIXEXCLUDE:
00197 return (FLG_EXTERNALPREFIX);
00198 case FLG_UNCHECKEDMACROPREFIXEXCLUDE:
00199 return (FLG_UNCHECKEDMACROPREFIX);
00200 case FLG_LOCALPREFIXEXCLUDE:
00201 return (FLG_LOCALPREFIX);
00202 case FLG_ITERPREFIXEXCLUDE:
00203 return (FLG_ITERPREFIX);
00204 case FLG_CONSTPREFIXEXCLUDE:
00205 return (FLG_CONSTPREFIX);
00206 BADDEFAULT;
00207 }
00208 }
00209
00210 static cstring
00211 namespaceName (flagcode flag)
00212 {
00213 switch (flag)
00214 {
00215 case FLG_MACROVARPREFIX:
00216 return cstring_makeLiteralTemp ("macro variable");
00217 case FLG_TAGPREFIX:
00218 return cstring_makeLiteralTemp ("tag");
00219 case FLG_ENUMPREFIX:
00220 return cstring_makeLiteralTemp ("enum member");
00221 case FLG_TYPEPREFIX:
00222 return cstring_makeLiteralTemp ("user-defined type");
00223 case FLG_FILESTATICPREFIX:
00224 return cstring_makeLiteralTemp ("file static");
00225 case FLG_GLOBPREFIX:
00226 return cstring_makeLiteralTemp ("global variable");
00227 case FLG_EXTERNALPREFIX:
00228 return cstring_makeLiteralTemp ("external");
00229 case FLG_LOCALPREFIX:
00230 return cstring_makeLiteralTemp ("local variable");
00231 case FLG_CONSTPREFIX:
00232 return cstring_makeLiteralTemp ("constant");
00233 case FLG_ITERPREFIX:
00234 return cstring_makeLiteralTemp ("iter");
00235 case FLG_UNCHECKEDMACROPREFIX:
00236 return cstring_makeLiteralTemp ("unchecked macro");
00237 BADDEFAULT;
00238 }
00239 }
00240
00241 void
00242 checkPrefix (uentry ue)
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;
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
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
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 }
00445
00446 static void
00447 checkNationalName (uentry ue)
00448 {
00449 flagcode czechflag;
00450 flagcode slovakflag;
00451 flagcode czechoslovakflag;
00452 bool gcf, gsf, gcsf;
00453
00454
00455 if (uentry_isFunction (ue)
00456 || uentry_isIter (ue)
00457 || uentry_isEndIter (ue))
00458 {
00459 czechflag = FLG_CZECHFUNCTIONS;
00460 slovakflag = FLG_SLOVAKFUNCTIONS;
00461 czechoslovakflag = FLG_CZECHOSLOVAKFUNCTIONS;
00462 }
00463 else if (uentry_isExpandedMacro (ue))
00464 {
00465 czechflag = FLG_CZECHMACROS;
00466 slovakflag = FLG_SLOVAKMACROS;
00467 czechoslovakflag = FLG_CZECHOSLOVAKMACROS;
00468 }
00469 else if (uentry_isVariable (ue))
00470 {
00471 if (uentry_isGlobal (ue) && context_getFlag (FLG_GLOBPREFIX))
00472 {
00473
00474 return;
00475 }
00476
00477 czechflag = FLG_CZECHVARS;
00478 slovakflag = FLG_SLOVAKVARS;
00479 czechoslovakflag = FLG_CZECHOSLOVAKVARS;
00480 }
00481 else if (uentry_isConstant (ue))
00482 {
00483 if (uentry_isGlobal (ue) && context_getFlag (FLG_CONSTPREFIX))
00484 {
00485
00486 return;
00487 }
00488
00489 czechflag = FLG_CZECHCONSTANTS;
00490 slovakflag = FLG_SLOVAKCONSTANTS;
00491 czechoslovakflag = FLG_CZECHOSLOVAKCONSTANTS;
00492 }
00493 else
00494 {
00495 if (uentry_isAnyTag (ue) || uentry_isEnumConstant (ue))
00496 {
00497 return;
00498 }
00499
00500 llassert (uentry_isDatatype (ue));
00501
00502 czechflag = FLG_CZECHTYPES;
00503 slovakflag = FLG_SLOVAKTYPES;
00504 czechoslovakflag = FLG_CZECHOSLOVAKTYPES;
00505 }
00506
00507 gcf = context_getFlag (czechflag);
00508 gsf = context_getFlag (slovakflag);
00509 gcsf = context_getFlag (czechoslovakflag);
00510
00511 if (gcf || (uentry_isFunction (ue)
00512 && context_getFlag (FLG_ACCESSCZECH)))
00513 {
00514 (void) checkCzechName (ue, czechflag, gcf);
00515 }
00516
00517 if (gsf || (uentry_isFunction (ue)
00518 && context_getFlag (FLG_ACCESSSLOVAK)))
00519 {
00520 (void) checkSlovakName (ue, slovakflag, gsf);
00521 }
00522
00523 if (gcsf)
00524 {
00525 if (uentry_isDatatype (ue))
00526 {
00527
00528 cstring name = uentry_rawName (ue);
00529 int charno = 1;
00530
00531 cstring_chars (name, c)
00532 {
00533 if (isupper ((unsigned char) c))
00534 {
00535 if (optgenerror
00536 (FLG_CZECHOSLOVAKTYPES,
00537 message
00538 ("%s %q name violates Czechoslovak naming convention. "
00539 "Czechoslovak datatype names should not use uppercase "
00540 "letters.",
00541 uentry_ekindName (ue),
00542 uentry_getName (ue)),
00543 uentry_whereLast (ue)))
00544 {
00545 uentry_setHasNameError (ue);
00546 }
00547 break;
00548 }
00549
00550 if (c == '_' && charno != 2 && charno != 3)
00551 {
00552 if (optgenerror
00553 (FLG_CZECHOSLOVAKTYPES,
00554 message ("%s %q name violates Czechoslovak naming "
00555 "convention. Czechoslovak datatype names "
00556 "should not use the _ charater.",
00557 uentry_ekindName (ue),
00558 uentry_getName (ue)),
00559 uentry_whereLast (ue)))
00560 {
00561 uentry_setHasNameError (ue);
00562 }
00563 break;
00564 }
00565
00566 charno++;
00567 } end_cstring_chars;
00568 }
00569 else
00570 {
00571 bool okay = checkCzechName (ue, czechflag, FALSE);
00572
00573
00574 okay |= checkSlovakName (ue, slovakflag, FALSE);
00575
00576 if (!okay)
00577 {
00578 if (optgenerror
00579 (czechoslovakflag,
00580 message ("%s %q name is not consistent with Czechoslovak "
00581 "naming convention.",
00582 uentry_ekindName (ue),
00583 uentry_getName (ue)),
00584 uentry_whereLast (ue)))
00585 {
00586 uentry_setHasNameError (ue);
00587 }
00588 }
00589 }
00590 }
00591 }
00592
00593 static bool checkCzechName (uentry ue, flagcode czechflag, bool report)
00594 {
00595 if (uentry_isDatatype (ue))
00596 {
00597
00598
00599
00600
00601
00602 cstring name = uentry_rawName (ue);
00603 int charno = 1;
00604
00605 cstring_chars (name, c)
00606 {
00607 if (c == '_' && charno != 2 && charno != 3)
00608 {
00609 if (report)
00610 {
00611 if (optgenerror
00612 (FLG_CZECHTYPES,
00613 message
00614 ("%s %q name violates Czech naming convention. "
00615 "Czech datatype names should not use the _ charater.",
00616 uentry_ekindName (ue),
00617 uentry_getName (ue)),
00618 uentry_whereLast (ue)))
00619 {
00620 uentry_setHasNameError (ue);
00621 }
00622 }
00623
00624 return FALSE;
00625 }
00626
00627 charno++;
00628 } end_cstring_chars;
00629 }
00630 else
00631 {
00632 typeIdSet acc = context_fileAccessTypes ();
00633 cstring pfx = czechPrefix (uentry_rawName (ue));
00634
00635 if (cstring_isEmpty (pfx))
00636 {
00637 if (uentry_isVariable (ue) || uentry_isConstant (ue))
00638 {
00639 ctype ct = uentry_getType (ue);
00640
00641 if (ctype_isAbstract (ct)
00642 && context_hasAccess (ctype_typeId (ct)))
00643 {
00644 if (report)
00645 {
00646 if (optgenerror
00647 (czechflag,
00648 message ("%s %q name is not consistent with Czech "
00649 "naming convention. The name should "
00650 "begin with %s_",
00651 uentry_ekindName (ue),
00652 uentry_getName (ue),
00653 ctype_unparse (ct)),
00654 uentry_whereLast (ue)))
00655 {
00656 uentry_setHasNameError (ue);
00657 }
00658 }
00659
00660 cstring_free (pfx);
00661 return FALSE;
00662 }
00663 }
00664 else if (uentry_isFunction (ue) || uentry_isIter (ue))
00665 {
00666 if (typeIdSet_isEmpty (acc))
00667 {
00668 ;
00669 }
00670 else
00671 {
00672 if (report)
00673 {
00674 if (optgenerror
00675 (czechflag,
00676 message ("%s %q name is not consistent with Czech "
00677 "naming convention. Accessible types: %q",
00678 uentry_ekindName (ue),
00679 uentry_getName (ue),
00680 typeIdSet_unparse (acc)),
00681 uentry_whereLast (ue)))
00682 {
00683 uentry_setHasNameError (ue);
00684 }
00685 }
00686
00687 cstring_free (pfx);
00688 return FALSE;
00689 }
00690 }
00691 else
00692 {
00693 ;
00694 }
00695 }
00696 else
00697 {
00698 if (usymtab_existsTypeEither (pfx))
00699 {
00700 ctype ct = usymtab_lookupAbstractType (pfx);
00701 typeId tid;
00702
00703 if (ctype_isUA (ct))
00704 {
00705 tid = ctype_typeId (ct);
00706
00707 if (ctype_isUser (ct) || context_hasAccess (tid))
00708 {
00709 ;
00710 }
00711 else
00712 {
00713 if (context_getFlag (FLG_ACCESSCZECH)
00714 || context_getFlag (FLG_ACCESSCZECHOSLOVAK))
00715 {
00716 if (!uentry_isVar (ue))
00717 {
00718 uentry_addAccessType (ue, tid);
00719 }
00720 }
00721 else
00722 {
00723 if (report)
00724 {
00725 if (llgenhinterror
00726 (czechflag,
00727 message
00728 ("%s %q name violates Czech naming "
00729 "convention. Czech prefix %s names "
00730 "an abstract type that is "
00731 "not accessible.",
00732 uentry_ekindName (ue),
00733 uentry_getName (ue),
00734 pfx),
00735 cstring_makeLiteral
00736 ("Use +accessczech to allow access to "
00737 "type <t> in functions "
00738 "named <t>_<name>."),
00739 uentry_whereLast (ue)))
00740 {
00741 uentry_setHasNameError (ue);
00742 }
00743 }
00744
00745 cstring_free (pfx);
00746 return FALSE;
00747 }
00748 }
00749 }
00750 else if (ctype_isManifestBool (ct))
00751 {
00752 if (context_canAccessBool ())
00753 {
00754 ;
00755 }
00756 else
00757 {
00758 if (context_getFlag (FLG_ACCESSCZECH)
00759 || context_getFlag (FLG_ACCESSCZECHOSLOVAK))
00760 {
00761 if (!uentry_isVar (ue))
00762 {
00763 tid = usymtab_getTypeId (context_getBoolName ());
00764 uentry_addAccessType (ue, tid);
00765 }
00766 }
00767 else
00768 {
00769 if (report)
00770 {
00771 if (llgenhinterror
00772 (czechflag,
00773 message
00774 ("%s %q name violates Czech naming "
00775 "convention. Type bool is not accessible.",
00776 uentry_ekindName (ue),
00777 uentry_getName (ue)),
00778 cstring_makeLiteral
00779 ("Use +accessczech to allow access to "
00780 "type <t> in functions named <t>_<name>."),
00781 uentry_whereLast (ue)))
00782 {
00783 uentry_setHasNameError (ue);
00784 }
00785 }
00786
00787 cstring_free (pfx);
00788 return FALSE;
00789 }
00790 }
00791 }
00792 else
00793 {
00794 ;
00795 }
00796 }
00797 else
00798 {
00799 if (cstring_equalLit (pfx, "int")
00800 || cstring_equalLit (pfx, "char")
00801 || cstring_equalLit (pfx, "short")
00802 || cstring_equalLit (pfx, "long")
00803 || cstring_equalLit (pfx, "unsigned")
00804 || cstring_equalLit (pfx, "signed")
00805 || cstring_equalLit (pfx, "float")
00806 || cstring_equalLit (pfx, "double"))
00807 {
00808 ;
00809 }
00810 else
00811 {
00812
00813
00814 if (cstring_equal (pfx, context_moduleName ()))
00815 {
00816 ;
00817 }
00818 else
00819 {
00820 if (report)
00821 {
00822 if (optgenerror
00823 (czechflag,
00824 message
00825 ("%s %q name violates Czech naming convention. "
00826 "Czech prefix %s is not the name of a type.",
00827 uentry_ekindName (ue),
00828 uentry_getName (ue),
00829 pfx),
00830 uentry_whereLast (ue)))
00831 {
00832 uentry_setHasNameError (ue);
00833 }
00834 }
00835
00836 cstring_free (pfx);
00837 return FALSE;
00838 }
00839 }
00840 }
00841 }
00842 cstring_free (pfx);
00843 }
00844
00845 return TRUE;
00846 }
00847
00848 static bool checkSlovakName (uentry ue, flagcode slovakflag, bool report)
00849 {
00850 if (uentry_isDatatype (ue))
00851 {
00852
00853
00854
00855
00856 if (context_getFlag (FLG_SLOVAK))
00857 {
00858 cstring name = uentry_rawName (ue);
00859
00860 cstring_chars (name, c)
00861 {
00862 if (isupper ((unsigned char) c))
00863 {
00864 if (report)
00865 {
00866 if (optgenerror
00867 (FLG_SLOVAKTYPES,
00868 message
00869 ("%s %q name violates Slovak naming convention. "
00870 "Slovak datatype names should not use uppercase "
00871 "letters.",
00872 uentry_ekindName (ue),
00873 uentry_getName (ue)),
00874 uentry_whereLast (ue)))
00875 {
00876 uentry_setHasNameError (ue);
00877 }
00878 }
00879 return FALSE;
00880 }
00881 } end_cstring_chars;
00882 }
00883 }
00884 else
00885 {
00886 typeIdSet acc = context_fileAccessTypes ();
00887 cstring pfx = slovakPrefix (uentry_rawName (ue));
00888
00889 if (cstring_isEmpty (pfx))
00890 {
00891 if (typeIdSet_isEmpty (acc))
00892 {
00893 ;
00894 }
00895 else
00896 {
00897 if (uentry_isFunction (ue))
00898 {
00899 if (report)
00900 {
00901 if (optgenerror
00902 (slovakflag,
00903 message ("%s %q name is not consistent with Slovak "
00904 "naming convention. Accessible types: %q",
00905 uentry_ekindName (ue),
00906 uentry_getName (ue),
00907 typeIdSet_unparse (acc)),
00908 uentry_whereLast (ue)))
00909 {
00910 uentry_setHasNameError (ue);
00911 }
00912 }
00913
00914 cstring_free (pfx);
00915 return FALSE;
00916 }
00917 else
00918 {
00919 ctype ct = uentry_getType (ue);
00920
00921 if (ctype_isUA (ct))
00922 {
00923 if (report)
00924 {
00925 if (optgenerror
00926 (slovakflag,
00927 message ("%s %q name is not consistent with "
00928 "Slovak naming convention. The "
00929 "name should begin with %s followed "
00930 "by an uppercase letter.",
00931 uentry_ekindName (ue),
00932 uentry_getName (ue),
00933 ctype_unparse (ct)),
00934 uentry_whereLast (ue)))
00935 {
00936 uentry_setHasNameError (ue);
00937 }
00938 }
00939
00940 cstring_free (pfx);
00941 return FALSE;
00942 }
00943 }
00944 }
00945 }
00946 else
00947 {
00948 if (usymtab_existsTypeEither (pfx))
00949 {
00950 ctype ct = usymtab_lookupAbstractType (pfx);
00951 typeId tid;
00952
00953 if (ctype_isUA (ct))
00954 {
00955 tid = ctype_typeId (ct);
00956
00957 if (ctype_isUser (ct) || context_hasAccess (tid))
00958 {
00959 ;
00960 }
00961 else
00962 {
00963 if (context_getFlag (FLG_ACCESSSLOVAK)
00964 || context_getFlag (FLG_ACCESSCZECHOSLOVAK))
00965 {
00966 if (!uentry_isVar (ue))
00967 {
00968 uentry_addAccessType (ue, tid);
00969 }
00970 }
00971 else
00972 {
00973 if (report)
00974 {
00975 if (llgenhinterror
00976 (slovakflag,
00977 message
00978 ("%s %q name violates Slovak naming "
00979 "convention. Slovak prefix %s names "
00980 "an abstract type that is not accessible.",
00981 uentry_ekindName (ue),
00982 uentry_getName (ue),
00983 pfx),
00984 cstring_makeLiteral
00985 ("Use +accessslovak to allow access to "
00986 "type <t> in functions named <t>_<name>."),
00987 uentry_whereLast (ue)))
00988 {
00989 uentry_setHasNameError (ue);
00990 }
00991 }
00992
00993 cstring_free (pfx);
00994 return FALSE;
00995 }
00996 }
00997 }
00998 else if (ctype_isManifestBool (ct))
00999 {
01000 if (context_canAccessBool ())
01001 {
01002 ;
01003 }
01004 else
01005 {
01006 if (context_getFlag (FLG_ACCESSSLOVAK)
01007 || context_getFlag (FLG_ACCESSCZECHOSLOVAK))
01008 {
01009 if (!uentry_isVar (ue))
01010 {
01011 tid = usymtab_getTypeId (context_getBoolName ());
01012 uentry_addAccessType (ue, tid);
01013 }
01014 }
01015 else
01016 {
01017 if (report)
01018 {
01019 if (llgenhinterror
01020 (slovakflag,
01021 message
01022 ("%s %q name violates Slovak naming convention. "
01023 "Type bool is not accessible.",
01024 uentry_ekindName (ue),
01025 uentry_getName (ue)),
01026 cstring_makeLiteral
01027 ("Use +accessslovak to allow access to "
01028 "type <t> in functions named <t>_<name>."),
01029 uentry_whereLast (ue)))
01030 {
01031 uentry_setHasNameError (ue);
01032 }
01033 }
01034
01035 cstring_free (pfx);
01036 return FALSE;
01037 }
01038 }
01039 }
01040 else
01041 {
01042 ;
01043 }
01044 }
01045 else
01046 {
01047 if (cstring_equalLit (pfx, "int")
01048 || cstring_equalLit (pfx, "char")
01049 || cstring_equalLit (pfx, "short")
01050 || cstring_equalLit (pfx, "long")
01051 || cstring_equalLit (pfx, "unsigned")
01052 || cstring_equalLit (pfx, "signed")
01053 || cstring_equalLit (pfx, "float")
01054 || cstring_equalLit (pfx, "double"))
01055 {
01056 ;
01057 }
01058 else
01059 {
01060
01061
01062 if (cstring_equal (pfx, context_moduleName ()))
01063 {
01064 ;
01065 }
01066 else
01067 {
01068 if (report)
01069 {
01070 if (optgenerror
01071 (slovakflag,
01072 message
01073 ("%s %q name violates Slovak naming convention. "
01074 "Slovak prefix %s is not the name of a type.",
01075 uentry_ekindName (ue),
01076 uentry_getName (ue),
01077 pfx),
01078 uentry_whereLast (ue)))
01079 {
01080 uentry_setHasNameError (ue);
01081 }
01082 }
01083
01084 cstring_free (pfx);
01085 return FALSE;
01086 }
01087 }
01088 }
01089 }
01090
01091 cstring_free (pfx);
01092 }
01093
01094 return TRUE;
01095 }
01096
01097 void
01098 checkGlobalName (uentry ue)
01099 {
01100 if (!uentry_isStatic (ue) && uentry_hasName (ue))
01101 {
01102 checkNationalName (ue);
01103 }
01104 else
01105 {
01106 ;
01107 }
01108 }
01109
01110 void
01111 checkLocalName ( uentry ue)
01112 {
01113 ;
01114 }
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 # define NRESERVEDNAMES 201
01125
01126
01127 # define NCPPNAMES 39
01128
01129 bool checkCppName (cstring name, fileloc loc)
01130 {
01131 static ob_mstring cppNames[NCPPNAMES] =
01132 {
01133 "and", "and_eq", "asm",
01134 "bitand", "bitor", "bool",
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 }
01158
01159 bool
01160 checkAnsiName (cstring name, fileloc loc)
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
01171
01172
01173
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;
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
01228
01229
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
01247
01248
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
01267
01268
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
01289
01290
01291
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
01334
01335
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
01356
01357
01358
01359
01360
01361
01362
01363
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
01381
01382
01383
01384
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 }
01407
01408 void checkParamNames (uentry ue)
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 }
01459
01460
01461
01462