BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
remove-device-h.py
00001 import json 00002 import os 00003 import stat 00004 import re 00005 from collections import OrderedDict 00006 from subprocess import Popen 00007 00008 git_processes = [] 00009 00010 class MyJSONEncoder(json.JSONEncoder): 00011 def __init__(self, *args, **kwargs): 00012 super(MyJSONEncoder, self).__init__(*args, **kwargs) 00013 self.current_indent = 0 00014 self.current_indent_str = "" 00015 00016 00017 def encode(self, o): 00018 #Special Processing for lists 00019 if isinstance(o, (list, tuple)): 00020 primitives_only = True 00021 for item in o: 00022 if isinstance(item, (list, tuple, dict)): 00023 primitives_only = False 00024 break 00025 output = [] 00026 if primitives_only: 00027 for item in o: 00028 output.append(json.dumps(item)) 00029 return "[" + ", ".join(output) + "]" 00030 else: 00031 self.current_indent += self.indent 00032 self.current_indent_str = " " * self.current_indent 00033 for item in o: 00034 output.append(self.current_indent_str + self.encode(item)) 00035 self.current_indent -= self.indent 00036 self.current_indent_str = " " * self.current_indent 00037 return "[\n" + ",\n".join(output) + "\n" + self.current_indent_str + "]" 00038 elif isinstance(o, dict): 00039 primitives_only = True 00040 for item in o.values(): 00041 if isinstance(item, (list, tuple, dict)): 00042 primitives_only = False 00043 break 00044 output = [] 00045 if primitives_only and len(o) < 3: 00046 for key, value in o.items(): 00047 output.append(json.dumps(key) + ": " + self.encode(value)) 00048 return "{" + ", ".join(output) + "}" 00049 else: 00050 self.current_indent += self.indent 00051 self.current_indent_str = " " * self.current_indent 00052 for key, value in o.items(): 00053 output.append(self.current_indent_str + json.dumps(key) + ": " + self.encode(value)) 00054 self.current_indent -= self.indent 00055 self.current_indent_str = " " * self.current_indent 00056 return "{\n" + ",\n".join(output) + "\n" + self.current_indent_str + "}" 00057 else: 00058 return json.dumps(o) 00059 00060 def load(path): 00061 with open(path, 'r') as f : 00062 return json.load(f, object_pairs_hook=OrderedDict) 00063 00064 def dump(path, obj): 00065 with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR), 'w') as f : 00066 os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) 00067 f.write(MyJSONEncoder(indent=4).encode(obj)) 00068 f.write(u'\n') 00069 f.truncate() 00070 00071 def find(stem, path) : 00072 for root, directories, files in os.walk(path, followlinks=True) : 00073 [dir for dir in directories if dir[0] != '.'] 00074 if (stem_match(stem,os.path.basename(os.path.normpath(root))) and 00075 "device.h" in files) : 00076 return os.path.join(root, "device.h") 00077 00078 def find_all_devices(path, verbose=False) : 00079 for root, directories, files in os.walk(path, followlinks=True) : 00080 [dir for dir in directories if dir[0] != '.'] 00081 if "device.h" in files : 00082 if verbose : print("[VERBOSE] found a device.h file in {}".format(root)) 00083 yield os.path.join(root, "device.h") 00084 00085 mbed_matcher = re.compile('mbed', re.IGNORECASE) 00086 def stem_match(stem, thing) : 00087 return (stem in thing or 00088 re.sub(mbed_matcher, '', stem) in thing) 00089 00090 attr_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+1.*$') 00091 def parse_attributes(path) : 00092 with open(path) as input : 00093 for line in input : 00094 m = re.match(attr_matcher, line) 00095 if m: yield m.group(1) 00096 00097 remove_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+[10].*$') 00098 def remove_attributes(path) : 00099 with open(path) as input : 00100 remainder = filter(lambda l: not re.match(remove_matcher, l), input) 00101 with open(path,"wb") as output : 00102 output.truncate(0) 00103 output.write("// The 'provides' section in 'target.json' is now used"+ 00104 " to create the device's hardware preprocessor switches.\n") 00105 output.write("// Check the 'provides' section of the target description"+ 00106 " in 'targets.json' for more details.\n") 00107 output.writelines(remainder) 00108 00109 def user_select(things, message) : 00110 print(message) 00111 for thing, number in zip(things, range(len(things))): 00112 print("{} : {}".format(number, thing)) 00113 selection = None 00114 while selection is None : 00115 print("please select an integer [0..{}] or specify all".format(len(things) - 1)) 00116 try : 00117 i = raw_input() 00118 if i == "all" : 00119 selection = "all" 00120 else : 00121 selection = int(i) 00122 if (selection > len(things) or 00123 selection < 0) : 00124 print("selection {} out of range".format(selection)) 00125 selection = None 00126 except (ValueError, SyntaxError) : 00127 print("selection not understood") 00128 if selection == "all" : 00129 return things 00130 else : 00131 return [things[selection]] 00132 00133 target_matcher = re.compile("TARGET_") 00134 def strip_target(str) : 00135 return re.sub(target_matcher, "", str) 00136 00137 def add_to_targets(targets, device_file, verbose=False, remove=False) : 00138 if verbose : print("[VERBOSE] trying target {}".format(device_file)) 00139 device = strip_target(os.path.basename(os.path.normpath(os.path.dirname(device_file)))) 00140 if not device : 00141 print("[WARNING] device {} did not have an associated device.h".format(device)) 00142 else : 00143 possible_matches = set([key for key in targets.keys() if stem_match(device, key)]) 00144 for key, value in targets.items() : 00145 for alt in value['extra_labels'] if 'extra_labels' in value else [] : 00146 if stem_match(device, alt) : possible_matches.add(key) 00147 for alt in value['extra_labels_add'] if 'extra_labels_add' in value else [] : 00148 if stem_match(device, alt) : possible_matches.add(key) 00149 possible_matches = list(possible_matches) 00150 for match in possible_matches : 00151 if device == match : possible_matches = [match] 00152 if not possible_matches : 00153 print("[WARNING] device {} did not have an associated entry in targets.json".format(device)) 00154 return None 00155 elif len(possible_matches) > 1 : 00156 message = ("possible matches for file {}".format(device_file)) 00157 target = user_select(possible_matches, message) 00158 else : 00159 target = possible_matches 00160 attrs = list(parse_attributes(device_file)) 00161 if attrs : 00162 for t in target : 00163 targets[t]["device_has"] = sorted(list(set(targets[t].setdefault("device_has",[]) + attrs))) 00164 if verbose : print("[VERBOSE] target {} now device_has {}".format(t, attrs)) 00165 if remove is True: 00166 remove_attributes(device_file) 00167 00168 if __name__ == '__main__' : 00169 import argparse 00170 parser = argparse.ArgumentParser(description='A helpful little script for converting' + 00171 ' device.h files to parts of the targets.json file') 00172 parser.add_argument('-a', '--all', action='store_true', 00173 help='find and convert all available device.h files in the'+ 00174 ' directory tree starting at the current directory') 00175 parser.add_argument('-f', '--file', nargs='+', help='specify an individual file to '+ 00176 'convert from device.h format to a piece of targets.json') 00177 parser.add_argument('-t', '--target', nargs='+', help='specify an individual target'+ 00178 ' to convert from device.h format to a piece of targets.json') 00179 parser.add_argument('-v', '--verbose', action='store_true', 00180 help="print out every target that is updated in the targets.json") 00181 parser.add_argument('-r', '--rm', action='store_true', 00182 help="remove the used attributes from a device.h file") 00183 args = parser.parse_args() 00184 if not args.target and not args.file and not args.all : 00185 print("[WARNING] no action specified; auto-formatting targets.json") 00186 00187 targets_file_name = os.path.join(os.curdir, "hal", "targets.json") 00188 try : 00189 targets = load(targets_file_name) 00190 except OSError : 00191 print("[ERROR] did not find targets.json where I expected it {}".format(targets_file_name)) 00192 exit(1) 00193 except ValueError : 00194 print("[ERROR] invalid json found in {}".format(targets_file_name)) 00195 exit(2) 00196 00197 if args.target : 00198 for target in args.target : 00199 device_file = find(target, os.curdir) 00200 if device_file : 00201 add_to_targets(targets, device_file, verbose=args.verbose, remove=args.rm) 00202 else : 00203 print("[WARNING] could not locate a device file for target {}".format(target)) 00204 00205 if args.file : 00206 for file in args.file : 00207 add_to_targets(targets, file, verbose=args.verbose, remove=args.rm) 00208 00209 if args.all : 00210 for file in find_all_devices(os.curdir, verbose=args.verbose) : 00211 add_to_targets(targets, file, verbose=args.verbose, remove=args.rm) 00212 00213 dump(targets_file_name, targets) 00214 00215 for process in git_processes : 00216 process.wait()
Generated on Tue Jul 12 2022 12:22:18 by
