/*------------------------------------------------------------------------- * Function: h5tools_str_append * * Purpose: Formats variable arguments according to printf() format * string and appends the result to variable length string STR. * * Return: Success: Pointer to buffer containing result. * * Failure: NULL * * Programmer: Robb Matzke * Monday, April 26, 1999 * * Modifications: * * Major change: need to check results of vsnprintf to * handle errors, empty format, and overflows. * * Programmer: REMcG Matzke * June 16, 2004 * *------------------------------------------------------------------------- */ char * h5tools_str_append(h5tools_str_t *str/*in,out*/, const char *fmt, ...) { va_list ap; /* Make sure we have some memory into which to print */ if (!str->s || str->nalloc <= 0) { str->nalloc = STR_INIT_LEN; str->s = malloc(str->nalloc); assert(str->s); str->s[0] = '\0'; str->len = 0; } if (strlen(fmt) == 0) { /* nothing to print */ return str->s; } /* Format the arguments and append to the value already in `str' */ while (1) { /* How many bytes available for new value, counting the new NUL */ size_t avail = str->nalloc - str->len; int nchars = -1; va_start(ap, fmt); nchars = HDvsnprintf(str->s + str->len, avail, fmt, ap); va_end(ap); if (nchars < 0) { /* failure, such as bad format */ return NULL; } if ((size_t) nchars >= avail || (0 == nchars && (strcmp(fmt, "%s")))) { /* Truncation return value as documented by C99, or zero return value with either of the * following conditions, each of which indicates that the proper C99 return value probably * should have been positive when the format string is * something other than "%s" * Alocate at least twice as much space and try again. */ size_t newsize = MAX(str->len + nchars + 1, 2 * str->nalloc); assert(newsize > str->nalloc); /*overflow*/ str->s = realloc(str->s, newsize); assert(str->s); str->nalloc = newsize; } else { /* Success */ str->len += nchars; break; } } return str->s; }
/*------------------------------------------------------------------------- * Function: parallel_print * * Purpose: wrapper for printf for use in parallel mode. * * Programmer: Leon Arber * * Date: December 1, 2004 * *------------------------------------------------------------------------- */ void parallel_print(const char* format, ...) { int bytes_written; va_list ap; HDva_start(ap, format); if(!g_Parallel) HDvprintf(format, ap); else { if(overflow_file == NULL) /*no overflow has occurred yet */ { #if 0 printf("calling HDvsnprintf: OUTBUFF_SIZE=%ld, outBuffOffset=%ld, ", (long)OUTBUFF_SIZE, (long)outBuffOffset); #endif bytes_written = HDvsnprintf(outBuff+outBuffOffset, OUTBUFF_SIZE-outBuffOffset, format, ap); #if 0 printf("bytes_written=%ld\n", (long)bytes_written); #endif HDva_end(ap); HDva_start(ap, format); #if 0 printf("Result: bytes_written=%ld, OUTBUFF_SIZE-outBuffOffset=%ld\n", (long)bytes_written, (long)OUTBUFF_SIZE-outBuffOffset); #endif if ((bytes_written < 0) || #ifdef H5_VSNPRINTF_WORKS (bytes_written >= (OUTBUFF_SIZE-outBuffOffset)) #else ((bytes_written+1) == (OUTBUFF_SIZE-outBuffOffset)) #endif ) { /* Terminate the outbuff at the end of the previous output */ outBuff[outBuffOffset] = '\0'; overflow_file = HDtmpfile(); if(overflow_file == NULL) HDfprintf(rawerrorstream, "warning: could not create overflow file. Output may be truncated.\n"); else bytes_written = HDvfprintf(overflow_file, format, ap); } else outBuffOffset += bytes_written; } else bytes_written = HDvfprintf(overflow_file, format, ap); } HDva_end(ap); }