source: trunk/gsdl/perllib/plugins/SRCPlug.pm@ 10254

Last change on this file since 10254 was 10254, checked in by kjdon, 19 years ago

added 'use strict' to all plugins, and made modifications (mostly adding 'my') to make them compile

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1###########################################################################
2#
3# SRCPlug.pm -- source code plugin
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright (C) 1999 New Zealand Digital Library Project
10#
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 2 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, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
26# John McPherson Nov 2000
27# originally based on TEXTPlug
28
29# filename is currently used for Title ( optionally minus some prefix )
30
31# Current languages:
32# text: READMEs/Makefiles
33# C/C++ (currently extracts #include statements and C++ class decls)
34# Perl (currently only done as text)
35# Shell (currently only done as text)
36
37# 12/05/02 Added usage datastructure - John Thompson
38
39package SRCPlug;
40
41use BasPlug;
42use parsargv;
43
44use strict;
45no strict 'refs'; # allow filehandles to be variables and viceversa
46
47sub BEGIN {
48 @SRCPlug::ISA = ('BasPlug');
49}
50
51my $arguments =
52 [ { 'name' => "process_exp",
53 'desc' => "{BasPlug.process_exp}",
54 'type' => "regexp",
55 'deft' => &get_default_process_exp(),
56 'reqd' => "no" } ,
57 { 'name' => "block_exp",
58 'desc' => "{BasPlug.block_exp}",
59 'type' => "regexp",
60 'deft' => &get_default_block_exp(),
61 'reqd' => "no" },
62 { 'name' => "remove_prefix",
63 'desc' => "{SRCPlug.remove_prefix}",
64 'type' => "regexp",
65 'deft' => "^.*[/\\]",
66 'reqd' => "no" } ];
67
68my $options = { 'name' => "SRCPlug",
69 'desc' => "{SRCPlug.desc}",
70 'abstract' => "no",
71 'inherits' => "yes",
72 'args' => $arguments };
73
74
75sub new {
76 my ($class) = shift (@_);
77 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
78 push(@$pluginlist, $class);
79
80 if(defined $arguments){ push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});}
81 if(defined $options) { push(@{$hashArgOptLists->{"OptList"}},$options)};
82
83 my $self = (defined $hashArgOptLists)? new BasPlug($pluginlist,$inputargs,$hashArgOptLists): new BasPlug($pluginlist,$inputargs);
84
85 return bless $self, $class;
86}
87
88sub get_default_block_exp {
89 my $self = shift (@_);
90
91 return q^(?i)\.(o|obj|a|so|dll)$^;
92}
93
94sub get_default_process_exp {
95 my $self = shift (@_);
96
97# return q^(?i)\.te?xt$^;
98 return q^(Makefile.*|README.*|(?i)\.(c|cc|cpp|C|h|hpp|pl|pm|sh))$^;
99}
100
101
102
103# do plugin specific processing of doc_obj
104sub process {
105 my $self = shift (@_);
106 my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
107 my $outhandle = $self->{'outhandle'};
108
109 print STDERR "<Processing n='$file' p='SRCPlug'>\n" if ($gli);
110 print $outhandle "SRCPlug: processing $file\n"
111 if $self->{'verbosity'} > 1;
112
113 my $cursection = $doc_obj->get_top_section();
114
115 my $filetype="text"; # Makefiles, READMEs, ...
116 if ($file =~ /\.(cc|h|cpp|C)$/) {$filetype="C++";} # assume all .h files...
117 elsif ($file =~ /\.c$/) {$filetype="C";}
118 elsif ($file =~ /\.p(l|m)$/) {$filetype="perl";}
119 elsif ($file =~ /\.sh$/) {$filetype="sh";}
120
121 # modify '<' and '>' for GML... (even though inside <pre> tags!!)
122 $$textref =~ s/</&lt;/g;
123 $$textref =~ s/>/&gt;/g;
124 $$textref =~ s/_/&#95;/g;
125 # try _escape_text($text) from doc.pm....
126
127 # don't want mg to turn escape chars into actual values
128 $$textref =~ s/\\/\\\\/g;
129
130 # use filename (minus any prefix) as the title.
131 my $title;
132 if ($self->{'remove_prefix' ne ""}) {
133 ($title = $file) =~ s/^$self->{'remove_prefix'}//;
134 } else {
135 ($title = $file) =~ s@^.*[/\\]@@; # remove pathname by default
136 }
137 $doc_obj->add_utf8_metadata ($cursection, "Title", $title);
138 $doc_obj->add_metadata ($cursection, "FileFormat", "SRC");
139
140 # remove the gsdl prefix from the filename
141 my $relative_filename=$file;
142 $relative_filename =~ s@^.*?gsdl[/\\]@@;
143 $doc_obj->add_utf8_metadata ($cursection, "filename", $relative_filename);
144
145 # class information from .h and .cc and .C and .cpp files
146 if ($filetype eq "C++")
147 {
148 process_c_plus_plus($textref,$pluginfo, $base_dir,
149 $file, $metadata, $doc_obj);
150 } elsif ($filetype eq "C")
151 {
152 get_includes_metadata($textref, $doc_obj);
153 }
154
155
156 # default operation...
157 # insert preformat tags and add text to document object
158 $doc_obj->add_utf8_text($cursection, "<pre>\n$$textref\n</pre>");
159
160 return 1;
161}
162
163
164
165
166sub get_includes_metadata {
167 my ($textref, $doc_obj) = @_;
168
169 my $topsection = $doc_obj->get_top_section();
170
171 # Get '#include' directives for metadata
172 if ($$textref !~ /\#\s*include\b/) {
173 return;
174 }
175
176 my @includes =
177 ($$textref =~ m/^\s*\#\s*include\s*(?:\"|&lt;)(.*?)(?:\"|&gt;)/mg);
178
179 my $incs_done_ref=$doc_obj->get_metadata($topsection, "includes");
180 my @incs_done;
181 if (defined($incs_done_ref)) {
182 @incs_done=@$incs_done_ref;
183 } else {
184 @incs_done=();
185 }
186
187 foreach my $inc (@includes) {
188 # add entries, but only if they don't already exist
189 if (!join('', map {$_ eq "$inc"?1:""} @incs_done)) {
190 push @incs_done, $inc;
191 $doc_obj->add_utf8_metadata($topsection, "includes", $inc);
192 }
193 }
194}
195
196
197
198sub process_c_plus_plus {
199 my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_;
200
201 my $topsection = $doc_obj->get_top_section();
202
203
204 # Check for include metadata
205 get_includes_metadata($textref, $doc_obj);
206
207
208
209 # Get class declarations (but not forward declarations...) as metadata
210 if ($$textref =~ /\bclass\b/ ) {
211 my $classnames=$$textref;
212
213 # remove commented lines
214 $classnames =~ s@/\*.*?\*/@@sg;
215 $classnames =~ s@//.*$@@mg;
216 while ($classnames =~ /\bclass\b/) {
217
218 # delete all lines up to the next "class"
219 while ($classnames !~ /^[^\n]*\bclass\b[^\n]*\n/)
220 {$classnames =~ s/.*\n//;}
221
222# $classnames =~ s/^([^c][^l])*(.)?$//mg; # delete unneccessary lines
223
224 # get the line including the next "class" and remove it from
225 # our tmp text.
226 $classnames =~ s/^(.*\bclass\b.*)$//m;
227
228 # don't index if merely a reference/fwd decl. of another class
229 if ($1 !~ /(friend\Wclass)|(class\W\w+\W?\;)|(\/\/.*class)/) {
230 # $1 is still the whole line - eg:
231 # "class StaffSystem: public BaseStaffSystem"
232 my $wholeline=$1;
233 my $classname=$1;
234 $classname =~ s/.*class\W(\w+).*/$1/;
235 my $classes=$doc_obj->get_metadata($topsection, "class");
236 foreach my $elem (@$classes) {
237 if ("$elem" eq "$classname") {goto class_done;}
238 }
239 $doc_obj->add_utf8_metadata($topsection, "class", $classname);
240 class_done:
241 $doc_obj->add_utf8_metadata($topsection, "classdecl", $wholeline);
242 }
243 }
244 } # end of "class"
245
246 return 1;
247}
248
2491;
250
Note: See TracBrowser for help on using the repository browser.