# @author Jonathan Hui <jhui@archedrock.com>
# @author David Gay
# @author Kevin Klues <klueska@cs.stanford.edu>
+# @author R. Steve McKown <rsmckown@gmail.com>
#
# $Revision$
# $Date$
#
+from __future__ import with_statement # Does this require too new a python?
+
+import os
+import re
from re import match
from sys import *
from xml.dom import *
if len( args ) == 1:
platformdir = args[0]
- # This gives the whole string when there's no / in platformdir
- platform = platformdir[platformdir.rfind( "/" ) + 1:]
+ platform = os.path.basename(platformdir)
+ # In case platformdir was specified with a trailing path separator
+ if not platform:
+ platformdir = os.path.dirname(platformdir)
+ platform = os.path.basename(platformdir)
+ familydir = os.path.dirname(platformdir)
+ if familydir and not os.path.isfile(os.path.join(familydir, '.family')):
+ familydir = ""
elif len( args ) == 0:
platformdir = ""
platform = ""
+ familydir = ""
else:
stderr.write( "Usage: tos-storage-stm25p [-t] <platform directory>\n" )
sub = platform
elif c == 'P':
sub = platformdir
+ elif c == 'F':
+ if not familydir:
+ nfail( "invalid include-path substitution character " + c + "; " + \
+ platform + " not in a family" )
+ sub = familydir
elif c == 'T':
sub = Popen( ["ncc", "-print-tosdir"], stdout=PIPE ).communicate( )[0]
sub = sub[:-1] # remove newline
return path
-NUM_SECTORS = 16
-SECTOR_SIZE = 65536
+HEADER_FILE = 'Stm25p.h'
+NUM_SECTORS = 0
+SECTOR_SIZE = 0
+
+def parseHeader( dotfile ):
+ """ Return an ordered list of paths from the dotfile """
+ paths = []
+ inArray = False
+ p = re.compile('push\s*\(\s*@includes,\s*qw\s*\(');
+ q = re.compile('\)\s*\)\s*;');
+ try:
+ with open(dotfile, 'r') as file:
+ for line in file:
+ path = line.strip()
+ if path:
+ if p.match(path):
+ inArray = True
+ elif q.match(path):
+ inArray = False
+ elif inArray == True:
+ paths.append(path)
+ return paths
+ except:
+ return []
+
+def findFile( paths, filename ):
+ """ Find the first occurrence of 'filename' in the list of paths given. """
+ for path in paths:
+ rpath = expand_path(path)
+ try:
+ for file in os.listdir(rpath):
+ if file == filename:
+ return rpath + '/' + filename
+ except OSError:
+ None
+ return None
+
+def findVars( path, vars ):
+ """ Finds values for the variables already present in vars from path """
+ inEnum = False
+ p = re.compile('enum\s.*{');
+ q = re.compile('}s*;');
+ r = re.compile('^\s*([A-Z0-9_]*)\s*=\s*([^,]*)');
+ with open(path, 'r') as file:
+ for line in file:
+ line = line.strip()
+ if line:
+ if p.match(line):
+ inEnum = True
+ elif q.match(line):
+ inEnum = False
+ elif inEnum == True:
+ m = r.search(line)
+ if vars.has_key(m.group(1)):
+ vars[m.group(1)] = m.group(2)
+
+paths = parseHeader(os.path.join(familydir, '.family')) + \
+ parseHeader(os.path.join(platformdir, '.platform'))
+if paths:
+ path = findFile(paths, HEADER_FILE)
+ if path:
+ enums = {}
+ enums["STM25P_NUM_SECTORS"] = 0
+ enums["STM25P_SECTOR_SIZE_LOG2"] = 0
+ findVars(path, enums)
+ NUM_SECTORS = int(enums["STM25P_NUM_SECTORS"])
+ SECTOR_SIZE = 2**int(enums["STM25P_SECTOR_SIZE_LOG2"])
+if NUM_SECTORS == 0 or SECTOR_SIZE == 0:
+ stderr.write( "tos-storage-stm25p: no valid Stm25p.h found.\n\t"
+ "Check @includes in the platform's .platform file\n" )
+ exit(2)
volumes = {}
outFile.write(" interface BlockWrite[uint8_t volume_id]; \n")
outFile.write(" interface LogRead[uint8_t volumeId]; \n")
outFile.write(" interface LogWrite[uint8_t volumeId]; \n")
-# outFile.write(" interface Mount[uint8_t volumeId]; \n")
-# outFile.write(" interface ConfigStorage[uint8_t volumeId]; \n")
+ outFile.write(" interface Mount[uint8_t volumeId]; \n")
+ outFile.write(" interface ConfigStorage[uint8_t volumeId]; \n")
outFile.write(" } \n")
outFile.write("} \n")
outFile.write("\n")
outFile.write(" BlockWrite = VolumeMapP; \n")
outFile.write(" LogRead = VolumeMapP; \n")
outFile.write(" LogWrite = VolumeMapP; \n")
+ outFile.write(" Mount = VolumeMapP; \n")
+ outFile.write(" ConfigStorage = VolumeMapP; \n")
for i in range(len(volumeNames)):
if volumeTypes[volumeNames[i]] == "block":
outFile.write(" VolumeMapP.SubLogWrite[" + volumeNames[i] + "] -> LogStorageC_" + volumeNames[i] + "; \n")
outFile.write("\n")
-# elif volumeTypes[volumeNames[i]] == "config":
-# outFile.write(" components new ConfigStorageC(" + volumeNames[i] + ") as ConfigStorageC_" + volumeNames[i] + "; \n")
-# outFile.write(" Mount[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n")
-# outFile.write(" ConfigStorage[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n")
+ elif volumeTypes[volumeNames[i]] == "config":
+ outFile.write(" components new ConfigStorageC(" + volumeNames[i] + ") as ConfigStorageC_" + volumeNames[i] + "; \n")
+ outFile.write(" Mount[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n")
+ outFile.write(" ConfigStorage[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n")
outFile.write("} \n")