Sync-to-go: update copyright for 2015
[s-roff.git] / src / lib-roff / string.cpp
blobf25a5fc3fdc796f3cfab132f02d61e0a9e2ea8e9
1 /*@
2 * Copyright (c) 2014 - 2015 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * This 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 2, or (at your option) any later
11 * version.
13 * This 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
16 * for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with groff; see the file COPYING. If not, write to the Free Software
20 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "config.h"
24 #include "lib.h"
26 #include "stringclass.h"
28 static char *salloc(int len, int *sizep);
29 static void sfree(char *ptr, int size);
30 static char *sfree_alloc(char *ptr, int size, int len, int *sizep);
31 static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep);
33 static char *salloc(int len, int *sizep)
35 if (len == 0) {
36 *sizep = 0;
37 return 0;
39 else
40 return new char[*sizep = len*2];
43 static void sfree(char *ptr, int)
45 a_delete ptr;
48 static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
50 if (oldsz >= len) {
51 *sizep = oldsz;
52 return ptr;
54 a_delete ptr;
55 if (len == 0) {
56 *sizep = 0;
57 return 0;
59 else
60 return new char[*sizep = len*2];
63 static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep)
65 if (oldsz >= newlen) {
66 *sizep = oldsz;
67 return ptr;
69 if (newlen == 0) {
70 a_delete ptr;
71 *sizep = 0;
72 return 0;
74 else {
75 char *p = new char[*sizep = newlen*2];
76 if (oldlen < newlen && oldlen != 0)
77 memcpy(p, ptr, oldlen);
78 a_delete ptr;
79 return p;
83 string::string() : ptr(0), len(0), sz(0)
87 string::string(const char *p, int n) : len(n)
89 assert(n >= 0);
90 ptr = salloc(n, &sz);
91 if (n != 0)
92 memcpy(ptr, p, n);
95 string::string(const char *p)
97 if (p == 0) {
98 len = 0;
99 ptr = 0;
100 sz = 0;
102 else {
103 len = strlen(p);
104 ptr = salloc(len, &sz);
105 memcpy(ptr, p, len);
109 string::string(char c) : len(1)
111 ptr = salloc(1, &sz);
112 *ptr = c;
115 string::string(const string &s) : len(s.len)
117 ptr = salloc(len, &sz);
118 if (len != 0)
119 memcpy(ptr, s.ptr, len);
122 string::~string()
124 sfree(ptr, sz);
127 string &string::operator=(const string &s)
129 ptr = sfree_alloc(ptr, sz, s.len, &sz);
130 len = s.len;
131 if (len != 0)
132 memcpy(ptr, s.ptr, len);
133 return *this;
136 string &string::operator=(const char *p)
138 if (p == 0) {
139 sfree(ptr, len);
140 len = 0;
141 ptr = 0;
142 sz = 0;
144 else {
145 int slen = strlen(p);
146 ptr = sfree_alloc(ptr, sz, slen, &sz);
147 len = slen;
148 memcpy(ptr, p, len);
150 return *this;
153 string &string::operator=(char c)
155 ptr = sfree_alloc(ptr, sz, 1, &sz);
156 len = 1;
157 *ptr = c;
158 return *this;
161 void string::move(string &s)
163 sfree(ptr, sz);
164 ptr = s.ptr;
165 len = s.len;
166 sz = s.sz;
167 s.ptr = 0;
168 s.len = 0;
169 s.sz = 0;
172 void string::grow1()
174 ptr = srealloc(ptr, sz, len, len + 1, &sz);
177 string &string::operator+=(const char *p)
179 if (p != 0) {
180 int n = strlen(p);
181 int newlen = len + n;
182 if (newlen > sz)
183 ptr = srealloc(ptr, sz, len, newlen, &sz);
184 memcpy(ptr + len, p, n);
185 len = newlen;
187 return *this;
190 string &string::operator+=(const string &s)
192 if (s.len != 0) {
193 int newlen = len + s.len;
194 if (newlen > sz)
195 ptr = srealloc(ptr, sz, len, newlen, &sz);
196 memcpy(ptr + len, s.ptr, s.len);
197 len = newlen;
199 return *this;
202 void string::append(const char *p, int n)
204 if (n > 0) {
205 int newlen = len + n;
206 if (newlen > sz)
207 ptr = srealloc(ptr, sz, len, newlen, &sz);
208 memcpy(ptr + len, p, n);
209 len = newlen;
213 string::string(const char *s1, int n1, const char *s2, int n2)
215 assert(n1 >= 0 && n2 >= 0);
216 len = n1 + n2;
217 if (len == 0) {
218 sz = 0;
219 ptr = 0;
221 else {
222 ptr = salloc(len, &sz);
223 if (n1 == 0)
224 memcpy(ptr, s2, n2);
225 else {
226 memcpy(ptr, s1, n1);
227 if (n2 != 0)
228 memcpy(ptr + n1, s2, n2);
233 int operator<=(const string &s1, const string &s2)
235 return (s1.len <= s2.len
236 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
237 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
240 int operator<(const string &s1, const string &s2)
242 return (s1.len < s2.len
243 ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
244 : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
247 int operator>=(const string &s1, const string &s2)
249 return (s1.len >= s2.len
250 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
251 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
254 int operator>(const string &s1, const string &s2)
256 return (s1.len > s2.len
257 ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
258 : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
261 void string::set_length(int i)
263 assert(i >= 0);
264 if (i > sz)
265 ptr = srealloc(ptr, sz, len, i, &sz);
266 len = i;
269 void string::clear()
271 len = 0;
274 int string::search(char c) const
276 char *p = ptr ? (char *)memchr(ptr, c, len) : NULL;
277 return p ? p - ptr : -1;
280 // we silently strip nuls
282 char *string::extract() const
284 char *p = ptr;
285 int n = len;
286 int nnuls = 0;
287 int i;
288 for (i = 0; i < n; i++)
289 if (p[i] == '\0')
290 nnuls++;
291 char *q = new char[n + 1 - nnuls];
292 char *r = q;
293 for (i = 0; i < n; i++)
294 if (p[i] != '\0')
295 *r++ = p[i];
296 *r = '\0';
297 return q;
300 void string::remove_spaces()
302 int l = len - 1;
303 while (l >= 0 && ptr[l] == ' ')
304 l--;
305 char *p = ptr;
306 if (l > 0)
307 while (*p == ' ') {
308 p++;
309 l--;
311 if (len - 1 != l) {
312 if (l >= 0) {
313 len = l + 1;
314 char *tmp = new char[sz];
315 memcpy(tmp, p, len);
316 a_delete ptr;
317 ptr = tmp;
319 else {
320 len = 0;
321 if (ptr) {
322 a_delete ptr;
323 ptr = 0;
329 void put_string(const string &s, FILE *fp)
331 int len = s.length();
332 const char *ptr = s.contents();
333 for (int i = 0; i < len; i++)
334 putc(ptr[i], fp);
337 string as_string(int i)
339 static char buf[INT_DIGITS + 2];
340 sprintf(buf, "%d", i);
341 return string(buf);
344 // s-it2-mode