Flowgrind
Advanced TCP traffic generator
fg_string.c
Go to the documentation of this file.
1 
6 /*
7  * Copyright (C) 2014 Alexander Zimmermann <alexander.zimmermann@netapp.com>
8  *
9  * This file is part of Flowgrind.
10  *
11  * Flowgrind is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * Flowgrind is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with Flowgrind. If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif /* HAVE_CONFIG_H */
29 
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "fg_string.h"
36 #include "fg_definitions.h"
37 
47 static inline char *strlendup_append(char *s, size_t slen, const char *a,
48  size_t alen)
49 {
50  char *ret = realloc(s, slen + alen + 1);
51  if (unlikely(!ret))
52  return NULL;
53 
54  /* append the string and the trailing \0 */
55  memcpy(&ret[slen], a, alen);
56  ret[slen+alen] = 0;
57 
58  return ret;
59 }
60 
61 size_t fmtlen(const char *fmt, va_list ap)
62 {
63  va_list ap2;
64  char c;
65 
66  /* If the output of vsnprintf is truncated, its return value is the
67  * number of characters which would have been written to the string
68  * if enough space had been available */
69  va_copy(ap2, ap);
70  size_t length = vsnprintf(&c, 1, fmt, ap2);
71  va_end(ap2);
72 
73  return length;
74 }
75 
76 char *strdup_append(char *s, const char *a)
77 {
78  if (unlikely(!s))
79  return strdup(a);
80 
81  if (unlikely(!a))
82  return s;
83 
84  return strlendup_append(s, strlen(s), a, strlen(a));
85 }
86 
87 char *strndup_append(char *s, const char *a, size_t n)
88 {
89  if (unlikely(!s))
90  return strdup(a);
91 
92  if (unlikely(!a))
93  return s;
94 
95  return strlendup_append(s, strlen(s), a, strnlen(a, n));
96 }
97 
98 int asprintf_append(char **strp, const char *fmt, ...)
99 {
100  va_list ap;
101 
102  va_start(ap, fmt);
103  size_t length = vasprintf_append(strp, fmt, ap);
104  va_end(ap);
105 
106  return length;
107 }
108 
109 int vasprintf_append(char **strp, const char *fmt, va_list ap)
110 {
111  if (unlikely(!(*strp)))
112  return vasprintf(strp, fmt, ap);
113 
114  size_t slen = strlen(*strp);
115  size_t alen = fmtlen(fmt, ap);
116 
117  /* The format resulted in no characters being formatted */
118  if (unlikely(alen == 0))
119  return -1;
120 
121  char *new_strp = realloc(*strp, slen + alen + 1);
122  if (unlikely(!(*new_strp)))
123  return -1;
124 
125  *strp = new_strp;
126 
127  va_list ap2;
128  va_copy(ap2, ap);
129  size_t length = vsnprintf(*strp + slen, alen + 1, fmt, ap2);
130  va_end(ap2);
131 
132  return length;
133 }
size_t fmtlen(const char *fmt, va_list ap)
Determine the number of characters that would be generated by a printf with format string fmt and arg...
Definition: fg_string.c:61
#define unlikely(x)
These macros gain us a few percent of speed.
static char * strlendup_append(char *s, size_t slen, const char *a, size_t alen)
Append the duplication of string a of length alen to the given string s at point slen.
Definition: fg_string.c:47
int asprintf_append(char **strp, const char *fmt,...)
Definition: fg_string.c:98
int vasprintf_append(char **strp, const char *fmt, va_list ap)
Definition: fg_string.c:109
char * strdup_append(char *s, const char *a)
Append the duplication of string a to the given string s.
Definition: fg_string.c:76
Functions to manipulate strings used by Flowgrind.
char * strndup_append(char *s, const char *a, size_t n)
Append at most n characters of the duplication of string a to the given string s. ...
Definition: fg_string.c:87
Common definitions used by the Flowgrind daemon, controller, and libs.