00001
00002
00003
00004
00005 '''rtshell
00006
00007 Copyright (C) 2009-2014
00008 Geoffrey Biggs
00009 RT-Synthesis Research Group
00010 Intelligent Systems Research Institute,
00011 National Institute of Advanced Industrial Science and Technology (AIST),
00012 Japan
00013 All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016
00017 Implementation of the command to find components, managers, etc.
00018
00019 '''
00020
00021
00022 import optparse
00023 import os
00024 import os.path
00025 import re
00026 import rtctree.tree
00027 import rtctree.path
00028 import sys
00029 import traceback
00030
00031 import path
00032 import rts_exceptions
00033 import rtshell
00034
00035
00036 def search(cmd_path, full_path, options, tree=None):
00037 def get_result(node, args):
00038 if node.full_path_str.startswith(cmd_path):
00039 result = node.full_path_str[len(cmd_path):]
00040 if not result:
00041
00042 return node.name
00043 return node.full_path_str
00044 else:
00045 return node.full_path_str
00046
00047
00048 def matches_search(node):
00049
00050 if options.type:
00051 if node.is_component and 'c' not in options.type:
00052 return False
00053 if node.is_manager and 'm' not in options.type and \
00054 'd' not in options.type:
00055 return False
00056 if node.is_nameserver and 'n' not in options.type and \
00057 'd' not in options.type:
00058 return False
00059 if node.is_directory and 'd' not in options.type and \
00060 (not node.is_nameserver and not node.is_manager):
00061 return False
00062 if node.is_zombie and 'z' not in options.type:
00063 return False
00064
00065 if max_depth > 0 and node.depth > max_depth:
00066 return False
00067 if not name_res:
00068 return True
00069
00070 for name_re in name_res:
00071 if name_re.search(node.full_path_str):
00072 return True
00073 return False
00074
00075 path, port = rtctree.path.parse_path(full_path)
00076 if port:
00077 raise rts_exceptions.NotADirectoryError(cmd_path)
00078
00079 trailing_slash = False
00080 if not path[-1]:
00081
00082 trailing_slash = True
00083 path = path[:-1]
00084
00085 if not tree:
00086 tree = rtctree.tree.RTCTree(paths=path, filter=[path])
00087
00088
00089 root = tree.get_node(path)
00090 if not root:
00091 raise rts_exceptions.NoSuchObjectError(cmd_path)
00092 if root.is_component and trailing_slash:
00093 raise rts_exceptions.NotADirectoryError(cmd_path)
00094
00095 if options.max_depth:
00096 max_depth = options.max_depth + len(path) - 1
00097 else:
00098 max_depth = 0
00099
00100 name_res = []
00101 for name in options.name:
00102
00103 name = re.escape (name)
00104
00105 name = name.replace (r'\*', '.*?')
00106
00107 name = name.replace (r'\?', r'.')
00108 name_res.append(re.compile(name))
00109 for name in options.iname:
00110
00111 name = re.escape (name)
00112
00113 name = name.replace (r'\*', '.*?')
00114
00115 name = name.replace (r'\?', r'.')
00116 name_res.append(re.compile(name, re.IGNORECASE))
00117
00118 return root.iterate(get_result, filter=[matches_search])
00119
00120
00121 def main(argv=None, tree=None):
00122 usage = '''Usage: %prog <search path> [options]
00123 Find entries in the RTC tree matching given constraints.'''
00124 version = rtshell.RTSH_VERSION
00125 parser = optparse.OptionParser(usage=usage, version=version)
00126 parser.add_option('-i', '--iname', dest='iname', action='append',
00127 type='string', default=[], help='Case-insensitive name pattern. '
00128 'This option can be specified multiple times.')
00129 parser.add_option('-m', '--maxdepth', dest='max_depth', action='store',
00130 type='int', default=0, help='Maximum depth to search down to in '
00131 'the tree. Set to 0 to disable. [Default: %default]')
00132 parser.add_option('-n', '--name', dest='name', action='append',
00133 type='string', default=[], help='Case-sensitive name pattern. '
00134 'This option can be specified multiple times.')
00135 parser.add_option('-t', '--type', dest='type', action='store',
00136 type='string', default='', help='Type of object: c (component), '
00137 'd (directory), m (manager), n (name server), z (zombie). '
00138 'Multiple types can be specified in a single entry, e.g. '
00139 '"--type=dmn".')
00140 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00141 default=False,
00142 help='Output verbose information. [Default: %default]')
00143
00144 if argv:
00145 sys.argv = [sys.argv[0]] + argv
00146 try:
00147 options, args = parser.parse_args()
00148 except optparse.OptionError, e:
00149 print >>sys.stderr, 'OptionError:', e
00150 return 1, []
00151
00152 if len(args) == 1:
00153 cmd_path = args[0]
00154 else:
00155 print >>sys.stderr, usage
00156 return 1, []
00157 full_path = path.cmd_path_to_full_path(cmd_path)
00158
00159 matches = []
00160 try:
00161 matches = search(cmd_path, full_path, options, tree)
00162 except Exception, e:
00163 if options.verbose:
00164 traceback.print_exc()
00165 print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00166 return 1, []
00167 return 0, matches
00168
00169
00170
00171