def main(self): """ Main function. """ oDb = TMDatabaseConnection() oLogic = VcsRevisionLogic(oDb) # Where to start. iStartRev = 0 if not self.oConfig.fFull: iStartRev = oLogic.getLastRevision(self.oConfig.sRepository) if iStartRev == 0: iStartRev = self.oConfig.iStartRevision # Construct a command line. os.environ['LC_ALL'] = 'en_US.utf-8' asArgs = [ 'svn', 'log', '--xml', '--revision', str(iStartRev) + ':HEAD', ] if self.oConfig.asExtraOptions is not None: asArgs.extend(self.oConfig.asExtraOptions) asArgs.append(self.oConfig.sUrl) if not self.oConfig.fQuiet: print('Executing: %s' % (asArgs, )) sLogXml = utils.processOutputChecked(asArgs) # Parse the XML and add the entries to the database. oParser = ET.XMLParser(target=ET.TreeBuilder(), encoding='utf-8') oParser.feed(sLogXml.encode('utf-8')) # does its own decoding and processOutputChecked always gives us decoded utf-8 now. oRoot = oParser.close() for oLogEntry in oRoot.findall('logentry'): iRevision = int(oLogEntry.get('revision')) sAuthor = oLogEntry.findtext('author').strip() sDate = oLogEntry.findtext('date').strip() sMessage = oLogEntry.findtext('msg', '').strip() if sMessage == '': sMessage = ' ' elif len(sMessage) > VcsRevisionData.kcchMax_sMessage: sMessage = sMessage[:VcsRevisionData.kcchMax_sMessage - 4] + ' ...' if not self.oConfig.fQuiet: utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s' % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage)) oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage) oLogic.addVcsRevision(oData) oDb.commit() oDb.close() return 0
def darwinGetPanicInfo(self): """ Returns a string with the aapl,panic-info content. """ # Retriev the info. try: sRawInfo = utils.processOutputChecked(['nvram', 'aapl,panic-info']); except Exception, oXcpt: return 'exception running nvram: %s' % (oXcpt,);
def main(self): """ Main function. """ oDb = TMDatabaseConnection(); oLogic = VcsRevisionLogic(oDb); # Where to start. iStartRev = 0; if not self.oConfig.fFull: iStartRev = oLogic.getLastRevision(self.oConfig.sRepository); if iStartRev == 0: iStartRev = self.oConfig.iStartRevision; # Construct a command line. os.environ['LC_ALL'] = 'en_US.utf-8'; asArgs = [ 'svn', 'log', '--xml', '--revision', str(iStartRev) + ':HEAD', ]; if self.oConfig.asExtraOptions is not None: asArgs.extend(self.oConfig.asExtraOptions); asArgs.append(self.oConfig.sUrl); if not self.oConfig.fQuiet: print('Executing: %s' % (asArgs,)); sLogXml = utils.processOutputChecked(asArgs); # Parse the XML and add the entries to the database. oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8'); oParser.feed(sLogXml.encode('utf-8')); # does its own decoding and processOutputChecked always gives us decoded utf-8 now. oRoot = oParser.close(); for oLogEntry in oRoot.findall('logentry'): iRevision = int(oLogEntry.get('revision')); sAuthor = oLogEntry.findtext('author').strip(); sDate = oLogEntry.findtext('date').strip(); sMessage = oLogEntry.findtext('msg', '').strip(); if sMessage == '': sMessage = ' '; elif len(sMessage) > VcsRevisionData.kcchMax_sMessage: sMessage = sMessage[:VcsRevisionData.kcchMax_sMessage - 4] + ' ...'; if not self.oConfig.fQuiet: utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s' % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage)); oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage); oLogic.addVcsRevision(oData); oDb.commit(); oDb.close(); return 0;
def main(self): """ Main function. """ oDb = TMDatabaseConnection() oLogic = VcsRevisionLogic(oDb) # Where to start. iStartRev = 0 if not self.oConfig.fFull: iStartRev = oLogic.getLastRevision(self.oConfig.sRepository) if iStartRev == 0: iStartRev = self.oConfig.iStartRevision # Construct a command line. os.environ["LC_ALL"] = "en_US.utf-8" asArgs = ["svn", "log", "--xml", "--revision", str(iStartRev) + ":HEAD"] if self.oConfig.asExtraOptions is not None: asArgs.extend(self.oConfig.asExtraOptions) asArgs.append(self.oConfig.sUrl) if not self.oConfig.fQuiet: print "Executing: %s" % (asArgs,) sLogXml = utils.processOutputChecked(asArgs) # Parse the XML and add the entries to the database. oParser = ET.XMLParser(target=ET.TreeBuilder(), encoding="utf-8") oParser.feed(sLogXml) oRoot = oParser.close() for oLogEntry in oRoot.findall("logentry"): iRevision = int(oLogEntry.get("revision")) sAuthor = oLogEntry.findtext("author").strip() sDate = oLogEntry.findtext("date").strip() sMessage = oLogEntry.findtext("msg", "").strip() if sMessage == "": sMessage = " " if not self.oConfig.fQuiet: print "sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s" % ( sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage, ) oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage) oLogic.addVcsRevision(oData) oDb.commit() oDb.close() return 0
def main(self): """ Main function. """ oDb = TMDatabaseConnection(); oLogic = VcsRevisionLogic(oDb); # Where to start. iStartRev = 0; if not self.oConfig.fFull: iStartRev = oLogic.getLastRevision(self.oConfig.sRepository); if iStartRev == 0: iStartRev = self.oConfig.iStartRevision; # Construct a command line. os.environ['LC_ALL'] = 'en_US.utf-8'; asArgs = [ 'svn', 'log', '--xml', '--revision', str(iStartRev) + ':HEAD', ]; if self.oConfig.asExtraOptions is not None: asArgs.extend(self.oConfig.asExtraOptions); asArgs.append(self.oConfig.sUrl); if not self.oConfig.fQuiet: print 'Executing: %s' % (asArgs,); sLogXml = utils.processOutputChecked(asArgs); # Parse the XML and add the entries to the database. oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8'); oParser.feed(sLogXml); oRoot = oParser.close(); for oLogEntry in oRoot.findall('logentry'): iRevision = int(oLogEntry.get('revision')); sAuthor = oLogEntry.findtext('author').strip(); sDate = oLogEntry.findtext('date').strip(); sMessage = oLogEntry.findtext('msg', '').strip(); if sMessage == '': sMessage = ' '; if not self.oConfig.fQuiet: print 'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s' % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage); oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage); oLogic.addVcsRevision(oData); oDb.commit(); oDb.close(); return 0;
def _figureVersion(self): """ Tries to figure which VBox version this is, setting self.aiVBoxVer. """ try: sVer = utils.processOutputChecked(['VBoxManage', '--version']) sVer = sVer.strip(); sVer = re.sub(r'_BETA.*r', '.', sVer); sVer = re.sub(r'_ALPHA.*r', '.', sVer); sVer = re.sub(r'_RC.*r', '.', sVer); sVer = sVer.replace('r', '.'); self.aiVBoxVer = [int(sComp) for sComp in sVer.split('.')]; reporter.log('VBox version: %s' % (self.aiVBoxVer,)); except: reporter.logXcpt(); return False; return True;
def _figureVersion(self): """ Tries to figure which VBox version this is, setting self.aiVBoxVer. """ try: sVer = utils.processOutputChecked(['VBoxManage', '--version']) sVer = sVer.strip() sVer = re.sub(r'_BETA.*r', '.', sVer) sVer = re.sub(r'_ALPHA.*r', '.', sVer) sVer = re.sub(r'_RC.*r', '.', sVer) sVer = sVer.replace('r', '.') self.aiVBoxVer = [int(sComp) for sComp in sVer.split('.')] reporter.log('VBox version: %s' % (self.aiVBoxVer, )) except: reporter.logXcpt() return False return True
def _figureVersion(self): """ Tries to figure which VBox version this is, setting self.aiVBoxVer. """ try: sVer = utils.processOutputChecked(["VBoxManage", "--version"]) sVer = sVer.strip() sVer = re.sub(r"_BETA.*r", ".", sVer) sVer = re.sub(r"_ALPHA.*r", ".", sVer) sVer = re.sub(r"_RC.*r", ".", sVer) sVer = sVer.replace("r", ".") self.aiVBoxVer = [int(sComp) for sComp in sVer.split(".")] reporter.log("VBox version: %s" % (self.aiVBoxVer,)) except: reporter.logXcpt() return False return True
def _getHelperOutput(self, sCmd): """ Invokes TestBoxHelper to obtain information hard to access from python. """ if self._sTestBoxHelper is None: if not utils.isRunningFromCheckout(): # See VBoxTestBoxScript.zip for layout. self._sTestBoxHelper = os.path.join(g_ksValidationKitDir, utils.getHostOs(), utils.getHostArch(), \ 'TestBoxHelper'); else: # Only for in-tree testing, so don't bother be too accurate right now. sType = os.environ.get('KBUILD_TYPE', os.environ.get('BUILD_TYPE', 'debug')); self._sTestBoxHelper = os.path.join(g_ksValidationKitDir, os.pardir, os.pardir, os.pardir, 'out', \ utils.getHostOsDotArch(), sType, 'testboxscript', \ utils.getHostOs(), utils.getHostArch(), \ 'TestBoxHelper'); if utils.getHostOs() in ['win', 'os2']: self._sTestBoxHelper += '.exe'; return utils.processOutputChecked([self._sTestBoxHelper, sCmd]).strip();
def _mountShare(self, sMountPoint, sType, sServer, sShare, sUser, sPassword, sWhat): """ Mounts the specified share if needed. Raises exception on failure. """ # Only mount if the type is specified. if sType is None: return True; # Test if already mounted. sTestFile = os.path.join(sMountPoint + os.path.sep, sShare + '.txt'); if os.path.isfile(sTestFile): return True; # # Platform specific mount code. # sHostOs = utils.getHostOs() if sHostOs in ('darwin', 'freebsd'): utils.sudoProcessCall(['/sbin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); utils.sudoProcessCall(['/usr/sbin/chown', str(os.getuid()), sMountPoint]); # pylint: disable=E1101 if sType == 'cifs': # Note! no smb://server/share stuff here, 10.6.8 didn't like it. utils.processOutputChecked(['/sbin/mount_smbfs', '-o', 'automounted,nostreams,soft,noowners,noatime,rdonly', '-f', '0555', '-d', '0555', '//%s:%s@%s/%s' % (sUser, sPassword, sServer, sShare), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'linux': utils.sudoProcessCall(['/bin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); if sType == 'cifs': utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'cifs', '-o', 'user='******',password='******',sec=ntlmv2' + ',uid=' + str(os.getuid()) # pylint: disable=E1101 + ',gid=' + str(os.getgid()) # pylint: disable=E1101 + ',nounix,file_mode=0555,dir_mode=0555,soft,ro', '//%s/%s' % (sServer, sShare), sMountPoint]); elif sType == 'nfs': utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'nfs', '-o', 'soft,ro', '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'solaris': utils.sudoProcessCall(['/sbin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); if sType == 'cifs': ## @todo This stuff doesn't work on wei01-x4600b.de.oracle.com running 11.1. FIXME! oPasswdFile = tempfile.TemporaryFile(); oPasswdFile.write(sPassword + '\n'); oPasswdFile.flush(); utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'smbfs', '-o', 'user='******',uid=' + str(os.getuid()) # pylint: disable=E1101 + ',gid=' + str(os.getgid()) # pylint: disable=E1101 + ',fileperms=0555,dirperms=0555,noxattr,ro', '//%s/%s' % (sServer, sShare), sMountPoint], stdin = oPasswdFile); oPasswdFile.close(); elif sType == 'nfs': utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'nfs', '-o', 'noxattr,ro', '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'win': if sType != 'cifs': raise TestBoxScriptException('Only CIFS mounts are supported on Windows.'); utils.processCall(['net', 'use', sMountPoint, '/d']); utils.processOutputChecked(['net', 'use', sMountPoint, '\\\\' + sServer + '\\' + sShare, sPassword, '/USER:'******'Unsupported host %s' % (sHostOs,)); # # Re-test. # if not os.path.isfile(sTestFile): raise TestBoxException('Failed to mount %s (%s[%s]) at %s: %s not found' % (sWhat, sServer, sShare, sMountPoint, sTestFile)); return True;
def _getHostSystemUuid(self): """ Get the system UUID string from the System, return null-uuid if unable to get retrieve it. """ if self._oOptions.sSystemUuid is not None: return self._oOptions.sSystemUuid; sUuid = self.ksNullUuid; # # Try get at the firmware UUID. # if utils.getHostOs() == 'linux': # NOTE: This requires to have kernel option enabled: # Firmware Drivers -> Export DMI identification via sysfs to userspace if os.path.exists('/sys/devices/virtual/dmi/id/product_uuid'): try: sVar = utils.sudoProcessOutputChecked(['cat', '/sys/devices/virtual/dmi/id/product_uuid']); sUuid = str(uuid.UUID(sVar.strip())); except: pass; ## @todo consider dmidecoder? What about EFI systems? elif utils.getHostOs() == 'win': # Windows: WMI try: import win32com.client; # pylint: disable=F0401 oWmi = win32com.client.Dispatch('WbemScripting.SWbemLocator'); oWebm = oWmi.ConnectServer('.', 'root\\cimv2'); for oItem in oWebm.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct'): if oItem.UUID != None: sUuid = str(uuid.UUID(oItem.UUID)); except: pass; elif utils.getHostOs() == 'darwin': try: sVar = utils.processOutputChecked(['/bin/sh', '-c', '/usr/sbin/ioreg -k IOPlatformUUID' \ + '| /usr/bin/grep IOPlatformUUID' \ + '| /usr/bin/head -1']); sVar = sVar.strip()[-(len(self.ksNullUuid) + 1):-1]; sUuid = str(uuid.UUID(sVar)); except: pass; elif utils.getHostOs() == 'solaris': # Solaris: The smbios util. try: sVar = utils.processOutputChecked(['/bin/sh', '-c', '/usr/sbin/smbios ' \ + '| /usr/xpg4/bin/sed -ne \'s/^.*UUID: *//p\'' \ + '| /usr/bin/head -1']); sUuid = str(uuid.UUID(sVar.strip())); except: pass; if self._isUuidGood(sUuid): return sUuid; # # Try add the MAC address. # uuid.getnode may provide it, or it may return a random number... # lMacAddr = uuid.getnode(); sNode = '%012x' % (lMacAddr,) if lMacAddr == uuid.getnode() and lMacAddr != 0 and len(sNode) == 12: return sUuid[:-12] + sNode; return sUuid;
def _mountShare(self, sMountPoint, sType, sServer, sShare, sUser, sPassword, sWhat): """ Mounts the specified share if needed. Raises exception on failure. """ # Only mount if the type is specified. if sType is None: return True; # Test if already mounted. sTestFile = os.path.join(sMountPoint + os.path.sep, sShare + '-new.txt'); if os.path.isfile(sTestFile): return True; # # Platform specific mount code. # sHostOs = utils.getHostOs() if sHostOs in ('darwin', 'freebsd'): utils.sudoProcessCall(['/sbin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); utils.sudoProcessCall(['/usr/sbin/chown', str(os.getuid()), sMountPoint]); # pylint: disable=E1101 if sType == 'cifs': # Note! no smb://server/share stuff here, 10.6.8 didn't like it. utils.processOutputChecked(['/sbin/mount_smbfs', '-o', 'automounted,nostreams,soft,noowners,noatime,rdonly', '-f', '0555', '-d', '0555', '//%s:%s@%s/%s' % (sUser, sPassword, sServer, sShare), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'linux': utils.sudoProcessCall(['/bin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); if sType == 'cifs': utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'cifs', '-o', 'user='******',password='******',sec=ntlmv2' + ',uid=' + str(os.getuid()) # pylint: disable=E1101 + ',gid=' + str(os.getgid()) # pylint: disable=E1101 + ',nounix,file_mode=0555,dir_mode=0555,soft,ro', '//%s/%s' % (sServer, sShare), sMountPoint]); elif sType == 'nfs': utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'nfs', '-o', 'soft,ro', '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'solaris': utils.sudoProcessCall(['/sbin/umount', sMountPoint]); utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]); if sType == 'cifs': ## @todo This stuff doesn't work on wei01-x4600b.de.oracle.com running 11.1. FIXME! oPasswdFile = tempfile.TemporaryFile(); oPasswdFile.write(sPassword + '\n'); oPasswdFile.flush(); utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'smbfs', '-o', 'user='******',uid=' + str(os.getuid()) # pylint: disable=E1101 + ',gid=' + str(os.getgid()) # pylint: disable=E1101 + ',fileperms=0555,dirperms=0555,noxattr,ro', '//%s/%s' % (sServer, sShare), sMountPoint], stdin = oPasswdFile); oPasswdFile.close(); elif sType == 'nfs': utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'nfs', '-o', 'noxattr,ro', '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)), sMountPoint]); else: raise TestBoxScriptException('Unsupported server type %s.' % (sType,)); elif sHostOs == 'win': if sType != 'cifs': raise TestBoxScriptException('Only CIFS mounts are supported on Windows.'); utils.processCall(['net', 'use', sMountPoint, '/d']); utils.processOutputChecked(['net', 'use', sMountPoint, '\\\\' + sServer + '\\' + sShare, sPassword, '/USER:'******'Unsupported host %s' % (sHostOs,)); # # Re-test. # if not os.path.isfile(sTestFile): raise TestBoxException('Failed to mount %s (%s[%s]) at %s: %s not found' % (sWhat, sServer, sShare, sMountPoint, sTestFile)); return True;
def main(self): """ Main function. """ oDb = TMDatabaseConnection(); oLogic = VcsRevisionLogic(oDb); oBugLogic = VcsBugReferenceLogic(oDb); # Where to start. iStartRev = 0; if not self.oConfig.fFull: if not self.oConfig.fBugRefsOnly: iStartRev = oLogic.getLastRevision(self.oConfig.sRepository); else: iStartRev = oBugLogic.getLastRevision(self.oConfig.sRepository); if iStartRev == 0: iStartRev = self.oConfig.iStartRevision; # Construct a command line. os.environ['LC_ALL'] = 'en_US.utf-8'; asArgs = [ 'svn', 'log', '--xml', '--revision', str(iStartRev) + ':HEAD', ]; if self.oConfig.asExtraOptions is not None: asArgs.extend(self.oConfig.asExtraOptions); asArgs.append(self.oConfig.sUrl); if not self.oConfig.fQuiet: print('Executing: %s' % (asArgs,)); sLogXml = utils.processOutputChecked(asArgs); # Parse the XML and add the entries to the database. oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8'); oParser.feed(sLogXml.encode('utf-8')); # Does its own decoding; processOutputChecked always gives us decoded utf-8 now. oRoot = oParser.close(); for oLogEntry in oRoot.findall('logentry'): iRevision = int(oLogEntry.get('revision')); sAuthor = oLogEntry.findtext('author', 'unspecified').strip(); # cvs2svn entries doesn't have an author. sDate = oLogEntry.findtext('date').strip(); sRawMsg = oLogEntry.findtext('msg', '').strip(); sMessage = sRawMsg; if sMessage == '': sMessage = ' '; elif len(sMessage) > VcsRevisionData.kcchMax_sMessage: sMessage = sMessage[:VcsRevisionData.kcchMax_sMessage - 4] + ' ...'; if not self.oConfig.fQuiet: utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s' % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage)); if not self.oConfig.fBugRefsOnly: oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage); oLogic.addVcsRevision(oData); # Analyze the raw message looking for bug tracker references. for oBugTracker in g_kdBugTrackers.values(): for sTag in oBugTracker.asCommitTags: off = sRawMsg.find(sTag); while off >= 0: off += len(sTag); while off < len(sRawMsg) and sRawMsg[off].isspace(): off += 1; if off < len(sRawMsg) and sRawMsg[off].isdigit(): offNum = off; while off < len(sRawMsg) and sRawMsg[off].isdigit(): off += 1; try: iBugNo = long(sRawMsg[offNum:off]); except Exception as oXcpt: utils.printErr(u'error! exception(r%s,"%s"): -> %s' % (iRevision, sRawMsg[offNum:off], oXcpt,)); else: if not self.oConfig.fQuiet: utils.printOut(u' r%u -> sBugTracker=%s iBugNo=%s' % (iRevision, oBugTracker.sDbId, iBugNo,)); oBugData = VcsBugReferenceData().initFromValues(self.oConfig.sRepository, iRevision, oBugTracker.sDbId, iBugNo); oBugLogic.addVcsBugReference(oBugData); # next off = sRawMsg.find(sTag, off); oDb.commit(); oDb.close(); return 0;
def darwinGetPanicInfo(self): """ Returns a string with the aapl,panic-info content. """ # Retriev the info. try: sRawInfo = utils.processOutputChecked(['nvram', 'aapl,panic-info']); except Exception as oXcpt: return 'exception running nvram: %s' % (oXcpt,); # Decode (%xx) and decompact it (7-bit -> 8-bit). ahDigits = \ { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, }; sInfo = ''; off = len('aapl,panic-info') + 1; iBit = 0; bLow = 0; while off < len(sRawInfo): # isprint is used to determine whether to %xx or %c it, so we have to # be a little careful before assuming % sequences are hex bytes. if sRawInfo[off] == '%' \ and off + 3 <= len(sRawInfo) \ and sRawInfo[off + 1] in ahDigits \ and sRawInfo[off + 2] in ahDigits: bCur = ahDigits[sRawInfo[off + 1]] * 0x10 + ahDigits[sRawInfo[off + 2]]; off += 3; else: bCur = ord(sRawInfo[off]); off += 1; sInfo += chr(((bCur & (0x7f >> iBit)) << iBit) | bLow); bLow = bCur >> (7 - iBit); if iBit < 6: iBit += 1; else: # Final bit in sequence. sInfo += chr(bLow); bLow = 0; iBit = 0; # Expand shorthand. sInfo = sInfo.replace('@', 'com.apple.'); sInfo = sInfo.replace('>', 'com.apple.driver.'); sInfo = sInfo.replace('|', 'com.apple.iokit.'); sInfo = sInfo.replace('$', 'com.apple.security.'); sInfo = sInfo.replace('!A', 'Apple'); sInfo = sInfo.replace('!a', 'Action'); sInfo = sInfo.replace('!B', 'Bluetooth'); sInfo = sInfo.replace('!C', 'Controller'); sInfo = sInfo.replace('!F', 'Family'); sInfo = sInfo.replace('!I', 'Intel'); sInfo = sInfo.replace('!U', 'AppleUSB'); sInfo = sInfo.replace('!P', 'Profile'); # Done. return sInfo