Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Compare file prefix only.
[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 "src/internal_config.h"  /* Do we need vasprintf? */
54 #include <stdio.h>
55 #include <assert.h>
56
57 #if !HAVE_VASPRINTF
58 #include <stdarg.h> /* vsnprintf */
59 int vasprintf(char **ptr, const char *fmt, va_list ap);
60 int vasprintf(char **ptr, const char *fmt, va_list ap)
61 {
62   size_t str_m;
63   int str_l;
64
65   *ptr = NULL;
66   {
67     va_list ap2;
68     va_copy(ap2, ap);           /* don't consume the original ap, we'll need it again */
69     str_l = vsnprintf(NULL, (size_t) 0, fmt, ap2);     /*get required size */
70     va_end(ap2);
71   }
72   xbt_assert(str_l >= 0);           /* possible integer overflow if str_m > INT_MAX */
73   *ptr = (char *) xbt_malloc(str_m = (size_t) str_l + 1);
74
75   int str_l2 = vsnprintf(*ptr, str_m, fmt, ap);
76   assert(str_l2 == str_l);
77
78   return str_l;
79 }
80 #endif
81
82 char *bvprintf(const char *fmt, va_list ap)
83 {
84   char *res;
85
86   if (vasprintf(&res, fmt, ap) < 0) {
87     /* Do not want to use xbt_die() here, as it uses the logging
88      * infrastructure and may fail to allocate memory too. */
89     fprintf(stderr, "bprintf: vasprintf failed. Aborting.\n");
90     xbt_abort();
91   }
92   return res;
93 }
94
95 char *bprintf(const char *fmt, ...)
96 {
97   va_list ap;
98
99   va_start(ap, fmt);
100   char *res = bvprintf(fmt, ap);
101   va_end(ap);
102   return res;
103 }