prometheus/config/load.go
Julius Volz cb6eb30182 Fix state cleanup bug between rule/config parser runs.
This fixes a bug that has been annoying me minorly for some time now:
sometimes, after parse errors, a subsequent parser run would fail.  The reason
is that yylex() modifies some global variables (yytext, yydata) during its run
to keep state. To make subsequent parser runs correct, these have to be reset
before each run.

Also, close files after reading them.
2013-01-12 02:35:40 +01:00

65 lines
1.6 KiB
Go

package config
import (
"errors"
"fmt"
"io"
"os"
"strings"
)
// NOTE: This parser is non-reentrant due to its dependence on global state.
// GoLex sadly needs these global variables for storing temporary token/parsing information.
var yylval *yySymType // For storing extra token information, like the contents of a string.
var yyline int // Line number within the current file or buffer.
var yypos int // Character position within the current line.
var parsedConfig = New() // Temporary variable for storing the parsed configuration.
type ConfigLexer struct {
errors []string
}
func (lexer *ConfigLexer) Lex(lval *yySymType) int {
yylval = lval
token_type := yylex()
return token_type
}
func (lexer *ConfigLexer) Error(errorStr string) {
err := fmt.Sprintf("Error reading config at line %v, char %v: %v", yyline, yypos, errorStr)
lexer.errors = append(lexer.errors, err)
}
func LoadFromReader(configReader io.Reader) (*Config, error) {
yyin = configReader
yypos = 1
yyline = 1
yydata = ""
yytext = ""
lexer := &ConfigLexer{}
yyParse(lexer)
if len(lexer.errors) > 0 {
err := errors.New(strings.Join(lexer.errors, "\n"))
return &Config{}, err
}
return parsedConfig, nil
}
func LoadFromString(configString string) (*Config, error) {
configReader := strings.NewReader(configString)
return LoadFromReader(configReader)
}
func LoadFromFile(fileName string) (*Config, error) {
configReader, err := os.Open(fileName)
defer configReader.Close()
if err != nil {
return &Config{}, err
}
return LoadFromReader(configReader)
}