# Part of the A-A-P recipe executive: Testing of automatic dependencies

# Copyright (C) 2002-2003 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

#
# This test checks that the following works properly:
# - A C file is used as a source, it needs to be scanned for included files.
# - One of the included files is a target in a dependency.
# - If the dependency changes the included file to include other files than
#   before the list of dependencies must be redone.
# - The source file is in a subdirectory, it should find included headers
#   there.
#

import sys, os, shutil, glob, string

def runaap(args):
    return os.system("%s ..%sMain.py %s" % (sys.argv[1], os.sep, args))

os.chdir("rectest")

# Create a recipe with a different filetype for the target, so that a different
# build action will be used.
# Check that the right action is used.
rec = "rectest.aap"
out = "rectest.out"
tdir = "rectestdir"
inp = "%s/rectest.c" % tdir
incl1 = "incl1.h"
incl2 = "incl2.h"
incl3 = "incl3.h"
incl1path = "%s/%s" % (tdir, incl1)
incl2path = "%s/%s" % (tdir, incl2)
incl3path = "%s/%s" % (tdir, incl3)

def cleanup():
    for file in [ rec, out, inp, incl1path, incl2path, incl3path ]:
	try:
	    os.remove(file)
	except:
	    pass
    try:
        shutil.rmtree(tdir)
    except:
        pass
    try:
	for dir in glob.glob('build-*'):
	    shutil.rmtree(dir)
    except:
	pass

cleanup()
os.mkdir(tdir)

inptext = """
HASGCC = no         # disable using gcc for dependency check
MESSAGE =           # be silent

all: %s
        f = $BDIR/$(source).aap
        :print (((`file2string(f)`)))
%s :
        :print $(#)include "%s" >! $target
""" % (inp, incl1path, incl2)

incl3_line = """        :print $(#)include "%s" >> $target
""" % incl3

# Create the source file that includes "incl1"
f = open(inp, "w")
f.write("""
#include <stdio.h>
#include "%s"
int main() { printf("Hello World!\\n"); return 0;}
""" % incl1)
f.close()

# Generate the header files.  "incl1" will be changed later.
for n in [incl1path, incl2path, incl3path]:
    f = open(n, "w")
    f.write("""
    /* nothing */
    """)
    f.close()

def updatecheck(round, actual, name):
    expected = '- updating target "%s"' % name
    if string.find(actual, expected) < 0:
        print '(%d) Did not find remark in log file: "%s"' % (round, expected)
        return 1
    return 0

def doit():
    res = 0
    for round, add_incl3, updated, scanned in [
            # should find correct dependencies.
                (1, 0, [incl1path, incl2path], 1),
            # should find the same without dependency check
                (2, 0, [incl1path, incl2path], 0),
            # should find third include file
                (3, 1, [incl1path, incl2path, incl3path], 1),
            # should not find third include file
                (4, 0, [incl1path, incl2path], 1),
             ]:

        # Create the recipe.
        f = open(rec, "w")
        f.write(inptext)
        if add_incl3:
            f.write(incl3_line)     # Also include "incl3".
        f.close()

        if runaap("-f %s >%s" % (rec, out)):
            res = 1
        f = open("AAPDIR/log")
        logtext = f.read()
        f.close()

        # Avoid seeing differences in forward slashes and backslashes.
        logtext = string.replace(logtext, "\\", "/")
        
        for n in updated:
            res = res + updatecheck(round, logtext, n)

        # Check if correct dependencies were found.
        f = open(out)
        outtext = f.read()
        f.close()
        depline = outtext[string.find(outtext, "(((") + 3 :
                            string.find(outtext, ")))")]
        deps = string.split(depline)

        # All expected dependencies must be in output.
        for n in updated:
            if n not in deps:
                print ('(%d) Did not find dependency in Aap output: "%s"'
                                                                  % (round, n))
                print 'Actual dependencies: %s' % str(deps)
                res = 1
        # All dependencies in output must be expected.
        for n in deps:
            if n and n != ":" and n not in updated + [inp]:
                print ('(%d) Found extra dependency in Aap output: "%s"'
                                                                  % (round, n))
                print 'Actual dependencies: %s' % str(deps)
                res = 1

        idx = string.find(logtext, "Scanning")
        if scanned:
            if idx < 0:
                print '(%d) Did not scan file' % round
                res = 1
        else:
            if idx >= 0:
                print '(%d) Scanned file again unneccesarily' % round
                res = 1

    return res

res = doit()

cleanup()

sys.exit(res)


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