Skip to content

Commit

Permalink
Several fixes & misc improvements
Browse files Browse the repository at this point in the history
Mopy/bash/cint.py:
Drop CBash 0.5.0 support entirely

Still had a random try in the middle of cint, when there's absolutely no
point - we can't support CBash 0.5.0 anymore, since all of the functions
have been renamed to start with a cb_, so even the fallback functions
won't exist, leading to cryptic error messages.

Instead, we now check if the CBash DLL is too old with
env.get_file_version() and log a more informative error if that is the
case.

Was originally thought to be the solution for #457, but that issue
turned out to be unrelated. Still a worthwhile commit for dropping a
print and improving the error message.

Mopy/bash/bolt.py:
Mopy/bash/mods_metadta.py:
Fix WryeText display of new tab links

Previously, it kept the exclamation mark if no alternate title was
defined for the link. Also added a better name for the xEdit cleaning
link.

Mopy/bash/basher/dialogs.py:
Fix Import Face dialog crashing

Since this line is unchanged from 9e6bbd9,
I can only conclude that wxPython must have changed behavior somewhere
along the way without anyone noticing. The line is clearly incorrect
though, we were allocating a sizer with space for 6 elements and shoving
10 in.

Note that this is *not* due to wx3 - wx2.8 exhibits the same behavior.

scripts/mktaglist.py:
Regression fix for SSE taglist generation

The taglist dir for SkyrimSE was renamed from 'Skyrim Special Edition'
to 'SkyrimSE' in 3542194.

However, the mktaglist script was not updated to account for these
changes. Whoops.

Mopy/bash/bosh/cosaves.py:
cosaves: Fixup for pluggy cosaves

Missed this when I fixed the xSE ones not discarding their lightly
loaded chunks before loading the full cosave.

Threw in a minor formatting change right below it, wrapping those
comments properly.

Under #437

Mopy/bash/ScriptParser.py:
ScriptParser: Fix broken arg count errors

When redoing some screenshots, I tried to reproduce the following error message:

  An error occurred in the wizard script:
  Line 15:	    Else 'What am I doing here?'
  Error:	(Line 15, Column 33): Too many arguments to Keyword 'Else':  got 1, expected 0.

However, I only managed to create the following:

  An error occurred in the wizard script:
  Line 15:	    Else 'What am I doing here?'
  Error:	(Line 15, Column 33): Too many arguments to Keyword 'self.text':  got 1, expected 0.

Turns out that the error reporting here has been broken since
40e3faa back in 2011.
Also wrapped the code I touched.

Under #446
  • Loading branch information
Infernio committed Sep 16, 2019
1 parent c0d818a commit 9e222e0
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 31 deletions.
51 changes: 35 additions & 16 deletions Mopy/bash/ScriptParser.py
Expand Up @@ -226,7 +226,9 @@ class ParserType(object):
def Type(self): return self.__class__.__name__

class Callable(ParserType):
def __init__(self, function, min_args=0, max_args=KEY.NA, passTokens=False, passCommas=False):
def __init__(self, callable_name, function, min_args=0,
max_args=KEY.NA, passTokens=False, passCommas=False):
self.callable_name = callable_name
self.function = function
self.passTokens = passTokens
self.passCommas = passCommas
Expand All @@ -246,33 +248,46 @@ def execute(self, *args):
numArgs = len(args)
if self.maxArgs != KEY.NO_MAX and numArgs > self.maxArgs:
if self.minArgs == self.maxArgs:
error(ERR_TOO_MANY_ARGS % (self.Type, u'self.text', numArgs, self.minArgs))
error(ERR_TOO_MANY_ARGS % (
self.Type, self.callable_name, numArgs, self.minArgs))
else:
error(ERR_TOO_MANY_ARGS % (self.Type, u'self.text', numArgs, u'min: %s, max: %s' % (self.minArgs,self.maxArgs)))
error(ERR_TOO_MANY_ARGS % (
self.Type, self.callable_name, numArgs,
u'min: %s, max: %s' % (self.minArgs,self.maxArgs)))
if numArgs < self.minArgs:
if self.maxArgs == KEY.NO_MAX:
error(ERR_TOO_FEW_ARGS % (self.Type, u'self.text', numArgs, u'min: %s' % self.minArgs))
error(ERR_TOO_FEW_ARGS % (
self.Type, self.callable_name, numArgs,
u'min: %s' % self.minArgs))
elif self.minArgs == self.maxArgs:
error(ERR_TOO_FEW_ARGS % (self.Type, u'self.text', numArgs, self.minArgs))
error(ERR_TOO_FEW_ARGS % (
self.Type, self.callable_name, numArgs, self.minArgs))
else:
error(ERR_TOO_FEW_ARGS % (self.Type, u'self.text', numArgs, u'min: %s, max: %s' % (self.minArgs, self.maxArgs)))
error(ERR_TOO_FEW_ARGS % (
self.Type, self.callable_name, numArgs,
u'min: %s, max: %s' % (self.minArgs, self.maxArgs)))
return self.function(*args)


class Operator(Callable):
def __init__(self, function, precedence, association=LEFT, passTokens=True):
def __init__(self, operator_name, function, precedence,
association=LEFT, passTokens=True):
self.precedence = precedence
self.association = association
if self.precedence in (OP.UNA, OP.NOT):
min_args = 1
else:
min_args = 2
super(Parser.Operator,self).__init__(function, min_args, passTokens=passTokens)
super(Parser.Operator,self).__init__(operator_name, function,
min_args,
passTokens=passTokens)

class Keyword(Callable):
def __init__(self, function, min_args=0, max_args=KEY.NA, passTokens=False, splitCommas=True, passCommas=False):
def __init__(self, keyword_name, function, min_args=0, max_args=KEY.NA,
passTokens=False, splitCommas=True, passCommas=False):
self.splitCommas = splitCommas
super(Parser.Keyword,self).__init__(function, min_args, max_args, passTokens, passCommas)
super(Parser.Keyword,self).__init__(keyword_name, function,
min_args, max_args,
passTokens, passCommas)

def __call__(self, *args):
gParser.StripOuterParens(args)
Expand All @@ -294,13 +309,16 @@ def __call__(self, *args):
return self.execute(*args)

class Function(Callable):
def __init__(self, function, min_args=0, max_args=KEY.NA, passTokens=False, dotFunction=False):
def __init__(self, function_name, function, min_args=0,
max_args=KEY.NA, passTokens=False, dotFunction=False):
"""function: function that will be called with the args
num_args: number of args required for the function
passTokens: whether tokens or the data within should be passed as args
dotFunction: whether this function can be called using the dot operator
"""
super(Parser.Function,self).__init__(function, min_args, max_args, passTokens)
super(Parser.Function,self).__init__(function_name, function,
min_args, max_args,
passTokens)
self.dotFunction = dotFunction

class Token:
Expand Down Expand Up @@ -443,19 +461,19 @@ def SetOperator(self, name, *args, **kwdargs):
type_ = getType(name, self)
if type_ not in [NAME,OPERATOR,UNKNOWN]:
error(ERR_CANNOT_SET % (u'operator', name, Types[type_]))
self.operators[name] = Parser.Operator(*args, **kwdargs)
self.operators[name] = Parser.Operator(name, *args, **kwdargs)
for i in name:
if i not in self.opChars: self.opChars += i
def SetKeyword(self, name, *args, **kwdargs):
type_ = getType(name, self)
if type_ not in [NAME,KEYWORD]:
error(ERR_CANNOT_SET % (u'keyword', name, Types[type_]))
self.keywords[name] = Parser.Keyword(*args, **kwdargs)
self.keywords[name] = Parser.Keyword(name, *args, **kwdargs)
def SetFunction(self, name, *args, **kwdargs):
type_ = getType(name, self)
if type_ not in [NAME,FUNCTION]:
error(ERR_CANNOT_SET % (u'function', name, Types[type_]))
self.functions[name] = Parser.Function(*args, **kwdargs)
self.functions[name] = Parser.Function(name, *args, **kwdargs)
def SetConstant(self, name, value):
type_ = getType(name, self)
if type_ not in [NAME,CONSTANT]:
Expand All @@ -465,6 +483,7 @@ def SetVariable(self, name, value):
type_ = getType(name, self)
if type_ not in [NAME, VARIABLE]:
error(ERR_CANNOT_SET % (u'variable', name, Types[type_]))
self.variables[name] = value

# Flow control stack
def PushFlow(self, stmnt_type, active, keywords, **attribs):
Expand Down
2 changes: 1 addition & 1 deletion Mopy/bash/basher/dialogs.py
Expand Up @@ -292,7 +292,7 @@ def __init__(self, parent, title, fileInfo, faces):
onButClick=self.DoImport, default=True)
self.picture = balt.Picture(self,350,210,scaling=2)
#--Layout
fgSizer = wx.FlexGridSizer(3,2,2,4)
fgSizer = wx.FlexGridSizer(5,2,2,4)
fgSizer.AddGrowableCol(1,1)
fgSizer.AddMany([
self.nameCheck,
Expand Down
3 changes: 3 additions & 0 deletions Mopy/bash/bolt.py
Expand Up @@ -2294,6 +2294,9 @@ def subLink(match):
if address == u'#': address += unicode(urllib.quote(reWd.sub(u'',text).encode('utf8')),'cp1252')
if address.startswith(u'!'):
newWindow = u' target="_blank"'
if address == text:
# We have no text, cut off the '!' here too
text = text[1:]
address = address[1:]
else:
newWindow = u''
Expand Down
9 changes: 6 additions & 3 deletions Mopy/bash/bosh/cosaves.py
Expand Up @@ -1468,9 +1468,12 @@ def __init__(self, cosave_path):
def read_cosave(self, light=False):
target_state = 1 if light else 2
if self.loading_state < target_state:
# The Pluggy file format requires reading a file twice: once all but
# the last 12 bytes, which is used for reading the header an chunks,
# and once all but the last 4 bytes, for a CRC check.
# Need to reset these to avoid adding duplicates
self.cosave_chunks = []
self.remappable_chunks = []
# The Pluggy file format requires reading a file twice: once all
# but the last 12 bytes, which is used for reading the header and
# chunks, and once all but the last 4 bytes, for a CRC check.
total_size = self.cosave_path.size
with self.cosave_path.open('rb') as ins:
# This is what we'll read the header and chunks from later.
Expand Down
2 changes: 1 addition & 1 deletion Mopy/bash/bosh/mods_metadata.py
Expand Up @@ -360,7 +360,7 @@ def refreshRuleSets(self):
ModRuleSet.RuleParser(ruleSet).parse(path)

_cleaning_wiki_url = u'[[!https://tes5edit.github.io/docs/5-mod-cleaning' \
u'-and-error-checking.html]]'
u'-and-error-checking.html|Tome of xEdit]]'

def checkMods(self, showModList=False, showRuleSets=False, showNotes=False,
showConfig=True, showSuggest=True, showCRC=False,
Expand Down
18 changes: 9 additions & 9 deletions Mopy/bash/cint.py
Expand Up @@ -170,12 +170,17 @@ def PositiveIsErrorCheck(result, function, cArguments, *args):
if isinstance(path,unicode) and os.name in ('nt','ce'):
LoadLibrary = windll.kernel32.LoadLibraryW
handle = LoadLibrary(path)
from env import get_file_version
if get_file_version(path) < (0, 7):
raise ImportError(u'Bundled CBash version is too old for this '
u'Wrye Bash version. Only 0.7.0+ is '
u'supported.')
_CBash = CDLL(path,handle=handle)
break
del paths
except (AttributeError,ImportError,OSError) as error:
_CBash = None
print error
deprint(u'Failed to import CBash.', traceback=True)
except:
_CBash = None
raise
Expand Down Expand Up @@ -206,14 +211,9 @@ def RaiseCB(raisedString):
## raise CBashError("Check the log.")
return

try:
_CGetVersionMajor = _CBash.cb_GetVersionMajor
_CGetVersionMinor = _CBash.cb_GetVersionMinor
_CGetVersionRevision = _CBash.cb_GetVersionRevision
except AttributeError: #Functions were renamed in v0.5.0
_CGetVersionMajor = _CBash.cb_GetMajor
_CGetVersionMinor = _CBash.cb_GetMinor
_CGetVersionRevision = _CBash.cb_GetRevision
_CGetVersionMajor = _CBash.cb_GetVersionMajor
_CGetVersionMinor = _CBash.cb_GetVersionMinor
_CGetVersionRevision = _CBash.cb_GetVersionRevision
_CGetVersionMajor.restype = c_ulong
_CGetVersionMinor.restype = c_ulong
_CGetVersionRevision.restype = c_ulong
Expand Down
2 changes: 1 addition & 1 deletion scripts/mktaglist.py
Expand Up @@ -47,7 +47,7 @@ def DownloadMasterlist(repository, destinationPath):
gamesData = [
(u'Oblivion', 'Oblivion.esm', 'oblivion', loot_api.GameType.tes4),
(u'Skyrim', 'Skyrim.esm', 'skyrim', loot_api.GameType.tes5),
(u'Skyrim Special Edition', 'Skyrim.esm', 'skyrimse', loot_api.GameType.tes5se),
(u'SkyrimSE', 'Skyrim.esm', 'skyrimse', loot_api.GameType.tes5se),
(u'Fallout3', 'Fallout3.esm', 'fallout3', loot_api.GameType.fo3),
(u'FalloutNV', 'FalloutNV.esm', 'falloutnv', loot_api.GameType.fonv),
(u'Fallout4', 'Fallout4.esm', 'fallout4', loot_api.GameType.fo4),
Expand Down

0 comments on commit 9e222e0

Please sign in to comment.