home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / tclX8.0.5 / buildidx.tcl < prev    next >
Text File  |  1999-02-24  |  6KB  |  175 lines

  1. #
  2. # buildidx.tcl --
  3. #
  4. # Code to build Tcl package library. Defines the proc `buildpackageindex'.
  5. #------------------------------------------------------------------------------
  6. # Copyright 1992-1997 Karl Lehenbauer and Mark Diekhans.
  7. #
  8. # Permission to use, copy, modify, and distribute this software and its
  9. # documentation for any purpose and without fee is hereby granted, provided
  10. # that the above copyright notice appear in all copies.  Karl Lehenbauer and
  11. # Mark Diekhans make no representations about the suitability of this
  12. # software for any purpose.  It is provided "as is" without express or
  13. # implied warranty.
  14. #------------------------------------------------------------------------------
  15. # $Id: buildidx.tcl,v 8.5.2.1 1998/04/26 20:03:33 markd Exp $
  16. #------------------------------------------------------------------------------
  17. #
  18.  
  19. namespace eval TclX {
  20.  
  21.  
  22.     #--------------------------------------------------------------------------
  23.     # The following code passes around a array containing information about a
  24.     # package.  The following fields are defined
  25.     #
  26.     #   o name - The name of the package.
  27.     #   o offset - The byte offset of the package in the file.
  28.     #   o length - Number of bytes in the current package (EOLN counts as one
  29.     #     byte, even if <cr><lf> is used.  This makes it possible to do a
  30.     #     single read.
  31.     #   o procs - The list of entry point procedures defined for the package.
  32.     #--------------------------------------------------------------------------
  33.  
  34.     #--------------------------------------------------------------------------
  35.     # Write a line to the index file describing the package.
  36.     #
  37.     proc PutIdxEntry {outfp pkgInfo} {
  38.         puts $outfp [concat [keylget pkgInfo name] \
  39.                             [keylget pkgInfo offset] \
  40.                             [keylget pkgInfo length] \
  41.                             [keylget pkgInfo procs]]
  42.     }
  43.  
  44.     #--------------------------------------------------------------------------
  45.     # Parse a package header found by a scan match.  Handle backslashed
  46.     # continuation lines.  Make a namespace reference out of the name
  47.     # that the Tcl auto_load function will like.  Global names have no
  48.     # leading :: (for historic reasons), all others are fully qualified.
  49.     #
  50.     proc ParsePkgHeader matchInfoVar {
  51.         upvar $matchInfoVar matchInfo
  52.  
  53.         set length [expr [clength $matchInfo(line)] + 1]
  54.         set line [string trimright $matchInfo(line)]
  55.         while {[string match {*\\} $line]} {
  56.             set line [csubstr $line 0 [expr [clength $line]-1]]
  57.             set nextLine [gets $matchInfo(handle)]
  58.             append line " " [string trimright $nextLine]
  59.             incr length [expr [clength $nextLine] + 1]
  60.         }
  61.         set procs {}
  62.         foreach p [lrange $line 2 end] {
  63.             lappend procs [auto_qualify $p ::]
  64.         }
  65.  
  66.         keylset pkgInfo name [lindex $line 1]
  67.         keylset pkgInfo offset $matchInfo(offset)
  68.         keylset pkgInfo procs $procs
  69.         keylset pkgInfo length $length
  70.         return $pkgInfo
  71.     }
  72.  
  73.     #--------------------------------------------------------------------------
  74.     # Do the actual work of creating a package library index from a library
  75.     # file.
  76.     #
  77.     proc CreateLibIndex {libName} {
  78.         if {[file extension $libName] != ".tlib"} {
  79.             error "Package library `$libName' does not have the extension\
  80.                     `.tlib'"
  81.         }
  82.         set idxName "[file root $libName].tndx"
  83.  
  84.         catch {file delete $idxName}
  85.  
  86.         set contectHdl [scancontext create]
  87.  
  88.         scanmatch $contectHdl "^#@package: " {
  89.             if {[catch {llength $matchInfo(line)}] || 
  90.                 ([llength $matchInfo(line)] < 2)} {
  91.                 error "invalid package header \"$matchInfo(line)\""
  92.             }
  93.             if ![lempty $pkgInfo] {
  94.                 TclX::PutIdxEntry $idxFH $pkgInfo
  95.             }
  96.             set pkgInfo [TclX::ParsePkgHeader matchInfo]
  97.             incr packageCnt
  98.         }
  99.  
  100.         scanmatch $contectHdl "^#@packend" {
  101.             if [lempty $pkgInfo] {
  102.                 error "#@packend without #@package in $libName"
  103.             }
  104.             keylset pkgInfo length \
  105.                     [expr [keylget pkgInfo length] + \
  106.                           [clength $matchInfo(line)]+1]
  107.             TclX::PutIdxEntry $idxFH $pkgInfo
  108.             set pkgInfo {}
  109.         }
  110.  
  111.  
  112.         scanmatch $contectHdl {
  113.             if ![lempty $pkgInfo] {
  114.                 keylset pkgInfo length \
  115.                         [expr [keylget pkgInfo length] + \
  116.                               [clength $matchInfo(line)]+1]
  117.             }
  118.         }
  119.  
  120.         try_eval {
  121.             set libFH [open $libName r]
  122.             set idxFH [open $idxName w]
  123.             set packageCnt 0
  124.             set pkgInfo {}
  125.             
  126.             scanfile $contectHdl $libFH
  127.             if {$packageCnt == 0} {
  128.                 error "No \"#@package:\" definitions found in $libName"
  129.             }   
  130.             if ![lempty $pkgInfo] {
  131.                 TclX::PutIdxEntry $idxFH $pkgInfo
  132.             }
  133.         } {
  134.             catch {file delete $idxName}
  135.             error $errorResult $errorInfo $errorCode
  136.         } {
  137.             catch {close $libFH}
  138.             catch {close $idxFH}
  139.         }
  140.  
  141.         scancontext delete $contectHdl
  142.  
  143.         # Set mode and ownership of the index to be the same as the library.
  144.         # Ignore errors if you can't set the ownership.
  145.  
  146.         # FIX: WIN32, when chmod/chown work.
  147.         global tcl_platform
  148.         if ![cequal $tcl_platform(platform) "unix"] return
  149.  
  150.         file stat $libName statInfo
  151.         chmod $statInfo(mode) $idxName
  152.         catch {
  153.            chown [list $statInfo(uid) $statInfo(gid)] $idxName
  154.         }
  155.     }
  156.  
  157. } ;# namespace TclX
  158.  
  159. #------------------------------------------------------------------------------
  160. # Create a package library index from a library file.
  161. #
  162. proc buildpackageindex {libfilelist} {
  163.     foreach libfile $libfilelist {
  164.         if [catch {
  165.             TclX::CreateLibIndex $libfile
  166.         } errmsg] {
  167.             global errorInfo errorCode
  168.             error "building package index for `$libfile' failed: $errmsg" \
  169.                 $errorInfo $errorCode
  170.         }
  171.     }
  172. }
  173.  
  174.