# Part of the A-A-P recipe executive: Add default rules and dependencies

# Copyright (C) 2002 Stichting NLnet Labs
# Permission to copy and use this file is specified in the file COPYING.
# If this file is missing you can find it here: http://www.a-a-p.org/COPYING

import string
import os.path

from Dictlist import string2dictlist, var2dictlist, dictlist2str, dictlistattr2str
from Rule import Rule, find_rule
from RecPos import RecPos
from Util import *
from Depend import Depend
from Dictlist import get_attrdict
from Message import *


def add_def_rule(work, targetcheck, target, sourcecheck, source,
			    build_attr, commands):
    if find_rule(work, targetcheck, sourcecheck):
        return	# rule for this target-source already exists

    # Add a default rule; Expand the source and target into dictlists.
    rpstack = [RecPos("Default rule")]
    targetlist = string2dictlist(rpstack, target)
    buildcheck, i = get_attrdict(rpstack, None, build_attr, 0, 0)
    sourcelist = string2dictlist(rpstack, source)
    work.add_rule(Rule(targetlist, buildcheck, sourcelist,
					      rpstack, "  " + commands + "\n"))


def doadddef(work):
    """
    Add default rules and dependencies, depending on what was defined in the
    recipe(s) read.
    """

    #
    # Add rules that are not covered by recipes.
    # TODO: put this separately somehow
    #
    add_def_rule(work, "%.o", "%.o",
		    "%.c", "%.c {check = c_md5}",
		    "{buildcheck = $CC $CFLAGS $CPPFLAGS}",
		    ":sys $CC $CFLAGS $CPPFLAGS -c $source -o $target")
    add_def_rule(work, "%.obj", "%.obj",
		    "%.c", "%.c {check = c_md5}",
		    "{buildcheck = $CC $CFLAGS $CPPFLAGS}",
		    ":sys $CC $CFLAGS $CPPFLAGS -c $source -o $target")


    #
    # If there is no dependency: create one from $SOURCE and $TARGET
    # Only possible if both are defined.
    #
    if not work.dependencies \
	    and work.globals.has_key("TARGET") and work.globals["TARGET"] \
	    and work.globals.has_key("SOURCE") and work.globals["SOURCE"]:

        targets = var2dictlist(work.globals, "TARGET")
        sources = var2dictlist(work.globals, "SOURCE")
	targets_len = len(targets)
	sources_len = len(sources)

	#
	# If there is a single target and no default rule or more than one
	# source, add a dependency with a link command in the form:
	#   $TARGET : {buildcheck = xxx} $BDIR/$SOURCE-OBJ
	#       link-command
	#
	if targets_len == 1 and (sources_len > 1
	       or not find_rule(work, targets[0]["name"], sources[0]["name"])):

	    # Created node for all items in $SOURCE and $TARGET, makes sure
	    # the attributes are carried over.
	    work.add_dictlist_nodes(sources)
	    work.add_dictlist_nodes(targets)

	    # For each source change the extension to $OBJSUF.
	    new_sources = []
	    i = 0
	    while i < sources_len:
		n = os.path.join(get_var_val(0, work.globals, "BDIR"),
							    sources[i]["name"])
		di = string.rfind(n, ".")
		if di > 0:
		    n = n[:di] + get_var_val(0, work.globals, "OBJSUF")
		# TODO: any attributes we should include here?
		new_sources.append({"name" : n})
		i = i + 1

	    rpstack = [RecPos("Default target")]
	    cmd = "  :sys $CC $CFLAGS $LDFLAGS -o $target $source\n"
	    attr, i = get_attrdict(rpstack, None,
					 "{buildcheck=$CFLAGS $LDFLAGS}", 0, 0)

	    msg_depend(_('Adding dependency from $TARGET and $SOURCE:\n%s : %s %s\n    %s')
		     % (dictlist2str(targets), dictlistattr2str(attr),
					       dictlist2str(new_sources), cmd))
	    work.add_dependency(rpstack,
		     Depend(targets, attr, new_sources, work, rpstack, cmd), 1)


# vim: set sw=4 sts=4 tw=79 fo+=l:
