check-doc.pl 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #!/usr/bin/perl
  2. # Documentation Checker
  3. # by trojal (modified by lighta)
  4. use strict;
  5. use File::Basename;
  6. use Getopt::Long;
  7. my $sHelp = 0;
  8. my $sAtcf = "../doc/atcommands.txt";
  9. my $sSctf = "../doc/script_commands.txt";
  10. my $sLeftOverChk = 0;
  11. my $sCmd = "chk";
  12. my $sValidCmd = "ls|chk";
  13. my $sTarget = "All";
  14. my $sValidTarget = "All|Script|Atc";
  15. my $sInc_atcf = "../doc/atcommands2.txt";
  16. my $sInc_scrtf = "../doc/script_commands2.txt";
  17. my($filename, $dir, $suffix) = fileparse($0);
  18. chdir $dir; #put ourself like was called in tool folder
  19. GetArgs();
  20. Main($sCmd,$sTarget);
  21. sub GetArgs {
  22. GetOptions(
  23. 'cmd=s' => \$sCmd, # which command to run
  24. 'atcf=s' => \$sAtcf, #atcommand doc file
  25. 'scriptf=s' => \$sSctf, #script doc file
  26. 'inc_atcf=s' => \$sInc_atcf, #include script doc file (for customs doc)
  27. 'inc_scrtf=s' => \$sInc_scrtf, #include script doc file (for customs doc)
  28. 'target=s' => \$sTarget, #Target (wich files to run-cmd into)
  29. 'leftover=i' => \$sLeftOverChk, #should we chk if all doc are linked to a src ?
  30. 'help!' => \$sHelp,
  31. ) or $sHelp=1; #display help if invalid option
  32. if( $sHelp ) {
  33. print "Incorrect option specified, available options are:\n"
  34. ."\t --atcf filename => file (specify atcommand doc to use)\n"
  35. ."\t --inc_atcf filename => include file (specify atcommand doc to use)\n"
  36. ."\t --scriptf filename => file (specify script doc to use)\n"
  37. ."\t --inc_scrtf filename => include file (specify script doc to use)\n"
  38. ."\t --leftover=0|1 => should we run reverse chk for leftover in documentation ?\n"
  39. ."\t --target => target (specify wich check to run [$sValidTarget])\n"
  40. ."\t --cmd => cmd (specify wich command to run [(default)$sValidCmd])\n";
  41. exit;
  42. }
  43. unless($sTarget =~ /$sValidTarget/i){
  44. print "Incorrect target specified. Available targets:\n"
  45. ."\t --target => target (specify wich check to run [(default)$sValidTarget])\n";
  46. exit;
  47. }
  48. unless($sCmd =~ /$sValidCmd/i){
  49. print "Incorrect command specified. Available commands:\n"
  50. ."\t --cmd => cmd (specify wich command to run [(default)$sValidCmd])\n";
  51. exit;
  52. }
  53. }
  54. sub Main { my ($sCmd,$sTarget) = @_;
  55. if($sTarget=~/both|all/i){ #both is keep as backard compatibility here cf check-doc.sh
  56. $sTarget = "script|atc";
  57. }
  58. if($sTarget=~/script/i){ #find which script commands are missing from doc/script_commands.txt
  59. my $raSct_cmd = Script_GetCmd();
  60. if($sCmd =~ /ls/i) {
  61. print "The list of script-commands found are = \n[ @$raSct_cmd ] \n\n";
  62. }
  63. if($sCmd =~ /chk/i) { Script_Chk($raSct_cmd); }
  64. }
  65. if($sTarget=~/atc/i){ #find which atcommands are missing from doc/atcommands.txt
  66. my $raAct_cmd = Atc_GetCmd();
  67. if($sCmd =~ /ls/i) {
  68. print "The list of atcommands found are = \n[ @$raAct_cmd ] \n\n";
  69. }
  70. if($sCmd =~ /chk/i) { Atc_Chk($raAct_cmd); }
  71. }
  72. }
  73. sub Chk { my($raA,$raB) = @_;
  74. my @aMissing = ();
  75. foreach my $sA (@$raA){
  76. my $sFound = 0;
  77. foreach my $sB (@$raB){
  78. $sFound=1 if($sA eq $sB);
  79. }
  80. unless($sFound){
  81. push(@aMissing,$sA);
  82. }
  83. }
  84. return \@aMissing;
  85. }
  86. sub Script_GetCmd {
  87. my @aSct_src = ("../src/map/script.c","../src/custom/script_def.inc");
  88. my @aDef_sct = ();
  89. foreach my $sSct_srcf (@aSct_src){
  90. unless(open FILE_SRC, "<$sSct_srcf") {
  91. print "Couldn't open file '$sSct_srcf'.\n";
  92. next;
  93. }
  94. while(<FILE_SRC>){
  95. next if($_ =~ /^#/); #ignoe include, define or macro
  96. if($_ =~ /BUILDIN_DEF|BUILDIN_DEF2/){
  97. $_ =~ s/\s+$//; #Remove trailing spaces.
  98. $_ =~ s/^\s+//; #Remove leading spaces.
  99. if($_ =~ /^BUILDIN_DEF2/){
  100. my @line = split('"',$_);
  101. push(@aDef_sct,$line[1]);
  102. }
  103. elsif($_ =~ /^BUILDIN_DEF/){
  104. my @line = split(',',$_);
  105. @line = split('\(',$line[0]);
  106. push(@aDef_sct,$line[1]);
  107. }
  108. }
  109. }
  110. close FILE_SRC;
  111. }
  112. return \@aDef_sct;
  113. }
  114. sub Script_Chk { my ($raDef_sct) = @_;
  115. my @aSct_docf = ($sSctf,$sInc_scrtf);
  116. my @aDoc_sct = ();
  117. my $raMiss_sct;
  118. foreach my $sSct_docf (@aSct_docf){
  119. unless(open FILE_DOC, "$sSct_docf"){
  120. print "Couldn't open file '$sSct_docf'.\n";
  121. next;
  122. }
  123. while(<FILE_DOC>){
  124. next if($_ =~ /^\*\*|^\*\s|^\s+/); #discard **, * foo, foo
  125. next if(/^\s+/);
  126. if($_ =~ /^\*/){
  127. my @line = split(' ',$_);
  128. @line = split('\(',$line[0]);
  129. @line = split('\<',$line[0]);
  130. $line[0] =~ s/\(|\{|\*|\r|\s|\;|\)|\"|\,//g; #todo please harmonize command definition for easier parse
  131. next if($line[0] eq "Name" || $line[0] eq "" || $line[0] eq "function"
  132. || $line[0] eq "if" || $line[0] eq "while" || $line[0] eq "do" || $line[0] eq "for" ); #exception list
  133. push(@aDoc_sct,$line[0]);
  134. }
  135. }
  136. close FILE_DOC;
  137. }
  138. $raMiss_sct = Chk($raDef_sct,\@aDoc_sct); #check missing documentation
  139. if(scalar(@$raMiss_sct)){
  140. print "Missing script documentation for function :{\n";
  141. foreach(@$raMiss_sct){
  142. print "\t$_ \n";
  143. }
  144. print "}\n\n";
  145. }
  146. else { print "All script commands in src are documented, no issues found.\n"; }
  147. if($sLeftOverChk){
  148. my $raLeftover_sct = Chk(\@aDoc_sct,$raDef_sct); #we just inverse the chk for leftover
  149. if(scalar(@$raLeftover_sct)){
  150. print "These script commands were found in doc with no associated source:{\n";
  151. foreach(@$raLeftover_sct){
  152. print "\t$_ \n";
  153. }
  154. print "}\n\n";
  155. }
  156. else { print "All script commands in documentation match a source BUILDIN, no leftovers found.\n"; }
  157. }
  158. }
  159. sub Atc_GetCmd {
  160. my @aAct_src = ("../src/map/atcommand.c","../src/custom/atcommand_def.inc");
  161. my @aDef_act = ();
  162. foreach my $sAct_srcf (@aAct_src){
  163. unless(open FILE_SRC, "<$sAct_srcf"){
  164. print "Couldn't open file '$sAct_srcf'.\n";
  165. next;
  166. }
  167. while(<FILE_SRC>){
  168. next if($_ =~ /^#/); #ignore include, define or macro
  169. if($_ =~ /ACMD_DEF|ACMD_DEF2|ACMD_DEFR|ACMD_DEF2R/){
  170. $_ =~ s/\s+$//; #Remove trailing spaces.
  171. $_ =~ s/^\s+//; #Remove leading spaces.
  172. if($_ =~ /^ACMD_DEF2|^ACMD_DEF2R/){
  173. my @line = split('"',$_);
  174. push(@aDef_act,$line[1]);
  175. }
  176. elsif($_ =~ /^ACMD_DEF|^ACMD_DEFR/){
  177. my @line = split(',',$_);
  178. @line = split('\(',$line[0]);
  179. $line[1] =~ s/\)//; #Remove closing brace
  180. push(@aDef_act,$line[1]);
  181. }
  182. }
  183. }
  184. close FILE_SRC;
  185. }
  186. return \@aDef_act;
  187. }
  188. sub Atc_Chk { my ($raDef_act) = @_;
  189. my @aAct_docf = ($sAtcf,$sInc_atcf);
  190. my @aDoc_act = ();
  191. my $raMiss_act;
  192. foreach my $sAct_docf (@aAct_docf){
  193. unless(open FILE_DOC, "$sAct_docf"){
  194. print "Couldn't open file '$sAct_docf'.\n";
  195. next;
  196. }
  197. while(<FILE_DOC>){
  198. next if($_ =~ /^\*\*|^\*\s|^\s+/); #discard **, * foo, foo
  199. next if(/^\s+/);
  200. if($_ =~ /^\@/){
  201. my @line = split(' ',$_);
  202. @line = split('\(',$line[0]);
  203. @line = split('\<',$line[0]);
  204. $line[0] =~ s/\(|\{|\@|\r|\s|\;|\)|\"|\,//g; #todo please harmonize command definition for easier parse
  205. push(@aDoc_act,$line[0]);
  206. }
  207. }
  208. close FILE_DOC;
  209. }
  210. $raMiss_act = Chk($raDef_act,\@aDoc_act); #check missing documentation
  211. if(scalar(@$raMiss_act)){
  212. print "Missing atcommand documentation for function :{\n";
  213. foreach(@$raMiss_act){
  214. print "\t$_ \n";
  215. }
  216. print "}\n\n";
  217. }
  218. else { print "All atcommands in src are documented, no issues found.\n"; }
  219. if($sLeftOverChk){
  220. my $raLeftover_sct = Chk(\@aDoc_act,$raDef_act); #we just inverse the chk for leftover
  221. if(scalar(@$raLeftover_sct)){
  222. print "These atcommands were found in doc with no associated source: {\n";
  223. foreach(@$raLeftover_sct){
  224. print "\t$_ \n";
  225. }
  226. print "}\n\n";
  227. }
  228. else { print "All atcommands in documentation match a source ATCMD, no leftovers found.\n"; }
  229. }
  230. }