mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +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