]>
Commit | Line | Data |
---|---|---|
616915dd | 1 | /* |
2 | ** LCLint - annotation-assisted static program checker | |
3 | ** Copyright (C) 1994-2000 University of Virginia, | |
4 | ** Massachusetts Institute of Technology | |
5 | ** | |
6 | ** This program is free software; you can redistribute it and/or modify it | |
7 | ** under the terms of the GNU General Public License as published by the | |
8 | ** Free Software Foundation; either version 2 of the License, or (at your | |
9 | ** option) any later version. | |
10 | ** | |
11 | ** This program is distributed in the hope that it will be useful, but | |
12 | ** WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | ** General Public License for more details. | |
15 | ** | |
16 | ** The GNU General Public License is available from http://www.gnu.org/ or | |
17 | ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
18 | ** MA 02111-1307, USA. | |
19 | ** | |
20 | ** For information on lclint: lclint-request@cs.virginia.edu | |
21 | ** To report a bug: lclint-bug@cs.virginia.edu | |
22 | ** For more information: http://lclint.cs.virginia.edu | |
23 | */ | |
24 | /* | |
25 | ** nameChecks.c | |
26 | */ | |
27 | ||
28 | # include "lclintMacros.nf" | |
29 | # include "basic.h" | |
30 | # include "nameChecks.h" | |
31 | ||
32 | static bool checkCzechName (uentry p_ue, flagcode p_czechflag, bool p_report) | |
33 | /*@modifies p_ue, g_msgstream@*/ ; | |
34 | ||
35 | static bool checkSlovakName (uentry p_ue, flagcode p_slovakflag, bool p_report) | |
36 | /*@modifies p_ue, g_msgstream@*/ ; | |
37 | ||
38 | static cstring czechPrefix (cstring name) | |
39 | { | |
40 | return (cstring_beforeChar (name, '_')); | |
41 | } | |
42 | ||
43 | static cstring slovakPrefix (cstring name) | |
44 | { | |
45 | int i = 0; | |
46 | ||
47 | cstring_chars (name, c) | |
48 | { | |
49 | if (isupper ((unsigned char) c)) | |
50 | { | |
51 | return (cstring_prefix (name, i)); | |
52 | } | |
53 | i++; | |
54 | } end_cstring_chars; | |
55 | ||
56 | return cstring_undefined; | |
57 | } | |
58 | ||
59 | static flagcode excludeCodes [] = | |
60 | { | |
61 | FLG_MACROVARPREFIXEXCLUDE, | |
62 | FLG_TAGPREFIXEXCLUDE, | |
63 | FLG_ENUMPREFIXEXCLUDE, | |
64 | FLG_FILESTATICPREFIXEXCLUDE, | |
65 | FLG_GLOBPREFIXEXCLUDE, | |
66 | FLG_TYPEPREFIXEXCLUDE, | |
67 | FLG_EXTERNALPREFIXEXCLUDE, | |
68 | FLG_UNCHECKEDMACROPREFIXEXCLUDE, | |
69 | FLG_LOCALPREFIXEXCLUDE, | |
70 | INVALID_FLAG | |
71 | } ; | |
72 | ||
73 | /*@iter excludeFlagCodes (yield flagcode code);@*/ | |
74 | # define excludeFlagCodes(m_c) \ | |
75 | { int m_i = 0; while (flagcode_isValid (excludeCodes[m_i])) \ | |
76 | { flagcode m_c = excludeCodes[m_i]; m_i++; | |
77 | ||
78 | # define end_excludeFlagCodes }} | |
79 | ||
80 | static bool matchPrefixChar (int nc, int pc) | |
81 | { | |
82 | if (nc == pc) | |
83 | { | |
84 | return TRUE; | |
85 | } | |
86 | else | |
87 | { | |
88 | switch (pc) | |
89 | { | |
90 | case PFX_UPPERCASE: | |
91 | return isupper (nc); | |
92 | case PFX_LOWERCASE: | |
93 | return islower (nc); | |
94 | case PFX_ANY: | |
95 | return TRUE; | |
96 | case PFX_DIGIT: | |
97 | return isdigit (nc); | |
98 | case PFX_NOTUPPER: | |
99 | return !isupper (nc); | |
100 | case PFX_NOTLOWER: | |
101 | return !islower (nc); | |
102 | case PFX_ANYLETTER: | |
103 | return isalpha (nc); | |
104 | case PFX_ANYLETTERDIGIT: | |
105 | return (isdigit (nc) || isalpha (nc)); | |
106 | default: return FALSE; | |
107 | } | |
108 | } | |
109 | ||
110 | BADEXIT; | |
111 | } | |
112 | ||
113 | static bool matchPrefix (cstring name, cstring prefix) | |
114 | { | |
115 | if (cstring_isUndefined (name) | |
116 | || cstring_isUndefined (prefix)) | |
117 | { | |
118 | return TRUE; | |
119 | } | |
120 | else | |
121 | { | |
122 | int namelen = cstring_length (name); | |
123 | int last = (int) '\0'; | |
124 | int n = 1; | |
125 | ||
126 | cstring_chars (prefix, pc) | |
127 | { | |
128 | int nc; | |
129 | ||
130 | if (pc == '*') | |
131 | { | |
132 | n++; | |
133 | ||
134 | ||
135 | while (n <= namelen) | |
136 | { | |
137 | nc = (int) cstring_getChar (name, n); | |
138 | ||
139 | if (!matchPrefixChar (nc, last)) | |
140 | { | |
141 | return FALSE; | |
142 | } | |
143 | n++; | |
144 | } | |
145 | ||
146 | return TRUE; | |
147 | } | |
148 | else | |
149 | { | |
150 | if (n > namelen) | |
151 | { | |
152 | if ((cstring_length (prefix) >= n + 1) | |
153 | && cstring_getChar (prefix, n + 1) == '*') | |
154 | { | |
155 | return TRUE; | |
156 | } | |
157 | else | |
158 | { | |
159 | return FALSE; | |
160 | } | |
161 | } | |
162 | ||
163 | nc = (int) cstring_getChar (name, n); | |
164 | ||
165 | if (!matchPrefixChar (nc, (int) pc)) | |
166 | { | |
167 | return FALSE; | |
168 | } | |
169 | } | |
170 | ||
171 | last = (int) pc; | |
172 | n++; | |
173 | } end_cstring_chars; | |
174 | ||
175 | return TRUE; | |
176 | } | |
177 | } | |
178 | ||
179 | static flagcode | |
180 | namespaceExcluded (flagcode code) /*@*/ | |
181 | { | |
182 | switch (code) | |
183 | { | |
184 | case FLG_MACROVARPREFIXEXCLUDE: | |
185 | return (FLG_MACROVARPREFIX); | |
186 | case FLG_TAGPREFIXEXCLUDE: | |
187 | return (FLG_TAGPREFIX); | |
188 | case FLG_ENUMPREFIXEXCLUDE: | |
189 | return (FLG_ENUMPREFIX); | |
190 | case FLG_FILESTATICPREFIXEXCLUDE: | |
191 | return (FLG_FILESTATICPREFIX); | |
192 | case FLG_GLOBPREFIXEXCLUDE: | |
193 | return (FLG_GLOBPREFIX); | |
194 | case FLG_TYPEPREFIXEXCLUDE: | |
195 | return (FLG_TYPEPREFIX); | |
196 | case FLG_EXTERNALPREFIXEXCLUDE: | |
197 | return (FLG_EXTERNALPREFIX); | |
198 | case FLG_UNCHECKEDMACROPREFIXEXCLUDE: | |
199 | return (FLG_UNCHECKEDMACROPREFIX); | |
200 | case FLG_LOCALPREFIXEXCLUDE: | |
201 | return (FLG_LOCALPREFIX); | |
202 | case FLG_ITERPREFIXEXCLUDE: | |
203 | return (FLG_ITERPREFIX); | |
204 | case FLG_CONSTPREFIXEXCLUDE: | |
205 | return (FLG_CONSTPREFIX); | |
206 | BADDEFAULT; | |
207 | } | |
208 | } | |
209 | ||
210 | static /*@observer@*/ cstring | |
211 | namespaceName (flagcode flag) /*@*/ | |
212 | { | |
213 | switch (flag) | |
214 | { | |
215 | case FLG_MACROVARPREFIX: | |
216 | return cstring_makeLiteralTemp ("macro variable"); | |
217 | case FLG_TAGPREFIX: | |
218 | return cstring_makeLiteralTemp ("tag"); | |
219 | case FLG_ENUMPREFIX: | |
220 | return cstring_makeLiteralTemp ("enum member"); | |
221 | case FLG_TYPEPREFIX: | |
222 | return cstring_makeLiteralTemp ("user-defined type"); | |
223 | case FLG_FILESTATICPREFIX: | |
224 | return cstring_makeLiteralTemp ("file static"); | |
225 | case FLG_GLOBPREFIX: | |
226 | return cstring_makeLiteralTemp ("global variable"); | |
227 | case FLG_EXTERNALPREFIX: | |
228 | return cstring_makeLiteralTemp ("external"); | |
229 | case FLG_LOCALPREFIX: | |
230 | return cstring_makeLiteralTemp ("local variable"); | |
231 | case FLG_CONSTPREFIX: | |
232 | return cstring_makeLiteralTemp ("constant"); | |
233 | case FLG_ITERPREFIX: | |
234 | return cstring_makeLiteralTemp ("iter"); | |
235 | case FLG_UNCHECKEDMACROPREFIX: | |
236 | return cstring_makeLiteralTemp ("unchecked macro"); | |
237 | BADDEFAULT; | |
238 | } | |
239 | } | |
240 | ||
241 | void | |
242 | checkPrefix (uentry ue) | |
243 | { | |
244 | cstring name = cstring_undefined; | |
245 | flagcode flag; | |
246 | ||
247 | if (uentry_isExpandedMacro (ue)) | |
248 | { | |
249 | flag = FLG_UNCHECKEDMACROPREFIX; | |
250 | } | |
251 | else if (uentry_isAnyTag (ue)) | |
252 | { | |
253 | flag = FLG_TAGPREFIX; | |
254 | } | |
255 | else if (uentry_isEnumConstant (ue)) | |
256 | { | |
257 | flag = FLG_ENUMPREFIX; | |
258 | } | |
259 | else if (uentry_isDatatype (ue)) | |
260 | { | |
261 | flag = FLG_TYPEPREFIX; | |
262 | } | |
263 | else if (uentry_isFileStatic (ue)) | |
264 | { | |
265 | flag = FLG_FILESTATICPREFIX; | |
266 | } | |
267 | else if (uentry_isGlobal (ue)) | |
268 | { | |
269 | flag = FLG_GLOBPREFIX; | |
270 | } | |
271 | else if (uentry_isVariable (ue)) | |
272 | { | |
273 | if (uentry_isRefParam (ue)) | |
274 | { | |
275 | return; /* already checked param */ | |
276 | } | |
277 | ||
278 | if (context_inMacro ()) | |
279 | { | |
280 | if (uentry_isAnyParam (ue)) | |
281 | { | |
282 | if (uentry_isYield (ue)) | |
283 | { | |
284 | flag = FLG_MACROVARPREFIX; | |
285 | } | |
286 | else | |
287 | { | |
288 | flag = FLG_LOCALPREFIX; | |
289 | } | |
290 | } | |
291 | else | |
292 | { | |
293 | flag = FLG_MACROVARPREFIX; | |
294 | } | |
295 | } | |
296 | else | |
297 | { | |
298 | flag = FLG_LOCALPREFIX; | |
299 | } | |
300 | } | |
301 | else if (uentry_isConstant (ue)) | |
302 | { | |
303 | flag = FLG_CONSTPREFIX; | |
304 | } | |
305 | else if (uentry_isIter (ue)) | |
306 | { | |
307 | flag = FLG_ITERPREFIX; | |
308 | } | |
309 | else if (uentry_isExported (ue)) | |
310 | { | |
311 | flag = FLG_EXTERNALPREFIX; | |
312 | } | |
313 | else | |
314 | { | |
315 | llcontbug (message ("What is it: %q", uentry_unparseFull (ue))); | |
316 | return; | |
317 | } | |
318 | ||
319 | if (flag == FLG_TYPEPREFIX || flag == FLG_GLOBPREFIX | |
320 | || flag == FLG_ENUMPREFIX || flag == FLG_CONSTPREFIX) | |
321 | { | |
322 | if (flag == FLG_ENUMPREFIX) | |
323 | { | |
324 | if (!context_getFlag (flag)) | |
325 | { | |
326 | flag = FLG_CONSTPREFIX; | |
327 | } | |
328 | } | |
329 | ||
330 | if (!context_getFlag (flag)) | |
331 | { | |
332 | flag = FLG_EXTERNALPREFIX; | |
333 | } | |
334 | } | |
335 | ||
336 | if (context_getFlag (flag)) | |
337 | { | |
338 | name = uentry_getName (ue); | |
339 | ||
340 | ||
341 | if (!matchPrefix (name, context_getString (flag))) | |
342 | { | |
343 | if (optgenerror | |
344 | (flag, | |
345 | message ("%s %s name is not consistent with %s " | |
346 | "namespace prefix \"%s\"", | |
347 | uentry_ekindName (ue), | |
348 | name, | |
349 | namespaceName (flag), | |
350 | context_getString (flag)), | |
351 | uentry_whereLast (ue))) | |
352 | { | |
353 | uentry_setHasNameError (ue); | |
354 | } | |
355 | } | |
356 | } | |
357 | ||
358 | excludeFlagCodes (code) | |
359 | { | |
360 | bool check = FALSE; | |
361 | ||
362 | if (context_getFlag (code)) | |
363 | { | |
364 | /*@-loopswitchbreak@*/ | |
365 | switch (code) | |
366 | { | |
367 | case FLG_MACROVARPREFIXEXCLUDE: | |
368 | check = (flag != FLG_MACROVARPREFIX); | |
369 | break; | |
370 | case FLG_TAGPREFIXEXCLUDE: | |
371 | check = (flag != FLG_TAGPREFIX); | |
372 | break; | |
373 | case FLG_ENUMPREFIXEXCLUDE: | |
374 | check = (flag != FLG_ENUMPREFIX); | |
375 | break; | |
376 | case FLG_FILESTATICPREFIXEXCLUDE: | |
377 | check = (flag != FLG_FILESTATICPREFIX); | |
378 | break; | |
379 | case FLG_GLOBPREFIXEXCLUDE: | |
380 | check = (flag != FLG_GLOBPREFIX); | |
381 | break; | |
382 | case FLG_TYPEPREFIXEXCLUDE: | |
383 | check = (flag != FLG_TYPEPREFIX); | |
384 | break; | |
385 | case FLG_EXTERNALPREFIXEXCLUDE: | |
386 | check = (flag != FLG_EXTERNALPREFIX | |
387 | && flag != FLG_GLOBPREFIX | |
388 | && flag != FLG_TYPEPREFIX | |
389 | && flag != FLG_UNCHECKEDMACROPREFIX); | |
390 | break; | |
391 | case FLG_UNCHECKEDMACROPREFIXEXCLUDE: | |
392 | check = (flag != FLG_UNCHECKEDMACROPREFIX); | |
393 | break; | |
394 | case FLG_LOCALPREFIXEXCLUDE: | |
395 | check = (flag != FLG_LOCALPREFIX); | |
396 | break; | |
397 | case FLG_CONSTPREFIXEXCLUDE: | |
398 | check = (flag != FLG_CONSTPREFIX); | |
399 | break; | |
400 | case FLG_ITERPREFIXEXCLUDE: | |
401 | check = (flag != FLG_ITERPREFIX); | |
402 | break; | |
403 | BADDEFAULT; | |
404 | } | |
405 | /*@=loopswitchbreak@*/ | |
406 | ||
407 | if (check) | |
408 | { | |
409 | flagcode rcode = namespaceExcluded (code); | |
410 | cstring pstring = context_getString (rcode); | |
411 | ||
412 | if (cstring_isDefined (pstring)) | |
413 | { | |
414 | if (cstring_isUndefined (name)) | |
415 | { | |
416 | name = uentry_getName (ue); | |
417 | } | |
418 | ||
419 | if (matchPrefix (name, context_getString (rcode))) | |
420 | { | |
421 | if (optgenerror | |
422 | (code, | |
423 | message | |
424 | ("%s %s name is not a %s (it is a %s), " | |
425 | "but matches the %s " | |
426 | "namespace prefix \"%s\"", | |
427 | uentry_ekindName (ue), | |
428 | name, | |
429 | namespaceName (rcode), | |
430 | namespaceName (flag), | |
431 | namespaceName (rcode), | |
432 | context_getString (rcode)), | |
433 | uentry_whereLast (ue))) | |
434 | { | |
435 | uentry_setHasNameError (ue); | |
436 | } | |
437 | } | |
438 | } | |
439 | } | |
440 | } | |
441 | } end_excludeFlagCodes ; | |
442 | ||
443 | cstring_free (name); | |
444 | } | |
445 | ||
446 | static void | |
447 | checkNationalName (uentry ue) | |
448 | { | |
449 | flagcode czechflag; | |
450 | flagcode slovakflag; | |
451 | flagcode czechoslovakflag; | |
452 | bool gcf, gsf, gcsf; | |
453 | ||
454 | ||
455 | if (uentry_isFunction (ue) | |
456 | || uentry_isIter (ue) | |
457 | || uentry_isEndIter (ue)) | |
458 | { | |
459 | czechflag = FLG_CZECHFUNCTIONS; | |
460 | slovakflag = FLG_SLOVAKFUNCTIONS; | |
461 | czechoslovakflag = FLG_CZECHOSLOVAKFUNCTIONS; | |
462 | } | |
463 | else if (uentry_isExpandedMacro (ue)) | |
464 | { | |
465 | czechflag = FLG_CZECHMACROS; | |
466 | slovakflag = FLG_SLOVAKMACROS; | |
467 | czechoslovakflag = FLG_CZECHOSLOVAKMACROS; | |
468 | } | |
469 | else if (uentry_isVariable (ue)) | |
470 | { | |
471 | if (uentry_isGlobal (ue) && context_getFlag (FLG_GLOBPREFIX)) | |
472 | { | |
473 | /* prefix checks supercede national naming checks */ | |
474 | return; | |
475 | } | |
476 | ||
477 | czechflag = FLG_CZECHVARS; | |
478 | slovakflag = FLG_SLOVAKVARS; | |
479 | czechoslovakflag = FLG_CZECHOSLOVAKVARS; | |
480 | } | |
481 | else if (uentry_isConstant (ue)) | |
482 | { | |
483 | if (uentry_isGlobal (ue) && context_getFlag (FLG_CONSTPREFIX)) | |
484 | { | |
485 | /* prefix checks supercede national naming checks */ | |
486 | return; | |
487 | } | |
488 | ||
489 | czechflag = FLG_CZECHCONSTANTS; | |
490 | slovakflag = FLG_SLOVAKCONSTANTS; | |
491 | czechoslovakflag = FLG_CZECHOSLOVAKCONSTANTS; | |
492 | } | |
493 | else | |
494 | { | |
495 | if (uentry_isAnyTag (ue) || uentry_isEnumConstant (ue)) | |
496 | { | |
497 | return; /* no errors for tags */ | |
498 | } | |
499 | ||
500 | llassert (uentry_isDatatype (ue)); | |
501 | ||
502 | czechflag = FLG_CZECHTYPES; | |
503 | slovakflag = FLG_SLOVAKTYPES; | |
504 | czechoslovakflag = FLG_CZECHOSLOVAKTYPES; | |
505 | } | |
506 | ||
507 | gcf = context_getFlag (czechflag); | |
508 | gsf = context_getFlag (slovakflag); | |
509 | gcsf = context_getFlag (czechoslovakflag); | |
510 | ||
511 | if (gcf || (uentry_isFunction (ue) | |
512 | && context_getFlag (FLG_ACCESSCZECH))) | |
513 | { | |
514 | (void) checkCzechName (ue, czechflag, gcf); | |
515 | } | |
516 | ||
517 | if (gsf || (uentry_isFunction (ue) | |
518 | && context_getFlag (FLG_ACCESSSLOVAK))) | |
519 | { | |
520 | (void) checkSlovakName (ue, slovakflag, gsf); | |
521 | } | |
522 | ||
523 | if (gcsf) | |
524 | { | |
525 | if (uentry_isDatatype (ue)) | |
526 | { | |
527 | /* May not have either _'s or uppercase letter */ | |
528 | cstring name = uentry_rawName (ue); | |
529 | int charno = 1; | |
530 | ||
531 | cstring_chars (name, c) | |
532 | { | |
533 | if (isupper ((unsigned char) c)) | |
534 | { | |
535 | if (optgenerror | |
536 | (FLG_CZECHOSLOVAKTYPES, | |
537 | message | |
538 | ("%s %q name violates Czechoslovak naming convention. " | |
539 | "Czechoslovak datatype names should not use uppercase " | |
540 | "letters.", | |
541 | uentry_ekindName (ue), | |
542 | uentry_getName (ue)), | |
543 | uentry_whereLast (ue))) | |
544 | { | |
545 | uentry_setHasNameError (ue); | |
546 | } | |
547 | break; | |
548 | } | |
549 | ||
550 | if (c == '_' && charno != 2 && charno != 3) | |
551 | { | |
552 | if (optgenerror | |
553 | (FLG_CZECHOSLOVAKTYPES, | |
554 | message ("%s %q name violates Czechoslovak naming " | |
555 | "convention. Czechoslovak datatype names " | |
556 | "should not use the _ charater.", | |
557 | uentry_ekindName (ue), | |
558 | uentry_getName (ue)), | |
559 | uentry_whereLast (ue))) | |
560 | { | |
561 | uentry_setHasNameError (ue); | |
562 | } | |
563 | break; | |
564 | } | |
565 | ||
566 | charno++; | |
567 | } end_cstring_chars; | |
568 | } | |
569 | else | |
570 | { | |
571 | bool okay = checkCzechName (ue, czechflag, FALSE); | |
572 | ||
573 | /* still need to call, to set access */ | |
574 | okay |= checkSlovakName (ue, slovakflag, FALSE); | |
575 | ||
576 | if (!okay) | |
577 | { | |
578 | if (optgenerror | |
579 | (czechoslovakflag, | |
580 | message ("%s %q name is not consistent with Czechoslovak " | |
581 | "naming convention.", | |
582 | uentry_ekindName (ue), | |
583 | uentry_getName (ue)), | |
584 | uentry_whereLast (ue))) | |
585 | { | |
586 | uentry_setHasNameError (ue); | |
587 | } | |
588 | } | |
589 | } | |
590 | } | |
591 | } | |
592 | ||
593 | static bool checkCzechName (uentry ue, flagcode czechflag, bool report) | |
594 | { | |
595 | if (uentry_isDatatype (ue)) | |
596 | { | |
597 | /* | |
598 | ** Czech datatypes may not have _'s, except if there are 1 or 2 characters | |
599 | ** before the only _. | |
600 | */ | |
601 | ||
602 | cstring name = uentry_rawName (ue); | |
603 | int charno = 1; | |
604 | ||
605 | cstring_chars (name, c) | |
606 | { | |
607 | if (c == '_' && charno != 2 && charno != 3) | |
608 | { | |
609 | if (report) | |
610 | { | |
611 | if (optgenerror | |
612 | (FLG_CZECHTYPES, | |
613 | message | |
614 | ("%s %q name violates Czech naming convention. " | |
615 | "Czech datatype names should not use the _ charater.", | |
616 | uentry_ekindName (ue), | |
617 | uentry_getName (ue)), | |
618 | uentry_whereLast (ue))) | |
619 | { | |
620 | uentry_setHasNameError (ue); | |
621 | } | |
622 | } | |
623 | ||
624 | return FALSE; | |
625 | } | |
626 | ||
627 | charno++; | |
628 | } end_cstring_chars; | |
629 | } | |
630 | else | |
631 | { | |
632 | typeIdSet acc = context_fileAccessTypes (); | |
633 | cstring pfx = czechPrefix (uentry_rawName (ue)); | |
634 | ||
635 | if (cstring_isEmpty (pfx)) | |
636 | { | |
637 | if (uentry_isVariable (ue) || uentry_isConstant (ue)) | |
638 | { | |
639 | ctype ct = uentry_getType (ue); | |
640 | ||
641 | if (ctype_isAbstract (ct) | |
642 | && context_hasAccess (ctype_typeId (ct))) | |
643 | { | |
644 | if (report) | |
645 | { | |
646 | if (optgenerror | |
647 | (czechflag, | |
648 | message ("%s %q name is not consistent with Czech " | |
649 | "naming convention. The name should " | |
650 | "begin with %s_", | |
651 | uentry_ekindName (ue), | |
652 | uentry_getName (ue), | |
653 | ctype_unparse (ct)), | |
654 | uentry_whereLast (ue))) | |
655 | { | |
656 | uentry_setHasNameError (ue); | |
657 | } | |
658 | } | |
659 | ||
660 | cstring_free (pfx); | |
661 | return FALSE; | |
662 | } | |
663 | } | |
664 | else if (uentry_isFunction (ue) || uentry_isIter (ue)) | |
665 | { | |
666 | if (typeIdSet_isEmpty (acc)) | |
667 | { | |
668 | ; /* okay - should not be czech name */ | |
669 | } | |
670 | else | |
671 | { | |
672 | if (report) | |
673 | { | |
674 | if (optgenerror | |
675 | (czechflag, | |
676 | message ("%s %q name is not consistent with Czech " | |
677 | "naming convention. Accessible types: %q", | |
678 | uentry_ekindName (ue), | |
679 | uentry_getName (ue), | |
680 | typeIdSet_unparse (acc)), | |
681 | uentry_whereLast (ue))) | |
682 | { | |
683 | uentry_setHasNameError (ue); | |
684 | } | |
685 | } | |
686 | ||
687 | cstring_free (pfx); | |
688 | return FALSE; | |
689 | } | |
690 | } | |
691 | else | |
692 | { | |
693 | ; | |
694 | } | |
695 | } | |
696 | else | |
697 | { | |
698 | if (usymtab_existsTypeEither (pfx)) | |
699 | { | |
700 | ctype ct = usymtab_lookupAbstractType (pfx); | |
701 | typeId tid; | |
702 | ||
703 | if (ctype_isUA (ct)) | |
704 | { | |
705 | tid = ctype_typeId (ct); | |
706 | ||
707 | if (ctype_isUser (ct) || context_hasAccess (tid)) | |
708 | { | |
709 | ; | |
710 | } | |
711 | else | |
712 | { | |
713 | if (context_getFlag (FLG_ACCESSCZECH) | |
714 | || context_getFlag (FLG_ACCESSCZECHOSLOVAK)) | |
715 | { | |
716 | if (!uentry_isVar (ue)) | |
717 | { | |
718 | uentry_addAccessType (ue, tid); | |
719 | } | |
720 | } | |
721 | else | |
722 | { | |
723 | if (report) | |
724 | { | |
725 | if (llgenhinterror | |
726 | (czechflag, | |
727 | message | |
728 | ("%s %q name violates Czech naming " | |
729 | "convention. Czech prefix %s names " | |
730 | "an abstract type that is " | |
731 | "not accessible.", | |
732 | uentry_ekindName (ue), | |
733 | uentry_getName (ue), | |
734 | pfx), | |
735 | cstring_makeLiteral | |
736 | ("Use +accessczech to allow access to " | |
737 | "type <t> in functions " | |
738 | "named <t>_<name>."), | |
739 | uentry_whereLast (ue))) | |
740 | { | |
741 | uentry_setHasNameError (ue); | |
742 | } | |
743 | } | |
744 | ||
745 | cstring_free (pfx); | |
746 | return FALSE; | |
747 | } | |
748 | } | |
749 | } | |
750 | else if (ctype_isManifestBool (ct)) | |
751 | { | |
752 | if (context_canAccessBool ()) | |
753 | { | |
754 | ; | |
755 | } | |
756 | else | |
757 | { | |
758 | if (context_getFlag (FLG_ACCESSCZECH) | |
759 | || context_getFlag (FLG_ACCESSCZECHOSLOVAK)) | |
760 | { | |
761 | if (!uentry_isVar (ue)) | |
762 | { | |
763 | tid = usymtab_getTypeId (context_getBoolName ()); | |
764 | uentry_addAccessType (ue, tid); | |
765 | } | |
766 | } | |
767 | else | |
768 | { | |
769 | if (report) | |
770 | { | |
771 | if (llgenhinterror | |
772 | (czechflag, | |
773 | message | |
774 | ("%s %q name violates Czech naming " | |
775 | "convention. Type bool is not accessible.", | |
776 | uentry_ekindName (ue), | |
777 | uentry_getName (ue)), | |
778 | cstring_makeLiteral | |
779 | ("Use +accessczech to allow access to " | |
780 | "type <t> in functions named <t>_<name>."), | |
781 | uentry_whereLast (ue))) | |
782 | { | |
783 | uentry_setHasNameError (ue); | |
784 | } | |
785 | } | |
786 | ||
787 | cstring_free (pfx); | |
788 | return FALSE; | |
789 | } | |
790 | } | |
791 | } | |
792 | else | |
793 | { | |
794 | ; | |
795 | } | |
796 | } | |
797 | else | |
798 | { | |
799 | if (cstring_equalLit (pfx, "int") | |
800 | || cstring_equalLit (pfx, "char") | |
801 | || cstring_equalLit (pfx, "short") | |
802 | || cstring_equalLit (pfx, "long") | |
803 | || cstring_equalLit (pfx, "unsigned") | |
804 | || cstring_equalLit (pfx, "signed") | |
805 | || cstring_equalLit (pfx, "float") | |
806 | || cstring_equalLit (pfx, "double")) | |
807 | { | |
808 | ; /* built-in types */ | |
809 | } | |
810 | else | |
811 | { | |
812 | /* no accessible types, could match module name */ | |
813 | ||
814 | if (cstring_equal (pfx, context_moduleName ())) | |
815 | { | |
816 | ; | |
817 | } | |
818 | else | |
819 | { | |
820 | if (report) | |
821 | { | |
822 | if (optgenerror | |
823 | (czechflag, | |
824 | message | |
825 | ("%s %q name violates Czech naming convention. " | |
826 | "Czech prefix %s is not the name of a type.", | |
827 | uentry_ekindName (ue), | |
828 | uentry_getName (ue), | |
829 | pfx), | |
830 | uentry_whereLast (ue))) | |
831 | { | |
832 | uentry_setHasNameError (ue); | |
833 | } | |
834 | } | |
835 | ||
836 | cstring_free (pfx); | |
837 | return FALSE; | |
838 | } | |
839 | } | |
840 | } | |
841 | } | |
842 | cstring_free (pfx); | |
843 | } | |
844 | ||
845 | return TRUE; | |
846 | } | |
847 | ||
848 | static bool checkSlovakName (uentry ue, flagcode slovakflag, bool report) | |
849 | { | |
850 | if (uentry_isDatatype (ue)) | |
851 | { | |
852 | /* | |
853 | ** Slovak datatypes may not have uppercase letters. | |
854 | */ | |
855 | ||
856 | if (context_getFlag (FLG_SLOVAK)) | |
857 | { | |
858 | cstring name = uentry_rawName (ue); | |
859 | ||
860 | cstring_chars (name, c) | |
861 | { | |
862 | if (isupper ((unsigned char) c)) | |
863 | { | |
864 | if (report) | |
865 | { | |
866 | if (optgenerror | |
867 | (FLG_SLOVAKTYPES, | |
868 | message | |
869 | ("%s %q name violates Slovak naming convention. " | |
870 | "Slovak datatype names should not use uppercase " | |
871 | "letters.", | |
872 | uentry_ekindName (ue), | |
873 | uentry_getName (ue)), | |
874 | uentry_whereLast (ue))) | |
875 | { | |
876 | uentry_setHasNameError (ue); | |
877 | } | |
878 | } | |
879 | return FALSE; | |
880 | } | |
881 | } end_cstring_chars; | |
882 | } | |
883 | } | |
884 | else | |
885 | { | |
886 | typeIdSet acc = context_fileAccessTypes (); | |
887 | cstring pfx = slovakPrefix (uentry_rawName (ue)); | |
888 | ||
889 | if (cstring_isEmpty (pfx)) | |
890 | { | |
891 | if (typeIdSet_isEmpty (acc)) | |
892 | { | |
893 | ; /* okay - should not be slovak name */ | |
894 | } | |
895 | else | |
896 | { | |
897 | if (uentry_isFunction (ue)) | |
898 | { | |
899 | if (report) | |
900 | { | |
901 | if (optgenerror | |
902 | (slovakflag, | |
903 | message ("%s %q name is not consistent with Slovak " | |
904 | "naming convention. Accessible types: %q", | |
905 | uentry_ekindName (ue), | |
906 | uentry_getName (ue), | |
907 | typeIdSet_unparse (acc)), | |
908 | uentry_whereLast (ue))) | |
909 | { | |
910 | uentry_setHasNameError (ue); | |
911 | } | |
912 | } | |
913 | ||
914 | cstring_free (pfx); | |
915 | return FALSE; | |
916 | } | |
917 | else | |
918 | { | |
919 | ctype ct = uentry_getType (ue); | |
920 | ||
921 | if (ctype_isUA (ct)) | |
922 | { | |
923 | if (report) | |
924 | { | |
925 | if (optgenerror | |
926 | (slovakflag, | |
927 | message ("%s %q name is not consistent with " | |
928 | "Slovak naming convention. The " | |
929 | "name should begin with %s followed " | |
930 | "by an uppercase letter.", | |
931 | uentry_ekindName (ue), | |
932 | uentry_getName (ue), | |
933 | ctype_unparse (ct)), | |
934 | uentry_whereLast (ue))) | |
935 | { | |
936 | uentry_setHasNameError (ue); | |
937 | } | |
938 | } | |
939 | ||
940 | cstring_free (pfx); | |
941 | return FALSE; | |
942 | } | |
943 | } | |
944 | } | |
945 | } | |
946 | else | |
947 | { | |
948 | if (usymtab_existsTypeEither (pfx)) | |
949 | { | |
950 | ctype ct = usymtab_lookupAbstractType (pfx); | |
951 | typeId tid; | |
952 | ||
953 | if (ctype_isUA (ct)) | |
954 | { | |
955 | tid = ctype_typeId (ct); | |
956 | ||
957 | if (ctype_isUser (ct) || context_hasAccess (tid)) | |
958 | { | |
959 | ; | |
960 | } | |
961 | else | |
962 | { | |
963 | if (context_getFlag (FLG_ACCESSSLOVAK) | |
964 | || context_getFlag (FLG_ACCESSCZECHOSLOVAK)) | |
965 | { | |
966 | if (!uentry_isVar (ue)) | |
967 | { | |
968 | uentry_addAccessType (ue, tid); | |
969 | } | |
970 | } | |
971 | else | |
972 | { | |
973 | if (report) | |
974 | { | |
975 | if (llgenhinterror | |
976 | (slovakflag, | |
977 | message | |
978 | ("%s %q name violates Slovak naming " | |
979 | "convention. Slovak prefix %s names " | |
980 | "an abstract type that is not accessible.", | |
981 | uentry_ekindName (ue), | |
982 | uentry_getName (ue), | |
983 | pfx), | |
984 | cstring_makeLiteral | |
985 | ("Use +accessslovak to allow access to " | |
986 | "type <t> in functions named <t>_<name>."), | |
987 | uentry_whereLast (ue))) | |
988 | { | |
989 | uentry_setHasNameError (ue); | |
990 | } | |
991 | } | |
992 | ||
993 | cstring_free (pfx); | |
994 | return FALSE; | |
995 | } | |
996 | } | |
997 | } | |
998 | else if (ctype_isManifestBool (ct)) | |
999 | { | |
1000 | if (context_canAccessBool ()) | |
1001 | { | |
1002 | ; | |
1003 | } | |
1004 | else | |
1005 | { | |
1006 | if (context_getFlag (FLG_ACCESSSLOVAK) | |
1007 | || context_getFlag (FLG_ACCESSCZECHOSLOVAK)) | |
1008 | { | |
1009 | if (!uentry_isVar (ue)) | |
1010 | { | |
1011 | tid = usymtab_getTypeId (context_getBoolName ()); | |
1012 | uentry_addAccessType (ue, tid); | |
1013 | } | |
1014 | } | |
1015 | else | |
1016 | { | |
1017 | if (report) | |
1018 | { | |
1019 | if (llgenhinterror | |
1020 | (slovakflag, | |
1021 | message | |
1022 | ("%s %q name violates Slovak naming convention. " | |
1023 | "Type bool is not accessible.", | |
1024 | uentry_ekindName (ue), | |
1025 | uentry_getName (ue)), | |
1026 | cstring_makeLiteral | |
1027 | ("Use +accessslovak to allow access to " | |
1028 | "type <t> in functions named <t>_<name>."), | |
1029 | uentry_whereLast (ue))) | |
1030 | { | |
1031 | uentry_setHasNameError (ue); | |
1032 | } | |
1033 | } | |
1034 | ||
1035 | cstring_free (pfx); | |
1036 | return FALSE; | |
1037 | } | |
1038 | } | |
1039 | } | |
1040 | else | |
1041 | { | |
1042 | ; | |
1043 | } | |
1044 | } | |
1045 | else | |
1046 | { | |
1047 | if (cstring_equalLit (pfx, "int") | |
1048 | || cstring_equalLit (pfx, "char") | |
1049 | || cstring_equalLit (pfx, "short") | |
1050 | || cstring_equalLit (pfx, "long") | |
1051 | || cstring_equalLit (pfx, "unsigned") | |
1052 | || cstring_equalLit (pfx, "signed") | |
1053 | || cstring_equalLit (pfx, "float") | |
1054 | || cstring_equalLit (pfx, "double")) | |
1055 | { | |
1056 | ; /* built-in types */ | |
1057 | } | |
1058 | else | |
1059 | { | |
1060 | /* no accessible types, could match module name */ | |
1061 | ||
1062 | if (cstring_equal (pfx, context_moduleName ())) | |
1063 | { | |
1064 | ; | |
1065 | } | |
1066 | else | |
1067 | { | |
1068 | if (report) | |
1069 | { | |
1070 | if (optgenerror | |
1071 | (slovakflag, | |
1072 | message | |
1073 | ("%s %q name violates Slovak naming convention. " | |
1074 | "Slovak prefix %s is not the name of a type.", | |
1075 | uentry_ekindName (ue), | |
1076 | uentry_getName (ue), | |
1077 | pfx), | |
1078 | uentry_whereLast (ue))) | |
1079 | { | |
1080 | uentry_setHasNameError (ue); | |
1081 | } | |
1082 | } | |
1083 | ||
1084 | cstring_free (pfx); | |
1085 | return FALSE; | |
1086 | } | |
1087 | } | |
1088 | } | |
1089 | } | |
1090 | ||
1091 | cstring_free (pfx); | |
1092 | } | |
1093 | ||
1094 | return TRUE; | |
1095 | } | |
1096 | ||
1097 | void | |
1098 | checkGlobalName (uentry ue) | |
1099 | { | |
1100 | if (!uentry_isStatic (ue) && uentry_hasName (ue)) | |
1101 | { | |
1102 | checkNationalName (ue); | |
1103 | } | |
1104 | else | |
1105 | { | |
1106 | ; | |
1107 | } | |
1108 | } | |
1109 | ||
1110 | void | |
1111 | checkLocalName (/*@unused@*/ uentry ue) | |
1112 | { | |
1113 | ; | |
1114 | } | |
1115 | ||
1116 | /* | |
1117 | ** Checks a name used by user source is not reserved by ANSI | |
1118 | ** (or for future library functions). | |
1119 | ** | |
1120 | ** The restrictions are described in X3.159-1989: 4.13 | |
1121 | */ | |
1122 | ||
1123 | /*@constant int NRESERVEDNAMES; @*/ | |
1124 | # define NRESERVEDNAMES 201 | |
1125 | ||
1126 | /*@constant int NCPPNAMES@*/ | |
1127 | # define NCPPNAMES 39 | |
1128 | ||
1129 | bool checkCppName (cstring name, fileloc loc) | |
1130 | { | |
1131 | static ob_mstring cppNames[NCPPNAMES] = | |
1132 | { | |
1133 | "and", "and_eq", "asm", | |
1134 | "bitand", "bitor", "bool", /* gasp: "bool", is special for lclint */ | |
1135 | "catch", "class", "compl", "const_class", | |
1136 | "delete", "dynamic_cast", "false", "friend", | |
1137 | "inline", "mutable", "namespace", "new", | |
1138 | "not", "not_eq", | |
1139 | "operator", "or", "or_eq", "overload", | |
1140 | "private", "protected", "public", | |
1141 | "reinterpret_cast", "static_cast", | |
1142 | "template", "this", "throw", "true", "try", | |
1143 | "typeid", "using", "virtual", "xor", "xor_eq" | |
1144 | } ; | |
1145 | ||
1146 | if (cstring_isDefined (cstring_bsearch (name, &cppNames[0], | |
1147 | NCPPNAMES))) | |
1148 | { | |
1149 | return (optgenerror | |
1150 | (FLG_CPPNAMES, | |
1151 | message ("Name %s is a keyword or reserved word in C++", | |
1152 | name), | |
1153 | loc)); | |
1154 | } | |
1155 | ||
1156 | return FALSE; | |
1157 | } | |
1158 | ||
1159 | bool | |
1160 | checkAnsiName (cstring name, fileloc loc) | |
1161 | { | |
1162 | bool hasError = FALSE; | |
1163 | int length = cstring_length (name); | |
1164 | char fchar = (length >= 1) ? cstring_firstChar (name) : '\0'; | |
1165 | char schar = (length >= 2) ? cstring_secondChar (name) : '\0'; | |
1166 | char tchar = (length >= 3) ? cstring_getChar (name, 3) : '\0'; | |
1167 | char rchar = (length >= 4) ? cstring_getChar (name, 4) : '\0'; | |
1168 | ||
1169 | /* | |
1170 | ** reservedNames | |
1171 | ** taken from Linden, "Expert C Programming", p. 126-8. | |
1172 | ** invariant: must be sorted (case-insensitive, lexicographically) | |
1173 | ** must end with NULL | |
1174 | */ | |
1175 | ||
1176 | static ob_mstring reservedNames[NRESERVEDNAMES] = | |
1177 | { | |
1178 | # include "reservedNames.nf" | |
1179 | } ; | |
1180 | ||
1181 | if (fileloc_isSystemFile (loc) || fileloc_isBuiltin (loc)) | |
1182 | { | |
1183 | return FALSE; /* no errors for system files */ | |
1184 | } | |
1185 | ||
1186 | # if 0 | |
1187 | { | |
1188 | int i = 0; | |
1189 | char *lastname = NULL; | |
1190 | char *name; | |
1191 | ||
1192 | while ((name = reservedNames[i]) != NULL) | |
1193 | { | |
1194 | llassertprint (lastname == NULL | |
1195 | || strcmp (name, lastname) > 0, | |
1196 | ("%s / %s", lastname, name)); | |
1197 | lastname = name; | |
1198 | i++; | |
1199 | } | |
1200 | ||
1201 | nreservedNames = i - 1; | |
1202 | } | |
1203 | # endif | |
1204 | ||
1205 | if (cstring_isDefined (cstring_bsearch (name, &reservedNames[0], | |
1206 | NRESERVEDNAMES))) | |
1207 | { | |
1208 | return (optgenerror | |
1209 | (FLG_ANSIRESERVED, | |
1210 | message ("Name %s is reserved for the standard library", | |
1211 | name), | |
1212 | loc)); | |
1213 | } | |
1214 | ||
1215 | if (fchar == '_') | |
1216 | { | |
1217 | hasError = optgenerror | |
1218 | (FLG_ANSIRESERVED, | |
1219 | message | |
1220 | ("Name %s is in the implementation name space (any identifier " | |
1221 | "beginning with underscore)", | |
1222 | name), | |
1223 | loc); | |
1224 | } | |
1225 | ||
1226 | /* | |
1227 | ** 4.13.1 Errors <errno.h> | |
1228 | ** | |
1229 | ** Macros that begin with E and a digit or E and an uppercase letter ... | |
1230 | */ | |
1231 | ||
1232 | else if (fchar == 'E' && (isdigit ((int) schar) | |
1233 | || isupper ((int) schar))) | |
1234 | { | |
1235 | hasError = optgenerror | |
1236 | (FLG_ANSIRESERVED, | |
1237 | message | |
1238 | ("Name %s is reserved for future ANSI library extensions. " | |
1239 | "Macros beginning with E and a digit or uppercase letter " | |
1240 | "may be added to <errno.h>. (See ANSI, Section 4.13.1)", | |
1241 | name), | |
1242 | loc); | |
1243 | } | |
1244 | ||
1245 | /* | |
1246 | ** 4.13.2 Character Handling <ctype.h> | |
1247 | ** | |
1248 | ** Function names that begin with either "is" or "to" and a lowercase letter ... | |
1249 | */ | |
1250 | ||
1251 | else if (((fchar == 'i' && schar == 's') | |
1252 | || (fchar == 't' && schar == 'o')) | |
1253 | && (islower ((int) tchar))) | |
1254 | { | |
1255 | hasError = optgenerror | |
1256 | (FLG_ANSIRESERVED, | |
1257 | message | |
1258 | ("Name %s is reserved for future ANSI library extensions. " | |
1259 | "Functions beginning with \"is\" or \"to\" and a lowercase " | |
1260 | "letter may be added to <ctype.h>. (See ANSI, Section 4.13.2)", | |
1261 | name), | |
1262 | loc); | |
1263 | } | |
1264 | ||
1265 | /* | |
1266 | ** 4.13.3 Localization <locale.h> | |
1267 | ** | |
1268 | ** Macros that begin with LC_ and an uppercase letter ... | |
1269 | */ | |
1270 | ||
1271 | else if (length >= 4 | |
1272 | && ((fchar == 'L') | |
1273 | && (schar == 'C') | |
1274 | && (tchar == '_')) | |
1275 | && (isupper ((int) rchar))) | |
1276 | { | |
1277 | hasError = optgenerror | |
1278 | (FLG_ANSIRESERVED, | |
1279 | message | |
1280 | ("Name %s is reserved for future ANSI library extensions. " | |
1281 | "Macros beginning with \"LC_\" and an uppercase letter may " | |
1282 | "be added to <locale.h>. (See ANSI, Section 4.13.3)", | |
1283 | name), | |
1284 | loc); | |
1285 | } | |
1286 | ||
1287 | /* | |
1288 | ** 4.13.4 Mathematics <math.h> | |
1289 | ** | |
1290 | ** The names of all existing functions declared in the <math.h> header, | |
1291 | ** suffixed with f or l... | |
1292 | */ | |
1293 | ||
1294 | else if ((cstring_lastChar (name) == 'f' || cstring_lastChar (name) == 'l') | |
1295 | && | |
1296 | (((length == 4) | |
1297 | && ((cstring_equalPrefix (name, "cos") || | |
1298 | cstring_equalPrefix (name, "sin") || | |
1299 | cstring_equalPrefix (name, "tan") || | |
1300 | cstring_equalPrefix (name, "exp") || | |
1301 | cstring_equalPrefix (name, "log") || | |
1302 | cstring_equalPrefix (name, "pow")))) | |
1303 | || ((length == 5) | |
1304 | && ((cstring_equalPrefix (name, "acos") || | |
1305 | cstring_equalPrefix (name, "asin") || | |
1306 | cstring_equalPrefix (name, "atan") || | |
1307 | cstring_equalPrefix (name, "cosh") || | |
1308 | cstring_equalPrefix (name, "sinh") || | |
1309 | cstring_equalPrefix (name, "sqrt") || | |
1310 | cstring_equalPrefix (name, "ceil") || | |
1311 | cstring_equalPrefix (name, "fabs") || | |
1312 | cstring_equalPrefix (name, "fmod") || | |
1313 | cstring_equalPrefix (name, "tanh") || | |
1314 | cstring_equalPrefix (name, "modf")))) | |
1315 | || ((length == 6) | |
1316 | && ((cstring_equalPrefix (name, "atan2") || | |
1317 | cstring_equalPrefix (name, "floor") || | |
1318 | cstring_equalPrefix (name, "frexp") || | |
1319 | cstring_equalPrefix (name, "ldexp") || | |
1320 | cstring_equalPrefix (name, "log10")))))) | |
1321 | { | |
1322 | hasError = optgenerror | |
1323 | (FLG_ANSIRESERVED, | |
1324 | message | |
1325 | ("Name %s is reserved for future ANSI library extensions. " | |
1326 | "The names of all existing functions in <math.h> suffixed " | |
1327 | "with 'f' or 'l' may be added to <math.h>. (See ANSI, Section 4.13.4)", | |
1328 | name), | |
1329 | loc); | |
1330 | } | |
1331 | ||
1332 | /* | |
1333 | ** 4.13.5 Signal Handling <signal.h> | |
1334 | ** | |
1335 | ** Macros that begin with either SIG or SIG_ and an uppercase letter or... | |
1336 | */ | |
1337 | ||
1338 | else if (fchar == 'S' && schar == 'I' && tchar == 'G' | |
1339 | && ((rchar == '_' && ((length >= 5 | |
1340 | && isupper ((int) cstring_getChar (name, 5))))) | |
1341 | || (isupper ((int) rchar)))) | |
1342 | { | |
1343 | hasError = optgenerror | |
1344 | (FLG_ANSIRESERVED, | |
1345 | message | |
1346 | ("Name %s is reserved for future ANSI library extensions. " | |
1347 | "Macros that begin with SIG and an uppercase letter or SIG_ " | |
1348 | "and an uppercase letter may be added to " | |
1349 | "<signal.h>. (See ANSI, Section 4.13.5)", | |
1350 | name), | |
1351 | loc); | |
1352 | } | |
1353 | ||
1354 | /* | |
1355 | ** 4.13.6 Input/Output <stdio.h> | |
1356 | ** | |
1357 | ** (nothing to check) | |
1358 | */ | |
1359 | ||
1360 | /* | |
1361 | ** 4.13.7 General Utilities <stdlib.h> | |
1362 | ** | |
1363 | ** Functions names that begin with str and a lowercase letter may be added to <stdlib.h>. | |
1364 | */ | |
1365 | ||
1366 | else if (fchar == 's' && schar == 't' && tchar == 'r' | |
1367 | && (islower ((int) rchar))) | |
1368 | { | |
1369 | hasError = optgenerror | |
1370 | (FLG_ANSIRESERVED, | |
1371 | message | |
1372 | ("Name %s is reserved for future ANSI library extensions. " | |
1373 | "Functions that begin with \"str\" and a lowercase letter " | |
1374 | "may be added to <stdlib.h> or <string.h>. (See ANSI, Section 4.13.7)", | |
1375 | name), | |
1376 | loc); | |
1377 | } | |
1378 | ||
1379 | /* | |
1380 | ** 4.13.8 String Handling <string.h> | |
1381 | ** | |
1382 | ** Function names that begin with str, mem, or wcs and a lowercase letter ... | |
1383 | ** | |
1384 | ** (Note: already checked "str" above.) | |
1385 | */ | |
1386 | ||
1387 | else if (((fchar == 'm' && schar == 'e' && tchar == 'm') | |
1388 | || (fchar == 'w' && schar == 'c' && tchar == 's')) | |
1389 | && (islower ((int) rchar))) | |
1390 | { | |
1391 | hasError = optgenerror | |
1392 | (FLG_ANSIRESERVED, | |
1393 | message | |
1394 | ("Name %s is reserved for future ANSI library extensions. " | |
1395 | "Functions that begin with \"mem\" or \"wcs\" and a " | |
1396 | "lowercase letter letter may be added to <string.h>. (See ANSI, Section 4.13.8)", | |
1397 | name), | |
1398 | loc); | |
1399 | } | |
1400 | else | |
1401 | { | |
1402 | ; | |
1403 | } | |
1404 | ||
1405 | return hasError; | |
1406 | } | |
1407 | ||
1408 | void checkParamNames (uentry ue) | |
1409 | { | |
1410 | cstring fpfx = context_getString (FLG_DECLPARAMPREFIX); | |
1411 | bool noformal = context_getFlag (FLG_DECLPARAMNAME); | |
1412 | ||
1413 | llassert (uentry_isFunction (ue)); | |
1414 | ||
1415 | if (cstring_isDefined (fpfx) || noformal) | |
1416 | { | |
1417 | uentryList params = uentry_getParams (ue); | |
1418 | ||
1419 | uentryList_elements (params, p) | |
1420 | { | |
1421 | if (uentry_hasName (p)) | |
1422 | { | |
1423 | if (noformal && !cstring_isDefined (fpfx)) | |
1424 | { | |
1425 | if (optgenerror | |
1426 | (FLG_DECLPARAMNAME, | |
1427 | message ("Declaration parameter has name: %q", | |
1428 | uentry_getName (p)), | |
1429 | uentry_whereLast (p))) | |
1430 | { | |
1431 | uentry_setHasNameError (p); | |
1432 | } | |
1433 | } | |
1434 | else | |
1435 | { | |
1436 | cstring pname = uentry_getName (p); | |
1437 | ||
1438 | if (!cstring_equalPrefix (pname, cstring_toCharsSafe (fpfx))) | |
1439 | { | |
1440 | if (context_getFlag (FLG_NAMECHECKS)) | |
1441 | { | |
1442 | if (optgenerror | |
1443 | (FLG_DECLPARAMPREFIX, | |
1444 | message ("Declaration parameter name %s does not begin " | |
1445 | "with protoparamprefix (%s)", | |
1446 | pname, fpfx), | |
1447 | uentry_whereLast (p))) | |
1448 | { | |
1449 | uentry_setHasNameError (p); | |
1450 | } | |
1451 | } | |
1452 | } | |
1453 | cstring_free (pname); | |
1454 | } | |
1455 | } | |
1456 | } end_uentryList_elements ; | |
1457 | } | |
1458 | } | |
1459 | ||
1460 | ||
1461 | ||
1462 |