# Jambase
# $Id:$

# This is a jambase that knows just enough to execute SubDir and
# include the Jamrules

# Allow base jamrules to require this file
BHBJAM = true ;

# other files
JAMFILE default = Jamfile ;
JAMRULES default = BhbJambase ;

# Basic utility variables
NEWLINE = "
" ;
SLASH = "/" ;
DOT = "." ;
DOTDOT = ".." ;

rule SubDir
{
	local r s ;

  #
  # SubDir TOP d1 [ ... ]
  #
  # This introduces a Jamfile that is part of a project tree 
  # rooted at $(TOP).  It (only once) includes the project-specific
  # rules file $(TOP)/CustomJambase and then sets search & locate stuff.
  #
  # If the variable $(TOPRULES) is set (where TOP is the first arg 
  # to SubDir), that file is included instead of $(TOP)/CustomJambase.
  #
  # Unlike the original Jambase, this just includes the CustomJambase
  # everything else is up to UserSubDir
  #

  if ! $($(<[1])-defined)
  {
    if ! $(<[1])
    {
      EXIT SubDir syntax error ;
    }

    makeSubDir $(<[1]) : $(<[2-]) ;

    $(<[1])-defined = true ;
  }

  #
  # If $(TOP)/Jamrules hasn't been included, do so.
  #

  if ! $($(<[1])-included)
  {
    # Gated entry.

    $(<[1])-included = TRUE ;

    # File is $(TOPRULES) or $(TOP)/Jamrules.

    r = $($(<[1])RULES) ;

    if ! $(r)
    {
      r = $(JAMRULES:R=$($(<[1]))) ;
    }

    # Include it.
    include $(r) ;
  }

  UserSubDir $(<) ;
}

rule UserSubDir
{
  # Empty Hook
}

# -------------
# Utility rules
# -------------
#
# From the original Jambase

rule makeString
{
	local _t ;

	$(<) = $(>[1]) ;
	for _t in $(>[2-])
	{
		$(<) = $($(<))$(_t) ;
	}
}

rule makeSubDir
{
	local _i _d ;

	# If $(>) is the path to the current directory, compute the
	# path (using ../../ etc) back to that root directory.
	# Sets result in $(<)

	if ! $(>[1]) 
	{
	    _d = $(DOT) ;
	} 
	else
	{
	    _d = $(DOTDOT) ;

	    for _i in $(>[2-])
	    {
		_d = $(_d:R=$(DOTDOT)) ;
	    }
	}

	$(<) = $(_d) ;
}

rule addDirName
{
	local _s _i ;

	# Turn individual elements in $(>) into a usable path.
	# Add result to $(<).

	if ! $(>)
	{
	    _s = $(DOT) ;
	}
	else if $(VMS)
	{
	    # This handles the following cases:
	    # 	a -> [.a]
	    # 	a b c -> [.a.b.c]
	    # 	x: -> x:
	    # 	x: a -> x:[a]
	    # 	x:[a] b -> x:[a.b]

	    switch $(>[1])
	    {
	    case *:* : _s = $(>[1]) ;
	    case \\[*\\] : _s = $(>[1]) ;
	    case * : _s = [.$(>[1])] ;
	    }

	    for _i in [.$(>[2-])]
	    {
		_s = $(_i:R=$(_s)) ;
	    }
	}
	else if $(MAC)
	{
	    _s = $(DOT) ;
	    
	    for _i in $(>)
	    {
	    	_s = $(_i:R=$(_s)) ;
	    }
	}
	else
	{
	    _s = $(>[1]) ; 

	    for _i in $(>[2-])
	    {
		_s = $(_i:R=$(_s)) ;
	    }
	}

	$(<) += $(_s) ;
}

rule makeDirName
{
	$(<) = ; addDirName $(<) : $(>) ;
}

rule makeGrist
{
	local _g _i ;

	# Turn individual elements in $(>) into grist.
	# Return result in $(<)

	_g = $(>[1]) ;

	for _i in $(>[2-])
	{
	    _g = $(_g)!$(_i) ;
	}

	$(<) = $(_g) ;
}

rule makeGristedName
{
	local _i _o ;

	# Produce name with grist in it, if SOURCE_GRIST is set.

	if ! $(SOURCE_GRIST)
	{
	    $(<) = $(>) ;
	}
	else 
	{
	    _o = ;
	    for _i in $(>)
	    {
		switch $(_i)
		{
		case *.h :	_o += $(_i) ;
		case * : 	_o += $(_i:G=$(SOURCE_GRIST)) ;
		}
	    }
	    $(<) = $(_o) ;
	}
}

rule makeCommon
{
	if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
	{
	    $(<) = $($(<)[2-]) ;
	    $(>) = $($(>)[2-]) ;
	    makeCommon $(<) : $(>) ;
	}
}

rule makeRelPath 
{
	local _l _r ;

	# first strip off common parts

	_l = $(<[2-]) ;
	_r = $(>) ;

	makeCommon _l : _r ;

	# now make path to root and path down

	makeSubDir _l : $(_l) ;
	makeDirName _r : $(_r) ;

	# Concatenate and save

	# XXX This should be better

	if $(_r) = $(DOT) {
	    $(<[1]) = $(_l) ;
	} else {
	    $(<[1]) = $(_r:R=$(_l)) ;
	}
}

rule makeSuffixed
{
   # E.g., "makeSuffixed s_exe $(SUFEXE) : yacc lex foo.bat ;"
   # sets $(s_exe) to (yacc,lex,foo.bat) on Unix and 
   # (yacc.exe,lex.exe,foo.bat) on NT.

	if $(<[2])
	{
	    local _i ;

	    $(<[1]) = ;

	    for _i in $(>)
	    {
		if $(_i:S)
		{
		    $(<[1]) += $(_i) ;
		}
		else
		{
		    $(<[1]) += $(_i:S=$(<[2])) ;
		}
	    }
	}
	else
	{
	    $(<[1]) = $(>) ;
	}
}

rule unmakeDir
{
    if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ 
    {
        unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;
    }
    else
    {
        $(<) = $(>) ;
    }
}

# -------------------
# Include the Jamfile
# -------------------

{
  if $(JAMFILE) { include $(JAMFILE) ; }
}