aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2019-05-26 03:14:48 +0700
committerShulhan <ms@kilabit.info>2019-05-26 03:19:07 +0700
commit9e0f6248bce30a6517c8d8cf3a08e3e7fa748c2a (patch)
tree353bc97a70b7a7239e4a5ab7c8e5095e9a26c002
parentc9ceaece557a117b0962710d1523d8dec35811d8 (diff)
downloadpakakeh.go-9e0f6248bce30a6517c8d8cf3a08e3e7fa748c2a.tar.xz
ini: replace multiple ifs conditions with switch statement
This is the third part of refactoring ini package. The change affect on how variable value being fetched and formatted.
-rw-r--r--lib/ini/linemode.go18
-rw-r--r--lib/ini/reader.go242
-rw-r--r--lib/ini/reader_test.go26
-rw-r--r--lib/ini/variable.go8
4 files changed, 152 insertions, 142 deletions
diff --git a/lib/ini/linemode.go b/lib/ini/linemode.go
index 68887a19..cecc8b48 100644
--- a/lib/ini/linemode.go
+++ b/lib/ini/linemode.go
@@ -15,3 +15,21 @@ const (
lineModeValue lineMode = 16
lineModeMulti lineMode = 32
)
+
+//
+// isLineModeVar will return true if mode is variable, which is either
+// lineModeSingle, lineModeValue, or lineModeMulti; otherwise it will return
+// false.
+//
+func isLineModeVar(mode lineMode) bool {
+ if mode&lineModeSingle > 0 {
+ return true
+ }
+ if mode&lineModeValue > 0 {
+ return true
+ }
+ if mode&lineModeMulti > 0 {
+ return true
+ }
+ return false
+}
diff --git a/lib/ini/reader.go b/lib/ini/reader.go
index 1b7af049..584b88a7 100644
--- a/lib/ini/reader.go
+++ b/lib/ini/reader.go
@@ -24,7 +24,6 @@ const (
tokHash = '#'
tokHyphen = '-'
tokNewLine = '\n'
- tokPercent = '%'
tokSecEnd = ']'
tokSecStart = '['
tokSemiColon = ';'
@@ -134,9 +133,7 @@ func (reader *reader) Parse(src []byte) (in *Ini, err error) {
reader._var.lineNum = reader.lineNum
- if reader._var.mode&lineModeSingle == lineModeSingle ||
- reader._var.mode&lineModeValue == lineModeValue ||
- reader._var.mode&lineModeMulti == lineModeMulti {
+ if isLineModeVar(reader._var.mode) {
if reader.sec.mode == lineModeEmpty {
err = fmt.Errorf(errVarNoSection,
reader.lineNum,
@@ -189,33 +186,36 @@ func (reader *reader) Parse(src []byte) (in *Ini, err error) {
}
func (reader *reader) parse() (err error) {
+ var isNewline bool
+
reader.bufFormat.Reset()
- for {
+ for !isNewline {
reader.b, err = reader.br.ReadByte()
if err != nil {
return err
}
- if reader.b == tokNewLine {
+ switch reader.b {
+ case tokNewLine:
reader.bufFormat.WriteByte(reader.b)
reader._var.format = reader.bufFormat.String()
- break
- }
- if reader.b == tokSpace || reader.b == tokTab {
+ isNewline = true
+
+ case tokSpace, tokTab:
reader.bufFormat.WriteByte(reader.b)
- continue
- }
- if reader.b == tokHash || reader.b == tokSemiColon {
- _ = reader.br.UnreadByte()
+ case tokHash, tokSemiColon:
+ _ = reader.br.UnreadByte()
return reader.parseComment()
- }
- if reader.b == tokSecStart {
+
+ case tokSecStart:
_ = reader.br.UnreadByte()
return reader.parseSectionHeader()
+
+ default:
+ _ = reader.br.UnreadByte()
+ return reader.parseVariable()
}
- _ = reader.br.UnreadByte()
- return reader.parseVariable()
}
return nil
@@ -270,30 +270,31 @@ func (reader *reader) parseSectionHeader() (err error) {
return errBadConfig
}
+ var isNewline bool
reader.bufFormat.Write([]byte{'%', 's'})
reader.buf.WriteRune(reader.r)
- for {
+ for !isNewline {
reader.r, _, err = reader.br.ReadRune()
if err != nil {
return errBadConfig
}
- if reader.r == tokSpace || reader.r == tokTab {
- break
- }
- if reader.r == tokSecEnd {
- reader.bufFormat.WriteRune(reader.r)
+ switch {
+ case reader.r == tokSpace, reader.r == tokTab:
+ isNewline = true
+ case reader.r == tokSecEnd:
+ reader.bufFormat.WriteRune(reader.r)
reader._var.secName = reader.buf.String()
-
return reader.parsePossibleComment()
- }
- if unicode.IsLetter(reader.r) || unicode.IsDigit(reader.r) || reader.r == tokHyphen || reader.r == tokDot {
+
+ case unicode.IsLetter(reader.r), unicode.IsDigit(reader.r),
+ reader.r == tokHyphen, reader.r == tokDot:
reader.buf.WriteRune(reader.r)
- continue
- }
- return errBadConfig
+ default:
+ return errBadConfig
+ }
}
reader.bufFormat.WriteRune(reader.r)
@@ -302,15 +303,12 @@ func (reader *reader) parseSectionHeader() (err error) {
return reader.parseSubsection()
}
-//
-// (0) Skip white-spaces
-//
func (reader *reader) parseSubsection() (err error) {
reader.buf.Reset()
reader._var.mode |= lineModeSubsection
- // (0)
+ // Skip white-spaces
for {
reader.b, err = reader.br.ReadByte()
if err != nil {
@@ -371,25 +369,26 @@ func (reader *reader) parseSubsection() (err error) {
// character.
//
func (reader *reader) parsePossibleComment() (err error) {
- for {
+ var isNewline bool
+
+ for !isNewline {
reader.b, err = reader.br.ReadByte()
if err != nil {
break
}
- if reader.b == tokNewLine {
+ switch reader.b {
+ case tokNewLine:
reader.bufFormat.WriteByte(reader.b)
- break
- }
- if reader.b == tokSpace || reader.b == tokTab {
+ isNewline = true
+ case tokSpace, tokTab:
reader.bufFormat.WriteByte(reader.b)
- continue
- }
- if reader.b == tokHash || reader.b == tokSemiColon {
+ case tokHash, tokSemiColon:
_ = reader.br.UnreadByte()
- err = reader.parseComment()
- return
+ return reader.parseComment()
+
+ default:
+ return errBadConfig
}
- return errBadConfig
}
reader._var.format = reader.bufFormat.String()
@@ -409,25 +408,34 @@ func (reader *reader) parseVariable() (err error) {
return errVarNameInvalid
}
+ var isNewline bool
reader.bufFormat.Write([]byte{'%', 's'})
reader.buf.WriteRune(reader.r)
- for {
+ for !isNewline {
reader.r, _, err = reader.br.ReadRune()
if err != nil {
break
}
- if reader.r == tokNewLine {
+ switch {
+ case reader.r == tokEqual:
reader.bufFormat.WriteRune(reader.r)
- break
- }
- if unicode.IsLetter(reader.r) || unicode.IsDigit(reader.r) ||
- reader.r == tokHyphen || reader.r == tokDot ||
- reader.r == tokUnderscore {
+
+ reader._var.mode = lineModeSingle
+ reader._var.key = reader.buf.String()
+
+ return reader.parseVarValue()
+
+ case reader.r == tokNewLine:
+ reader.bufFormat.WriteRune(reader.r)
+ isNewline = true
+
+ case unicode.IsLetter(reader.r), unicode.IsDigit(reader.r),
+ reader.r == tokHyphen, reader.r == tokDot,
+ reader.r == tokUnderscore:
reader.buf.WriteRune(reader.r)
- continue
- }
- if reader.r == tokHash || reader.r == tokSemiColon {
+
+ case reader.r == tokHash, reader.r == tokSemiColon:
_ = reader.br.UnreadRune()
reader._var.mode = lineModeSingle
@@ -435,24 +443,18 @@ func (reader *reader) parseVariable() (err error) {
reader._var.value = varValueTrue
return reader.parseComment()
- }
- if unicode.IsSpace(reader.r) {
+
+ case unicode.IsSpace(reader.r):
reader.bufFormat.WriteRune(reader.r)
reader._var.mode = lineModeSingle
reader._var.key = reader.buf.String()
return reader.parsePossibleValue()
- }
- if reader.r == tokEqual {
- reader.bufFormat.WriteRune(reader.r)
- reader._var.mode = lineModeSingle
- reader._var.key = reader.buf.String()
-
- return reader.parseVarValue()
+ default:
+ return errVarNameInvalid
}
- return errVarNameInvalid
}
reader._var.mode = lineModeSingle
@@ -468,29 +470,30 @@ func (reader *reader) parseVariable() (err error) {
// or `=`.
//
func (reader *reader) parsePossibleValue() (err error) {
- for {
+ var isNewline bool
+ for !isNewline {
reader.b, err = reader.br.ReadByte()
if err != nil {
break
}
- if reader.b == tokNewLine {
+ switch reader.b {
+ case tokNewLine:
reader.bufFormat.WriteByte(reader.b)
- break
- }
- if reader.b == tokSpace || reader.b == tokTab {
+ isNewline = true
+
+ case tokSpace, tokTab:
reader.bufFormat.WriteByte(reader.b)
- continue
- }
- if reader.b == tokHash || reader.b == tokSemiColon {
+
+ case tokHash, tokSemiColon:
_ = reader.br.UnreadByte()
reader._var.value = varValueTrue
return reader.parseComment()
- }
- if reader.b == tokEqual {
+ case tokEqual:
reader.bufFormat.WriteByte(reader.b)
return reader.parseVarValue()
+ default:
+ return errVarNameInvalid
}
- return errVarNameInvalid
}
reader._var.mode = lineModeSingle
@@ -504,13 +507,12 @@ func (reader *reader) parsePossibleValue() (err error) {
// At this point we found `=` on source, and we expect the rest of source will
// be variable value.
//
-// (0) Consume leading white-spaces.
-//
func (reader *reader) parseVarValue() (err error) {
reader.buf.Reset()
reader.bufSpaces.Reset()
- // (0)
+ // Consume leading white-spaces.
+consume_spaces:
for {
reader.b, err = reader.br.ReadByte()
if err != nil {
@@ -518,16 +520,17 @@ func (reader *reader) parseVarValue() (err error) {
reader._var.value = varValueTrue
return err
}
- if reader.b == tokSpace || reader.b == tokTab {
+ switch reader.b {
+ case tokSpace, tokTab:
reader.bufFormat.WriteByte(reader.b)
- continue
- }
- if reader.b == tokHash || reader.b == tokSemiColon {
+ continue consume_spaces
+
+ case tokHash, tokSemiColon:
_ = reader.br.UnreadByte()
reader._var.value = varValueTrue
return reader.parseComment()
- }
- if reader.b == tokNewLine {
+
+ case tokNewLine:
reader.bufFormat.WriteByte(reader.b)
reader._var.format = reader.bufFormat.String()
reader._var.value = varValueTrue
@@ -536,97 +539,91 @@ func (reader *reader) parseVarValue() (err error) {
break
}
+ reader.bufFormat.Write([]byte{'%', 's'})
reader._var.mode = lineModeValue
_ = reader.br.UnreadByte()
var (
- quoted bool
- esc bool
+ quoted bool
+ esc bool
+ isNewline bool
)
- for {
+ for !isNewline {
reader.b, err = reader.br.ReadByte()
if err != nil {
break
}
if esc {
- if reader.b == tokNewLine {
+ switch reader.b {
+ case tokNewLine:
reader._var.mode = lineModeMulti
-
reader.valueCommit(true)
-
- reader.bufFormat.WriteByte(tokNewLine)
-
reader.lineNum++
esc = false
continue
- }
- if reader.b == tokBackslash || reader.b == tokDoubleQuote {
+
+ case tokBackslash, tokDoubleQuote:
reader.valueWriteByte(reader.b)
esc = false
continue
- }
- if reader.b == 'b' {
- reader.bufFormat.WriteByte(reader.b)
+
+ case 'b':
reader.buf.WriteByte(tokBackspace)
esc = false
continue
- }
- if reader.b == 'n' {
- reader.bufFormat.WriteByte(reader.b)
+
+ case 'n':
reader.buf.WriteByte(tokNewLine)
esc = false
continue
- }
- if reader.b == 't' {
- reader.bufFormat.WriteByte(reader.b)
+ case 't':
reader.buf.WriteByte(tokTab)
esc = false
continue
}
return errValueInvalid
}
- if reader.b == tokSpace || reader.b == tokTab {
+
+ switch reader.b {
+ case tokSpace, tokTab:
if quoted {
reader.valueWriteByte(reader.b)
continue
}
- reader.bufFormat.WriteByte(reader.b)
reader.bufSpaces.WriteByte(reader.b)
- continue
- }
- if reader.b == tokBackslash {
- reader.bufFormat.WriteByte(reader.b)
+
+ case tokBackslash:
esc = true
- continue
- }
- if reader.b == tokDoubleQuote {
- reader.bufFormat.WriteByte(reader.b)
+
+ case tokDoubleQuote:
if quoted {
quoted = false
} else {
quoted = true
}
- continue
- }
- if reader.b == tokNewLine {
+
+ case tokNewLine:
reader.bufFormat.WriteByte(reader.b)
- break
- }
- if reader.b == tokHash || reader.b == tokSemiColon {
+ isNewline = true
+
+ case tokHash, tokSemiColon:
if quoted {
reader.valueWriteByte(reader.b)
continue
}
+ reader.bufFormat.Write(reader.bufSpaces.Bytes())
reader.valueCommit(false)
_ = reader.br.UnreadByte()
return reader.parseComment()
+
+ default:
+ reader.valueWriteByte(reader.b)
}
- reader.valueWriteByte(reader.b)
}
if quoted {
@@ -659,10 +656,5 @@ func (reader *reader) valueWriteByte(b byte) {
reader.bufSpaces.Reset()
}
- if b == tokPercent {
- reader.bufFormat.Write([]byte{'%', '%'})
- } else {
- reader.bufFormat.WriteByte(b)
- }
reader.buf.WriteByte(b)
}
diff --git a/lib/ini/reader_test.go b/lib/ini/reader_test.go
index 43dc5c21..198a2d49 100644
--- a/lib/ini/reader_test.go
+++ b/lib/ini/reader_test.go
@@ -391,7 +391,7 @@ func TestParseVarValue(t *testing.T) {
desc: `Double quoted with spaces`,
in: []byte(`" "`),
expErr: io.EOF,
- expFormat: `" "`,
+ expFormat: `%s`,
expValue: " ",
}, {
desc: `Double quote at start only`,
@@ -405,78 +405,78 @@ func TestParseVarValue(t *testing.T) {
desc: `Double quoted at start only`,
in: []byte(`"\\" value`),
expErr: io.EOF,
- expFormat: `"\\" value`,
+ expFormat: `%s`,
expValue: `\ value`,
}, {
desc: `Double quoted at end only`,
in: []byte(`value "\""`),
expErr: io.EOF,
- expFormat: `value "\""`,
+ expFormat: `%s`,
expValue: `value "`,
}, {
desc: `Double quoted at start and end`,
in: []byte(`"\\" value "\""`),
expErr: io.EOF,
- expFormat: `"\\" value "\""`,
+ expFormat: `%s`,
expValue: `\ value "`,
}, {
desc: `With comment #`,
in: []byte(`value # comment`),
expErr: io.EOF,
- expFormat: `value %s`,
+ expFormat: `%s %s`,
expValue: "value",
expComment: "# comment",
}, {
desc: `With comment ;`,
in: []byte(`value ; comment`),
expErr: io.EOF,
- expFormat: "value %s",
+ expFormat: "%s %s",
expValue: "value",
expComment: "; comment",
}, {
desc: `With comment # inside double-quote`,
in: []byte(`"value # comment"`),
expErr: io.EOF,
- expFormat: `"value # comment"`,
+ expFormat: `%s`,
expValue: `value # comment`,
}, {
desc: `With comment ; inside double-quote`,
in: []byte(`"value ; comment"`),
expErr: io.EOF,
- expFormat: `"value ; comment"`,
+ expFormat: `%s`,
expValue: `value ; comment`,
}, {
desc: `Double quote and comment #1`,
in: []byte(`val" "#ue`),
expErr: io.EOF,
- expFormat: `val" "%s`,
+ expFormat: `%s%s`,
expValue: `val `,
expComment: `#ue`,
}, {
desc: `Double quote and comment #2`,
in: []byte(`val" " #ue`),
expErr: io.EOF,
- expFormat: `val" " %s`,
+ expFormat: `%s %s`,
expValue: `val `,
expComment: `#ue`,
}, {
desc: `Double quote and comment #3`,
in: []byte(`val " " #ue`),
expErr: io.EOF,
- expFormat: `val " " %s`,
+ expFormat: `%s %s`,
expValue: `val `,
expComment: `#ue`,
}, {
desc: `Escaped chars #1`,
in: []byte(`value \"escaped\" here`),
expErr: io.EOF,
- expFormat: `value \"escaped\" here`,
+ expFormat: `%s`,
expValue: `value "escaped" here`,
}, {
desc: `Escaped chars #2`,
in: []byte(`"value\b\n\t\"escaped\" here"`),
expErr: io.EOF,
- expFormat: `"value\b\n\t\"escaped\" here"`,
+ expFormat: `%s`,
expValue: "value\b\n\t\"escaped\" here",
}, {
desc: `Invalid escaped chars`,
diff --git a/lib/ini/variable.go b/lib/ini/variable.go
index ab85f992..4d49da64 100644
--- a/lib/ini/variable.go
+++ b/lib/ini/variable.go
@@ -64,25 +64,25 @@ func (v *variable) String() string {
}
case lineModeValue:
if len(v.format) > 0 {
- _, _ = fmt.Fprintf(&buf, v.format, v.key)
+ _, _ = fmt.Fprintf(&buf, v.format, v.key, v.value)
} else {
_, _ = fmt.Fprintf(&buf, "%s = %s\n", v.key, v.value)
}
case lineModeValue | lineModeComment:
if len(v.format) > 0 {
- _, _ = fmt.Fprintf(&buf, v.format, v.key, v.others)
+ _, _ = fmt.Fprintf(&buf, v.format, v.key, v.value, v.others)
} else {
_, _ = fmt.Fprintf(&buf, "%s = %s %s\n", v.key, v.value, v.others)
}
case lineModeMulti:
if len(v.format) > 0 {
- _, _ = fmt.Fprintf(&buf, v.format, v.key)
+ _, _ = fmt.Fprintf(&buf, v.format, v.key, v.value)
} else {
_, _ = fmt.Fprintf(&buf, "%s = %s\n", v.key, v.value)
}
case lineModeMulti | lineModeComment:
if len(v.format) > 0 {
- _, _ = fmt.Fprintf(&buf, v.format, v.key, v.others)
+ _, _ = fmt.Fprintf(&buf, v.format, v.key, v.value, v.others)
} else {
_, _ = fmt.Fprintf(&buf, "%s = %s %s\n", v.key, v.value, v.others)
}