#  Copyright (c) 2005 Vladimir Prus.
# Copyright René Ferdinand Rivera Morell
#
#  Use, modification and distribution is subject to the Boost Software
#  License Version 1.0. (See accompanying file LICENSE.txt or
#  https://www.bfgroup.xyz/b2/LICENSE.txt)

import modules ;
import args ;

# Set a value for a named option, to be used when not overridden on the command
# line.
rule set ( name : value ? )
{
    .option.$(name) = $(value) ;
}

rule get ( name : default-value ? : implied-value ? )
{
    local m = [ args.get-arg $(name) ] ;
    # For backwards compat also check ARGV directly in case the arg has not been
    # declared.
    if ! $(m) && ! [ args.has-arg $(name) ]
    {
        m = [ MATCH --$(name)=(.*) : [ modules.peek : ARGV ] ] ;
    }
    if $(m) && $(m) != true
    {
        return $(m[1]) ;
    }
    if $(m) && $(implied-value)
    {
        return $(implied-value) ;
    }
    if $(.option.$(name))
    {
        return $(.option.$(name)) ;
    }
    return $(default-value) ;
}


# Check command-line args as soon as possible. For each option try to load
# module named after option. Is that succeeds, invoke 'process' rule in the
# module. The rule may return "true" to indicate that the regular build process
# should not be attempted.
#
# Options take the general form of: --<name>[=<value>] [<value>]
#
rule process ( )
{
    local ARGV = [ modules.peek : ARGV ] ;
    local BOOST_BUILD_PATH = [ modules.peek : BOOST_BUILD_PATH ] ;

    local dont-build ;
    local args = $(ARGV) ;
    while $(args)
    {
        local arg = [ MATCH ^--(.*) : $(args[1]) ] ;
        while $(args[2-]) && ! $(arg)
        {
            args = $(args[2-]) ;
            arg = [ MATCH ^--(.*) : $(args[1]) ] ;
        }
        args = $(args[2-]) ;

        if $(arg)
        {
            local split = [ MATCH "^(([^-=]+)[^=]*)(=?)(.*)$" : $(arg) ] ;
            local full-name = $(split[1]) ;
            local prefix = $(split[2]) ;
            local values ;

            if $(split[3])
            {
                values = $(split[4]) ;
            }
            if $(args) && ! [ MATCH ^(--).* : $(args[1]) ]
            {
                values += $(args[1]) ;
                args = $(args[2-]) ;
            }

            # Jook in options subdirectories of BOOST_BUILD_PATH for modules
            # matching the full option name and then its prefix.
            local plugin-dir = options ;
            local option-files = [ GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) :
                $(full-name).jam $(prefix).jam ] ;

            if $(option-files)
            {
                # Load the file into a module named for the option.
                local f = $(option-files[1]) ;
                local module-name = --$(f:D=:S=) ;
                modules.load $(module-name) : $(f:D=) : $(f:D) ;

                # If there is a process rule, call it with the full option name
                # and its value (if any). If there was no "=" in the option, the
                # value will be empty.
                if process in [ RULENAMES $(module-name) ]
                {
                    dont-build += [ modules.call-in $(module-name) : process
                        --$(full-name) : $(values) ] ;
                }
            }
        }
    }

    return $(dont-build) ;
}
