# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2012, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# DESCRIPTION
# This module implements the templating engine used by 'yocto-bsp' to
# create BSPs.  The BSP templates are simply the set of files expected
# to appear in a generated BSP, marked up with a small set of tags
# used to customize the output.  The engine parses through the
# templates and generates a Python program containing all the logic
# and input elements needed to display and retrieve BSP-specific
# information from the user.  The resulting program uses those results
# to generate the final BSP files.
#
# AUTHORS
# Tom Zanussi <tom.zanussi (at] intel.com>
#

import os
import sys
from abc import ABCMeta, abstractmethod
from tags import *
import shlex
import json
import subprocess
import shutil

class Line():
    """
    Generic (abstract) container representing a line that will appear
    in the BSP-generating program.
    """
    __metaclass__ = ABCMeta

    def __init__(self, line):
        self.line = line
        self.generated_line = ""
        self.prio = sys.maxint
        self.discard = False

    @abstractmethod
    def gen(self, context = None):
        """
        Generate the final executable line that will appear in the
        BSP-generation program.
        """
        pass

    def escape(self, line):
        """
        Escape single and double quotes and backslashes until I find
        something better (re.escape() escapes way too much).
        """
        return line.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")

    def parse_error(self, msg, lineno, line):
         raise SyntaxError("%s: %s" % (msg, line))


class NormalLine(Line):
    """
    Container for normal (non-tag) lines.
    """
    def __init__(self, line):
        Line.__init__(self, line)
        self.is_filename = False
        self.is_dirname = False
        self.out_filebase = None

    def gen(self, context = None):
        if self.is_filename:
            line = "current_file = \"" + os.path.join(self.out_filebase, self.escape(self.line)) + "\"; of = open(current_file, \"w\")"
        elif self.is_dirname:
            dirname = os.path.join(self.out_filebase, self.escape(self.line))
            line = "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
        else:
            line = "of.write(\"" + self.escape(self.line) + "\\n\")"
        return line


class CodeLine(Line):
    """
    Container for Python code tag lines.
    """
    def __init__(self, line):
        Line.__init__(self, line)

    def gen(self, context = None):
        return self.line


class Assignment:
    """
    Representation of everything we know about {{=name }} tags.
    Instances of these are used by Assignment lines.
    """
    def __init__(self, start, end, name):
        self.start = start
        self.end = end
        self.name = name


class AssignmentLine(NormalLine):
    """
    Container for normal lines containing assignment tags.  Assignment
    tags must be in ascending order of 'start' value.
    """
    def __init__(self, line):
        NormalLine.__init__(self, line)
        self.assignments = []

    def add_assignment(self, start, end, name):
        self.assignments.append(Assignment(start, end, name))

    def gen(self, context = None):
        line = self.escape(self.line)

        for assignment in self.assignments:
            replacement = "\" + " + assignment.name + " + \""
            idx = line.find(ASSIGN_TAG)
            line = line[:idx] + replacement + line[idx + assignment.end - assignment.start:]
        if self.is_filename:
            return "current_file = \"" + os.path.join(self.out_filebase, line) + "\"; of = open(current_file, \"w\")"
        elif self.is_dirname:
            dirname = os.path.join(self.out_filebase, line)
            return "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
        else:
            return "of.write(\"" + line + "\\n\")"


class InputLine(Line):
    """
    Base class for Input lines.
    """
    def __init__(self, props, tag, lineno):
        Line.__init__(self, tag)
        self.props = props
        self.lineno = lineno

        try:
            self.prio = int(props["prio"])
        except KeyError:
            self.prio = sys.maxint

    def gen(self, context = None):
        try:
            depends_on = self.props["depends-on"]
            try:
                depends_on_val = self.props["depends-on-val"]
            except KeyError:
                self.parse_error("No 'depends-on-val' for 'depends-on' property",
                                 self.lineno, self.line)
        except KeyError:
            pass


class EditBoxInputLine(InputLine):
    """
    Base class for 'editbox' Input lines.

    props:
        name: example - "Load address"
        msg: example - "Please enter the load address"
    result:
        Sets the value of the variable specified by 'name' to
        whatever the user typed.
    """
    def __init__(self, props, tag, lineno):
        InputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        InputLine.gen(self, context)
        name = self.props["name"]
        if not name:
            self.parse_error("No input 'name' property found",
                             self.lineno, self.line)
        msg = self.props["msg"]
        if not msg:
            self.parse_error("No input 'msg' property found",
                             self.lineno, self.line)

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        msg += " [default: " + default_choice + "]"

        line = name + " = default(raw_input(\"" + msg + " \"), " + name + ")"

        return line


class GitRepoEditBoxInputLine(EditBoxInputLine):
    """
    Base class for 'editbox' Input lines for user input of remote git
    repos.  This class verifies the existence and connectivity of the
    specified git repo.

    props:
        name: example - "Load address"
        msg: example - "Please enter the load address"
    result:
        Sets the value of the variable specified by 'name' to
        whatever the user typed.
    """
    def __init__(self, props, tag, lineno):
        EditBoxInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        EditBoxInputLine.gen(self, context)
        name = self.props["name"]
        if not name:
            self.parse_error("No input 'name' property found",
                             self.lineno, self.line)
        msg = self.props["msg"]
        if not msg:
            self.parse_error("No input 'msg' property found",
                             self.lineno, self.line)

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        msg += " [default: " + default_choice + "]"

        line = name + " = get_verified_git_repo(\"" + msg + "\"," + name + ")"

        return line


class FileEditBoxInputLine(EditBoxInputLine):
    """
    Base class for 'editbox' Input lines for user input of existing
    files.  This class verifies the existence of the specified file.

    props:
        name: example - "Load address"
        msg: example - "Please enter the load address"
    result:
        Sets the value of the variable specified by 'name' to
        whatever the user typed.
    """
    def __init__(self, props, tag, lineno):
        EditBoxInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        EditBoxInputLine.gen(self, context)
        name = self.props["name"]
        if not name:
            self.parse_error("No input 'name' property found",
                             self.lineno, self.line)
        msg = self.props["msg"]
        if not msg:
            self.parse_error("No input 'msg' property found",
                             self.lineno, self.line)

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        msg += " [default: " + default_choice + "]"

        line = name + " = get_verified_file(\"" + msg + "\"," + name + ", True)"

        return line


class BooleanInputLine(InputLine):
    """
    Base class for boolean Input lines.
    props:
        name: example - "keyboard"
        msg:  example - "Got keyboard?"
    result:
        Sets the value of the variable specified by 'name' to "yes" or "no"
        example - keyboard = "yes"
    """
    def __init__(self, props, tag, lineno):
        InputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        InputLine.gen(self, context)
        name = self.props["name"]
        if not name:
            self.parse_error("No input 'name' property found",
                             self.lineno, self.line)
        msg = self.props["msg"]
        if not msg:
            self.parse_error("No input 'msg' property found",
                             self.lineno, self.line)

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        msg += " [default: " + default_choice + "]"

        line = name + " = boolean(raw_input(\"" + msg + " \"), " + name + ")"

        return line


class ListInputLine(InputLine):
    """
    Base class for List-based Input lines. e.g. Choicelist, Checklist.
    """
    __metaclass__ = ABCMeta

    def __init__(self, props, tag, lineno):
        InputLine.__init__(self, props, tag, lineno)
        self.choices = []

    def gen_choicepair_list(self):
        """Generate a list of 2-item val:desc lists from self.choices."""
        if not self.choices:
            return None

        choicepair_list = list()

        for choice in self.choices:
            choicepair = []
            choicepair.append(choice.val)
            choicepair.append(choice.desc)
            choicepair_list.append(choicepair)

        return choicepair_list

    def gen_degenerate_choicepair_list(self, choices):
        """Generate a list of 2-item val:desc with val=desc from passed-in choices."""
        choicepair_list = list()

        for choice in choices:
            choicepair = []
            choicepair.append(choice)
            choicepair.append(choice)
            choicepair_list.append(choicepair)

        return choicepair_list

    def exec_listgen_fn(self, context = None):
        """
        Execute the list-generating function contained as a string in
        the "gen" property.
        """
        retval = None
        try:
            fname = self.props["gen"]
            modsplit = fname.split('.')
            mod_fn = modsplit.pop()
            mod = '.'.join(modsplit)

            __import__(mod)
            # python 2.7 has a better way to do this using importlib.import_module
            m = sys.modules[mod]

            fn = getattr(m, mod_fn)
            if not fn:
                self.parse_error("couldn't load function specified for 'gen' property ",
                                 self.lineno, self.line)
            retval = fn(context)
            if not retval:
                self.parse_error("function specified for 'gen' property returned nothing ",
                                 self.lineno, self.line)
        except KeyError:
            pass

        return retval

    def gen_choices_str(self, choicepairs):
        """
        Generate a numbered list of choices from a list of choicepairs
        for display to the user.
        """
        choices_str = ""

        for i, choicepair in enumerate(choicepairs):
            choices_str += "\t" + str(i + 1) + ") " + choicepair[1] + "\n"

        return choices_str

    def gen_choices_val_str(self, choicepairs):
        """
        Generate an array of choice values corresponding to the
        numbered list generated by gen_choices_str().
        """
        choices_val_list = "["

        for i, choicepair in enumerate(choicepairs):
            choices_val_list += "\"" + choicepair[0] + "\","
        choices_val_list += "]"

        return choices_val_list

    def gen_choices_val_list(self, choicepairs):
        """
        Generate an array of choice values corresponding to the
        numbered list generated by gen_choices_str().
        """
        choices_val_list = []

        for i, choicepair in enumerate(choicepairs):
            choices_val_list.append(choicepair[0])

        return choices_val_list

    def gen_choices_list(self, context = None, checklist = False):
        """
        Generate an array of choice values corresponding to the
        numbered list generated by gen_choices_str().
        """
        choices = self.exec_listgen_fn(context)
        if choices:
            if len(choices) == 0:
                self.parse_error("No entries available for input list",
                                 self.lineno, self.line)
            choicepairs = self.gen_degenerate_choicepair_list(choices)
        else:
            if len(self.choices) == 0:
                self.parse_error("No entries available for input list",
                                 self.lineno, self.line)
            choicepairs = self.gen_choicepair_list()

        return choicepairs

    def gen_choices(self, context = None, checklist = False):
        """
        Generate an array of choice values corresponding to the
        numbered list generated by gen_choices_str(), display it to
        the user, and process the result.
        """
        msg = self.props["msg"]
        if not msg:
            self.parse_error("No input 'msg' property found",
                             self.lineno, self.line)

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        msg += " [default: " + default_choice + "]"

        choicepairs = self.gen_choices_list(context, checklist)

        choices_str = self.gen_choices_str(choicepairs)
        choices_val_list = self.gen_choices_val_list(choicepairs)
        if checklist:
            choiceval = default(find_choicevals(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)
        else:
            choiceval = default(find_choiceval(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)

        return choiceval


def find_choiceval(choice_str, choice_list):
    """
    Take number as string and return val string from choice_list,
    empty string if oob.  choice_list is a simple python list.
    """
    choice_val = ""

    try:
        choice_idx = int(choice_str)
        if choice_idx <= len(choice_list):
            choice_idx -= 1
            choice_val = choice_list[choice_idx]
    except ValueError:
        pass

    return choice_val


def find_choicevals(choice_str, choice_list):
    """
    Take numbers as space-separated string and return vals list from
    choice_list, empty list if oob.  choice_list is a simple python
    list.
    """
    choice_vals = []

    choices = choice_str.split()
    for choice in choices:
        choice_vals.append(find_choiceval(choice, choice_list))

    return choice_vals


def default(input_str, name):
    """
    Return default if no input_str, otherwise stripped input_str.
    """
    if not input_str:
        return name

    return input_str.strip()


def verify_git_repo(giturl):
    """
    Verify that the giturl passed in can be connected to.  This can be
    used as a check for the existence of the given repo and/or basic
    git remote connectivity.

    Returns True if the connection was successful, fals otherwise
    """
    if not giturl:
        return False

    gitcmd = "git ls-remote %s > /dev/null 2>&1" % (giturl)
    rc = subprocess.call(gitcmd, shell=True)
    if rc == 0:
        return True

    return False


def get_verified_git_repo(input_str, name):
    """
    Return git repo if verified, otherwise loop forever asking user
    for filename.
    """
    msg = input_str.strip() + " "

    giturl = default(raw_input(msg), name)

    while True:
        if verify_git_repo(giturl):
            return giturl
        giturl = default(raw_input(msg), name)


def get_verified_file(input_str, name, filename_can_be_null):
    """
    Return filename if the file exists, otherwise loop forever asking
    user for filename.
    """
    msg = input_str.strip() + " "

    filename = default(raw_input(msg), name)

    while True:
        if not filename and filename_can_be_null:
            return filename
        if os.path.isfile(filename):
            return filename
        filename = default(raw_input(msg), name)


def replace_file(replace_this, with_this):
    """
    Replace the given file with the contents of filename, retaining
    the original filename.
    """
    try:
        replace_this.close()
        shutil.copy(with_this, replace_this.name)
    except IOError:
        pass


def boolean(input_str, name):
    """
    Return lowercase version of first char in string, or value in name.
    """
    if not input_str:
        return name

    str = input_str.lower().strip()
    if str and str[0] == "y" or str[0] == "n":
        return str[0]
    else:
        return name


def strip_base(input_str):
    """
    strip '/base' off the end of input_str, so we can use 'base' in
    the branch names we present to the user.
    """
    if input_str and input_str.endswith("/base"):
        return input_str[:-len("/base")]
    return input_str.strip()


deferred_choices = {}

def gen_choices_defer(input_line, context, checklist = False):
    """
    Save the context hashed the name of the input item, which will be
    passed to the gen function later.
    """
    name = input_line.props["name"]

    try:
        nameappend = input_line.props["nameappend"]
    except KeyError:
        nameappend = ""

    try:
        branches_base = input_line.props["branches_base"]
    except KeyError:
        branches_base = ""

    filename = input_line.props["filename"]

    closetag_start = filename.find(CLOSE_TAG)

    if closetag_start != -1:
        filename = filename[closetag_start + len(CLOSE_TAG):]

    filename = filename.strip()
    filename = os.path.splitext(filename)[0]

    captured_context = capture_context(context)
    context["filename"] = filename
    captured_context["filename"] = filename
    context["nameappend"] = nameappend
    captured_context["nameappend"] = nameappend
    context["branches_base"] = branches_base
    captured_context["branches_base"] = branches_base

    deferred_choice = (input_line, captured_context, checklist)
    key = name + "_" + filename + "_" + nameappend
    deferred_choices[key] = deferred_choice


def invoke_deferred_choices(name):
    """
    Invoke the choice generation function using the context hashed by
    'name'.
    """
    deferred_choice = deferred_choices[name]
    input_line = deferred_choice[0]
    context = deferred_choice[1]
    checklist = deferred_choice[2]

    context["name"] = name

    choices = input_line.gen_choices(context, checklist)

    return choices


class ChoicelistInputLine(ListInputLine):
    """
    Base class for choicelist Input lines.
    props:
        name: example - "xserver_choice"
        msg:  example - "Please select an xserver for this machine"
    result:
        Sets the value of the variable specified by 'name' to whichever Choice was chosen
        example - xserver_choice = "xserver_vesa"
    """
    def __init__(self, props, tag, lineno):
        ListInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        InputLine.gen(self, context)

        gen_choices_defer(self, context)
        name = self.props["name"]
        nameappend = context["nameappend"]
        filename = context["filename"]

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"

        return line


class ListValInputLine(InputLine):
    """
    Abstract base class for choice and checkbox Input lines.
    """
    def __init__(self, props, tag, lineno):
        InputLine.__init__(self, props, tag, lineno)

        try:
            self.val = self.props["val"]
        except KeyError:
            self.parse_error("No input 'val' property found", self.lineno, self.line)

        try:
            self.desc = self.props["msg"]
        except KeyError:
            self.parse_error("No input 'msg' property found", self.lineno, self.line)


class ChoiceInputLine(ListValInputLine):
    """
    Base class for choicelist item Input lines.
    """
    def __init__(self, props, tag, lineno):
        ListValInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        return None


class ChecklistInputLine(ListInputLine):
    """
    Base class for checklist Input lines.
    """
    def __init__(self, props, tag, lineno):
        ListInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        InputLine.gen(self, context)

        gen_choices_defer(self, context, True)
        name = self.props["name"]
        nameappend = context["nameappend"]
        filename = context["filename"]

        try:
            default_choice = self.props["default"]
        except KeyError:
            default_choice = ""

        line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"

        return line


class CheckInputLine(ListValInputLine):
    """
    Base class for checklist item Input lines.
    """
    def __init__(self, props, tag, lineno):
        ListValInputLine.__init__(self, props, tag, lineno)

    def gen(self, context = None):
        return None


dirname_substitutions = {}

class SubstrateBase(object):
    """
    Base class for both expanded and unexpanded file and dir container
    objects.
    """
    def __init__(self, filename, filebase, out_filebase):
        self.filename = filename
        self.filebase = filebase
        self.translated_filename = filename
        self.out_filebase = out_filebase
        self.raw_lines = []
        self.expanded_lines = []
        self.prev_choicelist = None

    def parse_error(self, msg, lineno, line):
         raise SyntaxError("%s: [%s: %d]: %s" % (msg, self.filename, lineno, line))

    def expand_input_tag(self, tag, lineno):
        """
        Input tags consist of the word 'input' at the beginning,
        followed by name:value property pairs which are converted into
        a dictionary.
        """
        propstr = tag[len(INPUT_TAG):]

        props = dict(prop.split(":", 1) for prop in shlex.split(propstr))
        props["filename"] = self.filename

        input_type = props[INPUT_TYPE_PROPERTY]
        if not props[INPUT_TYPE_PROPERTY]:
            self.parse_error("No input 'type' property found", lineno, tag)

        if input_type == "boolean":
            return BooleanInputLine(props, tag, lineno)
        if input_type == "edit":
            return EditBoxInputLine(props, tag, lineno)
        if input_type == "edit-git-repo":
            return GitRepoEditBoxInputLine(props, tag, lineno)
        if input_type == "edit-file":
            return FileEditBoxInputLine(props, tag, lineno)
        elif input_type == "choicelist":
            self.prev_choicelist = ChoicelistInputLine(props, tag, lineno)
            return self.prev_choicelist
        elif input_type == "choice":
            if not self.prev_choicelist:
                self.parse_error("Found 'choice' input tag but no previous choicelist",
                                 lineno, tag)
            choice = ChoiceInputLine(props, tag, lineno)
            self.prev_choicelist.choices.append(choice)
            return choice
        elif input_type == "checklist":
            return ChecklistInputLine(props, tag, lineno)
        elif input_type == "check":
            return CheckInputLine(props, tag, lineno)

    def expand_assignment_tag(self, start, line, lineno):
        """
        Expand all tags in a line.
        """
        expanded_line = AssignmentLine(line.rstrip())

        while start != -1:
            end = line.find(CLOSE_TAG, start)
            if end == -1:
                self.parse_error("No close tag found for assignment tag", lineno, line)
            else:
                name = line[start + len(ASSIGN_TAG):end].strip()
                expanded_line.add_assignment(start, end + len(CLOSE_TAG), name)
                start = line.find(ASSIGN_TAG, end)

        return expanded_line

    def expand_tag(self, line, lineno):
        """
        Returns a processed tag line, or None if there was no tag

        The rules for tags are very simple:
            - No nested tags
            - Tags start with {{ and end with }}
            - An assign tag, {{=, can appear anywhere and will
              be replaced with what the assignment evaluates to
            - Any other tag occupies the whole line it is on
                - if there's anything else on the tag line, it's an error
                - if it starts with 'input', it's an input tag and
                  will only be used for prompting and setting variables
                - anything else is straight Python
                - tags are in effect only until the next blank line or tag or 'pass' tag
                - we don't have indentation in tags, but we need some way to end a block
                  forcefully without blank lines or other tags - that's the 'pass' tag
                - todo: implement pass tag
                - directories and filenames can have tags as well, but only assignment
                  and 'if' code lines
                - directories and filenames are the only case where normal tags can
                  coexist with normal text on the same 'line'
        """
        start = line.find(ASSIGN_TAG)
        if start != -1:
            return self.expand_assignment_tag(start, line, lineno)

        start = line.find(OPEN_TAG)
        if start == -1:
            return None

        end = line.find(CLOSE_TAG, 0)
        if end == -1:
             self.parse_error("No close tag found for open tag", lineno, line)

        tag = line[start + len(OPEN_TAG):end].strip()

        if not tag.lstrip().startswith(INPUT_TAG):
            return CodeLine(tag)

        return self.expand_input_tag(tag, lineno)

    def append_translated_filename(self, filename):
        """
        Simply append filename to translated_filename
        """
        self.translated_filename = os.path.join(self.translated_filename, filename)

    def get_substituted_file_or_dir_name(self, first_line, tag):
        """
        If file or dir names contain name substitutions, return the name
        to substitute.  Note that this is just the file or dirname and
        doesn't include the path.
        """
        filename = first_line.find(tag)
        if filename != -1:
            filename += len(tag)
        substituted_filename = first_line[filename:].strip()
        this = substituted_filename.find(" this")
        if this != -1:
            head, tail = os.path.split(self.filename)
            substituted_filename = substituted_filename[:this + 1] + tail
            if tag == DIRNAME_TAG: # get rid of .noinstall in dirname
                substituted_filename = substituted_filename.split('.')[0]

        return substituted_filename

    def get_substituted_filename(self, first_line):
        """
        If a filename contains a name substitution, return the name to
        substitute.  Note that this is just the filename and doesn't
        include the path.
        """
        return self.get_substituted_file_or_dir_name(first_line, FILENAME_TAG)

    def get_substituted_dirname(self, first_line):
        """
        If a dirname contains a name substitution, return the name to
        substitute.  Note that this is just the dirname and doesn't
        include the path.
        """
        return self.get_substituted_file_or_dir_name(first_line, DIRNAME_TAG)

    def substitute_filename(self, first_line):
        """
        Find the filename in first_line and append it to translated_filename.
        """
        substituted_filename = self.get_substituted_filename(first_line)
        self.append_translated_filename(substituted_filename);

    def substitute_dirname(self, first_line):
        """
        Find the dirname in first_line and append it to translated_filename.
        """
        substituted_dirname = self.get_substituted_dirname(first_line)
        self.append_translated_filename(substituted_dirname);

    def is_filename_substitution(self, line):
        """
        Do we have a filename subustition?
        """
        if line.find(FILENAME_TAG) != -1:
            return True
        return False

    def is_dirname_substitution(self, line):
        """
        Do we have a dirname subustition?
        """
        if line.find(DIRNAME_TAG) != -1:
            return True
        return False

    def translate_dirname(self, first_line):
        """
        Just save the first_line mapped by filename.  The later pass
        through the directories will look for a dirname.noinstall
        match and grab the substitution line.
        """
        dirname_substitutions[self.filename] = first_line

    def translate_dirnames_in_path(self, path):
        """
        Translate dirnames below this file or dir, not including tail.
        dirname_substititions is keyed on actual untranslated filenames.
        translated_path contains the subsititutions for each element.
        """
        remainder = path[len(self.filebase)+1:]
        translated_path = untranslated_path = self.filebase

        untranslated_dirs = remainder.split(os.sep)

        for dir in untranslated_dirs:
            key = os.path.join(untranslated_path, dir + '.noinstall')
            try:
                first_line = dirname_substitutions[key]
            except KeyError:
                translated_path = os.path.join(translated_path, dir)
                untranslated_path = os.path.join(untranslated_path, dir)
                continue
            substituted_dir = self.get_substituted_dirname(first_line)
            translated_path = os.path.join(translated_path, substituted_dir)
            untranslated_path = os.path.join(untranslated_path, dir)

        return translated_path

    def translate_file_or_dir_name(self):
        """
        Originally we were allowed to use open/close/assign tags and python
        code in the filename, which fit in nicely with the way we
        processed the templates and generated code.  Now that we can't
        do that, we make those tags proper file contents and have this
        pass substitute the nice but non-functional names with those
        'strange' ones, and then proceed as usual.

        So, if files or matching dir<.noinstall> files contain
        filename substitutions, this function translates them into the
        corresponding 'strange' names, which future passes will expand
        as they always have.  The resulting pathname is kept in the
        file or directory's translated_filename.  Another way to think
        about it is that self.filename is the input filename, and
        translated_filename is the output filename before expansion.
        """
        # remove leaf file or dirname
        head, tail = os.path.split(self.filename)
        translated_path = self.translate_dirnames_in_path(head)
        self.translated_filename = translated_path

        # This is a dirname - does it have a matching .noinstall with
        # a substitution?  If so, apply the dirname subsititution.
        if not os.path.isfile(self.filename):
            key = self.filename + ".noinstall"
            try:
                first_line = dirname_substitutions[key]
            except KeyError:
                self.append_translated_filename(tail)
                return
            self.substitute_dirname(first_line)
            return

        f = open(self.filename)
        first_line = f.readline()
        f.close()

        # This is a normal filename not needing translation, just use
        # it as-is.
        if not first_line or not first_line.startswith("#"):
            self.append_translated_filename(tail)
            return

        # If we have a filename substitution (first line in the file
        # is a FILENAME_TAG line) do the substitution now.  If we have
        # a dirname substitution (DIRNAME_TAG in dirname.noinstall
        # meta-file), hash it so we can apply it when we see the
        # matching dirname later.  Otherwise we have a regular
        # filename, just use it as-is.
        if self.is_filename_substitution(first_line):
            self.substitute_filename(first_line)
        elif self.is_dirname_substitution(first_line):
            self.translate_dirname(first_line)
        else:
            self.append_translated_filename(tail)

    def expand_file_or_dir_name(self):
        """
        Expand file or dir names into codeline.  Dirnames and
        filenames can only have assignments or if statements.  First
        translate if statements into CodeLine + (dirname or filename
        creation).
        """
        lineno = 0

        line = self.translated_filename[len(self.filebase):]
        if line.startswith("/"):
            line = line[1:]
        opentag_start = -1

        start = line.find(OPEN_TAG)
        while start != -1:
            if not line[start:].startswith(ASSIGN_TAG):
                opentag_start = start
                break
            start += len(ASSIGN_TAG)
            start = line.find(OPEN_TAG, start)

        if opentag_start != -1:
            end = line.find(CLOSE_TAG, opentag_start)
            if end == -1:
                self.parse_error("No close tag found for open tag", lineno, line)
            # we have a {{ tag i.e. code
            tag = line[opentag_start + len(OPEN_TAG):end].strip()
            if not tag.lstrip().startswith(IF_TAG):
                self.parse_error("Only 'if' tags are allowed in file or directory names",
                                 lineno, line)
            self.expanded_lines.append(CodeLine(tag))

            # everything after }} is the actual filename (possibly with assignments)
            # everything before is the pathname
            line = line[:opentag_start] + line[end + len(CLOSE_TAG):].strip()

        assign_start = line.find(ASSIGN_TAG)
        if assign_start != -1:
            assignment_tag = self.expand_assignment_tag(assign_start, line, lineno)
            if isinstance(self, SubstrateFile):
                assignment_tag.is_filename = True
                assignment_tag.out_filebase = self.out_filebase
            elif isinstance(self, SubstrateDir):
                assignment_tag.is_dirname = True
                assignment_tag.out_filebase = self.out_filebase
            self.expanded_lines.append(assignment_tag)
            return

        normal_line = NormalLine(line)
        if isinstance(self, SubstrateFile):
            normal_line.is_filename = True
            normal_line.out_filebase = self.out_filebase
        elif isinstance(self, SubstrateDir):
            normal_line.is_dirname = True
            normal_line.out_filebase = self.out_filebase
        self.expanded_lines.append(normal_line)

    def expand(self):
        """
        Expand the file or dir name first, eventually this ends up
        creating the file or dir.
        """
        self.translate_file_or_dir_name()
        self.expand_file_or_dir_name()


class SubstrateFile(SubstrateBase):
    """
    Container for both expanded and unexpanded substrate files.
    """
    def __init__(self, filename, filebase, out_filebase):
        SubstrateBase.__init__(self, filename, filebase, out_filebase)

    def read(self):
        if self.raw_lines:
            return
        f = open(self.filename)
        self.raw_lines = f.readlines()

    def expand(self):
        """Expand the contents of all template tags in the file."""
        SubstrateBase.expand(self)
        self.read()

        for lineno, line in enumerate(self.raw_lines):
            # only first line can be a filename substitition
            if lineno == 0 and line.startswith("#") and FILENAME_TAG in line:
                continue # skip it - we've already expanded it
            expanded_line = self.expand_tag(line, lineno + 1) # humans not 0-based
            if not expanded_line:
                expanded_line = NormalLine(line.rstrip())
            self.expanded_lines.append(expanded_line)

    def gen(self, context = None):
        """Generate the code that generates the BSP."""
        base_indent = 0

        indent = new_indent = base_indent

        for line in self.expanded_lines:
            genline = line.gen(context)
            if not genline:
                continue
            if isinstance(line, InputLine):
                line.generated_line = genline
                continue
            if genline.startswith(OPEN_START):
                if indent == 1:
                    base_indent = 1
            if indent:
                if genline == BLANKLINE_STR or (not genline.startswith(NORMAL_START)
                                                and not genline.startswith(OPEN_START)):
                    indent = new_indent = base_indent
            if genline.endswith(":"):
                new_indent = base_indent + 1
            line.generated_line = (indent * INDENT_STR) + genline
            indent = new_indent


class SubstrateDir(SubstrateBase):
    """
    Container for both expanded and unexpanded substrate dirs.
    """
    def __init__(self, filename, filebase, out_filebase):
        SubstrateBase.__init__(self, filename, filebase, out_filebase)

    def expand(self):
        SubstrateBase.expand(self)

    def gen(self, context = None):
        """Generate the code that generates the BSP."""
        indent = new_indent = 0
        for line in self.expanded_lines:
            genline = line.gen(context)
            if not genline:
                continue
            if genline.endswith(":"):
                new_indent = 1
            else:
                new_indent = 0
            line.generated_line = (indent * INDENT_STR) + genline
            indent = new_indent


def expand_target(target, all_files, out_filebase):
    """
    Expand the contents of all template tags in the target.  This
    means removing tags and categorizing or creating lines so that
    future passes can process and present input lines and generate the
    corresponding lines of the Python program that will be exec'ed to
    actually produce the final BSP.  'all_files' includes directories.
    """
    for root, dirs, files in os.walk(target):
        for file in files:
            if file.endswith("~") or file.endswith("#"):
                continue
            f = os.path.join(root, file)
            sfile = SubstrateFile(f, target, out_filebase)
            sfile.expand()
            all_files.append(sfile)

        for dir in dirs:
            d = os.path.join(root, dir)
            sdir = SubstrateDir(d, target, out_filebase)
            sdir.expand()
            all_files.append(sdir)


def gen_program_machine_lines(machine, program_lines):
    """
    Use the input values we got from the command line.
    """
    line = "machine = \"" + machine + "\""
    program_lines.append(line)

    line = "layer_name = \"" + machine + "\""
    program_lines.append(line)


def sort_inputlines(input_lines):
    """Sort input lines according to priority (position)."""
    input_lines.sort(key = lambda l: l.prio)


def find_parent_dependency(lines, depends_on):
    for i, line in lines:
        if isinstance(line, CodeLine):
            continue
        if line.props["name"] == depends_on:
            return i

    return -1


def process_inputline_dependencies(input_lines, all_inputlines):
    """If any input lines depend on others, put the others first."""
    for line in input_lines:
        if isinstance(line, InputLineGroup):
            group_inputlines = []
            process_inputline_dependencies(line.group, group_inputlines)
            line.group = group_inputlines
            all_inputlines.append(line)
            continue

        if isinstance(line, CodeLine) or isinstance(line, NormalLine):
            all_inputlines.append(line)
            continue

        try:
            depends_on = line.props["depends-on"]
            depends_codeline = "if " + line.props["depends-on"] + " == \"" + line.props["depends-on-val"] + "\":"
            all_inputlines.append(CodeLine(depends_codeline))
            all_inputlines.append(line)
        except KeyError:
            all_inputlines.append(line)


def conditional_filename(filename):
    """
    Check if the filename itself contains a conditional statement.  If
    so, return a codeline for it.
    """
    opentag_start = filename.find(OPEN_TAG)

    if opentag_start != -1:
        if filename[opentag_start:].startswith(ASSIGN_TAG):
            return None
        end = filename.find(CLOSE_TAG, opentag_start)
        if end == -1:
            print "No close tag found for open tag in filename %s" % filename
            sys.exit(1)

        # we have a {{ tag i.e. code
        tag = filename[opentag_start + len(OPEN_TAG):end].strip()
        if not tag.lstrip().startswith(IF_TAG):
            print "Only 'if' tags are allowed in file or directory names, filename: %s" % filename
            sys.exit(1)

        return CodeLine(tag)

    return None


class InputLineGroup(InputLine):
    """
    InputLine that does nothing but group other input lines
    corresponding to all the input lines in a SubstrateFile so they
    can be generated as a group.  prio is the only property used.
    """
    def __init__(self, codeline):
        InputLine.__init__(self, {}, "", 0)
        self.group = []
        self.prio = sys.maxint
        self.group.append(codeline)

    def append(self, line):
        self.group.append(line)
        if line.prio < self.prio:
            self.prio = line.prio

    def len(self):
        return len(self.group)


def gather_inputlines(files):
    """
    Gather all the InputLines - we want to generate them first.
    """
    all_inputlines = []
    input_lines = []

    for file in files:
        if isinstance(file, SubstrateFile):
            group = None
            basename = os.path.basename(file.translated_filename)

            codeline = conditional_filename(basename)
            if codeline:
                group = InputLineGroup(codeline)

            have_condition = False
            condition_to_write = None
            for line in file.expanded_lines:
                if isinstance(line, CodeLine):
                    have_condition = True
                    condition_to_write = line
                    continue
                if isinstance(line, InputLine):
                    if group:
                        if condition_to_write:
                            condition_to_write.prio = line.prio
                            condition_to_write.discard = True
                            group.append(condition_to_write)
                            condition_to_write = None
                        group.append(line)
                    else:
                        if condition_to_write:
                            condition_to_write.prio = line.prio
                            condition_to_write.discard = True
                            input_lines.append(condition_to_write)
                            condition_to_write = None
                        input_lines.append(line)
                else:
                    if condition_to_write:
                        condition_to_write = None
                    if have_condition:
                        if not line.line.strip():
                            line.discard = True
                            input_lines.append(line)
                    have_condition = False

            if group and group.len() > 1:
                input_lines.append(group)

    sort_inputlines(input_lines)
    process_inputline_dependencies(input_lines, all_inputlines)

    return all_inputlines


def run_program_lines(linelist, codedump):
    """
    For a single file, print all the python code into a buf and execute it.
    """
    buf = "\n".join(linelist)

    if codedump:
        of = open("bspgen.out", "w")
        of.write(buf)
        of.close()
    exec buf


def gen_target(files, context = None):
    """
    Generate the python code for each file.
    """
    for file in files:
        file.gen(context)


def gen_program_header_lines(program_lines):
    """
    Generate any imports we need.
    """
    program_lines.append("current_file = \"\"")


def gen_supplied_property_vals(properties, program_lines):
    """
    Generate user-specified entries for input values instead of
    generating input prompts.
    """
    for name, val in properties.iteritems():
        program_line = name + " = \"" + val + "\""
        program_lines.append(program_line)


def gen_initial_property_vals(input_lines, program_lines):
    """
    Generate null or default entries for input values, so we don't
    have undefined variables.
    """
    for line in input_lines:
        if isinstance(line, InputLineGroup):
            gen_initial_property_vals(line.group, program_lines)
            continue

        if isinstance(line, InputLine):
            try:
                name = line.props["name"]
                try:
                    default_val = "\"" + line.props["default"] + "\""
                except:
                    default_val = "\"\""
                program_line = name + " = " + default_val
                program_lines.append(program_line)
            except KeyError:
                pass


def gen_program_input_lines(input_lines, program_lines, context, in_group = False):
    """
    Generate only the input lines used for prompting the user.  For
    that, we only have input lines and CodeLines that affect the next
    input line.
    """
    indent = new_indent = 0

    for line in input_lines:
        if isinstance(line, InputLineGroup):
            gen_program_input_lines(line.group, program_lines, context, True)
            continue
        if not line.line.strip():
            continue

        genline = line.gen(context)
        if not genline:
            continue
        if genline.endswith(":"):
            new_indent += 1
        else:
            if indent > 1 or (not in_group and indent):
                new_indent -= 1

        line.generated_line = (indent * INDENT_STR) + genline
        program_lines.append(line.generated_line)

        indent = new_indent


def gen_program_lines(target_files, program_lines):
    """
    Generate the program lines that make up the BSP generation
    program.  This appends the generated lines of all target_files to
    program_lines, and skips input lines, which are dealt with
    separately, or omitted.
    """
    for file in target_files:
        if file.filename.endswith("noinstall"):
            continue

        for line in file.expanded_lines:
            if isinstance(line, InputLine):
                continue
            if line.discard:
                continue

            program_lines.append(line.generated_line)


def create_context(machine, arch, scripts_path):
    """
    Create a context object for use in deferred function invocation.
    """
    context = {}

    context["machine"] = machine
    context["arch"] = arch
    context["scripts_path"] = scripts_path

    return context


def capture_context(context):
    """
    Create a context object for use in deferred function invocation.
    """
    captured_context = {}

    captured_context["machine"] = context["machine"]
    captured_context["arch"] = context["arch"]
    captured_context["scripts_path"] = context["scripts_path"]

    return captured_context


def expand_targets(context, bsp_output_dir, expand_common=True):
    """
    Expand all the tags in both the common and machine-specific
    'targets'.

    If expand_common is False, don't expand the common target (this
    option is used to create special-purpose layers).
    """
    target_files = []

    machine = context["machine"]
    arch = context["arch"]
    scripts_path = context["scripts_path"]

    lib_path = scripts_path + '/lib'
    bsp_path = lib_path + '/bsp'
    arch_path = bsp_path + '/substrate/target/arch'

    if expand_common:
        common = os.path.join(arch_path, "common")
        expand_target(common, target_files, bsp_output_dir)

    arches = os.listdir(arch_path)
    if arch not in arches or arch == "common":
        print "Invalid karch, exiting\n"
        sys.exit(1)

    target = os.path.join(arch_path, arch)
    expand_target(target, target_files, bsp_output_dir)

    gen_target(target_files, context)

    return target_files


def yocto_common_create(machine, target, scripts_path, layer_output_dir, codedump, properties_file, properties_str="", expand_common=True):
    """
    Common layer-creation code

    machine - user-defined machine name (if needed, will generate 'machine' var)
    target - the 'target' the layer will be based on, must be one in
           scripts/lib/bsp/substrate/target/arch
    scripts_path - absolute path to yocto /scripts dir
    layer_output_dir - dirname to create for layer
    codedump - dump generated code to bspgen.out
    properties_file - use values from this file if nonempty i.e no prompting
    properties_str - use values from this string if nonempty i.e no prompting
    expand_common - boolean, use the contents of (for bsp layers) arch/common
    """
    if os.path.exists(layer_output_dir):
        print "\nlayer output dir already exists, exiting. (%s)" % layer_output_dir
        sys.exit(1)

    properties = None

    if properties_file:
        try:
            infile = open(properties_file, "r")
        except IOError:
            print "Couldn't open properties file %s for reading, exiting" % properties_file
            sys.exit(1)

        properties = json.load(infile)

    if properties_str and not properties:
        properties = json.loads(properties_str)

    os.mkdir(layer_output_dir)

    context = create_context(machine, target, scripts_path)
    target_files = expand_targets(context, layer_output_dir, expand_common)

    input_lines = gather_inputlines(target_files)

    program_lines = []

    gen_program_header_lines(program_lines)

    gen_initial_property_vals(input_lines, program_lines)

    if properties:
        gen_supplied_property_vals(properties, program_lines)

    gen_program_machine_lines(machine, program_lines)

    if not properties:
        gen_program_input_lines(input_lines, program_lines, context)

    gen_program_lines(target_files, program_lines)

    run_program_lines(program_lines, codedump)


def yocto_layer_create(layer_name, scripts_path, layer_output_dir, codedump, properties_file, properties=""):
    """
    Create yocto layer

    layer_name - user-defined layer name
    scripts_path - absolute path to yocto /scripts dir
    layer_output_dir - dirname to create for layer
    codedump - dump generated code to bspgen.out
    properties_file - use values from this file if nonempty i.e no prompting
    properties - use values from this string if nonempty i.e no prompting
    """
    yocto_common_create(layer_name, "layer", scripts_path, layer_output_dir, codedump, properties_file, properties, False)

    print "\nNew layer created in %s.\n" % (layer_output_dir)
    print "Don't forget to add it to your BBLAYERS (for details see %s/README)." % (layer_output_dir)


def yocto_bsp_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties=None):
    """
    Create bsp

    machine - user-defined machine name
    arch - the arch the bsp will be based on, must be one in
           scripts/lib/bsp/substrate/target/arch
    scripts_path - absolute path to yocto /scripts dir
    bsp_output_dir - dirname to create for BSP
    codedump - dump generated code to bspgen.out
    properties_file - use values from this file if nonempty i.e no prompting
    properties - use values from this string if nonempty i.e no prompting
    """
    yocto_common_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties)

    print "\nNew %s BSP created in %s" % (arch, bsp_output_dir)


def print_dict(items, indent = 0):
    """
    Print the values in a possibly nested dictionary.
    """
    for key, val in items.iteritems():
        print "    "*indent + "\"%s\" :" % key,
        if type(val) == dict:
            print "{"
            print_dict(val, indent + 1)
            print "    "*indent + "}"
        else:
            print "%s" % val


def get_properties(input_lines):
    """
    Get the complete set of properties for all the input items in the
    BSP, as a possibly nested dictionary.
    """
    properties = {}

    for line in input_lines:
        if isinstance(line, InputLineGroup):
            statement = line.group[0].line
            group_properties = get_properties(line.group)
            properties[statement] = group_properties
            continue

        if not isinstance(line, InputLine):
            continue

        if isinstance(line, ChoiceInputLine):
            continue

        props = line.props
        item = {}
        name = props["name"]
        for key, val in props.items():
            if not key == "name":
                item[key] = val
        properties[name] = item

    return properties


def yocto_layer_list_properties(arch, scripts_path, properties_file, expand_common=True):
    """
    List the complete set of properties for all the input items in the
    layer.  If properties_file is non-null, write the complete set of
    properties as a nested JSON object corresponding to a possibly
    nested dictionary.
    """
    context = create_context("unused", arch, scripts_path)
    target_files = expand_targets(context, "unused", expand_common)

    input_lines = gather_inputlines(target_files)

    properties = get_properties(input_lines)
    if properties_file:
        try:
            of = open(properties_file, "w")
        except IOError:
            print "Couldn't open properties file %s for writing, exiting" % properties_file
            sys.exit(1)

        json.dump(properties, of, indent=1)
    else:
        print_dict(properties)


def split_nested_property(property):
    """
    A property name of the form x.y describes a nested property
    i.e. the property y is contained within x and can be addressed
    using standard JSON syntax for nested properties.  Note that if a
    property name itself contains '.', it should be contained in
    double quotes.
    """
    splittable_property = ""
    in_quotes = False
    for c in property:
        if c == '.' and not in_quotes:
            splittable_property += '\n'
            continue
        if c == '"':
            in_quotes = not in_quotes
        splittable_property += c

    split_properties = splittable_property.split('\n')

    if len(split_properties) > 1:
        return split_properties

    return None


def find_input_line_group(substring, input_lines):
    """
    Find and return the InputLineGroup containing the specified substring.
    """
    for line in input_lines:
        if isinstance(line, InputLineGroup):
            if substring in line.group[0].line:
                return line

    return None


def find_input_line(name, input_lines):
    """
    Find the input line with the specified name.
    """
    for line in input_lines:
        if isinstance(line, InputLineGroup):
            l = find_input_line(name, line.group)
            if l:
                return l

        if isinstance(line, InputLine):
            try:
                if line.props["name"] == name:
                    return line
                if line.props["name"] + "_" + line.props["nameappend"] == name:
                    return line
            except KeyError:
                pass

    return None


def print_values(type, values_list):
    """
    Print the values in the given list of values.
    """
    if type == "choicelist":
        for value in values_list:
            print "[\"%s\", \"%s\"]" % (value[0], value[1])
    elif type == "boolean":
        for value in values_list:
            print "[\"%s\", \"%s\"]" % (value[0], value[1])


def yocto_layer_list_property_values(arch, property, scripts_path, properties_file, expand_common=True):
    """
    List the possible values for a given input property.  If
    properties_file is non-null, write the complete set of properties
    as a JSON object corresponding to an array of possible values.
    """
    context = create_context("unused", arch, scripts_path)
    context["name"] = property

    target_files = expand_targets(context, "unused", expand_common)

    input_lines = gather_inputlines(target_files)

    properties = get_properties(input_lines)

    nested_properties = split_nested_property(property)
    if nested_properties:
        # currently the outer property of a nested property always
        # corresponds to an input line group
        input_line_group = find_input_line_group(nested_properties[0], input_lines)
        if input_line_group:
            input_lines[:] = input_line_group.group[1:]
            # The inner property of a nested property name is the
            # actual property name we want, so reset to that
            property = nested_properties[1]

    input_line = find_input_line(property, input_lines)
    if not input_line:
        print "Couldn't find values for property %s" % property
        return

    values_list = []

    type = input_line.props["type"]
    if type == "boolean":
        values_list.append(["y", "n"])
    elif type == "choicelist" or type == "checklist":
        try:
            gen_fn = input_line.props["gen"]
            if nested_properties:
                context["filename"] = nested_properties[0]
                try:
                    context["branches_base"] = input_line.props["branches_base"]
                except KeyError:
                    context["branches_base"] = None
            values_list = input_line.gen_choices_list(context, False)
        except KeyError:
            for choice in input_line.choices:
                choicepair = []
                choicepair.append(choice.val)
                choicepair.append(choice.desc)
                values_list.append(choicepair)

    if properties_file:
        try:
            of = open(properties_file, "w")
        except IOError:
            print "Couldn't open properties file %s for writing, exiting" % properties_file
            sys.exit(1)

        json.dump(values_list, of)

    print_values(type, values_list)


def yocto_bsp_list(args, scripts_path, properties_file):
    """
    Print available architectures, or the complete list of properties
    defined by the BSP, or the possible values for a particular BSP
    property.
    """
    if len(args) < 1:
        return False

    if args[0] == "karch":
        lib_path = scripts_path + '/lib'
        bsp_path = lib_path + '/bsp'
        arch_path = bsp_path + '/substrate/target/arch'
        print "Architectures available:"
        for arch in os.listdir(arch_path):
            if arch == "common" or arch == "layer":
                continue
            print "    %s" % arch
        return True
    else:
        arch = args[0]

    if len(args) < 2 or len(args) > 3:
        return False

    if len(args) == 2:
        if args[1] == "properties":
            yocto_layer_list_properties(arch, scripts_path, properties_file)
        else:
            return False

    if len(args) == 3:
        if args[1] == "property":
            yocto_layer_list_property_values(arch, args[2], scripts_path, properties_file)
        else:
            return False

    return True


def yocto_layer_list(args, scripts_path, properties_file):
    """
    Print the complete list of input properties defined by the layer,
    or the possible values for a particular layer property.
    """
    if len(args) < 1:
        return False

    if len(args) < 1 or len(args) > 2:
        return False

    if len(args) == 1:
        if args[0] == "properties":
            yocto_layer_list_properties("layer", scripts_path, properties_file, False)
        else:
            return False

    if len(args) == 2:
        if args[0] == "property":
            yocto_layer_list_property_values("layer", args[1], scripts_path, properties_file, False)
        else:
            return False

    return True


def map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
    """
    Return the linux-yocto bsp branch to use with the specified
    kbranch.  This handles the -standard variants for 3.4 and 3.8; the
    other variants don't need mappings.
    """
    if need_new_kbranch == "y":
        kbranch = new_kbranch
    else:
        kbranch = existing_kbranch

    if kbranch.startswith("standard/common-pc-64"):
        return "bsp/common-pc-64/common-pc-64-standard.scc"
    if kbranch.startswith("standard/common-pc"):
        return "bsp/common-pc/common-pc-standard.scc"
    else:
        return "ktypes/standard/standard.scc"


def map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
    """
    Return the linux-yocto bsp branch to use with the specified
    kbranch.  This handles the -preempt-rt variants for 3.4 and 3.8;
    the other variants don't need mappings.
    """
    if need_new_kbranch == "y":
        kbranch = new_kbranch
    else:
        kbranch = existing_kbranch

    if kbranch.startswith("standard/preempt-rt/common-pc-64"):
        return "bsp/common-pc-64/common-pc-64-preempt-rt.scc"
    if kbranch.startswith("standard/preempt-rt/common-pc"):
        return "bsp/common-pc/common-pc-preempt-rt.scc"
    else:
        return "ktypes/preempt-rt/preempt-rt.scc"


def map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
    """
    Return the linux-yocto bsp branch to use with the specified
    kbranch.  This handles the -tiny variants for 3.4 and 3.8; the
    other variants don't need mappings.
    """
    if need_new_kbranch == "y":
        kbranch = new_kbranch
    else:
        kbranch = existing_kbranch

    if kbranch.startswith("standard/tiny/common-pc"):
        return "bsp/common-pc/common-pc-tiny.scc"
    else:
        return "ktypes/tiny/tiny.scc"
