diff --git a/include/apr_lib.h b/include/apr_lib.h index 9f4cb2b339..cfdd2516b0 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 6c2549f428..b483d309e9 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 5b066ddb43..fe2fc93cf5 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; }