Renaming asprintf.c to printf.c, adding printf.h
This commit was SVN r2016.
Этот коммит содержится в:
родитель
9fd6f81d35
Коммит
ed9969f55f
278
src/util/printf.c
Обычный файл
278
src/util/printf.c
Обычный файл
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Buffer safe printf functions for portability to archaic platforms.
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "util/printf.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* Make a good guess about how long a printf-style varargs formatted
|
||||
* string will be once all the % escapes are filled in. We don't
|
||||
* handle every % escape here, but we handle enough, and then add a
|
||||
* fudge factor in at the end.
|
||||
*/
|
||||
static int guess_strlen(const char *fmt, va_list ap)
|
||||
{
|
||||
char *sarg;
|
||||
double darg;
|
||||
float farg;
|
||||
int i;
|
||||
int iarg;
|
||||
int len;
|
||||
long larg;
|
||||
|
||||
/* Start off with a fudge factor of 128 to handle the % escapes that
|
||||
we aren't calculating here */
|
||||
|
||||
len = strlen(fmt) + 128;
|
||||
for (i = 0; i < strlen(fmt); ++i) {
|
||||
if ('%' == fmt[i] && i + 1 < strlen(fmt)
|
||||
&& '%' != fmt[i + 1]) {
|
||||
++i;
|
||||
switch (fmt[i]) {
|
||||
case 's':
|
||||
sarg = va_arg(ap, char *);
|
||||
|
||||
/* If there's an arg, get the strlen, otherwise we'll
|
||||
* use (null) */
|
||||
|
||||
if (NULL != sarg)
|
||||
len += strlen(sarg);
|
||||
else
|
||||
len += 5;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
iarg = va_arg(ap, int);
|
||||
/* Alloc for minus sign */
|
||||
if (iarg < 0)
|
||||
++len;
|
||||
/* Now get the log10 */
|
||||
do {
|
||||
++len;
|
||||
iarg /= 10;
|
||||
} while (0 != iarg);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
iarg = va_arg(ap, int);
|
||||
/* Now get the log16 */
|
||||
do {
|
||||
++len;
|
||||
iarg /= 16;
|
||||
} while (0 != iarg);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
farg = va_arg(ap, int);
|
||||
/* Alloc for minus sign */
|
||||
if (farg < 0) {
|
||||
++len;
|
||||
farg = -farg;
|
||||
}
|
||||
/* Alloc for 3 decimal places + '.' */
|
||||
len += 4;
|
||||
/* Now get the log10 */
|
||||
do {
|
||||
++len;
|
||||
farg /= 10.0;
|
||||
} while (0 != farg);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
darg = va_arg(ap, int);
|
||||
/* Alloc for minus sign */
|
||||
if (darg < 0) {
|
||||
++len;
|
||||
darg = -darg;
|
||||
}
|
||||
/* Alloc for 3 decimal places + '.' */
|
||||
len += 4;
|
||||
/* Now get the log10 */
|
||||
do {
|
||||
++len;
|
||||
darg /= 10.0;
|
||||
} while (0 != darg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
/* Get %ld %lx %lX %lf */
|
||||
if (i + 1 < strlen(fmt)) {
|
||||
++i;
|
||||
switch (fmt[i]) {
|
||||
case 'x':
|
||||
case 'X':
|
||||
larg = va_arg(ap, int);
|
||||
/* Now get the log16 */
|
||||
do {
|
||||
++len;
|
||||
larg /= 16;
|
||||
} while (0 != larg);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
darg = va_arg(ap, int);
|
||||
/* Alloc for minus sign */
|
||||
if (darg < 0) {
|
||||
++len;
|
||||
darg = -darg;
|
||||
}
|
||||
/* Alloc for 3 decimal places + '.' */
|
||||
len += 4;
|
||||
/* Now get the log10 */
|
||||
do {
|
||||
++len;
|
||||
darg /= 10.0;
|
||||
} while (0 != darg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
default:
|
||||
larg = va_arg(ap, int);
|
||||
/* Now get the log10 */
|
||||
do {
|
||||
++len;
|
||||
larg /= 10;
|
||||
} while (0 != larg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
int ompi_asprintf(char **ptr, const char *fmt, ...)
|
||||
{
|
||||
int length;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
length = ompi_vasprintf(ptr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
int ompi_vasprintf(char **ptr, const char *fmt, va_list ap)
|
||||
{
|
||||
int length;
|
||||
|
||||
/* guess the size */
|
||||
length = guess_strlen(fmt, ap);
|
||||
|
||||
/* allocate a buffer */
|
||||
*ptr = (char *) malloc((size_t) length + 1);
|
||||
if (NULL == *ptr) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fill the buffer */
|
||||
length = vsprintf(*ptr, fmt, ap);
|
||||
|
||||
/* realloc */
|
||||
*ptr = realloc(*ptr, (size_t) length + 1);
|
||||
if (NULL == *ptr) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
int ompi_snprintf(char *str, size_t size, const char *fmt, ...)
|
||||
{
|
||||
int length;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
length = ompi_vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
int ompi_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
|
||||
{
|
||||
int length;
|
||||
char *buf;
|
||||
|
||||
length = ompi_vasprintf(&buf, fmt, ap);
|
||||
if (length < 0) {
|
||||
return length;
|
||||
}
|
||||
|
||||
/* return the length when given a null buffer (C99) */
|
||||
if (str) {
|
||||
if ((size_t) length < size) {
|
||||
strcpy(str, buf);
|
||||
} else {
|
||||
memcpy(str, buf, size - 1);
|
||||
str[size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char a[10];
|
||||
char b[173];
|
||||
char *s;
|
||||
int length;
|
||||
|
||||
puts("test for NULL buffer in snprintf:");
|
||||
length = ompi_snprintf(NULL, 0, "this is a string %d", 1004);
|
||||
printf("length = %d\n", length);
|
||||
|
||||
puts("test of snprintf to an undersize buffer:");
|
||||
length = ompi_snprintf(a, sizeof(a), "this is a string %d", 1004);
|
||||
printf("string = %s\n", a);
|
||||
printf("length = %d\n", length);
|
||||
printf("strlen = %d\n", (int) strlen(a));
|
||||
|
||||
puts("test of snprintf to an oversize buffer:");
|
||||
length = ompi_snprintf(b, sizeof(b), "this is a string %d", 1004);
|
||||
printf("string = %s\n", b);
|
||||
printf("length = %d\n", length);
|
||||
printf("strlen = %d\n", (int) strlen(b));
|
||||
|
||||
puts("test of asprintf:");
|
||||
length = ompi_asprintf(&s, "this is a string %d", 1004);
|
||||
printf("string = %s\n", s);
|
||||
printf("length = %d\n", length);
|
||||
printf("strlen = %d\n", (int) strlen(s));
|
||||
|
||||
free(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
130
src/util/printf.h
Обычный файл
130
src/util/printf.h
Обычный файл
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Buffer safe printf functions for portability to archaic platforms.
|
||||
*/
|
||||
|
||||
#ifndef OMPI_PRINTF_H
|
||||
#define OMPI_PRINTF_H
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Writes to a string under the control of a format string
|
||||
* that specifies how subsequent arguments are converted for output.
|
||||
*
|
||||
* @param str Output string buffer
|
||||
* @param size Size of string buffer
|
||||
* @param fmt Output format
|
||||
* @return Length of output string
|
||||
*
|
||||
* At most size-1 characters are printed into the output string (the
|
||||
* size'th character then gets the terminating `\0'); if the return
|
||||
* value is greater than or equal to the size argument, the string was
|
||||
* too short and some of the printed characters were discarded. The
|
||||
* output is always null-terminated.
|
||||
*
|
||||
* Returns the number of characters that would have been printed if
|
||||
* the size were unlimited (again, not including the final `\0').
|
||||
*
|
||||
* THIS IS A PORTABILITY FEATURE: USE snprintf() in CODE.
|
||||
*/
|
||||
int ompi_snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
|
||||
|
||||
/**
|
||||
* Writes to a string under the control of a format string that
|
||||
* specifies how arguments accessed via the variable-length argument
|
||||
* facilities of stdarg(3) are converted for output.
|
||||
*
|
||||
* @param str Output string buffer
|
||||
* @param size Size of string buffer
|
||||
* @param fmt Output format
|
||||
* @param ap Variable argument list pointer
|
||||
* @return Length of output string
|
||||
*
|
||||
* At most size-1 characters are printed into the output string (the
|
||||
* size'th character then gets the terminating `\0'); if the return
|
||||
* value is greater than or equal to the size argument, the string was
|
||||
* too short and some of the printed characters were discarded. The
|
||||
* output is always null-terminated.
|
||||
*
|
||||
* Returns the number of characters that would have been printed if
|
||||
* the size were unlimited (again, not including the final `\0').
|
||||
*
|
||||
* THIS IS A PORTABILITY FEATURE: USE vsnprintf() in CODE.
|
||||
*/
|
||||
int ompi_vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and writes to a string under the control of a format
|
||||
* string that specifies how subsequent arguments are converted for
|
||||
* output.
|
||||
*
|
||||
* @param *ptr Pointer to utput string buffer
|
||||
* @param fmt Output format
|
||||
* @return Length of output string
|
||||
*
|
||||
* Sets *ptr to be a pointer to a buffer sufficiently large to hold
|
||||
* the formatted string. This pointer should be passed to free(3) to
|
||||
* release the allocated storage when it is no longer needed. If
|
||||
* sufficient space cannot be allocated, asprintf() and vasprintf()
|
||||
* will return -1 and set ret to be a NULL pointer.
|
||||
*
|
||||
* Returns the number of characters printed.
|
||||
*
|
||||
* THIS IS A PORTABILITY FEATURE: USE asprintf() in CODE.
|
||||
*/
|
||||
int ompi_asprintf(char **ptr, const char *fmt, ...);
|
||||
|
||||
|
||||
/**
|
||||
* Allocates and writes to a string under the control of a format
|
||||
* string that specifies how arguments accessed via the
|
||||
* variable-length argument facilities of stdarg(3) are converted for
|
||||
* output.
|
||||
*
|
||||
* @param *ptr Pointer to utput string buffer
|
||||
* @param fmt Output format
|
||||
* @param ap Variable argument list pointer
|
||||
* @return Length of output string
|
||||
*
|
||||
* Sets *ptr to be a pointer to a buffer sufficiently large to hold
|
||||
* the formatted string. This pointer should be passed to free(3) to
|
||||
* release the allocated storage when it is no longer needed. If
|
||||
* sufficient space cannot be allocated, asprintf() and vasprintf()
|
||||
* will return -1 and set ret to be a NULL pointer.
|
||||
*
|
||||
* Returns the number of characters printed.
|
||||
*
|
||||
* THIS IS A PORTABILITY FEATURE: USE vasprintf() in CODE.
|
||||
*/
|
||||
int ompi_vasprintf(char **ptr, const char *fmt, va_list ap);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_PRINTF_H */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user