見出し画像

マージソートプログラムのカバレッジを測定してみた

プログラムを作成すると試験を実施するが、全てのルートを試験できているのかどうかが懸念される。最近ではカバレッジツールも増えてきていて、フリーで使用できるものもある。

とはいうものの、C言語のカバレッジは実は少し難しい。CPUそれぞれのネイティブコードを作成するものだから、マシンコードが実行されたのかどうかを判定しなければならず、CPUに依存するところが多くあるためである。このような状況にあって、比較的新しいC言語コンパイラである「clang」は、カバレッジ機能も提供してくれている。ならば、というわけで試してみた。

clangのカバレッジについては以下を参照。


カバレッジを有効にしてコンパイル

まずはカバレッジを有効にしてコンパイルする必要がある。これによって、カバレッジ測定に必要な情報をコードと共に出力することができる。

「clang」の場合は、次の2つのオプションを指定しなければならない。

  • -fcoverage-mapping

  • -fprofile-instr-generate=c27.profraw

「c27.profraw」はプロファイルデータを出力するファイルを指定するもので、希望のファイルを指定すればよい。
私の場合は次のコマンドを実行した。

cc -g -gdbx -fprofile-instr-generate=c27.profraw -fcoverage-mapping c27.c node.c -o /data/data/com.termux/files/usr/bin/_local/c27

実行

では、早速実行してみる。

c27

実行すると次のファイルが生成される。

c27.profraw

データ変換

profraw」から「profdata」に変換しなければならない。

llvm-profdata merge -sparse c27.profraw -o c27.profdata

この結果、さらに次のファイルが生成される。

c27.profdata

llvm-profdata」については以下を参照。


カバレッジ結果表示(サマリー)

さて。
いよいよカバレッジ結果の表示である。

llvm-cov」については以下を参照。

まずはサマリーを見てみよう。

サマリーとは概要で、各ファイルや確保関数の実行がどの程度カバーできたのかを割合で出力してくれる。

llvm-cov report /data/data/com.termux/files/usr/bin/_local/c27 -instr-profile=c27.profdata --show-functions -sources c27.c node.c

結果がこちらである。

File '/data/data/com.termux/files/home/c/kzn/c27/c27.c':
Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
-------------------------------------------------------------------------------------------------------
print_node_person                 5       0 100.00%        13       0 100.00%         2       0 100.00%
compare_number                   18       2  88.89%        15       2  86.67%        12       2  83.33%
compare_name                     12       1  91.67%         8       0 100.00%         8       1  87.50%
merge_node                       11       0 100.00%        16       0 100.00%         6       0 100.00%
mergeSort                         4       0 100.00%        10       0 100.00%         2       0 100.00%
main                              9       0 100.00%        34       0 100.00%         6       1  83.33%
-------------------------------------------------------------------------------------------------------
TOTAL                            59       3  94.92%        96       2  97.92%        36       4  88.89%

File '/data/data/com.termux/files/home/c/kzn/c27/node.c':
Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
-------------------------------------------------------------------------------------------------------
node_initialize                   1       0 100.00%         6       0 100.00%         0       0   0.00%
node_link_after                   7       2  71.43%        13       0 100.00%         4       2  50.00%
node_link_before                  7       1  85.71%        13       0 100.00%         4       1  75.00%
node_unlink                       7       1  85.71%        13       0 100.00%         4       1  75.00%
node_is_empty                     4       4   0.00%         7       7   0.00%         2       2   0.00%
node_is_alone                     6       0 100.00%         7       0 100.00%         4       1  75.00%
node_cut                          6       1  83.33%        10       0 100.00%         4       2  50.00%
node_get_middle                  10       1  90.00%        11       0 100.00%         6       1  83.33%
node_split                        4       1  75.00%         6       0 100.00%         2       1  50.00%
print_node                        8       8   0.00%        14      14   0.00%         4       4   0.00%
-------------------------------------------------------------------------------------------------------
TOTAL                            60      19  68.33%       100      21  79.00%        34      15  55.88%

100%にならない関数も少なくない。
では、それぞれの関数は、どこが実行できていないのだろうか。


カバレッジ結果表示

次のコマンドは、ソースコードの行単位で実行回数を表示してくれる。これによって、実行されなかったコードを特定することができる。

llvm-cov show -show-line-counts-or-regions --show-branches=count --show-expansions /data/data/com.termux/files/usr/bin/_local/c27 -instr-profile=c27.profdata
llvm-cov show -show-line-counts-or-regions --show-branches=count --show-expansions /data/data/com.termux/files/usr/bin/_local/c27 -instr-profile=c27.profdata
/data/data/com.termux/files/home/c/kzn/c27/c27.c:
    1|       |#include <stdio.h>
    2|       |#include "node.h"
    3|       |
    4|       |typedef struct {
    5|       |	int		number;
    6|       |	char	name[128];
    7|       |} Person;
    8|       |
    9|       |typedef struct {
   10|       |	Node	node;
   11|       |	Person	person;
   12|       |} NodePerson;
   13|       |
   14|       |char* name_of_NobelFysik[];
   15|       |
   16|       |void print_node_person(Node* top)
   17|      3|{
   18|      3|	NodePerson* current = (NodePerson*)top;
   19|    576|	while (1)
  ------------------
  |  Branch (19:9): [Folded - Ignored]
  ------------------
   20|    576|	{
   21|    576|		Person* p = &current->person;
   22|    576|		printf("%3d.%s\n", p->number, p->name);
   23|       |
   24|    576|		current = (NodePerson*)current->node.next;
   25|    576|		if (current == (NodePerson*)top)
  ------------------
  |  Branch (25:7): [True: 3, False: 573]
  ------------------
   26|      3|		{
   27|      3|			break;
   28|      3|		}
   29|    576|	}
   30|      3|}
   31|       |
   32|       |typedef int (*NodeCompare)(Node* node1, Node* node2);
   33|  1.47k|int compare_number(Node* node1, Node* node2){
   34|  1.47k|	if ((node1 == NULL) && (node2 == NULL)) { return 0;}
                                      ^136             ^0
  ------------------
  |  Branch (34:6): [True: 136, False: 1.33k]
  |  Branch (34:25): [True: 0, False: 136]
  ------------------
   35|  1.47k|    if (node1 == NULL) { return 1; }
                                     ^136
  ------------------
  |  Branch (35:9): [True: 136, False: 1.33k]
  ------------------
   36|  1.33k|    if (node2 == NULL) { return -1; }
                                     ^115
  ------------------
  |  Branch (36:9): [True: 115, False: 1.22k]
  ------------------
   37|       |
   38|  1.22k|	Person* p1 = &(((NodePerson*)node1)->person); 
   39|  1.22k|	Person* p2 = &(((NodePerson*)node2)->person); 
   40|       |
   41|  1.22k|	if (p1->number == p2->number) {
  ------------------
  |  Branch (41:6): [True: 0, False: 1.22k]
  ------------------
   42|      0|		return 0;
   43|      0|	}
   44|       |
   45|  1.22k|	if (p1->number < p2->number) {
  ------------------
  |  Branch (45:6): [True: 589, False: 632]
  ------------------
   46|    589|		return -1;
   47|       |
   48|    632|	} else {
   49|    632|		return 1;
   50|    632|	}
   51|  1.22k|}
   52|       |
   53|  1.47k|int compare_name(Node* node1, Node* node2){
   54|  1.47k|	if ((node1 == NULL) && (node2 == NULL)) { return 0;}
                                      ^142             ^0
  ------------------
  |  Branch (54:6): [True: 142, False: 1.33k]
  |  Branch (54:25): [True: 0, False: 142]
  ------------------
   55|  1.47k|    if (node1 == NULL) { return 1; }
                                     ^142
  ------------------
  |  Branch (55:9): [True: 142, False: 1.33k]
  ------------------
   56|  1.33k|    if (node2 == NULL) { return -1; }
                                     ^124
  ------------------
  |  Branch (56:9): [True: 124, False: 1.20k]
  ------------------
   57|       |
   58|  1.20k|	Person* p1 = &(((NodePerson*)node1)->person); 
   59|  1.20k|	Person* p2 = &(((NodePerson*)node2)->person); 
   60|  1.20k|	return strncmp(p1->name, p2->name, sizeof(p1->name));
   61|  1.33k|}
   62|       |
   63|    382|Node* merge_node(Node* node1, Node* node2, NodeCompare cmp) {
   64|    382|    Node* merge_node = NULL;
   65|       |
   66|  3.32k|	while (1) {
  ------------------
  |  Branch (66:9): [Folded - Ignored]
  ------------------
   67|  3.32k|    	if ((node1 == NULL) && (node2 == NULL)) { break; }
                                          ^660             ^382
  ------------------
  |  Branch (67:10): [True: 660, False: 2.66k]
  |  Branch (67:29): [True: 382, False: 278]
  ------------------
   68|       |
   69|  2.94k|    	if (cmp(node1, node2) < 0) {
  ------------------
  |  Branch (69:10): [True: 1.40k, False: 1.53k]
  ------------------
   70|  1.40k|			Node* sel_node = node1;
   71|  1.40k|			node1 = node_unlink(sel_node);
   72|  1.40k|			merge_node = node_link_before(merge_node, sel_node);
   73|  1.53k|    	} else {
   74|  1.53k|			Node* sel_node = node2;
   75|  1.53k|			node2 = node_unlink(sel_node);
   76|  1.53k|			merge_node = node_link_before(merge_node, sel_node);
   77|  1.53k|    	}
   78|  2.94k|	}
   79|       |
   80|    382|    return merge_node;
   81|    382|}
   82|       |
   83|    766|Node* mergeSort(Node* top, NodeCompare cmp) {
   84|       |	/* ノードが一つだけのとき */
   85|    766|	if (node_is_alone(top) == 1) {
  ------------------
  |  Branch (85:6): [True: 384, False: 382]
  ------------------
   86|    384|        return top;
   87|    384|    }
   88|       |
   89|       |	/* 半分に分割する */
   90|    382|	Node* half = node_split(top);
   91|       |
   92|       |	/* 再帰呼出 */
   93|       |	/* 左半分と右半分をそれぞれマージソートする */
   94|    382|    Node* left  = mergeSort(top, cmp);
   95|    382|    Node* right = mergeSort(half, cmp);
   96|       |
   97|       |	/* 分割したノードをマージする */
   98|    382|    Node* sorted = merge_node(left, right, cmp);
   99|       |
  100|    382|    return sorted;
  101|    766|}
  102|       |
  103|       |int main()
  104|      1|{
  105|      1|	NodePerson NobelFysik[256] = {0};
  106|       |
  107|      1|	int i;
  108|    193|	for (i = 0; i < 256; i++)
                                    ^192
  ------------------
  |  Branch (108:14): [True: 193, False: 0]
  ------------------
  109|    193|	{
  110|    193|		node_initialize(&NobelFysik[i].node, i+1);
  111|       |
  112|    193|		if (name_of_NobelFysik[i] == NULL) 
  ------------------
  |  Branch (112:7): [True: 1, False: 192]
  ------------------
  113|      1|		{
  114|      1|			break;
  115|      1|		}
  116|       |
  117|    192|		NobelFysik[i].person.number = i;
  118|    192|		strncpy(NobelFysik[i].person.name,  
  119|    192|				name_of_NobelFysik[i], 
  120|    192|				sizeof(NobelFysik[i].person.name));
  121|       |
  122|       |
  123|    192|		if (i > 0)
  ------------------
  |  Branch (123:7): [True: 191, False: 1]
  ------------------
  124|    191|		{
  125|    191|			node_link_after(
  126|    191|					&NobelFysik[i-1].node, 
  127|    191|					&NobelFysik[i].node);
  128|    191|		}
  129|    192|	}
  130|       |
  131|      1|	print_node_person(&NobelFysik[0].node);
  132|      1|	printf("#########################\n");
  133|       |
  134|      1|	Node* sorted_name = 
  135|      1|		mergeSort(&NobelFysik[0].node, compare_name);
  136|      1|	printf("#########################\n");
  137|       |
  138|      1|	print_node_person(sorted_name);
  139|      1|	printf("#########################\n");
  140|       |
  141|      1|	Node* sorted_number = 
  142|      1|		mergeSort(sorted_name, compare_number);
  143|      1|	printf("#########################\n");
  144|       |
  145|      1|	print_node_person(sorted_number);
  146|      1|	printf("#########################\n");
  147|      1|}
  148|       |
  149|       |char* name_of_NobelFysik[] =
  150|       |{
  151|       |	"Wilhelm Conrad Rontgen",
  152|       |	"Hendrik Antoon Lorentz",
  153|       |	"Pieter Zeeman",
  154|       |	"Pierre Curie",
  155|       |	"Marie Curie",
  156|       |	"Antoine Henri Becquerel",
  157|       |	"Lord (John William Strutt)Rayleigh",
  158|       |	"Philipp Eduard Anton von Lenard",
  159|       |	"Sir Joseph John Thomson",
  160|       |	"Albert Abraham Michelson",
  161|       |	"Gabriel Lippmann",
  162|       |	"Guglielmo Marconi",
  163|       |	"Carl Ferdinand Braun",
  164|       |	"Johannes Diderik van der Waals",
  165|       |	"Wilhelm Wien",
  166|       |	"Nils Gustaf Dalen",
  167|       |	"Heike Kamerlingh Onnes",
  168|       |	"Max von Laue",
  169|       |	"Sir William Henry Bragg",
  170|       |	"William Lawrence Bragg",
  171|       |	"Charles Glover Barkla",
  172|       |	"Max Karl Ernst Ludwig Planck",
  173|       |	"Johannes Stark",
  174|       |	"Charles-Edouard Guillaume",
  175|       |	"Albert Einstein",
  176|       |	"Niels Henrik David Bohr",
  177|       |	"Robert Andrews Millikan",
  178|       |	"Karl Manne Georg Siegbahn",
  179|       |	"James Franck",
  180|       |	"Gustav Ludwig Hertz",
  181|       |	"Jean Baptiste Perrin",
  182|       |	"Arthur Holly Compton",
  183|       |	"Charles Thomson Rees Wilson",
  184|       |	"Owen Willans Richardson",
  185|       |	"Prince Louis-Victor Pierre Raymond de Broglie",
  186|       |	"Sir Chandrasekhara Venkata Raman",
  187|       |	"Werner Karl Heisenberg",
  188|       |	"Paul Adrien Maurice Dirac",
  189|       |	"Erwin Schrodinger",
  190|       |	"James Chadwick",
  191|       |	"Carl David Anderson",
  192|       |	"Victor Franz Hess",
  193|       |	"Clinton Joseph Davisson",
  194|       |	"George Paget Thomson",
  195|       |	"Enrico Fermi",
  196|       |	"Ernest Orlando Lawrence",
  197|       |	"Otto Stern",
  198|       |	"Isidor Isaac Rabi",
  199|       |	"Wolfgang Pauli",
  200|       |	"Percy Williams Bridgman",
  201|       |	"Sir Edward Victor Appleton",
  202|       |	"Patrick Maynard Stuart Blackett",
  203|       |	"Hideki Yukawa",
  204|       |	"Cecil Frank Powell",
  205|       |	"Sir John Douglas Cockcroft",
  206|       |	"Ernest Thomas Sinton Walton",
  207|       |	"Felix Bloch",
  208|       |	"Edward Mills Purcell",
  209|       |	"Frits (Frederik) Zernike",
  210|       |	"Max Born",
  211|       |	"Walter Wilhelm Georg Franz Bothe",
  212|       |	"Willis Eugene Lamb",
  213|       |	"Polykarp Kusch",
  214|       |	"William Bradford Shockley",
  215|       |	"Walter Houser Brattain",
  216|       |	"John Bardeen",
  217|       |	"Tsung-Dao Lee",
  218|       |	"Chen Ning Yang",
  219|       |	"Pavel Alekseyevich Cherenkov",
  220|       |	"Il´ja Mikhailovich Frank",
  221|       |	"Igor Yevgenyevich Tamm",
  222|       |	"Emilio Gino Segre",
  223|       |	"Owen Chamberlain",
  224|       |	"Donald Arthur Glaser",
  225|       |	"Robert Hofstadter",
  226|       |	"Rudolf Ludwig Mossbauer",
  227|       |	"Lev Davidovich Landau",
  228|       |	"Eugene Paul Wigner",
  229|       |	"Maria Goeppert-Mayer",
  230|       |	"J. Hans D. Jensen",
  231|       |	"Charles Hard Townes",
  232|       |	"Nicolay Gennadiyevich Basov",
  233|       |	"Aleksandr Mikhailovich Prokhorov",
  234|       |	"Julian Schwinger",
  235|       |	"Richard P. Feynman",
  236|       |	"Sin-Itiro Tomonaga",
  237|       |	"Alfred Kastler",
  238|       |	"Hans Albrecht Bethe",
  239|       |	"Luis Walter Alvarez",
  240|       |	"Murray Gell-Mann",
  241|       |	"Hannes Olof Gosta Alfven",
  242|       |	"Louis Eugene Felix Neel",
  243|       |	"Dennis Gabor",
  244|       |	"John Bardeen",
  245|       |	"Leon Neil Cooper",
  246|       |	"John Robert Schrieffer",
  247|       |	"Leo Esaki",
  248|       |	"Ivar Giaever",
  249|       |	"Brian David Josephson",
  250|       |	"Antony Hewish",
  251|       |	"Sir Martin Ryle",
  252|       |	"Aage Niels Bohr",
  253|       |	"Ben Roy Mottelson",
  254|       |	"Leo James Rainwater",
  255|       |	"Burton Richter",
  256|       |	"Samuel Chao Chung Ting",
  257|       |	"Philip Warren Anderson",
  258|       |	"Sir Nevill Francis Mott",
  259|       |	"John Hasbrouck van Vleck",
  260|       |	"Arno Allan Penzias",
  261|       |	"Robert Woodrow Wilson",
  262|       |	"Pyotr Leonidovich Kapitsa",
  263|       |	"Steven Weinberg",
  264|       |	"Sheldon Lee Glashow",
  265|       |	"Abdus Salam",
  266|       |	"James Watson Cronin",
  267|       |	"Val Logsdon Fitch",
  268|       |	"Nicolaas Bloembergen",
  269|       |	"Arthur Leonard Schawlow",
  270|       |	"Kai M. Siegbahn",
  271|       |	"Kenneth G. Wilson",
  272|       |	"Subramanyan Chandrasekhar",
  273|       |	"William Alfred Fowler",
  274|       |	"Carlo Rubbia",
  275|       |	"Simon van der Meer",
  276|       |	"Klaus von Klitzing",
  277|       |	"Gerd Binnig",
  278|       |	"Heinrich Rohrer",
  279|       |	"Ernst Ruska",
  280|       |	"K. Alexander Muller",
  281|       |	"J. Georg Bednorz",
  282|       |	"Leon M. Lederman",
  283|       |	"Melvin Schwartz",
  284|       |	"Jack Steinberger",
  285|       |	"Hans G. Dehmelt",
  286|       |	"Wolfgang Paul",
  287|       |	"Norman F. Ramsey",
  288|       |	"Richard E. Taylor",
  289|       |	"Jerome I. Friedman",
  290|       |	"Henry W. Kendall",
  291|       |	"Pierre-Gilles de Gennes",
  292|       |	"Georges Charpak",
  293|       |	"Russell A. Hulse",
  294|       |	"Joseph H. Taylor Jr.",
  295|       |	"Clifford G. Shull",
  296|       |	"Bertram N. Brockhouse",
  297|       |	"Martin L. Perl",
  298|       |	"Frederick Reines",
  299|       |	"David M. Lee",
  300|       |	"Robert C. Richardson",
  301|       |	"Douglas D. Osheroff",
  302|       |	"Steven Chu",
  303|       |	"Claude Cohen-Tannoudji",
  304|       |	"William D. Phillips",
  305|       |	"Horst L. Stormer",
  306|       |	"Daniel C. Tsui",
  307|       |	"Robert B. Laughlin",
  308|       |	"Gerardus 't Hooft",
  309|       |	"Martinus J.G. Veltman",
  310|       |	"Jack S. Kilby",
  311|       |	"Herbert Kroemer",
  312|       |	"Zhores I. Alferov",
  313|       |	"Carl E. Wieman",
  314|       |	"Wolfgang Ketterle",
  315|       |	"Eric A. Cornell",
  316|       |	"Masatoshi Koshiba",
  317|       |	"Raymond Davis Jr.",
  318|       |	"Riccardo Giacconi",
  319|       |	"Alexei A. Abrikosov",
  320|       |	"Vitaly L. Ginzburg",
  321|       |	"Anthony J. Leggett",
  322|       |	"David J. Gross",
  323|       |	"H. David Politzer",
  324|       |	"Frank Wilczek",
  325|       |	"Roy J. Glauber",
  326|       |	"John L. Hall",
  327|       |	"Theodor W. Haensch",
  328|       |	"John C. Mather",
  329|       |	"George F. Smoot",
  330|       |	"Albert Fert",
  331|       |	"Peter Grunberg",
  332|       |	"Yoichiro Nambu",
  333|       |	"Makoto Kobayashi",
  334|       |	"Toshihide Masakawa",
  335|       |	"Charles K. Kao",
  336|       |	"Willard Boyle",
  337|       |	"George E. Smith",
  338|       |	"Andre Geim",
  339|       |	"Konstantin Novoselov",
  340|       |	"Saul Perlmutter",
  341|       |	"Brian Schmidt",
  342|       |	"Adam Riess",
  343|       |	NULL,
  344|       |};
  345|       |

/data/data/com.termux/files/home/c/kzn/c27/node.c:
    1|       |#include <stdio.h>
    2|       |#include "node.h"
    3|       |
    4|       |/************************************************/
    5|    193|void node_initialize(Node* node, int id) {
    6|    193|	node->next = node;
    7|    193|	node->prev = node;
    8|    193|	node->id   = id;
    9|    193|	return;
   10|    193|}
   11|       |
   12|       |/************************************************/
   13|    191|Node* node_link_after(Node* node1, Node* node2) {
   14|    191|	if (node1 == NULL) {return node2;}
                                  ^0
  ------------------
  |  Branch (14:6): [True: 0, False: 191]
  ------------------
   15|    191|	if (node2 == NULL) {return node1;}
                                  ^0
  ------------------
  |  Branch (15:6): [True: 0, False: 191]
  ------------------
   16|       |
   17|       |	/* node1:node1_a->node1_b-> ... ->node1_z */
   18|       |	/* node2:node2_a->node2_b-> ... ->node2_z */
   19|    191|	Node* node1_a = node1;
   20|    191|	Node* node1_b = node1->next;
   21|    191|	Node* node2_a = node2;
   22|    191|	Node* node2_z = node2->prev;
   23|       |
   24|       |	/* node1_a->node2_a-> ... ->node2_z->node1_b */
   25|    191|	node1_a->next = node2_a;
   26|    191|	node2_a->prev = node1_a;
   27|    191|	node2_z->next = node1_b;
   28|    191|	node1_b->prev = node2_z;
   29|       |
   30|    191|  	return node1;
   31|    191|}
   32|       |
   33|       |/************************************************/
   34|  2.94k|Node* node_link_before(Node* node1, Node* node2) {
   35|  2.94k|	if (node1 == NULL) {return node2;}
                                  ^382
  ------------------
  |  Branch (35:6): [True: 382, False: 2.56k]
  ------------------
   36|  2.56k|	if (node2 == NULL) {return node1;}
                                  ^0
  ------------------
  |  Branch (36:6): [True: 0, False: 2.56k]
  ------------------
   37|       |
   38|       |	/* node1:node1_a->node1_b-> ... ->node1_z */
   39|       |	/* node2:node2_a->node2_b-> ... ->node2_z */
   40|  2.56k|	Node* node1_a = node1;
   41|  2.56k|	Node* node1_z = node1->prev;
   42|  2.56k|	Node* node2_a = node2;
   43|  2.56k|	Node* node2_z = node2->prev;
   44|       |
   45|       |	/* node1_z->node2_a-> ... ->node2_z->node1_a */
   46|  2.56k|	node1_z->next = node2_a;
   47|  2.56k|	node2_a->prev = node1_z;
   48|  2.56k|	node2_z->next = node1_a;
   49|  2.56k|	node1_a->prev = node2_z;
   50|       |
   51|  2.56k|  	return node1;
   52|  2.56k|}
   53|       |
   54|       |/************************************************/
   55|  2.94k|Node* node_unlink(Node* node) {
   56|  2.94k|	if (node == NULL) {return node;}
                                 ^0
  ------------------
  |  Branch (56:6): [True: 0, False: 2.94k]
  ------------------
   57|  2.94k|	if (node_is_alone(node) == 1) {
  ------------------
  |  Branch (57:6): [True: 764, False: 2.18k]
  ------------------
   58|    764|		return NULL;
   59|    764|	}
   60|       |
   61|       |	/* ... ->prev->node->next-> ... */
   62|  2.18k|	Node* prev = node->prev;
   63|  2.18k|	Node* next = node->next;
   64|       |
   65|       |	/* ... ->prev->next-> ... */
   66|  2.18k|	prev->next = next;
   67|  2.18k|	next->prev = prev;
   68|       |
   69|       |	/* node->node */
   70|  2.18k|	node->prev = node;
   71|  2.18k|	node->next = node;
   72|       |
   73|  2.18k|  	return next;
   74|  2.94k|}
   75|       |
   76|       |/************************************************/
   77|      0|int node_is_empty(Node* node) {
   78|      0|	if (node == NULL) {
  ------------------
  |  Branch (78:6): [True: 0, False: 0]
  ------------------
   79|      0|		return 1;
   80|      0|	} else {
   81|      0|		return 0;
   82|      0|	}
   83|      0|}
   84|       |
   85|       |/************************************************/
   86|  3.71k|int node_is_alone(Node* node) {
   87|  3.71k|	if ((node->prev == node) && (node->next == node)) {
                                           ^1.14k
  ------------------
  |  Branch (87:6): [True: 1.14k, False: 2.56k]
  |  Branch (87:30): [True: 1.14k, False: 0]
  ------------------
   88|  1.14k|		return 1;
   89|  2.56k|	} else {
   90|  2.56k|		return 0;
   91|  2.56k|	}
   92|  3.71k|}
   93|       |
   94|       |/************************************************/
   95|    382|void node_cut(Node* top, Node* cut) {
   96|    382|	if ((top == NULL) || (cut == NULL)) {return;}
                                                   ^0
  ------------------
  |  Branch (96:6): [True: 0, False: 382]
  |  Branch (96:23): [True: 0, False: 382]
  ------------------
   97|       |	
   98|       |	/* top -> ... -> end1 -> cut -> ... -> end2 */
   99|    382|	Node* end1 = cut->prev;
  100|    382|	Node* end2 = top->prev;
  101|       |
  102|       |	/* top -> ... -> end1 */
  103|    382|	top->prev  = end1;
  104|    382|	end1->next = top;
  105|       |
  106|       |	/* cut -> ... -> end2 */
  107|    382|	cut->prev  = end2;
  108|    382|	end2->next = cut;
  109|       |
  110|    382|  	return;
  111|    382|}
  112|       |
  113|       |/************************************************/
  114|    382|Node* node_get_middle(Node* top) {
  115|    382|	if (top == NULL) {return NULL;}
                                ^0
  ------------------
  |  Branch (115:6): [True: 0, False: 382]
  ------------------
  116|       |
  117|       |	/* top:node_1->node_2->...->node_n */
  118|    382|    Node* slow = top;
  119|    382|    Node* fast = top;
  120|       |
  121|       |	/* slow = node_1->node_2->node_3->... */
  122|       |	/* fast = node_1->node_3->node_5->... */
  123|  1.40k|    while (1) {
  ------------------
  |  Branch (123:12): [Folded - Ignored]
  ------------------
  124|  1.40k|        slow = slow->next;
  125|  1.40k|        fast = fast->next->next;
  126|  1.40k|    	if (fast == top || fast->next == top) { break; }
                                      ^1.15k             ^382
  ------------------
  |  Branch (126:10): [True: 254, False: 1.15k]
  |  Branch (126:25): [True: 128, False: 1.02k]
  ------------------
  127|  1.40k|    }
  128|       |
  129|       |	/* slow = node_i (i = n/2) */
  130|    382|    return slow;
  131|    382|}
  132|       |
  133|       |/************************************************/
  134|    382|Node* node_split(Node* top) {
  135|    382|	if (top == NULL) {return NULL;}
                                ^0
  ------------------
  |  Branch (135:6): [True: 0, False: 382]
  ------------------
  136|       |
  137|       |	/* top:node_1->node_2->...->node_n */
  138|       |	/* half = node_i (i = n/2) */
  139|    382|	Node* half = node_get_middle(top);
  140|       |
  141|       |	/* top  -> ... -> end1 -> half -> ... -> end2 */
  142|       |	/* top  -> ... -> end1 */
  143|       |	/* half -> ... -> end2 */
  144|    382|	node_cut(top, half);
  145|       |
  146|    382|	return half;
  147|    382|}
  148|       |
  149|       |/************************************************/
  150|       |void print_node(Node* top)
  151|      0|{
  152|      0|	if (top == NULL) {printf("node is empty.\n");return;}
  ------------------
  |  Branch (152:6): [True: 0, False: 0]
  ------------------
  153|       |
  154|      0|	Node* current = top;
  155|      0|	while (1)
  ------------------
  |  Branch (155:9): [Folded - Ignored]
  ------------------
  156|      0|	{
  157|      0|		printf("%d ", current->id);
  158|       |
  159|      0|		current = current->next;
  160|      0|		if (current == top)
  ------------------
  |  Branch (160:7): [True: 0, False: 0]
  ------------------
  161|      0|		{
  162|      0|			break;
  163|      0|		}
  164|      0|	}
  165|       |
  166|      0|	printf("\n");
  167|      0|}
  168|       |

この記事が気に入ったらサポートをしてみませんか?