wmlxgettext: Fix "fix invalid escape sequence"

The original code was probably meant to strip trailing whitespace, which
turned out to be a bug when 4be9aa8584
fixed the buggy regexp so that it started working. That has now been
removed.

Fixed handling of multiline plural strings, which was broken too.

One feature has been left unimplemented, and will cause wmlxgettext to error
out. For "long bracketed" strings, Lua allows the contents to start with a
newline, which is automatically stripped from the resulting string. Trying to
understand the original purpose lead me to this feature of Lua strings which we
don't use in Wesnoth; and I finally concluded that, if someone wants to use
that feature, it can be their problem to implement it.

This fixes commit 4be9aa8584.

(cherry picked from commit e4239634e5)
This commit is contained in:
Steve Cotton 2024-04-02 12:26:17 +02:00 committed by Steve Cotton
parent 57b35dd6bd
commit 6f95b062cb
2 changed files with 43 additions and 33 deletions

View file

@ -71,7 +71,9 @@ class LuaCommentState:
return (xline, 'lua_idle')
# This matches translations enclosed in round brackets, such as a normal _("a") or
# the plural _("a", "aa", x), and passes them to the plural-string handling
# functions, even if it later turns out that it's not a plural.
class LuaStr00:
def __init__(self):
self.regex = re.compile(r'((?:_)|(?:.*?\(_)|(?:.*?\s+_))\s*\(')
@ -272,7 +274,7 @@ class LuaStr30:
# Plural Idle 1:
# When argument 1 or 2 is expected
# Here we expect " ' or a [ wich will say us what kind of string we will add.
# Here we expect " ' or a [ which will tell us what kind of string we will add.
class LuaPlIdle1:
def __init__(self):
self.regex = None
@ -363,7 +365,7 @@ class LuaPlIdle3:
#.....................
# Double-quote delimited strings
class LuaPl01:
def __init__(self):
rx = r'"((?:\\"|[^"])*)("?)'
@ -414,7 +416,7 @@ class LuaPl01:
return (xline, _nextstate)
# Single-quote delimited strings
class LuaPl02:
def __init__(self):
rx = r"'((?:\\'|[^'])*)('?)"
@ -465,7 +467,7 @@ class LuaPl02:
return (xline, _nextstate)
# Long-bracketed strings, with the ending on the same line
class LuaPl03:
def __init__(self):
rx = r'\[(=*)\[(.*?)]\1]'
@ -478,23 +480,18 @@ class LuaPl03:
_nextstate = 'lua_plidle2'
if status == 'wait_string':
_nextstate = 'lua_plidle2'
# we must fix values for luatype (wich is used later by
# PendingLuaString.store() )
pywmlx.state.machine._pending_luastring.luatype = 'luastr3'
# storing string into PendingLuaString
pywmlx.state.machine._pending_luastring.luastring = (
match.group(2)
pywmlx.state.machine._pending_luastring.addline(
match.group(2), True
)
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_plural'
)
else:
_nextstate = 'lua_plidle3'
# we must fix values for plural.pluraltype
pywmlx.state.machine._pending_luastring.plural.pluraltype = 2
# storing plural.string into PendingLuaString
pywmlx.state.machine._pending_luastring.plural.string = (
match.group(2)
pywmlx.state.machine._pending_luastring.plural.pluraltype = 3
pywmlx.state.machine._pending_luastring.plural.addline(
match.group(2), True
)
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_close'
@ -503,6 +500,7 @@ class LuaPl03:
# Long-bracketed strings, first line of a multiline string
class LuaPl03o:
def __init__(self):
rx = r'\[(=*)\[(.*)'
@ -515,8 +513,8 @@ class LuaPl03o:
if status == 'wait_string':
pywmlx.state.machine._pending_luastring.ismultiline = True
pywmlx.state.machine._pending_luastring.luatype = 'luastr3'
pywmlx.state.machine._pending_luastring.luastring = (
match.group(2)
pywmlx.state.machine._pending_luastring.addline(
match.group(2), True
)
pywmlx.state.machine._pending_luastring.numequals = (
len(match.group(1))
@ -524,8 +522,8 @@ class LuaPl03o:
else:
pywmlx.state.machine._pending_luastring.plural.ismultiline = True
pywmlx.state.machine._pending_luastring.plural.pluraltype = 3
pywmlx.state.machine._pending_luastring.plural.string = (
match.group(2)
pywmlx.state.machine._pending_luastring.plural.addline(
match.group(2), True
)
pywmlx.state.machine._pending_luastring.plural.numequals = (
len(match.group(1))
@ -534,6 +532,7 @@ class LuaPl03o:
# A previous line opened a double-quote delimited string inside a "_( ... )" translation bracket
# well... the regex will always be true on this state, so iffail will never
# be executed
class LuaPl10:
@ -547,19 +546,19 @@ class LuaPl10:
if status == 'wait_string':
pywmlx.state.machine._pending_luastring.addline( match.group(1) )
else:
pywmlx.state.machine_pending_luastring.plural.addline(
pywmlx.state.machine._pending_luastring.plural.addline(
match.group(1)
)
if match.group(2) == '"':
xline = xline [ match.end(): ]
if status == 'wait_string':
_nextstate = 'lua_plidle2'
pywmlx.state.machine_pending_luastring.plural.status = (
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_plural'
)
else:
_nextstate = 'lua_plidle3'
pywmlx.state.machine_pending_luastring.plural.status = (
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_close'
)
else:
@ -568,6 +567,7 @@ class LuaPl10:
# A previous line opened a single-quote delimited string inside a "_( ... )" translation bracket
# well... the regex will always be true on this state, so iffail will never
# be executed
class LuaPl20:
@ -581,19 +581,19 @@ class LuaPl20:
if status == 'wait_string':
pywmlx.state.machine._pending_luastring.addline( match.group(1) )
else:
pywmlx.state.machine_pending_luastring.plural.addline(
pywmlx.state.machine._pending_luastring.plural.addline(
match.group(1)
)
if match.group(2) == '"':
if match.group(2) == "'":
xline = xline [ match.end(): ]
if status == 'wait_string':
_nextstate = 'lua_plidle2'
pywmlx.state.machine_pending_luastring.plural.status = (
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_plural'
)
else:
_nextstate = 'lua_plidle3'
pywmlx.state.machine_pending_luastring.plural.status = (
pywmlx.state.machine._pending_luastring.plural.status = (
'wait_close'
)
else:

View file

@ -145,7 +145,8 @@ def checksentence(mystring, finfo, *, islua=False):
return 0
# When handling a PendingLuaString, if the string has a plural version then
# this class is used for the PendingLuaString.plural object.
class PendingPlural:
def __init__(self):
self.string = ''
@ -156,14 +157,21 @@ class PendingPlural:
# close parenthesis
# 'wait_close' --> expect close parenthesis
self.status = 'wait_string'
# pluraltype values, used for both single-line and multiline strings
# 0: initial value, should have been changed if a string was found
# 1: delimited by double-quotes
# 2: delimited by single-quotes
# 3: delimited by long brackets, self.numequals is the level of brackets
self.pluraltype = 0
self.numequals = 0
self.ismultiline = False
def addline(self, value, isfirstline=False):
if self.pluraltype != 3:
value = re.sub(r'\s*$', '', value)
else:
if self.pluraltype == 3 and isfirstline and value == "":
# This should be handled by not adding (self.string + '\n') on the next call,
# but someone can implement that if they start using long-bracket strings.
raise NotImplementedError("Not implemented: handling of long-bracket strings that start with a newline.")
if self.pluraltype == 3:
value = value.replace('\\', r'\\')
if isfirstline:
self.string = value
@ -202,9 +210,11 @@ class PendingLuaString:
self.plural = plural
def addline(self, value, isfirstline=False):
if self.luatype != 'luastr3':
value = re.sub(r'\s*$', '', value)
else:
if self.luatype == 'luastr3' and isfirstline and value == "":
# This should be handled by not adding (self.string + '\n') on the next call,
# but someone can implement that if they start using long-bracket strings.
raise NotImplementedError("Not implemented: handling of long-bracket strings that start with a newline.")
if self.luatype == 'luastr3':
value = value.replace('\\', r'\\')
if isfirstline:
self.luastring = value