Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
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.iteritems(): 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.iteritems(): 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.iteritems() : 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 13:16:04 by
