diff options
| author | Pierre Pronchery <khorben@FreeBSD.org> | 2026-06-24 19:47:19 +0000 |
|---|---|---|
| committer | Pierre Pronchery <khorben@FreeBSD.org> | 2026-06-29 05:21:29 +0000 |
| commit | ebcc78644e0cbc4141807c0887ef8d902cb91bb4 (patch) | |
| tree | da5efe7c3c9ae0f140e24a1b69833a476fb09f01 /libpkgconf/output.c | |
| parent | 6294b6ab217a2d5f1d2bc23a64505a228294c508 (diff) | |
Diffstat (limited to 'libpkgconf/output.c')
| -rw-r--r-- | libpkgconf/output.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/libpkgconf/output.c b/libpkgconf/output.c new file mode 100644 index 000000000000..fc7ab85ea2e1 --- /dev/null +++ b/libpkgconf/output.c @@ -0,0 +1,153 @@ +/* + * output.c + * I/O abstraction layer + * + * SPDX-License-Identifier: pkgconf + * + * Copyright (c) 2025 pkgconf authors (see AUTHORS). + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include <libpkgconf/stdinc.h> +#include <libpkgconf/libpkgconf.h> + +bool +pkgconf_output_putbuf(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer, bool newline) +{ + bool ret; + pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER; + + if (pkgconf_buffer_len(buffer) != 0) + pkgconf_buffer_append(&buf, pkgconf_buffer_str(buffer)); + + if (newline) + pkgconf_buffer_push_byte(&buf, '\n'); + + ret = output->write(output, stream, &buf); + pkgconf_buffer_finalize(&buf); + + return ret; +} + +bool +pkgconf_output_puts(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *str) +{ + bool ret; + pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER; + + pkgconf_buffer_append(&buf, str); + pkgconf_buffer_push_byte(&buf, '\n'); + ret = output->write(output, stream, &buf); + pkgconf_buffer_finalize(&buf); + + return ret; +} + +bool +pkgconf_output_fmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, ...) +{ + bool ret; + va_list va; + + va_start(va, fmt); + ret = pkgconf_output_vfmt(output, stream, fmt, va); + va_end(va); + + return ret; +} + +bool +pkgconf_output_vfmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, va_list src_va) +{ + va_list va; + bool ret; + pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER; + + va_copy(va, src_va); + pkgconf_buffer_append_vfmt(&buf, fmt, va); + va_end(va); + + ret = output->write(output, stream, &buf); + pkgconf_buffer_finalize(&buf); + + return ret; +} + +static bool +pkgconf_output_stdio_write(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer) +{ + (void) output; + + FILE *target = stream == PKGCONF_OUTPUT_STDERR ? stderr : stdout; + + if (buffer != NULL) + { + const char *str = pkgconf_buffer_str(buffer); + size_t size = pkgconf_buffer_len(buffer); + + if (size > 0 && !fwrite(str, size, 1, target)) + return false; + } + + fflush(target); + return true; +} + +static pkgconf_output_t pkgconf_default_output = { + .privdata = NULL, + .write = pkgconf_output_stdio_write, +}; + +pkgconf_output_t * +pkgconf_output_default(void) +{ + return &pkgconf_default_output; +} + +/* + * !doc + * + * .. c:function:: bool pkgconf_output_file_vfmt(FILE *f, const char *fmt, va_list va) + * + * Wrapper around :code:`vfprintf` that returns a boolean. + * + * :param FILE *f: Pointer to an open `FILE` pointer. + * :param: const char *fmt: Format string. + * :param va_list va: Variable list. + * :return: :code:`true` on success, :code:`false` on failure. + */ +bool +pkgconf_output_file_vfmt(FILE *f, const char *fmt, va_list va) +{ + int ret = vfprintf(f, fmt, va); + return ret >= 0; +} + +/* + * !doc + * + * .. c:function:: bool pkgconf_output_file_fmt(FILE *f, const char *fmt, va_list va) + * + * Wrapper around :code:`fprintf` that returns a boolean. + * + * :param FILE *f: Pointer to an open `FILE` pointer. + * :param: const char *fmt: Format string. + * :return: :code:`true` on success, :code:`false` on failure. + */ +bool +pkgconf_output_file_fmt(FILE *f, const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + bool ret = pkgconf_output_file_vfmt(f, fmt, va); + va_end(va); + + return ret; +} |
