2 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2009
3 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.com)
6 This file is part of groff.
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "stringclass.h"
25 static char *salloc(int len, int *sizep);
26 static void sfree(char *ptr, int size);
27 static char *sfree_alloc(char *ptr, int size, int len, int *sizep);
28 static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep);
30 static char *salloc(int len, int *sizep)
37 return new char[*sizep = len*2];
40 static void sfree(char *ptr, int)
45 static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
57 return new char[*sizep = len*2];
60 static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep)
62 if (oldsz >= newlen) {
72 char *p = new char[*sizep = newlen*2];
73 if (oldlen < newlen && oldlen != 0)
74 memcpy(p, ptr, oldlen);
80 string::string() : ptr(0), len(0), sz(0)
84 string::string(const char *p, int n) : len(n)
92 string::string(const char *p)
101 ptr = salloc(len, &sz);
106 string::string(char c) : len(1)
108 ptr = salloc(1, &sz);
112 string::string(const string &s) : len(s.len)
114 ptr = salloc(len, &sz);
116 memcpy(ptr, s.ptr, len);
124 string &string::operator=(const string &s)
126 ptr = sfree_alloc(ptr, sz, s.len, &sz);
129 memcpy(ptr, s.ptr, len);
133 string &string::operator=(const char *p)
142 int slen = strlen(p);
143 ptr = sfree_alloc(ptr, sz, slen, &sz);
150 string &string::operator=(char c)
152 ptr = sfree_alloc(ptr, sz, 1, &sz);
158 void string::move(string &s)
171 ptr = srealloc(ptr, sz, len, len + 1, &sz);
174 string &string::operator+=(const char *p)
178 int newlen = len + n;
180 ptr = srealloc(ptr, sz, len, newlen, &sz);
181 memcpy(ptr + len, p, n);
187 string &string::operator+=(const string &s)
190 int newlen = len + s.len;
192 ptr = srealloc(ptr, sz, len, newlen, &sz);
193 memcpy(ptr + len, s.ptr, s.len);
199 void string::append(const char *p, int n)
202 int newlen = len + n;
204 ptr = srealloc(ptr, sz, len, newlen, &sz);
205 memcpy(ptr + len, p, n);
210 string::string(const char *s1, int n1, const char *s2, int n2)
212 assert(n1 >= 0 && n2 >= 0);
219 ptr = salloc(len, &sz);
225 memcpy(ptr + n1, s2, n2);
230 int operator<=(const string &s1, const string &s2)
232 return (s1.len <= s2.len
233 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
234 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
237 int operator<(const string &s1, const string &s2)
239 return (s1.len < s2.len
240 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
241 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
244 int operator>=(const string &s1, const string &s2)
246 return (s1.len >= s2.len
247 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
248 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
251 int operator>(const string &s1, const string &s2)
253 return (s1.len > s2.len
254 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
255 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
258 void string::set_length(int i)
262 ptr = srealloc(ptr, sz, len, i, &sz);
271 int string::search(char c) const
273 char *p = ptr ? (char *)memchr(ptr, c, len) : NULL;
274 return p ? p - ptr : -1;
277 // we silently strip nuls
279 char *string::extract() const
285 for (i = 0; i < n; i++)
288 char *q = new char[n + 1 - nnuls];
290 for (i = 0; i < n; i++)
297 void string::remove_spaces()
300 while (l >= 0 && ptr[l] == ' ')
311 char *tmp = new char[sz];
326 void put_string(const string &s, FILE *fp)
328 int len = s.length();
329 const char *ptr = s.contents();
330 for (int i = 0; i < len; i++)
334 string as_string(int i)
336 static char buf[INT_DIGITS + 2];
337 sprintf(buf, "%d", i);