feat: Add Lua cataloger (#2613)

Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
This commit is contained in:
Laurent Goderre
2024-05-24 16:56:34 -04:00
committed by GitHub
parent 77b3f66404
commit b51252dbdb
33 changed files with 4754 additions and 82 deletions
+12 -75
View File
@@ -5,8 +5,8 @@ import (
"errors"
"fmt"
"io"
"strings"
"unicode"
"github.com/anchore/syft/syft/internal/parsing"
)
type erlangNode struct {
@@ -60,14 +60,14 @@ func parseErlang(reader io.Reader) (erlangNode, error) {
for i < len(data) {
item, err := parseErlangBlock(data, &i)
if err == errSkipComments {
skipWhitespace(data, &i)
parsing.SkipWhitespace(data, &i)
continue
}
if err != nil {
return node(nil), fmt.Errorf("%w\n%s", err, printError(data, i))
return node(nil), fmt.Errorf("%w\n%s", err, parsing.PrintError(data, i))
}
skipWhitespace(data, &i)
parsing.SkipWhitespace(data, &i)
if i, ok := item.value.(string); ok && i == "." {
continue
@@ -78,78 +78,24 @@ func parseErlang(reader io.Reader) (erlangNode, error) {
return out, nil
}
func printError(data []byte, i int) string {
line := 1
char := 1
prev := []string{}
curr := bytes.Buffer{}
for idx, c := range data {
if c == '\n' {
prev = append(prev, curr.String())
curr.Reset()
if idx >= i {
break
}
line++
char = 1
continue
}
if idx < i {
char++
}
curr.WriteByte(c)
}
l1 := fmt.Sprintf("%d", line-1)
l2 := fmt.Sprintf("%d", line)
if len(l1) < len(l2) {
l1 = " " + l1
}
sep := ": "
lines := ""
if len(prev) > 1 {
lines += fmt.Sprintf("%s%s%s\n", l1, sep, prev[len(prev)-2])
}
if len(prev) > 0 {
lines += fmt.Sprintf("%s%s%s\n", l2, sep, prev[len(prev)-1])
}
pointer := strings.Repeat(" ", len(l2)+len(sep)+char-1) + "^"
return fmt.Sprintf("line: %v, char: %v\n%s%s", line, char, lines, pointer)
}
func skipWhitespace(data []byte, i *int) {
for *i < len(data) && isWhitespace(data[*i]) {
*i++
}
}
func parseErlangBlock(data []byte, i *int) (erlangNode, error) {
block, err := parseErlangNode(data, i)
if err != nil {
return node(nil), err
}
skipWhitespace(data, i)
parsing.SkipWhitespace(data, i)
*i++ // skip the trailing .
return block, nil
}
func parseErlangNode(data []byte, i *int) (erlangNode, error) {
skipWhitespace(data, i)
parsing.SkipWhitespace(data, i)
c := data[*i]
switch c {
case '[', '{':
offset := *i + 1
skipWhitespace(data, &offset)
parsing.SkipWhitespace(data, &offset)
c2 := data[offset]
// Add support for empty lists
@@ -170,27 +116,18 @@ func parseErlangNode(data []byte, i *int) (erlangNode, error) {
return node(nil), errSkipComments
}
if isLiteral(c) {
if parsing.IsLiteral(c) {
return parseErlangLiteral(data, i)
}
return erlangNode{}, fmt.Errorf("invalid literal character: %s", string(c))
}
func isWhitespace(c byte) bool {
return unicode.IsSpace(rune(c))
}
func isLiteral(c byte) bool {
r := rune(c)
return unicode.IsNumber(r) || unicode.IsLetter(r) || r == '.' || r == '_'
}
func parseErlangLiteral(data []byte, i *int) (erlangNode, error) {
var buf bytes.Buffer
for *i < len(data) {
c := data[*i]
if isLiteral(c) {
if parsing.IsLiteral(c) {
buf.WriteByte(c)
} else {
break
@@ -239,13 +176,13 @@ func parseErlangList(data []byte, i *int) (erlangNode, error) {
item, err := parseErlangNode(data, i)
if err != nil {
if err == errSkipComments {
skipWhitespace(data, i)
parsing.SkipWhitespace(data, i)
continue
}
return node(nil), err
}
out.value = append(out.value.([]erlangNode), item)
skipWhitespace(data, i)
parsing.SkipWhitespace(data, i)
c := data[*i]
switch c {
case ',':