Skip to content

Commit

Permalink
Added basic include directive.
Browse files Browse the repository at this point in the history
  • Loading branch information
kellegous committed Mar 11, 2014
1 parent fe10c5c commit 4033e3a
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 1 deletion.
104 changes: 104 additions & 0 deletions direct.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package pork

import (
"bufio"
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io"
"os"
"path/filepath"
"strconv"
"strings"
)

// Execute an include directive
func execInclude(base, dir string, args []ast.Expr, w io.Writer) error {
strs := make([]string, len(args))
for i, arg := range args {

bl, ok := arg.(*ast.BasicLit)
if !ok || bl.Kind != token.STRING {
return fmt.Errorf("expected string literal: %s", dir[arg.Pos()-1:arg.End()-1])
}

sv, err := strconv.Unquote(bl.Value)
if err != nil {
return err
}

strs[i] = sv
}

for _, str := range strs {
if err := catFile(w, filepath.Join(base, str)); err != nil {
return err
}
}

return nil
}

// Expand an individual directive into the given writer.
func expandDirective(base, dir string, w io.Writer) error {
e, err := parser.ParseExpr(dir)
if err != nil {
return err
}

c, ok := e.(*ast.CallExpr)
if !ok {
return fmt.Errorf("expected expression: %s", dir)
}

name := dir[c.Fun.Pos()-1 : c.Fun.End()-1]
switch name {
case "include":
return execInclude(base, dir, c.Args, w)
default:
return fmt.Errorf("undefined directive: %s", name)
}
return nil
}

// Expand all source directives into the given writer
func expandDirectives(filename string, w io.Writer) error {
r, err := os.Open(filename)
if err != nil {
return err
}
defer r.Close()

base := filepath.Dir(filename)

br := bufio.NewReader(r)
var buf bytes.Buffer
for {
b, p, err := br.ReadLine()
if err == io.EOF {
return nil
} else if err != nil {
return err
}

buf.Write(b)
if p {
continue
}

l := strings.TrimSpace(buf.String())
buf.Reset()

if len(l) > 0 && !strings.HasPrefix(l, "//") {
return nil
}

if strings.HasPrefix(l, "//@") {
if err := expandDirective(base, strings.TrimSpace(l[3:]), w); err != nil {
return err
}
}
}
}
12 changes: 11 additions & 1 deletion pork.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,24 +553,34 @@ func compile(c *Config, src string, w io.Writer,
cmp func(*Config, string, string) error,
opt func(*Config, io.Writer) (io.WriteCloser, error)) error {

// create an optimization pipe
wo, err := opt(c, w)
if err != nil {
return err
}
defer wo.Close()

// open a temp file for the base compilation
t, err := ioutil.TempFile(os.TempDir(), "cmp-")
if err != nil {
return err
}
defer t.Close()
defer os.Remove(t.Name())

// TODO(knorton): This can be executed in parallel with
// directive expansion. It just needs to return the underlying
// os.Process which allows for Wait.
if err := cmp(c, src, t.Name()); err != nil {
return err
}

// TODO(knorton): Expand directives
// expand source directives
if err := expandDirectives(src, wo); err != nil {
return err
}

// copy the compile output into the writer
return catFile(wo, t.Name())
}

Expand Down

0 comments on commit 4033e3a

Please sign in to comment.