our
$VERSION
=
"0.01"
;
our
$DEBUG
= 0;
sub
parse
{
for
my
$file
(
@_
) {
parse_file(
$file
);
}
fix_alternates();
return
1;
}
my
%PACKAGES
;
my
%EVENTS
;
sub
parse_file
{
my
(
$file
) =
@_
;
print
STDERR
"Parsing file: '$file'\n"
if
$DEBUG
;
my
$package
;
open
(
my
$FILE
,
"<$file"
) or
die
"Can't open $file: $!"
;
while
(<
$FILE
>) {
if
(/\(\@\)PACKAGE:\s*(.*\S)\s*$/) {
$package
= $1;
print
STDERR
"Found package: '$package'\n"
if
$DEBUG
;
if
(not
exists
$PACKAGES
{
$package
}) {
$PACKAGES
{
$package
} = {
files
=> [],
methods
=> {},
abstract
=>
''
,
description
=>
''
,
};
}
push
@{
$PACKAGES
{
$package
}->{files}},
$file
.
"[$.]"
;
my
$abstract
= <
$FILE
>;
if
(
$abstract
=~ s/^\s*(
if
(
$abstract
) {
die
"Package $package (${file} [$.]) found a second abstract"
if
length
$PACKAGES
{
$package
}->{abstract} > 0;
$PACKAGES
{
$package
}->{abstract} =
$abstract
;
while
(<
$FILE
>) {
if
( s/^\s*(
$PACKAGES
{
$package
}->{description} .= (
$_
eq
''
?
"\n"
:
$_
);
}
else
{
last
;
}
}
}
}
}
elsif
(/\(\@\)METHOD:\s*(.*\S)\s*$/) {
my
$method
= $1;
$method
=~ s/\((.*)\)//;
my
$methodprototype
= $1;
$method
=~ s/\s+.*//;
my
$methoddescr
=
''
;
my
@alternates
;
die
"Method $method (${file} [$.]) not in a package"
if
not
defined
$package
;
print
STDERR
"Found method: '${package}::${method}'\n\tPrototype: $methodprototype\n"
if
$DEBUG
;
die
"Method $method (${file} [$.]) already defined in package $package"
if
exists
$PACKAGES
{
$package
}->{methods}->{
$method
};
while
(<
$FILE
>) {
if
(/\(\@\)METHOD:\s*(.*\S)\s*$/) {
my
$alternate
= $1;
$alternate
=~ s/\(.*\)//;
$alternate
=~ s/\s+.*//;
push
@alternates
,
$alternate
;
print
STDERR
"\tFound alternate method in package $package: '${alternate}'\n"
if
$DEBUG
;
}
elsif
( s/^\s*(
$methoddescr
.= (
$_
eq
''
?
"\n"
:
$_
);
}
else
{
$PACKAGES
{
$package
}->{methods}->{
$method
} = {
prototype
=>
$methodprototype
,
description
=>
$methoddescr
,
alternates
=> \
@alternates
,
};
last
;
}
}
}
elsif
(/\(\@\)EVENT:\s*(.*\S)\s*$/) {
my
$event
= $1;
$event
=~ s/\((.*)\)//;
my
$eventprototype
= $1;
$event
=~ s/\s+.*//;
my
$eventdescr
=
''
;
my
@packages
;
print
STDERR
"Found event: '$event'\n\tPrototype: $eventprototype\n"
if
$DEBUG
;
while
(<
$FILE
>) {
if
(/\(\@\)APPLIES_TO:\s*(.*\S)\s*$/) {
my
$applies
= $1;
@packages
=
split
(/\s*,\s*/,
$applies
);
print
STDERR
"\tApplies to: $applies\n"
if
$DEBUG
;
}
elsif
( s/^\s*(
$eventdescr
.= (
$_
eq
''
?
"\n"
:
$_
);
}
else
{
if
(
scalar
@packages
== 0) {
die
"Event $event ($file) found that applies to no packages"
;
}
else
{
for
my
$pack
(
@packages
) {
$pack
=
"Win32::GUI::"
.
$pack
unless
$pack
eq
'*'
;
my
$frompackage
=
defined
$package
?
$package
:
$pack
;
my
$tmpevent
=
$event
;
if
(
$frompackage
ne
$pack
) {
$tmpevent
.=
" ($frompackage)"
;
}
die
"Event $event (${file} [$.]) alredy defined in package($pack)"
if
exists
$EVENTS
{
$pack
}->{
$tmpevent
};
$EVENTS
{
$pack
}->{
$tmpevent
} = {
name
=>
$event
,
prototype
=>
$eventprototype
,
description
=>
$eventdescr
,
file
=>
$file
.
"[$.]"
,
};
}
}
last
;
}
}
}
}
close
(
$FILE
);
return
1;
}
sub
get_package_list
{
my
@tmp
=
sort
{
uc
$a
cmp
uc
$b
}
keys
%PACKAGES
;
return
@tmp
;
}
sub
get_package_abstract
{
my
$package
=
shift
;
return
$PACKAGES
{
$package
}->{abstract};
}
sub
get_package_description
{
my
$package
=
shift
;
return
$PACKAGES
{
$package
}->{description};
}
sub
get_package_method_list
{
my
$package
=
shift
;
return
sort
newfirst
keys
%{
$PACKAGES
{
$package
}->{methods}};
}
sub
newfirst
{
return
(
$a
=~ /^new/) ? -1 :
(
$b
=~ /^new/) ? 1 :
uc
(
$a
) cmp
uc
(
$b
);
}
sub
get_package_method_prototype
{
my
$package
=
shift
;
my
$method
=
shift
;
return
$PACKAGES
{
$package
}->{methods}->{
$method
}->{
prototype
};
}
sub
get_package_method_description
{
my
$package
=
shift
;
my
$method
=
shift
;
return
$PACKAGES
{
$package
}->{methods}->{
$method
}->{description};
}
sub
get_common_event_list
{
return
get_package_event_list(
'*'
);
}
sub
get_package_event_list
{
my
$package
=
shift
;
return
sort
{
lc
$a
cmp
lc
$b
}
keys
%{
$EVENTS
{
$package
}};
}
sub
get_common_event_name
{
my
$event
=
shift
;
return
get_package_event_name(
'*'
,
$event
);
}
sub
get_package_event_name
{
my
$package
=
shift
;
my
$event
=
shift
;
return
$EVENTS
{
$package
}->{
$event
}->{name};
}
sub
get_common_event_prototype
{
my
$event
=
shift
;
return
get_package_event_prototype(
'*'
,
$event
);
}
sub
get_package_event_prototype
{
my
$package
=
shift
;
my
$event
=
shift
;
return
$EVENTS
{
$package
}->{
$event
}->{
prototype
};
}
sub
get_common_event_description
{
my
$event
=
shift
;
return
get_package_event_description(
'*'
,
$event
);
}
sub
get_package_event_description
{
my
$package
=
shift
;
my
$event
=
shift
;
return
$EVENTS
{
$package
}->{
$event
}->{description};
}
sub
fix_alternates
{
for
my
$package
(
keys
%PACKAGES
) {
for
my
$method
(
keys
%{
$PACKAGES
{
$package
}->{methods}}) {
my
$alternates
=
$PACKAGES
{
$package
}->{methods}->{
$method
}->{alternates};
my
(
$altpack
,
$altproto
,
$altdesc
);
for
my
$altmethod
(
@$alternates
) {
if
(
$altmethod
!~ /^Win32::GUI::/) {
$altpack
=
$package
;
$altproto
=
$PACKAGES
{
$package
}->{methods}->{
$method
}->{
prototype
};
$altdesc
=
"See $method()"
;
}
else
{
(
$altpack
=
$altmethod
) =~ s/(.*::)/$1/;
$altproto
=
$PACKAGES
{
$package
}->{methods}->{
$method
}->{
prototype
};
$altdesc
=
$PACKAGES
{
$package
}->{methods}->{
$method
}->{description} .
"\n\n See also ${package}::${method}()."
;
}
die
"alternate method ${altpack}::${altmethod} already defined."
if
exists
$PACKAGES
{
$altpack
}->{methods}->{
$altmethod
};
$PACKAGES
{
$altpack
}->{methods}->{
$altmethod
} = {
prototype
=>
$altproto
,
description
=>
$altdesc
,
};
}
}
}
return
1;
}
1;