home *** CD-ROM | disk | FTP | other *** search
Wrap
# 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}}" =~ /┼:(┼)¿0/) # {¿0} is the leaf name of this script, for use in the generated comment below Evaluate %=("{{1}}" =~ /┼:(┼)¿1/) # {¿1} is the leaf name of the new .exp file, for use in the generated comment below Echo '###' Echo "### This file was generated by {{¿0}} (`Date`) from {{¿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 {{¿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 /Ñ@[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 /╢:╢:/ "{{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 /╢#/ "{{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 /╢#/ "{{TempFolder}}global_symbols" || Set Status 0 # followed by non-member symbols with comments (we know absolutely whether they are code or data) (Search -q /╢:╢:/ "{{TempFolder}}non_inline_symbols" || Echo -n) | Sort -unique -fs "╢#:" -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"; }