Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5053d29e87de9ca5cdc043e9aaa165061dcb49e3
[simgrid.git] / src / xbt / snprintf.c
1 /* Copyright (c) 2005-2010, 2012-2016. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /*
8  * snprintf.c - a portable implementation of snprintf
9  *
10  * AUTHOR
11  *   Mark Martinec <mark.martinec@ijs.si>, April 1999.
12  *
13  *   Copyright 1999, Mark Martinec. All rights reserved.
14  *
15  * TERMS AND CONDITIONS
16  *   This program is free software; you can redistribute it and/or modify
17  *   it under the terms of the "Frontier Artistic License" which comes
18  *   with this Kit.
19  *
20  *   This program is distributed in the hope that it will be useful,
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty
22  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23  *   See the Frontier Artistic License for more details.
24  *
25  *   You should have received a copy of the Frontier Artistic License
26  *   with this Kit in the file named LICENSE.txt .
27  *   If not, I'll be glad to provide one.
28  *
29  * FEATURES
30  * - careful adherence to specs regarding flags, field width and precision;
31  * - good performance for large string handling (large format, large
32  *   argument or large paddings). Performance is similar to system's sprintf
33  *   and in several cases significantly better (make sure you compile with
34  *   optimizations turned on, tell the compiler the code is strict ANSI
35  *   if necessary to give it more freedom for optimizations);
36  * - return value semantics per ISO/IEC 9899:1999 ("ISO C99");
37  * - written in standard ISO/ANSI C - requires an ANSI C compiler.
38  *
39  * [...]
40  *
41  * Routines asprintf and vasprintf return a pointer (in the ptr argument)
42  * to a buffer sufficiently large to hold the resulting string. This pointer
43  * should be passed to free(3) to release the allocated storage when it is
44  * no longer needed. If sufficient space cannot be allocated, these functions
45  * will return -1 and set ptr to be a NULL pointer. These two routines are a
46  * GNU C library extensions (glibc).
47  *
48  * AVAILABILITY
49  *   http://www.ijs.si/software/snprintf/
50  */
51
52 #include "xbt/sysdep.h"       /* xbt_abort() */
53 #include "simgrid_config.h"   /* Do we need vasprintf? */
54
55 #if !defined(HAVE_VASPRINTF)
56 #include <stdarg.h> /* vsnprintf */
57 int vasprintf(char **ptr, const char *fmt, va_list ap);
58 int vasprintf(char **ptr, const char *fmt, va_list ap)
59 {
60   size_t str_m;
61   int str_l;
62
63   *ptr = NULL;
64   {
65     va_list ap2;
66     va_copy(ap2, ap);           /* don't consume the original ap, we'll need it again */
67     str_l = vsnprintf(NULL, (size_t) 0, fmt, ap2);     /*get required size */
68     va_end(ap2);
69   }
70   xbt_assert(str_l >= 0);           /* possible integer overflow if str_m > INT_MAX */
71   *ptr = (char *) xbt_malloc(str_m = (size_t) str_l + 1);
72
73   int str_l2 = vsnprintf(*ptr, str_m, fmt, ap);
74   assert(str_l2 == str_l);
75
76   return str_l;
77 }
78 #endif
79
80 char *bvprintf(const char *fmt, va_list ap)
81 {
82   char *res;
83
84   if (vasprintf(&res, fmt, ap) < 0) {
85     /* Do not want to use xbt_die() here, as it uses the logging
86      * infrastucture and may fail to allocate memory too. */
87     fprintf(stderr, "bprintf: vasprintf failed. Aborting.\n");
88     xbt_abort();
89   }
90   return res;
91 }
92
93 char *bprintf(const char *fmt, ...)
94 {
95   va_list ap;
96
97   va_start(ap, fmt);
98   char *res = bvprintf(fmt, ap);
99   va_end(ap);
100   return res;
101 }