#define _GNU_SOURCE /* enable asprintf */ #include #include #include #include #include #include #ifdef __MINGW32__ #include #endif /* __MINGW32__ */ /* Warning: Temporarily the G_asprintf macro cannot be used * see explanation in gisdefs.h */ /* * Eric G. Miller egm2@jps.net * Thu, 2 May 2002 17:51:54 -0700 * * * I've got a sort of cheat for asprintf. We can't use vsnprintf for the * same reason we can't use snprintf ;-) Comments welcome. */ #ifndef G_asprintf /* We cheat by printing to a tempfile via vfprintf and then reading it * back in. Not the most efficient way, probably. */ /*! * \brief safe replacement for asprintf() * * Allocate a string large enough to hold the new output, * including the terminating NUL, and return a pointer to * the first parameter. * The pointer should be passed to G_free() to release the * allocated storage when it is no longer needed. * Returns number of bytes written. * * \param char **out * \param char *fmt * \return int */ #ifdef HAVE_ASPRINTF int G_asprintf(char **out, const char *fmt, ...) { va_list ap; int count; va_start(ap, fmt); count = vasprintf (out, fmt, ap); va_end(ap); return count; } #else int G_asprintf(char **out, const char *fmt, ...) { va_list ap; int ret_status = EOF; char dir_name[2001]; char file_name[2000]; FILE *fp = NULL; char *work = NULL; assert(out != NULL && fmt != NULL); va_start(ap, fmt); /* Warning: tmpfile() does not work well on Windows (MinGW) * if user does not have write access on the drive where * working dir is? */ #ifdef __MINGW32__ /* file_name = G_tempfile(); */ GetTempPath ( 2000, dir_name ); GetTempFileName ( dir_name, "asprintf", 0, file_name ); fp = fopen ( file_name, "w+" ); #else fp = tmpfile(); #endif /* __MINGW32__ */ if ( fp ) { int count; count = vfprintf(fp, fmt, ap); if (count >= 0) { work = G_calloc(count + 1, sizeof(char)); if (work != NULL) { rewind(fp); ret_status = fread(work, sizeof(char), count, fp); if (ret_status != count) { ret_status = EOF; G_free(work); work = NULL; } } } fclose(fp); #ifdef __MINGW32__ unlink ( file_name ); #endif /* __MINGW32__ */ } va_end(ap); *out = work; return ret_status; } #endif #endif