Skip to content

Commit

Permalink
Fix bug where control codes with spaces were not considered control c…
Browse files Browse the repository at this point in the history
…odes
  • Loading branch information
huderlem committed Nov 14, 2019
1 parent bf97e5f commit 2eac4ff
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 21 deletions.
15 changes: 6 additions & 9 deletions emitter/emitter_test.go
Expand Up @@ -886,9 +886,8 @@ MyScript_18:
func TestEmitTextStatements(t *testing.T) {
input := `
script TextFormatLineBreaks {
msgbox(format("Long cat is loooong once again\p"
"Very very loooong and we need to have"
"multiple lines to fit its loooongness"))
msgbox(format("Ryder: {COLOR BLUE}You were late to getting your"
"first Pokémon from {COLOR GREEN}Professor Cypress{COLOR BLUE}!"))
}
script MyScript {
Expand All @@ -913,9 +912,8 @@ MyScript::
TextFormatLineBreaks_Text_0:
.string "Long cat is loooong once again\p"
.string "Very very loooong and we need to have\n"
.string "multiple lines to fit its loooongness$"
.string "Ryder: {COLOR BLUE}You were late to getting your\n"
.string "first Pokémon from {COLOR GREEN}Professor Cypress{COLOR BLUE}!$"
MyScript_Text_0:
.string "Hello$"
Expand All @@ -938,9 +936,8 @@ MyScript::
TextFormatLineBreaks_Text_0:
.string "Long cat is loooong once again\p"
.string "Very very loooong and we need to have\n"
.string "multiple lines to fit its loooongness$"
.string "Ryder: {COLOR BLUE}You were late to getting your\n"
.string "first Pokémon from {COLOR GREEN}Professor Cypress{COLOR BLUE}!$"
MyScript_Text_0:
.string "Hello$"
Expand Down
29 changes: 20 additions & 9 deletions parser/formattext.go
Expand Up @@ -53,7 +53,10 @@ func (fw *FontWidthsConfig) FormatText(text string, maxWidth int, fontID string)
isFirstWord := true
pos := 0
for pos < len(text) {
endPos, word := fw.getNextWord(text[pos:])
endPos, word, err := fw.getNextWord(text[pos:])
if err != nil {
return "", err
}
if len(word) == 0 {
break
}
Expand Down Expand Up @@ -107,23 +110,24 @@ func (fw *FontWidthsConfig) FormatText(text string, maxWidth int, fontID string)
return formattedSb.String(), nil
}

func (fw *FontWidthsConfig) getNextWord(text string) (int, string) {
func (fw *FontWidthsConfig) getNextWord(text string) (int, string, error) {
escape := false
endPos := 0
startPos := 0
foundNonSpace := false
foundRegularRune := false
endOnNext := false
controlCodeLevel := 0
for pos, char := range text {
if endOnNext {
return pos, text[startPos:pos]
return pos, text[startPos:pos], nil
}
if escape && (char == 'l' || char == 'n' || char == 'p') {
if foundRegularRune {
return endPos, text[startPos:endPos]
return endPos, text[startPos:endPos], nil
}
endOnNext = true
} else if char == '\\' {
} else if char == '\\' && controlCodeLevel == 0 {
escape = true
if !foundRegularRune {
startPos = pos
Expand All @@ -132,23 +136,30 @@ func (fw *FontWidthsConfig) getNextWord(text string) (int, string) {
endPos = pos
} else {
if char == ' ' {
if foundNonSpace {
return pos, text[startPos:pos]
if foundNonSpace && controlCodeLevel == 0 {
return pos, text[startPos:pos], nil
}
} else {
if !foundNonSpace {
startPos = pos
}
foundRegularRune = true
foundNonSpace = true
if char == '{' {
controlCodeLevel++
} else if char == '}' {
if controlCodeLevel > 0 {
controlCodeLevel--
}
}
}
escape = false
}
}
if !foundNonSpace {
return len(text), ""
return len(text), "", nil
}
return len(text), text[startPos:]
return len(text), text[startPos:], nil
}

func (fw *FontWidthsConfig) isLineBreak(word string) bool {
Expand Down
4 changes: 3 additions & 1 deletion parser/formattext_test.go
Expand Up @@ -43,6 +43,8 @@ func TestGetNextWord(t *testing.T) {
{"Hello", 5, "Hello"},
{"{PLAYER} is cool", 8, "{PLAYER}"},
{"{PLAYER}is cool", 10, "{PLAYER}is"},
{"{COLOR BLUE}Player is cool", 18, "{COLOR BLUE}Player"},
{"{ COLOR BLUE RED }Player is cool", 25, "{ COLOR BLUE RED }Player"},
{"Foo Bar", 3, "Foo"},
{`Foo\nBar`, 3, "Foo"},
{`Foo\lBar`, 3, "Foo"},
Expand All @@ -57,7 +59,7 @@ func TestGetNextWord(t *testing.T) {
fw := FontWidthsConfig{}

for i, tt := range tests {
resultPos, resultValue := fw.getNextWord(tt.inputText)
resultPos, resultValue, _ := fw.getNextWord(tt.inputText)
if resultPos != tt.expectedPos {
t.Errorf("TestGetNextWord Test %d: Expected Pos '%d', but Got '%d'", i, tt.expectedPos, resultPos)
}
Expand Down
7 changes: 6 additions & 1 deletion parser/parser.go
Expand Up @@ -866,6 +866,7 @@ func (p *Parser) parseFormatStringOperator() (string, error) {
if err := p.expectPeek(token.STRING); err != nil {
return "", fmt.Errorf("line %d: invalid format() argument '%s'. Expected a string literal", p.peekToken.LineNumber, p.peekToken.Literal)
}
lineNum := p.curToken.LineNumber
rawText := p.curToken.Literal
var fontID string
setFontID := false
Expand All @@ -890,7 +891,11 @@ func (p *Parser) parseFormatStringOperator() (string, error) {
if !setFontID {
fontID = p.fonts.DefaultFontID
}
return p.fonts.FormatText(rawText, 208, fontID)
formatted, err := p.fonts.FormatText(rawText, 208, fontID)
if err != nil {
return "", fmt.Errorf("line %d: %s", lineNum, err.Error())
}
return formatted, nil
}

func (p *Parser) parseIfStatement(scriptName string) (*ast.IfStatement, []impText, error) {
Expand Down
2 changes: 1 addition & 1 deletion parser/parser_test.go
Expand Up @@ -1536,7 +1536,7 @@ script Foo {
text Foo {
format("Hi", "invalidFontID")
}`,
expectedError: "Unknown fontID 'invalidFontID' used in format(). List of valid fontIDs are '[1_latin]'",
expectedError: "line 3: Unknown fontID 'invalidFontID' used in format(). List of valid fontIDs are '[1_latin]'",
},
{
input: `
Expand Down

0 comments on commit 2eac4ff

Please sign in to comment.