#!/usr/bin/env python3
# Copyright (c) 2015-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

'''
This checks if all command line args are documented.
Return value is 0 to indicate no error.

Author: @MarcoFalke
'''

from subprocess import check_output
import re
import sys

FOLDER_GREP = 'src'
FOLDER_TEST = 'src/test/'
CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/{}'.format(FOLDER_GREP)
CMD_GREP_ARGS = r"egrep -r -I '(map(Multi)?Args(\.count\(|\[)|Get(Bool)?Arg\()\"\-[^\"]+?\"' {} | grep -v '{}'".format(CMD_ROOT_DIR, FOLDER_TEST)
CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' {}".format(CMD_ROOT_DIR)
REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
# list unsupported, deprecated and duplicate args as they need no documentation
SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags', '-blockminsize', '-dbcrashratio', '-forcecompactdb', '-usehd'])

def main():
  used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True)
  docd = check_output(CMD_GREP_DOCS, shell=True, universal_newlines=True)

  args_used = set(re.findall(REGEX_ARG,used))
  args_docd = set(re.findall(REGEX_DOC,docd)).union(SET_DOC_OPTIONAL)
  args_need_doc = args_used.difference(args_docd)
  args_unknown = args_docd.difference(args_used)

  print("Args used        : {}".format(len(args_used)))
  print("Args documented  : {}".format(len(args_docd)))
  print("Args undocumented: {}".format(len(args_need_doc)))
  print(args_need_doc)
  print("Args unknown     : {}".format(len(args_unknown)))
  print(args_unknown)

  sys.exit(len(args_need_doc))

if __name__ == "__main__":
    main()

@@ -435,16 +435,141 @@
 /test/'%0A
+REGEX_ARG = '(?:ForceSet%7CSoftSet%7CGet%7CIs)(?:Bool)?Args?(?:Set)?%5C(%22(-%5B%5E%22%5D+)%22'%0AREGEX_DOC = 'HelpMessageOpt%5C(%22(-%5B%5E%22=%5D+?)(?:=%7C%22)'%0A
 CMD_ROOT
@@ -654,97 +654,53 @@
 = r%22
-e
+git 
 grep -
-r -I '(map(Multi)?Args(%5C.count%5C(%7C%5C%5B)%7CGet(Bool)?Arg%5C()%5C%22%5C-%5B%5E%5C%22%5D+?%5C%22' %7B%7D %7C grep -v '
+-perl-regexp '%7B%7D' -- %7B%7D ':(exclude)
 %7B%7D'%22
@@ -699,32 +699,43 @@
 ude)%7B%7D'%22.format(
+REGEX_ARG, 
 CMD_ROOT_DIR, FO
@@ -767,55 +767,34 @@
 = r%22
-e
+git 
 grep -
-r -I 'HelpMessageOpt%5C(%5C%22%5C-%5B%5E%5C%22=%5D+?(=%7C%5C%22)
+-perl-regexp '%7B%7D
 ' %7B%7D
@@ -802,16 +802,27 @@
 .format(
+REGEX_DOC, 
 CMD_ROOT
@@ -831,172 +831,8 @@
 IR)%0A
-REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:%5C.count%5C(%7C%5C%5B)%7CGet(?:Bool)?Arg%5C()%5C%22(%5C-%5B%5E%5C%22%5D+?)%5C%22')%0AREGEX_DOC = re.compile(r'HelpMessageOpt%5C(%5C%22(%5C-%5B%5E%5C%22=%5D+?)(?:=%7C%5C%22)')%0A
 # li
@@ -1168,16 +1168,17 @@
 ehd'%5D)%0A%0A
+%0A
 def main
@@ -1181,16 +1181,18 @@
 main():%0A
+  
   used =
@@ -1257,16 +1257,18 @@
 s=True)%0A
+  
   docd =
@@ -1334,16 +1334,18 @@
 =True)%0A%0A
+  
   args_u
@@ -1361,24 +1361,35 @@
 (re.findall(
+re.compile(
 REGEX_ARG,us
@@ -1389,16 +1389,20 @@
 _ARG
-,
+), 
 used))%0A
+  
   ar
@@ -1426,16 +1426,27 @@
 findall(
+re.compile(
 REGEX_DO
@@ -1446,17 +1446,19 @@
 EGEX_DOC
-,
+), 
 docd)).u
@@ -1480,16 +1480,18 @@
 TIONAL)%0A
+  
   args_n
@@ -1534,16 +1534,18 @@
 docd)%0A  
+ 
+ 
 args_unk
@@ -1584,16 +1584,18 @@
 _used)%0A%0A
+  
   print(
@@ -1638,24 +1638,26 @@
 rgs_used)))%0A
+  
   print(%22Arg
@@ -1696,24 +1696,26 @@
 rgs_docd)))%0A
+  
   print(%22Arg
@@ -1758,24 +1758,26 @@
 need_doc)))%0A
+  
   print(args
@@ -1785,24 +1785,26 @@
 need_doc)%0A  
+ 
+ 
 print(%22Args 
@@ -1848,16 +1848,18 @@
 nown)))%0A
+  
   print(
@@ -1873,16 +1873,18 @@
 known)%0A%0A
+  
   sys.ex
@@ -1907,16 +1907,17 @@
 _doc))%0A%0A
+%0A
 if __nam

Fix check-doc script regexes