├── .gitignore ├── CodeAnalysisDemoTcLibrary ├── CodeAnalysis │ ├── CodeAnalysis.plcproj │ ├── CodeAnalysis.tmc │ ├── POUs │ │ └── MAIN.TcPOU │ └── PlcTask.TcTTO ├── CodeAnalysisDemoTcLibrary.sln ├── CodeAnalysisDemoTcLibrary.tsproj └── LaunchPLCStaticAnalysis.bat ├── LICENSE ├── README.md └── TcStaticAnalysisLoader ├── TcStaticAnalysisLoader.sln └── TcStaticAnalysisLoader ├── App.config ├── Constants.cs ├── MessageFilter.cs ├── Options.cs ├── Program.cs ├── Properties └── AssemblyInfo.cs └── TcStaticAnalysisLoader.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | # ////////////////////////////////////////////////////////////////////////////// 2 | # 3 | # This file makes sure everything in this folder (recursively) according to the 4 | # rules specified here is ignored by GIT version controlling. 5 | # 6 | # Revision history: 7 | # 8 | # 1.0/2015-09-09/Jakob Sagatowski 9 | # First revision. Created a default ignorefile with some TwinCAT 10 | # files extensions recommended by Beckhoff. 11 | # 1.1/2016-11-28/Jakob Sagatowski 12 | # Removed included libraries 13 | # 1.2/2017-04-27/Jakob Sagatowski 14 | # Removed *.tmc from the git ignore. Now *.tmc-files are included. 15 | # 1.3/2017-12-14/Jakob Sagatowski 16 | # Added *.~u. 17 | # 1.4/2018-10-03/Jakob Sagatowksi 18 | # Added .vs/ 19 | # 20 | # ////////////////////////////////////////////////////////////////////////////// 21 | 22 | #TwinCAT files 23 | *.tpy 24 | *.tclrs 25 | *.compiled-library 26 | *.compileinfo 27 | _Boot/ 28 | _CompileInfo/ 29 | _Libraries/ 30 | 31 | #OS junk files 32 | [Tt]humbs.db 33 | *.DS_Store 34 | #Visual Studio files 35 | *.[Oo]bj 36 | *.user 37 | *.aps 38 | *.pch 39 | *.vspscc 40 | *.vssscc 41 | *_i.c 42 | *_p.c 43 | *.ncb 44 | *.suo 45 | *.tlb 46 | *.tlh 47 | *.bak 48 | *.[Cc]ache 49 | *.ilk 50 | *.log 51 | *.lib 52 | *.sbr 53 | *.sdf 54 | *.opensdf 55 | *.mdf 56 | *.ldf 57 | *.sln.~u 58 | *.~u 59 | obj/ 60 | [Bb]in 61 | [Dd]ebug*/ 62 | [Rr]elease*/ 63 | .vs/ 64 | 65 | #Tooling 66 | _ReSharper*/ 67 | *.resharper 68 | [Tt]est[Rr]esult* 69 | Packages*/ 70 | #Project files 71 | #[Bb]uild/ 72 | 73 | #Subversion files 74 | .svn 75 | 76 | # Office Temp Files 77 | ~$* 78 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysis/CodeAnalysis.plcproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 1.0.0.0 5 | 2.0 6 | {3bc44299-ecdb-4784-92d7-0a6ab1672292} 7 | True 8 | CodeAnalysis 9 | 3.1.4022.3 10 | {1196f0f6-df6b-4c37-a8a1-1013f67d21aa} 11 | {b5a45463-ca77-4963-902d-cbeb52fad414} 12 | {2af5fed3-5593-4fb9-8ca7-ea1714eaf366} 13 | {45520f4e-5206-4c91-ac4f-a4009471c2b0} 14 | {d98ebeef-8084-43d6-988c-5d190be97b15} 15 | {f02c88e9-8a8f-4535-b1ba-db7974159df5} 16 | 17 | 18 | 19 | Code 20 | 21 | 22 | Code 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Tc2_Standard, * (Beckhoff Automation GmbH) 34 | Tc2_Standard 35 | 36 | 37 | Tc2_System, * (Beckhoff Automation GmbH) 38 | Tc2_System 39 | 40 | 41 | Tc3_Module, * (Beckhoff Automation GmbH) 42 | Tc3_Module 43 | 44 | 45 | 46 | 47 | Content 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | "<ProjectRoot>" 56 | 57 | {192FAD59-8248-4824-A8DE-9177C94C195A} 58 | 59 | "{192FAD59-8248-4824-A8DE-9177C94C195A}" 60 | 61 | 62 | 63 | {29BD8D0C-3586-4548-BB48-497B9A01693F} 64 | 65 | "{29BD8D0C-3586-4548-BB48-497B9A01693F}" 66 | 67 | NamingConventions 68 | 69 | "NamingConventions" 70 | 71 | 105 72 | 73 | "105" 74 | 75 | 76 | stPrefix 77 | 78 | 79 | 80 | 8 81 | 82 | "8" 83 | 84 | 85 | stPrefix 86 | 87 | 88 | 89 | 9 90 | 91 | "9" 92 | 93 | 94 | stPrefix 95 | 96 | 97 | 98 | 3 99 | 100 | "3" 101 | 102 | 103 | stPrefix 104 | 105 | 106 | 107 | 4 108 | 109 | "4" 110 | 111 | 112 | stPrefix 113 | 114 | 115 | 116 | 5 117 | 118 | "5" 119 | 120 | 121 | stPrefix 122 | 123 | 124 | 125 | 6 126 | 127 | "6" 128 | 129 | 130 | stPrefix 131 | 132 | 133 | 134 | 7 135 | 136 | "7" 137 | 138 | 139 | stPrefix 140 | 141 | 142 | 143 | 29 144 | 145 | "29" 146 | 147 | 148 | stPrefix 149 | 150 | 151 | 152 | 59 153 | 154 | "59" 155 | 156 | 157 | stPrefix 158 | 159 | 160 | 161 | 107 162 | 163 | "107" 164 | 165 | 166 | stPrefix 167 | 168 | 169 | 170 | 22 171 | 172 | "22" 173 | 174 | 175 | stPrefix 176 | 177 | 178 | 179 | 30 180 | 181 | "30" 182 | 183 | 184 | stPrefix 185 | 186 | 187 | 188 | 25 189 | 190 | "25" 191 | 192 | 193 | stPrefix 194 | 195 | 196 | 197 | 35 198 | 199 | "35" 200 | 201 | 202 | stPrefix 203 | 204 | 205 | 206 | 62 207 | 208 | "62" 209 | 210 | 211 | stPrefix 212 | 213 | 214 | 215 | 55 216 | 217 | "55" 218 | 219 | 220 | stPrefix 221 | 222 | 223 | 224 | 65 225 | 226 | "65" 227 | 228 | 229 | stPrefix 230 | 231 | 232 | 233 | 108 234 | 235 | "108" 236 | 237 | 238 | stPrefix 239 | 240 | 241 | 242 | 70 243 | 244 | "70" 245 | 246 | 247 | stPrefix 248 | 249 | 250 | 251 | 34 252 | 253 | "34" 254 | 255 | 256 | stPrefix 257 | 258 | 259 | 260 | 54 261 | 262 | "54" 263 | 264 | 265 | stPrefix 266 | 267 | 268 | 269 | 121 270 | 271 | "121" 272 | 273 | 274 | stPrefix 275 | 276 | 277 | 278 | 151 279 | 280 | "151" 281 | 282 | 283 | stPrefix 284 | 285 | 286 | 287 | 10 288 | 289 | "10" 290 | 291 | 292 | stPrefix 293 | 294 | 295 | 296 | 102 297 | 298 | "102" 299 | 300 | 301 | stPrefix 302 | 303 | 304 | 305 | 18 306 | 307 | "18" 308 | 309 | 310 | stPrefix 311 | 312 | 313 | 314 | 28 315 | 316 | "28" 317 | 318 | 319 | stPrefix 320 | 321 | 322 | 323 | 123 324 | 325 | "123" 326 | 327 | 328 | stPrefix 329 | 330 | 331 | 332 | 58 333 | 334 | "58" 335 | 336 | 337 | stPrefix 338 | 339 | 340 | 341 | 61 342 | 343 | "61" 344 | 345 | 346 | stPrefix 347 | 348 | 349 | 350 | 11 351 | 352 | "11" 353 | 354 | 355 | stPrefix 356 | 357 | 358 | 359 | 21 360 | 361 | "21" 362 | 363 | 364 | stPrefix 365 | 366 | 367 | 368 | 14 369 | 370 | "14" 371 | 372 | 373 | stPrefix 374 | 375 | 376 | 377 | 24 378 | 379 | "24" 380 | 381 | 382 | stPrefix 383 | 384 | 385 | 386 | 17 387 | 388 | "17" 389 | 390 | 391 | stPrefix 392 | 393 | 394 | 395 | 27 396 | 397 | "27" 398 | 399 | 400 | stPrefix 401 | 402 | 403 | 404 | 37 405 | 406 | "37" 407 | 408 | 409 | stPrefix 410 | 411 | 412 | 413 | 53 414 | 415 | "53" 416 | 417 | 418 | stPrefix 419 | 420 | 421 | 422 | 57 423 | 424 | "57" 425 | 426 | 427 | stPrefix 428 | 429 | 430 | 431 | 73 432 | 433 | "73" 434 | 435 | 436 | stPrefix 437 | 438 | 439 | 440 | 122 441 | 442 | "122" 443 | 444 | 445 | stPrefix 446 | 447 | 448 | 449 | 104 450 | 451 | "104" 452 | 453 | 454 | stPrefix 455 | 456 | 457 | 458 | 153 459 | 460 | "153" 461 | 462 | 463 | stPrefix 464 | 465 | 466 | 467 | 12 468 | 469 | "12" 470 | 471 | 472 | stPrefix 473 | 474 | 475 | 476 | 106 477 | 478 | "106" 479 | 480 | 481 | stPrefix 482 | 483 | 484 | 485 | 32 486 | 487 | "32" 488 | 489 | 490 | stPrefix 491 | 492 | 493 | 494 | 19 495 | 496 | "19" 497 | 498 | 499 | stPrefix 500 | 501 | 502 | 503 | 103 504 | 505 | "103" 506 | 507 | 508 | stPrefix 509 | 510 | 511 | 512 | 33 513 | 514 | "33" 515 | 516 | 517 | stPrefix 518 | 519 | 520 | 521 | 72 522 | 523 | "72" 524 | 525 | 526 | stPrefix 527 | 528 | 529 | 530 | 152 531 | 532 | "152" 533 | 534 | 535 | stPrefix 536 | 537 | 538 | 539 | 64 540 | 541 | "64" 542 | 543 | 544 | stPrefix 545 | 546 | 547 | 548 | 20 549 | 550 | "20" 551 | 552 | 553 | stPrefix 554 | 555 | 556 | 557 | 13 558 | 559 | "13" 560 | 561 | 562 | stPrefix 563 | 564 | 565 | 566 | 23 567 | 568 | "23" 569 | 570 | 571 | stPrefix 572 | 573 | 574 | 575 | 16 576 | 577 | "16" 578 | 579 | 580 | stPrefix 581 | 582 | 583 | 584 | 26 585 | 586 | "26" 587 | 588 | 589 | stPrefix 590 | 591 | 592 | 593 | 36 594 | 595 | "36" 596 | 597 | 598 | stPrefix 599 | 600 | 601 | 602 | 63 603 | 604 | "63" 605 | 606 | 607 | stPrefix 608 | 609 | 610 | 611 | 56 612 | 613 | "56" 614 | 615 | 616 | stPrefix 617 | 618 | 619 | 620 | 124 621 | 622 | "124" 623 | 624 | 625 | stPrefix 626 | 627 | 628 | 629 | 154 630 | 631 | "154" 632 | 633 | 634 | stPrefix 635 | 636 | 637 | 638 | 31 639 | 640 | "31" 641 | 642 | 643 | stPrefix 644 | 645 | 646 | 647 | 51 648 | 649 | "51" 650 | 651 | 652 | stPrefix 653 | 654 | 655 | 656 | 15 657 | 658 | "15" 659 | 660 | 661 | stPrefix 662 | 663 | 664 | 665 | 38 666 | 667 | "38" 668 | 669 | 670 | stPrefix 671 | 672 | 673 | 674 | 71 675 | 676 | "71" 677 | 678 | 679 | stPrefix 680 | 681 | 682 | 683 | 684 | 685 | 686 | Metrics 687 | 688 | "Metrics" 689 | 690 | 9b526466-3bbe-40a9-b5a5-1cfadd791459 691 | 692 | "9b526466-3bbe-40a9-b5a5-1cfadd791459" 693 | 694 | 695 | stUpperLimit 696 | "" 697 | bActive 698 | true 699 | stLowerLimit 700 | "" 701 | 702 | 703 | e58378e8-a2fb-4a33-8013-8a91270388d0 704 | 705 | "e58378e8-a2fb-4a33-8013-8a91270388d0" 706 | 707 | 708 | stUpperLimit 709 | "" 710 | bActive 711 | true 712 | stLowerLimit 713 | "" 714 | 715 | 716 | 2ee16325-7a34-4109-82cd-e99144bdbf43 717 | 718 | "2ee16325-7a34-4109-82cd-e99144bdbf43" 719 | 720 | 721 | stUpperLimit 722 | "" 723 | bActive 724 | false 725 | stLowerLimit 726 | "" 727 | 728 | 729 | 2a5d0bd7-5767-43e1-92ab-90d924ade69e 730 | 731 | "2a5d0bd7-5767-43e1-92ab-90d924ade69e" 732 | 733 | 734 | stUpperLimit 735 | "" 736 | bActive 737 | false 738 | stLowerLimit 739 | "" 740 | 741 | 742 | ca51b834-cb16-4517-8b02-4807ce263107 743 | 744 | "ca51b834-cb16-4517-8b02-4807ce263107" 745 | 746 | 747 | stUpperLimit 748 | "" 749 | bActive 750 | false 751 | stLowerLimit 752 | "" 753 | 754 | 755 | aebdfc4d-fc4f-4fac-bf2e-22b603bc1880 756 | 757 | "aebdfc4d-fc4f-4fac-bf2e-22b603bc1880" 758 | 759 | 760 | stUpperLimit 761 | "" 762 | bActive 763 | false 764 | stLowerLimit 765 | "" 766 | 767 | 768 | bb1ff1d3-b0bc-4909-9034-11d7c6edb61f 769 | 770 | "bb1ff1d3-b0bc-4909-9034-11d7c6edb61f" 771 | 772 | 773 | stUpperLimit 774 | "" 775 | bActive 776 | false 777 | stLowerLimit 778 | "" 779 | 780 | 781 | 3fb5ac29-8ac7-4ca4-863e-49c3c89643b9 782 | 783 | "3fb5ac29-8ac7-4ca4-863e-49c3c89643b9" 784 | 785 | 786 | stUpperLimit 787 | "" 788 | bActive 789 | false 790 | stLowerLimit 791 | "" 792 | 793 | 794 | c4137578-73e0-4a9c-ad9c-7773a1cff401 795 | 796 | "c4137578-73e0-4a9c-ad9c-7773a1cff401" 797 | 798 | 799 | stUpperLimit 800 | "" 801 | bActive 802 | true 803 | stLowerLimit 804 | "" 805 | 806 | 807 | daa3e89b-a727-4bc9-bd38-29afc6024f90 808 | 809 | "daa3e89b-a727-4bc9-bd38-29afc6024f90" 810 | 811 | 812 | stUpperLimit 813 | "" 814 | bActive 815 | true 816 | stLowerLimit 817 | "" 818 | 819 | 820 | b42720b9-b152-4b52-ad89-630e0f5acab1 821 | 822 | "b42720b9-b152-4b52-ad89-630e0f5acab1" 823 | 824 | 825 | stUpperLimit 826 | "" 827 | bActive 828 | true 829 | stLowerLimit 830 | "" 831 | 832 | 833 | 0ade9a3b-311c-4293-bc26-bcf994cdbbdc 834 | 835 | "0ade9a3b-311c-4293-bc26-bcf994cdbbdc" 836 | 837 | 838 | stUpperLimit 839 | "" 840 | bActive 841 | true 842 | stLowerLimit 843 | "" 844 | 845 | 846 | 15c07c54-9586-460c-802f-b3b4a408e3c7 847 | 848 | "15c07c54-9586-460c-802f-b3b4a408e3c7" 849 | 850 | 851 | stUpperLimit 852 | "" 853 | bActive 854 | true 855 | stLowerLimit 856 | "" 857 | 858 | 859 | 19fab17a-876c-4a8d-9d74-3e5d92b63dc8 860 | 861 | "19fab17a-876c-4a8d-9d74-3e5d92b63dc8" 862 | 863 | 864 | stUpperLimit 865 | "" 866 | bActive 867 | true 868 | stLowerLimit 869 | "" 870 | 871 | 872 | 87b20586-90da-40d8-82ce-62a7dd0ba8af 873 | 874 | "87b20586-90da-40d8-82ce-62a7dd0ba8af" 875 | 876 | 877 | stUpperLimit 878 | "" 879 | bActive 880 | false 881 | stLowerLimit 882 | "" 883 | 884 | 885 | c20d083b-41ea-4867-b762-015491579932 886 | 887 | "c20d083b-41ea-4867-b762-015491579932" 888 | 889 | 890 | stUpperLimit 891 | "" 892 | bActive 893 | true 894 | stLowerLimit 895 | "" 896 | 897 | 898 | 827ae15d-4cb9-4177-b870-6bea1db8ee44 899 | 900 | "827ae15d-4cb9-4177-b870-6bea1db8ee44" 901 | 902 | 903 | stUpperLimit 904 | "" 905 | bActive 906 | true 907 | stLowerLimit 908 | "" 909 | 910 | 911 | 1a004255-b771-48b6-aa33-ea35ce4d37ea 912 | 913 | "1a004255-b771-48b6-aa33-ea35ce4d37ea" 914 | 915 | 916 | stUpperLimit 917 | "" 918 | bActive 919 | false 920 | stLowerLimit 921 | "" 922 | 923 | 924 | 8360c2b5-e762-4cc0-935b-fb129cda1b4a 925 | 926 | "8360c2b5-e762-4cc0-935b-fb129cda1b4a" 927 | 928 | 929 | stUpperLimit 930 | "" 931 | bActive 932 | false 933 | stLowerLimit 934 | "" 935 | 936 | 937 | 40f104a2-99f0-486d-9c44-47e8c759ca07 938 | 939 | "40f104a2-99f0-486d-9c44-47e8c759ca07" 940 | 941 | 942 | stUpperLimit 943 | "" 944 | bActive 945 | false 946 | stLowerLimit 947 | "" 948 | 949 | 950 | 62b98ef9-b4c6-4777-bc0a-29245bb8b9f3 951 | 952 | "62b98ef9-b4c6-4777-bc0a-29245bb8b9f3" 953 | 954 | 955 | stUpperLimit 956 | "" 957 | bActive 958 | true 959 | stLowerLimit 960 | "" 961 | 962 | 963 | 6c74d656-f35f-41b9-b449-eae882ed12fe 964 | 965 | "6c74d656-f35f-41b9-b449-eae882ed12fe" 966 | 967 | 968 | stUpperLimit 969 | "" 970 | bActive 971 | true 972 | stLowerLimit 973 | "" 974 | 975 | 976 | 0ba696f2-ce22-4330-931f-4ddd5c597896 977 | 978 | "0ba696f2-ce22-4330-931f-4ddd5c597896" 979 | 980 | 981 | stUpperLimit 982 | "" 983 | bActive 984 | true 985 | stLowerLimit 986 | "" 987 | 988 | 989 | 6549803a-9e82-4b28-aff1-2425cbec813b 990 | 991 | "6549803a-9e82-4b28-aff1-2425cbec813b" 992 | 993 | 994 | stUpperLimit 995 | "" 996 | bActive 997 | true 998 | stLowerLimit 999 | "" 1000 | 1001 | 1002 | 6cb1bfb1-4d4a-43ed-96f4-cd0254fc33b5 1003 | 1004 | "6cb1bfb1-4d4a-43ed-96f4-cd0254fc33b5" 1005 | 1006 | 1007 | stUpperLimit 1008 | "" 1009 | bActive 1010 | false 1011 | stLowerLimit 1012 | "" 1013 | 1014 | 1015 | f6dd9a78-1e71-4d9c-9e61-394eb38f3809 1016 | 1017 | "f6dd9a78-1e71-4d9c-9e61-394eb38f3809" 1018 | 1019 | 1020 | stUpperLimit 1021 | "" 1022 | bActive 1023 | true 1024 | stLowerLimit 1025 | "" 1026 | 1027 | 1028 | 571980c1-792d-4355-a9cb-4c3a8f254ab0 1029 | 1030 | "571980c1-792d-4355-a9cb-4c3a8f254ab0" 1031 | 1032 | 1033 | stUpperLimit 1034 | "" 1035 | bActive 1036 | false 1037 | stLowerLimit 1038 | "" 1039 | 1040 | 1041 | eb349b41-54d8-47ed-ab7d-b5dbbc17709f 1042 | 1043 | "eb349b41-54d8-47ed-ab7d-b5dbbc17709f" 1044 | 1045 | 1046 | stUpperLimit 1047 | "" 1048 | bActive 1049 | true 1050 | stLowerLimit 1051 | "" 1052 | 1053 | 1054 | 209f2982-bd60-4988-9cf9-9ff21cbf643f 1055 | 1056 | "209f2982-bd60-4988-9cf9-9ff21cbf643f" 1057 | 1058 | 1059 | stUpperLimit 1060 | "" 1061 | bActive 1062 | false 1063 | stLowerLimit 1064 | "" 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | Rules 1071 | 1072 | "Rules" 1073 | 1074 | 35 1075 | 1076 | "35" 1077 | 1078 | 1079 | bWarning 1080 | False 1081 | bActive 1082 | True 1083 | 1084 | 1085 | 105 1086 | 1087 | "105" 1088 | 1089 | 1090 | bWarning 1091 | False 1092 | bActive 1093 | False 1094 | 1095 | 1096 | 63 1097 | 1098 | "63" 1099 | 1100 | 1101 | bWarning 1102 | False 1103 | bActive 1104 | True 1105 | 1106 | 1107 | 8 1108 | 1109 | "8" 1110 | 1111 | 1112 | bWarning 1113 | False 1114 | bActive 1115 | True 1116 | 1117 | 1118 | 9 1119 | 1120 | "9" 1121 | 1122 | 1123 | bWarning 1124 | False 1125 | bActive 1126 | True 1127 | 1128 | 1129 | 47 1130 | 1131 | "47" 1132 | 1133 | 1134 | bWarning 1135 | False 1136 | bActive 1137 | True 1138 | 1139 | 1140 | 1 1141 | 1142 | "1" 1143 | 1144 | 1145 | bWarning 1146 | False 1147 | bActive 1148 | True 1149 | 1150 | 1151 | 2 1152 | 1153 | "2" 1154 | 1155 | 1156 | bWarning 1157 | False 1158 | bActive 1159 | True 1160 | 1161 | 1162 | 3 1163 | 1164 | "3" 1165 | 1166 | 1167 | bWarning 1168 | False 1169 | bActive 1170 | True 1171 | 1172 | 1173 | 4 1174 | 1175 | "4" 1176 | 1177 | 1178 | bWarning 1179 | False 1180 | bActive 1181 | True 1182 | 1183 | 1184 | 5 1185 | 1186 | "5" 1187 | 1188 | 1189 | bWarning 1190 | False 1191 | bActive 1192 | True 1193 | 1194 | 1195 | 6 1196 | 1197 | "6" 1198 | 1199 | 1200 | bWarning 1201 | False 1202 | bActive 1203 | True 1204 | 1205 | 1206 | 7 1207 | 1208 | "7" 1209 | 1210 | 1211 | bWarning 1212 | False 1213 | bActive 1214 | True 1215 | 1216 | 1217 | 29 1218 | 1219 | "29" 1220 | 1221 | 1222 | bWarning 1223 | False 1224 | bActive 1225 | True 1226 | 1227 | 1228 | 133 1229 | 1230 | "133" 1231 | 1232 | 1233 | bWarning 1234 | False 1235 | bActive 1236 | False 1237 | 1238 | 1239 | 163 1240 | 1241 | "163" 1242 | 1243 | 1244 | bWarning 1245 | False 1246 | bActive 1247 | False 1248 | 1249 | 1250 | 107 1251 | 1252 | "107" 1253 | 1254 | 1255 | bWarning 1256 | False 1257 | bActive 1258 | False 1259 | 1260 | 1261 | 22 1262 | 1263 | "22" 1264 | 1265 | 1266 | bWarning 1267 | False 1268 | bActive 1269 | True 1270 | 1271 | 1272 | 15 1273 | 1274 | "15" 1275 | 1276 | 1277 | bWarning 1278 | False 1279 | bActive 1280 | True 1281 | 1282 | 1283 | 25 1284 | 1285 | "25" 1286 | 1287 | 1288 | bWarning 1289 | False 1290 | bActive 1291 | True 1292 | 1293 | 1294 | 167 1295 | 1296 | "167" 1297 | 1298 | 1299 | bWarning 1300 | False 1301 | bActive 1302 | False 1303 | 1304 | 1305 | 62 1306 | 1307 | "62" 1308 | 1309 | 1310 | bWarning 1311 | False 1312 | bActive 1313 | True 1314 | 1315 | 1316 | 55 1317 | 1318 | "55" 1319 | 1320 | 1321 | bWarning 1322 | False 1323 | bActive 1324 | True 1325 | 1326 | 1327 | 65 1328 | 1329 | "65" 1330 | 1331 | 1332 | bWarning 1333 | False 1334 | bActive 1335 | True 1336 | 1337 | 1338 | 75 1339 | 1340 | "75" 1341 | 1342 | 1343 | bWarning 1344 | False 1345 | bActive 1346 | True 1347 | 1348 | 1349 | 140 1350 | 1351 | "140" 1352 | 1353 | 1354 | bWarning 1355 | False 1356 | bActive 1357 | True 1358 | 1359 | 1360 | 42 1361 | 1362 | "42" 1363 | 1364 | 1365 | bWarning 1366 | False 1367 | bActive 1368 | True 1369 | 1370 | 1371 | 150 1372 | 1373 | "150" 1374 | 1375 | 1376 | bWarning 1377 | False 1378 | bActive 1379 | False 1380 | 1381 | 1382 | 114 1383 | 1384 | "114" 1385 | 1386 | 1387 | bWarning 1388 | False 1389 | bActive 1390 | False 1391 | 1392 | 1393 | 34 1394 | 1395 | "34" 1396 | 1397 | 1398 | bWarning 1399 | False 1400 | bActive 1401 | True 1402 | 1403 | 1404 | 162 1405 | 1406 | "162" 1407 | 1408 | 1409 | bWarning 1410 | False 1411 | bActive 1412 | False 1413 | 1414 | 1415 | 26 1416 | 1417 | "26" 1418 | 1419 | 1420 | bWarning 1421 | False 1422 | bActive 1423 | True 1424 | 1425 | 1426 | 13 1427 | 1428 | "13" 1429 | 1430 | 1431 | bWarning 1432 | False 1433 | bActive 1434 | True 1435 | 1436 | 1437 | 54 1438 | 1439 | "54" 1440 | 1441 | 1442 | bWarning 1443 | False 1444 | bActive 1445 | True 1446 | 1447 | 1448 | 148 1449 | 1450 | "148" 1451 | 1452 | 1453 | bWarning 1454 | False 1455 | bActive 1456 | False 1457 | 1458 | 1459 | 121 1460 | 1461 | "121" 1462 | 1463 | 1464 | bWarning 1465 | False 1466 | bActive 1467 | False 1468 | 1469 | 1470 | 41 1471 | 1472 | "41" 1473 | 1474 | 1475 | bWarning 1476 | False 1477 | bActive 1478 | True 1479 | 1480 | 1481 | 125 1482 | 1483 | "125" 1484 | 1485 | 1486 | bWarning 1487 | False 1488 | bActive 1489 | False 1490 | 1491 | 1492 | 60 1493 | 1494 | "60" 1495 | 1496 | 1497 | bWarning 1498 | False 1499 | bActive 1500 | True 1501 | 1502 | 1503 | 72 1504 | 1505 | "72" 1506 | 1507 | 1508 | bWarning 1509 | False 1510 | bActive 1511 | True 1512 | 1513 | 1514 | 112 1515 | 1516 | "112" 1517 | 1518 | 1519 | bWarning 1520 | False 1521 | bActive 1522 | False 1523 | 1524 | 1525 | 81 1526 | 1527 | "81" 1528 | 1529 | 1530 | bWarning 1531 | False 1532 | bActive 1533 | True 1534 | 1535 | 1536 | 102 1537 | 1538 | "102" 1539 | 1540 | 1541 | bWarning 1542 | False 1543 | bActive 1544 | True 1545 | 1546 | 1547 | 18 1548 | 1549 | "18" 1550 | 1551 | 1552 | bWarning 1553 | False 1554 | bActive 1555 | True 1556 | 1557 | 1558 | 132 1559 | 1560 | "132" 1561 | 1562 | 1563 | bWarning 1564 | False 1565 | bActive 1566 | True 1567 | 1568 | 1569 | 123 1570 | 1571 | "123" 1572 | 1573 | 1574 | bWarning 1575 | False 1576 | bActive 1577 | False 1578 | 1579 | 1580 | 28 1581 | 1582 | "28" 1583 | 1584 | 1585 | bWarning 1586 | False 1587 | bActive 1588 | True 1589 | 1590 | 1591 | 58 1592 | 1593 | "58" 1594 | 1595 | 1596 | bWarning 1597 | False 1598 | bActive 1599 | True 1600 | 1601 | 1602 | 61 1603 | 1604 | "61" 1605 | 1606 | 1607 | bWarning 1608 | False 1609 | bActive 1610 | True 1611 | 1612 | 1613 | 78 1614 | 1615 | "78" 1616 | 1617 | 1618 | bWarning 1619 | False 1620 | bActive 1621 | True 1622 | 1623 | 1624 | 21 1625 | 1626 | "21" 1627 | 1628 | 1629 | bWarning 1630 | False 1631 | bActive 1632 | True 1633 | 1634 | 1635 | 14 1636 | 1637 | "14" 1638 | 1639 | 1640 | bWarning 1641 | False 1642 | bActive 1643 | True 1644 | 1645 | 1646 | 24 1647 | 1648 | "24" 1649 | 1650 | 1651 | bWarning 1652 | False 1653 | bActive 1654 | False 1655 | 1656 | 1657 | 17 1658 | 1659 | "17" 1660 | 1661 | 1662 | bWarning 1663 | False 1664 | bActive 1665 | True 1666 | 1667 | 1668 | 48 1669 | 1670 | "48" 1671 | 1672 | 1673 | bWarning 1674 | False 1675 | bActive 1676 | True 1677 | 1678 | 1679 | 37 1680 | 1681 | "37" 1682 | 1683 | 1684 | bWarning 1685 | False 1686 | bActive 1687 | True 1688 | 1689 | 1690 | 64 1691 | 1692 | "64" 1693 | 1694 | 1695 | bWarning 1696 | False 1697 | bActive 1698 | True 1699 | 1700 | 1701 | 57 1702 | 1703 | "57" 1704 | 1705 | 1706 | bWarning 1707 | False 1708 | bActive 1709 | True 1710 | 1711 | 1712 | 77 1713 | 1714 | "77" 1715 | 1716 | 1717 | bWarning 1718 | False 1719 | bActive 1720 | True 1721 | 1722 | 1723 | 100 1724 | 1725 | "100" 1726 | 1727 | 1728 | bWarning 1729 | false 1730 | nUpperLimit 1731 | 1024 1732 | bActive 1733 | true 1734 | 1735 | 1736 | 130 1737 | 1738 | "130" 1739 | 1740 | 1741 | bWarning 1742 | False 1743 | bActive 1744 | True 1745 | 1746 | 1747 | 160 1748 | 1749 | "160" 1750 | 1751 | 1752 | bWarning 1753 | False 1754 | bActive 1755 | True 1756 | 1757 | 1758 | 134 1759 | 1760 | "134" 1761 | 1762 | 1763 | bWarning 1764 | False 1765 | bActive 1766 | False 1767 | 1768 | 1769 | 164 1770 | 1771 | "164" 1772 | 1773 | 1774 | bWarning 1775 | False 1776 | bActive 1777 | False 1778 | 1779 | 1780 | 119 1781 | 1782 | "119" 1783 | 1784 | 1785 | bWarning 1786 | False 1787 | bActive 1788 | False 1789 | 1790 | 1791 | 20 1792 | 1793 | "20" 1794 | 1795 | 1796 | bWarning 1797 | False 1798 | bActive 1799 | True 1800 | 1801 | 1802 | 27 1803 | 1804 | "27" 1805 | 1806 | 1807 | bWarning 1808 | False 1809 | bActive 1810 | True 1811 | 1812 | 1813 | 111 1814 | 1815 | "111" 1816 | 1817 | 1818 | bWarning 1819 | False 1820 | bActive 1821 | False 1822 | 1823 | 1824 | 40 1825 | 1826 | "40" 1827 | 1828 | 1829 | bWarning 1830 | False 1831 | bActive 1832 | True 1833 | 1834 | 1835 | 12 1836 | 1837 | "12" 1838 | 1839 | 1840 | bWarning 1841 | False 1842 | bActive 1843 | True 1844 | 1845 | 1846 | 115 1847 | 1848 | "115" 1849 | 1850 | 1851 | bWarning 1852 | False 1853 | bActive 1854 | False 1855 | 1856 | 1857 | 106 1858 | 1859 | "106" 1860 | 1861 | 1862 | bWarning 1863 | False 1864 | bActive 1865 | False 1866 | 1867 | 1868 | 145 1869 | 1870 | "145" 1871 | 1872 | 1873 | bWarning 1874 | False 1875 | bActive 1876 | False 1877 | 1878 | 1879 | 19 1880 | 1881 | "19" 1882 | 1883 | 1884 | bWarning 1885 | False 1886 | bActive 1887 | True 1888 | 1889 | 1890 | 166 1891 | 1892 | "166" 1893 | 1894 | 1895 | MaxInOuts 1896 | 10 1897 | bActive 1898 | false 1899 | bWarning 1900 | false 1901 | MaxOutputs 1902 | 10 1903 | MaxInputs 1904 | 10 1905 | 1906 | 1907 | 56 1908 | 1909 | "56" 1910 | 1911 | 1912 | bWarning 1913 | False 1914 | bActive 1915 | True 1916 | 1917 | 1918 | 36 1919 | 1920 | "36" 1921 | 1922 | 1923 | bWarning 1924 | False 1925 | bActive 1926 | True 1927 | 1928 | 1929 | 52 1930 | 1931 | "52" 1932 | 1933 | 1934 | bWarning 1935 | False 1936 | bActive 1937 | True 1938 | 1939 | 1940 | 16 1941 | 1942 | "16" 1943 | 1944 | 1945 | bWarning 1946 | False 1947 | bActive 1948 | False 1949 | 1950 | 1951 | 39 1952 | 1953 | "39" 1954 | 1955 | 1956 | bWarning 1957 | False 1958 | bActive 1959 | True 1960 | 1961 | 1962 | 103 1963 | 1964 | "103" 1965 | 1966 | 1967 | bWarning 1968 | False 1969 | bActive 1970 | True 1971 | 1972 | 1973 | 80 1974 | 1975 | "80" 1976 | 1977 | 1978 | bWarning 1979 | False 1980 | bActive 1981 | True 1982 | 1983 | 1984 | 44 1985 | 1986 | "44" 1987 | 1988 | 1989 | bWarning 1990 | False 1991 | bActive 1992 | True 1993 | 1994 | 1995 | 122 1996 | 1997 | "122" 1998 | 1999 | 2000 | bWarning 2001 | False 2002 | bActive 2003 | False 2004 | 2005 | 2006 | 113 2007 | 2008 | "113" 2009 | 2010 | 2011 | bWarning 2012 | False 2013 | bActive 2014 | False 2015 | 2016 | 2017 | 59 2018 | 2019 | "59" 2020 | 2021 | 2022 | bWarning 2023 | False 2024 | bActive 2025 | True 2026 | 2027 | 2028 | 10 2029 | 2030 | "10" 2031 | 2032 | 2033 | bWarning 2034 | False 2035 | bActive 2036 | True 2037 | 2038 | 2039 | 95 2040 | 2041 | "95" 2042 | 2043 | 2044 | bWarning 2045 | False 2046 | bActive 2047 | True 2048 | 2049 | 2050 | 117 2051 | 2052 | "117" 2053 | 2054 | 2055 | bWarning 2056 | False 2057 | bActive 2058 | False 2059 | 2060 | 2061 | 23 2062 | 2063 | "23" 2064 | 2065 | 2066 | bWarning 2067 | False 2068 | bActive 2069 | True 2070 | 2071 | 2072 | 33 2073 | 2074 | "33" 2075 | 2076 | 2077 | bWarning 2078 | True 2079 | bActive 2080 | True 2081 | 2082 | 2083 | 43 2084 | 2085 | "43" 2086 | 2087 | 2088 | bWarning 2089 | False 2090 | bActive 2091 | True 2092 | 2093 | 2094 | 53 2095 | 2096 | "53" 2097 | 2098 | 2099 | bWarning 2100 | False 2101 | bActive 2102 | True 2103 | 2104 | 2105 | 46 2106 | 2107 | "46" 2108 | 2109 | 2110 | bWarning 2111 | False 2112 | bActive 2113 | True 2114 | 2115 | 2116 | 73 2117 | 2118 | "73" 2119 | 2120 | 2121 | bWarning 2122 | False 2123 | bActive 2124 | False 2125 | 2126 | 2127 | 66 2128 | 2129 | "66" 2130 | 2131 | 2132 | bWarning 2133 | False 2134 | bActive 2135 | True 2136 | 2137 | 2138 | 76 2139 | 2140 | "76" 2141 | 2142 | 2143 | bWarning 2144 | False 2145 | bActive 2146 | True 2147 | 2148 | 2149 | 32 2150 | 2151 | "32" 2152 | 2153 | 2154 | bWarning 2155 | False 2156 | bActive 2157 | True 2158 | 2159 | 2160 | 120 2161 | 2162 | "120" 2163 | 2164 | 2165 | bWarning 2166 | False 2167 | bActive 2168 | False 2169 | 2170 | 2171 | 11 2172 | 2173 | "11" 2174 | 2175 | 2176 | bWarning 2177 | False 2178 | bActive 2179 | True 2180 | 2181 | 2182 | 124 2183 | 2184 | "124" 2185 | 2186 | 2187 | bWarning 2188 | False 2189 | bActive 2190 | False 2191 | 2192 | 2193 | 147 2194 | 2195 | "147" 2196 | 2197 | 2198 | bWarning 2199 | False 2200 | bActive 2201 | False 2202 | 2203 | 2204 | 31 2205 | 2206 | "31" 2207 | 2208 | 2209 | bWarning 2210 | False 2211 | bActive 2212 | True 2213 | 2214 | 2215 | 90 2216 | 2217 | "90" 2218 | 2219 | 2220 | bWarning 2221 | False 2222 | bActive 2223 | True 2224 | 2225 | 2226 | 51 2227 | 2228 | "51" 2229 | 2230 | 2231 | bWarning 2232 | False 2233 | bActive 2234 | True 2235 | 2236 | 2237 | 38 2238 | 2239 | "38" 2240 | 2241 | 2242 | bWarning 2243 | False 2244 | bActive 2245 | True 2246 | 2247 | 2248 | 101 2249 | 2250 | "101" 2251 | 2252 | 2253 | MinChars 2254 | 5 2255 | bActive 2256 | false 2257 | MaxChars 2258 | 30 2259 | Exceptions 2260 | "" 2261 | bWarning 2262 | false 2263 | 2264 | 2265 | 118 2266 | 2267 | "118" 2268 | 2269 | 2270 | bWarning 2271 | False 2272 | bActive 2273 | False 2274 | 2275 | 2276 | 131 2277 | 2278 | "131" 2279 | 2280 | 2281 | bWarning 2282 | False 2283 | bActive 2284 | True 2285 | 2286 | 2287 | 161 2288 | 2289 | "161" 2290 | 2291 | 2292 | bWarning 2293 | False 2294 | bActive 2295 | True 2296 | 2297 | 2298 | 2299 | 2300 | 2301 | NamingConventionsSettings 2302 | 2303 | "NamingConventionsSettings" 2304 | 2305 | 2306 | FirstCharUpperCase 2307 | False 2308 | CombineScopeWithDatatypePrefix 2309 | True 2310 | CombinedDataTypesRecursive 2311 | True 2312 | 2313 | 2314 | 2315 | 2316 | SuppressedKeywords 2317 | "" 2318 | PerformStaticAnalyse 2319 | true 2320 | 2321 | 2322 | {8F99A816-E488-41E4-9FA3-846536012284} 2323 | 2324 | "{8F99A816-E488-41E4-9FA3-846536012284}" 2325 | 2326 | 2327 | 2328 | {40450F57-0AA3-4216-96F3-5444ECB29763} 2329 | 2330 | "{40450F57-0AA3-4216-96F3-5444ECB29763}" 2331 | 2332 | 2333 | ActiveVisuProfile 2334 | IR0whWr8bwfyBwAAHf+pawAAAABVAgAADnffSgAAAAABAAAAAAAAAAEaUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwACTHsAZgA5ADUAYgBiADQAMgA2AC0ANQA1ADIANAAtADQAYgA0ADUALQA5ADQAMAAwAC0AZgBiADAAZgAyAGUANwA3AGUANQAxAGIAfQADCE4AYQBtAGUABDJUAHcAaQBuAEMAQQBUACAAMwAuADEAIABCAHUAaQBsAGQAIAA0ADAAMgAyAC4AMQAwAAUWUAByAG8AZgBpAGwAZQBEAGEAdABhAAZMewAxADYAZQA1ADUAYgA2ADAALQA3ADAANAAzAC0ANABhADYAMwAtAGIANgA1AGIALQA2ADEANAA3ADEAMwA4ADcAOABkADQAMgB9AAcSTABpAGIAcgBhAHIAaQBlAHMACEx7ADMAYgBmAGQANQA0ADUAOQAtAGIAMAA3AGYALQA0AGQANgBlAC0AYQBlADEAYQAtAGEAOAAzADMANQA2AGEANQA1ADEANAAyAH0ACUx7ADkAYwA5ADUAOAA5ADYAOAAtADIAYwA4ADUALQA0ADEAYgBiAC0AOAA4ADcAMQAtADgAOQA1AGYAZgAxAGYAZQBkAGUAMQBhAH0ACg5WAGUAcgBzAGkAbwBuAAsGaQBuAHQADApVAHMAYQBnAGUADQpUAGkAdABsAGUADhpWAGkAcwB1AEUAbABlAG0ATQBlAHQAZQByAA8OQwBvAG0AcABhAG4AeQAQDFMAeQBzAHQAZQBtABESVgBpAHMAdQBFAGwAZQBtAHMAEjBWAGkAcwB1AEUAbABlAG0AcwBTAHAAZQBjAGkAYQBsAEMAbwBuAHQAcgBvAGwAcwATKFYAaQBzAHUARQBsAGUAbQBzAFcAaQBuAEMAbwBuAHQAcgBvAGwAcwAUJFYAaQBzAHUARQBsAGUAbQBUAGUAeAB0AEUAZABpAHQAbwByABUiVgBpAHMAdQBOAGEAdABpAHYAZQBDAG8AbgB0AHIAbwBsABYUdgBpAHMAdQBpAG4AcAB1AHQAcwAXDHMAeQBzAHQAZQBtABgYVgBpAHMAdQBFAGwAZQBtAEIAYQBzAGUAGSZEAGUAdgBQAGwAYQBjAGUAaABvAGwAZABlAHIAcwBVAHMAZQBkABoIYgBvAG8AbAAbIlAAbAB1AGcAaQBuAEMAbwBuAHMAdAByAGEAaQBuAHQAcwAcTHsANAAzAGQANQAyAGIAYwBlAC0AOQA0ADIAYwAtADQANABkADcALQA5AGUAOQA0AC0AMQBiAGYAZABmADMAMQAwAGUANgAzAGMAfQAdHEEAdABMAGUAYQBzAHQAVgBlAHIAcwBpAG8AbgAeFFAAbAB1AGcAaQBuAEcAdQBpAGQAHxZTAHkAcwB0AGUAbQAuAEcAdQBpAGQAIEhhAGYAYwBkADUANAA0ADYALQA0ADkAMQA0AC0ANABmAGUANwAtAGIAYgA3ADgALQA5AGIAZgBmAGUAYgA3ADAAZgBkADEANwAhFFUAcABkAGEAdABlAEkAbgBmAG8AIkx7AGIAMAAzADMANgA2AGEAOAAtAGIANQBjADAALQA0AGIAOQBhAC0AYQAwADAAZQAtAGUAYgA4ADYAMAAxADEAMQAwADQAYwAzAH0AIw5VAHAAZABhAHQAZQBzACRMewAxADgANgA4AGYAZgBjADkALQBlADQAZgBjAC0ANAA1ADMAMgAtAGEAYwAwADYALQAxAGUAMwA5AGIAYgA1ADUANwBiADYAOQB9ACVMewBhADUAYgBkADQAOABjADMALQAwAGQAMQA3AC0ANAAxAGIANQAtAGIAMQA2ADQALQA1AGYAYwA2AGEAZAAyAGIAOQA2AGIANwB9ACYWTwBiAGoAZQBjAHQAcwBUAHkAcABlACdUVQBwAGQAYQB0AGUATABhAG4AZwB1AGEAZwBlAE0AbwBkAGUAbABGAG8AcgBDAG8AbgB2AGUAcgB0AGkAYgBsAGUATABpAGIAcgBhAHIAaQBlAHMAKBBMAGkAYgBUAGkAdABsAGUAKRRMAGkAYgBDAG8AbQBwAGEAbgB5ACoeVQBwAGQAYQB0AGUAUAByAG8AdgBpAGQAZQByAHMAKzhTAHkAcwB0AGUAbQAuAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEgAYQBzAGgAdABhAGIAbABlACwSdgBpAHMAdQBlAGwAZQBtAHMALUg2AGMAYgAxAGMAZABlADEALQBkADUAZABjAC0ANABhADMAYgAtADkAMAA1ADQALQAyADEAZgBhADcANQA2AGEAMwBmAGEANAAuKEkAbgB0AGUAcgBmAGEAYwBlAFYAZQByAHMAaQBvAG4ASQBuAGYAbwAvTHsAYwA2ADEAMQBlADQAMAAwAC0ANwBmAGIAOQAtADQAYwAzADUALQBiADkAYQBjAC0ANABlADMAMQA0AGIANQA5ADkANgA0ADMAfQAwGE0AYQBqAG8AcgBWAGUAcgBzAGkAbwBuADEYTQBpAG4AbwByAFYAZQByAHMAaQBvAG4AMgxMAGUAZwBhAGMAeQAzMEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwAVgBlAHIAcwBpAG8AbgBJAG4AZgBvADQwTABvAGEAZABMAGkAYgByAGEAcgBpAGUAcwBJAG4AdABvAFAAcgBvAGoAZQBjAHQANRpDAG8AbQBwAGEAdABpAGIAaQBsAGkAdAB5ANAAAhoD0AMBLQTQBQYaB9AHCBoBRQcJCNAACRoERQoLBAMAAAAFAAAACgAAAAAAAADQDAutAgAAANANAS0O0A8BLRDQAAkaBEUKCwQDAAAABQAAAAoAAAAoAAAA0AwLrQEAAADQDQEtEdAPAS0Q0AAJGgRFCgsEAwAAAAUAAAAKAAAAAAAAANAMC60CAAAA0A0BLRLQDwEtENAACRoERQoLBAMAAAAFAAAACgAAACgAAADQDAutAgAAANANAS0T0A8BLRDQAAkaBEUKCwQDAAAABQAAAAoAAAAKAAAA0AwLrQIAAADQDQEtFNAPAS0Q0AAJGgRFCgsEAwAAAAUAAAAKAAAAKAAAANAMC60CAAAA0A0BLRXQDwEtENAACRoERQoLBAMAAAAFAAAACgAAAAAAAADQDAutAgAAANANAS0W0A8BLRfQAAkaBEUKCwQDAAAABQAAAAoAAAAoAAAA0AwLrQQAAADQDQEtGNAPAS0Q0BkarQFFGxwB0AAcGgJFHQsEAwAAAAUAAAAKAAAAAAAAANAeHy0g0CEiGgJFIyQC0AAlGgVFCgsEAwAAAAMAAAAAAAAACgAAANAmC60AAAAA0AMBLSfQKAEtEdApAS0Q0AAlGgVFCgsEAwAAAAMAAAAAAAAACgAAANAmC60BAAAA0AMBLSfQKAEtEdApAS0QmiorAUUAAQLQAAEtLNAAAS0X0AAfLS3QLi8aA9AwC60BAAAA0DELrRMAAADQMhqtANAzLxoD0DALrQIAAADQMQutAwAAANAyGq0A0DQarQDQNRqtAA== 2335 | 2336 | 2337 | 2338 | 2339 | 2340 | 2341 | 2342 | System.Boolean 2343 | System.Collections.Hashtable 2344 | System.Int32 2345 | {54dd0eac-a6d8-46f2-8c27-2f43c7e49861} 2346 | System.String 2347 | 2348 | 2349 | 2350 | 2351 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysis/CodeAnalysis.tmc: -------------------------------------------------------------------------------- 1 | VERSION64uiMajorUINT160uiMinorUINT1616uiServicePackUINT1632uiPatchUINT1648PlcAppSystemInfo2048ObjIdOTCID320TaskCntUDINT3232OnlineChangeCntUDINT3264FlagsDWORD3296AdsPortUINT16128BootDataLoadedBOOL8144OldBootDataBOOL8152AppTimestampDT32160KeepOutputsOnBPBOOL8192ShutdownInProgressBOOL8200LicensesPendingBOOL8208BSODOccuredBOOL8216LoggedInBOOL8224TComSrvPtrITComObjectServer32256TcComInterfaceAppNameSTRING(63)512512ProjectNameSTRING(63)5121024PlcTaskSystemInfo1024ObjIdOTCID320CycleTimeUDINT3232PriorityUINT1664AdsPortUINT1680CycleCountUDINT3296DcTaskTimeLINT64128LastExecTimeUDINT32192FirstCycleBOOL8224CycleTimeExceededBOOL8232InCallAfterOutputUpdateBOOL8240RTViolationBOOL8248TaskNameSTRING(63)512512_Implicit_KindOfTask16INT_implicit_cyclic0_implicit_event1_implicit_external2_implicit_freewheeling3_Implicit_Jitter_Distribution48wRangeMaxWORD160wCountJitterNegWORD1616wCountJitterPosWORD1632hide_Implicit_Task_Info896dwVersionDWORD320pszNameSTRING(80)6464nPriorityINT16128KindOf_Implicit_KindOfTask16144bWatchdogBOOL8160bProfilingTaskBOOL8168dwEventFunctionPointerBYTE64192pszExternalEventSTRING(80)64256dwTaskEntryFunctionPointerBYTE64320dwWatchdogSensitivityDWORD32384dwIntervalDWORD32416dwWatchdogTimeDWORD32448dwLastCycleTimeDWORD32480dwAverageCycleTimeDWORD32512dwMaxCycleTimeDWORD32544dwMinCycleTimeDWORD32576diJitterDINT32608diJitterMinDINT32640diJitterMaxDINT32672dwCycleCountDWORD32704wTaskStatusWORD16736wNumOfJitterDistributionsWORD16752pJitterDistribution_Implicit_Jitter_Distribution64768bWithinSPSTimeSlicingBOOL8832byDummyBYTE8840bShouldBlockBOOL8848bActiveBOOL8856dwIECCycleCountDWORD32864hideCodeAnalysis{08500001-0000-0000-F000-000000000064}0PlcTask#x020100303PlcTask Internal0851968MAIN.bJustASimpleBoolean8BOOL4096224Constants.bLittleEndian8BOOL1TcVarGlobal4096240Constants.bSimulationMode8BOOL0TcVarGlobal4096248MAIN.sThisStringIsTooLong648STRING(80)Hello world4102976Constants.bFPUSupport8BOOL1TcVarGlobal4103624Constants.nRegisterSize16WORD64TcVarGlobal4103632Constants.nPackMode16UINT8TcVarGlobal4103648MAIN.nCounter64ULINT4103680Constants.RuntimeVersion64VERSION.uiMajor3.uiMinor5.uiServicePack6.uiPatch0TcVarGlobal4103744Constants.CompilerVersion64VERSION.uiMajor3.uiMinor5.uiServicePack10.uiPatch100TcVarGlobal4103808Constants.RuntimeVersionNumeric32DWORD50660864TcVarGlobal4103872Constants.CompilerVersionNumeric32DWORD50661988TcVarGlobal4103904TwinCAT_SystemInfoVarList._AppInfo2048PlcAppSystemInfono_initTcVarGlobal4103936TwinCAT_SystemInfoVarList._TaskInfo1024PlcTaskSystemInfo11no_initTcVarGlobal4105984TwinCAT_SystemInfoVarList._TaskPouOid_PlcTask32OTCIDno_initTcVarGlobal4107008TwinCAT_SystemInfoVarList._TaskOid_PlcTask32OTCIDno_initTcVarGlobal4107040TwinCAT_SystemInfoVarList.__PlcTask896_Implicit_Task_Info.dwVersion2TcContextNamePlcTaskTcVarGlobal4107072ApplicationNamePort_851ChangeDate2018-10-02T11:27:52GeneratedCodeSize217088GlobalDataSize53248 -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysis/POUs/MAIN.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysis/PlcTask.TcTTO: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 10000 6 | 20 7 | 8 | MAIN 9 | 10 | {278c6dec-494b-4769-bc00-ca5c0e51d23d} 11 | {458b0fa3-3b15-49ce-b3db-ff7e6e94b5d2} 12 | {9aa9e2b1-4185-40b2-bdfa-b2ae467206e0} 13 | {4bbac938-0600-408d-a54f-13754ef756e4} 14 | {f53093e2-3364-477a-ad98-90eb48bbd4bc} 15 | 16 | 17 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysisDemoTcLibrary.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{B1E792BE-AA5F-4E3C-8C82-674BF9C0715B}") = "CodeAnalysisDemoTcLibrary", "CodeAnalysisDemoTcLibrary.tsproj", "{C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|TwinCAT CE7 (ARMV7) = Debug|TwinCAT CE7 (ARMV7) 11 | Debug|TwinCAT OS (ARMT2) = Debug|TwinCAT OS (ARMT2) 12 | Debug|TwinCAT RT (x64) = Debug|TwinCAT RT (x64) 13 | Debug|TwinCAT RT (x86) = Debug|TwinCAT RT (x86) 14 | Release|TwinCAT CE7 (ARMV7) = Release|TwinCAT CE7 (ARMV7) 15 | Release|TwinCAT OS (ARMT2) = Release|TwinCAT OS (ARMT2) 16 | Release|TwinCAT RT (x64) = Release|TwinCAT RT (x64) 17 | Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86) 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 21 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 22 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 23 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 24 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 25 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 26 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 27 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 28 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 29 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 30 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 31 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 32 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 33 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 34 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 35 | {C03F3E12-07D5-4CB8-BCFF-F194DAC17F2F}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 36 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 37 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 38 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 39 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 40 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 41 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 42 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 43 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 44 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 45 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 46 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 47 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 48 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 49 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 50 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 51 | {3BC44299-ECDB-4784-92D7-0A6AB1672292}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 52 | EndGlobalSection 53 | GlobalSection(SolutionProperties) = preSolution 54 | HideSolutionNode = FALSE 55 | EndGlobalSection 56 | EndGlobal 57 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/CodeAnalysisDemoTcLibrary.tsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PlcTask 8 | 9 | 10 | 11 | 12 | 13 | 14 | CodeAnalysis Instance 15 | {08500001-0000-0000-F000-000000000064} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /CodeAnalysisDemoTcLibrary/LaunchPLCStaticAnalysis.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The MIT License(MIT) 4 | 5 | rem Copyright(c) 2018 Jakob Sagatowski 6 | 7 | rem Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | rem this software and associated documentation files (the "Software"), to deal in 9 | rem the Software without restriction, including without limitation the rights to 10 | rem use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | rem the Software, and to permit persons to whom the Software is furnished to do so, 12 | rem subject to the following conditions: 13 | 14 | rem The above copyright notice and this permission notice shall be included in all 15 | rem copies or substantial portions of the Software. 16 | 17 | rem THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | rem IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | rem FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | rem COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | rem IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | rem CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | rem ----------------------------------------------------------------------------- 25 | 26 | rem This is a windows batch file used to execute the TwinCAT static code analysis 27 | rem loader program. This batch file can be used in conjunction with some automation 28 | rem server software that launches this file once the static code analysis needs 29 | rem to be done. 30 | 31 | rem USAGE: 32 | rem Set the below variable TC_STATIC_ANALYSIS_LOADER_PATH to the complete path of 33 | rem where the executable TcStaticAnalysisLoader.exe resides. 34 | 35 | SET TC_STATIC_ANALYSIS_LOADER_PATH=C:\Program Files (x86)\TcSAL\TcStaticAnalysisLoader.exe 36 | 37 | rem Find the visual studio solution file. 38 | 39 | FOR /r %%i IN (*.sln) DO ( 40 | SET VISUAL_STUDIO_SOLUTION_PATH="%%i" 41 | ) 42 | 43 | rem Find the TwinCAT solution file. 44 | 45 | FOR /r %%i IN (*.tsproj) DO ( 46 | SET TWINCAT_PROJECT_PATH="%%i" 47 | ) 48 | 49 | rem Error handling of finding the files. 50 | 51 | IF NOT DEFINED VISUAL_STUDIO_SOLUTION_PATH ( 52 | echo Visual studio solution file path does not exist! 53 | GOTO Exit 54 | ) ELSE ( 55 | echo VISUAL_STUDIO_SOLUTION_PATH found! 56 | echo The filepath to the visual studio solution file is: %VISUAL_STUDIO_SOLUTION_PATH% 57 | ) 58 | IF NOT DEFINED TWINCAT_PROJECT_PATH ( 59 | echo TwinCAT project file does not exist! 60 | GOTO Exit 61 | ) ELSE ( 62 | echo TWINCAT_PROJECT_PATH found! 63 | echo The filepath to the TwinCAT project file is: %TWINCAT_PROJECT_PATH% 64 | ) 65 | 66 | rem Run the TwinCAT automation interface application 67 | IF EXIST "%TC_STATIC_ANALYSIS_LOADER_PATH%" ( 68 | "%TC_STATIC_ANALYSIS_LOADER_PATH%" -v %VISUAL_STUDIO_SOLUTION_PATH% -t %TWINCAT_PROJECT_PATH% 69 | ) ELSE ( 70 | echo The configured search path for TcStaticAnalysisLoader does not exist! 71 | GOTO Exit 72 | ) 73 | 74 | rem %errorlevel% is a system wide environment variable that is set upon execution of a program 75 | echo Exit code is %errorlevel% 76 | 77 | EXIT /B %errorlevel% 78 | 79 | :Exit 80 | echo Failed! 81 | EXIT /B 1 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jakob Sagatowski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TcStaticCodeAnalysisLoader 2 | TwinCAT static code analysis script and program. 3 | 4 | Details about this project are available in a series of posts I've made about 5 | continous integration/continous delivery (CI/CD) with TwinCAT available at: 6 | - [Part one](http://alltwincat.com/2018/07/05/ci-cd-with-twincat-part-one/) 7 | - [Part two](http://alltwincat.com/2018/07/26/ci-cd-with-twincat-part-two/) 8 | - [Part three](http://alltwincat.com/2018/08/28/ci-cd-with-twincat-part-three/) 9 | - [Part four](http://alltwincat.com/2018/10/04/ci-cd-with-twincat-part-four/) 10 | 11 | It's strongly recommended to read these four documents to get an introduction 12 | and vital background information to this software. 13 | 14 | This repository includes the following content: 15 | 16 | ## [CodeAnalysisDemoTcLibrary](https://github.com/sagatowski/TcStaticAnalysisLoader/tree/master/CodeAnalysisDemoTcLibrary) 17 | A TwinCAT PLC project that is to be analysed for static code analysis. This also 18 | includes the windows batch-script to be executed by a Jenkins job when a GIT 19 | repository change has been detected in the TwinCAT PLC project. This BAT-script 20 | launches the TwinCAT static code analysis program described below (TcStaticAnalysisLoader). 21 | 22 | ## [TcStaticAnalysisLoader](https://github.com/sagatowski/TcStaticAnalysisLoader/tree/master/TcStaticAnalysisLoader) 23 | A C# .NET program that does the static code analysis using Beckhoffs TE1200 product 24 | and reports the result back to the caller as either ERROR, UNSTABLE or SUCCESSFUL 25 | which can be used for instance in a Jenkins build slave. The static code analysis is filtered 26 | out from the TwinCAT build procedure. This program is used together with the batch-script 27 | from the CodeAnalysisDemoTcLibrary folder. -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2035 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TcStaticAnalysisLoader", "TcStaticAnalysisLoader\TcStaticAnalysisLoader.csproj", "{DF5DE715-DE1D-4B91-8385-1471EDB37A92}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DF5DE715-DE1D-4B91-8385-1471EDB37A92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DF5DE715-DE1D-4B91-8385-1471EDB37A92}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DF5DE715-DE1D-4B91-8385-1471EDB37A92}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DF5DE715-DE1D-4B91-8385-1471EDB37A92}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {E5A40121-8564-461C-B5B7-BD9B21FEE2E2} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/Constants.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | 4 | Copyright(c) 2018 Jakob Sagatowski 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Linq; 27 | using System.Text; 28 | using System.Threading.Tasks; 29 | 30 | namespace AllTwinCAT.TcStaticAnalysisLoader 31 | { 32 | static class Constants 33 | { 34 | public const string MIN_TC_VERSION_FOR_SC_ANALYSIS = "3.1.4022.0"; 35 | public const int RETURN_SUCCESSFULL = 0; 36 | public const int RETURN_ERROR = 1; 37 | public const int RETURN_UNSTABLE = 2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/MessageFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Forms; 8 | 9 | namespace AllTwinCAT.TcStaticAnalysisLoader { 10 | public class MessageFilter : IOleMessageFilter { 11 | // Class containing the IOleMessageFilter 12 | // thread error-handling functions. 13 | 14 | // Start the filter. 15 | public static void Register() { 16 | IOleMessageFilter newFilter = new MessageFilter(); 17 | IOleMessageFilter oldFilter = null; 18 | CoRegisterMessageFilter(newFilter, out oldFilter); 19 | } 20 | 21 | // Done with the filter, close it. 22 | public static void Revoke() { 23 | IOleMessageFilter oldFilter = null; 24 | CoRegisterMessageFilter(null, out oldFilter); 25 | } 26 | 27 | // 28 | // IOleMessageFilter functions. 29 | // Handle incoming thread requests. 30 | int IOleMessageFilter.HandleInComingCall(int dwCallType, 31 | System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 32 | lpInterfaceInfo) { 33 | //Return the flag SERVERCALL_ISHANDLED. 34 | return 0; 35 | } 36 | 37 | // Thread call was rejected, so try again. 38 | int IOleMessageFilter.RetryRejectedCall(System.IntPtr 39 | hTaskCallee, int dwTickCount, int dwRejectType) { 40 | if (dwRejectType == 2) 41 | // flag = SERVERCALL_RETRYLATER. 42 | { 43 | // Retry the thread call immediately if return >=0 & 44 | // <100. 45 | return 99; 46 | } 47 | // Too busy; cancel call. 48 | return -1; 49 | } 50 | 51 | int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 52 | int dwTickCount, int dwPendingType) { 53 | //Return the flag PENDINGMSG_WAITDEFPROCESS. 54 | return 2; 55 | } 56 | 57 | // Implement the IOleMessageFilter interface. 58 | [DllImport("Ole32.dll")] 59 | private static extern int 60 | CoRegisterMessageFilter(IOleMessageFilter newFilter, out 61 | IOleMessageFilter oldFilter); 62 | } 63 | 64 | [System.Runtime.InteropServices.ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 65 | InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 66 | interface IOleMessageFilter { 67 | [PreserveSig] 68 | int HandleInComingCall( 69 | int dwCallType, 70 | IntPtr hTaskCaller, 71 | int dwTickCount, 72 | IntPtr lpInterfaceInfo); 73 | 74 | [PreserveSig] 75 | int RetryRejectedCall( 76 | IntPtr hTaskCallee, 77 | int dwTickCount, 78 | int dwRejectType); 79 | 80 | [PreserveSig] 81 | int MessagePending( 82 | IntPtr hTaskCallee, 83 | int dwTickCount, 84 | int dwPendingType); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/Options.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Options.cs 3 | // 4 | // Authors: 5 | // Jonathan Pryor 6 | // 7 | // Copyright (C) 2008 Novell (http://www.novell.com) 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | // Compile With: 30 | // gmcs -debug+ -r:System.Core Options.cs -o:NDesk.Options.dll 31 | // gmcs -debug+ -d:LINQ -r:System.Core Options.cs -o:NDesk.Options.dll 32 | // 33 | // The LINQ version just changes the implementation of 34 | // OptionSet.Parse(IEnumerable), and confers no semantic changes. 35 | 36 | // 37 | // A Getopt::Long-inspired option parsing library for C#. 38 | // 39 | // NDesk.Options.OptionSet is built upon a key/value table, where the 40 | // key is a option format string and the value is a delegate that is 41 | // invoked when the format string is matched. 42 | // 43 | // Option format strings: 44 | // Regex-like BNF Grammar: 45 | // name: .+ 46 | // type: [=:] 47 | // sep: ( [^{}]+ | '{' .+ '}' )? 48 | // aliases: ( name type sep ) ( '|' name type sep )* 49 | // 50 | // Each '|'-delimited name is an alias for the associated action. If the 51 | // format string ends in a '=', it has a required value. If the format 52 | // string ends in a ':', it has an optional value. If neither '=' or ':' 53 | // is present, no value is supported. `=' or `:' need only be defined on one 54 | // alias, but if they are provided on more than one they must be consistent. 55 | // 56 | // Each alias portion may also end with a "key/value separator", which is used 57 | // to split option values if the option accepts > 1 value. If not specified, 58 | // it defaults to '=' and ':'. If specified, it can be any character except 59 | // '{' and '}' OR the *string* between '{' and '}'. If no separator should be 60 | // used (i.e. the separate values should be distinct arguments), then "{}" 61 | // should be used as the separator. 62 | // 63 | // Options are extracted either from the current option by looking for 64 | // the option name followed by an '=' or ':', or is taken from the 65 | // following option IFF: 66 | // - The current option does not contain a '=' or a ':' 67 | // - The current option requires a value (i.e. not a Option type of ':') 68 | // 69 | // The `name' used in the option format string does NOT include any leading 70 | // option indicator, such as '-', '--', or '/'. All three of these are 71 | // permitted/required on any named option. 72 | // 73 | // Option bundling is permitted so long as: 74 | // - '-' is used to start the option group 75 | // - all of the bundled options are a single character 76 | // - at most one of the bundled options accepts a value, and the value 77 | // provided starts from the next character to the end of the string. 78 | // 79 | // This allows specifying '-a -b -c' as '-abc', and specifying '-D name=value' 80 | // as '-Dname=value'. 81 | // 82 | // Option processing is disabled by specifying "--". All options after "--" 83 | // are returned by OptionSet.Parse() unchanged and unprocessed. 84 | // 85 | // Unprocessed options are returned from OptionSet.Parse(). 86 | // 87 | // Examples: 88 | // int verbose = 0; 89 | // OptionSet p = new OptionSet () 90 | // .Add ("v", v => ++verbose) 91 | // .Add ("name=|value=", v => Console.WriteLine (v)); 92 | // p.Parse (new string[]{"-v", "--v", "/v", "-name=A", "/name", "B", "extra"}); 93 | // 94 | // The above would parse the argument string array, and would invoke the 95 | // lambda expression three times, setting `verbose' to 3 when complete. 96 | // It would also print out "A" and "B" to standard output. 97 | // The returned array would contain the string "extra". 98 | // 99 | // C# 3.0 collection initializers are supported and encouraged: 100 | // var p = new OptionSet () { 101 | // { "h|?|help", v => ShowHelp () }, 102 | // }; 103 | // 104 | // System.ComponentModel.TypeConverter is also supported, allowing the use of 105 | // custom data types in the callback type; TypeConverter.ConvertFromString() 106 | // is used to convert the value option to an instance of the specified 107 | // type: 108 | // 109 | // var p = new OptionSet () { 110 | // { "foo=", (Foo f) => Console.WriteLine (f.ToString ()) }, 111 | // }; 112 | // 113 | // Random other tidbits: 114 | // - Boolean options (those w/o '=' or ':' in the option format string) 115 | // are explicitly enabled if they are followed with '+', and explicitly 116 | // disabled if they are followed with '-': 117 | // string a = null; 118 | // var p = new OptionSet () { 119 | // { "a", s => a = s }, 120 | // }; 121 | // p.Parse (new string[]{"-a"}); // sets v != null 122 | // p.Parse (new string[]{"-a+"}); // sets v != null 123 | // p.Parse (new string[]{"-a-"}); // sets v == null 124 | // 125 | 126 | using System; 127 | using System.Collections; 128 | using System.Collections.Generic; 129 | using System.Collections.ObjectModel; 130 | using System.ComponentModel; 131 | using System.Globalization; 132 | using System.IO; 133 | using System.Runtime.Serialization; 134 | using System.Security.Permissions; 135 | using System.Text; 136 | using System.Text.RegularExpressions; 137 | 138 | #if LINQ 139 | using System.Linq; 140 | #endif 141 | 142 | #if TEST 143 | using NDesk.Options; 144 | #endif 145 | 146 | namespace NDesk.Options { 147 | 148 | public class OptionValueCollection : IList, IList { 149 | 150 | List values = new List (); 151 | OptionContext c; 152 | 153 | internal OptionValueCollection (OptionContext c) 154 | { 155 | this.c = c; 156 | } 157 | 158 | #region ICollection 159 | void ICollection.CopyTo (Array array, int index) {(values as ICollection).CopyTo (array, index);} 160 | bool ICollection.IsSynchronized {get {return (values as ICollection).IsSynchronized;}} 161 | object ICollection.SyncRoot {get {return (values as ICollection).SyncRoot;}} 162 | #endregion 163 | 164 | #region ICollection 165 | public void Add (string item) {values.Add (item);} 166 | public void Clear () {values.Clear ();} 167 | public bool Contains (string item) {return values.Contains (item);} 168 | public void CopyTo (string[] array, int arrayIndex) {values.CopyTo (array, arrayIndex);} 169 | public bool Remove (string item) {return values.Remove (item);} 170 | public int Count {get {return values.Count;}} 171 | public bool IsReadOnly {get {return false;}} 172 | #endregion 173 | 174 | #region IEnumerable 175 | IEnumerator IEnumerable.GetEnumerator () {return values.GetEnumerator ();} 176 | #endregion 177 | 178 | #region IEnumerable 179 | public IEnumerator GetEnumerator () {return values.GetEnumerator ();} 180 | #endregion 181 | 182 | #region IList 183 | int IList.Add (object value) {return (values as IList).Add (value);} 184 | bool IList.Contains (object value) {return (values as IList).Contains (value);} 185 | int IList.IndexOf (object value) {return (values as IList).IndexOf (value);} 186 | void IList.Insert (int index, object value) {(values as IList).Insert (index, value);} 187 | void IList.Remove (object value) {(values as IList).Remove (value);} 188 | void IList.RemoveAt (int index) {(values as IList).RemoveAt (index);} 189 | bool IList.IsFixedSize {get {return false;}} 190 | object IList.this [int index] {get {return this [index];} set {(values as IList)[index] = value;}} 191 | #endregion 192 | 193 | #region IList 194 | public int IndexOf (string item) {return values.IndexOf (item);} 195 | public void Insert (int index, string item) {values.Insert (index, item);} 196 | public void RemoveAt (int index) {values.RemoveAt (index);} 197 | 198 | private void AssertValid (int index) 199 | { 200 | if (c.Option == null) 201 | throw new InvalidOperationException ("OptionContext.Option is null."); 202 | if (index >= c.Option.MaxValueCount) 203 | throw new ArgumentOutOfRangeException ("index"); 204 | if (c.Option.OptionValueType == OptionValueType.Required && 205 | index >= values.Count) 206 | throw new OptionException (string.Format ( 207 | c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName), 208 | c.OptionName); 209 | } 210 | 211 | public string this [int index] { 212 | get { 213 | AssertValid (index); 214 | return index >= values.Count ? null : values [index]; 215 | } 216 | set { 217 | values [index] = value; 218 | } 219 | } 220 | #endregion 221 | 222 | public List ToList () 223 | { 224 | return new List (values); 225 | } 226 | 227 | public string[] ToArray () 228 | { 229 | return values.ToArray (); 230 | } 231 | 232 | public override string ToString () 233 | { 234 | return string.Join (", ", values.ToArray ()); 235 | } 236 | } 237 | 238 | public class OptionContext { 239 | private Option option; 240 | private string name; 241 | private int index; 242 | private OptionSet set; 243 | private OptionValueCollection c; 244 | 245 | public OptionContext (OptionSet set) 246 | { 247 | this.set = set; 248 | this.c = new OptionValueCollection (this); 249 | } 250 | 251 | public Option Option { 252 | get {return option;} 253 | set {option = value;} 254 | } 255 | 256 | public string OptionName { 257 | get {return name;} 258 | set {name = value;} 259 | } 260 | 261 | public int OptionIndex { 262 | get {return index;} 263 | set {index = value;} 264 | } 265 | 266 | public OptionSet OptionSet { 267 | get {return set;} 268 | } 269 | 270 | public OptionValueCollection OptionValues { 271 | get {return c;} 272 | } 273 | } 274 | 275 | public enum OptionValueType { 276 | None, 277 | Optional, 278 | Required, 279 | } 280 | 281 | public abstract class Option { 282 | string prototype, description; 283 | string[] names; 284 | OptionValueType type; 285 | int count; 286 | string[] separators; 287 | 288 | protected Option (string prototype, string description) 289 | : this (prototype, description, 1) 290 | { 291 | } 292 | 293 | protected Option (string prototype, string description, int maxValueCount) 294 | { 295 | if (prototype == null) 296 | throw new ArgumentNullException ("prototype"); 297 | if (prototype.Length == 0) 298 | throw new ArgumentException ("Cannot be the empty string.", "prototype"); 299 | if (maxValueCount < 0) 300 | throw new ArgumentOutOfRangeException ("maxValueCount"); 301 | 302 | this.prototype = prototype; 303 | this.names = prototype.Split ('|'); 304 | this.description = description; 305 | this.count = maxValueCount; 306 | this.type = ParsePrototype (); 307 | 308 | if (this.count == 0 && type != OptionValueType.None) 309 | throw new ArgumentException ( 310 | "Cannot provide maxValueCount of 0 for OptionValueType.Required or " + 311 | "OptionValueType.Optional.", 312 | "maxValueCount"); 313 | if (this.type == OptionValueType.None && maxValueCount > 1) 314 | throw new ArgumentException ( 315 | string.Format ("Cannot provide maxValueCount of {0} for OptionValueType.None.", maxValueCount), 316 | "maxValueCount"); 317 | if (Array.IndexOf (names, "<>") >= 0 && 318 | ((names.Length == 1 && this.type != OptionValueType.None) || 319 | (names.Length > 1 && this.MaxValueCount > 1))) 320 | throw new ArgumentException ( 321 | "The default option handler '<>' cannot require values.", 322 | "prototype"); 323 | } 324 | 325 | public string Prototype {get {return prototype;}} 326 | public string Description {get {return description;}} 327 | public OptionValueType OptionValueType {get {return type;}} 328 | public int MaxValueCount {get {return count;}} 329 | 330 | public string[] GetNames () 331 | { 332 | return (string[]) names.Clone (); 333 | } 334 | 335 | public string[] GetValueSeparators () 336 | { 337 | if (separators == null) 338 | return new string [0]; 339 | return (string[]) separators.Clone (); 340 | } 341 | 342 | protected static T Parse (string value, OptionContext c) 343 | { 344 | TypeConverter conv = TypeDescriptor.GetConverter (typeof (T)); 345 | T t = default (T); 346 | try { 347 | if (value != null) 348 | t = (T) conv.ConvertFromString (value); 349 | } 350 | catch (Exception e) { 351 | throw new OptionException ( 352 | string.Format ( 353 | c.OptionSet.MessageLocalizer ("Could not convert string `{0}' to type {1} for option `{2}'."), 354 | value, typeof (T).Name, c.OptionName), 355 | c.OptionName, e); 356 | } 357 | return t; 358 | } 359 | 360 | internal string[] Names {get {return names;}} 361 | internal string[] ValueSeparators {get {return separators;}} 362 | 363 | static readonly char[] NameTerminator = new char[]{'=', ':'}; 364 | 365 | private OptionValueType ParsePrototype () 366 | { 367 | char type = '\0'; 368 | List seps = new List (); 369 | for (int i = 0; i < names.Length; ++i) { 370 | string name = names [i]; 371 | if (name.Length == 0) 372 | throw new ArgumentException ("Empty option names are not supported.", "prototype"); 373 | 374 | int end = name.IndexOfAny (NameTerminator); 375 | if (end == -1) 376 | continue; 377 | names [i] = name.Substring (0, end); 378 | if (type == '\0' || type == name [end]) 379 | type = name [end]; 380 | else 381 | throw new ArgumentException ( 382 | string.Format ("Conflicting option types: '{0}' vs. '{1}'.", type, name [end]), 383 | "prototype"); 384 | AddSeparators (name, end, seps); 385 | } 386 | 387 | if (type == '\0') 388 | return OptionValueType.None; 389 | 390 | if (count <= 1 && seps.Count != 0) 391 | throw new ArgumentException ( 392 | string.Format ("Cannot provide key/value separators for Options taking {0} value(s).", count), 393 | "prototype"); 394 | if (count > 1) { 395 | if (seps.Count == 0) 396 | this.separators = new string[]{":", "="}; 397 | else if (seps.Count == 1 && seps [0].Length == 0) 398 | this.separators = null; 399 | else 400 | this.separators = seps.ToArray (); 401 | } 402 | 403 | return type == '=' ? OptionValueType.Required : OptionValueType.Optional; 404 | } 405 | 406 | private static void AddSeparators (string name, int end, ICollection seps) 407 | { 408 | int start = -1; 409 | for (int i = end+1; i < name.Length; ++i) { 410 | switch (name [i]) { 411 | case '{': 412 | if (start != -1) 413 | throw new ArgumentException ( 414 | string.Format ("Ill-formed name/value separator found in \"{0}\".", name), 415 | "prototype"); 416 | start = i+1; 417 | break; 418 | case '}': 419 | if (start == -1) 420 | throw new ArgumentException ( 421 | string.Format ("Ill-formed name/value separator found in \"{0}\".", name), 422 | "prototype"); 423 | seps.Add (name.Substring (start, i-start)); 424 | start = -1; 425 | break; 426 | default: 427 | if (start == -1) 428 | seps.Add (name [i].ToString ()); 429 | break; 430 | } 431 | } 432 | if (start != -1) 433 | throw new ArgumentException ( 434 | string.Format ("Ill-formed name/value separator found in \"{0}\".", name), 435 | "prototype"); 436 | } 437 | 438 | public void Invoke (OptionContext c) 439 | { 440 | OnParseComplete (c); 441 | c.OptionName = null; 442 | c.Option = null; 443 | c.OptionValues.Clear (); 444 | } 445 | 446 | protected abstract void OnParseComplete (OptionContext c); 447 | 448 | public override string ToString () 449 | { 450 | return Prototype; 451 | } 452 | } 453 | 454 | [Serializable] 455 | public class OptionException : Exception { 456 | private string option; 457 | 458 | public OptionException () 459 | { 460 | } 461 | 462 | public OptionException (string message, string optionName) 463 | : base (message) 464 | { 465 | this.option = optionName; 466 | } 467 | 468 | public OptionException (string message, string optionName, Exception innerException) 469 | : base (message, innerException) 470 | { 471 | this.option = optionName; 472 | } 473 | 474 | protected OptionException (SerializationInfo info, StreamingContext context) 475 | : base (info, context) 476 | { 477 | this.option = info.GetString ("OptionName"); 478 | } 479 | 480 | public string OptionName { 481 | get {return this.option;} 482 | } 483 | 484 | [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)] 485 | public override void GetObjectData (SerializationInfo info, StreamingContext context) 486 | { 487 | base.GetObjectData (info, context); 488 | info.AddValue ("OptionName", option); 489 | } 490 | } 491 | 492 | public delegate void OptionAction (TKey key, TValue value); 493 | 494 | public class OptionSet : KeyedCollection 495 | { 496 | public OptionSet () 497 | : this (delegate (string f) {return f;}) 498 | { 499 | } 500 | 501 | public OptionSet (Converter localizer) 502 | { 503 | this.localizer = localizer; 504 | } 505 | 506 | Converter localizer; 507 | 508 | public Converter MessageLocalizer { 509 | get {return localizer;} 510 | } 511 | 512 | protected override string GetKeyForItem (Option item) 513 | { 514 | if (item == null) 515 | throw new ArgumentNullException ("option"); 516 | if (item.Names != null && item.Names.Length > 0) 517 | return item.Names [0]; 518 | // This should never happen, as it's invalid for Option to be 519 | // constructed w/o any names. 520 | throw new InvalidOperationException ("Option has no names!"); 521 | } 522 | 523 | [Obsolete ("Use KeyedCollection.this[string]")] 524 | protected Option GetOptionForName (string option) 525 | { 526 | if (option == null) 527 | throw new ArgumentNullException ("option"); 528 | try { 529 | return base [option]; 530 | } 531 | catch (KeyNotFoundException) { 532 | return null; 533 | } 534 | } 535 | 536 | protected override void InsertItem (int index, Option item) 537 | { 538 | base.InsertItem (index, item); 539 | AddImpl (item); 540 | } 541 | 542 | protected override void RemoveItem (int index) 543 | { 544 | base.RemoveItem (index); 545 | Option p = Items [index]; 546 | // KeyedCollection.RemoveItem() handles the 0th item 547 | for (int i = 1; i < p.Names.Length; ++i) { 548 | Dictionary.Remove (p.Names [i]); 549 | } 550 | } 551 | 552 | protected override void SetItem (int index, Option item) 553 | { 554 | base.SetItem (index, item); 555 | RemoveItem (index); 556 | AddImpl (item); 557 | } 558 | 559 | private void AddImpl (Option option) 560 | { 561 | if (option == null) 562 | throw new ArgumentNullException ("option"); 563 | List added = new List (option.Names.Length); 564 | try { 565 | // KeyedCollection.InsertItem/SetItem handle the 0th name. 566 | for (int i = 1; i < option.Names.Length; ++i) { 567 | Dictionary.Add (option.Names [i], option); 568 | added.Add (option.Names [i]); 569 | } 570 | } 571 | catch (Exception) { 572 | foreach (string name in added) 573 | Dictionary.Remove (name); 574 | throw; 575 | } 576 | } 577 | 578 | public new OptionSet Add (Option option) 579 | { 580 | base.Add (option); 581 | return this; 582 | } 583 | 584 | sealed class ActionOption : Option { 585 | Action action; 586 | 587 | public ActionOption (string prototype, string description, int count, Action action) 588 | : base (prototype, description, count) 589 | { 590 | if (action == null) 591 | throw new ArgumentNullException ("action"); 592 | this.action = action; 593 | } 594 | 595 | protected override void OnParseComplete (OptionContext c) 596 | { 597 | action (c.OptionValues); 598 | } 599 | } 600 | 601 | public OptionSet Add (string prototype, Action action) 602 | { 603 | return Add (prototype, null, action); 604 | } 605 | 606 | public OptionSet Add (string prototype, string description, Action action) 607 | { 608 | if (action == null) 609 | throw new ArgumentNullException ("action"); 610 | Option p = new ActionOption (prototype, description, 1, 611 | delegate (OptionValueCollection v) { action (v [0]); }); 612 | base.Add (p); 613 | return this; 614 | } 615 | 616 | public OptionSet Add (string prototype, OptionAction action) 617 | { 618 | return Add (prototype, null, action); 619 | } 620 | 621 | public OptionSet Add (string prototype, string description, OptionAction action) 622 | { 623 | if (action == null) 624 | throw new ArgumentNullException ("action"); 625 | Option p = new ActionOption (prototype, description, 2, 626 | delegate (OptionValueCollection v) {action (v [0], v [1]);}); 627 | base.Add (p); 628 | return this; 629 | } 630 | 631 | sealed class ActionOption : Option { 632 | Action action; 633 | 634 | public ActionOption (string prototype, string description, Action action) 635 | : base (prototype, description, 1) 636 | { 637 | if (action == null) 638 | throw new ArgumentNullException ("action"); 639 | this.action = action; 640 | } 641 | 642 | protected override void OnParseComplete (OptionContext c) 643 | { 644 | action (Parse (c.OptionValues [0], c)); 645 | } 646 | } 647 | 648 | sealed class ActionOption : Option { 649 | OptionAction action; 650 | 651 | public ActionOption (string prototype, string description, OptionAction action) 652 | : base (prototype, description, 2) 653 | { 654 | if (action == null) 655 | throw new ArgumentNullException ("action"); 656 | this.action = action; 657 | } 658 | 659 | protected override void OnParseComplete (OptionContext c) 660 | { 661 | action ( 662 | Parse (c.OptionValues [0], c), 663 | Parse (c.OptionValues [1], c)); 664 | } 665 | } 666 | 667 | public OptionSet Add (string prototype, Action action) 668 | { 669 | return Add (prototype, null, action); 670 | } 671 | 672 | public OptionSet Add (string prototype, string description, Action action) 673 | { 674 | return Add (new ActionOption (prototype, description, action)); 675 | } 676 | 677 | public OptionSet Add (string prototype, OptionAction action) 678 | { 679 | return Add (prototype, null, action); 680 | } 681 | 682 | public OptionSet Add (string prototype, string description, OptionAction action) 683 | { 684 | return Add (new ActionOption (prototype, description, action)); 685 | } 686 | 687 | protected virtual OptionContext CreateOptionContext () 688 | { 689 | return new OptionContext (this); 690 | } 691 | 692 | #if LINQ 693 | public List Parse (IEnumerable arguments) 694 | { 695 | bool process = true; 696 | OptionContext c = CreateOptionContext (); 697 | c.OptionIndex = -1; 698 | var def = GetOptionForName ("<>"); 699 | var unprocessed = 700 | from argument in arguments 701 | where ++c.OptionIndex >= 0 && (process || def != null) 702 | ? process 703 | ? argument == "--" 704 | ? (process = false) 705 | : !Parse (argument, c) 706 | ? def != null 707 | ? Unprocessed (null, def, c, argument) 708 | : true 709 | : false 710 | : def != null 711 | ? Unprocessed (null, def, c, argument) 712 | : true 713 | : true 714 | select argument; 715 | List r = unprocessed.ToList (); 716 | if (c.Option != null) 717 | c.Option.Invoke (c); 718 | return r; 719 | } 720 | #else 721 | public List Parse (IEnumerable arguments) 722 | { 723 | OptionContext c = CreateOptionContext (); 724 | c.OptionIndex = -1; 725 | bool process = true; 726 | List unprocessed = new List (); 727 | Option def = Contains ("<>") ? this ["<>"] : null; 728 | foreach (string argument in arguments) { 729 | ++c.OptionIndex; 730 | if (argument == "--") { 731 | process = false; 732 | continue; 733 | } 734 | if (!process) { 735 | Unprocessed (unprocessed, def, c, argument); 736 | continue; 737 | } 738 | if (!Parse (argument, c)) 739 | Unprocessed (unprocessed, def, c, argument); 740 | } 741 | if (c.Option != null) 742 | c.Option.Invoke (c); 743 | return unprocessed; 744 | } 745 | #endif 746 | 747 | private static bool Unprocessed (ICollection extra, Option def, OptionContext c, string argument) 748 | { 749 | if (def == null) { 750 | extra.Add (argument); 751 | return false; 752 | } 753 | c.OptionValues.Add (argument); 754 | c.Option = def; 755 | c.Option.Invoke (c); 756 | return false; 757 | } 758 | 759 | private readonly Regex ValueOption = new Regex ( 760 | @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); 761 | 762 | protected bool GetOptionParts (string argument, out string flag, out string name, out string sep, out string value) 763 | { 764 | if (argument == null) 765 | throw new ArgumentNullException ("argument"); 766 | 767 | flag = name = sep = value = null; 768 | Match m = ValueOption.Match (argument); 769 | if (!m.Success) { 770 | return false; 771 | } 772 | flag = m.Groups ["flag"].Value; 773 | name = m.Groups ["name"].Value; 774 | if (m.Groups ["sep"].Success && m.Groups ["value"].Success) { 775 | sep = m.Groups ["sep"].Value; 776 | value = m.Groups ["value"].Value; 777 | } 778 | return true; 779 | } 780 | 781 | protected virtual bool Parse (string argument, OptionContext c) 782 | { 783 | if (c.Option != null) { 784 | ParseValue (argument, c); 785 | return true; 786 | } 787 | 788 | string f, n, s, v; 789 | if (!GetOptionParts (argument, out f, out n, out s, out v)) 790 | return false; 791 | 792 | Option p; 793 | if (Contains (n)) { 794 | p = this [n]; 795 | c.OptionName = f + n; 796 | c.Option = p; 797 | switch (p.OptionValueType) { 798 | case OptionValueType.None: 799 | c.OptionValues.Add (n); 800 | c.Option.Invoke (c); 801 | break; 802 | case OptionValueType.Optional: 803 | case OptionValueType.Required: 804 | ParseValue (v, c); 805 | break; 806 | } 807 | return true; 808 | } 809 | // no match; is it a bool option? 810 | if (ParseBool (argument, n, c)) 811 | return true; 812 | // is it a bundled option? 813 | if (ParseBundledValue (f, string.Concat (n + s + v), c)) 814 | return true; 815 | 816 | return false; 817 | } 818 | 819 | private void ParseValue (string option, OptionContext c) 820 | { 821 | if (option != null) 822 | foreach (string o in c.Option.ValueSeparators != null 823 | ? option.Split (c.Option.ValueSeparators, StringSplitOptions.None) 824 | : new string[]{option}) { 825 | c.OptionValues.Add (o); 826 | } 827 | if (c.OptionValues.Count == c.Option.MaxValueCount || 828 | c.Option.OptionValueType == OptionValueType.Optional) 829 | c.Option.Invoke (c); 830 | else if (c.OptionValues.Count > c.Option.MaxValueCount) { 831 | throw new OptionException (localizer (string.Format ( 832 | "Error: Found {0} option values when expecting {1}.", 833 | c.OptionValues.Count, c.Option.MaxValueCount)), 834 | c.OptionName); 835 | } 836 | } 837 | 838 | private bool ParseBool (string option, string n, OptionContext c) 839 | { 840 | Option p; 841 | string rn; 842 | if (n.Length >= 1 && (n [n.Length-1] == '+' || n [n.Length-1] == '-') && 843 | Contains ((rn = n.Substring (0, n.Length-1)))) { 844 | p = this [rn]; 845 | string v = n [n.Length-1] == '+' ? option : null; 846 | c.OptionName = option; 847 | c.Option = p; 848 | c.OptionValues.Add (v); 849 | p.Invoke (c); 850 | return true; 851 | } 852 | return false; 853 | } 854 | 855 | private bool ParseBundledValue (string f, string n, OptionContext c) 856 | { 857 | if (f != "-") 858 | return false; 859 | for (int i = 0; i < n.Length; ++i) { 860 | Option p; 861 | string opt = f + n [i].ToString (); 862 | string rn = n [i].ToString (); 863 | if (!Contains (rn)) { 864 | if (i == 0) 865 | return false; 866 | throw new OptionException (string.Format (localizer ( 867 | "Cannot bundle unregistered option '{0}'."), opt), opt); 868 | } 869 | p = this [rn]; 870 | switch (p.OptionValueType) { 871 | case OptionValueType.None: 872 | Invoke (c, opt, n, p); 873 | break; 874 | case OptionValueType.Optional: 875 | case OptionValueType.Required: { 876 | string v = n.Substring (i+1); 877 | c.Option = p; 878 | c.OptionName = opt; 879 | ParseValue (v.Length != 0 ? v : null, c); 880 | return true; 881 | } 882 | default: 883 | throw new InvalidOperationException ("Unknown OptionValueType: " + p.OptionValueType); 884 | } 885 | } 886 | return true; 887 | } 888 | 889 | private static void Invoke (OptionContext c, string name, string value, Option option) 890 | { 891 | c.OptionName = name; 892 | c.Option = option; 893 | c.OptionValues.Add (value); 894 | option.Invoke (c); 895 | } 896 | 897 | private const int OptionWidth = 29; 898 | 899 | public void WriteOptionDescriptions (TextWriter o) 900 | { 901 | foreach (Option p in this) { 902 | int written = 0; 903 | if (!WriteOptionPrototype (o, p, ref written)) 904 | continue; 905 | 906 | if (written < OptionWidth) 907 | o.Write (new string (' ', OptionWidth - written)); 908 | else { 909 | o.WriteLine (); 910 | o.Write (new string (' ', OptionWidth)); 911 | } 912 | 913 | List lines = GetLines (localizer (GetDescription (p.Description))); 914 | o.WriteLine (lines [0]); 915 | string prefix = new string (' ', OptionWidth+2); 916 | for (int i = 1; i < lines.Count; ++i) { 917 | o.Write (prefix); 918 | o.WriteLine (lines [i]); 919 | } 920 | } 921 | } 922 | 923 | bool WriteOptionPrototype (TextWriter o, Option p, ref int written) 924 | { 925 | string[] names = p.Names; 926 | 927 | int i = GetNextOptionIndex (names, 0); 928 | if (i == names.Length) 929 | return false; 930 | 931 | if (names [i].Length == 1) { 932 | Write (o, ref written, " -"); 933 | Write (o, ref written, names [0]); 934 | } 935 | else { 936 | Write (o, ref written, " --"); 937 | Write (o, ref written, names [0]); 938 | } 939 | 940 | for ( i = GetNextOptionIndex (names, i+1); 941 | i < names.Length; i = GetNextOptionIndex (names, i+1)) { 942 | Write (o, ref written, ", "); 943 | Write (o, ref written, names [i].Length == 1 ? "-" : "--"); 944 | Write (o, ref written, names [i]); 945 | } 946 | 947 | if (p.OptionValueType == OptionValueType.Optional || 948 | p.OptionValueType == OptionValueType.Required) { 949 | if (p.OptionValueType == OptionValueType.Optional) { 950 | Write (o, ref written, localizer ("[")); 951 | } 952 | Write (o, ref written, localizer ("=" + GetArgumentName (0, p.MaxValueCount, p.Description))); 953 | string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0 954 | ? p.ValueSeparators [0] 955 | : " "; 956 | for (int c = 1; c < p.MaxValueCount; ++c) { 957 | Write (o, ref written, localizer (sep + GetArgumentName (c, p.MaxValueCount, p.Description))); 958 | } 959 | if (p.OptionValueType == OptionValueType.Optional) { 960 | Write (o, ref written, localizer ("]")); 961 | } 962 | } 963 | return true; 964 | } 965 | 966 | static int GetNextOptionIndex (string[] names, int i) 967 | { 968 | while (i < names.Length && names [i] == "<>") { 969 | ++i; 970 | } 971 | return i; 972 | } 973 | 974 | static void Write (TextWriter o, ref int n, string s) 975 | { 976 | n += s.Length; 977 | o.Write (s); 978 | } 979 | 980 | private static string GetArgumentName (int index, int maxIndex, string description) 981 | { 982 | if (description == null) 983 | return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); 984 | string[] nameStart; 985 | if (maxIndex == 1) 986 | nameStart = new string[]{"{0:", "{"}; 987 | else 988 | nameStart = new string[]{"{" + index + ":"}; 989 | for (int i = 0; i < nameStart.Length; ++i) { 990 | int start, j = 0; 991 | do { 992 | start = description.IndexOf (nameStart [i], j); 993 | } while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false); 994 | if (start == -1) 995 | continue; 996 | int end = description.IndexOf ("}", start); 997 | if (end == -1) 998 | continue; 999 | return description.Substring (start + nameStart [i].Length, end - start - nameStart [i].Length); 1000 | } 1001 | return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); 1002 | } 1003 | 1004 | private static string GetDescription (string description) 1005 | { 1006 | if (description == null) 1007 | return string.Empty; 1008 | StringBuilder sb = new StringBuilder (description.Length); 1009 | int start = -1; 1010 | for (int i = 0; i < description.Length; ++i) { 1011 | switch (description [i]) { 1012 | case '{': 1013 | if (i == start) { 1014 | sb.Append ('{'); 1015 | start = -1; 1016 | } 1017 | else if (start < 0) 1018 | start = i + 1; 1019 | break; 1020 | case '}': 1021 | if (start < 0) { 1022 | if ((i+1) == description.Length || description [i+1] != '}') 1023 | throw new InvalidOperationException ("Invalid option description: " + description); 1024 | ++i; 1025 | sb.Append ("}"); 1026 | } 1027 | else { 1028 | sb.Append (description.Substring (start, i - start)); 1029 | start = -1; 1030 | } 1031 | break; 1032 | case ':': 1033 | if (start < 0) 1034 | goto default; 1035 | start = i + 1; 1036 | break; 1037 | default: 1038 | if (start < 0) 1039 | sb.Append (description [i]); 1040 | break; 1041 | } 1042 | } 1043 | return sb.ToString (); 1044 | } 1045 | 1046 | private static List GetLines (string description) 1047 | { 1048 | List lines = new List (); 1049 | if (string.IsNullOrEmpty (description)) { 1050 | lines.Add (string.Empty); 1051 | return lines; 1052 | } 1053 | int length = 80 - OptionWidth - 2; 1054 | int start = 0, end; 1055 | do { 1056 | end = GetLineEnd (start, length, description); 1057 | bool cont = false; 1058 | if (end < description.Length) { 1059 | char c = description [end]; 1060 | if (c == '-' || (char.IsWhiteSpace (c) && c != '\n')) 1061 | ++end; 1062 | else if (c != '\n') { 1063 | cont = true; 1064 | --end; 1065 | } 1066 | } 1067 | lines.Add (description.Substring (start, end - start)); 1068 | if (cont) { 1069 | lines [lines.Count-1] += "-"; 1070 | } 1071 | start = end; 1072 | if (start < description.Length && description [start] == '\n') 1073 | ++start; 1074 | } while (end < description.Length); 1075 | return lines; 1076 | } 1077 | 1078 | private static int GetLineEnd (int start, int length, string description) 1079 | { 1080 | int end = Math.Min (start + length, description.Length); 1081 | int sep = -1; 1082 | for (int i = start; i < end; ++i) { 1083 | switch (description [i]) { 1084 | case ' ': 1085 | case '\t': 1086 | case '\v': 1087 | case '-': 1088 | case ',': 1089 | case '.': 1090 | case ';': 1091 | sep = i; 1092 | break; 1093 | case '\n': 1094 | return i; 1095 | } 1096 | } 1097 | if (sep == -1 || end == description.Length) 1098 | return end; 1099 | return sep; 1100 | } 1101 | } 1102 | } 1103 | 1104 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License(MIT) 3 | 4 | Copyright(c) 2018 Jakob Sagatowski 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | using EnvDTE80; 25 | using NDesk.Options; 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Linq; 30 | using System.Text; 31 | using System.Threading.Tasks; 32 | using TCatSysManagerLib; 33 | 34 | namespace AllTwinCAT.TcStaticAnalysisLoader 35 | { 36 | class Program { 37 | private static string VisualStudioSolutionFilePath = null; 38 | private static string TwinCATProjectFilePath = null; 39 | 40 | [STAThread] 41 | static int Main(string[] args) { 42 | bool showHelp = false; 43 | 44 | OptionSet options = new OptionSet() 45 | .Add("v=|VisualStudioSolutionFilePath=", v => VisualStudioSolutionFilePath = v) 46 | .Add("t=|TwinCATProjectFilePath=", t => TwinCATProjectFilePath = t) 47 | .Add("?|h|help", h => showHelp = h != null); 48 | 49 | try { 50 | options.Parse(args); 51 | } 52 | catch (OptionException e) { 53 | Console.WriteLine(e.Message); 54 | Console.WriteLine("Try `TcStaticAnalysisLoader --help' for more information."); 55 | return Constants.RETURN_ERROR; 56 | } 57 | options.Parse(args); 58 | 59 | Console.WriteLine("TcStaticAnalysisLoader.exe : argument 1: " + VisualStudioSolutionFilePath); 60 | Console.WriteLine("TcStaticAnalysisLoader.exe : argument 2: " + TwinCATProjectFilePath); 61 | 62 | /* Make sure the user has supplied the paths for both the Visual Studio solution file 63 | * and the TwinCAT project file. Also verify that these two files exists. 64 | */ 65 | if (showHelp || VisualStudioSolutionFilePath == null || TwinCATProjectFilePath == null) { 66 | DisplayHelp(options); 67 | return Constants.RETURN_ERROR; 68 | } 69 | if (!File.Exists(VisualStudioSolutionFilePath)) { 70 | Console.WriteLine("ERROR: Visual studio solution " + VisualStudioSolutionFilePath + " does not exist!"); 71 | return Constants.RETURN_ERROR; 72 | } 73 | if (!File.Exists(TwinCATProjectFilePath)) { 74 | Console.WriteLine("ERROR : TwinCAT project file " + TwinCATProjectFilePath + " does not exist!"); 75 | return Constants.RETURN_ERROR; 76 | } 77 | 78 | 79 | /* Find visual studio version */ 80 | string vsVersion = ""; 81 | string line; 82 | bool foundVsVersionLine = false; 83 | System.IO.StreamReader file = new System.IO.StreamReader(@VisualStudioSolutionFilePath); 84 | while ((line = file.ReadLine()) != null) { 85 | if (line.StartsWith("VisualStudioVersion")) { 86 | string version = line.Substring(line.LastIndexOf('=') + 2); 87 | Console.WriteLine("In Visual Studio solution file, found visual studio version " +version); 88 | string[] numbers = version.Split('.'); 89 | string major = numbers[0]; 90 | string minor = numbers[1]; 91 | 92 | bool isNumericMajor = int.TryParse(major, out int n); 93 | bool isNumericMinor = int.TryParse(minor, out int n2); 94 | 95 | if (isNumericMajor && isNumericMinor) { 96 | vsVersion = major + "." + minor; 97 | foundVsVersionLine = true; 98 | } 99 | break; 100 | } 101 | } 102 | file.Close(); 103 | 104 | if (!foundVsVersionLine) { 105 | Console.WriteLine("Did not find Visual studio version in Visual studio solution file"); 106 | return Constants.RETURN_ERROR; 107 | } 108 | 109 | /* Find TwinCAT project version */ 110 | string tcVersion = ""; 111 | bool foundTcVersionLine = false; 112 | file = new System.IO.StreamReader(@TwinCATProjectFilePath); 113 | while ((line = file.ReadLine()) != null) { 114 | if (line.Contains("TcVersion")) { 115 | string version = line.Substring(line.LastIndexOf("TcVersion=\"")); 116 | int pFrom = version.IndexOf("TcVersion=\"") + "TcVersion=\"".Length; 117 | int pTo = version.LastIndexOf("\">"); 118 | if (pTo > pFrom) { 119 | tcVersion = version.Substring(pFrom, pTo - pFrom); 120 | foundTcVersionLine = true; 121 | Console.WriteLine("In TwinCAT project file, found version " + tcVersion); 122 | } 123 | break; 124 | } 125 | } 126 | file.Close(); 127 | if (!foundTcVersionLine) { 128 | Console.WriteLine("Did not find TcVersion in TwinCAT project file"); 129 | return Constants.RETURN_ERROR; 130 | } 131 | 132 | 133 | /* Make sure TwinCAT version is at minimum version 3.1.4022.0 as the static code 134 | * analysis tool is only supported from this version and onward 135 | */ 136 | var versionMin = new Version(Constants.MIN_TC_VERSION_FOR_SC_ANALYSIS); 137 | var versionDetected = new Version(tcVersion); 138 | var compareResult = versionDetected.CompareTo(versionMin); 139 | if (compareResult < 0) { 140 | Console.WriteLine("The detected TwinCAT version in the project does not support TE1200 static code analysis"); 141 | Console.WriteLine("The minimum version that supports TE1200 is " + Constants.MIN_TC_VERSION_FOR_SC_ANALYSIS); 142 | return Constants.RETURN_ERROR; 143 | } 144 | 145 | MessageFilter.Register(); 146 | 147 | /* Make sure the DTE loads with the same version of Visual Studio as the 148 | * TwinCAT project was created in 149 | */ 150 | string VisualStudioProgId = "VisualStudio.DTE." + vsVersion; 151 | Type type = System.Type.GetTypeFromProgID(VisualStudioProgId); 152 | EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)System.Activator.CreateInstance(type); 153 | 154 | dte.SuppressUI = true; 155 | dte.MainWindow.Visible = false; 156 | EnvDTE.Solution visualStudioSolution = dte.Solution; 157 | visualStudioSolution.Open(@VisualStudioSolutionFilePath); 158 | EnvDTE.Project pro = visualStudioSolution.Projects.Item(1); 159 | 160 | ITcRemoteManager remoteManager = dte.GetObject("TcRemoteManager"); 161 | remoteManager.Version = tcVersion; 162 | var settings = dte.GetObject("TcAutomationSettings"); 163 | settings.SilentMode = true; // Only available from TC3.1.4020.0 and above 164 | 165 | /* Build the solution and collect any eventual errors. Make sure to 166 | * filter out everything that is 167 | * - Either a warning or an error 168 | * - Starts with the string "SA", which is everything from the TE1200 169 | * static code analysis tool 170 | */ 171 | visualStudioSolution.SolutionBuild.Clean(true); 172 | visualStudioSolution.SolutionBuild.Build(true); 173 | 174 | ErrorItems errors = dte.ToolWindows.ErrorList.ErrorItems; 175 | 176 | Console.WriteLine("Errors count: " + errors.Count); 177 | int tcStaticAnalysisWarnings = 0; 178 | int tcStaticAnalysisErrors = 0; 179 | for (int i = 1; i <= errors.Count; i++) { 180 | ErrorItem item = errors.Item(i); 181 | if (item.Description.StartsWith("SA") && (item.ErrorLevel != vsBuildErrorLevel.vsBuildErrorLevelLow)) { 182 | Console.WriteLine("Description: " + item.Description); 183 | Console.WriteLine("ErrorLevel: " + item.ErrorLevel); 184 | Console.WriteLine("Filename: " + item.FileName); 185 | if (item.ErrorLevel == vsBuildErrorLevel.vsBuildErrorLevelMedium) 186 | tcStaticAnalysisWarnings++; 187 | else if (item.ErrorLevel == vsBuildErrorLevel.vsBuildErrorLevelHigh) 188 | tcStaticAnalysisErrors++; 189 | } 190 | } 191 | 192 | dte.Quit(); 193 | 194 | MessageFilter.Revoke(); 195 | 196 | /* Return the result to the user */ 197 | if (tcStaticAnalysisErrors > 0) 198 | return Constants.RETURN_ERROR; 199 | else if (tcStaticAnalysisWarnings > 0) 200 | return Constants.RETURN_UNSTABLE; 201 | else 202 | return Constants.RETURN_SUCCESSFULL; 203 | } 204 | 205 | static void DisplayHelp(OptionSet p) { 206 | Console.WriteLine("Usage: TcStaticAnalysisLoader [OPTIONS]"); 207 | Console.WriteLine("Loads the TwinCAT static code analysis loader program with the selected visual studio solution and TwinCAT project."); 208 | Console.WriteLine("Example: TcStaticAnalysisLoader -v \"C:\\Jenkins\\workspace\\TcProject\\TcProject.sln\" -t \"C:\\Jenkins\\workspace\\TcProject\\PlcProject1\\PlcProj.tsproj\""); 209 | Console.WriteLine(); 210 | Console.WriteLine("Options:"); 211 | p.WriteOptionDescriptions(Console.Out); 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TcStaticAnalysisLoader")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TcStaticAnalysisLoader")] 13 | [assembly: AssemblyCopyright("Copyright © Jakob Sagatowski 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("df5de715-de1d-4b91-8385-1471edb37a92")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TcStaticAnalysisLoader/TcStaticAnalysisLoader/TcStaticAnalysisLoader.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DF5DE715-DE1D-4B91-8385-1471EDB37A92} 8 | Exe 9 | TcStaticAnalysisLoader 10 | TcStaticAnalysisLoader 11 | v4.6.1 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | True 37 | 38 | 39 | True 40 | 41 | 42 | True 43 | 44 | 45 | True 46 | 47 | 48 | True 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {3C49D6C3-93DC-11D0-B162-00A0248C244B} 73 | 3 74 | 2 75 | 0 76 | primary 77 | False 78 | True 79 | True 80 | 81 | 82 | 83 | --------------------------------------------------------------------------------