def __init__(self, toolchain_dir, toolchain_pathname, toolchain_id):
     # e.g. 
     #  toolchain_dir = /home/snorri/.ros/eros/toolchains
     #  toolchain_pathname = /home/snorri/.ros/eros/toolchains/crossdev/i686-pc-linux-gnu.cmake
     self.pathname = toolchain_pathname
     # Could check here, but if calling from toolchain_list, will always be arg 1 we want.
     tail = self.pathname.split(toolchain_dir)[1] # e.g. /crossdev/i686-pc-linux-gnu.cmake 
     cmake_name = os.path.basename(tail) # e.g. i686-pc-linux-gnu.cmake
     self.name = os.path.splitext(cmake_name)[0] # e.g. i686-pc-linux-gnu
     if ( self.pathname.find(eros_toolchain_dir()) != -1 ):
         self.group = "eros"
     else:
         self.group = "user"
     self.family = os.path.dirname(toolchain_pathname).split(toolchain_dir)[1] # e.g. /crossdev
     self.family = os.path.split(self.family)[1] # remove dir separators e.g. crossdev
     if ( self.family == '' ):
         self.family = "unknown"
     toolchain_exists = os.path.exists(core.rostoolchain_cmake())
     self.current = False
     if ( toolchain_exists ) :
         name_string = "TOOLCHAIN_TUPLE \"" + self.name + "\""
         if name_string in open(core.rostoolchain_cmake()).read():
             family_string = "TOOLCHAIN_FAMILY \"" + self.family + "\""
             if family_string in open(core.rostoolchain_cmake()).read():
                 self.current = True
     self.id = toolchain_id
def select_toolchain():
    '''
    Interactively selects and sets an ros toolchain.
      - return true or false depending on success/failure.
    '''
    list_toolchains()
    toolchain_id_string = raw_input("Enter a toolchain id #: ")
    if ( not toolchain_id_string.isdigit() ):
        print core.red_string("Aborting, invalid id #.")
        return False
    toolchain_id = int(toolchain_id_string)
    toolchains = toolchain_list()
    if not toolchain_id <= len(toolchains):
        print core.red_string("Aborting, invalid id #.")
        return False
    found_toolchain = False
    for toolchain in toolchains:
        if ( toolchain.id == toolchain_id ):
            found_toolchain = True
            selected_toolchain = toolchain
            break
    if ( not found_toolchain ):
        print core.red_string("Aborting, toolchain not found.")
        return False
    else:
        shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
        print
        return True
def select_toolchain_by_id(id):
    '''
    Selects toolchain by id.
      - return 1 if failure, 0 if success
    '''
    toolchains = toolchain_list()
    if ( int(id) > len(toolchains) ):
        print core.red_string("-- Aborting, # does not correspond to a toolchain.")
        list_toolchains()
        return 1
    else:
        selected_toolchain = toolchains[int(id)-1] # indexing starts at zero
        shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
        return 0
def select_toolchain_by_name(id_string):
    '''
    Selects toolchain by name or family/name string.
      - return 1 if failure, 0 if success
    '''
    bits = os.path.split(id_string)
    #print bits
    if  len(bits) == 2 :
        family = bits[0] # if just name is given, this will be empty
        name = bits[1]
        found_toolchain = False
        toolchains = toolchain_list()
        if family == "": # try and just match name
            for toolchain in toolchains:
                if ( toolchain.name == name ):
                    if found_toolchain:
                        print
                        print core.red_string("Multiple matches, please provide a full id string.")
                        list_toolchains()
                        return 1
                    else:
                        found_toolchain = True
                        selected_toolchain = toolchain
        else: # try and match both family, name
            for toolchain in toolchains:
                if toolchain.family == family and toolchain.name == name:
                    found_toolchain = True
                    selected_toolchain = toolchain
                    break
        if ( not found_toolchain ):
            print
            print core.red_string("Aborting, toolchain not found.")
            list_toolchains()
            return 1
        else:
            shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
            return 0
    else:
        print
        print core.red_string("Aborting, toolchain not found.")
        list_toolchains()
        return 1
def show_current_toolchain():
    '''
    Print the identity of the currently configured toolchain:
      - checks eros/user toolchain libraries for a match
      - if not eros/user toolchain, checks if toolchain configured, but unknown
      - otherwise prints none 
    '''
    pretext = core.bold_string("Current toolchain: ")
    toolchains = toolchain_list()
    found = False
    for toolchain in toolchains:
        if ( toolchain.current ):
            found = True
            current_toolchain = toolchain
    if ( found ):
        print pretext + current_toolchain.family + os.sep + current_toolchain.name
    else:
        if ( os.path.exists(core.rostoolchain_cmake()) ):
            print pretext + "unknown"
        else:
            print pretext + "none"
def main():
    from config import ErosConfig
    config = ErosConfig()
    from optparse import OptionParser
    usage = "\n\
  %prog               : shows the currently set ros toolchain\n\
  %prog clear         : clear the currently set ros toolchain\n\
  %prog create        : create a user-defined toolchain configuration\n\
  %prog delete        : delete a preconfigured toolchain\n\
  %prog help          : print this help information\n\
  %prog list          : list available eros and user-defined toolchains\n\
  %prog select        : interactively select a toolchain\n\
  %prog select <str>  : directly select the specified toolchain\n\
  %prog validate      : attempt to validate a toolchain (not yet implemented)\n\
  \n\
Description: \n\
  Create/delete and manage the toolchain configuration for this ros environment.\n\
  Location of the user toolchain directory can be modified via --dir or more \n\
  permanently via " + core.eros_config() + "."
    parser = OptionParser(usage=usage)
    parser.add_option("-d","--dir", action="store", default=config.user_toolchains_dir(), help="location of the user toolchain library")
    options, args = parser.parse_args()
    
    # Configure the user toolchain directory.
    user_toolchain_dir(options.dir)
        
    ###################
    # Show current
    ###################
    if not args:
        show_current_toolchain()
        return 0

    command = args[0]

    ###################
    # Help
    ###################
    if command == 'help':
        parser.print_help()
        return 0
        
    ###################
    # List
    ###################
    if command == 'list':
        list_toolchains()
        return 0
    ###################
    # Clear
    ###################
    if command == 'clear':
        if os.path.exists(core.rostoolchain_cmake()):
            os.remove(core.rostoolchain_cmake())
            print
            print "-- Toolchain configuration cleared."
            # print "-- Remember to reconfigure ROS_BOOST_ROOT if necessary."
            print
        else:
            print
            print "-- Nothing to do (no toolchain configuration present)."
            print
        return 0
    ###################
    # Create
    ###################
    if command == 'create':
        return create_toolchain()

    ###################
    # Delete
    ###################
    if command == 'delete':
        return delete_toolchain()

    ###################
    # Select
    ###################
    if command == 'select': 
        if len(args) == 1: # interactive selection
            if not select_toolchain():
                return 1
        else:
            if args[1].isdigit():
                if select_toolchain_by_id(args[1]):
                    return 1
            else:
                if select_toolchain_by_name(args[1]):
                    return 1
        # Not currently needing it, but anyway, its good to have.
        print "-- Toolchain copied to rostoolchain.cmake."
        patch_ros()
        check_platform()
        #print "-- You need to manually export a root for the boost in your toolchain in setup.sh."
        #print "  -- (typically the same as the TOOLCHAIN_INSTALL_PREFIX), e.g."
        #print
        #print "          export ROS_BOOST_ROOT=\"/usr/my_toolchain_tuple/usr/local\""
        print 
        return 0
    
    ###################
    # Validate
    ###################
    if command == 'validate':
        print
        print "-- This command is not yet available."
        print
        return 0 
    
    # If we reach here, we have not received a valid command.
    print
    print "-- Not a valid command [" + command + "]."
    print
    parser.print_help()
    print

    return 1