Revamp qstrs: they now include length and hash.

Can now have null bytes in strings.  Can define ROM qstrs per port using
qstrdefsport.h
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
new file mode 100644
index 0000000..4e74ea8
--- /dev/null
+++ b/py/makeqstrdata.py
@@ -0,0 +1,62 @@
+import argparse
+import re
+
+# this must match the equivalent function in qstr.c
+def compute_hash(qstr):
+    hash = 0
+    for char in qstr:
+        hash += ord(char)
+    return hash & 0xffff
+
+def do_work(infiles):
+    # read the qstrs in from the input files
+    qstrs = []
+    for infile in infiles:
+        with open(infile, 'rt') as f:
+            line_number = 0
+            for line in f:
+                line_number += 1
+                line = line.strip()
+
+                # ignore blank lines and comments
+                if len(line) == 0 or line.startswith('//'):
+                    continue
+
+                # verify line is of the correct form
+                match = re.match(r'Q\(([0-9A-Za-z_]+)\)$', line)
+                if not match:
+                    print('({}:{}) bad qstr format, got {}'.format(infile, line_number, line))
+                    return False
+
+                # get the qstr value
+                qstr = match.group(1)
+
+                # don't add duplicates
+                if qstr in qstrs:
+                    continue
+
+                # add the qstr to the list
+                qstrs.append(qstr)
+
+    # process the qstrs, printing out the generated C header file
+    print('// This file was automatically generated by makeqstrdata.py')
+    print()
+    for qstr in qstrs:
+        qhash = compute_hash(qstr)
+        qlen = len(qstr)
+        print('Q({}, (const byte*)"\\x{:02x}\\x{:02x}\\x{:02x}\\x{:02x}" "{}")'.format(qstr, qhash & 0xff, (qhash >> 8) & 0xff, qlen & 0xff, (qlen >> 8) & 0xff, qstr))
+
+    return True
+
+def main():
+    arg_parser = argparse.ArgumentParser(description='Process raw qstr file and output qstr data with length, hash and data bytes')
+    arg_parser.add_argument('files', nargs='+', help='input file(s)')
+    args = arg_parser.parse_args()
+
+    result = do_work(args.files)
+    if not result:
+        print('exiting with error code')
+        exit(1)
+
+if __name__ == "__main__":
+    main()