func (w *Writer) init(rootDir, name, dst string) error { var err error w.name = path2.RemoveExt(name) w.base = filepath.Base(w.name) outName := dst if outName == "" { outName := w.name + ".go" if outName == name { return ErrGoFileNotAllowed } } w.pkg, err = path2.LastDir(outName) if err != nil { return err } if w.pkg == "" { return ErrNoPackage } w.name = strings.TrimPrefix(w.name, rootDir) if len(w.name) > 0 && w.name[0] == '/' || w.name[0] == '\\' { w.name = w.name[1:] } if len(w.name) == 0 { return fmt.Errorf("invalid template name after trim root dir: %s:%s", name, rootDir) } fd, err := os.OpenFile(outName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } w.fd = fd w.buffer = bytes2.MakeBuffer(0, 1024) w.topBuffer = bytes2.MakeBuffer(0, 256) w.dst = io2.NewErrorWriter(w.buffer) return nil }
func TestRenderTo(t *testing.T) { buf := bytes2.MakeBuffer(0, 128) LightRed.RenderTo(buf, "aaaaaaaaaaaaa\n") LightRed.RenderTo(buf, "bbbbb\n") }
func Parse(r io.Reader, w Writer) error { br := io2.BufReader(r) rawBuff := bytes2.MakeBuffer(0, 1024) evalBuff := bytes2.MakeBuffer(0, 64) blockBuff := bytes2.MakeBuffer(0, 248) topBuff := bytes2.MakeBuffer(0, 64) inclNameBuff := bytes2.MakeBuffer(0, 8) inclDataBuff := bytes2.MakeBuffer(0, 8) stat := STAT_RAW line := 1 row := 1 for { r, _, err := br.ReadRune() if err == io.EOF { break } if err != nil { return err } switch stat { case STAT_RAW: if r == '{' { stat = STAT_PREFIX err = writeReset(w.WriteRaw, rawBuff) if err != nil { return err } } else { rawBuff.WriteRune(r) } case STAT_PREFIX: if r == '=' { stat = STAT_EVAL } else if r == '%' { stat = STAT_BLOCK } else if r == '^' { stat = STAT_TOP } else if r == '+' { stat = STAT_INCLUDE } else { return errors.Newf("unexpected character %c at %d:%d, expect '%' or '='", r, line, row) } case STAT_INCLUDE: if r == ' ' { } else if r == '"' { stat = STAT_INCLUDE_NAME } else { return errors.Newf(`unexpected character %c at %d:%d, expect '"'`, r, line, row) } case STAT_INCLUDE_NAME: if r == '"' { stat = STAT_INCLUDE_DATA } else { _, err = inclNameBuff.WriteRune(r) if err != nil { return err } } case STAT_INCLUDE_DATA: if r == '+' { matched, err := expect(br, '}') if err != nil { return err } if !matched { return errors.Newf("unexpected character at %d:%d, expect '}'", line, row) } err = w.WriteInclude(inclNameBuff.Bytes(), inclDataBuff.Bytes()) if err != nil { return err } inclNameBuff.Reset() inclDataBuff.Reset() stat = STAT_RAW } else { _, err = inclDataBuff.WriteRune(r) if err != nil { return err } } default: p := w.WriteEval b := evalBuff er := '=' if stat == STAT_BLOCK { p = w.WriteBlock b = blockBuff er = '%' } else if stat == STAT_TOP { p = w.WriteTop b = topBuff er = '^' } if r == er { matched, err := expect(br, '}') if err != nil { return err } if !matched { return errors.Newf("unexpected character at %d:%d, expect '}'", line, row) } err = writeReset(p, b) if err != nil { return err } stat = STAT_RAW } else { b.WriteRune(r) } } if r == '\n' { line += 1 row = 1 } else { row += 1 } } if stat != STAT_RAW { return errors.Newf("unexpected eof") } return writeReset(w.WriteRaw, rawBuff) }
// {Model} -> tablename // {Model:Field, Field} fieldname, fieldname // {Model.Field, Field} tablename.fieldname, tablename.fieldnam func (v Visitor) conv(sql string) (s string, err error) { const ( INIT = iota PARSING_MODEL PARSING_FIELD ) state := INIT sqlbuf := bytes2.MakeBuffer(0, len(sql)) modelbuf := bytes2.MakeBuffer(0, 8) fieldbuf := bytes2.MakeBuffer(0, 8) var table *Table var withModel bool for i := range sql { c := sql[i] switch state { case INIT: if c == '{' { state = PARSING_MODEL withModel = false modelbuf.Reset() fieldbuf.Reset() } else { sqlbuf.WriteByte(c) } case PARSING_MODEL: switch c { case '}': if err = v.writeModel(sqlbuf, modelbuf); err != nil { return } state = INIT case '.': withModel = true fallthrough case ':': if err = v.modelTable(modelbuf, &table); err != nil { return } state = PARSING_FIELD default: modelbuf.WriteByte(c) } case PARSING_FIELD: if c == ',' || c == '}' { if err = v.writeField(table, withModel, sqlbuf, modelbuf, fieldbuf); err != nil { return } fieldbuf.Reset() if c == '}' { state = INIT } else { sqlbuf.WriteByte(c) } } else if c == ' ' { sqlbuf.WriteByte(c) } else { fieldbuf.WriteByte(c) } } } return sqlbuf.String(), nil }