Date: 29th July 1998

This patch adds lexical warnings to Perl. It should apply over
5.005_50

NOTE: This is a prototype. Do not assume that lexical warnings will
      necessarily be anything like this implementation.

Changes 
=======

  Date: 8th April 1998

    * patch now applies cleanly over 5.004_64

    * added the -X switch (the inverse "lint" command)

  Date: 26th Feb 1997

    * By popular demand, the warnings bitmask can now be of arbitrary
      length. The code uses an SV* to store the bitmask.

    * Rationalised the warning categories a bit. This area still needs
      a lot of work.

    * Added -W switch (the "lint" command).

    * Added an experimental feature to allow warnings to be excalated
      to fatal errors.


The "use warning" pragma
========================

    The "use warning" pragma is intended to replace both the use of the
    command line flag "-w" and its equivalent variable $^W with a pragma
    that works like the existing "strict" pragma.

    This means that the scope of the pragma is limited to the enclosing
    block. It also means that that a pragma setting will not leak across
    files (via use/require/do). This will allow authors to define the
    degree of warning checks that will be applied to their module.

    By default warnings are disabled.

    All warnings are enabled in a block by either of these:

	use warning ;
	use warning 'all' ;

    Similarly all warnings are disabled in a block by either of these:

	no warning ;
	no warning 'all' ;

    A hierarchy of "categories" have been defined to allow groups of
    warnings to be enabled/disabled in isolation.  The current
    hierarchy is:

	all - +--- unsafe -------+--- taint
	      |			 |
	      |			 +--- substr
	      |			 |
	      |			 +--- signal
	      |			 |
	      |			 +--- closure
	      |			 |
	      |			 +--- untie
	      |			 
	      +--- io	---------+--- pipe
	      |			 |
	      |			 +--- unopened
	      |			 |
	      |			 +--- closed
	      |			 |
	      |			 +--- newline
	      |			 |
	      |			 +--- exec
	      |
	      +--- syntax    ----+--- ambiguous
	      |			 |
	      |			 +--- semicolon
	      |			 |
	      |			 +--- precedence
	      |			 |
	      |			 +--- reserved
	      |			 |
	      |			 +--- octal
	      |			 |
	      |			 +--- parenthesis
	      |			 |
	      |			 +--- deprecated
	      |
	      |--- uninitialized
	      |
	      +--- void
	      |
	      +--- recursion
	      |
	      +--- redefine
	      |
	      +--- numeric
	      |
	      +--- once
	      |
	      +--- misc

    This hierarchy is very tentative. Feedback is needed.

    Just like the "strict" pragma any of these categories can be
    combined

	use warning qw(void redefine) ;
	no warning qw(io syntax untie) ;

The "lint" flag, -W
===================

If the -W flag is used on the command line, it will enable all warnings
throughout the program regardless of whether warnings were disabled
locally using "no warning" or $^W =0. This includes any file that gets
included during compilation via use/require.

The inverse "lint" flag, -X
===========================
Does exactly the same as the -W flag, except it disables all warnings.


Backward Compatability
======================

    How Lexical Warnings interact with -w/$^W

    1. The -w flag just sets the global $^W variable as in 5.004
       This means that any legacy code that currently relies on
       manipulating $^W to control warning behaviour will still work.

    2. Apart from now being a boolean, the $^W variable operates in
       exactly the same horrible uncontrolled global way as in 5.004,
       except...

    3. If a piece of code is under the control of a lexical warning
       pragma, the $^W variable will be ignored.
 
       The combined effect of 2 & 3 is that it will will allow new code
       which will use the lexical warning pragma to control old
       $^W-type code (using a local $^W=0) if it really wants to, but
       not vice-versa.
 
    4. The only way to override a lexical warnings setting is with the
       new -W or -X command line flags.


Fatal Warnings
==============

This feature is very experimental.

The presence of the word "FATAL" in the category list will escalate any
warnings from the category specified that are detected in the lexical
scope into fatal errors. In the code below, there are 3 places where a
deprecated warning will be detected, the middle one will produce a
fatal error.


    use warning ;

    $a = 1 if $a EQ $b ;

    {
	use warning qw(FATAL deprecated) ;
        $a = 1 if $a EQ $b ;
    }

    $a = 1 if $a EQ $b ;


TODO
====

test harness for -X (assuming it is a permanent fixture).
win32, os2 & vms all have warnings. These need to be included.

Unresolved Issues
=================

  The pragma name?
    A few possibilities:
	warning
	warnings
	warn

  Hierarchy of Warnings
    The current patch has a fairly arbitrary hierarchy.
    Ideas for a useful hierarchy would be most welcome.

  A command line option to turn off all warnings?
     -X or -q, perhaps.

  Current mandatory warnings.
    May be useful to bring them under the control of this pragma.

  Severity
    Do we want/need a severity classification?
        pedantic
        high/strict/precise
        medium/default
        low/common
    
  Versions
    This is a thorhy issue. Say someone writes a script using Perl
    5.004 and places this at the top:

	use warning ;

    Time passes and 5.005 comes out. It has added a few extra warnings.
    The script prints warning messages.

    A possibility is to allow the warnings that are checked to be
    limited to those available in a given version of Perl. A possible
    syntax could be:

	use warning 5.004 ;

    or

	use warning 5.004 qw(void uninitialized) ;

    Do we really need this amount of control?

  Documentation
    There isn't any yet.


  perl5db.pl
    The debugger saves and restores $^W at runtime. I haven't checked
    whether the debugger will still work with the lexical warnings
    patch applied.

  diagnostics.pm
    I *think* I've got diagnostics to work with the lexiacal warnings
    patch, but there were design decisions made in diagnostics to work
    around the limitations of $^W. Now that those limitations are gone,
    the module should be revisited.
