Skip to content
Open
52 changes: 52 additions & 0 deletions .github/workflows/coding_guidelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Coding Guidelines

on: pull_request_target

jobs:
compliance_job:
runs-on: ubuntu-latest
name: Run coding guidelines checks on patch series (PR)
steps:
- name: Checkout the code
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: cache-pip
uses: actions/cache@v1
with:
path: ~/.cache/pip
key: ${{ runner.os }}-doc-pip

- name: Install python dependencies
run: |
pip3 install unidiff
pip3 install wheel
pip3 install sh

- name: Install Packages
run: |
sudo apt-get install ocaml-base-nox
wget https://launchpad.net/~npalix/+archive/ubuntu/coccinelle/+files/coccinelle_1.0.8~20.04npalix1_amd64.deb
sudo dpkg -i coccinelle_1.0.8~20.04npalix1_amd64.deb

- name: Run Coding Guildeines Checks
continue-on-error: true
id: coding_guidelines
env:
BASE_REF: ${{ github.base_ref }}
run: |
export ZEPHYR_BASE=$PWD
source zephyr-env.sh
# debug
ls -la
git log --pretty=oneline | head -n 10
./scripts/ci/guideline_check.py --output output.txt -c origin/${BASE_REF}..

- name: Annotate
uses: yuzutech/[email protected]
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
input: './violations.json'
title: 'Violations'
2 changes: 1 addition & 1 deletion drivers/i2c/i2c_imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(i2c_imx);

struct i2c_imx_config {
I2C_Type *base;
void (*irq_config_func)(const struct device *dev);
void (*irq_config_func)(const struct device *device);
uint32_t bitrate;
};

Expand Down
1 change: 1 addition & 0 deletions kernel/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct k_sem *_trace_list_k_sem;
static int init_sem_module(const struct device *dev)
{
ARG_UNUSED(dev);
int exp;

Z_STRUCT_SECTION_FOREACH(k_sem, sem) {
SYS_TRACING_OBJ_INIT(k_sem, sem);
Expand Down
1 change: 1 addition & 0 deletions lib/os/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static void *chunk_mem(struct z_heap *h, chunkid_t c)
static void free_list_remove_bidx(struct z_heap *h, chunkid_t c, int bidx)
{
struct z_heap_bucket *b = &h->buckets[bidx];
int remove;

CHECK(!chunk_used(h, c));
CHECK(b->next != 0);
Expand Down
107 changes: 107 additions & 0 deletions scripts/ci/guideline_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2021 Intel Corporation

import os
import sh
import argparse
import re
from unidiff import PatchSet
import json

if "ZEPHYR_BASE" not in os.environ:
exit("$ZEPHYR_BASE environment variable undefined.")

repository_path = os.environ['ZEPHYR_BASE']

sh_special_args = {
'_tty_out': False,
'_cwd': repository_path
}

coccinelle_scripts = ["/scripts/coccinelle/reserved_names.cocci",
"/scripts/coccinelle/same_identifier.cocci",
"/scripts/coccinelle/identifier_length.cocci",
]


def parse_coccinelle(contents: str, violations: dict):
reg = re.compile("([a-zA-Z0-9/]*\\.[ch]:[0-9]*)(:[0-9\\-]*: )(.*)")
for line in contents.split("\n"):
r = reg.match(line)
if r:
f = r.group(1)
if f in violations:
violations[f].append(r.group(3))
else:
violations[r.group(1)] = [r.group(3)]


def parse_args():
parser = argparse.ArgumentParser(
description="Check if change requires full twister")
parser.add_argument('-c', '--commits', default=None,
help="Commit range in the form: a..b")
parser.add_argument("-o", "--output", required=False,
help="Print violation into a file")
return parser.parse_args()


def main():
args = parse_args()
if not args.commits:
exit("missing commit range")

# pylint does not like the 'sh' library
# pylint: disable=too-many-function-args,unexpected-keyword-arg
commit = sh.git("diff", args.commits, **sh_special_args)
patch_set = PatchSet(commit)
zephyr_base = os.getenv("ZEPHYR_BASE")
violations = {}
numViolations = 0
vlist = []

for f in patch_set:
if not f.path.endswith(".c") and not f.path.endswith(".h") or not os.path.exists(zephyr_base + "/" + f.path):
continue

for script in coccinelle_scripts:
script_path = os.getenv("ZEPHYR_BASE") + "/" + script
cocci = sh.coccicheck(
"--mode=report",
"--cocci=" +
script_path,
f.path,
**sh_special_args)
parse_coccinelle(cocci, violations)

for hunk in f:
for line in hunk:
if line.is_added:
violation = "{}:{}".format(f.path, line.target_line_no)
if violation in violations:
v = {}
v['message'] = "\t\n".join(violations[violation])
v['file'] = violation.split(":")[0]
v['line'] = violation.split(":")[1]
v['annotation_level'] = "failure"
vlist.append(v)
numViolations += 1
if args.output:
with open(args.output, "a+") as fp:
fp.write("{}:{}\n".format(
violation, "\t\n".join(
violations[violation])))
else:
print(
"{}:{}".format(
violation, "\t\n".join(
violations[violation])))
with open('violations.json', 'w') as outfile:
json.dump(vlist, outfile)
return numViolations


if __name__ == "__main__":
ret = main()
exit(ret)
2 changes: 1 addition & 1 deletion scripts/coccinelle/identifier_length.cocci
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ pos << r_idlen.p;
@@

if (len(id) > 31):
msg="WARNING: Identifier %s length %d > 31" % (id, len(id))
msg="WARNING: Violation to rule 5.1 or 5.2 (Identifiers shall be distinct) %s length %d > 31" % (id, len(id))
coccilib.report.print_report(pos[0], msg)
92 changes: 92 additions & 0 deletions scripts/coccinelle/reserved_names.cocci
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Check violations for rule 5.7
// https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_21_02.c
//
// Confidence: Moderate
// Copyright: (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

virtual report

@initialize:python@
@@

@common_case@
position p;
identifier t, v;
expression E;
type T;
@@
(
struct t *v@p;
|
struct t v@p;
|
union t v@p;
|
T v@p;
|
T *v@p;
|
struct t *v@p = E;
|
struct t v@p = E;
|
union t v@p = E;
|
T v@p = E;
|
T *v@p = E;
)

@ script:python @
v << common_case.v;
p << common_case.p;
@@

msg = "WARNING: Violation to rule 21.2 (Should not used a reserved identifier) - {}".format(v)
with open("scripts/coccinelle/symbols.txt", "r") as fp:
symbols = fp.read().splitlines()
if v in symbols:
coccilib.report.print_report(p[0], msg)

@function_match@
type T;
identifier f;
position p;
@@
T f@p(...) {
...
}

@ script:python @
v << function_match.f;
@@

msg = "WARNING: Violation to rule 21.2 (Should not used a reserved identifier) - {}".format(v)
with open("scripts/coccinelle/symbols.txt", "r") as fp:
symbols = fp.read().splitlines()
if v in symbols:
coccilib.report.print_report(p[0], msg)

@function_parameter@
type T1, T2;
identifier function, v;
position p;
parameter list[n] P1;
parameter list[n1] P2;
@@
T1 function(P1, T2 *v@p, P2) {
...
}

@ script:python @
v << function_parameter.v;
p << function_parameter.p;
@@

msg = "WARNING: Violation to rule 21.2 (Should not used a reserved identifier) - {}".format(v)
with open("scripts/coccinelle/symbols.txt", "r") as fp:
symbols = fp.read().splitlines()
if v in symbols:
coccilib.report.print_report(p[0], msg)
76 changes: 76 additions & 0 deletions scripts/coccinelle/same_identifier.cocci
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Check violations for rule 5.7
// https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_05_07.c
//
// Confidence: Moderate
// Copyright: (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

virtual report

@initialize:python@
@@

@common_case@
position p;
identifier t, v;
@@
(
struct t *v@p;
|
struct t v@p;
|
union t v@p;
)

@ script:python @
t << common_case.t;
v << common_case.v;
p << common_case.p;
@@

msg = "WARNING: Violation to rule 5.7 (Tag name should be unique) tag: {}".format(v)
if t == v:
coccilib.report.print_report(p[0], msg)

@per_type@
type T;
identifier v;
position p;
@@
(
T v@p;
|
T *v@p;
)

@ script:python @
t << per_type.T;
v << per_type.v;
p << per_type.p;
@@

msg = "WARNING: Violation to rule 5.7 (Tag name should be unique) tag: {}".format(v)
if t == v:
coccilib.report.print_report(p[0], msg)

@function_match@
type T1, T2;
identifier function, v;
position p;
parameter list[n] P1;
parameter list[n1] P2;
@@
T1 function(P1, T2 *v@p, P2) {
...
}

@ script:python @
v << function_match.v;
t << function_match.T2;
p << function_match.p;
@@

msg = "WARNING: Violation to rule 5.7 (Tag name should be unique) tag: {}".format(v)
if v == t.split(" ")[-1]:
coccilib.report.print_report(p[0], msg)
Loading