From 0f280de9e63e0ba71dd826b0e62b65e5a94df6d5 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Thu, 27 Mar 2025 14:10:05 +0000 Subject: [PATCH] Add %pg printf format string converter to print a pool tag: * strings/apr_snprintf.c (apr_vformatter): Add %pg support. * test/testfmt.c (test_tag_fmt): New test case. --- include/apr_lib.h | 3 +++ strings/apr_snprintf.c | 19 +++++++++++++++++++ test/testfmt.c | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/apr_lib.h b/include/apr_lib.h index 9f4cb2b3397..cfdd2516b01 100644 --- a/include/apr_lib.h +++ b/include/apr_lib.h @@ -120,6 +120,8 @@ APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname); * ('0' is printed if !APR_HAS_THREADS) * - %%pm takes an apr_status_t * and prints the appropriate error * string (from apr_strerror) corresponding to that error code. + * - %%pg takes an apr_pool_t * and prints the pool tag, + * or '(untagged)' if no pool tag is set * - %%pp takes a void * and outputs it in hex * - %%pB takes a apr_uint32_t * as bytes and outputs it's apr_strfsize * - %%pF same as above, but takes a apr_off_t * @@ -128,6 +130,7 @@ APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname); * %%pA, %%pI, %%pT, %%pp are available from APR 1.0.0 onwards (and in 0.9.x). * %%pt is only available from APR 1.2.0 onwards. * %%pm, %%pB, %%pF and %%pS are only available from APR 1.3.0 onwards. + * %%pg is only available from APR 2.0.0 onwards. * * The %%p hacks are to force gcc's printf warning code to skip * over a pointer argument without complaining. This does diff --git a/strings/apr_snprintf.c b/strings/apr_snprintf.c index 6c2549f4289..b483d309e9b 100644 --- a/strings/apr_snprintf.c +++ b/strings/apr_snprintf.c @@ -1191,6 +1191,25 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), } break; + /* print the tag for an apr_pool_t */ + case 'g': + { + apr_pool_t *prv; + + prv = va_arg(ap, apr_pool_t *); + if (prv != NULL) { + s = (char *)apr_pool_get_tag(prv); + if (!s) s = "(untagged)"; + s_len = strlen(s); + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; + case 'T': #if APR_HAS_THREADS { diff --git a/test/testfmt.c b/test/testfmt.c index 5b066ddb439..fe2fc93cf51 100644 --- a/test/testfmt.c +++ b/test/testfmt.c @@ -146,6 +146,27 @@ static void error_fmt(abts_case *tc, void *data) ABTS_STR_EQUAL(tc, sbuf, s); } +#define TEST_TAG "pool_tag_fmt_tag" + +static void pool_tag_fmt(abts_case *tc, void *data) +{ + char sbuf[150]; + apr_pool_t *testp; + + APR_ASSERT_SUCCESS(tc, "Create test pool", apr_pool_create(&testp, NULL)); + +#if !APR_POOL_DEBUG + apr_snprintf(sbuf, sizeof sbuf, "tag-%pg-end", testp); + ABTS_STR_EQUAL(tc, "tag-(untagged)-end", sbuf); +#endif + + apr_pool_tag(testp, TEST_TAG); + apr_snprintf(sbuf, sizeof sbuf, "tag-%pg-end", testp); + ABTS_STR_EQUAL(tc, "tag-" TEST_TAG "-end", sbuf); + + apr_pool_destroy(testp); +} + abts_suite *testfmt(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -160,6 +181,7 @@ abts_suite *testfmt(abts_suite *suite) abts_run_test(suite, uint64_t_hex_fmt, NULL); abts_run_test(suite, more_int64_fmts, NULL); abts_run_test(suite, error_fmt, NULL); + abts_run_test(suite, pool_tag_fmt, NULL); return suite; }