#!/bin/sh
# the next line restarts using the interpreter \
exec tclsh "$0" "$@"

# $Id: source.tcl,v 1.14 2002/05/30 17:13:10 jfontain Exp $

# This utility can be used to combine all sourced files making a Tcl
# program into a single file, so that the source command is no longer
# required for the program to run.

# This is most useful for creating tclets (Tcl applets) running within
# the Tcl plug-in, which, as a safe interpreter, does not allow files to
# be sourced by default (read the Tcl plugin faq for ways to allow
# sourcing files).

# type "source.tcl -h" for usage.

proc sourceCode {fileName} {
    global sourced directories duplicates

    if {!$duplicates&&[info exists sourced($fileName)]} {
        return {}                                                                     ;# do not process the same file more than once
    }
    set sourced($fileName) {}

    set code {}
    if {[string length $fileName]==0} {
        set file stdin
    } else {
        if {[string match /* $fileName]} {
            set file [open $fileName]
        } else {
            foreach directory $directories {                                                          ;# search multiple directories
                if {![catch {set file [open $directory/$fileName]}]} break
            }
        }
        if {![info exists file]} {
            puts stderr "could not find file $fileName"
            exit 1
        }
    }
    set skip 0
    while {[gets $file line]>=0} {
        set continues [string match {*\\} $line]
        if {$skip||[regexp {^[ 	]*#} $line]} {                                        ;# skip comments and eventually following line
            set skip $continues
            continue
        }
        if {!$continues} {
            regsub {[ 	]*;#.*$} $line {} line                  ;# eventually remove trailing comments or blanks on terminated lines
        }
        if {[scan $line { source %s} name]>0} {
            append code [sourceCode [subst $name]]
            continue
        }
        append code $line\n
    }
    if {[string length $fileName]>0} {
        close $file
    }
    return $code
}

if {[string match -h* [lindex $argv 0]]} {
    puts "usage: $argv0 \[-o outputFile\] \[inputFile\]"
    exit
}

set duplicates 0
set output stdout
set directories .                      ;# always start with current directory for files included through the source command facility

foreach {option value} $argv {
    switch -- $option {
        -d {
            set duplicates $value
        }
        -I {
            lappend directories $value
        }
        -o {
            set output [open $value w]
        }
    }
}

puts $output [sourceCode $option]
close $output
