DoConf.py :  » Build » A-A-P » aap-1.091 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Build » A A P 
A A P » aap 1.091 » DoConf.py
# Part of the A-A-P recipe executive: configure command handling

# 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

import Global
from Util import *
from Message import *
from Conftest import CheckFunc,CheckHeader,CheckType,CheckLib,CheckBuilder


class ConfContext:
    """
    Context for configure tests.  Used for the _conf scope.
    """
    def __init__(self, vardict):
        """
        The "_conf" scope is used for variables, so that things like $CC and
        $LIBS can use the value from the _conf scope.
        """
        self.vardict = vardict
        self.havedict = {}
        self.headerfilename = "confdefs.h"
        self.headerclean = 0        # set to 1 when headerfilename has been
                                    # cleared
        self.default_lang = None

    def Display(self, msg):
        msg_info(Global.globals, msg, msgm_cont)

    def Log(self, msg):
        msg_log(Global.globals, msg, msgm_cont)

    def AppendLIBS(self, lib_name_list):
        from Scope import find_recdict

        # Find the recdict where "LIBS" is defined and obtain the old value.
        # Also obtain the old value of $_conf.LIBS.
        rd = find_recdict(Global.globals, "LIBS")
        if rd:
            oldval = rd.get("LIBS")
        else:
            oldval = None
        conf_oldval = Global.globals["_conf"].data.get("LIBS")

        # Append library/libraries to the old value.
        if oldval:
            newval = oldval
        else:
            newval = ""
        for k in lib_name_list:
            if newval:
                newval = newval + " "
            newval = newval + ("-l%s" % k)

        # Set the new value in the same scope.  Also set $_conf.LIBS, so that
        # ":conf write recipe" will use the new value.
        if rd:
            rd["LIBS"] = newval
        Global.globals["_conf"].data["LIBS"] = newval

        return [rd, oldval, conf_oldval]

    def SetLIBS(self, newval):
        # Get the recdict, and old values from the list that AppendLIBS()
        # returned.
        rd = newval[0]
        oldval = newval[1]
        conf_oldval = newval[2]

        # Get the current value of $LIBS in ret_oldval and store the value from
        # newval.
        if rd:
            ret_oldval = rd.get("LIBS")
            rd["LIBS"] = oldval
        else:
            ret_oldval = None

        # Get the current value of $_conf.LIBS in ret_conf_oldval and store
        # the value from newval.
        ret_conf_oldval = Global.globals["_conf"].get("LIBS")
        if conf_oldval is None:
            del Global.globals["_conf"].data["LIBS"]
        else:
            Global.globals["_conf"].data["LIBS"] = conf_oldval

        return [rd, ret_oldval, ret_conf_oldval]


    def BuildProg(self, text, ext):
        self.Log("\n")          # add a line break after "Checking..."

        # source -> object
        src = "conftest" + ext
        trg = "conftest" + Global.globals["_no"].OBJSUF
        res = self.RunAction("compile", text, src, trg)

        if not res:
            # object -> program
            src = trg
            if ext == ".cpp":
                src = src + "{buildaction = cxx_build}"
            trg = "conftest" + Global.globals["_no"].EXESUF
            res = self.RunAction("build", None, src, trg)

        try_delete(trg)
        return res

    def CompileProg(self, text, ext):
        self.Log("\n")          # add a line break after "Checking..."

        # source -> object
        src = "conftest" + ext
        trg = "conftest" + Global.globals["_no"].OBJSUF
        res = self.RunAction("compile", text, src, trg)
        try_delete(trg)
        return res

    def RunAction(self, action, text, src, trg):
        """
        Run action "action" with source "src" and target "trg".
        When "text" is not None write it to "src".
        Afterwards "src" is always deleted.
        Returns an empty string for success, an error message for failure.
        """
        save_message = Global.globals.get("MESSAGE")
        Global.globals["MESSAGE"] = ""
        save_sys_cmd_log = Global.sys_cmd_log
        Global.sys_cmd_log = " "

        try:
            from Commands import aap_do
            if text:
                f = open(src, "w")
                f.write(text)
                f.close()
            aap_do(0, Global.globals, "%s {target = %s} %s"
                                                          % (action, trg, src))
            msg = ""

            # If there is no error but there is output, log it (e.g., for a
            # warning).
            if Global.sys_cmd_log != " ": 
                msg_log(Global.globals, Global.sys_cmd_log)

        except UserError:
            msg = ((_("Failed to %s test program:") % action)
                                               + Global.sys_cmd_log)

        if save_message is None:
            del Global.globals["MESSAGE"]
        else:
            Global.globals["MESSAGE"] = save_message
        Global.sys_cmd_log = save_sys_cmd_log

        try_delete(src)
        return msg



def init_conf_dict(confdict):
    """
    Called to init a ConfContext() object and add it to the "_conf" scope
    "confdict".
    """
    # "confdict" is used for context.vardict, so that the variables are
    # available as $_conf.VAR.
    context = ConfContext(confdict)

    # _conf.context is used to access the ConfContext object
    confdict["context"] = context

    # _conf.have is a shortcut to _conf.context.havedict
    confdict["have"] = context.havedict


def doconf(line_nr, recdict, optiondict, argdictlist):
    """
    Do the configure checks.  Implementation of the ":conf" command.
    """
    from Work import getrpstack
    from Process import recipe_error
    rpstack = getrpstack(recdict, line_nr)

    # Get the ConfContext object from the _conf scope.
    context = recdict["_conf"].context

    command = argdictlist[0]["name"]

    # Init the configure stuff when not done already.
    # TODO: Is it possible that the file is truncated with an ":execute"
    # command?
    if not context.headerclean and command != "init":
        _init_conf(context)

    if command in [ "header", "function", "type", "lib" ]:
        #
        # :conf header stdlib.h ...
        # :conf function snprintf ...
        # :conf type size_t ...
        # :conf lib iconv,iconv_open ...
        #
        if len(argdictlist) < 2:
            recipe_error(rpstack, _('":conf %s" requires at least one more argument') % command)
        found = 0
        for i in range(1, len(argdictlist)):
            testarg = argdictlist[i]["name"]
            headerarg = argdictlist[i].get("header")
            langarg = argdictlist[i].get("language")
            if not langarg:
                langarg = context.default_lang

            if command == "header":
                msg = CheckHeader(context, testarg,
                                        header = headerarg, language = langarg)
            elif command == "type":
                fallbackarg = argdictlist[i].get("fallback")
                msg = CheckType(context, testarg, fallback = fallbackarg,
                                        header = headerarg, language = langarg)
            elif command == "lib":
                call = argdictlist[i].get("call")
                comma = string.find(testarg, ",")
                if comma < 0:
                    if not call:
                        recipe_error(rpstack,
                                _('":conf lib" requires an argument in the form libname,funcname.'))
                    lib_name = testarg
                    func_name = None
                else:
                    lib_name = testarg[0:comma]
                    func_name = testarg[comma+1:]
                msg = CheckLib(context, lib_name, func_name, call = call,
                                        header = headerarg, language = langarg)
            else: # command == "function"
                msg = CheckFunc(context, testarg,
                                        header = headerarg, language = langarg)

            if not msg:
                found = 1
                if optiondict.get("oneof"):
                    break
            elif optiondict.get("required"):
                recipe_error(rpstack, _('required %s "%s" not found.')
                                                          % (command, testarg))
        if not found and optiondict.get("oneof"):
            from Dictlist import dictlist2str
            recipe_error(rpstack,
                    _('None of the %ss found for ":conf {oneof} %s"')
                    % (command,
                       dictlist2str(argdictlist, Expand(0, Expand.quote_aap))))

    elif command == "write":
        #
        # :conf write header config.h
        # :conf write recipe config.aap
        #
        from Dictlist import dictlist_expand
        dictlist_expand(argdictlist)
        if len(argdictlist) != 3:
            recipe_error(rpstack, _('":conf write" requires two arguments'))
        what = argdictlist[1]["name"]
        fname = argdictlist[2]["name"]

        if what == "header":
            # We copy confdefs.h to the target file.  This makes sure the same
            # file that was used for testing is used.
            from CopyMove import remote_copy_move
            remote_copy_move(rpstack, recdict, 1,
                             [ {"name" : context.headerfilename} ],
                             { "name" : fname },
                             { 'mkdir' : 1, 'force' : 1}, 0, errmsg = 1)
        elif what == "recipe":
            try:
                f = open(fname, "w")
            except StandardError, e:
                recipe_error(rpstack, _('Could not create recipe "%s": %s')
                                                             % (fname, str(e)))
            try:
                f.write("# Generated by Aap.  You are not supposed to edit this file.\n\n")
                for k in context.vardict.keys():
                    if not k in ["have", "context"] and context.vardict[k]:
                        f.write("%s = %s\n" % (k, context.vardict[k]))
                f.close()
            except StandardError, e:
                recipe_error(rpstack, _('Could not write to recipe "%s": %s')
                                                             % (fname, str(e)))
            else:
                msg_info(recdict, 'Written config recipe "%s"' % fname)

        else:
            recipe_error(rpstack, _('Unsupported argument for ":conf write": "%s"') % what)

    elif command == "init":
        #
        # :conf init
        #
        if len(argdictlist) > 1:
            recipe_error(rpstack, _('Too many arguments for ":conf init"'))
        _init_conf(context)

    elif command == "language":
        #
        # :conf language C++
        #
        if len(argdictlist) != 2:
            recipe_error(rpstack, _('":conf language" requires one argument'))
        context.default_lang = argdictlist[1]["name"]
        # check for a valid language
        msg = CheckBuilder(context, language = context.default_lang)
        if msg:
            msg_warning(recdict, _('Cannot compile a simple %s program: %s')
                                                 % (context.default_lang, msg))

    else:
        recipe_error(rpstack, _('Unsupported :conf argument: "%s"') % command)


def _init_conf(context):
    """
    Init the configure stuff.  This makes sure the "headerfilename" is empty.
    """
    try:
        f = open(context.headerfilename, "w+")
        f.write("/* Generated by Aap.  You are not supposed to edit this file. */\n\n")
        f.close()
    except StandardError, e:
        msg_warning(Global.globals, _("Could not make %s empty: %s")
                                        % (context.headerfilename, str(e)))
    context.headerclean = 1


def cleanup(recdict):
    """
    Cleanup after doing configure checks.
    """
    # Get the ConfContext object from the _conf scope.
    context = recdict["_conf"].context

    try_delete(context.headerfilename)

# vim: set sw=4 et sts=4 tw=79 fo+=l:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.