Browse Source

do not include files already parsed

fixes #4
pull/16/head
Brett Langdon 11 years ago
parent
commit
ceff779ca4
3 changed files with 42 additions and 4 deletions
  1. +1
    -1
      example/example.cfg
  2. +7
    -3
      forge.go
  3. +34
    -0
      parser.go

+ 1
- 1
example/example.cfg View File

@ -9,7 +9,7 @@ primary {
negative = FALSE;
nothing = NULL;
# Include external files
include "./include*.cfg";
include "./*.cfg";
# Primary-sub stuff
sub {
key = "primary sub key value";


+ 7
- 3
forge.go View File

@ -101,7 +101,6 @@ package forge
import (
"bytes"
"io"
"os"
"strings"
)
@ -116,11 +115,16 @@ func ParseBytes(data []byte) (*Section, error) {
// and responds with `*Section` and potentially an `error` if it cannot
// properly parse the configf
func ParseFile(filename string) (*Section, error) {
reader, err := os.Open(filename)
parser, err := NewFileParser(filename)
if err != nil {
return nil, err
}
return ParseReader(reader)
err = parser.Parse()
if err != nil {
return nil, err
}
return parser.GetSettings(), nil
}
// ParseReader takes an `io.Reader` representation of the config file, parses it


+ 34
- 0
parser.go View File

@ -13,6 +13,7 @@ import (
// Parser is a struct to hold data necessary for parsing a config from a scanner
type Parser struct {
files []string
settings *Section
scanner *Scanner
curTok token.Token
@ -24,6 +25,7 @@ type Parser struct {
func NewParser(reader io.Reader) *Parser {
settings := NewSection()
return &Parser{
files: make([]string, 0),
scanner: NewScanner(reader),
settings: settings,
curSection: settings,
@ -31,6 +33,30 @@ func NewParser(reader io.Reader) *Parser {
}
}
// NewParser will create and initialize a new Parser from a provided from a filename string
func NewFileParser(filename string) (*Parser, error) {
reader, err := os.Open(filename)
if err != nil {
return nil, err
}
parser := NewParser(reader)
parser.addFile(filename)
return parser, nil
}
func (parser *Parser) addFile(filename string) {
parser.files = append(parser.files, filename)
}
func (parser *Parser) hasParsed(search string) bool {
for _, filename := range parser.files {
if filename == search {
return true
}
}
return false
}
func (parser *Parser) syntaxError(msg string) error {
msg = fmt.Sprintf(
"syntax error line <%d> column <%d>: %s",
@ -165,6 +191,11 @@ func (parser *Parser) parseInclude() error {
}
oldScanner := parser.scanner
for _, filename := range filenames {
// We have already visited this file, don't include again
// DEV: This can cause recursive includes if this isn't here :o
if parser.hasParsed(filename) {
continue
}
reader, err := os.Open(filename)
if err != nil {
return err
@ -172,6 +203,9 @@ func (parser *Parser) parseInclude() error {
parser.curSection.AddInclude(filename)
parser.scanner = NewScanner(reader)
parser.parse()
// Make sure to add the filename to the internal list to ensure we don't
// accidentally recursively include config files
parser.addFile(filename)
}
parser.scanner = oldScanner
parser.readToken()


Loading…
Cancel
Save