Naming Convention Checker
Overview
Rules for Symbol Naming
Naming Convention Rules File
Starting Naming Convention Check
Limitations
Naming Convention Checker Message Log
Overview
DA-C gives you the possibility to bring in certain conventions relating to the naming of project symbols, and to check whether the names you have defined in the project correspond to the conventions assigned. If the names of the symbols in your project are standardized, then finding your way around in the project is much easier. In this way you can tell, by looking at what follows a variable name, what its type is, whether the variable is local, static, global, etc. These conventions are introduced for reasons of legibility and intelligibility of the code written. An example of this is the set of rules known as Hungarian notation. Hungarian notation has been accepted as a standard according to which the variable name is preceded by key letters describing which type of data the variable represents. Using this notation allows you to identify variable type using the prefix it carries. These prefixes are also used together, according to demand (e.g. a long pointer to string with a null-ending would have the prefix "lpsz").
Many other rules can also be assigned.
Naming Convention Check as a feature within DA-C encompasses the following:
a. Naming Convention check via a set of rules which you can assign using a dialog;
b. Rules based on regular expressions;
c. Rules which reside in a file, so that they can be used in multiple projects;
d. Naming Convention Check can be started independently from the Start menu or set to start automatically, right after Static Code Analysis;
e. Check results are displayed in the form of warnings in the Message Logs. You can set these warnings to be displayed in a Message Logs tab or together with Static Code Analysis warnings.
Rules for Symbol Naming
You assign each rule using two regular expressions. The first regular expression is called regular expression for type. The second regular expression is called regular expression for name. You can find a description of regular expressions in "Editor", the one difference being that the characters $ and ^ (which in regular expressions used in Editor signal the beginning and end of a line) are treated like ordinary characters here.
Naming Convention rule macros related to source files could be defined and used in regular expressions so that symbols of the source file could be checked if they contain specific prefix, suffix or other part of the name. Macro name can contain only alphanumeric characters. If filename contains spaces or '%', it must be enclosed in "". Format: %MacroName% "Filename_without_extension" = MacroValue
Using a regular expression for type you assign type, that is the kind of symbol for whose name you would like to assign a rule. In a regular expression for type you can use the following words and characters:
C language keywords which name basic types (int, char, float ...),
C language keywords which name type modifiers (short, const, volatile, auto, ... ),
Expressions which, together with other expressions, enable you to form compound types (strings and pointers), and these are array of and ptr to,
C language keywords struct, union, typedef and enum, used to describe structured (structures and unions) and enumerated types,
The expression function returning, used to describe functions,
The expression macro, used to describe macros. Old type description "#define" is supported for compatibility reasons.Using a regular expression for name you assign the naming rule itself. These regular expressions will be explained through examples.
Examples of Regular Expressions
Using Naming Convention macros:
%sncname% mainmod = MAM // MainMmod.* ...
^function returning int$ = ^main|fri_P%sncname%_.*$ // e.g. for MainMod.c: global function "fri_PMAM_foo"
^static function returning int$ = ^fri_S%sncname%_.*$ // e.g. for MainMod.c: static function "fri_SMAM_foo"A regular expression for type can, in the simplest case, represent a basic or compound type, as in the following example:
char
float
ptr to char
array of
ptr to array of intYou, therefore, use such expressions to mark some symbol types for the naming of which you would like to assign a rule. The language of regular expressions, however, provides a much wider symbol type class to choose from. For example:
ptr to .+
marks all pointer, that is, a pointer to any object in the code.
Use od typedef. For example:
typedef unsigned char CHAR8; // 8-Bit character
typedef unsigned char uINT8; // 8-Bit integer, the same basic type (unsigned char)
static CHAR8 ext_c8_c8; // char
static const uINT8 CONST_EXT_U8_u8 = {1u}; // byte
^static unsigned char CHAR8$ = ^ch_.+$ // char
^static const unsigned char uINT8$ = ^u8_.+$ // byteA symbol naming rule has the following format:
<symbol_Regex> = <naming_Regex>
where
<symbol_Regex>
is described by a regular expression for type, and the<naming_Regex>
is described by a regular expression for name.Table 1: Examples of regular expressions
Expression
Description
^char$ = ^c[A-Z][a-z0-9]*$
A char type variable must begin with an initial lowercase "c" followed by an uppercase letter, and then by an arbitrary combination of lowercase letters and numerals. Underscore is not allowed.
^int$ = ^i[A-Z][a-z0-9]*$
An int type variable must begin with an initial lowercase "i" followed by an uppercase letter, and then by an arbitrary combination of lowercase letters and numerals. Underscore is not allowed.
^array of .+$ = ^a.*$
Array type variables must begin with a lowercase letter "a", while the rest is arbitrary.
^array of ptr to char$ = ^apc(_|[a-z])+$
Variables of the string of pointers to characters type must begin with a combination of lowercase letters "apc", followed by an arbitrary combination of lowercase letters and underscore characters, with at least one character following the obligatory prefix "apc".
Structures are used without specifying their members. For example, if the project contains the defined structure
typedef struct complex { int re; int im; } Complex;
and you would like the names of all variables of the Complex type to begin with the prefix cmplx followed by an uppercase A or B character, and the remainder of the name (if there is any) to contain only lowercase letters, then you can write:
^struct complex$ = ^cplx_(A|B)[a-z]*$
If you would like to describe an enumerated type using a regular expression for type, for example
typedef enum days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } Days;
and you would like all variables of this type to begin with a lowercase e with an arbitrary extension, then you can write the rule:
^enum days$ = ^e_.+$
If you would like to assign a regular expression as a naming convention relating to functions, you can write the following rules:
^function returning int$ = ^main|fi_.+$
^function returning .+$ = ^f.+$by means of which you have specified that all functions which return the result of the int type should have a name beginning with the lowercase letters fi, and all other functions should have names beginning with the lowercase letter f.
If you would like to assign a regular expression as a naming convention relating to macros, then use the word
macro
in this way:^global macro$ = ^G_([A-Z]|_)+$ // Macro defined in Header file
^module macro$ = ^([A-Z]|_)+$ // Macro defined in Source module filewhich, in this example, means that the macro name is written exclusively with uppercase letters, with the use of underscore characters.
If a symbol corresponds to a regular expression for type of more than one rule, the corresponding warning is reported only if its name cannot correspond to the regular expression for name of any of these rules.
If you want to define a rule for variables which are defined within functions, you have to put in the keyword auto. If you want to define the rule for variables which are defined outside the functions, and which are not static, you just specify the type.
We will show this in the following example:
int a;
static int b;
void f1( void )
{
int c;
c = a+b;
}If you specify the rule for this example
^int$ = ^q.*$
you will get a warning only for variable "a".
If you specify the rule
^auto int$ = ^q.*$
you will get a warning only for variable "c".
If you specify the rule
^.+int$ = ^q.*$
you will get a warning for all three variables.
A type modifier in a rule must be entered in front of the type. For example, if you want to check the names of variables of the following types:
long signed int
long unsigned int
short unsigned int
short signed intappropriate regular type expressions in your rules must be respectively:
signed long int
unsigned long int
unsigned short int
signed short intYou should be careful while using structures and unions. Let us look at the following example:
union umyunion { float a; int c; } uMyUnion;
Let the name-checking rule be
^union$ = ^u.+$
By using this rule the symbol
umyunion
will be checked, and the rule for checkinguMyUnion
symbol should be:^union umyunion$ = ^u.+$
Let us look at the following example of an unnamed union:
union { int a; int b; } uMyUnion2;
If you want to enter the rule for
uMyUnion2
Names Convention checking, you need to write the regular expression for union<unnamed>
type, so that checking for unnamed union type variables or structure type variables would differ from checking for structures or unions .Therefore,
uMyUnion2
checking rule should be as in the following example:^union <unnamed>$ = ^u.+$
Naming Convention Rules File
Assigning naming rules is based on the concept of a file with rules. You can create this file yourself or select one of the existing ones. You can also open one of the existing files and alter it in accordance with your needs. In this way it is possible to use the same rules for multiple projects.
To navigate on Rules you may use mouse's right click on symbol.
Further you may choose Debug in Options > Naming Convention Checker to get additional messages about matched or not matched Rules.
When you want to avoid some messages you may define general rules. Such rules must stay at the Naming Convention Rules file end, because all rules behind it are hidden.
// Such rules must stay at the Naming Convention Rules file end, because all rules behind it are hidden.
^.*$ = ^.*$Starting Naming Convention Check
You can start Naming Convention Check in one of three ways:
Directly via the Start > Naming Convention Compliance Check main menu command.
If Check after building SCA database option has been enabled in the Options > Naming Convention Checker. When this option is enabled, each time you execute Start > Rebuild Database or Start > Build Database, Names Convention Check will automatically be carried out.
Command-Line Parameter (direct or in one script)
We recommend to use of Debug mode messages for development and verification of your Naming convention rules. See Options > Naming Convention Checker.
Limitations
The rules for naming symbols are liable to limitations imposed by regular languages. The rules which concern the semantics of a particular name are also not supported. You cannot use types you yourself have defined to check variable names. Also, types obtained by macro replacement from basic types cannot be used in this context.
For example, if the following appears somewhere in the project
#define BOOL int
BOOL boolVar;then you cannot use the type BOOL as part of a regular expression; in other words, you cannot require, for example, that all variables of the type BOOL have a lowercase "b" for the first letter, and that variables of the type int begin with a lowercase "i".
Probably you may use this way instead:
// Source file
typedef enum { false, true } BOOL;// Naming Convention Rules file
^typedef.*$ = ^T_.+$ // Typedef's shall have "T_" prefix
^const <enum>$ = ^true|false|en_[A-Z][A-Z_]+$ // "true", "false" or "en_" prefix
^enum <unnamed> BOOL$ = ^b.*$ // "BOOL" variables shall have "b" prefix
^.*$ BOOL$ = ^b.*$ // Shorter versionLikewise, the rules you assign are liable to limitations imposed by regular languages1. Rules pertaining to the semantics of a name specified are also not supported.
Naming Convention Checker Message Log
Check results are displayed in the Message Logs, in the form of a warnings.
Double-clicking the line in the Message Logs with warning takes you to the location of the definition of the symbol in question in the project source code.
If you enable the Report separately option, these warnings will be displayed in a separate Message Logs tab. If you have disabled this option, warnings are displayed together with Static Code Analysis warnings.
You can find more about warnings in Appendix B - Messages in a section "Naming Convention Check Warnings"
1 Fischer, C. N., LeBlanc Jr., R. J., "Crafting A Compiler", Benjamin/Cummings Publishing Company, 1988.
Copyright © 1993-2022, RistanCASE PR