shelldocs.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #!/usr/bin/python
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import re
  15. import sys
  16. import string
  17. from optparse import OptionParser
  18. def docstrip(key,string):
  19. string=re.sub("^## @%s " % key ,"",string)
  20. string=string.lstrip()
  21. string=string.rstrip()
  22. return string
  23. def toc(list):
  24. tocout=[]
  25. header=()
  26. for i in list:
  27. if header != i.getinter():
  28. header=i.getinter()
  29. line=" * %s\n" % (i.headerbuild())
  30. tocout.append(line)
  31. line=" * [%s](#%s)\n" % (i.getname().replace("_","\_"),i.getname())
  32. tocout.append(line)
  33. return tocout
  34. class ShellFunction:
  35. def __init__(self):
  36. self.reset()
  37. def __cmp__(self,other):
  38. if (self.audience == other.audience):
  39. if (self.stability == other.stability):
  40. if (self.replaceb == other.replaceb):
  41. return(cmp(self.name,other.name))
  42. else:
  43. if (self.replaceb == "Yes"):
  44. return -1
  45. else:
  46. return 1
  47. else:
  48. if (self.stability == "Stable"):
  49. return -1
  50. else:
  51. return 1
  52. else:
  53. if (self.audience == "Public"):
  54. return -1
  55. else:
  56. return 1
  57. def reset(self):
  58. self.name=None
  59. self.audience=None
  60. self.stability=None
  61. self.replaceb=None
  62. self.returnt=None
  63. self.desc=None
  64. self.params=None
  65. def setname(self,text):
  66. definition=text.split();
  67. self.name=definition[1]
  68. def getname(self):
  69. if (self.name is None):
  70. return "None"
  71. else:
  72. return self.name
  73. def setaudience(self,text):
  74. self.audience=docstrip("audience",text)
  75. self.audience=self.audience.capitalize()
  76. def getaudience(self):
  77. if (self.audience is None):
  78. return "None"
  79. else:
  80. return self.audience
  81. def setstability(self,text):
  82. self.stability=docstrip("stability",text)
  83. self.stability=self.stability.capitalize()
  84. def getstability(self):
  85. if (self.stability is None):
  86. return "None"
  87. else:
  88. return self.stability
  89. def setreplace(self,text):
  90. self.replaceb=docstrip("replaceable",text)
  91. self.replaceb=self.replaceb.capitalize()
  92. def getreplace(self):
  93. if (self.replaceb is None):
  94. return "None"
  95. else:
  96. return self.replaceb
  97. def getinter(self):
  98. return( (self.getaudience(), self.getstability(), self.getreplace()))
  99. def addreturn(self,text):
  100. if (self.returnt is None):
  101. self.returnt = []
  102. self.returnt.append(docstrip("return",text))
  103. def getreturn(self):
  104. if (self.returnt is None):
  105. return "Nothing"
  106. else:
  107. return "\n\n".join(self.returnt)
  108. def adddesc(self,text):
  109. if (self.desc is None):
  110. self.desc = []
  111. self.desc.append(docstrip("description",text))
  112. def getdesc(self):
  113. if (self.desc is None):
  114. return "None"
  115. else:
  116. return " ".join(self.desc)
  117. def addparam(self,text):
  118. if (self.params is None):
  119. self.params = []
  120. self.params.append(docstrip("param",text))
  121. def getparams(self):
  122. if (self.params is None):
  123. return ""
  124. else:
  125. return " ".join(self.params)
  126. def getusage(self):
  127. line="%s %s" % (self.name, self.getparams())
  128. return line
  129. def headerbuild(self):
  130. if self.getreplace() == "Yes":
  131. replacetext="Replaceable"
  132. else:
  133. replacetext="Not Replaceable"
  134. line="%s/%s/%s" % (self.getaudience(), self.getstability(), replacetext)
  135. return(line)
  136. def getdocpage(self):
  137. line="### `%s`\n\n"\
  138. "* Synopsis\n\n"\
  139. "```\n%s\n"\
  140. "```\n\n" \
  141. "* Description\n\n" \
  142. "%s\n\n" \
  143. "* Returns\n\n" \
  144. "%s\n\n" \
  145. "| Classification | Level |\n" \
  146. "| :--- | :--- |\n" \
  147. "| Audience | %s |\n" \
  148. "| Stability | %s |\n" \
  149. "| Replaceable | %s |\n\n" \
  150. % (self.getname(),
  151. self.getusage(),
  152. self.getdesc(),
  153. self.getreturn(),
  154. self.getaudience(),
  155. self.getstability(),
  156. self.getreplace())
  157. return line
  158. def __str__(self):
  159. line="{%s %s %s %s}" \
  160. % (self.getname(),
  161. self.getaudience(),
  162. self.getstability(),
  163. self.getreplace())
  164. return line
  165. def main():
  166. parser=OptionParser(usage="usage: %prog --skipprnorep --output OUTFILE --input INFILE [--input INFILE ...]")
  167. parser.add_option("-o","--output", dest="outfile",
  168. action="store", type="string",
  169. help="file to create", metavar="OUTFILE")
  170. parser.add_option("-i","--input", dest="infile",
  171. action="append", type="string",
  172. help="file to read", metavar="INFILE")
  173. parser.add_option("--skipprnorep", dest="skipprnorep",
  174. action="store_true", help="Skip Private & Not Replaceable")
  175. (options, args)=parser.parse_args()
  176. allfuncs=[]
  177. for filename in options.infile:
  178. with open(filename,"r") as shellcode:
  179. funcdef=ShellFunction()
  180. for line in shellcode:
  181. if line.startswith('## @description'):
  182. funcdef.adddesc(line)
  183. elif line.startswith('## @audience'):
  184. funcdef.setaudience(line)
  185. elif line.startswith('## @stability'):
  186. funcdef.setstability(line)
  187. elif line.startswith('## @replaceable'):
  188. funcdef.setreplace(line)
  189. elif line.startswith('## @param'):
  190. funcdef.addparam(line)
  191. elif line.startswith('## @return'):
  192. funcdef.addreturn(line)
  193. elif line.startswith('function'):
  194. funcdef.setname(line)
  195. if options.skipprnorep:
  196. if funcdef.getaudience() == "Private" and \
  197. funcdef.getreplace() == "No":
  198. pass
  199. else:
  200. allfuncs.append(funcdef)
  201. funcdef=ShellFunction()
  202. allfuncs=sorted(allfuncs)
  203. outfile=open(options.outfile, "w")
  204. for line in toc(allfuncs):
  205. outfile.write(line)
  206. outfile.write("\n------\n\n")
  207. header=[]
  208. for funcs in allfuncs:
  209. if header != funcs.getinter():
  210. header=funcs.getinter()
  211. line="## %s\n" % (funcs.headerbuild())
  212. outfile.write(line)
  213. outfile.write(funcs.getdocpage())
  214. outfile.close()
  215. if __name__ == "__main__":
  216. main()