asprintf.c

Go to the documentation of this file.
00001 #define _GNU_SOURCE /* enable asprintf */
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <stdarg.h>
00005 #include <unistd.h>
00006 #include <assert.h>
00007 #include <grass/gis.h>
00008 
00009 #ifdef __MINGW32__
00010 #include <windows.h>
00011 #endif /* __MINGW32__ */
00012 
00013 /* Warning: Temporarily the G_asprintf macro cannot be used 
00014 * see explanation in gisdefs.h */
00015 
00016 /*
00017  * Eric G. Miller egm2@jps.net 
00018  * Thu, 2 May 2002 17:51:54 -0700 
00019  * 
00020  * 
00021  * I've got a sort of cheat for asprintf. We can't use vsnprintf for the
00022  * same reason we can't use snprintf ;-)  Comments welcome.
00023  */
00024 
00025 #ifndef G_asprintf
00026 
00027 /* We cheat by printing to a tempfile via vfprintf and then reading it
00028  * back in.  Not the most efficient way, probably.
00029  */
00030 
00046 #ifdef HAVE_ASPRINTF 
00047 
00048 int G_asprintf(char **out, const char *fmt, ...)
00049 {
00050     va_list ap;
00051     int count;
00052 
00053     va_start(ap, fmt);
00054     count = vasprintf (out, fmt, ap);
00055     va_end(ap);
00056 
00057     return count;
00058 }
00059 
00060 #else
00061 int G_asprintf(char **out, const char *fmt, ...)
00062 {
00063     va_list ap;
00064     int ret_status = EOF;
00065     char dir_name[2001];
00066     char file_name[2000];
00067     FILE *fp = NULL;
00068     char *work = NULL;
00069 
00070     assert(out != NULL && fmt != NULL);
00071 
00072     va_start(ap, fmt);
00073 
00074     /* Warning: tmpfile() does not work well on Windows (MinGW)
00075      *          if user does not have write access on the drive where 
00076      *          working dir is? */
00077 #ifdef __MINGW32__
00078     /* file_name = G_tempfile(); */
00079     GetTempPath ( 2000, dir_name );
00080     GetTempFileName ( dir_name, "asprintf", 0, file_name );
00081     fp = fopen ( file_name, "w+" );
00082 #else
00083     fp = tmpfile(); 
00084 #endif /* __MINGW32__ */
00085 
00086     if ( fp ) {
00087         int count;
00088 
00089         count = vfprintf(fp, fmt, ap);
00090         if (count >= 0) {
00091             work = G_calloc(count + 1, sizeof(char));
00092             if (work != NULL) {
00093                 rewind(fp);
00094                 ret_status = fread(work, sizeof(char), count, fp);
00095                 if (ret_status != count) {
00096                     ret_status = EOF;
00097                     G_free(work);
00098                     work = NULL;
00099                 }
00100             }
00101         }
00102         fclose(fp);
00103 #ifdef __MINGW32__
00104         unlink ( file_name );
00105 #endif /* __MINGW32__ */
00106     }
00107     va_end(ap);
00108     *out = work;
00109 
00110     return ret_status;
00111 }
00112 #endif
00113 
00114 #endif

Generated on Wed Dec 19 14:59:05 2007 for GRASS by  doxygen 1.5.4