mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 14:13:48 +03:00
Clean up Dispenser and filename handling a bit
This commit is contained in:
parent
59910923d1
commit
8420a2f250
5 changed files with 33 additions and 47 deletions
|
@ -24,19 +24,16 @@ import (
|
||||||
// except that it can do so with some notion of structure. An empty
|
// except that it can do so with some notion of structure. An empty
|
||||||
// Dispenser is invalid; call NewDispenser to make a proper instance.
|
// Dispenser is invalid; call NewDispenser to make a proper instance.
|
||||||
type Dispenser struct {
|
type Dispenser struct {
|
||||||
filename string
|
tokens []Token
|
||||||
tokens []Token
|
cursor int
|
||||||
cursor int
|
nesting int
|
||||||
nesting int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDispenser returns a Dispenser filled with the given tokens.
|
// NewDispenser returns a Dispenser filled with the given tokens.
|
||||||
// TODO: Get rid of the filename argument; it seems pointless here
|
func NewDispenser(tokens []Token) *Dispenser {
|
||||||
func NewDispenser(filename string, tokens []Token) *Dispenser {
|
|
||||||
return &Dispenser{
|
return &Dispenser{
|
||||||
filename: filename,
|
tokens: tokens,
|
||||||
tokens: tokens,
|
cursor: -1,
|
||||||
cursor: -1,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +167,8 @@ func (d *Dispenser) Val() string {
|
||||||
return d.tokens[d.cursor].Text
|
return d.tokens[d.cursor].Text
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line gets the line number of the current token. If there is no token
|
// Line gets the line number of the current token.
|
||||||
// loaded, it returns 0.
|
// If there is no token loaded, it returns 0.
|
||||||
func (d *Dispenser) Line() int {
|
func (d *Dispenser) Line() int {
|
||||||
if d.cursor < 0 || d.cursor >= len(d.tokens) {
|
if d.cursor < 0 || d.cursor >= len(d.tokens) {
|
||||||
return 0
|
return 0
|
||||||
|
@ -179,16 +176,12 @@ func (d *Dispenser) Line() int {
|
||||||
return d.tokens[d.cursor].Line
|
return d.tokens[d.cursor].Line
|
||||||
}
|
}
|
||||||
|
|
||||||
// File gets the filename of the current token. If there is no token loaded,
|
// File gets the filename where the current token originated.
|
||||||
// it returns the filename originally given when parsing started.
|
|
||||||
func (d *Dispenser) File() string {
|
func (d *Dispenser) File() string {
|
||||||
if d.cursor < 0 || d.cursor >= len(d.tokens) {
|
if d.cursor < 0 || d.cursor >= len(d.tokens) {
|
||||||
return d.filename
|
return ""
|
||||||
}
|
}
|
||||||
if tokenFilename := d.tokens[d.cursor].File; tokenFilename != "" {
|
return d.tokens[d.cursor].File
|
||||||
return tokenFilename
|
|
||||||
}
|
|
||||||
return d.filename
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Args is a convenience function that loads the next arguments
|
// Args is a convenience function that loads the next arguments
|
||||||
|
@ -240,28 +233,22 @@ func (d *Dispenser) NewFromNextTokens() *Dispenser {
|
||||||
} else {
|
} else {
|
||||||
d.cursor--
|
d.cursor--
|
||||||
}
|
}
|
||||||
return NewDispenser(d.filename, tkns)
|
return NewDispenser(tkns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token returns the current token.
|
// Token returns the current token.
|
||||||
func (d *Dispenser) Token() Token {
|
func (d *Dispenser) Token() Token {
|
||||||
return d.TokenAt(d.cursor)
|
if d.cursor < 0 || d.cursor >= len(d.tokens) {
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Dispenser) TokenAt(cursor int) Token {
|
|
||||||
if cursor < 0 || cursor >= len(d.tokens) {
|
|
||||||
return Token{}
|
return Token{}
|
||||||
}
|
}
|
||||||
return d.tokens[cursor]
|
return d.tokens[d.cursor]
|
||||||
}
|
|
||||||
|
|
||||||
// Cursor returns the current cursor (token index).
|
|
||||||
func (d *Dispenser) Cursor() int {
|
|
||||||
return d.cursor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset sets d's cursor to the beginning, as
|
||||||
|
// if this was a new and unused dispenser.
|
||||||
func (d *Dispenser) Reset() {
|
func (d *Dispenser) Reset() {
|
||||||
d.cursor = -1
|
d.cursor = -1
|
||||||
|
d.nesting = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArgErr returns an argument error, meaning that another
|
// ArgErr returns an argument error, meaning that another
|
||||||
|
|
|
@ -308,9 +308,9 @@ func TestDispenser_ArgErr_Err(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestDispenser(input string) *Dispenser {
|
func newTestDispenser(input string) *Dispenser {
|
||||||
tokens, err := allTokens(strings.NewReader(input))
|
tokens, err := allTokens("Testfile", strings.NewReader(input))
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
log.Fatalf("getting all tokens from input: %v", err)
|
log.Fatalf("getting all tokens from input: %v", err)
|
||||||
}
|
}
|
||||||
return NewDispenser("Testfile", tokens)
|
return NewDispenser(tokens)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,18 @@ import (
|
||||||
// an error. If you do not want to check for valid directives,
|
// an error. If you do not want to check for valid directives,
|
||||||
// pass in nil instead.
|
// pass in nil instead.
|
||||||
func Parse(filename string, input io.Reader) ([]ServerBlock, error) {
|
func Parse(filename string, input io.Reader) ([]ServerBlock, error) {
|
||||||
tokens, err := allTokens(input)
|
tokens, err := allTokens(filename, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p := parser{Dispenser: NewDispenser(filename, tokens)}
|
p := parser{Dispenser: NewDispenser(tokens)}
|
||||||
return p.parseAll()
|
return p.parseAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// allTokens lexes the entire input, but does not parse it.
|
// allTokens lexes the entire input, but does not parse it.
|
||||||
// It returns all the tokens from the input, unstructured
|
// It returns all the tokens from the input, unstructured
|
||||||
// and in order.
|
// and in order.
|
||||||
func allTokens(input io.Reader) ([]Token, error) {
|
func allTokens(filename string, input io.Reader) ([]Token, error) {
|
||||||
l := new(lexer)
|
l := new(lexer)
|
||||||
err := l.load(input)
|
err := l.load(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -48,6 +48,7 @@ func allTokens(input io.Reader) ([]Token, error) {
|
||||||
}
|
}
|
||||||
var tokens []Token
|
var tokens []Token
|
||||||
for l.next() {
|
for l.next() {
|
||||||
|
l.token.File = filename
|
||||||
tokens = append(tokens, l.token)
|
tokens = append(tokens, l.token)
|
||||||
}
|
}
|
||||||
return tokens, nil
|
return tokens, nil
|
||||||
|
@ -265,7 +266,7 @@ func (p *parser) doImport() error {
|
||||||
// list of matching filenames
|
// list of matching filenames
|
||||||
absFile, err := filepath.Abs(p.Dispenser.File())
|
absFile, err := filepath.Abs(p.Dispenser.File())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.filename, err)
|
return p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.File(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches []string
|
var matches []string
|
||||||
|
@ -327,7 +328,7 @@ func (p *parser) doSingleImport(importFile string) ([]Token, error) {
|
||||||
return nil, p.Errf("Could not import %s: is a directory", importFile)
|
return nil, p.Errf("Could not import %s: is a directory", importFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
importedTokens, err := allTokens(file)
|
importedTokens, err := allTokens(importFile, file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, p.Errf("Could not read tokens while importing %s: %v", importFile, err)
|
return nil, p.Errf("Could not read tokens while importing %s: %v", importFile, err)
|
||||||
}
|
}
|
||||||
|
@ -336,7 +337,7 @@ func (p *parser) doSingleImport(importFile string) ([]Token, error) {
|
||||||
// (we use full, absolute path to avoid bugs: issue #1892)
|
// (we use full, absolute path to avoid bugs: issue #1892)
|
||||||
filename, err := filepath.Abs(importFile)
|
filename, err := filepath.Abs(importFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, p.Errf("Failed to get absolute path of file: %s: %v", p.Dispenser.filename, err)
|
return nil, p.Errf("Failed to get absolute path of file: %s: %v", importFile, err)
|
||||||
}
|
}
|
||||||
for i := 0; i < len(importedTokens); i++ {
|
for i := 0; i < len(importedTokens); i++ {
|
||||||
importedTokens[i].File = filename
|
importedTokens[i].File = filename
|
||||||
|
@ -497,7 +498,7 @@ func (sb ServerBlock) DispenseDirective(dir string) *Dispenser {
|
||||||
tokens = append(tokens, seg...)
|
tokens = append(tokens, seg...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NewDispenser("", tokens)
|
return NewDispenser(tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Segment is a list of tokens which begins with a directive
|
// Segment is a list of tokens which begins with a directive
|
||||||
|
@ -513,9 +514,3 @@ func (s Segment) Directive() string {
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDispenser returns a dispenser for this
|
|
||||||
// segment's tokens.
|
|
||||||
func (s Segment) NewDispenser() *Dispenser {
|
|
||||||
return NewDispenser("", s)
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
func TestAllTokens(t *testing.T) {
|
func TestAllTokens(t *testing.T) {
|
||||||
input := strings.NewReader("a b c\nd e")
|
input := strings.NewReader("a b c\nd e")
|
||||||
expected := []string{"a", "b", "c", "d", "e"}
|
expected := []string{"a", "b", "c", "d", "e"}
|
||||||
tokens, err := allTokens(input)
|
tokens, err := allTokens("TestAllTokens", input)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Expected no error, got %v", err)
|
t.Fatalf("Expected no error, got %v", err)
|
||||||
|
|
|
@ -38,6 +38,10 @@ func init() {
|
||||||
type ServerType struct {
|
type ServerType struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: customize directive ordering
|
||||||
|
|
||||||
|
// TODO: hide caddyfile when serving static files
|
||||||
|
|
||||||
// Setup makes a config from the tokens.
|
// Setup makes a config from the tokens.
|
||||||
func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
|
func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
|
||||||
options map[string]string) (*caddy.Config, []caddyconfig.Warning, error) {
|
options map[string]string) (*caddy.Config, []caddyconfig.Warning, error) {
|
||||||
|
@ -88,7 +92,7 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
|
||||||
}
|
}
|
||||||
if dirFunc, ok := registeredDirectives[dir]; ok {
|
if dirFunc, ok := registeredDirectives[dir]; ok {
|
||||||
results, err := dirFunc(Helper{
|
results, err := dirFunc(Helper{
|
||||||
Dispenser: segment.NewDispenser(),
|
Dispenser: caddyfile.NewDispenser(segment),
|
||||||
warnings: &warnings,
|
warnings: &warnings,
|
||||||
matcherDefs: matcherDefs,
|
matcherDefs: matcherDefs,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue