1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<book>
<bookinfo>
<title>Cppcheck 1.87</title>
<date>2018-04-23</date>
</bookinfo>
<chapter>
<title>イントロダクション</title>
<para>Cppcheck は C/C++の静的解析ツールです。C/C++ コンパイラやその他の解析ツールとは異なり、シンタックスエラーを検出しません。 その代わりに、Cppcheckは、コンパイラが通常、検出に失敗するような種類のバグを検出します。このプロジェクトのゴールは、擬陽性 0 です。</para>
<para>サポートしているプログラムのソースコードとプラットフォーム:</para>
<itemizedlist>
<listitem>
<para>さまざまなコンパイラの拡張構文や、インラインアセンブル等を含む、非標準的なソースコードをチェックできます。</para>
</listitem>
<listitem>
<para>Cppcheck は 最新のC++規格をサポートしている、あらゆるC++コンパイラでコンパイルできるようにしています。</para>
</listitem>
<listitem>
<para>Cppcheck は 十分なCPUパワーとメモリーのある、あらゆるプラットフォームで動作するようにしています。</para>
</listitem>
</itemizedlist>
<para>Cppcheckに限界があることをご理解ください。Cppcheckの報告しているエラーに稀に間違いのあることがあります。また、Cppcheck が検出しないバグが残っていることもあります。</para>
<para>ソフトウェアを注意深くテストすれば、Cppcheckを使うより、より多くのバグを検出できるでしょう。ソフトウェアを注意深く実装すれば、Cppcheckを使うより、より多くのバグを検出できるでしょう。しかし、あなたのソフトウェアを実装するときやテストするときに見逃したバグのいくつかを Cppcheckが検出できるでしょう。</para>
</chapter>
<chapter>
<title>GUIでのはじめ方</title>
<para>GUIの起動</para>
<section>
<title>新しいプロジェクト(New Project)</title>
<para>新しプロジェクトのファイルの作成は必要ではありませんが、最初のステップに最適です。ファイル(<literal>File</literal>)と新しいプロジェクトファイル(<literal>New project file</literal>)を通じて学べます。</para>
</section>
<section>
<title>新しいプロジェクト(New Project) - パス(Paths)と定義(Defines)</title>
<para>あなたのプロジェクトはどのようなプロジェクトでしょうか。あなたのプロジェクトがVisual Studioのプロジェクトの場合、または(cmake/qbs/等の)コンパイルデータベースqが精製できる場合、あなたはプロジェクトをインポート(import)できます。</para>
<para>そうではない場合には、そのプロジェクトのパスと定義をマニュアルで調整します。次の図は、Visual Studio のプロジェクトファイルをインポートした場合のスクリーンショットです。</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/gui-newproject-pathsanddefines.png"/>
</imageobject>
</mediaobject>
</section>
<section>
<title>新しいプロジェクト(New Project) - プロジェクト(Project)</title>
<para>プロジェクトタブ(Project tab)では、ビルドディレクトリ(<literal>Cppcheck build dir</literal>)を設定しましょう。これはCppcheckが様々な分析する情報を保管するために使用します。プログラム全体の解析、インクリメンタル解析、統計などです。それぞれのプロジェクトは、それぞれのビルドディレクトリを持ちます。次のスクリーンショットはビルドディレクトリを<literal>cppcheck-build-dir</literal>と設定しています。このパスはプロジェクトファイルからの相対パスです。</para>
<para>あなたは、あなた使用する全てのライブラリーを選択すべきです。次のスクリーンショットではmicrosoft_sal と windowsライブラリーを選択しています。ライブラリーについてはこのマニュアルを参照してして下さい。</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/gui-newproject-project.png"/>
</imageobject>
</mediaobject>
</section>
<section>
<title>新しいプロジェクト(New Project) - アドオン(Addons)</title>
<para>ここでは 除外タブ(<literal>Exclude</literal>)と抑制タブ(<literal>Suppressions</literal>)をスキップします。これは結果をあとで微調整するために使います。</para>
<para>アドオンタブ(Addons)であなたは別の分析を追加できます。このアドオンにはpythonが必要です。</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/gui-newproject-addons.png"/>
</imageobject>
</mediaobject>
</section>
<section>
<title>解析(Analyze)</title>
<para>ダイアログの<literal>OK</literal>ボタンをクリックします。解析がすぐに始まります。</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/gui-results.png"/>
</imageobject>
</mediaobject>
<para>全ての警告が有効になり、やや賑やかになります。あなたが注意しない様々な警告があり得ます。これは簡単に修正できます。メッセージを右クリックして、隠す(<literal>Hide</literal>)または抑制( <literal>Suppress</literal>)を選びます。メッセージの隠しは永久ではありません。これは次の解析でまた表示されます。メッセージの抑制は、永久です。抑制されたidはプロジェクトファイルに保存されるので、これらは二度と表示されません。</para>
</section>
</chapter>
<chapter>
<title>コマンドラインでの始め方</title>
<section>
<title>最初のテスト</title>
<para>これは単純なソースコードです。</para>
<programlisting>int main()
{
char a[10];
a[10] = 0;
return 0;
}</programlisting>
<para>このソースコードを<filename>file1.c</filename>に保存して次のコマンドを実行します。</para>
<programlisting>cppcheck file1.c</programlisting>
<para>cppcheck は次のように出力するでしょう。</para>
<programlisting>Checking file1.c...
[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds</programlisting>
</section>
<section>
<title>フォルダ内の全てのファイルをチェックする</title>
<para>通常、プログラムは多くのソースファイルから構成されます。そして、それら全てをチェックしたいでしょう。Cppcheck は一つのディレクトリ以下の全てのソースファイルをチェックできます。</para>
<programlisting>cppcheck path</programlisting>
<para>ここで"path"はディレクトリのパスです。このようにすれば cppcheck はディレクトリ以下の全てのファイルを再帰的にチェックします。</para>
<programlisting>Checking path/file1.cpp...
1/2 files checked 50% done
Checking path/file2.cpp...
2/2 files checked 100% done</programlisting>
</section>
<section>
<title>マニュアルでファイルをチェックまたはプロジェクトファイルの使用</title>
<para>Cppcheckでは、ファイルやパスを指定する事でファイルチェックを指定できます。一方ででプロジェクトファイル(cmake/visual studio)を使用できます。</para>
<para>プロジェクトファイルの使用は早急に始められます、というのもあなたが設定してする項目が少なくなるからです。</para>
<para>マニュアルでのファイルチェックは、解析をより細かく制御できます。</para>
<para>どちらのアプローチが良い結果になるかはわかりません。両方の方法を試して下さい。両方のアプローチを使用するとより多くののバグを見つけられる結果が得られるかもしれません。</para>
<para>以降の章でより詳細を説明します。</para>
</section>
<section>
<title>チェックからファイルやフォルダを除外する</title>
<para>ファイルやフォルダをチェック対象から除外する方法は二つあります。最初の方法は、あなたがチェックしたいファイルやフォルダだけをcppcheckに指定することです。</para>
<programlisting>cppcheck src/a src/b</programlisting>
<para><filename class="directory">src/a</filename> と <filename class="directory">src/b</filename> 以下の全てのファイルだけをチェックします。</para>
<para>第二の方法は、<parameter class="command">-i</parameter>オプションと共に除外したいファイルやフォルダを指定することです。次のコマンドでは<filename class="directory">src/c</filename>以下のファイルをチェックしません。</para>
<programlisting>cppcheck -isrc/c src</programlisting>
<para>このオプションは現在<parameter class="command">--project</parameter>オプションと同時に使用できません。また、このオプションが有効なのは、インプットディレクトリが提供するされたときです。複数のディレクトリを無視するためには、<parameter class="command">-i</parameter>を複数回使用します。次のコマンドではsrc/b と src/c 以下のファイルをチェックしません。</para>
<programlisting>cppcheck -isrc/b -isrc/c</programlisting>
</section>
<section>
<title>Severities(厳格度)</title>
<para>メッセージのseverities(厳格度)には次のものがあります。:</para>
<variablelist>
<varlistentry>
<term>error(エラー)</term>
<listitem>
<para>バグが検出されたときに使用します。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>warning(警告)</term>
<listitem>
<para>防衛的プログラミングでバグを避けるための提案です。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>style</term>
<listitem>
<para>コードの可読性の向上に関連した、スタイル関連の指摘(未使用関数、冗長なコードなど)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>performance</term>
<listitem>
<para>コードの高速化のための提案。これらの提案は、一般的な知識に基づいたものでしかありません。このメッセージの修正によって計測できるほど処理速度が向上するかどうかはわかりません。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>portability</term>
<listitem>
<para>移植性についての警告。64 bit CPUへの移植性。コンパイラ依存(独自拡張)ソースコードについての警告など。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>information</term>
<listitem>
<para>設定上の問題設定を変更している間だけ有効にすることをお勧めします。</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section>
<title>メッセージの表示</title>
<para>デフォルトでは<parameter class="command">error</parameter>のメッセージだけを表示します。<parameter class="command">--enable</parameter>を使用すると他のチェックを有効にできます。</para>
<programlisting># warning のメッセージを有効にします。
cppcheck --enable=warning file.c
# performanceのメッセージを有効にします。
cppcheck --enable=performance file.c
# informationのメッセージを有効にします。
cppcheck --enable=information file.c
# 歴史的な理由により --enable=style を指定すると warning, performance,
# portability と styleのメッセージを有効にします。古いxml形式を使用しているときには、これらの厳格度を"style"として報告されます。
cppcheck --enable=style file.c
# warning と performance のメッセージを有効にします。
cppcheck --enable=warning,performance file.c
# unusedFunction のチェックを有効にします。今回は --enable=styleでは有効にできない。
# というのは、これではライブラリではうまく動作しないからです。
cppcheck --enable=unusedFunction file.c
# 全てのメッセージを有効にします。
cppcheck --enable=all</programlisting>
<para><literal>--enable=unusedFunction</literal>はプログラム全体をチェックするときにだけ有効にしてください。また、<literal>--enable=all</literal>もプログラム全体をチェックするときにだけ有効にしてください。というのは、unusedFunction チェックは、関数が呼び出されなかったときに警告するチェックだからです。関数呼び出しがチェック範囲にみつからなかったという可能性のノイズになります。</para>
<section>
<title>疑いのあるチェック</title>
<para>Cppcheckはデフォルトで解析に疑いのない場合にだけエラーメッセージを表示します。しかし、<parameter class="command">--inconclusive</parameter>オプションを使用すると、解析に疑いのある場合であってもエラーメッセージを表示します。</para>
<programlisting>cppcheck --inconclusive path</programlisting>
<para>これは、もちろん、実際に問題がないものに対しても、警告することになります。このオプションは、疑いのある警告を表示してもよい場合に限り、使用してください。</para>
</section>
</section>
<section>
<title>結果をファイルに保存</title>
<para>多くの場合、チェックの結果をファイルに保存したいと考えるでしょう。通常のシェルのリダイレクション機能を使って、エラー出力をファイルに保存することができます。</para>
<programlisting>cppcheck file1.c 2> err.txt</programlisting>
</section>
<section>
<title>マルチスレッドチェック</title>
<para>オプションの<literal>-j</literal> を使用してスレッド数を指定することができます。例えば、4スレッドを使ってフォルダ以下の全てのファイルをチェックする場合は次のように実行します。</para>
<programlisting>cppcheck -j 4 path</programlisting>
<para>このチェックでは未使用関数の検出(unusedFunction checking)は無効になることに注意してください。</para>
</section>
<section>
<title>プラットフォーム</title>
<para>あなたがターゲットとするプラットフォームの設定を使用すべきです。</para>
<para>デフォルトで、Cppcheckはネイティブのプラットフォームの設定を使用しますので、あなたのソースコードがローカルの環境でコンパイルし実行する場合には正常に動作するでしょう。</para>
<para>Cppcheck にはビルトインのプラットフォーム設定として、<literal>unix</literal>と<literal>windows</literal>をターゲットにしたものがあります。コマンドラインオプションの<literal>--platform</literal>を使ってプラットフォーム設定を指定できます。</para>
<para>XMLファイルで自身のプラットフォームにあった設定ファイルを作成することもできます。ここに例をあげます。:</para>
<programlisting><?xml version="1"?>
<platform>
<char_bit>8</char_bit>
<default-sign>signed</default-sign>
<sizeof>
<short>2</short>
<int>4</int>
<long>4</long>
<long-long>8</long-long>
<float>4</float>
<double>8</double>
<long-double>12</long-double>
<pointer>4</pointer>
<size_t>4</size_t>
<wchar_t>2</wchar_t>
</sizeof>
</platform></programlisting>
</section>
</chapter>
<chapter>
<title>Project(プロジェクト)</title>
<para>CMakeやVisual Studioを使っているとき、あなたは<literal>--project</literal>を使ってプロジェクトを解析できます。</para>
<para>これでカンタンにチェックでき、結果も得られます。あなたに必要な設定項目はありません。しかしこれが最も良い結果を得る方法とは限りません。私たちは、このプロジェクトファイルを利用する方法と、<literal>--project</literal>を利用しない方法を試してよいオプションを選ぶようにお勧めします。</para>
<section>
<title>CMake</title>
<para>Cppcheckはコンパイルデータベースを理解します。あなたはこれをCMakeで生成できます。</para>
<para>例:</para>
<programlisting>$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .</programlisting>
<para><literal>compile_commands.json</literal>ファイルが現在のディレクトリに生成されます。</para>
<para>それからCppcheckをこのように実行します。:</para>
<programlisting>$ cppcheck --project=compile_commands.json</programlisting>
</section>
<section>
<title>Visual Studio</title>
<para>あなたは個々にのプロジェクトファイル(*.vcxproj)でCppcheckを実行できますし、ソルーション全体(*.sln)でも実行できます。</para>
<programlisting># run cppcheck on a whole solution
$ cppcheck --project=foobar.sln
# run cppcheck on a individual project
$ cppcheck --project=foobar.vcxproj</programlisting>
<para>Visual Studio内でcppcheckを実行するための、Visual Studioプラグインもあります。</para>
</section>
</chapter>
<chapter id="preprocessor-configurations">
<title>プリプロセッサの設定</title>
<para>あなたが <literal>--project</literal>を使用した場合、Cppcheckはプロジェクトファイルからプリプロセッサーの設定を読み取ります。</para>
<para>そうでなければ、あなたはインクルードパスやディレクティブを設定したくなるでしょう。</para>
<section>
<title>ディレクティブ</title>
<para>ここに2つの設定があるファイルがあります(Aが定義された場合と定義されていない場合):</para>
<programlisting>#ifdef A
x = y;
#else
x = z;
#endif</programlisting>
<para>Cppcheckはデフォルトでプリプロセッサのデファインのコンパイルスイッチ設定の組み合わせを全てチェックします。(ただし、これらのうち #error を除く)そのため上のコードは、Aが定義された場合とAが定義されていない場合の両方を解析します。</para>
<para>これを変更するには -D を使います。また -D を使用した場合、cppcheckは与えられたコンパイルスイッチだけが有効でその他は設定されていないとしてチェックします。これは、コンパイラのように動作します。また、 <literal>--force</literal> や <literal>--max-configs</literal> を使用すると、コンパイルスイッチの組み合わせの上限を上書きしてチェックすることができます。</para>
<programlisting># 全てのコンパイルスイッチの組み合わせをチェックする。
cppcheck file.c
# Aのコンパイルスイッチが有効になっている場合の組み合わせをチェックする
cppcheck -DA file.c
# check all configurations when macro A is defined
cppcheck -DA --force file.c</programlisting>
<para>また、もう一つのオプションに-U があります。これはシンボルのundefとなります。使用例:</para>
<programlisting>cppcheck -UX file.c</programlisting>
<para>これはXが定義されていないことを意味します。Cppcheck は Xが定義されている組み合わせをチェックしません。</para>
</section>
<section>
<title>インクルードパス指定</title>
<para>インクルードパスを追加するには<parameter class="command">-I</parameter>オプションに続けてパスを指定します。</para>
<para>Cppcheckのプリプロセッサは基本的に他のプリプロセッサと同様にインクルードを扱います。しかし、その他のプリプロセッサはヘッダファイルが見つからない場合に停止するのとは違って、cppcheckはただ単に、メッセージ情報を表示してソースコードの解析を続けます。</para>
<para>cppcheckは常にソースコード全体を確認する必要がないので、このような仕様になっています。実際に、全てのインクルードパスを与えないことを推奨しています。もちろん、クラスのメンバーの実装を確認した上でクラスの宣言をCppcheckでチェックするのは有用ではありますが、標準ライブラリのヘッダーをCppcheckに確認させるのは有用ではありません。というのは、チェックにかかる時間が長くなり、あまりよくない結果が表示されるからです。そのような場合、.cfg ファイル (後述します)によってcppcheckに関数や型の実装の情報を提供する方がよいでしょう。</para>
</section>
</chapter>
<chapter>
<title>XML出力</title>
<para>Cppcheckは出力を<literal>XML</literal>形式に変更できます。<parameter>--xml</parameter> オプションでフォーマットを指定します。</para>
<para>ファイルをチェックし、<literal>XML</literal>形式で出力するコマンドのサンプルです。:</para>
<programlisting>cppcheck --xml file1.cpp</programlisting>
<para>これが出力例です。:</para>
<programlisting><?xml version="1.0" encoding="UTF-8"?>
<results version="2">
<cppcheck version="1.66">
<errors>
<error id="someError" severity="error" msg="short error text"
verbose="long error text" inconclusive="true" cwe="312">
<location file0="file.c" file="file.h" line="1"/>
</error>
</errors>
</results></programlisting>
<section>
<title><error> 要素</title>
<para>それぞれのエラーは<literal><error></literal>要素に記載されます。属性:</para>
<variablelist>
<varlistentry>
<term><sgmltag class="attribute">id</sgmltag></term>
<listitem>
<para>エラーのidこれは、妥当なシンボル名です。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag class="attribute">severity</sgmltag></term>
<listitem>
<para>以下のいずれかです: <literal>error</literal>, <literal>warning</literal>, <literal>style</literal>, <literal>performance</literal>, <literal>portability</literal>, <literal>information</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag class="attribute">msg</sgmltag></term>
<listitem>
<para>短い形式のエラーメッセージ</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag>verbose</sgmltag></term>
<listitem>
<para>長い形式のエラーメッセージ</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag>inconclusive</sgmltag></term>
<listitem>
<para>この属性は、メッセージに疑いのある場合にのみ使用されます。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag>cwe</sgmltag></term>
<listitem>
<para>メッセージのCWE ID。この属性は、メッセージのCWE IDが判明している場合のみ使用されます。</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section>
<title><location>要素</title>
<para>エラーに関連する全ての位置情報は<literal><location></literal> 要素内にリストアップされます。主要な位置は、リストの最初の要素になります。</para>
<para>属性:</para>
<variablelist>
<varlistentry>
<term><sgmltag class="attribute">file</sgmltag></term>
<listitem>
<para>ファイル名相対パスまたは絶対パスのどちらかです。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag class="attribute">file0</sgmltag></term>
<listitem>
<para>ソースファイルの名前(オプション)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag class="attribute">line</sgmltag></term>
<listitem>
<para>数</para>
</listitem>
</varlistentry>
<varlistentry>
<term><sgmltag class="attribute">info</sgmltag></term>
<listitem>
<para>オプションの、それぞれの位置につiての短い情報</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</chapter>
<chapter>
<title>出力の形式の変更</title>
<para>もし、テンプレートを使用して、出力の形式を変更することができます。</para>
<section>
<title>事前定義した出力フォーマット</title>
<para>Visual Studioに互換性のある形式が必要な場合には、<parameter class="command">--template=vs</parameter>を使用します。</para>
<programlisting>cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c</programlisting>
<para>このオプションは出力形式を次のように変更します。:</para>
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
samples/arrayIndexOutOfBounds/bad.c(6): error: Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
<para><literal>gcc</literal>に互換性のある出力が必要な場合には、<parameter class="command">--template=gcc</parameter>を使用します。:</para>
<programlisting>cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c</programlisting>
<para>このオプションは出力形式を次のように変更します。:</para>
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
samples/arrayIndexOutOfBounds/bad.c:6:6: warning: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds]
a[2] = 0;
^</programlisting>
</section>
<section>
<title>ユーザー定義出力形式(1行)</title>
<para>自分で自身でパターンを作成できます。例えば古い<literal>gcc</literal> のよuな出力フォーマットで警告メッセージを出力してほしい場合次のように指定します。:</para>
<programlisting>cppcheck --template="{file}:{line}: {severity}: {message}" samples/arrayIndexOutOfBounds/bad.c</programlisting>
<para>このオプションは出力形式を次のように変更します。:</para>
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
samples/arrayIndexOutOfBounds/bad.c:6: error: Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
<para>コンマ区切りフォーマット:</para>
<programlisting>cppcheck --template="{file},{line},{severity},{id},{message}" samples/arrayIndexOutOfBounds/bad.c</programlisting>
<para>このオプションは出力形式を次のように変更します。:</para>
<programlisting>Checking samples/arrayIndexOutOfBounds/bad.c ...
samples/arrayIndexOutOfBounds/bad.c,6,error,arrayIndexOutOfBounds,Array 'a[2]' accessed at index 2, which is out of bounds.</programlisting>
</section>
<section>
<title>ユーザー定義出力形式(複数行)</title>
<para>多くの警告は、複数の位置を指定します。サンプルコード:</para>
<programlisting>void f(int *p)
{
*p = 3; // line 3
}
int main()
{
int *p = 0; // line 8
f(p); // line 9
return 0;
}</programlisting>
<para>3行目でヌルポインタのデリファレンスの可能性があります。Cppcheckは追加の位置情報を表示してその結論がどこから発生したかを示すことができます。そのためには、コマンドラインで<literal>--template</literal> と <literal>--template-location</literal>の両方を使用する必要があります。</para>
<para>サンプルコマンド:</para>
<programlisting>cppcheck --template="{file}:{line}: {severity}: {message}\n{code}" --template-location="{file}:{line}: note: {info}\n{code}" multiline.c</programlisting>
<para>cppcheck は次のように出力します。</para>
<programlisting>Checking multiline.c ...
multiline.c:3: warning: Possible null pointer dereference: p
*p = 3;
^
multiline.c:8: note: Assignment 'p=0', assigned value is 0
int *p = 0;
^
multiline.c:9: note: Calling function 'f', 1st argument 'p' value is 0
f(p);
^
multiline.c:3: note: Null pointer dereference
*p = 3;
^</programlisting>
<para>この警告の最初の行は<literal>--template</literal> で指定したフォーマットです。</para>
<para>この警告の残りの行は<literal>--template-location</literal>で指定したフォーマットです。</para>
</section>
<section>
<title>--templateで指定するフォーマット</title>
<para><literal>--template</literal> では以下の要素が利用できます。:</para>
<variablelist>
<varlistentry>
<term>{file}</term>
<listitem>
<para>ファイル名</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{line}</term>
<listitem>
<para>行数</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{column}</term>
<listitem>
<para>カラム番号</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{callstack}</term>
<listitem>
<para>全ての位置。それぞれの位置は[{file}:{line}]のフォーマットで記載され、また->で位置を区切ります。例えば次のようになります。: [multiline.c:8] -> [multiline.c:9] -> [multiline.c:3]</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{inconclusive:text}</term>
<listitem>
<para>警告が確定的でない場合のメッセージを表示します。このメッセージは含まれていない場合もある、任意のテキストです。サンプル: {inconclusive:inconclusive,}</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{severity}</term>
<listitem>
<para>エラー/警告/スタイル/性能/移植性/情報</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{message}</term>
<listitem>
<para>警告メッセージ</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{id}</term>
<listitem>
<para>警告id</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{code}</term>
<listitem>
<para>実際のコード</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\t</term>
<listitem>
<para>タブ</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\n</term>
<listitem>
<para>改行</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\r</term>
<listitem>
<para>キャリッジリターン</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section>
<title>--template-location で指定するフォーマット</title>
<para><literal>--template-location</literal>では以下の要素が利用できます。:</para>
<variablelist>
<varlistentry>
<term>{file}</term>
<listitem>
<para>ファイル名</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{line}</term>
<listitem>
<para>行数</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{column}</term>
<listitem>
<para>カラム番号</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{info}</term>
<listitem>
<para>現在位置についての情報メッセージ</para>
</listitem>
</varlistentry>
<varlistentry>
<term>{code}</term>
<listitem>
<para>実際のコード</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\t</term>
<listitem>
<para>タブ</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\t</term>
<listitem>
<para>改行</para>
</listitem>
</varlistentry>
<varlistentry>
<term>\r</term>
<listitem>
<para>キャリッジリターン</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</chapter>
<chapter>
<title>Misra</title>
<para>Cppcheckは<literal>MISRA</literal> C 2012 向けのチェッカのアドオンを持っています。</para>
<section>
<title>要求事項</title>
<para>必要なもの:</para>
<itemizedlist>
<listitem>
<para>Python (2系 または 3系)</para>
</listitem>
<listitem>
<para><literal>MISRA C 2012</literal>の PDFこのPDFは<uri>http://www.misra.org.uk</uri>で購入できます (15-20 ポンド)</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>MISRA テキストファイル</title>
<para><literal>MISRA</literal>ルールテキストの公開は禁止されています。そのため<literal>MISRA</literal>ルールテキストはこのアドオンから直接利用できません。代わりにこのアドオンはテキストファイルからルールのテキストを読み込みます。MISRA PDFの ”Appendix A Summary of guidelines"のテキストをコピーペーストした場合、それがルールのテキストになります。</para>
<para>もしあなたが<literal>xpdf</literal>を持っているなら、テキストファイルはコマンドラインから簡単に生成できます。 (<literal>pdftotext</literal> は<literal>xpdf</literal>に含まれています。):</para>
<programlisting>pdftotext misra-c-2012.pdf output.txt</programlisting>
<para>この出力は100%完璧であるとは限りません。少し手直しする必要があることもあります。</para>
<para>その他のpdfからtextに変換するソフトでもうまくいくでしょう。</para>
<para>テキストファイルをマニュアルで作成してするには、MISRA PDFの Appendix A "Summary of guidelines" をコピーペーストします。フォーマット:</para>
<programlisting>Appendix A Summary of guidelines
Rule 1.1
Rule text
Rule 1.2
Rule text
...</programlisting>
<para>あなたが無効にしたいルールは、ルールテキストがなくても構いません。ルールテキストのないルールはアドオンによって抑制されます。</para>
</section>
</chapter>
<chapter>
<title>出力の抑制</title>
<para>ある種のエラーをフィルタリングしたい場合、出力を抑制することができます。</para>
<section>
<title>プレーンテキスト抑制</title>
<para>エラーの種類によって出力を抑制することができます。つぎのいずれかの形式で出力を抑制します。:</para>
<programlisting>[error id]:[filename]:[line]
[error id]:[filename2]
[error id]</programlisting>
<para>この<replaceable>error id</replaceable> は抑制したいエラーのidです。このエラーのIDを簡単に調べるには、<parameter class="command">--xml</parameter>オプションをコマンドラインで与えます。そのXML出力から、<replaceable>id</replaceable>の文字列が取得できます。このエラーのIDに<literal>*</literal>を指定して全ての種類のメッセージを抑制することができます。(これは指定したファイルに限ることができます。)</para>
<para>また<replaceable>filename</replaceable>にはワイルドキャラクターである、<literal>*</literal> または <literal>?</literal>を含めることができます。前者には全ての文字列にマッチし、後者は任意の一文字にマッチします。またWindowsを含む全てのOSで、パス区切りに"/" を使うことをお勧めします。</para>
<section>
<title>コマンドライン抑制</title>
<para><parameter class="command">--suppress=</parameter>のコマンドラインオプションを使用して、コマンドラインで抑制を指定することができます。例:</para>
<programlisting>cppcheck --suppress=memleak:src/file1.cpp src/</programlisting>
</section>
<section>
<title>ファイルで抑制リストを指定</title>
<para>また、抑制ファイルを作成することもできます。例:</para>
<programlisting>// src/file1.cppのmemleak と exceptNew の エラーを抑制
memleak:src/file1.cpp
exceptNew:src/file1.cpp
// 全てのファイルのuninitvarエラーを抑制する。
uninitvar</programlisting>
<para>空行やコメント行を抑制ファイルに記載することができます。</para>
<para>そして、この抑制ファイルは次のようにして使用します。:</para>
<programlisting>cppcheck --suppressions-list=suppressions.txt src/</programlisting>
</section>
</section>
<section>
<title>XML 抑制</title>
<para>XMLファイルで抑制を指定できます。サンプルファイル:</para>
<programlisting><?xml version="1.0"?>
<suppressions>
<suppression>
<id>uninitvar</id>
<fileName>src/file1.c</fileName>
<lineNumber>10</lineNumber>
<symbolName>var</symbolName>
</suppression>
</suppressions></programlisting>
<para>このXMLフォーマットは拡張可能であり、将来さらなる属性を加えるかもしれません。</para>
</section>
<section>
<title>インライン出力抑制</title>
<para>エラー出力の抑制をソースコード中に直接、コメントの形で記載することもできます。このコメントには特別なキーワードを含めて記載します。ただし、インライン出力を抑制するコメントをソースコードに追加すると、ソースコードの可読性が少し悪くなってしまうかもしれません。</para>
<para>このソースコードは通常エラメッセージを出力する例です。:</para>
<programlisting>void f() {
char arr[5];
arr[10] = 0;
}</programlisting>
<para>前のソースコードに対する出力は次のようになります。:</para>
<programlisting># cppcheck test.c
Checking test.c...
[test.c:3]: (error) Array 'arr[5]' index 10 out of bounds</programlisting>
<para>このエラーメッセージを抑制するには次のようなコメントを追加します。:</para>
<programlisting>void f() {
char arr[5];
// cppcheck-suppress arrayIndexOutOfBounds
arr[10] = 0;
}</programlisting>
<para>これで、--inline-suppr オプションの準備ができました。次のようにcppcheckを起動するとエラーが抑制されます。:</para>
<programlisting>cppcheck --inline-suppr test.c</programlisting>
<para>特定のシンボルにのみ適用するインライン抑制を指定できます。:</para>
<programlisting>// cppcheck-suppress arrayIndexOutOfBounds symbolName=arr</programlisting>
<para>抑制のためにコメントを書きます。; や // を使って開始点を指定できます。</para>
<programlisting>// cppcheck-suppress arrayIndexOutOfBounds ; some comment
// cppcheck-suppress arrayIndexOutOfBounds // some comment</programlisting>
</section>
</chapter>
<chapter>
<title>ライブラリ設定</title>
<para>WinAPI, POSIX, gtk, Qtなど他の外部のライブラリを使用した場合、<literal>Cppcheck</literal>は外部の関数がどのようなものであるかがわかりません。<literal>Cppcheck</literal> はそのため、メモリリークやバッファオーバーフロー、ヌルポインタのデリファレンスの可能性といったさまざまな問題が検出できません。これを解決するには設定ファイル(.cfg file)を使用します。</para>
<para>Cppcheckはいくつかのライブラリ用の設定を持っています。これらは次のようにしてロードできます。cppcheckは C または C++言語用の標準ライブラリの設定 <literal>std.cfg</literal>はいつもロードします。ご注意ください。もしあなたが有名なライブラリの設定ファイルを作成した場合や更新した場合には、私達のサイトにアップロードしてくれると非常に助かります。</para>
<section>
<title>カスタム設定ファイル(.cfg file)の使用</title>
<para>あなたのプロジェクト専用の設定ファイルを作成し、使用することができます。そのためには、<literal>--check-library</literal> と<literal>--enable=information</literal> を使用して設定のためのヒントを入手します。</para>
<para>設定ファイルの編集に、<literal>Library Editor</literal>の使用をお勧めします、これは<literal>Cppcheck GUI</literal>に含まれています。これは<literal>View</literal>メニューで使用できます。すべての設定がこのマニュアルに載っていません。</para>
<para>この設定ファイル<literal>.cfg</literal>のフォーマットに質問がある場合、フォーラム(http://sourceforge.net/p/cppcheck/discussion/)で質問してください。</para>
<para>コマンドラインのcppcheck はカスタマイズした設定ファイル(.cfg files)を作業パスから読み込もうとします。作業パスはcppcheckを実行しているパスですでそこに設定ファイルがあると考えます。</para>
<para>GUIのcppcheckはプロジェクトのファイルパスから設定ファイルを読み込もうとします。カスタマイズした設定ファイル(.cfg file)は <literal>プロジェクトファイルの編集</literal> ダイアログで確認できます。このタイアログを表示させるには<literal>ファイル</literal> メニューから開いてください。</para>
</section>
<section>
<title>メモリーリソースのリーク</title>
<para>Cppcheck はリークのチェックが調整できます。言い換えれば、あなたはメモリーやリソースを割り当てる関数またはその割り当てを回収する関数を指定できます。</para>
<section>
<title>alloc と dealloc</title>
<para>ここにサンプルのプログラムがあります。:</para>
<para><programlisting>void test()
{
HPEN pen = CreatePen(PS_SOLID, 1, RGB(255,0,0));
}</programlisting></para>
<para>上のコード例はリソースリークの欠陥があります。 - <literal>CreatePen()</literal> は WinAPI 関数でpenを作成します。しかし、Cppcheckは関数からの返り値が解放されていなければならないと仮定しません。そのためエラーメッセージは表示されません。:</para>
<programlisting># cppcheck pen1.c
Checking pen1.c...</programlisting>
<para>もしあなたが設定ファイルを与えれば、<literal>Cppcheck</literal>はバグを検出します。:</para>
<programlisting># cppcheck --library=windows.cfg pen1.c
Checking pen1.c...
[pen1.c:3]: (error) Resource leak: pen</programlisting>
<para>これが最小限の<literal>windows.cfg</literal> ファイルです:</para>
<programlisting><?xml version="1.0"?>
<def>
<resource>
<alloc>CreatePen</alloc>
<dealloc>DeleteObject</dealloc>
</resource>
</def></programlisting>
<para>このアロケート関数とデアロケート関数はグループにまとめられています。それぞれのグループは<literal><resource></literal> や <literal><memory></literal> タグ中で定義されており、その<literal><dealloc></literal>関数によって特定されます。これは、<literal><dealloc></literal>タグでオーバーラップしたグループはマージされます。</para>
</section>
<section>
<title>leak-ignore とuse</title>
<para>しばしば、割り当てられたポインタを関数に渡すことがあります。例:</para>
<programlisting>void test()
{
char *p = malloc(100);
dostuff(p);
}</programlisting>
<para>もし設定ファイルがなく、Cppcheckが<literal>dostuff</literal>の仕様を把握していなければ、Cppcheckは<literal>dostuff</literal>がメモリーについて配慮しており、メモリーリークは発生しないと仮定します。</para>
<para><literal>dostuff</literal>がメモリーについて配慮せず、解放などを行なっていないことを指定するためには、<literal>leak-ignore</literal>を<literal><function></literal> タグ中で使います。:</para>
<programlisting><?xml version="1.0"?>
<def>
<function name="dostuff">
<leak-ignore/>
<arg nr="1"/>
</function>
</def></programlisting>
<para>これとは逆に<literal>dostuff</literal>がメモリーについて配慮している場合には次のように設定します。:</para>
<programlisting><?xml version="1.0"?>
<def>
<memory>
<dealloc>free</dealloc>
<use>dostuff</use>
</memory>
</def></programlisting>
<para>なお、この<literal><use></literal>の設定は論理的に全く無意味です。この設定がない場合でも同じエラーが表示されます。これは<literal>--check-library</literal>のinformationメッセージを減らすために使用します。</para>
</section>
</section>
<section>
<title>関数の動作</title>
<para>関数の動作や関数の使用方法を指定するのに、<literal><function></literal>タグが使えます。関数は、その名前によって特定されます。この名前は、<literal>name</literal> 属性とその引数によって指定されます。この名前はコンマで区切られた関数名のリストです。名前空間やクラス中の関数の場合には、完全修飾名で指定されます。例: <literal><function name="memcpy,std::memcpy"></literal>もしテンプレート関数がある場合、インスタンス化した名前を提供してします。<literal><function name="dostuff<int>"></literal>.</para>
<section>
<title>関数引き数</title>
<para>関数がとる引数は、<literal><arg></literal>タグで指定できます。引数のそれぞれは、引数の順番(1始まり)を<literal>nr</literal>属性で示します。<literal>nr="any"</literal> は任意の引き数を表します。また、<literal>nr="variadic"</literal>は可変長引数を表します。オプション引数は、デフォルト値で指定します。: <literal>default="value"</literal>. それぞれの引数に対する設定は、全ての引数に対する指定を上書きします。</para>
<section>
<title>非ブール</title>
<para>ここで誤った比較のあるサンプルプログラムがあります。:</para>
<programlisting>void test()
{
if (MemCmp(buffer1, buffer2, 1024==0)) {}
}</programlisting>
<para><literal>Cppcheck</literal>は、この関数にブール値を渡してよいと仮定します。:</para>
<programlisting># cppcheck notbool.c
Checking notbool.c...</programlisting>
<para>もしあなたが設定ファイルを与えれば、Cppcheckはバグを検出します。:</para>
<programlisting># cppcheck --library=notbool.cfg notbool.c
Checking notbool.c...
[notbool.c:5]: (error) Invalid MemCmp() argument nr 3. 非ブール値が求められています。</programlisting>
<para>ここで最小のnotbool.cfgを用意しました。</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="MemCmp">
<arg nr="1"/>
<arg nr="2"/>
<arg nr="3">
<not-bool/>
</arg>
</function>
</def></programlisting></para>
</section>
<section>
<title>未初期化メモリ</title>
<para>ここにサンプルのプログラムがあります。:</para>
<programlisting>void test()
{
char buffer1[1024];
char buffer2[1024];
CopyMemory(buffer1, buffer2, 1024);
}</programlisting>
<para>このプログラムのバグは buffer2 が初期化されていないことです。CopyMemory 関数の第二引数は初期化されている必要があります。しかし、<literal>Cppcheck</literal>は関数に未初期化の変数を渡してもよいと仮定しています。:</para>
<programlisting># cppcheck uninit.c
Checking uninit.c...</programlisting>
<para>もしあなたが設定ファイルを与えれば、Cppcheckはバグを検出します。:</para>
<programlisting># cppcheck --library=windows.cfg uninit.c
Checking uninit.c...
[uninit.c:5]: (error) Uninitialized variable: buffer2</programlisting>
<para>注意:これは、ポインタが示すメモリ領域が初期化されていなければならないことを意味しています。</para>
<para>これが最小限の<literal>windows.cfg</literal>ファイルです。:</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="CopyMemory">
<arg nr="1"/>
<arg nr="2">
<not-uninit/>
</arg>
<arg nr="3"/>
</function>
</def></programlisting></para>
</section>
<section>
<title>ヌルポインタ</title>
<para>Cppcheckは、関数にヌルポインタを渡してもよいと仮定しています。ここにサンプルのプログラムがあります。:</para>
<programlisting>void test()
{
CopyMemory(NULL, NULL, 1024);
}</programlisting>
<para>MSDNの文書はこれが問題あるかないかを明らかにしていません。しかし、ここでは問題ありと仮定します。Cppcheck は関数にヌルポインタを渡してもよいと仮定していますので、エラーを出力しません。:</para>
<programlisting># cppcheck null.c
Checking null.c...</programlisting>
<para>もしあなたが設定ファイルを与えれば、<literal>Cppcheck</literal>はバグを検出します。:</para>
<programlisting>cppcheck --library=windows.cfg null.c
Checking null.c...
[null.c:3]: (error) Null pointer dereference</programlisting>
<para>注意:<literal><not-uninit></literal>は値について意味しています。初期化されていないメモリが関数に渡されています。</para>
<para>これが最小限の<literal>windows.cfg</literal> ファイルです:</para>
<programlisting><?xml version="1.0"?>
<def>
<function name="CopyMemory">
<arg nr="1">
<not-null/>
</arg>
<arg nr="2"/>
<arg nr="3"/>
</function>
</def></programlisting>
</section>
<section>
<title>フォーマット文字列</title>
<para>フォーマット文字列を扱う関数を定義できます。例:</para>
<programlisting>void test()
{
do_something("%i %i\n", 1024);
}</programlisting>
<para>これについてもエラーは報告されません。:</para>
<programlisting># cppcheck formatstring.c
Checking formatstring.c...</programlisting>
<para>引数がフォーマット文字列であることを出力する設定ファイルが作成できます。設定ファイルの例です。:</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="do_something">
<formatstr type="printf"/>
<arg nr="1">
<formatstr/>
</arg>
</function>
</def></programlisting>これで、Cppcheckはエラーを報告できるようになりました。:</para>
<programlisting>cppcheck --library=test.cfg formatstring.c
Checking formatstring.c...
[formatstring.c:3]: (error) do_something format string requires 2 parameters but only 1 is given.</programlisting>
<para>このフォーマット文字列の<literal>type</literal>属性は次のどちらかになります。:</para>
<itemizedlist>
<listitem>
<para>printf - printf のルールに従うフォーマット文字列</para>
</listitem>
<listitem>
<para>scanf - scanf のルールに従うフォーマット文字列</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>値の範囲</title>
<para>有効な値の範囲が定義できます。想像してください。:</para>
<programlisting>void test()
{
do_something(1024);
}</programlisting>
<para>これについてもエラーは報告されません。:</para>
<programlisting># cppcheck valuerange.c
Checking valuerange.c...</programlisting>
<para>1024 が 範囲外の値であることを出力する設定ファイルが作成できます。設定ファイルの例です。:</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="do_something">
<arg nr="1">
<valid>0:1023</valid>
</arg>
</function>
</def></programlisting>これで、Cppcheckはエラーを報告できるようになりました。:</para>
<programlisting>cppcheck --library=test.cfg range.c
Checking range.c...
[range.c:3]: (error) Invalid do_something() argument nr 1. この値は1024ですが、妥当な値は0から1023までです。</programlisting>
<para>validの要素で次のような表現が利用できます。:</para>
<programlisting>0,3,5 => 0, 3 それに 5 だけが有効な値です。
-10:20 => -10 から 20 までの値(両端含む)が有効な値です。
:0 => 0または0未満の値が有効な値です。
0: => 0または0以上の値が有効な値です。
0,2:32 => 0 または2から32までの値(両端含む)が有効な値です。
-1.5:5.6 => -1.5 から 5.6 までの値(両端含む)が有効な値です。 </programlisting>
</section>
<section>
<title>最小サイズ</title>
<para>いくつかの関数はバッファーを引数にとります。バッファの最小サイズを指定することができます。(要素数ではなくバイト数です。)想像してください。:</para>
<programlisting>void test()
{
char str[5];
do_something(str,"12345");
}</programlisting>
<para>これについてもエラーは報告されません。:</para>
<programlisting># cppcheck minsize.c
Checking minsize.c...</programlisting>
<para>設定ファイルで、例えば、引数1のバッファのサイズが引数2の文字列長より大きくなればならないと警告するような設定ファイルを作成できます。例を挙げます。:</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="do_something">
<arg nr="1">
<minsize type="strlen" arg="2"/>
</arg>
<arg nr="2"/>
</function>
</def></programlisting>これで、Cppcheckはこのエラーを報告できるようになりました。:</para>
<programlisting>cppcheck --library=1.cfg minsize.c
Checking minsize.c...
[minsize.c:4]: (error) Buffer is accessed out of bounds: str
</programlisting>
<para>minsizes はいくつかの種類があります。:</para>
<variablelist>
<varlistentry>
<term>strlen</term>
<listitem>
<para>バッファーのサイズが、その他の引数の文字列長より大きくなければなりません。例: std.cfg のstrcpyの設定を参照してください。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>argvalue</term>
<listitem>
<para>バッファーのサイズがその他の引数の値より大きくなればなりません。例: std.cfg のmemsetの設定を参照してください。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>sizeof</term>
<listitem>
<para>バッファーのサイズがその他の引数のバッファーのサイズより大きくなればなりません。例:posix.cfgのmemccpyの設定をみてください。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>mul</term>
<listitem>
<para>バッファーのサイズがその他の2つの引数の値の積より大きくなればなりません。典型的な使用例としては、一つの引数が構造体などの要素のサイズを指定し、もうひとつの引数が要素の個数を定義するような場合です。例: std.cfg のfreadの設定を参照してください</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section>
<title>strz</title>
<para>これを指定すると、数が0終端文字列でなければならないということができます。</para>
<para><programlisting><?xml version="1.0"?>
<def>
<function name="do_something">
<arg nr="1">
<strz/>
</arg>
</function>
</def></programlisting></para>
</section>
</section>
<section>
<title>noreturn</title>
<para>Cppcheck はこの関数がいつも値を返すとは仮定していません。ここにサンプルのプログラムがあります。:</para>
<programlisting>void test(int x)
{
int data, buffer[1024];
if (x == 1)
data = 123;
else
ZeroMemory(buffer, sizeof(buffer));
buffer[0] = data; // <- error: xが1でないとき初期化されていない
}</programlisting>
<para>理屈の上では、<literal>ZeroMemory</literal>がプログラムを終了させてもバグはありません。そのため Cppcheckはエラーを報告しません。:</para>
<programlisting># cppcheck noreturn.c
Checking noreturn.c...</programlisting>
<para>しかし、<literal>--check-library</literal> をつかうとエラーが出力されます。:</para>
<programlisting># cppcheck --check-library noreturn.c
Checking noreturn.c...
[noreturn.c:7]: (information) --check-library: Function ZeroMemory() should have <noreturn> configuration
</programlisting>
<para>もし適切な <literal>windows.cfg</literal> が提供されていましたら、このバグは検出されます。:</para>
<programlisting># cppcheck --library=windows.cfg noreturn.c
Checking noreturn.c...
[noreturn.c:8]: (error) Uninitialized variable: data</programlisting>
<para>これが最小限の<literal>windows.cfg</literal> ファイルです:</para>
<programlisting><?xml version="1.0"?>
<def>
<function name="ZeroMemory">
<noreturn>false</noreturn>
<arg nr="1"/>
<arg nr="2"/>
</function>
</def></programlisting>
</section>
<section>
<title>use-retval</title>
<para>他になにも指定されていない限り、cppcheckは関数が返り値を無視していても問題ないと仮定します。:</para>
<programlisting>bool test(const char* a, const char* b)
{
strcmp(a, b); // <- bug: strcmp の呼び出しは副作用を持ちませんが返り値を無視している。
return true;
}</programlisting>
<para><literal>strcmp</literal> が副作用を持つ場合、パラメータが関数に渡されている結果を無視しても問題はなく、このような仮定は正しいといえます。:</para>
<programlisting># cppcheck useretval.c
Checking useretval.c...</programlisting>
<para>もし適切な<literal>lib.cfg</literal> が提供されていましたら、このバグは検出されます。:</para>
<programlisting># cppcheck --library=lib.cfg --enable=warning useretval.c
Checking useretval.c...
[useretval.c:3]: (warning) Return value of function strcmp() is not used.</programlisting>
<para>これが最小限の<literal>lib.cfg</literal> ファイルです。:</para>
<programlisting><?xml version="1.0"?>
<def>
<function name="strcmp">
<use-retval/>
<arg nr="1"/>
<arg nr="2"/>
</function>
</def></programlisting>
</section>
<section>
<title>pure関数(pure)とconst関数</title>
<para>これらは、GCC関数属性のpureとconstに対応します。</para>
<para>pure関数は、値を返す以外の効果を持ちません。そしてその返り値はその関数の引数とグローバル変数によってのみ決まります。</para>
<para>const関数は、値を返す以外の効果を持ちません。そしてその返り値はその関数の引数によってのみ決まります。</para>
<para>ここにサンプルのプログラムがあります。:</para>
<programlisting>void f(int x)
{
if (calculate(x) == 213) {
} else if (calculate(x) == 213) {
// 到達不能コード
}
}</programlisting>
<para>もし<literal>calculate()</literal> がconst関数であれば、<literal>calculate(x)</literal>は両方の条件で同じ値を返します。というのも、同じパラメータを引数にしているからです。</para>
<para>Cppcheck は通常、その結果が異なると仮定するため、Cppcheckはこのコード例に警告を出しません。:</para>
<programlisting># cppcheck const.c
Checking const.c...</programlisting>
<para>もし適切な<literal>const.cfg</literal> が提供されていましたら、このバグは検出されます。:</para>
<programlisting># cppcheck --enable=style --library=const const.c
Checking const.c...
[const.c:7]: (style) Expression is always false because 'else if' condition matches previous condition at line 5.</programlisting>
<para>これが最小限の<literal>const.cfg</literal> ファイルです。:</para>
<programlisting><?xml version="1.0"?>
<def>
<function name="calculate">
<const/>
<arg nr="1"/>
</function>
</def></programlisting>
</section>
<section>
<title>関数strcpyの設定例</title>
<para>標準関数のstrcpyのための適切な設定は次のようになる。:</para>
<programlisting> <function name="strcpy">
<leak-ignore/>
<noreturn>false</noreturn>
<arg nr="1">
<not-null/>
</arg>
<arg nr="2">
<not-null/>
<not-uninit/>
<strz/>
</arg>
</function></programlisting>
<para>この<literal><leak-ignore/></literal> は、リークチェック中に関数呼び出しを無視するように、Cppcheckに伝えます。この関数は、割り当てられたメモリを解放しないことを意味しています。</para>
<para>この<literal><noreturn></literal> は、この関数が、返り値を返すかどうかをCppchecに伝えます。</para>
<para>この関数は第一引数にポインタを取ります。しかしこのポインタは、ヌルポインタであってはなりません。というのは<literal><not-null></literal>が使用されているからです。</para>
<para>この関数は第二引数にポインタを取ります。このポインタはヌルポインタであってはなりません。また、このポインタは初期化されたデータを指していなければなりません。<literal><not-null></literal> と <literal><not-uninit></literal> は正しく使用されています。さらにいえば、このポインタは0終端文字列(zero-terminated string)でなければなりません。そのため<strz>が使用されています。</para>
</section>
</section>
<section>
<title>define</title>
<para>ライブラリはマクロプリプロセッサのdefineを使用することができます。例:</para>
<programlisting><?xml version="1.0"?>
<def>
<define name="NULL_VALUE" value="0"/>
</def></programlisting>
<para>プリプロセッサの段階でソースコード中に "NULL_VALUE" が現れるごとに、"0"で置き換えます。</para>
</section>
<section>
<title>podtype</title>
<para>多くのソースコードで、プラットフォームに依存しない型をtypedefによって定義しています。"podtype"のタグによって、cppcheckがこれらをサポートするために必要な情報を提供できます。このような情報のない場合、cppcheckは次の例でみるような "uint16_t" 型を理解できません。</para>
<programlisting>void test() {
uint16_t a;
}</programlisting>
<para>そのため、未使用変数である、'a'が未使用であるとのメッセージが表示されません。</para>
<programlisting># cppcheck --enable=style unusedvar.cpp
Checking unusedvar.cpp...</programlisting>
<para>もし uint16_t が以下のように定義されていた場合、結果にメッセージが反映されます。</para>
<programlisting><?xml version="1.0"?>
<def>
<podtype name="uint16_t" sign="u" size="2"/>
</def></programlisting>
<para>型のサイズはバイトサイズで指定します。符号の "sign" 属性は 符号ありの "s" か 符号無し "u" のどちらかです。これらの属性はオプションです。このライブラリを使用しますと、cppcheckはメッセージを表示できるようになります。</para>
<programlisting># cppcheck --library=lib.cfg --enable=style unusedvar.cpp
Checking unusedvar.cpp...
[unusedvar.cpp:2]: (style) Unused variable: a</programlisting>
</section>
<section>
<title>コンテナ(container)</title>
<para>C++ ライブラリの多くや STL 自身は、非常によく似た機能性をもつコンテナを提供します。ライブラリによってその動作をcppcheckに伝えられます。それぞれのコンテナの設定にはユニークなIDが必要とします。コンテナの設定には、startPatternを加えることができます(オプション)。この startPatternはToken::Match パターンとendPattern に有効でなけばなりません。また、このendPatternはリンクしているトークンと比較されるものです。オブション属性の"inherits"は事前に定義されたコンテナのIDをとります。</para>
<para><container>タグの内部で、<size>、<access>、<other>を選択して使用して関数を定義できます。これらのタグはそれぞれ、"resize" やその結果を与えるような動作を指定することができます。その例 "end-iterator"を示します。</para>
<para>次の例は、std::vectorの為の定義を示しています。std::vectorは"stdContainer"の定義に基づいていますが、ここには表示していません。:</para>
<programlisting><?xml version="1.0"?>
<def>
<container id="stdVector" startPattern="std :: vector &lt;" inherits="stdContainer">
<size>
<function name="push_back" action="push"/>
<function name="pop_back" action="pop"/>
</size>
<access indexOperator="array-like">
<function name="at" yields="at_index"/>
<function name="front" yields="item"/>
<function name="back" yields="item"/>
</access>
</container>
</def></programlisting>
</section>
</chapter>
<chapter>
<title>ルール(Rules)</title>
<para>正規表現を使用して、ユーザーがルール(rule)を定義することができます。</para>
<para>これらのカスタムルールは、ソースコードを高度に分析した結果を使用することができません。しかしソースコード中の非常にシンプルなパターンについて簡単にルールを作成することができます。</para>
<para>ルールの作成を始めるには次の関連記事を参照してください。:</para>
<para><ulink url="http://sourceforge.net/projects/cppcheck/files/Articles/">http://sourceforge.net/projects/cppcheck/files/Articles/</ulink></para>
<para>ルールのファイルフォーマットは次のとおりです。:</para>
<programlisting><?xml version="1.0"?>
<rule>
<tokenlist>LIST</tokenlist>
<pattern>PATTERN</pattern>
<message>
<id>ID</id>
<severity>SEVERITY</severity>
<summary>SUMMARY</summary>
</message>
</rule></programlisting>
<para>patternタグ中にCDATAを含めた場合、XMLに干渉する可能性がありますので使用時はご注意ください。:</para>
<programlisting><![CDATA[some<strange>pattern]]></programlisting>
<section>
<title><tokenlist></title>
<para>この<literal><tokenlist></literal> 要素はオプションです。この要素がある場合、どのトークンをチェックするかを指示することができます。この<literal>LIST</literal>は<literal>define</literal>, <literal>raw</literal>, <literal>normal</literal> , <literal>simple</literal>のいずれかです。</para>
<variablelist>
<varlistentry>
<term>define</term>
<listitem>
<para>#define プリプロセッサの記述をチェックするために使用します。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>raw</term>
<listitem>
<para>プリプロセッサの出力をチェックするために使用します。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>normal</term>
<listitem>
<para><literal>normal</literal> のトークンリストをチェックするために使用します。ソースコードをある程度、単純化した結果をチェックすることになります。</para>
</listitem>
</varlistentry>
<varlistentry>
<term>simple</term>
<listitem>
<para>単純なトークンリストをチェックするために使用します。ソースコードを完全に単純化した結果をチェックすることになります。ほとんどの Cppcheckのチェックには、この 単純ばトークンリストを使用します。</para>
</listitem>
</varlistentry>
</variablelist>
<para>もし<tokenlist>要素を省略した場合、<literal>simple</literal> が使用されます。</para>
</section>
<section>
<title><pattern></title>
<para>この<literal>PATTERN</literal> にはPerlの正規表現と互換性のある正規表現 <literal>PCRE</literal>を指定します。</para>
</section>
<section>
<title><id></title>
<para>この ID にはユーザーが定義した message idを指定します。</para>
</section>
<section>
<title><severity></title>
<para>この<literal>SEVERITY</literal>には<literal>Cppcheck</literal> の厳格度(severities)である、次のいずれかを指定します。: <literal>information</literal>, <literal>performance</literal>, <literal>portability</literal>, <literal>style</literal>, <literal>warning</literal>,<literal>error</literal></para>
</section>
<section>
<title><summary></title>
<para>オプションです。メッセージのサマリーです。もしこのsummaryトークンが指定されていなければ、マッチしたトークンが出力されます。</para>
</section>
</chapter>
<chapter>
<title>Cppcheck アドオン</title>
<para>Cppcheckのアドオンは、個別のスクリプトや個別のプログラムとして実装されています。Cppcheckのアドオンを使用すると次のような利点があります。</para>
<itemizedlist>
<listitem>
<para>洗練された分析の結果を使用した個別の、外部チェックを追加できます。</para>
</listitem>
<listitem>
<para>ソースコードが可視化できます。</para>
</listitem>
<listitem>
<para>その他</para>
</listitem>
</itemizedlist>
<section>
<title>Cppcheckアドオンの使用方法</title>
<para>現在、アドオンを使用するには2段階の操作が必要です。:</para>
<orderedlist>
<listitem>
<para>Cppcheckを実行し、ダンプファイルを生成します。</para>
</listitem>
<listitem>
<para>アドオンでダンプファイルを処理します。</para>
</listitem>
</orderedlist>
<para><literal>--dump</literal>フラグを使用するとダンプファイルを生成できます。foo/ フォルダ以下の全てのソースファイルからダンプファイルを生成するには次のようにします。</para>
<programlisting>cppcheck --dump foo/</programlisting>
<para>foo/ フォルダ以下の全てのダンプファイルをアドオンで処理するには次のようにします。</para>
<programlisting>python addon.py foo/*.dump</programlisting>
<section>
<title>Cppcheckアドオンの見つけ方</title>
<para>ダウンロードできる、アドオンがいくつかあります。</para>
<itemizedlist>
<listitem>
<para>Cppcheck プロジェクトはいくつかのアドオンを以下の場所で提供しています。: <uri>http://github.com/danmar/cppcheck/blob/master/addons</uri></para>
</listitem>
<listitem>
<para>ublinterは規格で定義されていない未定義動作に注力した"lint"です。: <uri>http://github.com/danmar/ublinter</uri></para>
</listitem>
</itemizedlist>
<para>あなたのアドオンの情報をご紹介ください。(商用、フリーを問いません。)</para>
</section>
</section>
<section>
<title>Cppcheck アドオンの作成</title>
<para>Cppcheck は XML形式でダンプファイルを生成できます。このファイルには以下のようなものが含まれています。:</para>
<itemizedlist>
<listitem>
<para>トークンリスト(Token list)</para>
</listitem>
<listitem>
<para>シンタックスツリー(Syntax trees)</para>
</listitem>
<listitem>
<para>シンボルデータベース(関数、クラス、変数、スコープ)</para>
</listitem>
<listitem>
<para>既知の値(value flow analysis)</para>
</listitem>
</itemizedlist>
<para>Cppcheckはアドオンを直接実行することはできません。直接実行するためにインターフェースはありません。これは、次のような制限がないことを意味します。:</para>
<itemizedlist>
<listitem>
<para>アドオンを作成しリリースする際に、どのようなライセンスでも適用できます。</para>
</listitem>
<listitem>
<para>アドオンの作成に、どのようなスクリプト言語やプログラミング言語で作成できます。</para>
</listitem>
<listitem>
<para>アドオン作成者がユーザーインターフェースと出力を決定できます。</para>
</listitem>
<listitem>
<para>警告の生成以外の目的にもアドオン使用できます。</para>
</listitem>
</itemizedlist>
<para>アドオン作成者の利便性のために、Cppcheck プロジェクトは PythonからCppcheckのデータにアクセスするための cppcheckdata.pyを提供しています。cppcheckdata.pyの使用はオプションです。</para>
<section>
<title>使用例1 - 全トークンの表示</title>
<para>Script:</para>
<programlisting>import sys
import cppcheckdata
def printtokens(data):
for token in data.tokenlist:
print(token.str)
for arg in sys.argv[1:]:
printtokens(cppcheckdata.parse(arg))</programlisting>
</section>
<section>
<title>使用例2 - 全関数リストアップ</title>
<para>Script:</para>
<programlisting>import sys
import cppcheckdata
def printfunctions(data):
for scope in data.scopes:
if scope.type == 'Function':
print(scope.className)
for arg in sys.argv[1:]:
printfunctions(cppcheckdata.parse(arg))</programlisting>
</section>
<section>
<title>使用例 3 - 全クラスリストアップ</title>
<para>Script:</para>
<programlisting>import sys
import cppcheckdata
def printclasses(data):
for scope in data.scopes:
if scope.type == 'Class':
print(scope.className)
for arg in sys.argv[1:]:
printfunctions(cppcheckdata.parse(arg))</programlisting>
</section>
</section>
</chapter>
<chapter>
<title>HTML 形式での報告</title>
<para>cppcheckのXML出力をHTML形式に変更できます。これを利用するには、Python と pygments module (<ulink url="http://pygments.org/">http://pygments.org/</ulink>) が必要です。Cppcheckのソースツリーに<filename class="directory">htmlreport</filename>というフォルダがあります。このフォルダには、CppcheckのXMLファイルをHTML出力に変換するスクリプトがあります。</para>
<para>このコマンドでヘルプ画面を生成するには次のように実行します。</para>
<programlisting>htmlreport/cppcheck-htmlreport -h</programlisting>
<para>出力画面には次の内容が表示されます。:</para>
<programlisting>Usage: cppcheck-htmlreport [options]
Options:
-h, --help show this help message and exit
--file=FILE The cppcheck xml output file to read defects from.
Default is reading from stdin.
--report-dir=REPORT_DIR
The directory where the html report content is written.
--source-dir=SOURCE_DIR
Base directory where source code files can be found.</programlisting>
<para>使用例:</para>
<programlisting>./cppcheck gui/test.cpp --xml 2> err.xml
htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.</programlisting>
</chapter>
<chapter>
<title>グラフィカルインターフェースGUI</title>
<section>
<title>イントロダクション</title>
<para>Cppcheck GUIが利用できます。</para>
<para>メイン画面は、このソフトを起動時に表示されます。</para>
</section>
<section>
<title>ソースコードのチェック</title>
<para><guimenu>Check</guimenu>メニューを使用します。</para>
</section>
<section>
<title>結果の確認</title>
<para>結果はリスト表示されます。</para>
<para><guimenu>View</guimenu> メニューを操作して、メッセージの種類毎に表示/非表示を切り替えできます。</para>
<para>結果をXML ファイルに保存して、後で確認できます。<literal>Save results to file</literal> と <literal>Open XML</literal>を参照してください。</para>
</section>
<section>
<title>設定</title>
<para><guimenu>Language</guimenu>メニューからいつでも使用言語を変更できます。</para>
<para>設定は、<menuchoice> <guimenu>Edit</guimenu> <guimenuitem>Preferences</guimenuitem> </menuchoice>で変更できます。</para>
</section>
<section>
<title>プロジェクトファイル</title>
<para>プロジェクトファイルは、プロジェクト固有の設定を保存するのに使用します。固有の設定には次のものがあります。:</para>
<itemizedlist>
<listitem>
<para>インクルードパス</para>
</listitem>
<listitem>
<para>プリプロセッサのdefine</para>
</listitem>
</itemizedlist>
<para>このマニュアルの<link linkend="preprocessor-configurations">3 章</link>にあるように、全てのコンパイルスイッチの組み合わせをチェックします。コンパイルスイッチの組み合わせを制限したい場合にだけ、プリプロセッサのdefineを指定してください。</para>
</section>
</chapter>
</book>
|