Fix for UBSan build
[platform/upstream/doxygen.git] / qtools / qgstring.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2004 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby 
7  * granted. No representations are made about the suitability of this software 
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15
16 #include <stdio.h>
17 #include "qgstring.h"
18
19 #include <assert.h>
20
21 #define BLOCK_SIZE 64
22 #define ROUND_SIZE(x) ((x)+BLOCK_SIZE-1)&~(BLOCK_SIZE-1)
23
24 #define DBG_STR(x) do { } while(0)
25 //#define DBG_STR(x) printf x
26
27 QGString::QGString() // make null string
28   : m_data(0), m_len(0), m_memSize(0) 
29 {
30   DBG_STR(("%p: QGString::QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
31
32
33 QGString::QGString(uint size)
34 {
35   if (size==0)
36   {
37     m_data=0;
38     m_len=0;
39   }
40   else
41   {
42     m_memSize = ROUND_SIZE(size+1);
43     m_data = (char*)malloc(m_memSize);
44     memset(m_data,' ',size);
45     m_data[size]='\0';
46     m_len=size;
47   }
48   DBG_STR(("%p: QGString::QGString(uint size=%d) %d:%s\n",
49       this,size,m_len,m_data?m_data:"<none>"));
50 }
51
52 QGString::QGString( const QGString &s ) 
53
54   if (s.m_memSize==0)
55   {
56     m_data    = 0;
57     m_len     = 0;
58     m_memSize = 0;
59   }
60   else
61   {
62     m_data    = (char *)malloc(s.m_memSize); 
63     m_len     = s.m_len;
64     m_memSize = s.m_memSize;
65     qstrcpy(m_data,s.m_data);
66   }
67   DBG_STR(("%p: QGString::QGString(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
68
69
70 QGString::QGString( const char *str )
71 {
72   if (str==0)
73   {
74     m_data=0;
75     m_len=0;
76     m_memSize=0;
77   }
78   else
79   {
80     m_len = qstrlen(str);
81     m_memSize = ROUND_SIZE(m_len+1);
82     assert(m_memSize>=m_len+1);
83     m_data = (char *)malloc(m_memSize);
84     qstrcpy(m_data,str);
85   }
86   DBG_STR(("%p: QGString::QGString(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
87 }
88
89 QGString::~QGString() 
90
91   free(m_data); 
92   m_data=0; 
93   DBG_STR(("%p: QGString::~QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
94 }
95
96 bool QGString::resize( uint newlen )
97 {
98   m_len = 0;
99   if (newlen==0)
100   {
101     if (m_data) { free(m_data); m_data=0; }
102     m_memSize=0;
103     DBG_STR(("%p: 1.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
104     return TRUE;
105   }
106   m_memSize = ROUND_SIZE(newlen+1);
107   assert(m_memSize>=newlen+1);
108   if (m_data==0)
109   {
110     m_data = (char *)malloc(m_memSize);
111   }
112   else
113   {
114     m_data = (char *)realloc(m_data,m_memSize);
115   }
116   if (m_data==0) 
117   {
118     DBG_STR(("%p: 2.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
119     return FALSE;
120   }
121   m_data[newlen]='\0';
122   m_len = qstrlen(m_data);
123   DBG_STR(("%p: 3.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
124   return TRUE;
125 }
126
127 bool QGString::enlarge( uint newlen )
128 {
129   if (newlen==0)
130   {
131     if (m_data) { free(m_data); m_data=0; }
132     m_memSize=0;
133     m_len=0;
134     return TRUE;
135   }
136   uint newMemSize = ROUND_SIZE(newlen+1);
137   if (newMemSize==m_memSize) return TRUE;
138   m_memSize = newMemSize;
139   if (m_data==0)
140   {
141     m_data = (char *)malloc(m_memSize);
142   }
143   else
144   {
145     m_data = (char *)realloc(m_data,m_memSize);
146   }
147   if (m_data==0) 
148   {
149     return FALSE;
150   }
151   m_data[newlen-1]='\0';
152   if (m_len>newlen) m_len=newlen;
153   return TRUE;
154 }
155
156 void QGString::setLen( uint newlen )
157 {
158   m_len = newlen<=m_memSize ? newlen : m_memSize;
159 }
160
161 QGString &QGString::operator=( const QGString &s ) 
162 {
163   if (m_data) free(m_data);
164   if (s.m_memSize==0) // null string
165   {
166     m_data    = 0;
167     m_len     = 0;
168     m_memSize = 0;
169   }
170   else
171   {
172     m_len     = s.m_len;
173     m_memSize = s.m_memSize;
174     m_data    = (char*)malloc(m_memSize);
175     qstrcpy(m_data,s.m_data);
176   }
177   DBG_STR(("%p: QGString::operator=(const QGString &%p) %d:%s\n",
178       this,&s,m_len,m_data?m_data:"<none>"));
179   return *this;
180 }
181
182 QGString &QGString::operator=( const char *str ) 
183
184   if (m_data) free(m_data);
185   if (str==0) // null string
186   {
187     m_data    = 0;
188     m_len     = 0;
189     m_memSize = 0;
190   }
191   else
192   {
193     m_len     = qstrlen(str);
194     m_memSize = ROUND_SIZE(m_len+1);
195     assert(m_memSize>=m_len+1);
196     m_data    = (char*)malloc(m_memSize);
197     qstrcpy(m_data,str);
198   }
199   DBG_STR(("%p: QGString::operator=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
200   return *this;
201 }
202
203 QGString &QGString::operator+=( const QGString &s )
204 {
205   if (s.m_memSize==0) return *this;
206   uint len1 = length();
207   uint len2 = s.length();
208   uint memSize = ROUND_SIZE(len1 + len2 + 1);
209   assert(memSize>=len1+len2+1);
210   char *newData = memSize!=m_memSize ? (char*)realloc( m_data, memSize ) : m_data;
211   m_memSize = memSize;
212   if (m_data)
213   {
214     m_data = newData;
215     memcpy( m_data + len1, s, len2 + 1 );
216   }
217   m_len = len1+len2;
218   DBG_STR(("%p: QGString::operator+=(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
219   return *this;
220 }
221
222 QGString &QGString::operator+=( const char *str )
223 {
224   if (!str) return *this;
225   uint len1 = length();
226   uint len2 = qstrlen(str);
227   uint memSize = ROUND_SIZE(len1 + len2 + 1);
228   assert(memSize>=len1+len2+1);
229   char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
230   m_memSize = memSize;
231   if (newData)
232   {
233     m_data = newData;
234     memcpy( m_data + len1, str, len2 + 1 );
235   }
236   m_len+=len2;
237   DBG_STR(("%p: QGString::operator+=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
238   return *this;
239 }
240
241 QGString &QGString::operator+=( char c )
242 {
243   uint len = m_len;
244   uint memSize = ROUND_SIZE(len+2);
245   assert(memSize>=len+2);
246   char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
247   m_memSize = memSize;
248   if (newData)
249   {
250     m_data = newData;
251     m_data[len] = c;
252     m_data[len+1] = '\0';
253   }
254   m_len++;
255   DBG_STR(("%p: QGString::operator+=(char s) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
256   return *this;
257 }
258