/* 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; }
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"); }
/* 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; }
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); }
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; }
/* 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; }
//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); }
/** * 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; }
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; }
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; }
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); }
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; }
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); }
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); }
/*! 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; } } }
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; } }
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)); }
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); }
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] */
// 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; }
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); }
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; }
/** 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); }
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); }
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); } }
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); }
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; }
/******************************************************************************* 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; } } }