Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 import json
marcozecchini 0:9fca2b23d0ba 2 import os
marcozecchini 0:9fca2b23d0ba 3 import stat
marcozecchini 0:9fca2b23d0ba 4 import re
marcozecchini 0:9fca2b23d0ba 5 from collections import OrderedDict
marcozecchini 0:9fca2b23d0ba 6 from subprocess import Popen
marcozecchini 0:9fca2b23d0ba 7
marcozecchini 0:9fca2b23d0ba 8 git_processes = []
marcozecchini 0:9fca2b23d0ba 9
marcozecchini 0:9fca2b23d0ba 10 class MyJSONEncoder(json.JSONEncoder):
marcozecchini 0:9fca2b23d0ba 11 def __init__(self, *args, **kwargs):
marcozecchini 0:9fca2b23d0ba 12 super(MyJSONEncoder, self).__init__(*args, **kwargs)
marcozecchini 0:9fca2b23d0ba 13 self.current_indent = 0
marcozecchini 0:9fca2b23d0ba 14 self.current_indent_str = ""
marcozecchini 0:9fca2b23d0ba 15
marcozecchini 0:9fca2b23d0ba 16
marcozecchini 0:9fca2b23d0ba 17 def encode(self, o):
marcozecchini 0:9fca2b23d0ba 18 #Special Processing for lists
marcozecchini 0:9fca2b23d0ba 19 if isinstance(o, (list, tuple)):
marcozecchini 0:9fca2b23d0ba 20 primitives_only = True
marcozecchini 0:9fca2b23d0ba 21 for item in o:
marcozecchini 0:9fca2b23d0ba 22 if isinstance(item, (list, tuple, dict)):
marcozecchini 0:9fca2b23d0ba 23 primitives_only = False
marcozecchini 0:9fca2b23d0ba 24 break
marcozecchini 0:9fca2b23d0ba 25 output = []
marcozecchini 0:9fca2b23d0ba 26 if primitives_only:
marcozecchini 0:9fca2b23d0ba 27 for item in o:
marcozecchini 0:9fca2b23d0ba 28 output.append(json.dumps(item))
marcozecchini 0:9fca2b23d0ba 29 return "[" + ", ".join(output) + "]"
marcozecchini 0:9fca2b23d0ba 30 else:
marcozecchini 0:9fca2b23d0ba 31 self.current_indent += self.indent
marcozecchini 0:9fca2b23d0ba 32 self.current_indent_str = " " * self.current_indent
marcozecchini 0:9fca2b23d0ba 33 for item in o:
marcozecchini 0:9fca2b23d0ba 34 output.append(self.current_indent_str + self.encode(item))
marcozecchini 0:9fca2b23d0ba 35 self.current_indent -= self.indent
marcozecchini 0:9fca2b23d0ba 36 self.current_indent_str = " " * self.current_indent
marcozecchini 0:9fca2b23d0ba 37 return "[\n" + ",\n".join(output) + "\n" + self.current_indent_str + "]"
marcozecchini 0:9fca2b23d0ba 38 elif isinstance(o, dict):
marcozecchini 0:9fca2b23d0ba 39 primitives_only = True
marcozecchini 0:9fca2b23d0ba 40 for item in o.values():
marcozecchini 0:9fca2b23d0ba 41 if isinstance(item, (list, tuple, dict)):
marcozecchini 0:9fca2b23d0ba 42 primitives_only = False
marcozecchini 0:9fca2b23d0ba 43 break
marcozecchini 0:9fca2b23d0ba 44 output = []
marcozecchini 0:9fca2b23d0ba 45 if primitives_only and len(o) < 3:
marcozecchini 0:9fca2b23d0ba 46 for key, value in o.iteritems():
marcozecchini 0:9fca2b23d0ba 47 output.append(json.dumps(key) + ": " + self.encode(value))
marcozecchini 0:9fca2b23d0ba 48 return "{" + ", ".join(output) + "}"
marcozecchini 0:9fca2b23d0ba 49 else:
marcozecchini 0:9fca2b23d0ba 50 self.current_indent += self.indent
marcozecchini 0:9fca2b23d0ba 51 self.current_indent_str = " " * self.current_indent
marcozecchini 0:9fca2b23d0ba 52 for key, value in o.iteritems():
marcozecchini 0:9fca2b23d0ba 53 output.append(self.current_indent_str + json.dumps(key) + ": " + self.encode(value))
marcozecchini 0:9fca2b23d0ba 54 self.current_indent -= self.indent
marcozecchini 0:9fca2b23d0ba 55 self.current_indent_str = " " * self.current_indent
marcozecchini 0:9fca2b23d0ba 56 return "{\n" + ",\n".join(output) + "\n" + self.current_indent_str + "}"
marcozecchini 0:9fca2b23d0ba 57 else:
marcozecchini 0:9fca2b23d0ba 58 return json.dumps(o)
marcozecchini 0:9fca2b23d0ba 59
marcozecchini 0:9fca2b23d0ba 60 def load(path):
marcozecchini 0:9fca2b23d0ba 61 with open(path, 'r') as f :
marcozecchini 0:9fca2b23d0ba 62 return json.load(f, object_pairs_hook=OrderedDict)
marcozecchini 0:9fca2b23d0ba 63
marcozecchini 0:9fca2b23d0ba 64 def dump(path, obj):
marcozecchini 0:9fca2b23d0ba 65 with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR), 'w') as f :
marcozecchini 0:9fca2b23d0ba 66 os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
marcozecchini 0:9fca2b23d0ba 67 f.write(MyJSONEncoder(indent=4).encode(obj))
marcozecchini 0:9fca2b23d0ba 68 f.write(u'\n')
marcozecchini 0:9fca2b23d0ba 69 f.truncate()
marcozecchini 0:9fca2b23d0ba 70
marcozecchini 0:9fca2b23d0ba 71 def find(stem, path) :
marcozecchini 0:9fca2b23d0ba 72 for root, directories, files in os.walk(path, followlinks=True) :
marcozecchini 0:9fca2b23d0ba 73 [dir for dir in directories if dir[0] != '.']
marcozecchini 0:9fca2b23d0ba 74 if (stem_match(stem,os.path.basename(os.path.normpath(root))) and
marcozecchini 0:9fca2b23d0ba 75 "device.h" in files) :
marcozecchini 0:9fca2b23d0ba 76 return os.path.join(root, "device.h")
marcozecchini 0:9fca2b23d0ba 77
marcozecchini 0:9fca2b23d0ba 78 def find_all_devices(path, verbose=False) :
marcozecchini 0:9fca2b23d0ba 79 for root, directories, files in os.walk(path, followlinks=True) :
marcozecchini 0:9fca2b23d0ba 80 [dir for dir in directories if dir[0] != '.']
marcozecchini 0:9fca2b23d0ba 81 if "device.h" in files :
marcozecchini 0:9fca2b23d0ba 82 if verbose : print("[VERBOSE] found a device.h file in {}".format(root))
marcozecchini 0:9fca2b23d0ba 83 yield os.path.join(root, "device.h")
marcozecchini 0:9fca2b23d0ba 84
marcozecchini 0:9fca2b23d0ba 85 mbed_matcher = re.compile('mbed', re.IGNORECASE)
marcozecchini 0:9fca2b23d0ba 86 def stem_match(stem, thing) :
marcozecchini 0:9fca2b23d0ba 87 return (stem in thing or
marcozecchini 0:9fca2b23d0ba 88 re.sub(mbed_matcher, '', stem) in thing)
marcozecchini 0:9fca2b23d0ba 89
marcozecchini 0:9fca2b23d0ba 90 attr_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+1.*$')
marcozecchini 0:9fca2b23d0ba 91 def parse_attributes(path) :
marcozecchini 0:9fca2b23d0ba 92 with open(path) as input :
marcozecchini 0:9fca2b23d0ba 93 for line in input :
marcozecchini 0:9fca2b23d0ba 94 m = re.match(attr_matcher, line)
marcozecchini 0:9fca2b23d0ba 95 if m: yield m.group(1)
marcozecchini 0:9fca2b23d0ba 96
marcozecchini 0:9fca2b23d0ba 97 remove_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+[10].*$')
marcozecchini 0:9fca2b23d0ba 98 def remove_attributes(path) :
marcozecchini 0:9fca2b23d0ba 99 with open(path) as input :
marcozecchini 0:9fca2b23d0ba 100 remainder = filter(lambda l: not re.match(remove_matcher, l), input)
marcozecchini 0:9fca2b23d0ba 101 with open(path,"wb") as output :
marcozecchini 0:9fca2b23d0ba 102 output.truncate(0)
marcozecchini 0:9fca2b23d0ba 103 output.write("// The 'provides' section in 'target.json' is now used"+
marcozecchini 0:9fca2b23d0ba 104 " to create the device's hardware preprocessor switches.\n")
marcozecchini 0:9fca2b23d0ba 105 output.write("// Check the 'provides' section of the target description"+
marcozecchini 0:9fca2b23d0ba 106 " in 'targets.json' for more details.\n")
marcozecchini 0:9fca2b23d0ba 107 output.writelines(remainder)
marcozecchini 0:9fca2b23d0ba 108
marcozecchini 0:9fca2b23d0ba 109 def user_select(things, message) :
marcozecchini 0:9fca2b23d0ba 110 print(message)
marcozecchini 0:9fca2b23d0ba 111 for thing, number in zip(things, range(len(things))):
marcozecchini 0:9fca2b23d0ba 112 print("{} : {}".format(number, thing))
marcozecchini 0:9fca2b23d0ba 113 selection = None
marcozecchini 0:9fca2b23d0ba 114 while selection is None :
marcozecchini 0:9fca2b23d0ba 115 print("please select an integer [0..{}] or specify all".format(len(things) - 1))
marcozecchini 0:9fca2b23d0ba 116 try :
marcozecchini 0:9fca2b23d0ba 117 i = raw_input()
marcozecchini 0:9fca2b23d0ba 118 if i == "all" :
marcozecchini 0:9fca2b23d0ba 119 selection = "all"
marcozecchini 0:9fca2b23d0ba 120 else :
marcozecchini 0:9fca2b23d0ba 121 selection = int(i)
marcozecchini 0:9fca2b23d0ba 122 if (selection > len(things) or
marcozecchini 0:9fca2b23d0ba 123 selection < 0) :
marcozecchini 0:9fca2b23d0ba 124 print("selection {} out of range".format(selection))
marcozecchini 0:9fca2b23d0ba 125 selection = None
marcozecchini 0:9fca2b23d0ba 126 except (ValueError, SyntaxError) :
marcozecchini 0:9fca2b23d0ba 127 print("selection not understood")
marcozecchini 0:9fca2b23d0ba 128 if selection == "all" :
marcozecchini 0:9fca2b23d0ba 129 return things
marcozecchini 0:9fca2b23d0ba 130 else :
marcozecchini 0:9fca2b23d0ba 131 return [things[selection]]
marcozecchini 0:9fca2b23d0ba 132
marcozecchini 0:9fca2b23d0ba 133 target_matcher = re.compile("TARGET_")
marcozecchini 0:9fca2b23d0ba 134 def strip_target(str) :
marcozecchini 0:9fca2b23d0ba 135 return re.sub(target_matcher, "", str)
marcozecchini 0:9fca2b23d0ba 136
marcozecchini 0:9fca2b23d0ba 137 def add_to_targets(targets, device_file, verbose=False, remove=False) :
marcozecchini 0:9fca2b23d0ba 138 if verbose : print("[VERBOSE] trying target {}".format(device_file))
marcozecchini 0:9fca2b23d0ba 139 device = strip_target(os.path.basename(os.path.normpath(os.path.dirname(device_file))))
marcozecchini 0:9fca2b23d0ba 140 if not device :
marcozecchini 0:9fca2b23d0ba 141 print("[WARNING] device {} did not have an associated device.h".format(device))
marcozecchini 0:9fca2b23d0ba 142 else :
marcozecchini 0:9fca2b23d0ba 143 possible_matches = set([key for key in targets.keys() if stem_match(device, key)])
marcozecchini 0:9fca2b23d0ba 144 for key, value in targets.iteritems() :
marcozecchini 0:9fca2b23d0ba 145 for alt in value['extra_labels'] if 'extra_labels' in value else [] :
marcozecchini 0:9fca2b23d0ba 146 if stem_match(device, alt) : possible_matches.add(key)
marcozecchini 0:9fca2b23d0ba 147 for alt in value['extra_labels_add'] if 'extra_labels_add' in value else [] :
marcozecchini 0:9fca2b23d0ba 148 if stem_match(device, alt) : possible_matches.add(key)
marcozecchini 0:9fca2b23d0ba 149 possible_matches = list(possible_matches)
marcozecchini 0:9fca2b23d0ba 150 for match in possible_matches :
marcozecchini 0:9fca2b23d0ba 151 if device == match : possible_matches = [match]
marcozecchini 0:9fca2b23d0ba 152 if not possible_matches :
marcozecchini 0:9fca2b23d0ba 153 print("[WARNING] device {} did not have an associated entry in targets.json".format(device))
marcozecchini 0:9fca2b23d0ba 154 return None
marcozecchini 0:9fca2b23d0ba 155 elif len(possible_matches) > 1 :
marcozecchini 0:9fca2b23d0ba 156 message = ("possible matches for file {}".format(device_file))
marcozecchini 0:9fca2b23d0ba 157 target = user_select(possible_matches, message)
marcozecchini 0:9fca2b23d0ba 158 else :
marcozecchini 0:9fca2b23d0ba 159 target = possible_matches
marcozecchini 0:9fca2b23d0ba 160 attrs = list(parse_attributes(device_file))
marcozecchini 0:9fca2b23d0ba 161 if attrs :
marcozecchini 0:9fca2b23d0ba 162 for t in target :
marcozecchini 0:9fca2b23d0ba 163 targets[t]["device_has"] = sorted(list(set(targets[t].setdefault("device_has",[]) + attrs)))
marcozecchini 0:9fca2b23d0ba 164 if verbose : print("[VERBOSE] target {} now device_has {}".format(t, attrs))
marcozecchini 0:9fca2b23d0ba 165 if remove is True:
marcozecchini 0:9fca2b23d0ba 166 remove_attributes(device_file)
marcozecchini 0:9fca2b23d0ba 167
marcozecchini 0:9fca2b23d0ba 168 if __name__ == '__main__' :
marcozecchini 0:9fca2b23d0ba 169 import argparse
marcozecchini 0:9fca2b23d0ba 170 parser = argparse.ArgumentParser(description='A helpful little script for converting' +
marcozecchini 0:9fca2b23d0ba 171 ' device.h files to parts of the targets.json file')
marcozecchini 0:9fca2b23d0ba 172 parser.add_argument('-a', '--all', action='store_true',
marcozecchini 0:9fca2b23d0ba 173 help='find and convert all available device.h files in the'+
marcozecchini 0:9fca2b23d0ba 174 ' directory tree starting at the current directory')
marcozecchini 0:9fca2b23d0ba 175 parser.add_argument('-f', '--file', nargs='+', help='specify an individual file to '+
marcozecchini 0:9fca2b23d0ba 176 'convert from device.h format to a piece of targets.json')
marcozecchini 0:9fca2b23d0ba 177 parser.add_argument('-t', '--target', nargs='+', help='specify an individual target'+
marcozecchini 0:9fca2b23d0ba 178 ' to convert from device.h format to a piece of targets.json')
marcozecchini 0:9fca2b23d0ba 179 parser.add_argument('-v', '--verbose', action='store_true',
marcozecchini 0:9fca2b23d0ba 180 help="print out every target that is updated in the targets.json")
marcozecchini 0:9fca2b23d0ba 181 parser.add_argument('-r', '--rm', action='store_true',
marcozecchini 0:9fca2b23d0ba 182 help="remove the used attributes from a device.h file")
marcozecchini 0:9fca2b23d0ba 183 args = parser.parse_args()
marcozecchini 0:9fca2b23d0ba 184 if not args.target and not args.file and not args.all :
marcozecchini 0:9fca2b23d0ba 185 print("[WARNING] no action specified; auto-formatting targets.json")
marcozecchini 0:9fca2b23d0ba 186
marcozecchini 0:9fca2b23d0ba 187 targets_file_name = os.path.join(os.curdir, "hal", "targets.json")
marcozecchini 0:9fca2b23d0ba 188 try :
marcozecchini 0:9fca2b23d0ba 189 targets = load(targets_file_name)
marcozecchini 0:9fca2b23d0ba 190 except OSError :
marcozecchini 0:9fca2b23d0ba 191 print("[ERROR] did not find targets.json where I expected it {}".format(targets_file_name))
marcozecchini 0:9fca2b23d0ba 192 exit(1)
marcozecchini 0:9fca2b23d0ba 193 except ValueError :
marcozecchini 0:9fca2b23d0ba 194 print("[ERROR] invalid json found in {}".format(targets_file_name))
marcozecchini 0:9fca2b23d0ba 195 exit(2)
marcozecchini 0:9fca2b23d0ba 196
marcozecchini 0:9fca2b23d0ba 197 if args.target :
marcozecchini 0:9fca2b23d0ba 198 for target in args.target :
marcozecchini 0:9fca2b23d0ba 199 device_file = find(target, os.curdir)
marcozecchini 0:9fca2b23d0ba 200 if device_file :
marcozecchini 0:9fca2b23d0ba 201 add_to_targets(targets, device_file, verbose=args.verbose, remove=args.rm)
marcozecchini 0:9fca2b23d0ba 202 else :
marcozecchini 0:9fca2b23d0ba 203 print("[WARNING] could not locate a device file for target {}".format(target))
marcozecchini 0:9fca2b23d0ba 204
marcozecchini 0:9fca2b23d0ba 205 if args.file :
marcozecchini 0:9fca2b23d0ba 206 for file in args.file :
marcozecchini 0:9fca2b23d0ba 207 add_to_targets(targets, file, verbose=args.verbose, remove=args.rm)
marcozecchini 0:9fca2b23d0ba 208
marcozecchini 0:9fca2b23d0ba 209 if args.all :
marcozecchini 0:9fca2b23d0ba 210 for file in find_all_devices(os.curdir, verbose=args.verbose) :
marcozecchini 0:9fca2b23d0ba 211 add_to_targets(targets, file, verbose=args.verbose, remove=args.rm)
marcozecchini 0:9fca2b23d0ba 212
marcozecchini 0:9fca2b23d0ba 213 dump(targets_file_name, targets)
marcozecchini 0:9fca2b23d0ba 214
marcozecchini 0:9fca2b23d0ba 215 for process in git_processes :
marcozecchini 0:9fca2b23d0ba 216 process.wait()