home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / tools / AnnotateExports
Encoding:
Text File  |  1998-04-08  |  10.1 KB  |  285 lines

  1. # The contents of this file are subject to the Netscape Public License
  2. # Version 1.0 (the "NPL"); you may not use this file except in
  3. # compliance with the NPL.  You may obtain a copy of the NPL at
  4. # http://www.mozilla.org/NPL/
  5. #
  6. # Software distributed under the NPL is distributed on an "AS IS" basis,
  7. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  8. # for the specific language governing rights and limitations under the
  9. # NPL.
  10. #
  11. # The Initial Developer of this code under the NPL is Netscape
  12. # Communications Corporation.  Portions created by Netscape are
  13. # Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  14. # Reserved.
  15.  
  16.  
  17. #
  18. # AnnotateExports exp_file [old_exp_file]
  19. #
  20. #        Original Author: scc (Scott Collins)
  21.  
  22.  
  23. # ...munge a .exp file generated by CodeWarrior into a form fit for humans and MakeStub as well as CodeWarrior
  24. # itself.  When the optional second .exp file is given, it determines which symbols from the first file will be
  25. # exported (other symbols will be present but commented out), and overrides the symbol kind (code or data) for
  26. # those symbols from the first file for which CW did not tell us the kind.  This makes it easy to generate a new
  27. # .exp that lists all the up-to-date symbols in project, but exports nothing new:
  28.  
  29. #  1. Make the .exp file that you want to bring up-to-date writable; and remove it from its project.
  30. #  2. Re-link the project so that CodeWarrior will generate a fresh .exp file listing all exportable symbols.
  31. #  3. Use this script to munge the new .exp file, filtering with the old:
  32. #       AnnotateExports new.exp old.exp | Catenate > old.exp
  33. #  4. Add the old .exp file (with its new contents) back into the project; and re-link.
  34.  
  35. # If you're adding new symbols, then before re-linking in step 4, un-comment their signatures in the re-added .exp file.
  36. # Usually radical updates like this won't even be necessary.  It will often suffice to simply comment or un-comment an
  37. # existing symbol in the .exp file.
  38.  
  39. # Warning: When you run this script with the optional `old' .exp file, symbols exported by the `old' .exp file,
  40. #        but not found in the new one will be listed in a special section at the end of the generated file.  They may
  41. #        be `re-exports', i.e., symbols defined in a shared library your project includes, and re-exported by you.
  42. #        _Or_ (more likely) they could be old signatures that you no longer implement and should be deleted.  So, when
  43. #        you regenerate a .exp file SCROLL TO THE END AND SEE IF YOU NEED TO DELETE SOME OF THESE ENTRIES.
  44.  
  45. # Warning: MakeStub is very picky about comments.  To be ignored, they must start in the left-most column.
  46. # Warning: this script may need to be adjusted when CodeWarrior supports namespaces.
  47.  
  48.  
  49.  
  50.     #
  51.     # Emit a comment to go at the top of the generated .exp file
  52.     #
  53.  
  54. Evaluate %=("{{0}}" =~ /┼:(┼)¿0/)        #    {¿0} is the leaf name of this script, for use in the generated comment below
  55. Evaluate %=("{{1}}" =~ /┼:(┼)¿1/)        # {¿1} is the leaf name of the new .exp file, for use in the generated comment below
  56.  
  57. Echo '###'
  58. Echo "### This file was generated by {{¿0}} (`Date`) from {{¿1}}."
  59. Echo '###'
  60. Echo '### [Un-]Comment-out (do not delete) symbols and annotate with #{code} and #{data} to control export.'
  61. Echo "### When brand new signatures are to be exported, regenerate this file as described in {{¿0}}."
  62. Echo '### Warning: all comments MUST start in the left column, or else stubs will be built wrong.'
  63. Echo '###'
  64.  
  65.  
  66.  
  67.     #
  68.     # Sort the raw input file (and perform some eliding) before sending it into the Perl script
  69.     #
  70.  
  71.     # Strip out all '@#@' symbols (out-of-line inlines which will never be imported)
  72. (Search -q -r /Ñ@[0-9]+@/ "{{1}}" || Echo -n) > "{{TempFolder}}non_inline_symbols"
  73.     # Copy and sort all lines not containing "::" into a temporary file.  This comprises all non-member symbols.
  74. (Search -q -r /╢:╢:/ "{{TempFolder}}non_inline_symbols" || Echo -n) | Sort -unique > "{{TempFolder}}global_symbols"
  75.  
  76.  
  77.     # The file we're passing into the Perl script is sorted such that...
  78. Begin
  79.     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)
  80.     Search -q /╢#/ "{{TempFolder}}global_symbols" || Set Status 0                    # followed by non-member symbols with comments (we know absolutely whether they are code or data)
  81.     (Search -q /╢:╢:/ "{{TempFolder}}non_inline_symbols" || Echo -n) | Sort -unique -fs "╢#:" -f 2,1
  82.                                                                                                                 # followed by member symbols, sorted first by classname, and within a class by member name
  83. End > "{{TempFolder}}sorted_symbols"
  84.  
  85.  
  86.  
  87.     #
  88.     # Call the Perl (part of this) script to do the complicated munging...
  89.     #
  90.  
  91.     # The Perl script takes two arguments.  Neither is optional.
  92.     # If we're not given the (optional) list of symbols to allow the .exp file to export...
  93. If ( Not "{{2}}" )
  94.     Set 2 "{{TempFolder}}sorted_symbols"    # ...then use the file itself as the list of what to allow, i.e., allowing everything.
  95. End
  96.  
  97.     # Tell Perl to find a Perl script within this file, and run it with two parameters...
  98. Perl -S -x "{{0}}" "{{TempFolder}}sorted_symbols" "{{2}}"
  99.  
  100.  
  101.  
  102.     #
  103.     # Clean up...
  104.     #
  105.  
  106. Delete -i "{{TempFolder}}non_inline_symbols" "{{TempFolder}}global_symbols" "{{TempFolder}}sorted_symbols"
  107. Exit 0
  108.  
  109.  
  110.  
  111.     #
  112.     # The Perl (part of this) script...
  113.     #
  114.  
  115. #!perl
  116.  
  117. #
  118. # Inputs:
  119. #        (0) sorted `new' .exp file with CodeWarrior generated comments
  120. #        (1) `old' .exp file, possibly annotated with #{code} and #{data}
  121.  
  122. # Constants:
  123.  
  124. $codeKind            = "#\{code\}\n";
  125. $dataKind            = "#\{data\}\n";
  126. $defaultKind    = $codeKind;
  127.  
  128.  
  129.  
  130.     #
  131.     # parse the old .exp file, and remember each exported symbol and its kind (i.e., unknown, code, or data)
  132.     #
  133.  
  134. open OLD_EXP_FILE, "<$ARGV[1]" or die "couldn\'t open \"$ARGV[1]\"";
  135. $symbol_kind = $defaultKind;
  136. while ( $_ = <OLD_EXP_FILE> )
  137.     {
  138.         if ( $_ =~ /^(\#\{(code|data)\})/ )                        # if the line is a #{code} or #{data} directive...
  139.             {
  140.                 $symbol_kind = "$1\n";                                        # ...subsequent symbols will be of that kind
  141.             }
  142.         elsif ( $_ =~ /^([^\s\#]+)/ )                                    # else, if there is an exported symbol on this line...
  143.             {        
  144.                 $previously_exported{$1} = $symbol_kind;    # ...put it in the table of exported symbols, along with its kind.
  145.             }
  146.     }
  147. close OLD_EXP_FILE;
  148.  
  149.  
  150.  
  151.     #
  152.     # parse the new .exp file which must contain CodeWarrior generated .exp comments
  153.     #
  154.  
  155. open NEW_EXP_FILE, "<$ARGV[0]" or die "couldn\'t open \"$ARGV[0]\"";
  156.  
  157. $symbol_classname                = "";
  158. $last_printed_classname    = $symbol_classname;
  159.  
  160. $symbol_kind                        = $defaultKind;
  161. $last_printed_kind            = $symbol_kind;
  162.  
  163. $seen_any_commented_symbol    = 0;
  164.  
  165. print "\n\n###\n### Symbols you may have to hand annotate with #\{code\} or #\{data\}...\n###\n\n";
  166.  
  167. while ( $_ = <NEW_EXP_FILE> )
  168.     {
  169.         $ending_hand_annotated_symbols = 0;
  170.  
  171.  
  172.         if ( $_ =~ /^#\s*(\S+)/ )
  173.             {
  174.                     # if someone already commented out the entire line (CodeWarrior doesn't currently do this), they must mean `don't export this symbol'
  175.                 $_ = "$1$'";
  176.                 delete $previously_exported{$1};
  177.             }
  178.  
  179.             # If the current line contains a comment...
  180.  
  181.         if ( $_ =~ /#/ )
  182.             {
  183.                 if ( ! $seen_any_commented_symbol )
  184.                     {
  185.                         print "\n\n###\n### Symbols which do not require hand annotation...\n###\n\n";
  186.                         $seen_any_commented_symbol = 1;
  187.                         $ending_hand_annotated_symbols = 1;
  188.                     }
  189.  
  190.                     # '::' appears on a line if and only if CodeWarrior added a comment giving a symbols unmangled classname::membername
  191.                     # WARNING: when CodeWarrior supports namespaces, this may need to be changed.
  192.                 if ( $_ =~ /# (\w+)::/ )
  193.                     {
  194.                         $symbol_classname = $1;
  195.                     }
  196.  
  197.  
  198.                 $symbol_kind_unknown = 0;            # Since there was a comment, the symbol kind (i.e., code or data), is definitely known.
  199.  
  200.                     # Parentheses appear on a line if and only if CodeWarrior added a comment giving a symbols function prototype.
  201.                 if ( $_ =~ /\(/ )
  202.                     {
  203.                         $symbol_kind = $codeKind;    # ...therefore, this symbol is a function.
  204.                     }
  205.                 else
  206.                     {
  207.                         $symbol_kind = $dataKind;    # ...else, it is data (since a CodeWarrior generated .exp file lists only code and
  208.                                                                             # data, and only comments symbols that it knows whether they are code or data, and
  209.                                                                             # since this item is not code and has a comment).
  210.                     }
  211.             }
  212.         else
  213.             {
  214.                 $symbol_kind                    = $defaultKind;
  215.                 $symbol_kind_unknown    = 1;
  216.             }
  217.  
  218.  
  219.  
  220.             # If the current line contains an exported symbol...
  221.  
  222.         if ( $_ =~ /^(\S+)/ )
  223.             {
  224.                 $symbol = $1;
  225.                 $symbol_was_previously_exported = exists( $previously_exported{$symbol} );
  226.  
  227.                     # 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.
  228.                 if ( $symbol_kind_unknown && $symbol_was_previously_exported )
  229.                     {
  230.                         $symbol_kind = $previously_exported{$symbol};
  231.                     }
  232.  
  233.                 $starting_new_class    = ($symbol_classname ne $last_printed_classname);
  234.                 $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
  235.                 
  236.                 if ( $starting_new_class )
  237.                     {
  238.                         print "\n### class $symbol_classname\n";
  239.                         $last_printed_classname = $symbol_classname;
  240.                     }
  241.  
  242.                 if ( $starting_new_kind )
  243.                     {
  244.                         print $symbol_kind;
  245.                         $last_printed_kind = $symbol_kind;
  246.                     }
  247.  
  248.  
  249.                 if ( $symbol_was_previously_exported )
  250.                     {
  251.                         delete $previously_exported{$symbol};
  252.                     }
  253.                 else
  254.                     {
  255.                         print '# ';
  256.                     }
  257.                 print "$symbol\n";                                                                                        # ...and emit the symbol name.
  258.             }
  259.         
  260.     }
  261. close NEW_EXP_FILE;
  262.  
  263.     #
  264.     #
  265.     #
  266.  
  267.  
  268. $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";
  269.  
  270. $last_printed_kind = "";
  271. foreach $symbol ( sort(keys %previously_exported) )
  272.     {
  273.         print $header;
  274.         $header = "";
  275.  
  276.         $symbol_kind                = $previously_exported{$symbol};
  277.         $starting_new_kind    = ($symbol_kind ne $last_printed_kind);
  278.         if ( $starting_new_kind )
  279.             {
  280.                 print $symbol_kind;
  281.                 $last_printed_kind = $symbol_kind;
  282.             }
  283.         print "$symbol\n";
  284.     }
  285.