0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Cコード解析】elseブロックを自動で追加する

Last updated at Posted at 2024-10-19

コーディングの業務をやっていると静的解析ツールから受けた指摘を対処する仕事がある。今回はif文に対してelseブロックを自動追加するスクリプトを作成する。

ifブロックをマッチさせるパターン

前回書いた記事をベースに考える。

下記の正規表現でifブロックまたはelseブロックをマッチさせる。

(?<=\n)\s*(?:\bif\b|\belse\b\s*\bif\b)\s*\([^()]*\)\s*(\{(?:[^{}]|(?1))*\})(?!\s*\belse\b\s*\bif\b|\s*\belse\b)

少々、長いパターンだが、ifまたはelse ifから始まるブロックを探す正規表現である。
また、ブロックの後ろにelse ifまたはelseがないことを保証する。正規表現の末尾の(?!\s*\belse\b\s*\bif\b|\s*\belse\b)で実現している。

これによってelse ifブロックまたはelseブロックが続かない、ifブロックとelse ifブロックを抜き出せる。つまり下記のようなif文のコード。

	if  (a < 10)
	{
		printf("a is small value");
	}

	if(b < 10)
	{
		printf("b is small value");
	}
	else if(c < 10)
	{
		printf("c is small value");
	}

マッチさせたifブロックにelseブロックを追加する

regex.subを使ってelseブロックを追加する。コードは下記。

import regex

def elseblock_repl(match):
	elseblock = "\nelse\n{\n\t/* 処理なし */\n}"
	matchstr = match.group()

	# if文のインデントを取得する
	indent = regex.search(r"[\t ]*(?=\bif\b|\belse\b\s*\bif\b)", matchstr, regex.DOTALL).group()
	return matchstr + elseblock.replace("\n", "\n" + indent)

with open("test.c", "r", encoding="utf-8", errors="ignore") as file_obj:
	codetext = file_obj.read()
	ret = regex.sub(r"(?<=\n)\s*(?:\bif\b|\belse\b\s*\bif\b)\s*\([^()]*\)\s*(\{(?:[^{}]|(?1))*\})(?!\s*\belse\b\s*\bif\b|\s*\belse\b)", elseblock_repl, codetext, regex.DOTALL)
print(ret)

regex.subで置換先の文字列はelseblock_repl関数を指定する。
まずはif文のインデントを図る。下記の正規表現を使うことでifまたはelse ifの前にあるスペースとタブを抽出できる。

[\t ]*(?=\bif\b|\belse\b\s*\bif\b

抽出したインデントをelseブロックのテンプレートであるelseblockに対してインデントを追加させ、実際に追加する場所のインデントと合うようにする。

elseblock_repl関数の引数であるmatchにはマッチ情報が入ってくるため、マッチした文字列にインデントを調整したelseブロックの文字列を加えたものをreturnする。すると、elseがないifブロックに対してelseブロックが追加される。

まとめ

このスクリプトを考えた経緯は静的解析ツールの指摘に自動で対応したいから。プロジェクトの規模にもよるが「elseがありません!」という指摘が500件とか1000件になると、それを手動で直すだけで数日掛かるし指も痛める。こういった単調作業はどんどん自動化したい。:grin:

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?