b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * This file originated in the realmd project
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * Copyright 2013 Red Hat Inc
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * This program is free software: you can redistribute it and/or modify
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * it under the terms of the GNU Lesser General Public License as published
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * by the Free Software Foundation; either version 2 of the licence or (at
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * your option) any later version.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * See the included COPYING file for more information.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * Author: Stef Walter <stefw@redhat.com>
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * Some snippets of code from gnulib, but have since been refactored
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * to within an inch of their life...
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * vsprintf with automatic memory allocation.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * This program is free software; you can redistribute it and/or modify it
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * under the terms of the GNU Library General Public License as published
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * by the Free Software Foundation; either version 2, or (at your option)
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * any later version.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * This program is distributed in the hope that it will be useful,
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * but WITHOUT ANY WARRANTY; without even the implied warranty of
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter * Library General Public License for more details.
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter void (* copy_fn) (void *, const char *, size_t),
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter while (count > 0) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter const char *piece,
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Waltersafe_format_string_cb (void (* copy_fn) (void *, const char *, size_t),
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter const char * const args[],
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Piece of raw string */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* An literal percent sign? */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Test for positional argument. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Look-ahead parsing, otherwise skipped */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter unsigned int n = 0;
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter for (i = 0; i < 6 && *cp >= '0' && *cp <= '9'; i++, cp++) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Positional argument 0 is invalid. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter if (n == 0) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Positional argument N too high */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Read the supported flags. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter for (; ; cp++) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Supported but ignored */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Parse the width. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter for (i = 0; i < 6 && *cp >= '0' && *cp <= '9'; i++, cp++) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Parse the precision. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter for (i = 0, cp++; i < 6 && *cp >= '0' && *cp <= '9'; cp++, i++) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Read the conversion character. */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter switch (*cp++) {
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Non-positional argument */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Too many arguments used */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* No other conversion characters are supported */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* How many characters are we printing? */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Do we need padding? */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter safe_padding (left ? 0 : width - len, &total, copy_fn, data);
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* The actual data */;
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Do we need padding? */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter safe_padding (left ? width - len : 0, &total, copy_fn, data);
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walterstatic const char **
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter mem = realloc (args, sizeof (const char *) * alo_args);
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter const char *piece,
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Don't copy if too much data */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter /* Null termination happens later */
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter ret = safe_format_string_cb (snprintf_copy_fn, &cx, format, args, num_args);
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter } else if (len > 0) {