gdoc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. eval '(exit $?0)' && eval 'exec perl -S "$0" ${1+"$@"}'
  2. & eval 'exec perl -S "$0" $argv:q'
  3. if 0;
  4. ## Copyright (c) 2002-2012 Simon Josefsson
  5. ## added -texinfo, -listfunc, -pkg-name
  6. ## man page revamp
  7. ## various improvements
  8. ## Copyright (c) 2001, 2002 Nikos Mavrogiannopoulos
  9. ## added -tex
  10. ## Copyright (c) 1998 Michael Zucchi
  11. # This program is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation, either version 3 of the License, or
  14. # (at your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. # This will read a C source code file and scan for embedded comments
  24. # in the style of gnome comments (+minor extensions - see below).
  25. # usage:
  26. # gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ]
  27. # [ -sourceversion verno ] [ -include file | -includefuncprefix ]
  28. # [ -bugsto address ] [ -pkg-name packagename ]
  29. # [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ]
  30. # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
  31. #
  32. # Set output format using one of -docbook, -html, -text, -man, -tex,
  33. # -texinfo, or -listfunc. Default is man.
  34. #
  35. # -sourceversion
  36. # Version number for source code, e.g. '1.0.4'. Used in 'man' headers.
  37. # Defaults to using current date.
  38. #
  39. # -include FILE
  40. # For man pages, mention #include <FILE.h> in the synopsis.
  41. #
  42. # -includefuncprefix
  43. # For man pages, mention a #include <FILE.h> in the synopsis.
  44. # The FILE derived from the function prefix. For example, a
  45. # function gss_init_sec_context will generate an include
  46. # statement of #include <gss.h>.
  47. #
  48. # -bugsto address
  49. # For man pages, include a section about reporting bugs and mention
  50. # the given e-mail address, e.g 'bug-libidn@gnu.org'.
  51. #
  52. # -pkg-name packagename
  53. # For man pages when -bugsto is used, also include help URLs to the
  54. # the project's home page. For example, "GNU Libidn".
  55. #
  56. # -seeinfo infonode
  57. # For man pages, include a section that point to an info manual
  58. # for more information.
  59. #
  60. # -copyright notice
  61. # For man pages, include a copyright section with the given
  62. # notice after a preamble. Use, e.g., '2002, 2003 Simon Josefsson'.
  63. #
  64. # -verbatimcopying
  65. # For man pages, and when the -copyright parameter is used,
  66. # add a licensing statement that say verbatim copying is permitted.
  67. #
  68. # -function funcname
  69. # If set, then only generate documentation for the given function(s). All
  70. # other functions are ignored.
  71. #
  72. # c files - list of 'c' files to process
  73. #
  74. # All output goes to stdout, with errors to stderr.
  75. #
  76. # format of comments.
  77. # In the following table, (...)? signifies optional structure.
  78. # (...)* signifies 0 or more structure elements
  79. # /**
  80. # * function_name(:)? (- short description)?
  81. # (* @parameterx: (description of parameter x)?)*
  82. # (* a blank line)?
  83. # * (Description:)? (Description of function)?
  84. # * (Section header: (section description)? )*
  85. # (*)?*/
  86. #
  87. # So .. the trivial example would be:
  88. #
  89. # /**
  90. # * my_function
  91. # **/
  92. #
  93. # If the Description: header tag is ommitted, then there must be a blank line
  94. # after the last parameter specification.
  95. # e.g.
  96. # /**
  97. # * my_function - does my stuff
  98. # * @my_arg: its mine damnit
  99. # *
  100. # * Does my stuff explained.
  101. # */
  102. #
  103. # or, could also use:
  104. # /**
  105. # * my_function - does my stuff
  106. # * @my_arg: its mine damnit
  107. # * Description: Does my stuff explained.
  108. # */
  109. # etc.
  110. #
  111. # All descriptions can be multiline, apart from the short function description.
  112. #
  113. # All descriptive text is further processed, scanning for the following special
  114. # patterns, which are highlighted appropriately.
  115. #
  116. # 'funcname()' - function
  117. # '$ENVVAR' - environmental variable OBSOLETE (?)
  118. # '#struct_name' - name of a structure
  119. # '@parameter' - name of a parameter
  120. # '%CONST' - name of a constant.
  121. #
  122. # Extensions for LaTeX:
  123. #
  124. # 1. the symbol '->' will be replaced with a rightarrow
  125. # 2. x^y with ${x}^{y}$.
  126. # 3. xxx\: with xxx:
  127. use POSIX qw(strftime);
  128. # match expressions used to find embedded type information
  129. $type_constant = "\\\%(\\w+)";
  130. $type_func = "(\\w+\\(\\))";
  131. $type_param = "\\\@(\\w+)";
  132. $type_struct = "\\\#(\\w+)";
  133. $type_env = "(\\\$\\w+)";
  134. # Output conversion substitutions.
  135. # One for each output format
  136. # these work fairly well
  137. %highlights_html = ( $type_constant, "<i>\$1</i>",
  138. $type_func, "<b>\$1</b>",
  139. $type_struct, "<i>\$1</i>",
  140. $type_param, "<tt><b>\$1</b></tt>" );
  141. $blankline_html = "<p>";
  142. %highlights_texinfo = ( $type_constant, "\\\@code{\$1}",
  143. $type_func, "\\\@code{\$1}",
  144. $type_struct, "\\\@code{\$1}",
  145. $type_param, "\\\@code{\$1}" );
  146. $blankline_texinfo = "";
  147. %highlights_tex = ( $type_constant, "{\\\\it \$1}",
  148. $type_func, "{\\\\bf \$1}",
  149. $type_struct, "{\\\\it \$1}",
  150. $type_param, "{\\\\bf \$1}" );
  151. $blankline_tex = "\\\\";
  152. # sgml, docbook format
  153. %highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
  154. $type_func, "<function>\$1</function>",
  155. $type_struct, "<structname>\$1</structname>",
  156. $type_env, "<envar>\$1</envar>",
  157. $type_param, "<parameter>\$1</parameter>" );
  158. $blankline_sgml = "</para><para>\n";
  159. # these are pretty rough
  160. %highlights_man = ( $type_constant, "\\\\fB\$1\\\\fP",
  161. $type_func, "\\\\fB\$1\\\\fP",
  162. $type_struct, "\\\\fB\$1\\\\fP",
  163. $type_param, "\\\\fI\$1\\\\fP" );
  164. $blankline_man = "";
  165. # text-mode
  166. %highlights_text = ( $type_constant, "\$1",
  167. $type_func, "\$1",
  168. $type_struct, "\$1",
  169. $type_param, "\$1" );
  170. $blankline_text = "";
  171. sub usage {
  172. print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinfo -listfunc ]\n";
  173. print " [ -sourceversion verno ] [ -include file | -includefuncprefix ]\n";
  174. print " [ -bugsto address ] [ -seeinfo infonode ] [ -copyright notice]\n";
  175. print " [ -verbatimcopying ] [ -pkg-name packagename ]\n";
  176. print " [ -function funcname [ -function funcname ...] ]\n";
  177. print " c source file(s) > outputfile\n";
  178. exit 1;
  179. }
  180. # read arguments
  181. if ($#ARGV==-1) {
  182. usage();
  183. }
  184. $verbose = 0;
  185. $output_mode = "man";
  186. %highlights = %highlights_man;
  187. $blankline = $blankline_man;
  188. $modulename = "API Documentation";
  189. $sourceversion = strftime "%Y-%m-%d", localtime;
  190. $function_only = 0;
  191. while ($ARGV[0] =~ m/^-(.*)/) {
  192. $cmd = shift @ARGV;
  193. if ($cmd eq "-html") {
  194. $output_mode = "html";
  195. %highlights = %highlights_html;
  196. $blankline = $blankline_html;
  197. } elsif ($cmd eq "-man") {
  198. $output_mode = "man";
  199. %highlights = %highlights_man;
  200. $blankline = $blankline_man;
  201. } elsif ($cmd eq "-tex") {
  202. $output_mode = "tex";
  203. %highlights = %highlights_tex;
  204. $blankline = $blankline_tex;
  205. } elsif ($cmd eq "-texinfo") {
  206. $output_mode = "texinfo";
  207. %highlights = %highlights_texinfo;
  208. $blankline = $blankline_texinfo;
  209. } elsif ($cmd eq "-text") {
  210. $output_mode = "text";
  211. %highlights = %highlights_text;
  212. $blankline = $blankline_text;
  213. } elsif ($cmd eq "-docbook") {
  214. $output_mode = "sgml";
  215. %highlights = %highlights_sgml;
  216. $blankline = $blankline_sgml;
  217. } elsif ($cmd eq "-listfunc") {
  218. $output_mode = "listfunc";
  219. } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
  220. $modulename = shift @ARGV;
  221. } elsif ($cmd eq "-sourceversion") {
  222. $sourceversion = shift @ARGV;
  223. } elsif ($cmd eq "-include") {
  224. $include = shift @ARGV;
  225. } elsif ($cmd eq "-includefuncprefix") {
  226. $includefuncprefix = 1;
  227. } elsif ($cmd eq "-bugsto") {
  228. $bugsto = shift @ARGV;
  229. } elsif ($cmd eq "-pkg-name") {
  230. $pkgname = shift @ARGV;
  231. } elsif ($cmd eq "-copyright") {
  232. $copyright = shift @ARGV;
  233. } elsif ($cmd eq "-verbatimcopying") {
  234. $verbatimcopying = 1;
  235. } elsif ($cmd eq "-seeinfo") {
  236. $seeinfo = shift @ARGV;
  237. } elsif ($cmd eq "-function") { # to only output specific functions
  238. $function_only = 1;
  239. $function = shift @ARGV;
  240. $function_table{$function} = 1;
  241. } elsif ($cmd eq "-v") {
  242. $verbose = 1;
  243. } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
  244. usage();
  245. }
  246. }
  247. ##
  248. # dumps section contents to arrays/hashes intended for that purpose.
  249. #
  250. sub dump_section {
  251. my $name = shift @_;
  252. my $contents = join "\n", @_;
  253. if ($name =~ m/$type_constant/) {
  254. $name = $1;
  255. # print STDERR "constant section '$1' = '$contents'\n";
  256. $constants{$name} = $contents;
  257. } elsif ($name =~ m/$type_param/) {
  258. # print STDERR "parameter def '$1' = '$contents'\n";
  259. $name = $1;
  260. $parameters{$name} = $contents;
  261. } else {
  262. # print STDERR "other section '$name' = '$contents'\n";
  263. $sections{$name} = $contents;
  264. push @sectionlist, $name;
  265. }
  266. }
  267. ##
  268. # output function
  269. #
  270. # parameters, a hash.
  271. # function => "function name"
  272. # parameterlist => @list of parameters
  273. # parameters => %parameter descriptions
  274. # sectionlist => @list of sections
  275. # sections => %descriont descriptions
  276. #
  277. sub repstr {
  278. $pattern = shift;
  279. $repl = shift;
  280. $match1 = shift;
  281. $match2 = shift;
  282. $match3 = shift;
  283. $match4 = shift;
  284. $output = $repl;
  285. $output =~ s,\$1,$match1,g;
  286. $output =~ s,\$2,$match2,g;
  287. $output =~ s,\$3,$match3,g;
  288. $output =~ s,\$4,$match4,g;
  289. eval "\$return = qq/$output/";
  290. # print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 replace $repl yielded $output interpolated $return\n";
  291. $return;
  292. }
  293. sub just_highlight {
  294. my $contents = join "\n", @_;
  295. my $line;
  296. my $ret = "";
  297. foreach $pattern (keys %highlights) {
  298. # print "scanning pattern $pattern ($highlights{$pattern})\n";
  299. $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2, $3, $4):gse;
  300. }
  301. foreach $line (split "\n", $contents) {
  302. if ($line eq ""){
  303. $ret = $ret . $lineprefix . $blankline;
  304. } else {
  305. $ret = $ret . $lineprefix . $line;
  306. }
  307. $ret = $ret . "\n";
  308. }
  309. return $ret;
  310. }
  311. sub output_highlight {
  312. print (just_highlight (@_));
  313. }
  314. # output in texinfo
  315. sub output_texinfo {
  316. my %args = %{$_[0]};
  317. my ($parameter, $section);
  318. my $count;
  319. print "\@subheading ".$args{'function'}."\n";
  320. print "\@anchor{".$args{'function'}."}\n";
  321. print "\@deftypefun {" . $args{'functiontype'} . "} ";
  322. print "{".$args{'function'}."} ";
  323. print "(";
  324. $count = 0;
  325. foreach $parameter (@{$args{'parameterlist'}}) {
  326. print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}";
  327. if ($count != $#{$args{'parameterlist'}}) {
  328. $count++;
  329. print ", ";
  330. }
  331. }
  332. print ")\n";
  333. foreach $parameter (@{$args{'parameterlist'}}) {
  334. if ($args{'parameters'}{$parameter}) {
  335. print "\@var{".$parameter."}: ";
  336. output_highlight($args{'parameters'}{$parameter});
  337. print "\n";
  338. }
  339. }
  340. foreach $section (@{$args{'sectionlist'}}) {
  341. print "\n\@strong{$section:} " if $section ne $section_default;
  342. $args{'sections'}{$section} =~ s:([{}]):\@\1:gs;
  343. output_highlight($args{'sections'}{$section});
  344. }
  345. print "\@end deftypefun\n\n";
  346. }
  347. # output in html
  348. sub output_html {
  349. my %args = %{$_[0]};
  350. my ($parameter, $section);
  351. my $count;
  352. print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>\n";
  353. print "<i>".$args{'functiontype'}."</i>\n";
  354. print "<b>".$args{'function'}."</b>\n";
  355. print "(";
  356. $count = 0;
  357. foreach $parameter (@{$args{'parameterlist'}}) {
  358. print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
  359. if ($count != $#{$args{'parameterlist'}}) {
  360. $count++;
  361. print ", ";
  362. }
  363. }
  364. print ")\n";
  365. print "<h3>Arguments</h3>\n";
  366. print "<dl>\n";
  367. foreach $parameter (@{$args{'parameterlist'}}) {
  368. print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
  369. print "<dd>";
  370. output_highlight($args{'parameters'}{$parameter});
  371. }
  372. print "</dl>\n";
  373. foreach $section (@{$args{'sectionlist'}}) {
  374. print "<h3>$section</h3>\n";
  375. print "<ul>\n";
  376. output_highlight($args{'sections'}{$section});
  377. print "</ul>\n";
  378. }
  379. print "<hr>\n";
  380. }
  381. # output in tex
  382. sub output_tex {
  383. my %args = %{$_[0]};
  384. my ($parameter, $section);
  385. my $count;
  386. my $func = $args{'function'};
  387. my $param;
  388. my $param2;
  389. my $sec;
  390. my $check;
  391. my $type;
  392. $func =~ s/_/\\_/g;
  393. print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\n";
  394. $type = $args{'functiontype'};
  395. $type =~ s/_/\\_/g;
  396. print "{\\it ".$type."}\n";
  397. print "{\\bf ".$func."}\n";
  398. print "(";
  399. $count = 0;
  400. foreach $parameter (@{$args{'parameterlist'}}) {
  401. $param = $args{'parametertypes'}{$parameter};
  402. $param2 = $parameter;
  403. $param =~ s/_/\\_/g;
  404. $param2 =~ s/_/\\_/g;
  405. print "{\\it ".$param."} {\\bf ".$param2."}";
  406. if ($count != $#{$args{'parameterlist'}}) {
  407. $count++;
  408. print ", ";
  409. }
  410. }
  411. print ")\n";
  412. print "\n{\\large{Arguments}}\n";
  413. print "\\begin{itemize}\n";
  414. $check=0;
  415. foreach $parameter (@{$args{'parameterlist'}}) {
  416. $param1 = $args{'parametertypes'}{$parameter};
  417. $param1 =~ s/_/\\_/g;
  418. $param2 = $parameter;
  419. $param2 =~ s/_/\\_/g;
  420. $check = 1;
  421. print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n";
  422. # print "\n";
  423. $param3 = $args{'parameters'}{$parameter};
  424. $param3 =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
  425. $out = just_highlight($param3);
  426. $out =~ s/_/\\_/g;
  427. print $out;
  428. }
  429. if ($check==0) {
  430. print "\\item void\n";
  431. }
  432. print "\\end{itemize}\n";
  433. foreach $section (@{$args{'sectionlist'}}) {
  434. $sec = $section;
  435. $sec =~ s/_/\\_/g;
  436. $sec =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
  437. print "\n{\\large{$sec}}\\\\\n";
  438. print "\\begin{rmfamily}\n";
  439. $sec = $args{'sections'}{$section};
  440. $sec =~ s/\\:/:/g;
  441. $sec =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
  442. $sec =~ s/->/\$\\rightarrow\$/g;
  443. $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g;
  444. $out = just_highlight($sec);
  445. $out =~ s/_/\\_/g;
  446. print $out;
  447. print "\\end{rmfamily}\n";
  448. }
  449. print "\n";
  450. }
  451. # output in sgml DocBook
  452. sub output_sgml {
  453. my %args = %{$_[0]};
  454. my ($parameter, $section);
  455. my $count;
  456. my $id;
  457. $id = $args{'module'}."-".$args{'function'};
  458. $id =~ s/[^A-Za-z0-9]/-/g;
  459. print "<refentry>\n";
  460. print "<refmeta>\n";
  461. print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
  462. print "</refmeta>\n";
  463. print "<refnamediv>\n";
  464. print " <refname>".$args{'function'}."</refname>\n";
  465. print " <refpurpose>\n";
  466. print " ".$args{'purpose'}."\n";
  467. print " </refpurpose>\n";
  468. print "</refnamediv>\n";
  469. print "<refsynopsisdiv>\n";
  470. print " <title>Synopsis</title>\n";
  471. print " <funcsynopsis>\n";
  472. print " <funcdef>".$args{'functiontype'}." ";
  473. print "<function>".$args{'function'}." ";
  474. print "</function></funcdef>\n";
  475. # print "<refsect1>\n";
  476. # print " <title>Synopsis</title>\n";
  477. # print " <funcsynopsis>\n";
  478. # print " <funcdef>".$args{'functiontype'}." ";
  479. # print "<function>".$args{'function'}." ";
  480. # print "</function></funcdef>\n";
  481. $count = 0;
  482. if ($#{$args{'parameterlist'}} >= 0) {
  483. foreach $parameter (@{$args{'parameterlist'}}) {
  484. print " <paramdef>".$args{'parametertypes'}{$parameter};
  485. print " <parameter>$parameter</parameter></paramdef>\n";
  486. }
  487. } else {
  488. print " <void>\n";
  489. }
  490. print " </funcsynopsis>\n";
  491. print "</refsynopsisdiv>\n";
  492. # print "</refsect1>\n";
  493. # print parameters
  494. print "<refsect1>\n <title>Arguments</title>\n";
  495. # print "<para>\nArguments\n";
  496. if ($#{$args{'parameterlist'}} >= 0) {
  497. print " <variablelist>\n";
  498. foreach $parameter (@{$args{'parameterlist'}}) {
  499. print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
  500. print " <listitem>\n <para>\n";
  501. $lineprefix=" ";
  502. output_highlight($args{'parameters'}{$parameter});
  503. print " </para>\n </listitem>\n </varlistentry>\n";
  504. }
  505. print " </variablelist>\n";
  506. } else {
  507. print " <para>\n None\n </para>\n";
  508. }
  509. print "</refsect1>\n";
  510. # print out each section
  511. $lineprefix=" ";
  512. foreach $section (@{$args{'sectionlist'}}) {
  513. print "<refsect1>\n <title>$section</title>\n <para>\n";
  514. # print "<para>\n$section\n";
  515. if ($section =~ m/EXAMPLE/i) {
  516. print "<example><para>\n";
  517. }
  518. output_highlight($args{'sections'}{$section});
  519. # print "</para>";
  520. if ($section =~ m/EXAMPLE/i) {
  521. print "</para></example>\n";
  522. }
  523. print " </para>\n</refsect1>\n";
  524. }
  525. print "\n\n";
  526. }
  527. ##
  528. # output in man
  529. sub output_man {
  530. my %args = %{$_[0]};
  531. my ($parameter, $section);
  532. my $count;
  533. print ".\\\" DO NOT MODIFY THIS FILE! It was generated by gdoc.\n";
  534. print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{'module'} . "\" \"". $args{'module'} . "\"\n";
  535. print ".SH NAME\n";
  536. print $args{'function'};
  537. if ($args{'purpose'}) {
  538. print " \\- " . $args{'purpose'} . "\n";
  539. } else {
  540. print " \\- API function\n";
  541. }
  542. print ".SH SYNOPSIS\n";
  543. print ".B #include <". $args{'include'} . ">\n"
  544. if $args{'include'};
  545. print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n"
  546. if $args{'includefuncprefix'};
  547. print ".sp\n";
  548. print ".BI \"".$args{'functiontype'}." ".$args{'function'}."(";
  549. $count = 0;
  550. foreach $parameter (@{$args{'parameterlist'}}) {
  551. print $args{'parametertypes'}{$parameter}." \" ".$parameter." \"";
  552. if ($count != $#{$args{'parameterlist'}}) {
  553. $count++;
  554. print ", ";
  555. }
  556. }
  557. print ");\"\n";
  558. print ".SH ARGUMENTS\n";
  559. foreach $parameter (@{$args{'parameterlist'}}) {
  560. print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 12\n";
  561. $param = $args{'parameters'}{$parameter};
  562. $param =~ s/-/\\-/g;
  563. output_highlight($param);
  564. }
  565. foreach $section (@{$args{'sectionlist'}}) {
  566. print ".SH \"" . uc($section) . "\"\n";
  567. $sec = $args{'sections'}{$section};
  568. $sec =~ s/-/\\-/g;
  569. output_highlight($sec);
  570. }
  571. if ($args{'bugsto'}) {
  572. print ".SH \"REPORTING BUGS\"\n";
  573. print "Report bugs to <". $args{'bugsto'} . ">.\n";
  574. if ($args{'pkgname'}) {
  575. print $args{'pkgname'} . " home page: " .
  576. "http://www.gnu.org/software/" . $args{'module'} . "/\n";
  577. }
  578. print "General help using GNU software: http://www.gnu.org/gethelp/\n";
  579. }
  580. if ($args{'copyright'}) {
  581. print ".SH COPYRIGHT\n";
  582. print "Copyright \\(co ". $args{'copyright'} . ".\n";
  583. if ($args{'verbatimcopying'}) {
  584. print ".br\n";
  585. print "Copying and distribution of this file, with or without modification,\n";
  586. print "are permitted in any medium without royalty provided the copyright\n";
  587. print "notice and this notice are preserved.\n";
  588. }
  589. }
  590. if ($args{'seeinfo'}) {
  591. print ".SH \"SEE ALSO\"\n";
  592. print "The full documentation for\n";
  593. print ".B " . $args{'module'} . "\n";
  594. print "is maintained as a Texinfo manual. If the\n";
  595. print ".B info\n";
  596. print "and\n";
  597. print ".B " . $args{'module'} . "\n";
  598. print "programs are properly installed at your site, the command\n";
  599. print ".IP\n";
  600. print ".B info " . $args{'seeinfo'} . "\n";
  601. print ".PP\n";
  602. print "should give you access to the complete manual.\n";
  603. }
  604. }
  605. sub output_listfunc {
  606. my %args = %{$_[0]};
  607. print $args{'function'} . "\n";
  608. }
  609. ##
  610. # output in text
  611. sub output_text {
  612. my %args = %{$_[0]};
  613. my ($parameter, $section);
  614. print "Function = ".$args{'function'}."\n";
  615. print " return type: ".$args{'functiontype'}."\n\n";
  616. foreach $parameter (@{$args{'parameterlist'}}) {
  617. print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
  618. print " -> ".$args{'parameters'}{$parameter}."\n";
  619. }
  620. foreach $section (@{$args{'sectionlist'}}) {
  621. print " $section:\n";
  622. print " -> ";
  623. output_highlight($args{'sections'}{$section});
  624. }
  625. }
  626. ##
  627. # generic output function - calls the right one based
  628. # on current output mode.
  629. sub output_function {
  630. # output_html(@_);
  631. eval "output_".$output_mode."(\@_);";
  632. }
  633. ##
  634. # takes a function prototype and spits out all the details
  635. # stored in the global arrays/hsahes.
  636. sub dump_function {
  637. my $prototype = shift @_;
  638. if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
  639. $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
  640. $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
  641. $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
  642. $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/) {
  643. $return_type = $1;
  644. $function_name = $2;
  645. $args = $3;
  646. # print STDERR "ARGS = '$args'\n";
  647. foreach $arg (split ',', $args) {
  648. # strip leading/trailing spaces
  649. $arg =~ s/^\s*//;
  650. $arg =~ s/\s*$//;
  651. # print STDERR "SCAN ARG: '$arg'\n";
  652. @args = split('\s', $arg);
  653. # print STDERR " -> @args\n";
  654. $param = pop @args;
  655. # print STDERR " -> @args\n";
  656. if ($param =~ m/^(\*+)(.*)/) {
  657. $param = $2;
  658. push @args, $1;
  659. }
  660. if ($param =~ m/^(.*)(\[\])$/) {
  661. $param = $1;
  662. push @args, $2;
  663. }
  664. # print STDERR " :> @args\n";
  665. $type = join " ", @args;
  666. if ($parameters{$param} eq "" && $param != "void") {
  667. $parameters{$param} = "-- undescribed --";
  668. print STDERR "warning: $lineno: Function parameter '$param' not described in '$function_name'\n";
  669. }
  670. push @parameterlist, $param;
  671. $parametertypes{$param} = $type;
  672. # print STDERR "param = '$param', type = '$type'\n";
  673. }
  674. } else {
  675. print STDERR "warning: $lineno: Cannot understand prototype: '$prototype'\n" if (!($prototype =~ m,GSASL_VALID_MECHANISM_CHARACTERS,));
  676. return;
  677. }
  678. if ($function_only==0 || defined($function_table{$function_name})) {
  679. output_function({'function' => $function_name,
  680. 'module' => $modulename,
  681. 'sourceversion' => $sourceversion,
  682. 'include' => $include,
  683. 'includefuncprefix' => $includefuncprefix,
  684. 'bugsto' => $bugsto,
  685. 'pkgname' => $pkgname,
  686. 'copyright' => $copyright,
  687. 'verbatimcopying' => $verbatimcopying,
  688. 'seeinfo' => $seeinfo,
  689. 'functiontype' => $return_type,
  690. 'parameterlist' => \@parameterlist,
  691. 'parameters' => \%parameters,
  692. 'parametertypes' => \%parametertypes,
  693. 'sectionlist' => \@sectionlist,
  694. 'sections' => \%sections,
  695. 'purpose' => $function_purpose
  696. });
  697. }
  698. }
  699. ######################################################################
  700. # main
  701. # states
  702. # 0 - normal code
  703. # 1 - looking for function name
  704. # 2 - scanning field start.
  705. # 3 - scanning prototype.
  706. $state = 0;
  707. $section = "";
  708. $doc_special = "\@\%\$\#";
  709. $doc_start = "^/\\*\\*\$";
  710. $doc_end = "\\*/";
  711. $doc_com = "\\s*\\*\\s*";
  712. $doc_func = $doc_com."(\\w+):?";
  713. $doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):\\s*(.*)";
  714. $doc_content = $doc_com."(.*)";
  715. %constants = ();
  716. %parameters = ();
  717. @parameterlist = ();
  718. %sections = ();
  719. @sectionlist = ();
  720. $contents = "";
  721. $section_default = "Description"; # default section
  722. $section = $section_default;
  723. $lineno = 0;
  724. foreach $file (@ARGV) {
  725. if (!open(IN,"<$file")) {
  726. print STDERR "Error: Cannot open file $file\n";
  727. next;
  728. }
  729. while (<IN>) {
  730. $lineno++;
  731. if ($state == 0) {
  732. if (/$doc_start/o) {
  733. $state = 1; # next line is always the function name
  734. }
  735. } elsif ($state == 1) { # this line is the function name (always)
  736. if (/$doc_func/o) {
  737. $function = $1;
  738. $state = 2;
  739. if (/-\s*(.*)/) {
  740. $function_purpose = $1;
  741. } else {
  742. $function_purpose = "";
  743. }
  744. if ($verbose) {
  745. print STDERR "Info($lineno): Scanning doc for $function\n";
  746. }
  747. } else {
  748. print STDERR "warning: $lineno: Cannot understand $_ on line $lineno",
  749. " - I thought it was a doc line\n";
  750. $state = 0;
  751. }
  752. } elsif ($state == 2) { # look for head: lines, and include content
  753. if (/$doc_sect/o) {
  754. $newsection = $1;
  755. $newcontents = $2;
  756. if ($contents ne "") {
  757. dump_section($section, $contents);
  758. $section = $section_default;
  759. }
  760. $contents = $newcontents;
  761. if ($contents ne "") {
  762. $contents .= "\n";
  763. }
  764. $section = $newsection;
  765. } elsif (/$doc_end/) {
  766. if ($contents ne "") {
  767. dump_section($section, $contents);
  768. $section = $section_default;
  769. $contents = "";
  770. }
  771. # print STDERR "end of doc comment, looking for prototype\n";
  772. $prototype = "";
  773. $state = 3;
  774. } elsif (/$doc_content/) {
  775. # miguel-style comment kludge, look for blank lines after
  776. # @parameter line to signify start of description
  777. if ($1 eq "" && $section =~ m/^@/) {
  778. dump_section($section, $contents);
  779. $section = $section_default;
  780. $contents = "";
  781. } else {
  782. $contents .= $1."\n";
  783. }
  784. } else {
  785. # i dont know - bad line? ignore.
  786. print STDERR "warning: $lineno: Bad line: $_";
  787. }
  788. } elsif ($state == 3) { # scanning for function { (end of prototype)
  789. if (m#\s*/\*\s+MACDOC\s*#io) {
  790. # do nothing
  791. }
  792. elsif (/([^\{]*)/) {
  793. $prototype .= $1;
  794. }
  795. if (/\{/) {
  796. $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
  797. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
  798. $prototype =~ s@^ +@@gos; # strip leading spaces
  799. dump_function($prototype);
  800. $function = "";
  801. %constants = ();
  802. %parameters = ();
  803. %parametertypes = ();
  804. @parameterlist = ();
  805. %sections = ();
  806. @sectionlist = ();
  807. $prototype = "";
  808. $state = 0;
  809. }
  810. }
  811. }
  812. }