tango 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/usr/bin/perl
  2. use strict;
  3. #use vars qw(\$version \$help \$verbose \$lang \@includes \%ents);
  4. use Getopt::Long;
  5. sub print_revision ($$);
  6. sub print_usage ($$);
  7. sub print_help ($$);
  8. sub slurp ($$$@);
  9. my $PROGNAME = "tango";
  10. my $REVISION = '$Revision$ ';
  11. $REVISION =~ s/^\$Revision: //;
  12. $REVISION =~ s/ \$ $//;
  13. my $PACKAGE = 'Nagios Plugins';
  14. my $RELEASE = '1.3';
  15. my $WARRANTY = "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\ncopies of the plugins under the terms of the GNU General Public License.\nFor more information about these matters, see the file named COPYING.\n";
  16. my $version = undef;
  17. my $help = undef;
  18. my $verbose = undef;
  19. my $lang = undef;
  20. my $follow = undef;
  21. my @INCLUDE = undef;
  22. Getopt::Long::Configure('bundling');
  23. GetOptions
  24. ("V" => \$version, "version" => \$version,
  25. "h" => \$help, "help" => \$help,
  26. "v" => \$verbose, "verbose" => \$verbose,
  27. "f" => \$follow, "follow!" => \$follow,
  28. "l=s" => \$lang, "language=s" => \$lang,
  29. "I=s" => \@INCLUDE);
  30. if ($help) {
  31. print_help ($PROGNAME,$REVISION);
  32. exit 0;
  33. }
  34. if ($version) {
  35. print_revision ($PROGNAME,$REVISION);
  36. exit 0;
  37. }
  38. if (!defined($lang)) {
  39. print_usage ($PROGNAME,$REVISION);
  40. exit 1;
  41. }
  42. my $t;
  43. my @files;
  44. my $file;
  45. my $key;
  46. my $ent;
  47. my $cmd;
  48. my $dir;
  49. # first step is to get a set of defines in effect
  50. # we do this with gcc preprocessor
  51. #
  52. # first, assemble the command
  53. my $cmd = "/usr/bin/gcc -E -dM";
  54. foreach $dir (@INCLUDE) {
  55. $cmd .= " -I $dir" if ($dir) ;
  56. }
  57. # add the file(s) to process
  58. while ($file = shift) {
  59. push @files, $file;
  60. $cmd .= " $file";
  61. }
  62. # then execute the command, storing defines in %main::ents
  63. open T, "$cmd |";
  64. while (<T>) {
  65. next if (m|\#define\s+[^\s\(]+\(|);
  66. if (m|\#define\s+(\S+)\s+(\"?)(.*?)\2$|) {
  67. $key = $1;
  68. $ent = $3;
  69. $ent =~ s|\\n\\n|</para>\n\n<para>|msg;
  70. $ent =~ s|\\n|\n|msg;
  71. $main::ents{$key} = $ent;
  72. }
  73. }
  74. # then we slurp the file to fetch the XML
  75. my $xml = "";
  76. foreach $file (@files) {
  77. $xml .= slurp ($lang, $follow, $file, @INCLUDE);
  78. }
  79. # finally substitute the defines as XML entities
  80. foreach $key (keys %main::ents) {
  81. $xml =~ s/\&$key\;/$main::ents{$key}/msg;
  82. }
  83. # and print the result
  84. print $xml;
  85. exit 0;
  86. sub print_revision ($$) {
  87. my $PROGNAME = shift;
  88. my $REVISION = shift;
  89. print "$PROGNAME ($PACKAGE $RELEASE) $REVISION\n";
  90. print "$WARRANTY";
  91. }
  92. sub print_usage ($$) {
  93. my $PROGNAME = shift;
  94. my $REVISION = shift;
  95. print qq"\n$PROGNAME -l <language> [options] file [...]\n"
  96. }
  97. sub print_help ($$) {
  98. my $PROGNAME = shift;
  99. my $REVISION = shift;
  100. print_usage ($PROGNAME, $REVISION);
  101. print qq"
  102. Options:
  103. -l, --language=STRING
  104. Currently supported languages are C and perl
  105. ";
  106. }
  107. sub slurp ($$$@) {
  108. no strict 'refs';
  109. my ($lang, $follow, $file, @INCLUDE) = @_;
  110. my $xml = "";
  111. my $block;
  112. my $dir = "";
  113. my $ostat;
  114. my $descriptor = 'T' . int(rand 100000000);
  115. if ($file !~ m|^[\.\/\\]|) {
  116. foreach $dir (@INCLUDE) {
  117. if ($ostat = open $descriptor, "<$dir/$file") {
  118. push @main::includes, $file;
  119. last;
  120. }
  121. }
  122. } else {
  123. $ostat = open $descriptor, "<$file";
  124. push @main::includes, $file if $ostat;
  125. }
  126. return "" unless $ostat;
  127. if ($lang eq 'C') {
  128. while (<$descriptor>) {
  129. $block = $_;
  130. if ($follow && m|^\s*\#\s*include\s+[<"]([^\">]+)[">]|) {
  131. $xml .= slurp ($lang, $follow, $1, @INCLUDE) unless (in (@main::includes, $1));
  132. }
  133. if ($block =~ m|(\S+)\s+(\S+)\s*(\([^\)]*\));|) {
  134. $main::ents{"PROTO_$2"} = "$1 $2 $3";
  135. }
  136. if ($block =~ m|//|) { # C++ style one-line comment
  137. if (m|//\@\@-(.*)-\@\@|) {
  138. $xml .= $1;
  139. }
  140. }
  141. if ($block =~ m|/\*|) { # normal C comments
  142. while ($block !~ m|/\*(.*)\*/|ms) {
  143. $block .= <$descriptor>;
  144. }
  145. if ($block =~ m|\@\@-(.*)-\@\@|ms) {
  146. $xml .= $1;
  147. } elsif ($block =~ m|\@s*-(.*)\s*-\@|ms) {
  148. $key = $1;
  149. while ($block !~ m|\*/\s*([^\;]+);|ms) {
  150. $block .= <$descriptor>;
  151. }
  152. if ($block =~ m|\*/\s*([^\;]+);|ms) {
  153. $main::ents{$key} = $1;
  154. }
  155. }
  156. }
  157. }
  158. }
  159. close $descriptor;
  160. return $xml;
  161. }
  162. sub in () {
  163. my $el = pop;
  164. foreach $key (@_) {
  165. return 1 if ($key eq $el);
  166. }
  167. return 0;
  168. }
  169. sub CommentStart ($) {
  170. my $lang = shift;
  171. if ($lang eq 'C') {
  172. return '/*';
  173. } elsif ($lang == 'perl') {
  174. return '#';
  175. } else {
  176. return undef;
  177. }
  178. }
  179. # if ($_ =~ m/^\s*\#\s*define\s+([-_a-zA-Z0-9]+)\s+(.*)\s*$/) {
  180. # $key = $1;
  181. # $main::ents{$key} = "$2";
  182. # while (($main::ents{$key} =~ s/\\\s*$//s) && ($block = <$descriptor>)) {
  183. # $main::ents{$key} .= $block;
  184. # }
  185. # $main::ents{$key} =~ s/"(.*)"$/$1/s;
  186. # $main::ents{$key} =~ s/\s+\/[\/\*].*$//s;
  187. # }
  188. ### Local Variables: ;;;
  189. ### tab-width: 2 ;;;
  190. ### perl-indent-level: 2 ;;;
  191. ### End: ;;;