mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
refactor(fstab): Adapt fstab to new style; Adapting the parser
This commit is contained in:
parent
f6b825ebed
commit
1f4717deba
45
server/handlers/fstab/ast/fstab.go
Normal file
45
server/handlers/fstab/ast/fstab.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
commonparser "config-lsp/common/parser"
|
||||||
|
"github.com/emirpasic/gods/maps/treemap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FstabFieldName string
|
||||||
|
|
||||||
|
const (
|
||||||
|
FstabFieldSpec FstabFieldName = "spec"
|
||||||
|
FstabFieldMountPoint FstabFieldName = "mountpoint"
|
||||||
|
FstabFieldFileSystemType FstabFieldName = "filesystemtype"
|
||||||
|
FstabFieldOptions FstabFieldName = "options"
|
||||||
|
FstabFieldFreq FstabFieldName = "freq"
|
||||||
|
FstabFieldPass FstabFieldName = "pass"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FstabField struct {
|
||||||
|
common.LocationRange
|
||||||
|
Value commonparser.ParsedString
|
||||||
|
}
|
||||||
|
|
||||||
|
type FstabFields struct {
|
||||||
|
common.LocationRange
|
||||||
|
Spec *FstabField
|
||||||
|
MountPoint *FstabField
|
||||||
|
FilesystemType *FstabField
|
||||||
|
Options *FstabField
|
||||||
|
Freq *FstabField
|
||||||
|
Pass *FstabField
|
||||||
|
}
|
||||||
|
|
||||||
|
type FstabEntry struct {
|
||||||
|
Fields FstabFields
|
||||||
|
}
|
||||||
|
|
||||||
|
type FstabConfig struct {
|
||||||
|
// [uint32]FstabEntry - line number to line mapping
|
||||||
|
Entries *treemap.Map
|
||||||
|
|
||||||
|
// [uint32]{} - line number to empty struct for comments
|
||||||
|
CommentLines map[uint32]struct{}
|
||||||
|
}
|
159
server/handlers/fstab/ast/parser.go
Normal file
159
server/handlers/fstab/ast/parser.go
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/common"
|
||||||
|
commonparser "config-lsp/common/parser"
|
||||||
|
"config-lsp/utils"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/emirpasic/gods/maps/treemap"
|
||||||
|
|
||||||
|
gods "github.com/emirpasic/gods/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewFstabConfig() *FstabConfig {
|
||||||
|
config := &FstabConfig{}
|
||||||
|
config.Clear()
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FstabConfig) Clear() {
|
||||||
|
c.Entries = treemap.NewWith(gods.UInt32Comparator)
|
||||||
|
c.CommentLines = map[uint32]struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var commentPattern = regexp.MustCompile(`^\s*#`)
|
||||||
|
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
||||||
|
var whitespacePattern = regexp.MustCompile(`\S+`)
|
||||||
|
|
||||||
|
func (c *FstabConfig) Parse(input string) []common.LSPError {
|
||||||
|
errors := make([]common.LSPError, 0)
|
||||||
|
lines := utils.SplitIntoLines(input)
|
||||||
|
|
||||||
|
for rawLineNumber, line := range lines {
|
||||||
|
lineNumber := uint32(rawLineNumber)
|
||||||
|
|
||||||
|
if emptyPattern.MatchString(line) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if commentPattern.MatchString(line) {
|
||||||
|
c.CommentLines[lineNumber] = struct{}{}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
errors = append(
|
||||||
|
errors,
|
||||||
|
c.parseStatement(lineNumber, line)...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FstabConfig) parseStatement(
|
||||||
|
line uint32,
|
||||||
|
input string,
|
||||||
|
) []common.LSPError {
|
||||||
|
fields := whitespacePattern.FindAllStringIndex(input, -1)
|
||||||
|
|
||||||
|
if len(fields) == 0 {
|
||||||
|
return []common.LSPError{
|
||||||
|
{
|
||||||
|
Range: common.LocationRange{
|
||||||
|
Start: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: 0,
|
||||||
|
},
|
||||||
|
End: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var spec *FstabField
|
||||||
|
var mountPoint *FstabField
|
||||||
|
var filesystemType *FstabField
|
||||||
|
var options *FstabField
|
||||||
|
var freq *FstabField
|
||||||
|
var pass *FstabField
|
||||||
|
|
||||||
|
switch len(fields) {
|
||||||
|
case 6:
|
||||||
|
pass = parseField(line, input, fields[5])
|
||||||
|
fallthrough
|
||||||
|
case 5:
|
||||||
|
freq = parseField(line, input, fields[4])
|
||||||
|
fallthrough
|
||||||
|
case 4:
|
||||||
|
options = parseField(line, input, fields[3])
|
||||||
|
fallthrough
|
||||||
|
case 3:
|
||||||
|
filesystemType = parseField(line, input, fields[2])
|
||||||
|
fallthrough
|
||||||
|
case 2:
|
||||||
|
mountPoint = parseField(line, input, fields[1])
|
||||||
|
fallthrough
|
||||||
|
case 1:
|
||||||
|
spec = parseField(line, input, fields[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fstabLine := FstabEntry{
|
||||||
|
Fields: FstabFields{
|
||||||
|
LocationRange: common.LocationRange{
|
||||||
|
Start: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: 0,
|
||||||
|
},
|
||||||
|
End: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: uint32(len(input)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: spec,
|
||||||
|
MountPoint: mountPoint,
|
||||||
|
FilesystemType: filesystemType,
|
||||||
|
Options: options,
|
||||||
|
Freq: freq,
|
||||||
|
Pass: pass,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Entries.Put(line, fstabLine)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseField(
|
||||||
|
line uint32,
|
||||||
|
input string,
|
||||||
|
field []int,
|
||||||
|
) *FstabField {
|
||||||
|
start := uint32(field[0])
|
||||||
|
end := uint32(field[1])
|
||||||
|
value := input[start:end]
|
||||||
|
|
||||||
|
return &FstabField{
|
||||||
|
LocationRange: common.LocationRange{
|
||||||
|
Start: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: start,
|
||||||
|
},
|
||||||
|
End: common.Location{
|
||||||
|
Line: line,
|
||||||
|
Character: end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Value: commonparser.ParseRawString(value, commonparser.ParseFeatures{
|
||||||
|
ParseEscapedCharacters: true,
|
||||||
|
ParseDoubleQuotes: true,
|
||||||
|
Replacements: &map[string]string{
|
||||||
|
`\\040`: " ",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
75
server/handlers/fstab/ast/parser_test.go
Normal file
75
server/handlers/fstab/ast/parser_test.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"config-lsp/utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExample1(
|
||||||
|
t *testing.T,
|
||||||
|
) {
|
||||||
|
input := utils.Dedent(`
|
||||||
|
LABEL=test /mnt/test ext4 defaults 0 0
|
||||||
|
`)
|
||||||
|
c := NewFstabConfig()
|
||||||
|
|
||||||
|
errors := c.Parse(input)
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
t.Fatalf("Expected no errors, got %v", errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Entries.Size() != 1 {
|
||||||
|
t.Fatalf("Expected 1 entry, got %d", c.Entries.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
rawFirstEntry, _ := c.Entries.Get(uint32(0))
|
||||||
|
firstEntry := rawFirstEntry.(FstabEntry)
|
||||||
|
if !(firstEntry.Fields.Spec.Value.Value == "LABEL=test" && firstEntry.Fields.MountPoint.Value.Value == "/mnt/test" && firstEntry.Fields.FilesystemType.Value.Value == "ext4" && firstEntry.Fields.Options.Value.Value == "defaults" && firstEntry.Fields.Freq.Value.Value == "0" && firstEntry.Fields.Pass.Value.Value == "0") {
|
||||||
|
t.Fatalf("Expected entry to be LABEL=test /mnt/test ext4 defaults 0 0, got %v", firstEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Spec.LocationRange.Start.Line == 0 && firstEntry.Fields.Spec.LocationRange.Start.Character == 0) {
|
||||||
|
t.Errorf("Expected spec start to be 0:0, got %v", firstEntry.Fields.Spec.LocationRange.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Spec.LocationRange.End.Line == 0 && firstEntry.Fields.Spec.LocationRange.End.Character == 10) {
|
||||||
|
t.Errorf("Expected spec end to be 0:10, got %v", firstEntry.Fields.Spec.LocationRange.End)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.MountPoint.LocationRange.Start.Line == 0 && firstEntry.Fields.MountPoint.LocationRange.Start.Character == 11) {
|
||||||
|
t.Errorf("Expected mountpoint start to be 0:11, got %v", firstEntry.Fields.MountPoint.LocationRange.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.MountPoint.LocationRange.End.Line == 0 && firstEntry.Fields.MountPoint.LocationRange.End.Character == 20) {
|
||||||
|
t.Errorf("Expected mountpoint end to be 0:20, got %v", firstEntry.Fields.MountPoint.LocationRange.End)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.FilesystemType.LocationRange.Start.Line == 0 && firstEntry.Fields.FilesystemType.LocationRange.Start.Character == 21) {
|
||||||
|
t.Errorf("Expected filesystemtype start to be 0:21, got %v", firstEntry.Fields.FilesystemType.LocationRange.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.FilesystemType.LocationRange.End.Line == 0 && firstEntry.Fields.FilesystemType.LocationRange.End.Character == 25) {
|
||||||
|
t.Errorf("Expected filesystemtype end to be 0:25, got %v", firstEntry.Fields.FilesystemType.LocationRange.End)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Options.LocationRange.Start.Line == 0 && firstEntry.Fields.Options.LocationRange.Start.Character == 26) {
|
||||||
|
t.Errorf("Expected options start to be 0:26, got %v", firstEntry.Fields.Options.LocationRange.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Options.LocationRange.End.Line == 0 && firstEntry.Fields.Options.LocationRange.End.Character == 34) {
|
||||||
|
t.Errorf("Expected options end to be 0:34, got %v", firstEntry.Fields.Options.LocationRange.End)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Freq.LocationRange.Start.Line == 0 && firstEntry.Fields.Freq.LocationRange.Start.Character == 35) {
|
||||||
|
t.Errorf("Expected freq start to be 0:35, got %v", firstEntry.Fields.Freq.LocationRange.Start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Freq.LocationRange.End.Line == 0 && firstEntry.Fields.Freq.LocationRange.End.Character == 36) {
|
||||||
|
t.Errorf("Expected freq end to be 0:36, got %v", firstEntry.Fields.Freq.LocationRange.End)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(firstEntry.Fields.Pass.LocationRange.Start.Line == 0 && firstEntry.Fields.Pass.LocationRange.Start.Character == 37) {
|
||||||
|
t.Errorf("Expected pass start to be 0:37, got %v", firstEntry.Fields.Pass.LocationRange.Start)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user