[Libreoffice-commits] .: 2 commits - src/formula.py src/globals.py src/xlsmodel.py src/xlsrecord.py
Kohei Yoshida
kohei at kemper.freedesktop.org
Fri Apr 8 22:28:35 PDT 2011
src/formula.py | 261 -------------------------------------------------------
src/globals.py | 5 -
src/xlsmodel.py | 4
src/xlsrecord.py | 87 ++++++++++--------
4 files changed, 58 insertions(+), 299 deletions(-)
New commits:
commit 55cd111906b799491c527620da7dff7a867ffde3
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Sat Apr 9 01:27:00 2011 -0400
Renamed FormulaPaser2 to FormulaParser.
diff --git a/src/formula.py b/src/formula.py
index b49fa6a..76000ff 100644
--- a/src/formula.py
+++ b/src/formula.py
@@ -597,7 +597,7 @@ _tokenMap = {
0x42: _FuncVar
}
-class FormulaParser2(object):
+class FormulaParser(object):
"""This is a new formula parser that will eventually replace the old one.
Once replaced, I'll change the name to FormulaParser and the names of the
diff --git a/src/xlsmodel.py b/src/xlsmodel.py
index 50b2af3..f47a088 100644
--- a/src/xlsmodel.py
+++ b/src/xlsmodel.py
@@ -425,7 +425,7 @@ class Worksheet(SheetBase):
wbg = wb.getWorkbookGlobal()
tokens = wbg.getFilterRange(self.__sheetID)
- parser = formula.FormulaParser2(None, tokens)
+ parser = formula.FormulaParser(None, tokens)
parser.parse()
tokens = parser.getTokens()
if len(tokens) != 1 or tokens[0].tokenType != formula.TokenType.Area3d:
@@ -528,7 +528,7 @@ class FormulaCell(CellBase):
def createDOM (self, wb):
nd = node.Element('formula-cell')
if self.tokens != None:
- parser = formula.FormulaParser2(None, self.tokens)
+ parser = formula.FormulaParser(None, self.tokens)
parser.parse()
nd.setAttr('formula', parser.getText())
s = globals.getRawBytes(self.tokens, True, False)
diff --git a/src/xlsrecord.py b/src/xlsrecord.py
index 0686650..4d97008 100644
--- a/src/xlsrecord.py
+++ b/src/xlsrecord.py
@@ -649,13 +649,13 @@ class CF(BaseRecordHandler):
if len(self.formula1) > 0:
self.appendLine("formula 1 (bytes): %s"%globals.getRawBytes(self.formula1, True, False))
- parser = formula.FormulaParser2(self.header, self.formula1)
+ parser = formula.FormulaParser(self.header, self.formula1)
parser.parse()
self.appendLine("formula 1 (displayed): " + parser.getText())
if len(self.formula2) > 0:
self.appendLine("formula 2 (bytes): %s"%globals.getRawBytes(self.formula2, True, False))
- parser = formula.FormulaParser2(self.header, self.formula2)
+ parser = formula.FormulaParser(self.header, self.formula2)
parser.parse()
self.appendLine("formula 2 (displayed): " + parser.getText())
@@ -785,7 +785,7 @@ class Dv(BaseRecordHandler):
self.formula1 = self.readBytes(formulaLen)
self.strFormula1 = ''
if len(self.formula1) > 0:
- parser = formula.FormulaParser2(self.header, self.formula1)
+ parser = formula.FormulaParser(self.header, self.formula1)
parser.parse()
self.strFormula1 = parser.getText()
@@ -794,7 +794,7 @@ class Dv(BaseRecordHandler):
self.formula2 = self.readBytes(formulaLen)
self.strFormula2 = ''
if len(self.formula2) > 0:
- parser = formula.FormulaParser2(self.header, self.formula2)
+ parser = formula.FormulaParser(self.header, self.formula2)
parser.parse()
self.strFormula2 = parser.getText()
@@ -944,7 +944,7 @@ class Formula(BaseRecordHandler):
def parseBytes (self):
self.__parseBytes()
- fparser = formula.FormulaParser2(self.header, self.tokens)
+ fparser = formula.FormulaParser(self.header, self.tokens)
fparser.parse()
ftext = fparser.getText()
@@ -981,7 +981,7 @@ class Array(BaseRecordHandler):
self.__parseBytes()
self.appendLine("range: %s"%self.ref.toString())
self.appendLineBoolean("always calc", self.alwaysCalc)
- fparser = formula.FormulaParser2(self.header, self.tokens)
+ fparser = formula.FormulaParser(self.header, self.tokens)
fparser.parse()
self.appendLine("formula bytes: %s"%globals.getRawBytes(self.tokens, True, False))
self.appendLine("formula string: %s"%fparser.getText())
@@ -1512,7 +1512,7 @@ class Name(BaseRecordHandler):
self.__parseBytes()
tokenText = globals.getRawBytes(self.tokenBytes, True, False)
- o = formula.FormulaParser2(self.header, self.tokenBytes)
+ o = formula.FormulaParser(self.header, self.tokenBytes)
o.parse()
formulaText = o.getText()
self.appendLine("name: %s"%globals.encodeName(self.name))
@@ -1694,7 +1694,7 @@ class ExternName(BaseRecordHandler):
self.appendLine("formula bytes: %s"%tokenText)
# parse formula tokens
- o = formula.FormulaParser2(self.header, self.tokens)
+ o = formula.FormulaParser(self.header, self.tokens)
o.parse()
ftext = o.getText()
self.appendLine("formula: %s"%ftext)
@@ -3075,7 +3075,7 @@ class CTCellContent(BaseRecordHandler):
def readFormula (self):
size = globals.getSignedInt(self.readBytes(2))
fmlaBytes = self.readBytes(size)
- o = formula.FormulaParser2(self.header, fmlaBytes)
+ o = formula.FormulaParser(self.header, fmlaBytes)
o.parse()
return "formula", fmlaBytes, o.getText()
@@ -3360,7 +3360,7 @@ class CHSourceLink(BaseRecordHandler):
if self.linkType == CHSourceLink.DataSourceType.Reference:
# external reference. Read the formula tokens.
self.appendLine("formula tokens: %s"%globals.getRawBytes(self.tokens,True,False))
- parser = formula.FormulaParser2(self.header, self.tokens)
+ parser = formula.FormulaParser(self.header, self.tokens)
parser.parse()
self.appendLine("formula: %s"%parser.getText())
commit f06698e14a8b1aac1a527ee17ec273148de398db
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Sat Apr 9 01:25:48 2011 -0400
Re-did EXTERNNAME record handler & removed the obsolete FormulaParser.
diff --git a/src/formula.py b/src/formula.py
index 7fb2c5f..b49fa6a 100644
--- a/src/formula.py
+++ b/src/formula.py
@@ -118,265 +118,6 @@ def parseCellRangeAddress (bytes):
obj.lastCol = (obj.lastCol & 0x00FF)
return obj
-
-def makeSheetName (sheet1, sheet2):
- if sheet2 == None or sheet1 == sheet2:
- sheetName = "sheetID='%d'"%sheet1
- else:
- sheetName = "sheetID='%d-%d'"%(sheet1, sheet2)
- return sheetName
-
-
-class TokenBase(object):
- """base class for token handler
-
-Derive a class from this base class to create a token handler for a formula
-token.
-
-The parse method takes the token array position that points to the first
-token to be processed, and returns the position of the laste token that has
-been processed. So, if the handler processes only one token, it should
-return the same value it receives without incrementing it.
-
-"""
- def __init__ (self, header, tokens):
- self.header = header
- self.tokens = tokens
- self.size = len(self.tokens)
- self.init()
-
- def init (self):
- """initializer for a derived class"""
- pass
-
- def parse (self, i):
- return i
-
- def getText (self):
- return ''
-
-class Add(TokenBase): pass
-class Sub(TokenBase): pass
-class Mul(TokenBase): pass
-class Div(TokenBase): pass
-class Power(TokenBase): pass
-class Concat(TokenBase): pass
-class LT(TokenBase): pass
-class LE(TokenBase): pass
-class EQ(TokenBase): pass
-class GE(TokenBase): pass
-class GT(TokenBase): pass
-class NE(TokenBase): pass
-class Isect(TokenBase): pass
-class List(TokenBase): pass
-class Range(TokenBase): pass
-
-class Plus(TokenBase): pass
-class Minus(TokenBase): pass
-class Percent(TokenBase): pass
-
-class NameX(TokenBase):
- """external name"""
-
- def parse (self, i):
- i += 1
- self.refID = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- self.nameID = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- return i
-
- def getText (self):
- return "<externname externSheetID='%d' nameID='%d'>"%(self.refID, self.nameID)
-
-
-class Ref3dR(TokenBase):
- """3D reference or external reference to a cell"""
-
- def init (self):
- self.cell = None
- self.sheet1 = None
- self.sheet2 = None
-
- def parse (self, i):
- try:
- i += 1
- self.sheet1 = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- if self.header == 0x0023:
- # 3A in EXTERNNAME expects a 2nd sheet index
- self.sheet2 = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- self.cell = parseCellAddress(self.tokens[i:i+4])
- i += 4
- except InvalidCellAddress:
- pass
- return i
-
- def getText (self):
- if self.cell == None:
- return ''
- cellName = self.cell.getName()
- sheetName = makeSheetName(self.sheet1, self.sheet2)
- return "<3dref %s cellAddress='%s'>"%(sheetName, cellName)
-
-
-class Ref3dV(TokenBase):
- """3D reference or external reference to a cell"""
-
- def init (self):
- self.cell = None
-
- def parse (self, i):
- try:
- i += 1
- self.extSheetId = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- self.cell = parseCellAddress(self.tokens[i:i+4])
- i += 4
- except InvalidCellAddress:
- pass
- return i
-
- def getText (self):
- if self.cell == None:
- return ''
- cellName = self.cell.getName()
- return "<3dref externSheetID=%d cellAddress='%s'>"%(self.extSheetId, cellName)
-
-
-class Ref3dA(Ref3dV):
- def __init__ (self, header, tokens):
- Ref3dV.__init__(self, header, tokens)
-
-
-class Area3d(TokenBase):
-
- def parse (self, i):
- self.cellrange = None
- try:
- op = self.tokens[i]
- i += 1
- self.extSheetId = globals.getSignedInt(self.tokens[i:i+2])
- i += 2
- self.cellrange = parseCellRangeAddress(self.tokens[i:i+8])
- except InvalidCellAddress:
- pass
- return i
-
- def getText (self):
- if self.cellrange == None:
- return ''
- cellRangeName = self.cellrange.getName()
- return "<3drange externSheetID=%d rangeAddress='%s'>"%(self.extSheetId, cellRangeName)
-
-class Error(TokenBase):
-
- def parse (self, i):
- i += 1 # skip opcode
- self.errorNum = globals.getSignedInt(self.tokens[i:i+1])
- i += 1
- return i
-
- def getText (self):
- errorText = ''
- if self.errorNum == 0x17:
- errorText = '#REF!'
- return "<error code='0x%2.2X' text='%s'>"%(self.errorNum, errorText)
-
-tokenMap = {
- # binary operator
- 0x03: Add,
- 0x04: Sub,
- 0x05: Mul,
- 0x06: Div,
- 0x07: Power,
- 0x08: Concat,
- 0x09: LT,
- 0x0A: LE,
- 0x0B: EQ,
- 0x0C: GE,
- 0x0D: GT,
- 0x0E: NE,
- 0x0F: Isect,
- 0x10: List,
- 0x11: Range,
-
- # unary operator
- 0x12: Plus,
- 0x13: Minus,
- 0x14: Percent,
-
- # operand tokens
- 0x39: NameX,
- 0x59: NameX,
- 0x79: NameX,
-
- # 3d reference (TODO: There is a slight variation in how a cell reference
- # is represented between 0x3A and 0x5A).
- 0x3A: Ref3dR,
- 0x5A: Ref3dV,
- 0x7A: Ref3dA,
-
- 0x3B: Area3d,
- 0x5B: Area3d,
- 0x7B: Area3d,
-
- 0x1C: Error,
-
- # last item
- 0xFFFF: None
-}
-
-class FormulaParser(object):
- """formula parser for token bytes
-
-This class receives a series of bytes that represent formula tokens through
-the constructor. That series of bytes must also include the formula length
-which is usually the first 2 bytes.
-"""
- def __init__ (self, header, tokens, sizeField=True):
- self.header = header
- self.strm = globals.ByteStream(tokens)
- self.text = ''
- self.sizeField = sizeField
-
- def parse (self):
- length = self.strm.getSize()
- if self.sizeField:
- # first 2-bytes contain the length of the formula tokens
- length = self.strm.readUnsignedInt(2)
- if length <= 0:
- return
- ftokens = self.strm.readBytes(length)
- length = len(ftokens)
- else:
- ftokens = self.strm.readRemainingBytes()
-
- i = 0
- while i < length:
- tk = ftokens[i]
-
- if type(tk) == type('c'):
- # get the ordinal of the character.
- tk = ord(tk)
-
- if not tokenMap.has_key(tk):
- # no token handler
- i += 1
- continue
-
- # token handler exists.
- o = tokenMap[tk](self.header, ftokens)
- i = o.parse(i)
- self.text += o.getText() + ' '
-
- i += 1
-
-
- def getText (self):
- return self.text
-
# ============================================================================
class TokenType:
diff --git a/src/globals.py b/src/globals.py
index de4f199..6c9f31f 100644
--- a/src/globals.py
+++ b/src/globals.py
@@ -112,9 +112,10 @@ class ByteStream(object):
bytes = self.readBytes(8)
return getDouble(bytes)
- def readUnicodeString (self):
+ def readUnicodeString (self, textLen=None):
# First 2-bytes contains the text length, followed by a 1-byte flag.
- textLen = self.readUnsignedInt(2)
+ if textLen == None:
+ textLen = self.readUnsignedInt(2)
bytes = self.bytes[self.pos:]
text, byteLen = getRichText(bytes, textLen)
self.moveForward (byteLen)
diff --git a/src/xlsrecord.py b/src/xlsrecord.py
index 7644dc7..0686650 100644
--- a/src/xlsrecord.py
+++ b/src/xlsrecord.py
@@ -1638,50 +1638,67 @@ class ExternSheet(BaseRecordHandler):
class ExternName(BaseRecordHandler):
- def __parseOptionFlags (self, flags):
- self.isBuiltinName = (flags & 0x0001) != 0
- self.isAutoDDE = (flags & 0x0002) != 0
- self.isStdDocName = (flags & 0x0008) != 0
- self.isOLE = (flags & 0x0010) != 0
+ def __parseBytes (self):
+ flag = self.readUnsignedInt(2)
+
+ self.isBuiltinName = (flag & 0x0001) != 0
+ self.automatic = (flag & 0x0002) != 0
+ self.wantPict = (flag & 0x0004) != 0
+ self.isOLE = (flag & 0x0008) != 0
+ self.isOLELink = (flag & 0x0010) != 0
+
# 5 - 14 bits stores last successful clip format
- self.lastClipFormat = (flags & 0x7FE0)
+ self.clipFormat = (flag & 0x7FE0) / 2**5
- def parseBytes (self):
- # first 2 bytes are option flags for external name.
- optionFlags = globals.getSignedInt(self.bytes[0:2])
- self.__parseOptionFlags(optionFlags)
+ self.displayAsIcon = (flag & 0x8000) != 0
- if self.isOLE:
+ if self.isOLELink:
# next 4 bytes are 32-bit storage ID
- storageID = globals.getSignedInt(self.bytes[2:6])
- nameLen = globals.getSignedInt(self.bytes[6:7])
- name, byteLen = globals.getRichText(self.bytes[7:], nameLen)
- self.appendLine("type: OLE")
- self.appendLine("storage ID: %d"%storageID)
- self.appendLine("name: %s"%name)
+ self.storageID = self.readUnsignedInt(4)
+ nameLen = self.readUnsignedInt(1)
+ self.name = self.readUnicodeString(nameLen)
else:
# assume external defined name (could be DDE link).
# TODO: differentiate DDE link from external defined name.
- supbookID = globals.getSignedInt(self.bytes[2:4])
- nameLen = globals.getSignedInt(self.bytes[6:7])
- name, byteLen = globals.getRichText(self.bytes[7:], nameLen)
- tokenText = globals.getRawBytes(self.bytes[7+byteLen:], True, False)
+ self.supbookID = self.readUnsignedInt(2)
+ nameLen = self.readUnsignedInt(1)
+ self.name = self.readUnicodeString(nameLen)
+ self.tokens = self.readRemainingBytes()
+
+ def parseBytes (self):
+ self.__parseBytes()
+
+ self.appendLineBoolean("built-in name", self.isBuiltinName)
+ self.appendLineBoolean("auto DDE or OLE", self.automatic)
+ self.appendLineBoolean("use picture format", self.wantPict)
+ self.appendLineBoolean("OLE", self.isOLE)
+ self.appendLineBoolean("OLE Link", self.isOLELink)
+ self.appendLine("clip format: %d"%self.clipFormat)
+ self.appendLineBoolean("display as icon", self.displayAsIcon)
+
+ if self.isOLELink:
+ self.appendLine("type: OLE")
+ self.appendLine("storage ID: 0x%4.4X"%self.storageID)
+ self.appendLine("name: %s"%self.name)
+ else:
+ # TODO: Test this.
self.appendLine("type: defined name")
- if supbookID == 0:
+ if self.supbookID == 0:
self.appendLine("sheet ID: 0 (global defined names)")
else:
- self.appendLine("sheet ID: %d"%supbookID)
- self.appendLine("name: %s"%name)
+ self.appendLine("sheet ID: %d"%self.supbookID)
+
+ self.appendLine("name: %s"%self.name)
+ tokenText = globals.getRawBytes(self.tokens, True, False)
self.appendLine("formula bytes: %s"%tokenText)
# parse formula tokens
- o = formula.FormulaParser(self.header, self.bytes[7+byteLen:])
+ o = formula.FormulaParser2(self.header, self.tokens)
o.parse()
ftext = o.getText()
self.appendLine("formula: %s"%ftext)
-
class Xct(BaseRecordHandler):
def __parseBytes (self):
@@ -3058,7 +3075,7 @@ class CTCellContent(BaseRecordHandler):
def readFormula (self):
size = globals.getSignedInt(self.readBytes(2))
fmlaBytes = self.readBytes(size)
- o = formula.FormulaParser(self.header, fmlaBytes, False)
+ o = formula.FormulaParser2(self.header, fmlaBytes)
o.parse()
return "formula", fmlaBytes, o.getText()
More information about the Libreoffice-commits
mailing list