Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 3145

Show
Ignore:
Timestamp:
01/31/08 15:04:34 (10 months ago)
Author:
sean
Message:

* Moved exception trace generation from tango.core.Exception into the runtime. This involved adding a TraceInfo? interface to the global Exception class, and moving the machinery to generate a trace into genobj.d.


* The new hook to attach a trace hander is as follows:

extern (C) void  rt_setTraceHandler( void function( void* ptr = null ) h );

This feature is exposed in tango.core.Runtime as the new 'traceHandler' property.


* The change to tracing inspired me to similarly rewire the collection handler code to move that hook into the runtime as well. This was done to improve efficiency for collections, as each collected object can now simply test a pointer to see if a handler is set rather than calling into user-space to perform the same check. The new hook for this mechanism is:

extern (C) void  rt_setCollectHandler( void function(Object) h );

And the feature is also exposed in the Runtime object as the new collectHandler property. I thought about the name 'collectHandler' being in Runtime rather than GC, but I think the accompanying explanation for the function justifies the decision.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/common/tango/core/Exception.d

    r2913 r3145  
    1313{ 
    1414    alias void  function( char[] file, size_t line, char[] msg = null ) assertHandlerType; 
    15     alias TracedExceptionInfo function( void* ptr = null ) traceHandlerType; 
    1615 
    1716    assertHandlerType   assertHandler   = null; 
    18     traceHandlerType    traceHandler    = null; 
    19 } 
    20  
    21  
    22 interface TracedExceptionInfo 
    23 { 
    24     int opApply( int delegate( inout char[] ) ); 
    2517} 
    2618 
     
    3022- Exception 
    3123  - OutOfMemoryException 
    32  
    33   - TracedException 
    34     - SwitchException 
    35     - AssertException 
    36     - ArrayBoundsException 
    37     - FinalizeException 
    38  
    39     - PlatformException 
    40       - ProcessException 
    41       - ThreadException 
    42         - FiberException 
    43       - SyncException 
    44       - IOException 
    45         - SocketException 
    46           - SocketAcceptException 
    47         - AddressException 
    48         - HostException 
    49         - VfsException 
    50         - ClusterException 
    51  
    52     - NoSuchElementException 
    53       - CorruptedIteratorException 
    54  
    55     - IllegalArgumentException 
    56       - IllegalElementException 
    57  
    58     - TextException 
    59       - RegexException 
    60       - LocaleException 
    61       - UnicodeException 
    62  
    63     - PayloadException 
     24  - SwitchException 
     25  - AssertException 
     26  - ArrayBoundsException 
     27  - FinalizeException 
     28 
     29  - PlatformException 
     30    - ProcessException 
     31    - ThreadException 
     32      - FiberException 
     33    - SyncException 
     34    - IOException 
     35      - SocketException 
     36        - SocketAcceptException 
     37      - AddressException 
     38      - HostException 
     39      - VfsException 
     40      - ClusterException 
     41 
     42  - NoSuchElementException 
     43    - CorruptedIteratorException 
     44 
     45  - IllegalArgumentException 
     46    - IllegalElementException 
     47 
     48  - TextException 
     49    - RegexException 
     50    - LocaleException 
     51    - UnicodeException 
     52 
     53  - PayloadException 
    6454*/ 
    6555//////////////////////////////////////////////////////////////////////////////// 
     
    8474 
    8575/** 
    86  * Stores a stack trace when thrown. 
    87  */ 
    88 class TracedException : Exception 
    89 
    90     this( char[] msg ) 
    91     { 
    92         super( msg ); 
    93         m_info = traceContext(); 
    94     } 
    95  
    96     this( char[] msg, Exception e ) 
    97     { 
    98         super( msg, e ); 
    99         m_info = traceContext(); 
     76 * Base class for operating system or library exceptions. 
     77 */ 
     78class PlatformException : Exception 
     79
     80    this( char[] msg ) 
     81    { 
     82        super( msg ); 
     83    } 
     84
     85 
     86/** 
     87 * Thrown on an assert error. 
     88 */ 
     89class AssertException : Exception 
     90
     91    this( char[] file, size_t line ) 
     92    { 
     93        super( "Assertion failure", file, line ); 
    10094    } 
    10195 
     
    10397    { 
    10498        super( msg, file, line ); 
    105         m_info = traceContext(); 
    106     } 
    107  
    108     char[] toString() 
    109     { 
    110         if( m_info is null ) 
    111             return super.toString(); 
    112         char[] buf = super.toString(); 
    113         buf ~= "\n----------------"; 
    114         foreach( line; m_info ) 
    115             buf ~= "\n" ~ line; 
    116         return buf; 
    117     } 
    118  
    119     int opApply( int delegate( inout char[] buf ) dg ) 
    120     { 
    121         if( m_info is null ) 
    122             return 0; 
    123         return m_info.opApply( dg ); 
    124     } 
    125  
    126 private: 
    127     TracedExceptionInfo m_info; 
    128 
    129  
    130  
    131 /** 
    132  * Base class for operating system or library exceptions. 
    133  */ 
    134 class PlatformException : TracedException 
    135 
    136     this( char[] msg ) 
    137     { 
    138         super( msg ); 
    139     } 
    140 
    141  
    142 /** 
    143  * Thrown on an assert error. 
    144  */ 
    145 class AssertException : TracedException 
     99    } 
     100
     101 
     102 
     103/** 
     104 * Thrown on an array bounds error. 
     105 */ 
     106class ArrayBoundsException : Exception 
    146107{ 
    147108    this( char[] file, size_t line ) 
    148109    { 
    149         super( "Assertion failure", file, line ); 
    150     } 
    151  
    152     this( char[] msg, char[] file, size_t line ) 
    153     { 
    154         super( msg, file, line ); 
    155     } 
    156 } 
    157  
    158  
    159 /** 
    160  * Thrown on an array bounds error. 
    161  */ 
    162 class ArrayBoundsException : TracedException 
    163 { 
    164     this( char[] file, size_t line ) 
    165     { 
    166110        super( "Array index out of bounds", file, line ); 
    167111    } 
     
    172116 * Thrown on finalize error. 
    173117 */ 
    174 class FinalizeException : TracedException 
     118class FinalizeException : Exception 
    175119{ 
    176120    ClassInfo   info; 
     
    192136 * Thrown on a switch error. 
    193137 */ 
    194 class SwitchException : TracedException 
     138class SwitchException : Exception 
    195139{ 
    196140    this( char[] file, size_t line ) 
     
    204148 * Represents a text processing error. 
    205149 */ 
    206 class TextException : TracedException 
     150class TextException : Exception 
    207151{ 
    208152    this( char[] msg ) 
     
    277221 
    278222/** 
    279  * The basic exception thrown by the tango.io.vfs package.  
     223 * The basic exception thrown by the tango.io.vfs package. 
    280224 */ 
    281225private class VfsException : IOException 
     
    288232 
    289233/** 
    290  * The basic exception thrown by the tango.io.cluster package.  
     234 * The basic exception thrown by the tango.io.cluster package. 
    291235 */ 
    292236private class ClusterException : IOException 
     
    387331 * guid. 
    388332 */ 
    389 class RegistryException : TracedException 
     333class RegistryException : Exception 
    390334{ 
    391335    this( char[] msg ) 
     
    399343 * Thrown when an illegal argument is encountered. 
    400344 */ 
    401 class IllegalArgumentException : TracedException 
     345class IllegalArgumentException : Exception 
    402346{ 
    403347    this( char[] msg ) 
     
    427371 * Thrown on past-the-end errors by iterators and containers. 
    428372 */ 
    429 class NoSuchElementException : TracedException 
     373class NoSuchElementException : Exception 
    430374{ 
    431375    this( char[] msg ) 
     
    462406{ 
    463407    assertHandler = h; 
    464 } 
    465  
    466  
    467 /** 
    468  * Overrides the default trace hander with a user-supplied version. 
    469  * 
    470  * Params: 
    471  *  h = The new trace handler.  Set to null to use the default handler. 
    472  */ 
    473 void setTraceHandler( traceHandlerType h ) 
    474 { 
    475     traceHandler = h; 
    476408} 
    477409 
     
    517449 
    518450 
    519 /** 
    520  * This function will be called when a TracedException is constructed.  The 
    521  * user-supplied trace handler will be called if one has been supplied, 
    522  * otherwise no trace will be generated. 
    523  * 
    524  * Params: 
    525  *  ptr = A pointer to the location from which to generate the trace, or null 
    526  *        if the trace should be generated from within the trace handler 
    527  *        itself. 
    528  * 
    529  * Returns: 
    530  *  An object describing the current calling context or null if no handler is 
    531  *  supplied. 
    532  */ 
    533 TracedExceptionInfo traceContext( void* ptr = null ) 
    534 { 
    535     if( traceHandler is null ) 
    536         return null; 
    537     return traceHandler( ptr ); 
    538 } 
    539  
    540451//////////////////////////////////////////////////////////////////////////////// 
    541452// Internal Error Callbacks 
  • trunk/lib/common/tango/core/Memory.d

    r3073 r3145  
    4747    extern (C) void gc_removeRoot( void* p ); 
    4848    extern (C) void gc_removeRange( void* p ); 
    49  
    50     alias bool function( Object obj ) collectHandlerType; 
    5149} 
    5250 
     
    432430        gc_removeRange( p ); 
    433431    } 
    434  
    435  
    436     /** 
    437      * Overrides the default collect hander with a user-supplied version. 
    438      * 
    439      * Params: 
    440      *  h = The new collect handler.  Set to null to use the default handler. 
    441      */ 
    442     static void collectHandler( collectHandlerType h ) 
    443     { 
    444         sm_collectHandler = h; 
    445     } 
    446  
    447  
    448 private: 
    449     static collectHandlerType   sm_collectHandler = null; 
    450432} 
    451  
    452  
    453 //////////////////////////////////////////////////////////////////////////////// 
    454 // Overridable Callbacks 
    455 //////////////////////////////////////////////////////////////////////////////// 
    456  
    457  
    458 /** 
    459  * This function will be called when resource objects (ie. objects with a dtor) 
    460  * are finalized by the garbage collector.  The user-supplied collect handler 
    461  * will be called if one has been supplied, otherwise no action will be taken. 
    462  * 
    463  * Params: 
    464  *  obj = The object being collected. 
    465  * 
    466  * Returns: 
    467  *  true if the runtime should call this object's dtor and false if not. 
    468  *  Default behavior is to return true. 
    469  */ 
    470 extern (C) bool onCollectResource( Object obj ) 
    471 { 
    472     if( GC.sm_collectHandler is null ) 
    473         return true; 
    474     return GC.sm_collectHandler( obj ); 
    475 } 
  • trunk/lib/common/tango/core/Runtime.d

    r2465 r3145  
    1313    extern (C) bool rt_isHalting(); 
    1414 
    15     alias bool function() moduleUnitTesterType; 
     15    alias bool function() ModuleUnitTester; 
     16    alias bool function(Object) CollectHandler; 
     17    alias Exception.TraceInfo function( void* ptr = null ) TraceHandler; 
     18 
     19    extern (C) void  rt_setCollectHandler( CollectHandler h ); 
     20    extern (C) void  rt_setTraceHandler( TraceHandler h ); 
    1621} 
    1722 
     
    4348 
    4449    /** 
     50     * Overrides the default trace mechanism with s user-supplied version.  A 
     51     * trace represents the context from which an exception was thrown, and the 
     52     * trace handler will be called when this occurs.  The pointer supplied to 
     53     * this routine indicates the base address from which tracing should occur. 
     54     * If the supplied pointer is null then the trace routine should determine 
     55     * an appropriate calling context from which to begin the trace. 
     56     * 
     57     * Params: 
     58     *  h = The new trace handler.  Set to null to use the default handler. 
     59     */ 
     60    static void traceHandler( TraceHandler h ) 
     61    { 
     62        rt_setTraceHandler( h ); 
     63    } 
     64 
     65 
     66    /** 
     67     * Overrides the default collect hander with a user-supplied version.  This 
     68     * routine will be called for each resource object that is finalized in a 
     69     * non-deterministic manner--typically during a garbage collection cycle. 
     70     * If the supplied routine returns true then the object's dtor will called 
     71     * as normal, but if the routine returns false than the dtor will not be 
     72     * called.  The default behavior is for all object dtors to be called. 
     73     * 
     74     * Params: 
     75     *  h = The new collect handler.  Set to null to use the default handler. 
     76     */ 
     77    static void collectHandler( CollectHandler h ) 
     78    { 
     79        rt_setCollectHandler( h ); 
     80    } 
     81 
     82 
     83    /** 
    4584     * Overrides the default module unit tester with a user-supplied version. 
     85     * This routine will be called once on program initialization.  The return 
     86     * value of this routine indicates to the runtime whether the body of the 
     87     * program will be executed. 
    4688     * 
    4789     * Params: 
    4890     *  h = The new unit tester.  Set to null to use the default unit tester. 
    4991     */ 
    50     static void moduleUnitTester( moduleUnitTesterType h ) 
     92    static void moduleUnitTester( ModuleUnitTester h ) 
    5193    { 
    5294        sm_moduleUnitTester = h; 
     
    5597 
    5698private: 
    57     static moduleUnitTesterType sm_moduleUnitTester = null; 
     99    static ModuleUnitTester sm_moduleUnitTester = null; 
    58100} 
    59101 
  • trunk/lib/compiler/dmd/dmain2.d

    r2913 r3145  
    232232                    { 
    233233                       // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg); 
    234                        console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n"); 
     234                       console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.toString)("\n"); 
    235235                    } 
    236236                    else 
     
    239239                       console (e.classinfo.name)(": ")(e.toString)("\n"); 
    240240                    } 
     241                    if (e.info) 
     242                    { 
     243                        console ("----------------\n"); 
     244                        foreach (t; e.info) 
     245                            console (t)("\n"); 
     246                    } 
     247                    if (e.next) 
     248                        console ("\n"); 
    241249                    e = e.next; 
    242250                } 
  • trunk/lib/compiler/dmd/genobj.d

    r3088 r3145  
    887887} 
    888888 
     889 
     890//////////////////////////////////////////////////////////////////////////////// 
     891// Exception 
     892//////////////////////////////////////////////////////////////////////////////// 
     893 
     894 
    889895class Exception : Object 
    890896{ 
     897    interface TraceInfo 
     898    { 
     899        int opApply( int delegate( inout char[] ) ); 
     900    } 
     901 
    891902    char[]      msg; 
    892903    char[]      file; 
    893904    size_t      line; 
     905    TraceInfo   info; 
    894906    Exception   next; 
    895907 
    896     this(char[] msg, Exception next = null
     908    this( char[] msg, Exception next = null
    897909    { 
    898910        this.msg = msg; 
    899911        this.next = next; 
    900     } 
    901  
    902     this(char[] msg, char[] file, size_t line, Exception next = null) 
     912        this.info = traceContext(); 
     913    } 
     914 
     915    this( char[] msg, char[] file, size_t line, Exception next = null ) 
    903916    { 
    904917        this(msg, next); 
    905918        this.file = file; 
    906919        this.line = line; 
     920        this.info = traceContext(); 
    907921    } 
    908922 
     
    911925        return msg; 
    912926    } 
     927} 
     928 
     929 
     930alias Exception.TraceInfo function( void* ptr = null ) TraceHandler; 
     931private TraceHandler traceHandler = null; 
     932 
     933 
     934/** 
     935 * Overrides the default trace hander with a user-supplied version. 
     936 * 
     937 * Params: 
     938 *  h = The new trace handler.  Set to null to use the default handler. 
     939 */ 
     940extern (C) void  rt_setTraceHandler( TraceHandler h ) 
     941{ 
     942    traceHandler = h; 
     943} 
     944 
     945 
     946/** 
     947 * This function will be called when an Exception is constructed.  The 
     948 * user-supplied trace handler will be called if one has been supplied, 
     949 * otherwise no trace will be generated. 
     950 * 
     951 * Params: 
     952 *  ptr = A pointer to the location from which to generate the trace, or null 
     953 *        if the trace should be generated from within the trace handler 
     954 *        itself. 
     955 * 
     956 * Returns: 
     957 *  An object describing the current calling context or null if no handler is 
     958 *  supplied. 
     959 */ 
     960Exception.TraceInfo traceContext( void* ptr = null ) 
     961{ 
     962    if( traceHandler is null ) 
     963        return null; 
     964    return traceHandler( ptr ); 
    913965} 
    914966 
  • trunk/lib/compiler/dmd/lifetime.d

    r2955 r3145  
    6767    extern (C) BlkInfo gc_query( void* p ); 
    6868 
    69     extern (C) bool onCollectResource( Object o ); 
    7069    extern (C) void onFinalizeError( ClassInfo c, Exception e ); 
    7170    extern (C) void onOutOfMemoryError(); 
     
    7776        PAGESIZE = 4096 
    7877    } 
     78 
     79    alias bool function(Object) CollectHandler; 
     80    CollectHandler collectHandler = null; 
    7981} 
    8082 
     
    446448 * 
    447449 */ 
     450extern (C) void  rt_setCollectHandler(CollectHandler h) 
     451{ 
     452    collectHandler = h; 
     453} 
     454 
     455 
     456/** 
     457 * 
     458 */ 
    448459extern (C) void rt_finalize(void* p, bool det = true) 
    449460{ 
     
    460471            try 
    461472            { 
    462                 if (det || onCollectResource(cast(Object)p)) 
     473                if (det || collectHandler is null || collectHandler(cast(Object)p)) 
    463474                { 
    464475                    do 
  • trunk/lib/compiler/dmd/mars.h

    r2076 r3145  
    7373    size_t line; 
    7474 
     75    struct Interface *info; 
    7576    struct Exception *next; 
    7677} Exception; 
  • trunk/lib/compiler/gdc/dgccmain2.d

    r3095 r3145  
    240240                    { 
    241241                       // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg); 
    242                        console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n"); 
     242                       console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.toString)("\n"); 
    243243                    } 
    244244                    else 
     
    247247                       console (e.classinfo.name)(": ")(e.toString)("\n"); 
    248248                    } 
     249                    if (e.info) 
     250                    { 
     251                        console ("----------------\n"); 
     252                        foreach (t; e.info) 
     253                            console (t)("\n"); 
     254                    } 
     255                    if (e.next) 
     256                        console ("\n"); 
    249257                    e = e.next; 
    250258                } 
  • trunk/lib/compiler/gdc/genobj.d

    r3088 r3145  
    897897} 
    898898 
     899//////////////////////////////////////////////////////////////////////////////// 
     900// Exception 
     901//////////////////////////////////////////////////////////////////////////////// 
    899902class Exception : Object 
    900903{ 
     904    interface TraceInfo 
     905    { 
     906        int opApply( int delegate( inout char[] ) ); 
     907    } 
    901908    char[]      msg; 
    902909    char[]      file; 
    903910    size_t      line; 
     911    TraceInfo   info; 
    904912    Exception   next; 
    905913 
     
    908916        this.msg = msg; 
    909917        this.next = next; 
     918        this.info = traceContext(); 
    910919    } 
    911920 
     
    915924        this.file = file; 
    916925        this.line = line; 
     926        this.info = traceContext(); 
    917927    } 
    918928 
     
    921931        return msg; 
    922932    } 
     933} 
     934 
     935 
     936alias Exception.TraceInfo function( void* ptr = null ) TraceHandler; 
     937private TraceHandler traceHandler = null; 
     938 
     939 
     940/** 
     941 * Overrides the default trace hander with a user-supplied version. 
     942 * 
     943 * Params: 
     944 *  h = The new trace handler.  Set to null to use the default handler. 
     945 */ 
     946extern (C) void  rt_setTraceHandler( TraceHandler h ) 
     947{ 
     948    traceHandler = h; 
     949} 
     950 
     951 
     952/** 
     953 * This function will be called when an Exception is constructed.  The 
     954 * user-supplied trace handler will be called if one has been supplied, 
     955 * otherwise no trace will be generated. 
     956 * 
     957 * Params: 
     958 *  ptr = A pointer to the location from which to generate the trace, or null 
     959 *        if the trace should be generated from within the trace handler 
     960 *        itself. 
     961 * 
     962 * Returns: 
     963 *  An object describing the current calling context or null if no handler is 
     964 *  supplied. 
     965 */ 
     966Exception.TraceInfo traceContext( void* ptr = null ) 
     967{ 
     968    if( traceHandler is null ) 
     969        return null; 
     970    return traceHandler( ptr ); 
    923971} 
    924972 
  • trunk/lib/compiler/gdc/lifetime.d

    r2955 r3145  
    6767    extern (C) BlkInfo gc_query( void* p ); 
    6868 
    69     extern (C) bool onCollectResource( Object o ); 
    7069    extern (C) void onFinalizeError( ClassInfo c, Exception e ); 
    7170    extern (C) void onOutOfMemoryError(); 
     
    7776        PAGESIZE = 4096 
    7877    } 
     78    alias bool function(Object) CollectHandler; 
     79    CollectHandler collectHandler = null; 
    7980} 
    8081 
     
    439440 * 
    440441 */ 
     442extern (C) void  rt_setCollectHandler(CollectHandler h) 
     443{ 
     444    collectHandler = h; 
     445} 
     446 
     447 
     448/** 
     449 * 
     450 */ 
    441451extern (C) void rt_finalize(void* p, bool det = true) 
    442452{ 
     
    453463            try 
    454464            { 
    455                 if (det || onCollectResource(cast(Object)p)) 
     465                if (det || collectHandler is null || collectHandler(cast(Object)p)) 
    456466                { 
    457467                    do 
  • trunk/lib/compiler/gdc/mars.h

    r2076 r3145  
    7474    size_t line; 
    7575 
     76    struct Interface *info; 
    7677    struct Exception *next; 
    7778} Exception; 
  • trunk/object.di

    r3028 r3145  
    156156class Exception : Object 
    157157{ 
     158    interface TraceInfo 
     159    { 
     160        int opApply( int delegate( inout char[] ) ); 
     161        char[] toString(); 
     162    } 
     163 
    158164    char[]      msg; 
    159165    char[]      file; 
    160166    size_t      line; 
     167    TraceInfo   info; 
    161168    Exception   next; 
    162169 
  • trunk/tango/core/Variant.d

    r3045 r3145  
    88module tango.core.Variant; 
    99 
    10 private import tango.core.Exception : TracedException; 
    1110private import tango.core.Vararg : va_list; 
    1211 
     
    198197 * without using a compatible type. 
    199198 */ 
    200 class VariantTypeMismatchException : TracedException 
     199class VariantTypeMismatchException : Exception 
    201200{ 
    202201    this(TypeInfo expected, TypeInfo got) 
     
    599598        assert( !v.isImplicitly!(float), v.type.toString ); 
    600599        assert( v.get!(double) == 3.1413 ); 
    601          
     600 
    602601        auto u = Variant(v); 
    603602        assert( u.isA!(double), u.type.toString ); 
     
    657656            hash[v2] = 1; 
    658657            hash[v3] = 2; 
    659              
     658 
    660659            assert( hash[v1] == 0 ); 
    661660            assert( hash[v2] == 1 ); 
  • trunk/tango/io/archive/Zip.d

    r3075 r3145  
    1 /******************************************************************************* 
     1/******************************************************************************* 
    22 * 
    3  * copyright:   Copyright © 2007 Daniel Keep.  All rights reserved. 
     3 * copyright:   Copyright © 2007 Daniel Keep.  All rights reserved. 
    44 * 
    55 * license:     BSD style: $(LICENSE) 
     
    261261    Data* data; 
    262262    static assert( Data.sizeof == 42 ); 
    263      
     263 
    264264    char[] file_name; 
    265265    ubyte[] extra_field; 
     
    319319       data.file_comment_length = file_comment.length; 
    320320 
    321         // Ok; let's do this!  
     321        // Ok; let's do this! 
    322322        version( BigEndian ) swapAll(data); 
    323323        writeExact(output, (&data)[0..1]); 
     
    406406    Data data; 
    407407    static assert( data.sizeof == 18 ); 
    408      
     408 
    409409    char[] file_comment; 
    410410 
     
    427427        Data data = this.data; 
    428428        data.file_comment_length = file_comment.length; 
    429          
     429 
    430430        version( BigEndian ) swapAll(data); 
    431431        writeExact(output, (&data)[0..1]); 
     
    569569 *  } 
    570570 * ----- 
    571  *  
     571 * 
    572572 * See the ZipEntry class for more information on the contents of entries. 
    573573 * 
     
    611611    } 
    612612} 
    613      
     613 
    614614    /** 
    615615     * Creates a ZipBlockReader using the provided InputStream.  Please note 
     
    660660                assert( state == State.Open ); 
    661661                return more; 
    662                  
     662 
    663663            case State.Open: 
    664664                return (current_index < headers.length); 
     
    681681        if( !more ) 
    682682            ZipExhaustedException(); 
    683          
     683 
    684684        return new ZipEntry(headers[current_index++], &open_file); 
    685685    } 
     
    711711        { 
    712712            entry = get(entry); 
    713              
     713 
    714714            result = dg(entry); 
    715715            if( result ) 
     
    949949 
    950950        LocalFileHeader lheader; lheader.fill(source); 
    951          
     951 
    952952        if( !lheader.agrees_with(header) ) 
    953953            ZipException.incons(header.file_name); 
    954          
     954 
    955955        // Ok; get a slice stream for the file 
    956956        return new SliceSeekInputStream( 
     
    983983        this(FilePath(path)); 
    984984    } 
    985      
     985 
    986986    /// ditto 
    987987    this(PathView path) 
     
    11471147        timeToDos(info.modified, lhdata.modification_file_time, 
    11481148                                 lhdata.modification_file_date); 
    1149          
     1149 
    11501150        put_local_header(lhdata, info.name); 
    1151          
     1151 
    11521152        // Store comment 
    11531153        entries[$-1].comment = info.comment; 
     
    13451345        // Write out the header and the filename 
    13461346        auto header_pos = seeker.seek(0, IConduit.Seek.Anchor.Current); 
    1347          
     1347 
    13481348        write(output, LocalFileHeader.signature); 
    13491349        header.put(output); 
     
    13841384        return header.data.uncompressed_size;; 
    13851385    } 
    1386      
     1386 
    13871387    /** 
    13881388     * Opens a stream for reading from the file.  The contents of this stream 
     
    15251525// 
    15261526 
    1527 import tango.core.Exception : TracedException; 
    1528  
    15291527/** 
    15301528 * This is the base class from which all exceptions generated by this module 
    15311529 * derive from. 
    15321530 */ 
    1533 class ZipException : TracedException 
     1531class ZipException : Exception 
    15341532{ 
    15351533    this(char[] msg) { super(msg); } 
     
    16791677        switch( m ) 
    16801678        { 
    1681             case 0:      
     1679            case 0: 
    16821680            case 8:     assert(false); // supported 
    16831681 
     
    20692067        '\u00ea': '\x88', '\u00eb': '\x89', '\u00e8': '\x8a', '\u00ef': '\x8b', 
    20702068        '\u00ee': '\x8c', '\u00ec': '\x8d', '\u00c4': '\x8e', '\u00c5': '\x8f', 
    2071      
     2069 
    20722070        '\u00c9': '\x90', '\u00e6': '\x91', '\u00c6': '\x92', '\u00f4': '\x93', 
    20732071        '\u00f6': '\x94', '\u00f2': '\x95', '\u00fb': '\x96', '\u00f9': '\x97', 
    20742072        '\u00ff': '\x98', '\u00d6': '\x99', '\u00dc': '\x9a', '\u00f8': '\x9b', 
    20752073        '\u00a3': '\x9c', '\u00a5': '\x9d', '\u20a7': '\x9e', '\u0192': '\x9f', 
    2076      
     2074 
    20772075        '\u00e1': '\xa0', '\u00ed': '\xa1', '\u00f3': '\xa2', '\u00fa': '\xa3', 
    20782076        '\u00f1': '\xa4', '\u00d1': '\xa5', '\u00aa': '\xa6', '\u00ba': '\xa7', 
    20792077        '\u00bf': '\xa8', '\u2310': '\xa9', '\u00ac': '\xaa', '\u00bd': '\xab', 
    20802078        '\u00bc': '\xac', '\u00a1': '\xad', '\u00ab': '\xae', '\u00bb': '\xaf', 
    2081      
     2079 
    20822080        '\u2591': '\xb0', '\u2592': '\xb1', '\u2593': '\xb2', '\u2502': '\xb3', 
    20832081        '\u2524': '\xb4', '\u2561': '\xb5', '\u2562': '\xb6', '\u2556': '\xb7', 
    20842082        '\u2555': '\xb8', '\u2563': '\xb9', '\u2551': '\xba', '\u2557': '\xbb', 
    20852083        '\u255d': '\xbc', '\u255c': '\xbd', '\u255b': '\xbe', '\u2510': '\xbf', 
    2086      
     2084 
    20872085        '\u2514': '\xc0', '\u2534': '\xc1', '\u252c': '\xc2', '\u251c': '\xc3', 
    20882086        '\u2500': '\xc4', '\u253c': '\xc5', '\u255e': '\xc6', '\u255f': '\xc7', 
    20892087        '\u255a': '\xc8', '\u2554': '\xc9', '\u2569': '\xca', '\u2566': '\xcb', 
    20902088        '\u2560': '\xcc', '\u2550': '\xcd', '\u256c': '\xce', '\u2567': '\xcf', 
    2091      
     2089 
    20922090        '\u2568': '\xd0', '\u2564': '\xd1', '\u2565': '\xd2', '\u2559': '\xd3', 
    20932091        '\u2558': '\xd4', '\u2552': '\xd5', '\u2553': '\xd6', '\u256b': '\xd7', 
     
    20992097        '\u03a6': '\xe8', '\u0398': '\xe9', '\u03a9': '\xea', '\u03b4': '\xeb', 
    21002098        '\u221e': '\xec', '\u03c6': '\xed', '\u03b5': '\xee', '\u2229': '\xef', 
    2101      
     2099 
    21022100        '\u2261': '\xf0', '\u00b1': '\xf1', '\u2265': '\xf2', '\u2264': '\xf3', 
    21032101        '\u2320': '\xf4', '\u2321': '\xf5', '\u00f7': '\xf6', '\u2248': '\xf7', 
     
    21252123                if( 32 <= d && d <= 126 || d == 0 ) 
    21262124                    r[k++] = d; 
    2127                  
     2125 
    21282126                else if( d == '\u2302' ) 
    21292127                    r[k++] = '\x7f'; 
     
    21312129                else if( auto e_ptr = d in utf8_to_cp437_map ) 
    21322130                    r[k++] = *e_ptr; 
    2133                  
     2131 
    21342132                else 
    21352133                { 
     
    22272225    // *muttering angrily* 
    22282226    scope cal = new Gregorian; 
    2229      
     2227 
    22302228    if( cal.getYear(time) < 1980 ) 
    22312229        ZipException.tooold; 
     
    22542252/******************************************************************************* 
    22552253 
    2256     copyright:  Copyright © 2007 Daniel Keep.  All rights reserved. 
     2254    copyright:  Copyright © 2007 Daniel Keep.  All rights reserved. 
    22572255 
    22582256    license:    BSD style: $(LICENSE) 
     
    23772375/******************************************************************************* 
    23782376 
    2379     copyright:  Copyright ©