gecko-dev/cmd/macfe/tools/AnnotateExports

285 строки
9.8 KiB
Plaintext
Исходник Ответственный История

# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
# AnnotateExports exp_file [old_exp_file]
#
# Original Author: scc (Scott Collins)
# ...munge a .exp file generated by CodeWarrior into a form fit for humans and MakeStub as well as CodeWarrior
# itself. When the optional second .exp file is given, it determines which symbols from the first file will be
# exported (other symbols will be present but commented out), and overrides the symbol kind (code or data) for
# those symbols from the first file for which CW did not tell us the kind. This makes it easy to generate a new
# .exp that lists all the up-to-date symbols in project, but exports nothing new:
# 1. Make the .exp file that you want to bring up-to-date writable; and remove it from its project.
# 2. Re-link the project so that CodeWarrior will generate a fresh .exp file listing all exportable symbols.
# 3. Use this script to munge the new .exp file, filtering with the old:
# AnnotateExports new.exp old.exp | Catenate > old.exp
# 4. Add the old .exp file (with its new contents) back into the project; and re-link.
# If you're adding new symbols, then before re-linking in step 4, un-comment their signatures in the re-added .exp file.
# Usually radical updates like this won't even be necessary. It will often suffice to simply comment or un-comment an
# existing symbol in the .exp file.
# Warning: When you run this script with the optional `old' .exp file, symbols exported by the `old' .exp file,
# but not found in the new one will be listed in a special section at the end of the generated file. They may
# be `re-exports', i.e., symbols defined in a shared library your project includes, and re-exported by you.
# _Or_ (more likely) they could be old signatures that you no longer implement and should be deleted. So, when
# you regenerate a .exp file SCROLL TO THE END AND SEE IF YOU NEED TO DELETE SOME OF THESE ENTRIES.
# Warning: MakeStub is very picky about comments. To be ignored, they must start in the left-most column.
# Warning: this script may need to be adjusted when CodeWarrior supports namespaces.
#
# Emit a comment to go at the top of the generated .exp file
#
Evaluate %=("{{0}}" =~ /<2F>:(<28>)<29>0/) # {<7B>0} is the leaf name of this script, for use in the generated comment below
Evaluate %=("{{1}}" =~ /<2F>:(<28>)<29>1/) # {<7B>1} is the leaf name of the new .exp file, for use in the generated comment below
Echo '###'
Echo "### This file was generated by {{<7B>0}} (`Date`) from {{<7B>1}}."
Echo '###'
Echo '### [Un-]Comment-out (do not delete) symbols and annotate with #{code} and #{data} to control export.'
Echo "### When brand new signatures are to be exported, regenerate this file as described in {{<7B>0}}."
Echo '### Warning: all comments MUST start in the left column, or else stubs will be built wrong.'
Echo '###'
#
# Sort the raw input file (and perform some eliding) before sending it into the Perl script
#
# Strip out all '@#@' symbols (out-of-line inlines which will never be imported)
(Search -q -r /<2F>@[0-9]+@/ "{{1}}" || Echo -n) > "{{TempFolder}}non_inline_symbols"
# Copy and sort all lines not containing "::" into a temporary file. This comprises all non-member symbols.
(Search -q -r /<2F>:<3A>:/ "{{TempFolder}}non_inline_symbols" || Echo -n) | Sort -unique > "{{TempFolder}}global_symbols"
# The file we're passing into the Perl script is sorted such that...
Begin
Search -q -r /<2F>#/ "{{TempFolder}}global_symbols" || Set Status 0 # non-member symbols without comments come first (the ones we can't between code and data without help)
Search -q /<2F>#/ "{{TempFolder}}global_symbols" || Set Status 0 # followed by non-member symbols with comments (we know absolutely whether they are code or data)
(Search -q /<2F>:<3A>:/ "{{TempFolder}}non_inline_symbols" || Echo -n) | Sort -unique -fs "<22>#:" -f 2,1
# followed by member symbols, sorted first by classname, and within a class by member name
End > "{{TempFolder}}sorted_symbols"
#
# Call the Perl (part of this) script to do the complicated munging...
#
# The Perl script takes two arguments. Neither is optional.
# If we're not given the (optional) list of symbols to allow the .exp file to export...
If ( Not "{{2}}" )
Set 2 "{{TempFolder}}sorted_symbols" # ...then use the file itself as the list of what to allow, i.e., allowing everything.
End
# Tell Perl to find a Perl script within this file, and run it with two parameters...
Perl -S -x "{{0}}" "{{TempFolder}}sorted_symbols" "{{2}}"
#
# Clean up...
#
Delete -i "{{TempFolder}}non_inline_symbols" "{{TempFolder}}global_symbols" "{{TempFolder}}sorted_symbols"
Exit 0
#
# The Perl (part of this) script...
#
#!perl
#
# Inputs:
# (0) sorted `new' .exp file with CodeWarrior generated comments
# (1) `old' .exp file, possibly annotated with #{code} and #{data}
# Constants:
$codeKind = "#\{code\}\n";
$dataKind = "#\{data\}\n";
$defaultKind = $codeKind;
#
# parse the old .exp file, and remember each exported symbol and its kind (i.e., unknown, code, or data)
#
open OLD_EXP_FILE, "<$ARGV[1]" or die "couldn\'t open \"$ARGV[1]\"";
$symbol_kind = $defaultKind;
while ( $_ = <OLD_EXP_FILE> )
{
if ( $_ =~ /^(\#\{(code|data)\})/ ) # if the line is a #{code} or #{data} directive...
{
$symbol_kind = "$1\n"; # ...subsequent symbols will be of that kind
}
elsif ( $_ =~ /^([^\s\#]+)/ ) # else, if there is an exported symbol on this line...
{
$previously_exported{$1} = $symbol_kind; # ...put it in the table of exported symbols, along with its kind.
}
}
close OLD_EXP_FILE;
#
# parse the new .exp file which must contain CodeWarrior generated .exp comments
#
open NEW_EXP_FILE, "<$ARGV[0]" or die "couldn\'t open \"$ARGV[0]\"";
$symbol_classname = "";
$last_printed_classname = $symbol_classname;
$symbol_kind = $defaultKind;
$last_printed_kind = $symbol_kind;
$seen_any_commented_symbol = 0;
print "\n\n###\n### Symbols you may have to hand annotate with #\{code\} or #\{data\}...\n###\n\n";
while ( $_ = <NEW_EXP_FILE> )
{
$ending_hand_annotated_symbols = 0;
if ( $_ =~ /^#\s*(\S+)/ )
{
# if someone already commented out the entire line (CodeWarrior doesn't currently do this), they must mean `don't export this symbol'
$_ = "$1$'";
delete $previously_exported{$1};
}
# If the current line contains a comment...
if ( $_ =~ /#/ )
{
if ( ! $seen_any_commented_symbol )
{
print "\n\n###\n### Symbols which do not require hand annotation...\n###\n\n";
$seen_any_commented_symbol = 1;
$ending_hand_annotated_symbols = 1;
}
# '::' appears on a line if and only if CodeWarrior added a comment giving a symbols unmangled classname::membername
# WARNING: when CodeWarrior supports namespaces, this may need to be changed.
if ( $_ =~ /# (\w+)::/ )
{
$symbol_classname = $1;
}
$symbol_kind_unknown = 0; # Since there was a comment, the symbol kind (i.e., code or data), is definitely known.
# Parentheses appear on a line if and only if CodeWarrior added a comment giving a symbols function prototype.
if ( $_ =~ /\(/ )
{
$symbol_kind = $codeKind; # ...therefore, this symbol is a function.
}
else
{
$symbol_kind = $dataKind; # ...else, it is data (since a CodeWarrior generated .exp file lists only code and
# data, and only comments symbols that it knows whether they are code or data, and
# since this item is not code and has a comment).
}
}
else
{
$symbol_kind = $defaultKind;
$symbol_kind_unknown = 1;
}
# If the current line contains an exported symbol...
if ( $_ =~ /^(\S+)/ )
{
$symbol = $1;
$symbol_was_previously_exported = exists( $previously_exported{$symbol} );
# If we don't know the kind of this symbol (code or data), get it from the table we built from the old .exp file.
if ( $symbol_kind_unknown && $symbol_was_previously_exported )
{
$symbol_kind = $previously_exported{$symbol};
}
$starting_new_class = ($symbol_classname ne $last_printed_classname);
$starting_new_kind = ($symbol_kind ne $last_printed_kind) || $starting_new_class || $ending_hand_annotated_symbols; # ...also forces #{code} and #{data} to be self-contained per class
if ( $starting_new_class )
{
print "\n### class $symbol_classname\n";
$last_printed_classname = $symbol_classname;
}
if ( $starting_new_kind )
{
print $symbol_kind;
$last_printed_kind = $symbol_kind;
}
if ( $symbol_was_previously_exported )
{
delete $previously_exported{$symbol};
}
else
{
print '# ';
}
print "$symbol\n"; # ...and emit the symbol name.
}
}
close NEW_EXP_FILE;
#
#
#
$header = "\n\n###\n### Symbols which are not present, but you wanted to export anyway (i.e., either re-exports or mistakes)...\n###\n\n";
$last_printed_kind = "";
foreach $symbol ( sort(keys %previously_exported) )
{
print $header;
$header = "";
$symbol_kind = $previously_exported{$symbol};
$starting_new_kind = ($symbol_kind ne $last_printed_kind);
if ( $starting_new_kind )
{
print $symbol_kind;
$last_printed_kind = $symbol_kind;
}
print "$symbol\n";
}