Skip to content

Commit

Permalink
Reduce usage of the fmt package
Browse files Browse the repository at this point in the history
Progress towards capnproto#364.

This gets all of the really "easy" cases in the main and rpc pacakges;
the remainder will require building a couple less trivial helpers.
  • Loading branch information
zenhack committed Dec 31, 2022
1 parent 5a5e462 commit 364e19c
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 26 deletions.
27 changes: 12 additions & 15 deletions address.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package capnp

import (
"fmt"
"strconv"
)

// An address is an index inside a segment's data (in bytes).
// It is bounded to [0, maxSegmentSize).
type address uint32

// String returns the address in hex format.
func (a address) String() string {
return fmt.Sprintf("%#08x", uint64(a))
return strconv.FormatUint(uint64(a), 16)
}

// GoString returns the address in hex format.
func (a address) GoString() string {
return fmt.Sprintf("capnp.address(%#08x)", uint64(a))
return "capnp.address(%" + a.String() + ")"
}

// addSize returns the address a+sz. ok is false if the result would
Expand Down Expand Up @@ -62,12 +58,12 @@ func (sz Size) String() string {
if sz == 1 {
return "1 byte"
}
return fmt.Sprintf("%d bytes", sz)
return fmtUdecimal(sz) + " bytes"
}

// GoString returns the size as a Go expression.
func (sz Size) GoString() string {
return fmt.Sprintf("capnp.Size(%d)", sz)
return "capnp.Size(" + fmtUdecimal(sz) + ")"
}

// times returns the size sz*n. ok is false if the result would be
Expand Down Expand Up @@ -124,12 +120,12 @@ func (off DataOffset) String() string {
if off == 1 {
return "+1 byte"
}
return fmt.Sprintf("+%d bytes", off)
return "+" + fmtUdecimal(off) + " bytes"
}

// GoString returns the offset as a Go expression.
func (off DataOffset) GoString() string {
return fmt.Sprintf("capnp.DataOffset(%d)", off)
return "capnp.DataOffset(" + fmtUdecimal(off) + ")"
}

// ObjectSize records section sizes for a struct or list.
Expand Down Expand Up @@ -181,12 +177,13 @@ func (sz ObjectSize) totalWordCount() int32 {
// String returns a short, human readable representation of the object
// size.
func (sz ObjectSize) String() string {
return fmt.Sprintf("{datasz=%d ptrs=%d}", sz.DataSize, sz.PointerCount)
return "{datasz=" + fmtUdecimal(sz.DataSize) + " ptrs=" + fmtUdecimal(sz.PointerCount) + "}"
}

// GoString formats the ObjectSize as a keyed struct literal.
func (sz ObjectSize) GoString() string {
return fmt.Sprintf("capnp.ObjectSize{DataSize: %d, PointerCount: %d}", sz.DataSize, sz.PointerCount)
return "capnp.ObjectSize{DataSize: " + fmtUdecimal(sz.DataSize) +
", PointerCount: " + fmtUdecimal(sz.PointerCount) + "}"
}

// BitOffset is an offset in bits from the beginning of a struct's data
Expand All @@ -205,10 +202,10 @@ func (bit BitOffset) mask() byte {

// String returns the offset in the format "bit X".
func (bit BitOffset) String() string {
return fmt.Sprintf("bit %d", bit)
return "bit " + fmtUdecimal(bit)
}

// GoString returns the offset as a Go expression.
func (bit BitOffset) GoString() string {
return fmt.Sprintf("capnp.BitOffset(%d)", bit)
return "capnp.BitOffset(" + fmtUdecimal(bit) + ")"
}
3 changes: 1 addition & 2 deletions answer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package capnp

import (
"context"
"fmt"
"strconv"
"sync"

Expand Down Expand Up @@ -206,7 +205,7 @@ func (p *Promise) requireUnresolved(callerMethod string) {
if p.err == nil {
prevMethod = "Fulfill"
} else {
prevMethod = fmt.Sprintf("Reject (error = %q)", p.err)
prevMethod = "Reject (error = " + strconv.Quote(p.err.Error()) + ")"
}

panic("Promise." + callerMethod +
Expand Down
9 changes: 5 additions & 4 deletions capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ type CapabilityID uint32

// String returns the ID in the format "capability X".
func (id CapabilityID) String() string {
return fmt.Sprintf("capability %d", id)
return "capability " + fmtUdecimal(id)
}

// GoString returns the ID as a Go expression.
func (id CapabilityID) GoString() string {
return fmt.Sprintf("capnp.CapabilityID(%d)", id)
return "capnp.CapabilityID(" + fmtUdecimal(id) + ")"
}

// A Client is a reference to a Cap'n Proto capability.
Expand Down Expand Up @@ -652,9 +652,10 @@ func finalizeClient(c *client) {
}
var msg string
if c.creatorFile == "" {
msg = fmt.Sprintf("leaked client created by %s", fname)
msg = "leaked client created by " + fname
} else {
msg = fmt.Sprintf("leaked client created by %s on %s:%d", fname, c.creatorFile, c.creatorLine)
msg = "leaked client created by " + fname + " on " +
c.creatorFile + ":" + fmtIdecimal(c.creatorLine)
}
if c.creatorStack != "" {
msg += "\nCreation stack trace:\n" + c.creatorStack + "\n"
Expand Down
28 changes: 28 additions & 0 deletions fmt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package capnp

// Helpers for formatting strings. We avoid the use of the fmt package for the benefit
// of environments that care about minimizing executable size.

import "strconv"

// An address is an index inside a segment's data (in bytes).
// It is bounded to [0, maxSegmentSize).
type address uint32

// fmtUdecimal is a helper for formatting unsigned integers as decimals.
func fmtUdecimal[T isUint](n T) string {
return strconv.FormatUint(uint64(n), 10)
}

// Like fmtIdecimal, but for signed integers.
func fmtIdecimal[T isInt](n T) string {
return strconv.FormatInt(int64(n), 10)
}

type isUint interface {
~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint
}

type isInt interface {
~int8 | ~int16 | ~int32 | ~int64 | ~int
}
4 changes: 2 additions & 2 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ func (ssa *SingleSegmentArena) Allocate(sz Size, segs map[SegmentID]*Segment) (S
}

func (ssa SingleSegmentArena) String() string {
return fmt.Sprintf("single-segment arena [len=%d cap=%d]", len(ssa), cap(ssa))
return "single-segment arena [len=" + fmtIdecimal(len(ssa)) + " cap=" + fmtIdecimal(cap(ssa)) + "]"
}

type roSingleSegment []byte
Expand Down Expand Up @@ -586,7 +586,7 @@ func (msa *MultiSegmentArena) Allocate(sz Size, segs map[SegmentID]*Segment) (Se
}

func (msa *MultiSegmentArena) String() string {
return fmt.Sprintf("multi-segment arena [%d segments]", len(*msa))
return "multi-segment arena [" + fmtIdecimal(len(*msa)) + " segments]"
}

// nextAlloc computes how much more space to allocate given the number
Expand Down
6 changes: 3 additions & 3 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ func (c *Conn) receive() error {
}

default:
c.er.ReportError(fmt.Errorf("unknown message type %v from remote", recv.Which()))
c.er.ReportError(errors.New("unknown message type " + recv.Which().String() + " from remote"))
c.withLocked(func(c *lockedConn) {
c.sendMessage(ctx, func(m rpccp.Message) error {
defer release()
Expand Down Expand Up @@ -744,7 +744,7 @@ func (c *Conn) handleCall(ctx context.Context, call rpccp.Call, releaseCall capn
// TODO(3rd-party handshake): support sending results to 3rd party vat
if call.SendResultsTo().Which() != rpccp.Call_sendResultsTo_Which_caller {
// TODO(someday): handle SendResultsTo.yourself
c.er.ReportError(fmt.Errorf("incoming call: results destination is not caller"))
c.er.ReportError(errors.New("incoming call: results destination is not caller"))

c.withLocked(func(c *lockedConn) {
c.sendMessage(ctx, func(m rpccp.Message) error {
Expand Down Expand Up @@ -1513,7 +1513,7 @@ func (c *Conn) handleDisembargo(ctx context.Context, d rpccp.Disembargo, release
})

default:
c.er.ReportError(fmt.Errorf("incoming disembargo: context %v not implemented", d.Context().Which()))
c.er.ReportError(errors.New("incoming disembargo: context " + d.Context().Which().String() + " not implemented"))
c.withLocked(func(c *lockedConn) {
c.sendMessage(ctx, func(m rpccp.Message) (err error) {
if m, err = m.NewUnimplemented(); err == nil {
Expand Down

0 comments on commit 364e19c

Please sign in to comment.