// Parse parses the input just enough to group tokens, in // order, by server block. No further parsing is performed. // Server blocks are returned in the order in which they appear. // Directives that do not appear in validDirectives will cause // an error. If you do not want to check for valid directives, // pass in nil instead. func Parse(filename string, input io.Reader, validDirectives []string) ([]ServerBlock, error) { … } // allTokens lexes the entire input, but does not parse it. // It returns all the tokens from the input, unstructured // and in order. func allTokens(input io.Reader) ([]Token, error) { … } type parser … func (p *parser) parseAll() ([]ServerBlock, error) { … } func (p *parser) parseOne() error { … } func (p *parser) begin() error { … } func (p *parser) addresses() error { … } func (p *parser) blockContents() error { … } // directives parses through all the lines for directives // and it expects the next token to be the first // directive. It goes until EOF or closing curly brace // which ends the server block. func (p *parser) directives() error { … } // doImport swaps out the import directive and its argument // (a total of 2 tokens) with the tokens in the specified file // or globbing pattern. When the function returns, the cursor // is on the token before where the import directive was. In // other words, call Next() to access the first token that was // imported. func (p *parser) doImport() error { … } // doSingleImport lexes the individual file at importFile and returns // its tokens or an error, if any. func (p *parser) doSingleImport(importFile string) ([]Token, error) { … } // directive collects tokens until the directive's scope // closes (either end of line or end of curly brace block). // It expects the currently-loaded token to be a directive // (or } that ends a server block). The collected tokens // are loaded into the current server block for later use // by directive setup functions. func (p *parser) directive() error { … } // openCurlyBrace expects the current token to be an // opening curly brace. This acts like an assertion // because it returns an error if the token is not // a opening curly brace. It does NOT advance the token. func (p *parser) openCurlyBrace() error { … } // closeCurlyBrace expects the current token to be // a closing curly brace. This acts like an assertion // because it returns an error if the token is not // a closing curly brace. It does NOT advance the token. func (p *parser) closeCurlyBrace() error { … } // validDirective returns true if dir is in p.validDirectives. func (p *parser) validDirective(dir string) bool { … } // replaceEnvVars replaces environment variables that appear in the token // and understands both the $UNIX and %WINDOWS% syntaxes. func replaceEnvVars(s string) string { … } // replaceEnvReferences performs the actual replacement of env variables // in s, given the placeholder start and placeholder end strings. func replaceEnvReferences(s, refStart, refEnd string) string { … } type ServerBlock … func (p *parser) isSnippet() (bool, string) { … } // read and store everything in a block for later replay. func (p *parser) snippetTokens() ([]Token, error) { … }