1 /* Copyright (C) 1989-2020 Free Software Foundation, Inc.
2 Written by James Clark (jjc@jclark.com)
4 This file is part of groff.
6 groff is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include "stringclass.h"
29 static char *salloc(int len, int *sizep);
30 static void sfree(char *ptr, int size);
31 static char *sfree_alloc(char *ptr, int size, int len, int *sizep);
32 static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep);
34 static char *salloc(int len, int *sizep)
41 return new char[*sizep = len*2];
44 static void sfree(char *ptr, int)
49 static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
61 return new char[*sizep = len*2];
64 static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep)
66 if (oldsz >= newlen) {
76 char *p = new char[*sizep = newlen*2];
77 if (oldlen < newlen && oldlen != 0)
78 memcpy(p, ptr, oldlen);
84 string::string() : ptr(0), len(0), sz(0)
88 string::string(const char *p, int n) : len(n)
96 string::string(const char *p)
105 ptr = salloc(len, &sz);
111 string::string(char c) : len(1)
113 ptr = salloc(1, &sz);
117 string::string(const string &s) : len(s.len)
119 ptr = salloc(len, &sz);
121 memcpy(ptr, s.ptr, len);
129 string &string::operator=(const string &s)
131 ptr = sfree_alloc(ptr, sz, s.len, &sz);
134 memcpy(ptr, s.ptr, len);
138 string &string::operator=(const char *p)
147 int slen = strlen(p);
148 ptr = sfree_alloc(ptr, sz, slen, &sz);
156 string &string::operator=(char c)
158 ptr = sfree_alloc(ptr, sz, 1, &sz);
164 void string::move(string &s)
177 ptr = srealloc(ptr, sz, len, len + 1, &sz);
180 string &string::operator+=(const char *p)
184 int newlen = len + n;
186 ptr = srealloc(ptr, sz, len, newlen, &sz);
187 memcpy(ptr + len, p, n);
193 string &string::operator+=(const string &s)
196 int newlen = len + s.len;
198 ptr = srealloc(ptr, sz, len, newlen, &sz);
199 memcpy(ptr + len, s.ptr, s.len);
205 void string::append(const char *p, int n)
208 int newlen = len + n;
210 ptr = srealloc(ptr, sz, len, newlen, &sz);
211 memcpy(ptr + len, p, n);
216 string::string(const char *s1, int n1, const char *s2, int n2)
218 assert(n1 >= 0 && n2 >= 0);
225 ptr = salloc(len, &sz);
231 memcpy(ptr + n1, s2, n2);
236 int operator<=(const string &s1, const string &s2)
238 return (s1.len <= s2.len
239 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
240 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
243 int operator<(const string &s1, const string &s2)
245 return (s1.len < s2.len
246 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
247 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
250 int operator>=(const string &s1, const string &s2)
252 return (s1.len >= s2.len
253 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
254 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
257 int operator>(const string &s1, const string &s2)
259 return (s1.len > s2.len
260 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
261 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
264 void string::set_length(int i)
268 ptr = srealloc(ptr, sz, len, i, &sz);
277 int string::search(char c) const
279 char *p = ptr ? (char *)memchr(ptr, c, len) : 0;
280 return p ? p - ptr : -1;
283 // we silently strip nuls
285 char *string::extract() const
291 for (i = 0; i < n; i++)
294 char *q =(char*)malloc(n + 1 - nnuls);
295 if (q != 0 /* nullptr */) {
297 for (i = 0; i < n; i++)
305 void string::remove_spaces()
308 while (l >= 0 && ptr[l] == ' ')
319 char *tmp = new char[sz];
335 void put_string(const string &s, FILE *fp)
337 int len = s.length();
338 const char *ptr = s.contents();
339 for (int i = 0; i < len; i++)
343 string as_string(int i)
345 static char buf[INT_DIGITS + 2];
346 sprintf(buf, "%d", i);
354 // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: