- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / re2 / util / stringprintf.cc
1 // Copyright 2002 The RE2 Authors.  All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "util/util.h"
6
7 #ifndef va_copy
8 #define va_copy(d,s) ((d) = (s)) //KLUGE: for MS compilers
9 #endif
10
11 namespace re2 { 
12
13 static void StringAppendV(string* dst, const char* format, va_list ap) {
14   // First try with a small fixed size buffer
15   char space[1024];
16
17   // It's possible for methods that use a va_list to invalidate
18   // the data in it upon use.  The fix is to make a copy
19   // of the structure before using it and use that copy instead.
20   va_list backup_ap;
21   va_copy(backup_ap, ap);
22   int result = vsnprintf(space, sizeof(space), format, backup_ap);
23   va_end(backup_ap);
24
25   if ((result >= 0) && (result < sizeof(space))) {
26     // It fit
27     dst->append(space, result);
28     return;
29   }
30
31   // Repeatedly increase buffer size until it fits
32   int length = sizeof(space);
33   while (true) {
34     if (result < 0) {
35       // Older behavior: just try doubling the buffer size
36       length *= 2;
37     } else {
38       // We need exactly "result+1" characters
39       length = result+1;
40     }
41     char* buf = new char[length];
42
43     // Restore the va_list before we use it again
44     va_copy(backup_ap, ap);
45     result = vsnprintf(buf, length, format, backup_ap);
46     va_end(backup_ap);
47
48     if ((result >= 0) && (result < length)) {
49       // It fit
50       dst->append(buf, result);
51       delete[] buf;
52       return;
53     }
54     delete[] buf;
55   }
56 }
57
58 string StringPrintf(const char* format, ...) {
59   va_list ap;
60   va_start(ap, format);
61   string result;
62   StringAppendV(&result, format, ap);
63   va_end(ap);
64   return result;
65 }
66
67 void SStringPrintf(string* dst, const char* format, ...) {
68   va_list ap;
69   va_start(ap, format);
70   dst->clear();
71   StringAppendV(dst, format, ap);
72   va_end(ap);
73 }
74
75 void StringAppendF(string* dst, const char* format, ...) {
76   va_list ap;
77   va_start(ap, format);
78   StringAppendV(dst, format, ap);
79   va_end(ap);
80 }
81
82 }  // namespace re2