Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp1872090rwb; Sun, 14 Aug 2022 14:53:37 -0700 (PDT) X-Google-Smtp-Source: AA6agR65OM8yUFnITIm9Dm2o/dI1YHvC7HMIZMG9xZXTBTF490f1+Xp7XkPqERSXndfz2qPVutBW X-Received: by 2002:a17:907:7290:b0:731:3c0a:97f8 with SMTP id dt16-20020a170907729000b007313c0a97f8mr8660429ejc.127.1660514017182; Sun, 14 Aug 2022 14:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660514017; cv=none; d=google.com; s=arc-20160816; b=ESHtqV//+PTlPLLS1PCfT1qIaTRhdj6r2iQvteNYNb07gshDcoHAuG4tklayugJxZe mtIMTWJacOx7UcbBqPDYHNMZ2gJckjblQoRlaX3CpZs3LFbUWlijsQ/dwP/My/hpxXGF aJO6y5lMt1qOM+VO/SjbSQyMP0lbsbtDFJWYhT/XWHlzgUJA4QUbDLyURrSCwHYi6OBR T8Gtw+getkW4pcCHH66dGuokOjHkri/nmV1BxH6PaY7YG19r2ZQg2TiRs5/WfUNQrW2R rfBzuoW2ehbDohjXC1Ue6vKNs8t3NRtVD91qMweFcThU3/33t4ufpmZBRgIVVSqQjWns yu5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Vj+dUILWbh28JfOZyUO57tkh5j92cz8PsOwdjIDTAsg=; b=n/3YxY5BE6i4KajNmytnWH+r6s9bDkf2gWGTRWxoTfh0WlhmsloJpikscNZgltpuTc p7UqWOO9WQ+r69q1CzVUf4TFWADMFQC7nTTOaJQ4YK9ExvndKQYyYAFTursIkEuQd71n /BdwTqmAX98W8qPtx4FOLHk71E9VsY7dVqy6acK7S/Kqh+9l/+WfdQFz1DxxXY0hh9uw mRv0PdQmCY4gxOK3c1QVCcqk+6r0jQXEoxhm3xcEN340sFbsiLJQl3RtIMraiPgHT+We mOY0i7ExX/Pn2x7hHTgfGZ5DExYRwqiMTBhQcLeaPcph/tKPIDsBaia8mVqkbor1FnKg oLbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=Qq2U7DnR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w20-20020a1709060a1400b007315c977bb0si5770949ejf.214.2022.08.14.14.53.12; Sun, 14 Aug 2022 14:53:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=Qq2U7DnR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240303AbiHNVU7 (ORCPT + 99 others); Sun, 14 Aug 2022 17:20:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239909AbiHNVUm (ORCPT ); Sun, 14 Aug 2022 17:20:42 -0400 Received: from out0.migadu.com (out0.migadu.com [94.23.1.103]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA4CB64FC for ; Sun, 14 Aug 2022 14:20:40 -0700 (PDT) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1660512038; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Vj+dUILWbh28JfOZyUO57tkh5j92cz8PsOwdjIDTAsg=; b=Qq2U7DnRXMEXPLrPHvyIOKzNmansWscUtWGEopV6sq3G8WbSaEE9GhrHRQ4WJB5JOiqZ/b l+mGEKvaVkBhLJ3EGljIhHllnryhy78eJwhhMNDShaBC9u7Z9Tglg1rQDpYh8KjnlLIE9r dhdF2XvwRCAlpNm/7x4tuVMZTx22/7s= From: Kent Overstreet To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org, Kent Overstreet , Matthew Wilcox Subject: [PATCH 01/32] lib/printbuf: New data structure for printing strings Date: Sun, 14 Aug 2022 17:19:40 -0400 Message-Id: <20220814212011.1727798-2-kent.overstreet@linux.dev> In-Reply-To: <20220814212011.1727798-1-kent.overstreet@linux.dev> References: <20220814212011.1727798-1-kent.overstreet@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: linux.dev X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kent Overstreet This adds printbufs: a printbuf points to a char * buffer and knows the size of the output buffer as well as the current output position. Future patches will be adding more features to printbuf, but initially printbufs are targeted at refactoring and improving our existing code in lib/vsprintf.c - so this initial printbuf patch has the features required for that. Signed-off-by: Kent Overstreet Reviewed-by: Matthew Wilcox (Oracle) --- include/linux/printbuf.h | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 include/linux/printbuf.h diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h new file mode 100644 index 0000000000..1aa3331bf0 --- /dev/null +++ b/include/linux/printbuf.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRINTBUF_H +#define _LINUX_PRINTBUF_H + +#include +#include + +/* + * Printbufs: String buffer for outputting (printing) to, for vsnprintf + */ + +struct printbuf { + char *buf; + unsigned size; + unsigned pos; +}; + +/* + * Returns size remaining of output buffer: + */ +static inline unsigned printbuf_remaining_size(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos : 0; +} + +/* + * Returns number of characters we can print to the output buffer - i.e. + * excluding the terminating nul: + */ +static inline unsigned printbuf_remaining(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos - 1 : 0; +} + +static inline unsigned printbuf_written(struct printbuf *out) +{ + return out->size ? min(out->pos, out->size - 1) : 0; +} + +/* + * Returns true if output was truncated: + */ +static inline bool printbuf_overflowed(struct printbuf *out) +{ + return out->pos >= out->size; +} + +static inline void printbuf_nul_terminate(struct printbuf *out) +{ + if (out->pos < out->size) + out->buf[out->pos] = 0; + else if (out->size) + out->buf[out->size - 1] = 0; +} + +static inline void __prt_char(struct printbuf *out, char c) +{ + if (printbuf_remaining(out)) + out->buf[out->pos] = c; + out->pos++; +} + +static inline void prt_char(struct printbuf *out, char c) +{ + __prt_char(out, c); + printbuf_nul_terminate(out); +} + +static inline void __prt_chars(struct printbuf *out, char c, unsigned n) +{ + unsigned i, can_print = min(n, printbuf_remaining(out)); + + for (i = 0; i < can_print; i++) + out->buf[out->pos++] = c; + out->pos += n - can_print; +} + +static inline void prt_chars(struct printbuf *out, char c, unsigned n) +{ + __prt_chars(out, c, n); + printbuf_nul_terminate(out); +} + +static inline void prt_bytes(struct printbuf *out, const void *b, unsigned n) +{ + unsigned i, can_print = min(n, printbuf_remaining(out)); + + for (i = 0; i < can_print; i++) + out->buf[out->pos++] = ((char *) b)[i]; + out->pos += n - can_print; + + printbuf_nul_terminate(out); +} + +static inline void prt_str(struct printbuf *out, const char *str) +{ + prt_bytes(out, str, strlen(str)); +} + +static inline void prt_hex_byte(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_hi(byte)); + __prt_char(out, hex_asc_lo(byte)); + printbuf_nul_terminate(out); +} + +static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_upper_hi(byte)); + __prt_char(out, hex_asc_upper_lo(byte)); + printbuf_nul_terminate(out); +} + +#define PRINTBUF_EXTERN(_buf, _size) \ +((struct printbuf) { \ + .buf = _buf, \ + .size = _size, \ +}) + +#endif /* _LINUX_PRINTBUF_H */ -- 2.36.1