# 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: