use fmt; use io; use memio; use strings; use trace; type Tracer = struct { trace::tracer, }; fn newtracer() Tracer = Tracer { log = &tracer_log, }; fn tracer_log( tr: *trace::tracer, ctx: nullable *trace::context, lvl: trace::level, fmt: str, fields: fmt::field... ) void = { // XXX: ideally there would be a statically allocated buffer for // reasonably short messages and allocation would only happen for // messages longer than that. ideally ideally there would be locking so // we wouldn't need to allocate at all. const buf = memio::dynamic_from(alloc([], 256)); defer io::close(&buf)!; let ctx_ = ctx; for (true) match (ctx_) { case let ctx__: *trace::context => fmt::fprintf(&buf, ctx__.fmt, ctx__.fields...)!; io::write(&buf, [0x3a, 0x20])!; // ": " ctx_ = ctx__.next; case null => break; }; fmt::fprintfln(&buf, fmt, fields...)!; const prio = 6 - lvl: int; androlog(prio, memio::string(&buf)!); };