マージソートプログラムのカバレッジを測定してみた
プログラムを作成すると試験を実施するが、全てのルートを試験できているのかどうかが懸念される。最近ではカバレッジツールも増えてきていて、フリーで使用できるものもある。
とはいうものの、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 = ¤t->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| |