Esempio n. 1
0
int
sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap)
{
	va_list ap2;
	int r, len;
	u_char *p;

	VA_COPY(ap2, ap);
	if ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	if (len == 0) {
		r = 0;
		goto out; /* Nothing to do */
	}
	va_end(ap2);
	VA_COPY(ap2, ap);
	if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0)
		goto out;
	if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) {
		r = SSH_ERR_INTERNAL_ERROR;
		goto out; /* Shouldn't happen */
	}
	/* Consume terminating \0 */
	if ((r = sshbuf_consume_end(buf, 1)) != 0)
		goto out;
	r = 0;
 out:
	va_end(ap2);
	return r;
}
Esempio n. 2
0
static void textblock_vappend_c(textblock *tb, byte attr, const char *fmt,
		va_list vp)
{
	while (1)
	{
		va_list args;
		size_t len;

		size_t remaining = tb->size - tb->strlen;
		char *fmt_start = tb->text + tb->strlen;

		VA_COPY(args, vp);
		len = vstrnfmt(fmt_start, remaining, fmt, args);
		va_end(args);
		if (len < remaining - 1)
		{
			byte *attr_start = tb->attrs + (tb->strlen * sizeof *tb->attrs);
			memset(attr_start, attr, len * sizeof *tb->attrs);

			tb->strlen += len;
			break;
		}

		tb->size = TEXTBLOCK_LEN_INCR(tb->size);
		tb->text = mem_realloc(tb->text, tb->size);
		tb->attrs = mem_realloc(tb->attrs, tb->size * sizeof *tb->attrs);
	}
}
Esempio n. 3
0
void sieve_direct_vdebug
(struct sieve_instance *svinst, struct sieve_error_handler *ehandler,
	unsigned int flags, const char *location, const char *fmt, va_list args)
{
	if ( (flags & SIEVE_ERROR_FLAG_GLOBAL) != 0 &&
		(ehandler == NULL || ehandler->parent == NULL) &&
		svinst->system_ehandler != ehandler) {
		i_assert(svinst->system_ehandler != NULL);
		if (svinst->system_ehandler->vdebug != NULL ) {
			va_list args_copy;

			VA_COPY(args_copy, args);
			svinst->system_ehandler->vdebug
				(svinst->system_ehandler, 0, location, fmt, args_copy);
			va_end(args_copy);
		}
	}

	if ( ehandler == NULL )
		return;

	if ( ehandler->parent != NULL || ehandler->log_debug ) {
		if ( ehandler->vdebug != NULL )
			ehandler->vdebug(ehandler, flags, location, fmt, args);
	}
}
Esempio n. 4
0
void smtp_server_command_fail(struct smtp_server_command *cmd,
			      unsigned int status, const char *enh_code,
			      const char *fmt, ...)
{
	unsigned int i;
	va_list args;

	i_assert(status / 100 > 2);

	va_start(args, fmt);
	if (cmd->replies_expected == 1) {
		smtp_server_reply_indexv(&cmd->context, 0,
					 status, enh_code, fmt, args);
	} else for (i = 0; i < cmd->replies_expected; i++) {
		bool sent = FALSE;

		if (array_is_created(&cmd->replies)) {
			const struct smtp_server_reply *reply =
				array_idx(&cmd->replies, i);
			sent = reply->sent;
		}
	
		/* send the same reply for all */
		if (!sent) {
			va_list args_copy;
			VA_COPY(args_copy, args);
			smtp_server_reply_indexv(&cmd->context, i,
				status, enh_code, fmt, args_copy);
			va_end(args_copy);
		}
	}
	va_end(args);
}
Esempio n. 5
0
int     memcache_printf(VSTREAM *stream, const char *fmt,...)
{
    va_list ap;
    int     ret;

    va_start(ap, fmt);

    if (msg_verbose) {
	VSTRING *buf = vstring_alloc(100);
	va_list ap2;

	VA_COPY(ap2, ap);
	vstring_vsprintf(buf, fmt, ap2);
	va_end(ap2);
	msg_info("%s write: %s", VSTREAM_PATH(stream), STR(buf));
	vstring_free(buf);
    }

    /*
     * Do the I/O.
     */
    ret = memcache_vprintf(stream, fmt, ap);
    va_end(ap);
    return (ret);
}
Esempio n. 6
0
/**
 * Format data to stream.
 *
 * @return the amount of bytes written, -1 on error.
 */
ssize_t
ostream_printf(ostream_t *os, const char *fmt, ...)
{
	va_list args, args2;
	char buf[1024];
	size_t len;
	char *data;
	ssize_t w;

	ostream_check(os);

	va_start(args, fmt);

	VA_COPY(args2, args);
	len = gm_vsnprintf(buf, sizeof buf, fmt, args2);
	va_end(args2);

	if (len >= sizeof buf - 1) {
		data = h_strdup_len_vprintf(fmt, args, &len);
	} else {
		data = buf;
	}
	va_end(args);

	w = ostream_write(os, data, len);

	if (data != buf)
		hfree(data);

	return w;
}
Esempio n. 7
0
 char *talloc_vasprintf(TALLOC_CTX *t, const char *fmt, va_list ap)
{	
	int len;
	char *ret;
	va_list ap2;
	
	VA_COPY(ap2, ap);  /* for systems were va_list is a struct */
	len = vsnprintf(NULL, 0, fmt, ap2);

	ret = talloc(t, len+1);
	if (ret) {
		VA_COPY(ap2, ap);
		vsnprintf(ret, len+1, fmt, ap2);
	}

	return ret;
}
Esempio n. 8
0
/**
 * Realloc @p s to append the formatted result of @p fmt and @p ap,
 * and return @p s, which may have moved.  Good for gradually
 * accumulating output into a string buffer.
 **/
 char *talloc_vasprintf_append(TALLOC_CTX *t, char *s,
			       const char *fmt, va_list ap)
{	
	int len, s_len;
	va_list ap2;

	VA_COPY(ap2, ap);
	s_len = strlen(s);
	len = vsnprintf(NULL, 0, fmt, ap2);

	s = talloc_realloc(t, s, s_len + len+1);
	if (!s) return NULL;

	VA_COPY(ap2, ap);
	vsnprintf(s+s_len, len+1, fmt, ap2);

	return s;
}
Esempio n. 9
0
 char *talloc_vasprintf(TALLOC_CTX *t, const char *fmt, va_list ap)
{	
	int len;
	char *ret;
	va_list ap2;
	
	VA_COPY(ap2, ap);

	len = vsnprintf(NULL, 0, fmt, ap2);

	ret = TALLOC(t, len+1);
	if (ret) {
		VA_COPY(ap2, ap);
		vsnprintf(ret, len+1, fmt, ap2);
	}

	return ret;
}
Esempio n. 10
0
int
vasprintf(char **str, const char *fmt, va_list ap)
{
	int ret = -1;
	va_list ap2;
	char *string, *newstr;
	size_t len;

	VA_COPY(ap2, ap);
	if ((string = malloc(INIT_SZ)) == NULL)
		goto fail;

	ret = vsnprintf(string, INIT_SZ, fmt, ap2);
	if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
		*str = string;
	} else if (ret == INT_MAX || ret < 0) { /* Bad length */
		free(string);
		goto fail;
	} else {	/* bigger than initial, realloc allowing for nul */
		len = (size_t)ret + 1;
		if ((newstr = realloc(string, len)) == NULL) {
			free(string);
			goto fail;
		} else {
			va_end(ap2);
			VA_COPY(ap2, ap);
			ret = vsnprintf(newstr, len, fmt, ap2);
			if (ret >= 0 && (size_t)ret < len) {
				*str = newstr;
			} else { /* failed with realloc'ed string, give up */
				free(newstr);
				goto fail;
			}
		}
	}
	va_end(ap2);
	return (ret);

fail:
	*str = NULL;
	errno = ENOMEM;
	va_end(ap2);
	return (-1);
}
Esempio n. 11
0
/*
 * format a string into the output buffer
 * designed for formats which themselves call fmt,
 * but ignore any width flags
 */
int
fmtprint(Fmt *f, char *fmt, ...)
{
	va_list va;
	int n;

	f->flags = 0;
	f->width = 0;
	f->prec = 0;
	VA_COPY(va, f->args);
	VA_END(f->args);
	va_start(f->args, fmt);
	n = dofmt(f, fmt);
	va_end(f->args);
	f->flags = 0;
	f->width = 0;
	f->prec = 0;
	VA_COPY(f->args,va);
	VA_END(va);
	if(n >= 0)
		return 0;
	return n;
}
Esempio n. 12
0
void marpaXml_log(marpaXmlLog_t *marpaXmlLogp, marpaXmlLogLevel_t marpaXmlLogLeveli, const char *fmts, ...) {
  va_list                ap;
#ifdef VA_COPY
  va_list                ap2;
#endif
  char                  *msgs;
  static const char     *emptyMessages = "Empty message";
  marpaXmlLogCallback_t  logCallbackp;
  void                  *userDatavp;
  marpaXmlLogLevel_t     marpaXmlDefaultLogLeveli;

  if (marpaXmlLogp != NULL) {
    if (marpaXmlLogp->logCallbackp != NULL) {
      logCallbackp = marpaXmlLogp->logCallbackp;
    } else {
      logCallbackp = &_marpaXmlLog_defaultCallback;
    }
    userDatavp = marpaXmlLogp->userDatavp;
    marpaXmlDefaultLogLeveli = marpaXmlLogp->marpaXmlLogLeveli;
  } else {
    userDatavp = NULL;
    logCallbackp = &_marpaXmlLog_defaultCallback;
    marpaXmlDefaultLogLeveli = MARPAXML_LOGLEVEL_WARNING;
  }

  if (marpaXmlLogLeveli >= marpaXmlDefaultLogLeveli) {

    va_start(ap, fmts);
#ifdef VA_COPY
    VA_COPY(ap2, ap);
    msgs = (fmts != NULL) ? messageBuilder_ap(fmts, ap2) : (char *) emptyMessages;
    va_end(ap2);
#else
    msgs = (fmts != NULL) ? messageBuilder_ap(fmts, ap) : (char *) emptyMessages;
#endif
    va_end(ap);

    if (msgs != messageBuilder_internalErrors()) {
      logCallbackp(userDatavp, marpaXmlLogLeveli, msgs);
    } else {
      logCallbackp(userDatavp, MARPAXML_LOGLEVEL_ERROR, msgs);
    }

    if (msgs != emptyMessages && msgs != messageBuilder_internalErrors()) {
      /* No need to assign to NULL, this is a local variable and we will return just after */
      free(msgs);
    }
  }

}
Esempio n. 13
0
MARPAWRAPPER_EXPORT void genericLogger_log(const genericLogger_t *genericLoggerp, genericLoggerLevel_t leveli, const char *fmts, ...) {
  va_list                ap;
#ifdef VA_COPY
  va_list                ap2;
#endif
  char                  *msgs;
  static const char     *emptyMessages = "Empty message";
  genericLoggerCallback_t  logCallbackp;
  void                  *userDatavp;
  genericLoggerLevel_t     genericLoggerDefaultLogLeveli;

  if (genericLoggerp != NULL) {
    if (genericLoggerp->genericLoggerOption.logCallbackp != NULL) {
      logCallbackp = genericLoggerp->genericLoggerOption.logCallbackp;
    } else {
      logCallbackp = &_genericLogger_defaultCallback;
    }
    userDatavp = genericLoggerp->genericLoggerOption.userDatavp;
    genericLoggerDefaultLogLeveli = genericLoggerp->genericLoggerOption.leveli;
  } else {
    userDatavp = NULL;
    logCallbackp = &_genericLogger_defaultCallback;
    genericLoggerDefaultLogLeveli = GENERICLOGGER_LOGLEVEL_WARNING;
  }

  if (leveli >= genericLoggerDefaultLogLeveli) {

    va_start(ap, fmts);
#ifdef VA_COPY
    VA_COPY(ap2, ap);
    msgs = (fmts != NULL) ? messageBuilder_ap(fmts, ap2) : (char *) emptyMessages;
    va_end(ap2);
#else
    msgs = (fmts != NULL) ? messageBuilder_ap(fmts, ap) : (char *) emptyMessages;
#endif
    va_end(ap);

    if (msgs != messageBuilder_internalErrors()) {
      logCallbackp(userDatavp, leveli, msgs);
    } else {
      logCallbackp(userDatavp, GENERICLOGGER_LOGLEVEL_ERROR, msgs);
    }

    if (msgs != emptyMessages && msgs != messageBuilder_internalErrors()) {
      /* No need to assign to NULL, this is a local variable and we will return just after */
      free(msgs);
    }
  }

}
Esempio n. 14
0
int string_appendvf (String *sobj, const char *fmt, va_list args)
{
	va_list args_cpy;
	int written = 0;
	int remaining;

	if (!sobj)
		return 0;

	/* make sure we got something to work with */
	if (sobj->alloc == 0)
	{
		if (string_resize (sobj, STRING_SIZE) == 0)
			return 0;
	}

	/* loop until the buffer is big enough */
	for (;;)
	{
		if (sobj->len < sobj->alloc) /* make sure there is room for '\0' */
		{
			remaining = sobj->alloc - sobj->len;

			/*
			 * We have to make a copy of the va_list because we may pass this
			 * point multiple times. Note that simply calling va_start again is
			 * not a good idea since the va_start/va_end should be in the same
			 * stack frame because of some obscure implementations.
			 */
			VA_COPY (args_cpy, args);
			written = vsnprintf (sobj->str + sobj->len, remaining, fmt,
			                     args_cpy);
			va_end (args_cpy);

			/* break if we have written everything */
			if (written > -1 && written < remaining)
				break;
		}

		/* if we got here, we don't have enough memory in the underlying buffer
		 * to fit this fmt buffer */
		if (string_resize (sobj, sobj->alloc * 2) == 0)
			return 0;
	}

	sobj->len += written;

	return written;
}
Esempio n. 15
0
int
vfprint(int fd, char *fmt, va_list args)
{
	Fmt f;
	char buf[256];
	int n;

	fmtfdinit(&f, fd, buf, sizeof(buf));
	VA_COPY(f.args,args);
	n = dofmt(&f, fmt);
	VA_END(f.args);
	if(n > 0 && __fmtFdFlush(&f) == 0)
		return -1;
	return n;
}
Esempio n. 16
0
void
DefaultLogger::log(const Level level, const char *format, va_list args) {
	log4cxx::LevelPtr log4cxxLevel = toLog4cxxLevel(level);
	if (logger_->isEnabledFor(log4cxxLevel)) {
		va_list tmpargs;
		VA_COPY(tmpargs, args);
		size_t size = vsnprintf(NULL, 0, format, tmpargs);
		va_end(tmpargs);
		if (size > 0) {
			std::vector<char> data(size + 1);
			vsnprintf(&data[0], size + 1, format, args);
			logger_->log(log4cxxLevel, std::string(data.begin(), data.begin() + size));
		}
	}
}
Esempio n. 17
0
/*
 * print into an allocated string buffer
 */
char*
vsmprint(char *fmt, va_list args)
{
	Fmt f;
	int n;

	if(fmtstrinit(&f) < 0)
		return nil;
	VA_COPY(f.args,args);
	n = dofmt(&f, fmt);
	VA_END(f.args);
	if(n < 0){
		free(f.start);
		return nil;
	}
	return fmtstrflush(&f);
}
Esempio n. 18
0
 int d_vfprintf(FILE *f, const char *format, va_list ap)
{
	char *p, *p2;
	int ret, maxlen, clen;
	const char *msgstr;
	va_list ap2;

	/* do any message translations */
	msgstr = lang_msg(format);
	if (!msgstr) return -1;

	VA_COPY(ap2, ap);

	ret = vasprintf(&p, msgstr, ap2);

	lang_msg_free(msgstr);

	if (ret <= 0) return ret;

	/* now we have the string in unix format, convert it to the display
	   charset, but beware of it growing */
	maxlen = ret*2;
again:
	p2 = malloc(maxlen);
	if (!p2) {
		SAFE_FREE(p);
		return -1;
	}
	clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, True);

	if (clen >= maxlen) {
		/* it didn't fit - try a larger buffer */
		maxlen *= 2;
		SAFE_FREE(p2);
		goto again;
	}

	/* good, its converted OK */
	SAFE_FREE(p);
	ret = fwrite(p2, 1, clen, f);
	SAFE_FREE(p2);

	return ret;
}
Esempio n. 19
0
int
runevsnprint(Rune *buf, int len, char *fmt, va_list args)
{
	Fmt f;

	if(len <= 0)
		return -1;
	f.runes = 1;
	f.start = buf;
	f.to = buf;
	f.stop = buf + len - 1;
	f.flush = 0;
	f.farg = nil;
	f.nfmt = 0;
	VA_COPY(f.args,args);
	dofmt(&f, fmt);
	VA_END(f.args);
	*(Rune*)f.to = '\0';
	return (Rune*)f.to - buf;
}
Esempio n. 20
0
void sieve_direct_verror
(struct sieve_instance *svinst, struct sieve_error_handler *ehandler,
	unsigned int flags, const char *location, const char *fmt, va_list args)
{
	if ( (flags & SIEVE_ERROR_FLAG_GLOBAL) != 0 &&
		(ehandler == NULL || ehandler->parent == NULL)) {
		i_assert(svinst->system_ehandler != NULL);
		if (svinst->system_ehandler != ehandler ||
			(flags & SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO) != 0) {
			va_list args_copy;

			VA_COPY(args_copy, args);

			if ( (flags & SIEVE_ERROR_FLAG_GLOBAL_MAX_INFO) != 0 ) {
				if (svinst->system_ehandler->vinfo != NULL ) {
					svinst->system_ehandler->vinfo
						(svinst->system_ehandler, 0, location, fmt, args_copy);
				}
			} else {
				if ( svinst->system_ehandler->verror != NULL ) {
					svinst->system_ehandler->verror
						(svinst->system_ehandler, 0, location, fmt, args_copy);
				}
			}
			va_end(args_copy);
			if (svinst->system_ehandler == ehandler)
				return;
		}
	}

	if ( ehandler == NULL )
		return;

	if ( ehandler->parent != NULL || sieve_errors_more_allowed(ehandler) ) {
		if ( ehandler->verror != NULL )
			ehandler->verror(ehandler, flags, location, fmt, args);

		if ( ehandler->pool != NULL )
			ehandler->errors++;
	}
}
Esempio n. 21
0
char*
vseprint(char *buf, char *e, char *fmt, va_list args)
{
	Fmt f;

	if(e <= buf)
		return nil;
	f.runes = 0;
	f.start = buf;
	f.to = buf;
	f.stop = e - 1;
	f.flush = 0;
	f.farg = nil;
	f.nfmt = 0;
	VA_COPY(f.args,args);
	fmtlocaleinit(&f, nil, nil, nil);
	dofmt(&f, fmt);
	VA_END(f.args);
	*(char*)f.to = '\0';
	return (char*)f.to;
}
Esempio n. 22
0
void str_vprintfa(string_t *str, const char *fmt, va_list args)
{
#define SNPRINTF_INITIAL_EXTRA_SIZE 128
	va_list args2;
	char *tmp;
	unsigned int init_size;
	size_t pos = str->used;
	int ret, ret2;

	VA_COPY(args2, args);

	/* the format string is modified only if %m exists in it. it happens
	   only in error conditions, so don't try to t_push() here since it'll
	   just slow down the normal code path. */
	fmt = printf_format_fix_get_len(fmt, &init_size);
	init_size += SNPRINTF_INITIAL_EXTRA_SIZE;

	/* @UNSAFE */
	if (pos+init_size > buffer_get_size(str) &&
	    pos < buffer_get_size(str)) {
		/* avoid growing buffer larger if possible. this is also
		   required if buffer isn't dynamically growing. */
		init_size = buffer_get_size(str)-pos;
	}
	tmp = buffer_get_space_unsafe(str, pos, init_size);
	ret = vsnprintf(tmp, init_size, fmt, args);
	i_assert(ret >= 0);

	if ((unsigned int)ret >= init_size) {
		/* didn't fit with the first guess. now we know the size,
		   so try again. */
		tmp = buffer_get_space_unsafe(str, pos, ret + 1);
		ret2 = vsnprintf(tmp, ret + 1, fmt, args2);
		i_assert(ret2 == ret);
	}

	/* drop the unused data, including terminating NUL */
	buffer_set_used_size(str, pos + ret);
}
Esempio n. 23
0
char *t_noalloc_strdup_vprintf(const char *format, va_list args,
			       unsigned int *size_r)
{
#define SNPRINTF_INITIAL_EXTRA_SIZE 256
	va_list args2;
	char *tmp;
	unsigned int init_size;
	int ret;
#ifdef DEBUG
	int old_errno = errno;
#endif

	VA_COPY(args2, args);

	/* the format string is modified only if %m exists in it. it happens
	   only in error conditions, so don't try to t_push() here since it'll
	   just slow down the normal code path. */
	format = printf_format_fix_get_len(format, &init_size);
	init_size += SNPRINTF_INITIAL_EXTRA_SIZE;

	tmp = t_buffer_get(init_size);
	ret = vsnprintf(tmp, init_size, format, args);
	i_assert(ret >= 0);

	*size_r = ret + 1;
	if ((unsigned int)ret >= init_size) {
		/* didn't fit with the first guess. now we know the size,
		   so try again. */
		tmp = t_buffer_get(*size_r);
		ret = vsnprintf(tmp, *size_r, format, args2);
		i_assert((unsigned int)ret == *size_r-1);
	}
#ifdef DEBUG
	/* we rely on errno not changing. it shouldn't. */
	i_assert(errno == old_errno);
#endif
	va_end(args2);
	return tmp;
}
Esempio n. 24
0
xnode_prop_ns_vprintf(xnode_t *element,
	const char *uri, const char *name, const char *fmt, va_list args)
{
	char buf[1024];
	va_list args2;
	char *value;
	bool result;

	VA_COPY(args2, args);
	if (str_vbprintf(buf, sizeof buf, fmt, args2) >= sizeof buf - 1) {
		value = h_strdup_vprintf(fmt, args);
	} else {
		value = buf;
	}
	va_end(args2);

	result = xnode_prop_ns_set(element, uri, name, value);

	if (value != buf)
		hfree(value);

	return result;
}
Esempio n. 25
0
/* Heart of the matter */
static void
rs_log_va(int flags, char const *caller_fn_name, char const *fmt, va_list va)


{
    int level = flags & RS_LOG_PRIMASK;
    struct rs_logger_list *l;

    rs_lazy_default();

    if (level <= rs_trace_level)
      for (l = logger_list; l; l = l->next)
          if (level <= l->max_level) {
              /* We need to use va_copy() here, because functions like vsprintf
               * may destructively modify their va_list argument, but we need
               * to ensure that it's still valid next time around the loop. */
              va_list copied_va;
              VA_COPY(copied_va, va);
              l->fn(flags, caller_fn_name,
                    fmt, copied_va, l->private_ptr, l->private_int);
              VA_COPY_END(copied_va);
          }
}
Esempio n. 26
0
/**
 * Concatenates a variable number of NUL-terminated strings into buffer
 * which will be allocated using walloc().
 *
 * The list of strings must be terminated by a (void *) 0. The first
 * list element may be NULL in which case 1 is returned.
 *
 * @param dst_ptr if not NULL, it will point to the allocated buffer.
 * @param first the first source string or NULL.
 *
 * @return The sum of the lengths of all passed strings plus 1 for the
 *         the trailing NUL. Use this as size argument for wfree() to
 *		   release the allocated buffer.
 */
size_t
w_concat_strings(char **dst_ptr, const char *first, ...)
{
	va_list ap;
	va_list ap2;
	size_t len;

	va_start(ap, first);
	VA_COPY(ap2, ap);
	len = concat_strings_v(NULL, 0, first, ap);
	va_end(ap);

	if (dst_ptr) {
		size_t ret;

		*dst_ptr = walloc(len + 1);
		ret = concat_strings_v(*dst_ptr, len + 1, first, ap2);
		va_end(ap2);
		g_assert(ret == len);
	}

	return 1 + len;
}
Esempio n. 27
0
void
memBufPrintf(MemBuf * mb, const char *fmt,...)
{
    va_list args;
    va_start(args, fmt);
#else
void
memBufPrintf(va_alist)
     va_dcl
{
    va_list args;
    MemBuf *mb = NULL;
    const char *fmt = NULL;
    mb_size_t sz = 0;
    va_start(args);
    mb = va_arg(args, MemBuf *);
    fmt = va_arg(args, char *);
#endif
    memBufVPrintf(mb, fmt, args);
    va_end(args);
}


/* vprintf for other printf()'s to use; calls vsnprintf, extends buf if needed */
void
memBufVPrintf(MemBuf * mb, const char *fmt, va_list vargs)
{
#if defined VA_COPY
    va_list ap;
#endif
    int sz = 0;
    assert(mb && fmt);
    assert(mb->buf);
    assert(!mb->stolen);	/* not frozen */
    /* assert in Grow should quit first, but we do not want to have a scary infinite loop */
    while (mb->capacity <= mb->max_capacity) {
	mb_size_t free_space = mb->capacity - mb->size;
	/* put as much as we can */

#if defined VA_COPY
	VA_COPY(ap, vargs);	/* Fix of bug 753. The value of vargs is undefined
				 * * after vsnprintf() returns. Make a copy of vargs
				 * * incase we loop around and call vsnprintf() again.
				 */
	sz = vsnprintf(mb->buf + mb->size, free_space, fmt, ap);
	va_end(ap);
#else
	sz = vsnprintf(mb->buf + mb->size, free_space, fmt, vargs);
#endif
	/* check for possible overflow */
	/* snprintf on Linuz returns -1 on overflows */
	/* snprintf on FreeBSD returns at least free_space on overflows */
	if (sz < 0 || sz >= free_space)
	    memBufGrow(mb, mb->capacity + 1);
	else
	    break;
    }
    mb->size += sz;
    /* on Linux and FreeBSD, '\0' is not counted in return value */
    /* on XXX it might be counted */
    /* check that '\0' is appended and not counted */
    if (!mb->size || mb->buf[mb->size - 1]) {
	assert(!mb->buf[mb->size]);
    } else {
	mb->size--;
    }
}
Esempio n. 28
0
static int
dopr(char *buffer, size_t maxlen, const char *format, va_list args_in)
{
	char ch;
	intmax_t value;
	LDOUBLE fvalue;
	char *strvalue;
	int min;
	int max;
	int state;
	int flags;
	int cflags;
	size_t currlen;
	va_list args;

	VA_COPY(args, args_in);
	
	state = DP_S_DEFAULT;
	currlen = flags = cflags = min = 0;
	max = -1;
	ch = *format++;
	
	while (state != DP_S_DONE) {
		if (ch == '\0') 
			state = DP_S_DONE;

		switch(state) {
		case DP_S_DEFAULT:
			if (ch == '%') 
				state = DP_S_FLAGS;
			else
				DOPR_OUTCH(buffer, currlen, maxlen, ch);
			ch = *format++;
			break;
		case DP_S_FLAGS:
			switch (ch) {
			case '-':
				flags |= DP_F_MINUS;
				ch = *format++;
				break;
			case '+':
				flags |= DP_F_PLUS;
				ch = *format++;
				break;
			case ' ':
				flags |= DP_F_SPACE;
				ch = *format++;
				break;
			case '#':
				flags |= DP_F_NUM;
				ch = *format++;
				break;
			case '0':
				flags |= DP_F_ZERO;
				ch = *format++;
				break;
			default:
				state = DP_S_MIN;
				break;
			}
			break;
		case DP_S_MIN:
			if (isdigit((unsigned char)ch)) {
				min = 10*min + char_to_int (ch);
				ch = *format++;
			} else if (ch == '*') {
				min = va_arg (args, int);
				ch = *format++;
				state = DP_S_DOT;
			} else {
				state = DP_S_DOT;
			}
			break;
		case DP_S_DOT:
			if (ch == '.') {
				state = DP_S_MAX;
				ch = *format++;
			} else { 
				state = DP_S_MOD;
			}
			break;
		case DP_S_MAX:
			if (isdigit((unsigned char)ch)) {
				if (max < 0)
					max = 0;
				max = 10*max + char_to_int (ch);
				ch = *format++;
			} else if (ch == '*') {
				max = va_arg (args, int);
				ch = *format++;
				state = DP_S_MOD;
			} else {