diff --git a/appenders.go b/appenders.go index bad661b..e4b4204 100644 --- a/appenders.go +++ b/appenders.go @@ -1,6 +1,9 @@ package strftime import ( + "bytes" + "fmt" + "io" "strconv" "strings" "time" @@ -61,7 +64,7 @@ type Appender interface { Append([]byte, time.Time) []byte } -// AppendFunc is an utility type to allow users to create a +// AppendFunc is an utility type to allow users to create a // function-only version of an Appender type AppendFunc func([]byte, time.Time) []byte @@ -71,6 +74,27 @@ func (af AppendFunc) Append(b []byte, t time.Time) []byte { type appenderList []Appender +type dumper interface { + dump(io.Writer) +} + +func (l appenderList) dump(out io.Writer) { + var buf bytes.Buffer + ll := len(l) + for i, a := range l { + if dumper, ok := a.(dumper); ok { + dumper.dump(&buf) + } else { + fmt.Fprintf(&buf, "%#v", a) + } + + if i < ll-1 { + fmt.Fprintf(&buf, ",\n") + } + } + buf.WriteTo(out) +} + // does the time.Format thing type stdlibFormat struct { s string @@ -104,6 +128,10 @@ func (v stdlibFormat) combine(w combiner) Appender { return StdlibFormat(v.s + w.str()) } +func (v stdlibFormat) dump(out io.Writer) { + fmt.Fprintf(out, "stdlib: %s", v.s) +} + type verbatimw struct { s string } @@ -135,6 +163,10 @@ func (v verbatimw) str() string { return v.s } +func (v verbatimw) dump(out io.Writer) { + fmt.Fprintf(out, "verbatim: %s", v.s) +} + // These words below, as well as any decimal character var combineExclusion = []string{ "Mon", diff --git a/specifications.go b/specifications.go index e31ef54..9d3f55b 100644 --- a/specifications.go +++ b/specifications.go @@ -72,7 +72,6 @@ func populateDefaultSpecifications(ds SpecificationSet) { ds.Set('a', abbrvWeekDayName) ds.Set('B', fullMonthName) ds.Set('b', abbrvMonthName) - ds.Set('h', abbrvMonthName) ds.Set('C', centuryDecimal) ds.Set('c', timeAndDate) ds.Set('D', mdy) @@ -80,6 +79,7 @@ func populateDefaultSpecifications(ds SpecificationSet) { ds.Set('e', dayOfMonthSpacePad) ds.Set('F', ymd) ds.Set('H', twentyFourHourClockZeroPad) + ds.Set('h', abbrvMonthName) ds.Set('I', twelveHourClockZeroPad) ds.Set('j', dayOfYear) ds.Set('k', twentyFourHourClockSpacePad) diff --git a/strftime.go b/strftime.go index 379767f..81c0d88 100644 --- a/strftime.go +++ b/strftime.go @@ -33,10 +33,11 @@ func (ae *appenderExecutor) handle(a Appender) { } func compile(handler compileHandler, p string, ds SpecificationSet) error { - // This is a really tight loop, so we don't even calls to - // Verbatim() to cuase extra stuff - var verbatim verbatimw for l := len(p); l > 0; l = len(p) { + // This is a really tight loop, so we don't even calls to + // Verbatim() to cuase extra stuff + var verbatim verbatimw + i := strings.IndexByte(p, '%') if i < 0 { verbatim.s = p @@ -182,6 +183,13 @@ func (f *Strftime) Format(dst io.Writer, t time.Time) error { return nil } +// Dump outputs the internal structure of the formatter, for debugging purposes. +// Please do NOT assume the output format to be fixed: it is expected to change +// in the future. +func (f *Strftime) Dump(out io.Writer) { + f.compiled.dump(out) +} + func (f *Strftime) format(b []byte, t time.Time) []byte { for _, w := range f.compiled { b = w.Append(b, t) diff --git a/strftime_test.go b/strftime_test.go index 2f9ed52..2def373 100644 --- a/strftime_test.go +++ b/strftime_test.go @@ -1,8 +1,10 @@ package strftime_test import ( + "bytes" "fmt" "os" + "strings" "testing" "time" @@ -213,3 +215,15 @@ func Example_CustomSpecifications() { // Daisuke Maki // Daisuke Maki } + +func TestGHIssue9(t *testing.T) { + pattern, _ := strftime.New("/longer/path/to/see/where/this/leads//test99%Y%m%d.log") + + var buf bytes.Buffer + pattern.Format(&buf, time.Now()) + + if !assert.True(t, strings.Contains(buf.String(), "/")) { + t.Logf("---> %s", buf.String()) + return + } +}