Implement vasprintf and asprintf for platforms lacking them.

This commit is contained in:
Pierre-Antoine Lacaze
2012-01-09 09:44:58 +01:00
parent 86d88e9773
commit 002f27a30f
3 changed files with 35 additions and 40 deletions

View File

@@ -2299,16 +2299,6 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
m->module->getFunction("__do_assert_varying");
Assert(assertFunc != NULL);
#ifdef ISPC_IS_WINDOWS
char errorString[2048];
if (sprintf_s(errorString, sizeof(errorString),
"%s(%d): Assertion failed: %s\n", pos.name,
pos.first_line, message.c_str()) == -1) {
Error(pos, "Fatal error in sprintf_s() call when generating assert "
"string.");
return;
}
#else
char *errorString;
if (asprintf(&errorString, "%s:%d:%d: Assertion failed: %s\n",
pos.name, pos.first_line, pos.first_column,
@@ -2317,7 +2307,6 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
"unable to allocate memory!");
return;
}
#endif
std::vector<llvm::Value *> args;
args.push_back(ctx->GetStringPtr(errorString));
@@ -2325,9 +2314,7 @@ AssertStmt::EmitCode(FunctionEmitContext *ctx) const {
args.push_back(ctx->GetFullMask());
ctx->CallInst(assertFunc, NULL, args, "");
#ifndef ISPC_IS_WINDOWS
free(errorString);
#endif // !ISPC_IS_WINDOWS
}

View File

@@ -187,6 +187,32 @@ lPrintWithWordBreaks(const char *buf, int columnWidth, FILE *out) {
}
#ifdef ISPC_IS_WINDOWS
// we cover for the lack vasprintf and asprintf on windows (also covers mingw)
int
vasprintf(char **sptr, const char *fmt, va_list argv)
{
int wanted = vsnprintf(*sptr = NULL, 0, fmt, argv);
if((wanted < 0) || ((*sptr = (char*)malloc( 1 + wanted )) == NULL))
return -1;
return vsprintf(*sptr, fmt, argv);
}
int
asprintf(char **sptr, const char *fmt, ...)
{
int retval;
va_list argv;
va_start(argv, fmt);
retval = vasprintf(sptr, fmt, argv);
va_end(argv);
return retval;
}
#endif
/** Helper function for Error(), Warning(), etc.
@param type The type of message being printed (e.g. "Warning")
@@ -197,30 +223,6 @@ lPrintWithWordBreaks(const char *buf, int columnWidth, FILE *out) {
*/
static void
lPrint(const char *type, SourcePos p, const char *fmt, va_list args) {
#ifdef ISPC_IS_WINDOWS
char errorBuf[2048], formattedBuf[2048];
if (vsnprintf_s(errorBuf, sizeof(errorBuf), _TRUNCATE, fmt, args) == -1) {
fprintf(stderr, "vsnprintf_s() error!\n");
return;
}
if (p.first_line == 0) {
// We don't have a valid SourcePos, so create a message without it
if (sprintf_s(formattedBuf, sizeof(formattedBuf), "%s: %s\n",
type, errorBuf) == -1) {
fprintf(stderr, "vsnprintf_s() error!\n");
exit(1);
}
}
else {
// Create an error message that includes the file and line number
if (sprintf_s(formattedBuf, sizeof(formattedBuf), "%s(%d): %s: %s\n",
p.name, p.first_line, type, errorBuf) == -1) {
fprintf(stderr, "vsnprintf_s() error!\n");
exit(1);
}
}
#else
char *errorBuf, *formattedBuf;
if (vasprintf(&errorBuf, fmt, args) == -1) {
fprintf(stderr, "vasprintf() unable to allocate memory!\n");
@@ -241,7 +243,6 @@ lPrint(const char *type, SourcePos p, const char *fmt, va_list args) {
exit(1);
}
}
#endif
// Now that we've done all that work, see if we've already printed the
// exact same error message. If so, return, so we don't redundantly
@@ -254,10 +255,8 @@ lPrint(const char *type, SourcePos p, const char *fmt, va_list args) {
lPrintWithWordBreaks(formattedBuf, lTerminalWidth(), stderr);
lPrintFileLineContext(p);
#ifndef ISPC_IS_WINDOWS
free(errorBuf);
free(formattedBuf);
#endif // !ISPC_IS_WINDOWS
}

9
util.h
View File

@@ -40,6 +40,9 @@
#define ISPC_UTIL_H
#include "ispc.h"
#ifdef ISPC_IS_WINDOWS
#include <stdarg.h>
#endif
struct SourcePos;
@@ -62,6 +65,12 @@ inline uint32_t RoundUpPow2(uint32_t v) {
#define PRINTF_FUNC
#endif // __GNUG__
// for cross-platform compatibility
#ifdef ISPC_IS_WINDOWS
int vasprintf(char **sptr, const char *fmt, va_list argv);
int asprintf(char **sptr, const char *fmt, ...);
#endif
/** Prints a debugging message. These messages are only printed if
g->debugPrint is \c true. In addition to a program source code
position to associate with the message, a printf()-style format string