Пример #1
0
/* Like sdscatprintf() but gets va_list instead of being variadic. */
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
    va_list cpy;
    char staticbuf[1024], *buf = staticbuf, *t;
    size_t buflen = strlen(fmt)*2;

    /* We try to start using a static buffer for speed.
     * If not possible we revert to heap allocation. */
    if (buflen > sizeof(staticbuf)) {
        buf = s_malloc(buflen);
        if (buf == NULL) return NULL;
    } else {
        buflen = sizeof(staticbuf);
    }

    /* Try with buffers two times bigger every time we fail to
     * fit the string in the current buffer size. */
    while(1) {
        buf[buflen-2] = '\0';
        va_copy(cpy,ap);
        vsnprintf(buf, buflen, fmt, cpy);
        va_end(cpy);
        if (buf[buflen-2] != '\0') {
            if (buf != staticbuf) s_free(buf);
            buflen *= 2;
            buf = s_malloc(buflen);
            if (buf == NULL) return NULL;
            continue;
        }
        break;
    }

    /* Finally concat the obtained string to the SDS string and return it. */
    t = sdscat(s, buf);
    if (buf != staticbuf) s_free(buf);
    return t;
}
Пример #2
0
static void
assert_stats_foreach_yielded_counters_matches(StatsCluster *sc, ...)
{
  ValidateCountersState st;
  va_list va;
  gint type_count = 0;
  gint t;

  va_start(va, sc);
  st.validate_count = 0;
  va_copy(st.types, va);

  t = va_arg(va, gint);
  while (t >= 0)
    {
      type_count++;
      t = va_arg(va, gint);
    }
  
  stats_cluster_foreach_counter(sc, _validate_yielded_counters, &st);
  va_end(va);
  
  assert_gint(type_count, st.validate_count, "the number of validated counters mismatch the expected size");
}
Пример #3
0
/* return allocated string w/printf() result */
char *alloc_vprintf(const char *fmt, va_list ap)
{
	va_list ap_copy;
	int len;
	char *string;

	/* determine the length of the buffer needed */
	va_copy(ap_copy, ap);
	len = vsnprintf(NULL, 0, fmt, ap_copy);
	va_end(ap_copy);

	/* allocate and make room for terminating zero. */
	/* FIXME: The old version always allocated at least one byte extra and
	 * other code depend on that. They should be probably be fixed, but for
	 * now reserve the extra byte. */
	string = malloc(len + 2);
	if (string == NULL)
		return NULL;

	/* do the real work */
	vsnprintf(string, len + 1, fmt, ap);

	return string;
}
Пример #4
0
int vasprintf(char** strp, const char* format, va_list ap)
{
	int count;
	va_list aq;

	va_copy(aq, ap);

	// Find out how long the resulting string is
	count = vsnprintf(NULL, 0, format, aq);
	va_end(aq);

	if (count == 0)
	{
		*strp = strdup("");
		return 0;
	}
	else if (count < 0)
	{
		// Something went wrong, so return the error code (probably still requires checking of "errno" though)
		return -1;
	}

	assert(strp != NULL);

	// Allocate memory for our string
	*strp = (char *)malloc(count + 1);
	if (*strp == NULL)
	{
		debug(LOG_FATAL, "Out of memory!");
		abort();
		return -1;
	}

	// Do the actual printing into our newly created string
	return vsprintf(*strp, format, ap);
}
Пример #5
0
status_t String8::appendFormatV(const char* fmt, va_list args)
{
    int n, result = NO_ERROR;
    va_list tmp_args;

    /* args is undefined after vsnprintf.
     * So we need a copy here to avoid the
     * second vsnprintf access undefined args.
     */
    va_copy(tmp_args, args);
    n = vsnprintf(NULL, 0, fmt, tmp_args);
    va_end(tmp_args);

    if (n != 0) {
        size_t oldLength = length();
        char* buf = lockBuffer(oldLength + n);
        if (buf) {
            vsnprintf(buf + oldLength, n + 1, fmt, args);
        } else {
            result = NO_MEMORY;
        }
    }
    return result;
}
Пример #6
0
/* Implementation of vasprintf from GNU/BSD */
int util_vasprintf(char **out, const char *fmt, va_list args)
{
  char *ret;
  int alloc_size;
  va_list args_copy;
  va_copy(args_copy, args);
  alloc_size = vsnprintf((char*)NULL, 0, fmt, args);
  if (alloc_size >= 0) { /* alloc_size contains the size of the string to 
  						    be allocated since vsnprintf always returns
  						    the number of bytes that would be printed 
  						    in case of unlimited buffer space */
    ret = (char*)malloc((size_t)alloc_size + 1);
    if (ret) {
      if (vsnprintf(ret, (size_t)alloc_size + 1, fmt, args_copy) < 0) {
      	free(ret);
      	alloc_size = -1;
      	ret = NULL;
      }
    }
    *out = ret;
  }
  va_end(args_copy);
  return alloc_size;
}
Пример #7
0
//We wrap the actual sdc_error to issolate custom handlers from vaargs
void sdc_error_wrap(Callback& callback, const int line_no, const std::string& near_text, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);

    //We need to copy the args so we don't change them before the true formating
    va_list args_copy;
    va_copy(args_copy, args);

    //Determine the formatted length using a copy of the args
    int len = std::vsnprintf(nullptr, 0, fmt, args_copy); 

    va_end(args_copy); //Clean-up

    //Negative if there is a problem with the format string
    assert(len >= 0 && "Problem decoding format string");

    size_t buf_size = len + 1; //For terminator

    //Allocate a buffer
    //  unique_ptr will free buffer automatically
    std::unique_ptr<char[]> buf(new char[buf_size]);

    //Format into the buffer using the original args
    len = std::vsnprintf(buf.get(), buf_size, fmt, args);

    va_end(args); //Clean-up

    assert(len >= 0 && "Problem decoding format string");
    assert(static_cast<size_t>(len) == buf_size - 1);

    //Build the string from the buffer
    std::string msg(buf.get(), len);

    //Call the error handler
    callback.parse_error(line_no, near_text, msg);
}
Пример #8
0
/**
 * Send a SCPI command with a variadic argument list.
 *
 * @param scpi Previously initialized SCPI device structure.
 * @param format Format string.
 * @param args Argument list.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_send_variadic(struct sr_scpi_dev_inst *scpi,
			 const char *format, va_list args)
{
	va_list args_copy;
	char *buf;
	int len, ret;

	/* Get length of buffer required. */
	va_copy(args_copy, args);
	len = vsnprintf(NULL, 0, format, args_copy);
	va_end(args_copy);

	/* Allocate buffer and write out command. */
	buf = g_malloc(len + 1);
	vsprintf(buf, format, args);

	/* Send command. */
	ret = scpi->send(scpi->priv, buf);

	/* Free command buffer. */
	g_free(buf);

	return ret;
}
Пример #9
0
int OUTPUTFORMATTER::vprint( const char* fmt,  va_list ap )  throw( IO_ERROR )
{
    // This function can call vsnprintf twice.
    // But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
    // va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
    // see: www.cplusplus.com/reference/cstdio/vsnprintf
    // we make a copy of va_list ap for the second call, if happens
    va_list tmp;
    va_copy( tmp, ap );
    int ret = vsnprintf( &buffer[0], buffer.size(), fmt, ap );

    if( ret >= (int) buffer.size() )
    {
        buffer.resize( ret + 1000 );
        ret = vsnprintf( &buffer[0], buffer.size(), fmt, tmp );
    }

    va_end( tmp );      // Release the temporary va_list, initialised from ap

    if( ret > 0 )
        write( &buffer[0], ret );

    return ret;
}
Пример #10
0
char*
vformat(char *buff, size_t *_size, const char *fmt, va_list ap)
{
    if (!buff || !_size || !*_size) {
        char *res = nullptr;
        vasprintf(&res, fmt, ap);
        return res;
    }
    va_list _ap;
    va_copy(_ap, ap);
    size_t size = *_size;
    size_t new_size = vsnprintf(buff, size, fmt, ap) + 1;
    if (new_size > size) {
        new_size = alignTo(new_size, 1024);
        if (allocated) {
            buff = (char*)realloc(buff, new_size);
        } else {
            buff = (char*)malloc(new_size);
        }
        *_size = new_size;
        new_size = vsnprintf(buff, new_size, fmt, _ap);
    }
    return buff;
}
Пример #11
0
static void sdlogger(void *data, mrp_log_level_t level, const char *file,
                     int line, const char *func, const char *format, va_list ap)
{
    va_list cp;
    int     prio;
    char    filebuf[1024], linebuf[64];

    MRP_UNUSED(data);

    va_copy(cp, ap);
    switch (level) {
    case MRP_LOG_ERROR:   prio = LOG_ERR;     break;
    case MRP_LOG_WARNING: prio = LOG_WARNING; break;
    case MRP_LOG_INFO:    prio = LOG_INFO;    break;
    case MRP_LOG_DEBUG:   prio = LOG_DEBUG;   break;
    default:              prio = LOG_INFO;
    }

    snprintf(filebuf, sizeof(filebuf), "CODE_FILE=%s", file);
    snprintf(linebuf, sizeof(linebuf), "CODE_LINE=%d", line);
    sd_journal_printv_with_location(prio, filebuf, linebuf, func, format, cp);

    va_end(cp);
}
Пример #12
0
int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p)
{
	int r;
	va_list p2;
	char buf[128];

	va_copy(p2, p);
	r = vsnprintf(buf, 128, format, p);
	va_end(p);

	/* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */

	if (r < 128) {
		va_end(p2);
		*string_ptr = strdup(buf);
		return (*string_ptr ? r : -1);
	}

	*string_ptr = malloc(r+1);
	r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1);
	va_end(p2);

	return r;
}
Пример #13
0
int				ft_printf(const char *format, ...)
{
	int				printed_ch;
	va_list			ap[2];
	t_type_format	print_format;
	char			*p;
	char			*str;

	printed_ch = 0;
	p = ft_write_to_procent((char *)format, &printed_ch);
	va_start(ap[0], format);
	va_copy(ap[1], ap[0]);
	while (p)
	{
		p = ft_copy_convertor(p, &str);
		print_format = ft_set_format(str, ap);
		if (print_format.conv != 0)
			printed_ch += ft_print_arg(print_format, ap);
		p = ft_write_to_procent(p, &printed_ch);
	}
	va_end(ap[1]);
	va_end(ap[0]);
	return (printed_ch);
}
Пример #14
0
char			*ft_build(va_list args, t_format *opt)
{
	va_list			ptr;
	char			*content;
	int				i;

	if (opt->type & 0xff)
	{
		if (opt->arg > 0)
		{
			va_copy(ptr, args);
			i = -1;
			while (++i < opt->arg)
				va_arg(ptr, void *);
			content = ft_get(ptr, opt);
			va_end(ptr);
		}
		else
			content = ft_get(args, opt);
	}
	else
		content = ft_alter(ft_ctos(opt->spec), opt, 0, 1);
	return (content);
}
Пример #15
0
/*! A counterpart of vsprintf, which allocates the result string
    on the heap an is save against buffer overflows.

    Returns 0, if the system is out of memory.
*/
char* hpgs_vsprintf_malloc (const char *fmt, va_list ap)
{
  /* Guess we need no more than 1024 bytes. */
  int n, size = 1024;
  char *p;
  if ((p = malloc (size)) == NULL)
    return p;

  while (1)
    {
      /* Try to print in the allocated space. */
      va_list aq;
      va_copy(aq, ap);      
#ifdef WIN32
      n = _vsnprintf (p, size, fmt, aq);
#else
      n = vsnprintf (p, size, fmt, aq);
#endif
      va_end(aq);
      /* If that worked, return the string. */
      if (n > -1 && n < size)
	{ return p; }
      /* Else try again with more space. */
      if (n > -1)    /* glibc 2.1 */
	size = n+1; /* precisely what is needed */
      else           /* glibc 2.0 */
	size *= 2;  /* twice the old size */

      {
        char *np = realloc (p, size);
      
        if (!np) { free(p); return 0; }
        p = np;
      }
    }
}
Пример #16
0
bool InputController_vinit(InputController * self, InputMap * inputMap, va_list args) {
	va_list argsCopy;
	
	call_super(init, self);
	self->dispose = InputController_dispose;
	self->keyDown = InputController_keyDown;
	self->keyUp = InputController_keyUp;
	self->keyModifiersChanged = InputController_keyModifiersChanged;
	self->gamepadButtonDown = InputController_gamepadButtonDown;
	self->gamepadButtonUp = InputController_gamepadButtonUp;
	self->gamepadAxisMoved = InputController_gamepadAxisMoved;
	self->triggerAction = InputController_triggerAction;
	self->releaseAction = InputController_releaseAction;
	self->reset = InputController_reset;
	
	self->eventDispatcher = EventDispatcher_create(self);
	self->inputMap = inputMap;
	self->lastModifiers = 0x0;
	self->actionCount = 0;
	self->actions = NULL;
	
	va_copy(argsCopy, args);
	while (va_arg(argsCopy, const char *) != NULL) {
		self->actionCount++;
	}
	va_end(argsCopy);
	
	if (self->actionCount > 0) {
		unsigned int actionIndex;
		
		self->actions = malloc(sizeof(struct InputController_action) * self->actionCount);
		for (actionIndex = 0; actionIndex < self->actionCount; actionIndex++) {
			self->actions[actionIndex].actionID = Atom_fromString(va_arg(args, const char *));
			self->actions[actionIndex].triggered = false;
		}
	}
Пример #17
0
static int
int_vasprintf (char **result, const char *format, va_list args)
{
  const char *p = format;
  /* Add one to make sure that it is never zero, which might cause malloc
     to return NULL.  */
  int total_width = strlen (format) + 1;
  va_list ap;

#ifdef va_copy
  va_copy (ap, args);
#else
  memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list));
#endif

  while (*p != '\0')
    {
      if (*p++ == '%')
        {
          while (strchr ("-+ #0", *p))
            ++p;
          if (*p == '*')
            {
              ++p;
              total_width += abs (va_arg (ap, int));
            }
          else
            total_width += strtoul (p, (char **) &p, 10);
          if (*p == '.')
            {
              ++p;
              if (*p == '*')
                {
                  ++p;
                  total_width += abs (va_arg (ap, int));
                }
Пример #18
0
static void
shader_perf_log_mesa(void *data, const char *fmt, ...)
{
   struct brw_context *brw = (struct brw_context *)data;

   va_list args;
   va_start(args, fmt);

   if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
      va_list args_copy;
      va_copy(args_copy, args);
      vfprintf(stderr, fmt, args_copy);
      va_end(args_copy);
   }

   if (brw->perf_debug) {
      GLuint msg_id = 0;
      _mesa_gl_vdebug(&brw->ctx, &msg_id,
                      MESA_DEBUG_SOURCE_SHADER_COMPILER,
                      MESA_DEBUG_TYPE_PERFORMANCE,
                      MESA_DEBUG_SEVERITY_MEDIUM, fmt, args);
   }
   va_end(args);
}
Пример #19
0
ats_ptr_type
atspre_vsprintf_size
(
  ats_size_type bsz
, const ats_ptr_type fmt, ats_ref_type ap0
) {
  int n ; char *res ; va_list ap ;
//
  while (1) {
    res = ATS_MALLOC(bsz) ;
    va_copy(ap, *(va_list*)ap0) ;
    n = vsnprintf(res, bsz, (char*)fmt, ap) ;
    va_end(ap) ;
    if (n >= 0) {
      if (n < bsz) return res ;
      bsz = n+1 ; ATS_FREE(res) ; continue ;
    } else {
      return ((ats_ptr_type)0) ;
    } // end of [if]
  } // end of [while]
//
  return (ats_ptr_type)0 ; // deadcode
//
} /* end of [atspre_vsprintf_size] */
Пример #20
0
// copypasta to fix an OPENBSDBUG
int file_vprintf(RMagic *ms, const char *fmt, va_list ap) {
	va_list ap2;
	int len;
	char cbuf[4096];
	char *buf, *newstr;
	int buflen;// = strlen (buf);

	va_copy (ap2, ap);
	len = vsnprintf (cbuf, sizeof (cbuf), fmt, ap2);
	va_end (ap2);
	if (len < 0)
		goto out;
	cbuf[len] = 0;
	buf = strdup (cbuf);

	buflen = len;
	if (ms->o.buf != NULL) {
		int obuflen = strlen (ms->o.buf);
		len = obuflen+buflen+1;
		newstr = malloc (len+1);
		memset (newstr, 0, len+1); // XXX: unnecessary?
		newstr[len] = 0;
		memcpy (newstr, ms->o.buf, obuflen);
		memcpy (newstr+obuflen, buf, buflen);
		free (buf);
		if (len < 0)
			goto out;
		free (ms->o.buf);
		buf = newstr;
	}
	ms->o.buf = buf;
	return 0;
out:
	file_error (ms, errno, "vasprintf failed");
	return -1;
}
Пример #21
0
int __gcov_execl(const char *path, char *arg, ...)
{
    va_list ap, aq;
    unsigned i, length;
    char **args;

    va_start(ap, arg);
    va_copy(aq, ap);

    length = 2;
    while (va_arg(ap, char *))
             length++;

    va_end(ap);

    args = (char **) xmalloc(length * sizeof(void *));
    args[0] = arg;
    for (i = 1; i < length; i++)
        args[i] = va_arg(aq, char *);

    va_end(aq);

    return execv(path, args);
}
Пример #22
0
static int z_vprintf (hpgs_z_ostream_stream *stream, const char *fmt, va_list ap)
{
  int n;
  size_t size=1024;
  char *buf;

  while (1)
    {
      if (stream->errflg)
        return EOF;

      buf = hpgs_alloca(size);

      /* Try to print in the allocated space. */
      va_list aq;
      va_copy(aq, ap);
#ifdef WIN32
      n = _vsnprintf (buf, size, fmt, aq);
#else
      n = vsnprintf (buf, size, fmt, aq);
#endif
      va_end(aq);

      /* If that worked, push the string. */
      if (n > -1 && n < size)
	return z_write(buf,n,1,stream) ? n : -1;
 
      /* Else try again with more space. */
      if (n < 0)
        size *= 2;
      else
        size = n+1;
    }

  return 0;
}
Пример #23
0
/** Add a module failure message VALUE_PAIR to the request
 */
void vmodule_failure_msg(REQUEST *request, char const *fmt, va_list ap)
{
	char *p;
	VALUE_PAIR *vp;
	va_list aq;

	if (!fmt || !request->packet) {
		return;
	}

	vp = paircreate(request->packet, PW_MODULE_FAILURE_MESSAGE, 0);
	if (!vp) {
		return;
	}

	/*
	 *  If we don't copy the original ap we get a segfault from vasprintf. This is apparently
	 *  due to ap sometimes being implemented with a stack offset which is invalidated if
	 *  ap is passed into another function. See here:
	 *  http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
	 *
	 *  I don't buy that explanation, but doing a va_copy here does prevent SEGVs seen when
	 *  running unit tests which generate errors under CI.
	 */
	va_copy(aq, ap);
	p = talloc_vasprintf(vp, fmt, aq);
	talloc_set_type(p, char);
	va_end(aq);
	if (request->module && *request->module) {
		pairsprintf(vp, "%s: %s", request->module, p);
	} else {
		pairsprintf(vp, "%s", p);
	}
	talloc_free(p);
	pairadd(&request->packet->vps, vp);
}
Пример #24
0
void bb_verror_msg(const char *s, va_list p, const char* strerr)
{
	/* va_copy is used because it is not portable
	 * to use va_list p twice */
	va_list p2;
	va_copy(p2, p);

	if (!s) /* nomsg[_and_die] uses NULL fmt */
		s = ""; /* some libc don't like printf(NULL) */

	if (logmode & LOGMODE_STDIO) {
		fflush(stdout);
		fprintf(stderr, "%s: ", applet_name);
		vfprintf(stderr, s, p);
		if (!strerr)
			fputs(msg_eol, stderr);
		else
			fprintf(stderr, "%s%s%s",
					s[0] ? ": " : "",
					strerr, msg_eol);
	}
	if (ENABLE_FEATURE_SYSLOG && (logmode & LOGMODE_SYSLOG)) {
		if (!strerr)
			vsyslog(LOG_ERR, s, p2);
		else  {
			char *msg;
			if (vasprintf(&msg, s, p2) < 0) {
				fprintf(stderr, "%s: %s\n", applet_name, bb_msg_memory_exhausted);
				xfunc_die();
			}
			syslog(LOG_ERR, "%s: %s", msg, strerr);
			free(msg);
		}
	}
	va_end(p2);
}
Пример #25
0
int tims_error(ClientSession_T * session, const char *formatstring, ...)
{
	va_list ap, cp;
	char *s;

	if (session->error_count >= MAX_ERRORS) {
		ci_write(session->ci, "BYE \"Too many errors, closing connection.\"\r\n");
		session->SessionResult = 2;	/* possible flood */
		return -3;
	}

	va_start(ap, formatstring);
	va_copy(cp, ap);
	s = g_strdup_vprintf(formatstring, cp);
	va_end(cp);
	va_end(ap);

	ci_write(session->ci, s);
	g_free(s);

	TRACE(TRACE_DEBUG, "an invalid command was issued");
	session->error_count++;
	return 1;
}
SimpleString VStringFromFormat(const char* format, va_list args)
{
	va_list argsCopy;
	va_copy(argsCopy, args);
	enum
	{
		sizeOfdefaultBuffer = 100
	};
	char defaultBuffer[sizeOfdefaultBuffer];
	SimpleString resultString;

	int size = PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
	if (size < sizeOfdefaultBuffer) {
		resultString = SimpleString(defaultBuffer);
	}
	else {
		char* newBuffer = SimpleString::allocStringBuffer(size + 1);
		PlatformSpecificVSNprintf(newBuffer, size + 1, format, argsCopy);
		resultString = SimpleString(newBuffer);

		SimpleString::deallocStringBuffer(newBuffer);
	}
	return resultString;
}
std::string string_vprintf(const char *fmt, va_list args) {
  size_t size = 500;
  char *buf = (char *)malloc(size);
  // grow the buffer size until the output is no longer truncated
  while (1) {
    va_list args_copy;
#if defined(_WIN32)
    args_copy = args;
    size_t nwritten = _vsnprintf(buf, size-1, fmt, args_copy);
#else
    va_copy(args_copy, args);
    size_t nwritten = vsnprintf(buf, size-1, fmt, args_copy);
#endif
    // Some c libraries return -1 for overflow, some return a number larger than size-1
    if (nwritten < size-2) {
      buf[nwritten+1] = 0;
      std::string ret(buf);
      free(buf);
      return ret;
    }
    size *= 2;
    buf = (char *)realloc(buf, size);
  }
}
Пример #28
0
void oqueue_pushvf(OQueue *q, const char *fmt, va_list ap)
{
    char *str;
    ssize_t len = 100;
    int n;
    va_list ap_copy;

    str = calloc(len, sizeof(char));

    while (1) {
        va_copy(ap_copy, ap);
        n = vsnprintf(str, len, fmt, ap_copy);

        if (n > -1 && n < len) {
            break;
        }

        len *= 2;
        str = realloc(str, len * sizeof(char));
    }

    oqueue_push(q, str);
    free(str);
}
Пример #29
0
int BufferVPrintf(Buffer *buffer, const char *format, va_list ap)
{
    va_list aq;
    va_copy(aq, ap);
    if (!buffer || !format)
    {
        return -1;
    }
    int printed = 0;
    /*
     * We don't know how big of a buffer we will need. It might be that we have enough space
     * or it might be that we don't have enough space. Unfortunately, we cannot reiterate over
     * a va_list, so our only solution is to tell the caller to retry the call. We signal this
     * by returning zero. Before doing that we increase the buffer to a suitable size.
     * The tricky part is the implicit sharing and the reference counting, if we are not shared then
     * everything is easy, however if we are shared then we need a different strategy.
     */
    if (RefCountIsShared(buffer->ref_count))
    {
        char *new_buffer = NULL;
        new_buffer = (char *)xmalloc(buffer->capacity);
        RefCount *ref_count = buffer->ref_count;
        buffer->ref_count = NULL;
        RefCountNew(&buffer->ref_count);
        RefCountAttach(buffer->ref_count, buffer);
        RefCountDetach(ref_count, buffer);
        /*
         * Ok, now we need to take care of the buffer.
         */
        unsigned int i = 0;
        unsigned int used = 0;
        for (i = 0; i < buffer->used; ++i)
        {
            new_buffer[i] = buffer->buffer[i];
            if ((buffer->buffer[i] == '\0') && (buffer->mode == BUFFER_BEHAVIOR_CSTRING))
            {
                break;
            }
            ++used;
        }
        buffer->buffer = new_buffer;
        buffer->used = used;
    }
    printed = vsnprintf(buffer->buffer, buffer->capacity, format, aq);
    if (printed >= buffer->capacity)
    {
        /*
         * Allocate a larger buffer and retry.
         * We use the copy of the list.
         */
        if (printed > buffer->memory_cap)
        {
            /*
             * We would go over the memory_cap limit.
             */
            return -1;
        }
        unsigned int required_blocks = (printed / DEFAULT_BUFFER_SIZE) + 1;
        buffer->buffer = (char *)xrealloc(buffer->buffer, required_blocks * DEFAULT_BUFFER_SIZE);
        buffer->capacity = required_blocks * DEFAULT_BUFFER_SIZE;
        buffer->used = 0;
        printed = vsnprintf(buffer->buffer, buffer->capacity, format, ap);
        buffer->used = printed;
    }
    else
    {
        buffer->used = printed;
    }
    return printed;
}
Пример #30
0
/*******************************************************************************
Function:
  PAL_vsnprintf (silent version)
  for more details, see PAL_vsnprintf in printf.c
*******************************************************************************/
INT Silent_PAL_vsnprintf(LPSTR Buffer, INT Count, LPCSTR Format, va_list aparg)
{
    BOOL BufferRanOut = FALSE;
    CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */
    LPSTR BufferPtr = Buffer;
    LPCSTR Fmt = Format;
    LPWSTR TempWStr;
    CHAR TempStr[MAX_STR_LEN+1];
    WCHAR TempWChar;
    INT Flags;
    INT Width;
    INT Precision;
    INT Prefix;
    INT Type;
    INT Length;
    INT TempInt;
    int wctombResult;
    va_list ap;
    
    va_copy(ap, aparg);

    while (*Fmt)
    {
        if ((BufferPtr - Buffer) >= Count)
        {
            BufferRanOut = TRUE;
            break;
        }
        else if(*Fmt == '%' &&
                TRUE == Silent_ExtractFormatA(&Fmt, TempBuff, &Flags,
                                                &Width, &Precision,
                                                &Prefix, &Type))
        {
            if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_STRING)
            {
                if (PRECISION_STAR == Precision)
                {
                    Precision = va_arg(ap, INT);
                }
                else if (PRECISION_INVALID == Precision)
                {
                    /* both a '*' and a number, ignore, but remove arg */
                    TempInt = va_arg(ap, INT); /* value not used */
                }
                TempWStr = va_arg(ap, LPWSTR);
                Length = Silent_WideCharToMultiByte(TempWStr, -1, 0, 0);
                if (!Length)
                {
                    va_end(ap);
                    return -1;
                }

                /* clip string output to MAX_STR_LEN characters */
                if(-1 == Precision)
                {
                    Precision = MAX_STR_LEN;
                }

                if (PRECISION_DOT == Precision)
                {
                    /* copy nothing */
                    *TempStr = 0;
                    Length = 0;
                }
                else if (Precision > 0 && Precision < Length - 1)
                {
                    Length = Silent_WideCharToMultiByte(TempWStr, Precision, 
                                                        TempStr, Length);
                    if (!Length)
                    {
                        va_end(ap);
                        return -1;
                    }
                    TempStr[Length] = 0;
                    Length = Precision;
                }
                /* copy everything */
                else
                {
                    wctombResult = Silent_WideCharToMultiByte(TempWStr, -1,
                                                              TempStr, Length);
                    if (!wctombResult)
                    {
                        PAL_free(TempStr);
                        va_end(ap);
                        return -1;
                    }
                    --Length; /* exclude null char */
                }

                /* do the padding (if needed)*/
                BufferRanOut = !Internal_AddPaddingA(&BufferPtr,
                                                   Count - (BufferPtr - Buffer),
                                                   TempStr,
                                                   Width - Length,
                                                   Flags);
            }
            else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR)
            {
                CHAR TempBuffer[4];
                if (PRECISION_STAR == Precision ||
                    PRECISION_INVALID == Precision)
                {
                    /* ignore (because it's a char), and remove arg */
                    TempInt = va_arg(ap, INT); /* value not used */
                }

                TempWChar = va_arg(ap, int);
                Length = Silent_WideCharToMultiByte(&TempWChar, 1, TempBuffer, 4);
                if (!Length)
                {
                    va_end(ap);
                    return -1;
                }
                TempBuffer[Length] = 0;

                /* do the padding (if needed)*/
                BufferRanOut = !Internal_AddPaddingA(&BufferPtr,
                                                   Count - (BufferPtr - Buffer),
                                                   TempBuffer,
                                                   Width - Length,
                                                   Flags);

            }
            /* this places the number of bytes written to the buffer in the
               next arg */
            else if (Type == PFF_TYPE_N)
            {
                if (PRECISION_STAR == Precision)
                {
                    Precision = va_arg(ap, INT);
                }
                if (Prefix == PFF_PREFIX_SHORT)
                {
                    *(va_arg(ap, short *)) = BufferPtr - Buffer;
                }
                else
                {
                    *(va_arg(ap, LPLONG)) = BufferPtr - Buffer;
                }
            }
            /* types that sprintf can handle */
            else
            {
                size_t TempCount = Count - (BufferPtr - Buffer);

                TempInt = 0;
                /* %h (short) doesn't seem to be handled properly by local sprintf,
                   so lets do the truncation ourselves.  (ptr -> int -> short to avoid
                   warnings */
                if (Type == PFF_TYPE_P && Prefix == PFF_PREFIX_SHORT)
                {
                    long trunc1;
                    short trunc2;

                    trunc1 = va_arg(ap, LONG);
                    trunc2 = (short)trunc1;

                    TempInt = snprintf(BufferPtr, TempCount, TempBuff, trunc2);
                }
                else
                {
                    /* limit string output (%s) to 300 characters */
                    if(TempBuff[0]=='%' && TempBuff[1]=='s')
                    {
                        if (strcpy_s(TempBuff, sizeof(TempBuff), "%.300s") != SAFECRT_SUCCESS)
                        {
                            va_end(ap);
                            return -1;
                        }
                    }                                     
                    va_list apcopy;
                    va_copy(apcopy, ap);
                    TempInt = PAL__vsnprintf(BufferPtr, TempCount, TempBuff, apcopy);
                    va_end(apcopy);
                    PAL_printf_arg_remover(&ap, Width, Precision, Type, Prefix);
                }

                if (TempInt < 0 || static_cast<size_t>(TempInt) >= TempCount) /* buffer not long enough */
                {
                    BufferPtr += TempCount;
                    BufferRanOut = TRUE;
                }
                else
                {
                    BufferPtr += TempInt;
                }
            }
        }