Nokia Code Quality Rules Guide
Nokia Code Quality Rules Guide
USER GUIDE
EXISTING RULES:
SL NO. RULE RULE DESCRIPTION
NUMBER
5 RULE 5 Number of characters per line should not exceed more than 80
12 RULE 12 Enum names shall be entirely uppercase with words separated by und
erscore.
13 RULE 13 Data members of structs are named like ordinary nonmember variable
s. They do not have the trailing underscores that data members in
classes have.
15 RULE 15 In a switch statement, each case must end with a break or a return
statement.
19 RULE 19 Functions with many arguments must be avoided. They often indicate
improper design.
20 RULE 20 Inline functions should only be used for sufficiently simple functions.
21 RULE 21 The name of the files shall only contain one period, to separate the
file extension.
22 RULE 22 Header files shall have the extension .h for both C and C++ files
27 RULE 27 When defining a function, parameter order is: inputs, then outputs.
To run all the rules together using a single script, trigger [Link] inside
code_checker_tool directory with git or hg repo as its argument in command line.
Here <hg or git repo’s root directory> is a git or hg repo where we are trying to check
for the violations in files(.c files and .h files).
This will collect the list of files modified from all outgoing changesets and run with
all the implemented rules.
This script will generate logs directory with master log and log with respective source
file name.
Can check [Link] for more information on execution of code checker tool.
[Link]:
àTool : Pycparser
int x = 2;
switch (x)
break;
return 0;
Violation cases:
int main() {
int num = 8;
switch (num) {
case 7:
printf("Value is 7");
break;
case 8:
printf("Value is 8");
break;
case 9:
return 9;
default:
printf("Out of range");
break;
return 0;
RULE 2 à The names of the preprocessor macros shall be entirely uppercase with two words
separated by underscore.
#endif /* fILE_FOO_SEEN */
àTool : Python
return 0;
}
#include <inttypes.h> Violation case : “ – non ASCII character in printf
#include <stdio.h> statements
bool is_little_endian()
{
int x = 1;
char *y = (char*)&x;
return 1;
}
int main()
int x = 0x89ABCDEF;
int y = 0x76543210;
printf(“Merged number = 0x%x\n”,
merge_bytes(x,y));
return 0;
}
à Tool: Python
RULE 5 à Number of characters per line should not exceed more than 80
àTool : Python
RULE 6 à We need to avoid to use global variables. If we should use it indeed, we need to add
à Tool: Pycparser
àTool : Pycparser
RULE 8 à Long function bodies must be avoided. Recommended size is not more than 60 statements
à Tool: Pycparser
à Violation case : function body that has more than 60 statements.(excluding comments)
RULE 9 à
All of a project's header files should be listed/included as descendants of the project's source directo
ry without use of UNIX directory shortcuts
àTool : Python
switch(myvar)
{
case 101:
k = 10;
p = k + 1;
return 10;
case 120:
case 130:
return 20;
}
return 0;
}
int dummy;
int dummy2;
return 0;
}
àTool: Python
àTool : Pycparser
RULE 12 à Enum names shall be entirely uppercase with words separated by underscore.
àTool: Pycparser
enum week{Mon, Tue, Wed, Thur, Fri, Sat, violation case : enum names should be entirely
Sun}; uppercase with words separated by underscore
int main()
{
enum week day;
day = Wed;
printf("%d",day);
return 0;
}
àTool : Pycparser
àTool: Pycparser
RULE 15. In a switch statement, each case must end with a break or a return statement.
Tool: pycparser
With the help of ast tree , for each case statement we can check if it have break or return
statement and raise an error in other cases.
#include <stdio.h> Violation cases:
int main() · Case 1, no break or return
{
int x = 2;
switch (x)
{
case 1: printf("Choice is 1");
case 2: printf("Choice is 2");
break;
case 3: printf("Choice is 3");
break;
default: printf("Choice other than 1, 2
and 3");
break;
}
return 0;
Violation cases:
#include <stdio.h> · NONE
int main() {
int num = 8;
Limitation:
This code only checks for switch cases in level 1.
RULE 16 à All header files should have #define guards to prevent multiple inclusion.
à Tool: python script
à The format of the symbol name should be <MODULE>_[EXPORT]|[INCLUDE]_<FILE>_H.
This rule is to guarantee guard's uniqueness. Example : Foo/export/baz.h should have the following
guard
#ifndef FOO_EXPORT_BAZ_H
1. define FOO_EXPORT_BAZ_H
…
2. endif //FOO_EXPORT_BAZ_H
/*gfb Violation case: int a is not gaurded
#define
#ifndef
#endif
* jsc
hch*/
int a; // int a is not guarded
#ifndef hhh_h
#define hhh_h
…
#endif
RULE 17. Upon creation, all pointers must be initialized either to 0 (NULL) or to an object.
Tool:pycparser
Check if the declaration is pointer and if it’s initialized either to 0 (NULL) or to an object.
If it’s not assigned to anything store it’s name and check if it’s assigned anywhere further in the
same block.
int main(){ Violation case:
int s=50; ‘check’ pointer is not initialized.
int *check;
int *check2=NULL;
return 0;
}
printf("%d\n", *pc);
Limitation:
This code only checks for pointers in level 1 and won’t check for pointers in structures.
RULE 19. Functions with many arguments must be avoided. They often indicate improper design.
Tool:pycparser
Get the length of parameter’s list with the help of pycparser’s ast tree ,raise violation if length
exceeds the limit .
void averageAndRew(int aa, int Let’s say max count =3
b, int c, int d, int e); Violation case:
‘averageAndRew’ has [Link] arguments more
than maxcount.
RULE 20 à Inline functions should only be used for sufficiently simple functions.
à Tool : pycparser
à MAX_LINES=4
à Limitation case: more than 4 lines in inline functions
Violation case: 5 lines in inline function
inline void foo() i.e., more than 4 lines in inline function
{
int x;
printf("by");
//return 10 ; // returning the output value as
per requirement
}
static inline int food()
{
printf("hi");
int a;
printf(a);
int d=9;
return 20;
RULE 21. The name of the files shall only contain one period, to separate the file extension.
Tool: python
With the help of these commands we can get file name-
slash_index=file_input.rfind("/")
filename=file_input[slash_index+1:]
after getting filename we can check count of ‘.’ In file name to get [Link] extensions.
Filename: fun_c.c No violation
Filename: fun_c.c.c Violation case:
File name contain more than one period.
RULE 22 à Header files shall have the extension .h for both C and C++ files
à Tool: python script and regular expression
#include<[Link]> //violation Violation case: only .h is allowed
#include "square" //violation
int getsqr()
{
return 6;
}
int main()
{
return 3;
}
#include "geometry.h" // no violation No violation
int getsqr()
{
return 6;
}
int main()
RULE 23. The names of formal arguments to functions must always be specified and must be the
same both in the function declaration and in the function definition.
Tool: pycparser
· Using pycparser get the variable names of function arguments at declaration and store
them in dictionary, and check if the names of function arguments are same in function
definition, if it’s not same violation occurs.
int addition(int *num1, int Violation case:
*num2); ‘addition’ function’s argument names are
int main(){} different in both declaration and definition.
int addition(int *a,int *b)
{
return *a + *b;
}
RULE 24 à The return value of a function should generally not be void :return an appropriate
value or error code so that the caller can handle success and failure appropriately.
à Tool: pycparser and python script
inline void foo(int *a) // violation Violation case
{
int x;
printf("by");
return 7;
}
· Using pycparser get the function name and check if the name have “And” in it , and
raise a violation if it exists.
void averageAndRew(int aa, int Violation case:
b, int c, int d, int e); ‘averageAndRew’ have And in
function name
Void bandName() No violation
{
}
RULE 26 à Functions shall not contain too many nesting levels (nested if-else-for-while-...)
statements). -- Having too many nesting levels indicates a refactoring is appropriate.
à Tool: pycparser.
à MAX_LIMIT_OF_LOOPS=4
à Limitation case -- More than 4 nesting levels is a violation
-- Does not support for loops(if-else-for-while-dowhile-switch) without
curly brackets { … }.
Sample code:
void TestForLoop() Violation case: the nesting level is more than 4
{ (max limit)
for(int x=0;x<2;x++) //1st
{
if(x==1)//2nd
{
for (int b = 0; b < 56; b++) //3rd
{
for (int c = 0; c < 196; c++) //4th
{
for(int d=0;d<200;d++) //violation because
more that 4 nesting levels #5th nesting level
{
printf("can vote");
}
}}}}}
if(factor == i)
{
printf("%d", i);
printf("\n");
}
}}
}
RULE [Link] defining a function, parameter order is: inputs, then outputs.
Tool: pycparser
Using pycparser get the variable which is being returned by the function and check if it’s the
Last argument , if it’s not, raise a violation.
int subbb(x,z){ Violation case:
Function ‘subb’ parameters are not in
char a='b'; order as per rule.
return x;
RULE 29. Pointers to pointer as function argument must be avoided whenever possible.
Tool: pycparser
Using pycparser check if any of the function argument is a double/triple pointer and raise violation if
there a double pointer.
RULE 30 à Variables in conditional statements shall not form unary conditional expressions, unless
the variables are boolean type.
à Tool: pycparser
à For example, the following statements are NOT allowed unless v is of boolean type:
if (v) ...
if (!v) ... if (v && ...) ...
int main () Violation case: the variables in conditional
{ statements (ex., if (…)) should be of Boolean
int i = 9; type // here d, i, x, t, c are of integer type.
for (int a = 0; a < 9; a++)
{
int d = 8;
if (d) //violation
{
printf ("everytime" "\n");
}
}
if (i) //violation
{
int x=3;
if (x) //violation
{
printf("if if""\n");
}
int choice = 1;
int f;
switch (choice)
{
int c = 8;
case 1:
f = 6;
if (c) //violation
{
printf ("switch");
}
}
}
RULE [Link] const keyword should be used where possible. For predefined strings, use const char *
rather than char *.
Tool: pycparser
Python code using pycparser identifies every char pointer and checks if it’s predefined, after
validation it checks for const keyword and raise violation if it’s not there.
char *f='a'; Violation case:
‘f’ char pointer is not assigned with const
keyword.
Const char No violation
*string_id[5]={'a','b','c','d','
e'};
RULE 32 à The names of variables and data members are all lowercase, with underscores between
words.
à Tool: python, pycparser and regular expression
variable names or data members
RULE 33.A function shall not return a pointer or reference to its automatic (stack) variables.
Tool: pycparser
Pyhton code using pycparser make a list of variables, pointers which are declared inside function,
If the return statement consists of either a pointer or reference to its automatic (stack) variables
raise a violation .
int sumDigits() Violation case:
{ ‘&sum’ is reference to stack variable, so
int sum = 0; violation
int *a;
int digit;
if (sum==o)
{
int b=0;
}
for(digit = 0; digit <= 9; ++digit)
{
int *for1;
sum += digit;
}
return &sum ;
}
RULE [Link] with boolean return values and no output parameters should be named with
prefixes is, are, has, exist.
Tool: Pycparser
Python code using pycparser identifies if the function type is Boolean , then checks if the function
name starts with is, are, has, exist.
bool isPrime() No violation
{…
}
bool not_prime() Violation case:
{ ‘not_prime’ is a Boolean function with no is,
} are, has, exist prefix.
RULE 36 à Every code block should use brackets. Disallow to omit brackets.
à Tool : pycparser.
à All the blocks of the code (loops, functions, structures) should use { }.
à Limitation case: does not support loops inside any other loop without { … } ( i.e., for(…)
…if(…) )
int main () Violation case: some blocks of the code doesn’t
{ have brackets {…}
int i = 9;
for (int a = 0; a < 9; a++)
{
int d = 8;
if (d) //violation because of no { }
if (i)
{
int x=3;
if (x) //violation because of no { }
printf("if if""\n");
}
while (i < 7)
{
i--;
int t = 6;
if (t) //violation because of no { }
int choice = 1;
int f;
switch (choice)
{
int c = 8;
case 1:
f = 6;
if (c)
{ //no violation
printf ("switch");
}
}
}
RULE 37 à functions used in conditional statements shall not form unary conditional expression,
unless their return value is of boolean type.
à Tool: pycparser
struct person Violation case: functions used in conditional
{ statements shall not form unary conditional
int x; expression,
int fp(); unless their return value is of boolean type.
int (*f) (int, int);
};
void (*signal(int sig, void (*func)(int)))(int);
int areSignalsPresent(){
int a=9;
int c=a*a;
return c;
}
int *main()
{
int i = 9;
for (int a1 = 0; a1 < 9; a1++)
{
int dQ = 8;
if (*f()) //violation
{
printf ("everytime" "\n");
}
}
printf("if if""\n");
}
while (i < 7)
{
i--;
int t = 6;
if (*signal()) //violation
{
int l=99;
printf ("ttt while" "\n");
}
}
int choice = 1;
int f;
if (*signal())
{
printf("c is 81");
}
return 0;
}
Developer Guide