-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathidlwave_catalog
executable file
·214 lines (197 loc) · 6.18 KB
/
idlwave_catalog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/usr/bin/perl -w
#
# idlwave_catalog
#
# Program to create IDLWAVE library catalogs.
#
# (c) 2002-2004 J.D. Smith <[email protected]>
#
# Scans all IDL ".pro" files at the current level and recursively in
# all directories beneath it, compiling a catalog of information for
# each directory with any routines found, stored in a file named
# ".idlwave_catalog". Any such "library catalogs" on the IDL path
# will be automatically loaded into IDLWAVE.
#
# Usage: idlwave_catalog [-l] [-v] [-d] [-s] [-f] [-x PATTERN] [-h] libname
# libname - Unique name of the catalog (4 or more alphanumeric
# characters -- only 10 will be shown in routine info).
# -l - Scan local directory only, otherwise recursively
# catalog all directories at or beneath this one.
# -v - Print verbose information.
# -d - Instead of scanning, delete all .idlwave_catalog files
# here or below.
# -s - Be silent.
# -f - Force overwriting any catalogs found with a different
# library name.
# -x - Skip directories matching the passed pattern
# -h - Print this usage.
#
# You can arrange to have this script run automatically to update
# libraries which change frequently. The name will be used to refer
# to the routines collectively, so make it unique and descriptive
# (without spaces). E.g. "NasaLib". A file named .idlwave_catalog
# will be created in each directory with ".pro" routine files.
#
# $Id: idlwave_catalog,v 1.5 2004/10/13 20:34:07 jdsmith Exp $
use Getopt::Std;
$opt_l=$opt_s=$opt_f=$opt_v=$opt_d=$opt_h=0;
getopt('x');
$opt_v=0 if $opt_s;
usage() if $opt_h;
unless ($opt_d) {
$libname=shift or usage();
if (length($libname)<=3 or ($libname=~tr/A-Za-z0-9_//c)) {
die
"LibName must be alphanumeric, >3 characters, and contains no spaces.\n"
}
}
$cat=".idlwave_catalog";
unless ($opt_l) {
use File::Find;
find(sub{
if (/\Q$cat\E$/) {
if ($opt_d) {
if (unlink $_) {
print "Removing catalog $File::Find::name\n" if $opt_v;
} else {
warn "Can't remove catalog $File::Find::name: $!\n"
unless $opt_s;
}
} else {
$dirs{$File::Find::dir}{cat}=libname($_);
}
return;
}
return if $opt_d;
return unless -f and /\.pro$/i;
parsefile($File::Find::dir, $_);
}, '.');
} else { #Just process the local directory
opendir(DIR,".") || die "Can't open this directory: $!";
if (-f $cat) {
if ($opt_d) {
if (unlink $cat) {
print "Removing catalog $cat\n" if $opt_v;
} else {
warn "Can't remove catalog $cat: $!\n" unless $opt_s;
}
} else {
$dirs{"."}{cat}=libname($cat);
}
}
unless($opt_d) {
foreach (grep {-f and /\.pro$/i} readdir(DIR)) {
parsefile(".",$_);
}
}
closedir DIR;
}
exit if $opt_d; #Nothing more to do
foreach $dir (keys %dirs) {
if ($opt_x and $dir=~/$opt_x/) {
print "Skipping $dir\n" if $opt_v;
next;
}
next if !defined($dirs{$dir}{pro}) || !$dirs{$dir}{pro};
print "Cataloging $dir\n" if $opt_v;
if (exists $dirs{$dir}{cat} && $dirs{$dir}{cat} ne $libname) {
if ($opt_f) {
warn "Overwriting existing \"$dirs{$dir}{cat}\" catalog in " .
($dir eq "."?"this directory":$dir) . ".\n" unless $opt_s;
} else {
warn "Skipping existing \"$dirs{$dir}{cat}\" catalog in " .
($dir eq "."?"this directory":$dir) .
" (-f overrides).\n" unless $opt_s;
next;
}
}
unless (open CATALOG, ">$dir/$cat") {
warn "Can't open catalog file $dir/$cat for writing... skipping\n";
next;
}
$time=localtime();
print CATALOG <<EOF;
;;
;; IDLWAVE catalog for library $libname
;; Automatically Generated -- do not edit.
;; Created by idlwave_catalog on $time
;;
(setq idlwave-library-catalog-libname "$libname")
(setq idlwave-library-catalog-routines
EOF
print CATALOG " '(".join("\n ",@{$dirs{$dir}{pro}});
print CATALOG "))\n";
}
if($opt_v && !%dirs) {
print $opt_l?"Current directory contains no .pro files.\n":
"No directories with .pro files found.\n";
}
sub parsefile {
my ($dir,$file)=@_;
my ($call,@kwds,@args,@entries);
open FILE, $file;
while (<FILE>) {
next unless
/^[ \t]*(pro|function)[ \t]+(?:([a-zA-Z0-9\$_]+)::)?([a-zA-Z0-9\$_]+)/i;
($type,$class,$name)=(lc($1) eq "pro"?"pro":"fun",$2,$3);
$call="";
@kwds=@args=();
while (/[ \t]*\$\s*(;.*)?[\r\n]+/) { # Continuations
$call.=$`;
$_=<FILE>;
while (/^\s*(;.*)?[\r\n]+/) {$_=<FILE>} #skip blank or comment lines
}
s/\s*(;.*)?[\r\n]+//;
$call.=$_;
while($call=~/,\s*([a-zA-Z][a-zA-Z0-9\$_]*|(?:_ref)?_extra)\s*(=)?/gi) {
if ($2) {
push @kwds, $1;
} else {
push @args, $1;
}
}
$is_func=$type eq "fun";
@kwds=sort {lc($a) cmp lc($b)} @kwds;
# Name type class
push @{$dirs{$dir}{pro}},
qq{("$name" $type } . ($class?qq("$class"):"nil") .
# Source (source-type file dir library-name)
qq< (lib "$file" nil "$libname") > .
#Calling sequence
'"' . ($is_func?"Result = ":"") . ($class?'Obj ->[%s::]':"") . '%s' .
# Argument list
(@args?($is_func?"(":", ") .
join(", ",@args) .
($is_func?')':""):"") . '"' .
# Keywords
' (nil' . (@kwds?' ("'.join('") ("', @kwds).'")':"") . "))";
}
close FILE;
return
}
sub libname {
my $file=shift;
open FILE, $file;
while (<FILE>) {
return $1 if /\(setq idlwave-library-catalog-libname "([^"]+)"\)/;
}
"";
}
sub usage {
print <<EOF;
Usage: idlwave_catalog [-l] [-v] [-d] [-s] [-f] [-h] [-x PATTERN] libname
libname - Unique name of the catalog (4 or more alphanumeric
characters -- only 10 will be shown in routine info).
-l - Scan local directory only, otherwise recursively
catalog all directories at or beneath this one.
-v - Print verbose information.
-d - Instead of scanning, delete all .idlwave_catalog files
here or below.
-s - Be silent.
-f - Force overwriting any catalogs found with a different
library name.
-x - Skip directories matching the passed pattern.
-h - Print this usage.
EOF
exit;
}