2 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
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 2, or (at your option) any later
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 along
19 with groff; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "stringclass.h"
26 static char *salloc(int len
, int *sizep
);
27 static void sfree(char *ptr
, int size
);
28 static char *sfree_alloc(char *ptr
, int size
, int len
, int *sizep
);
29 static char *srealloc(char *ptr
, int size
, int oldlen
, int newlen
, int *sizep
);
31 static char *salloc(int len
, int *sizep
)
38 return new char[*sizep
= len
*2];
41 static void sfree(char *ptr
, int)
46 static char *sfree_alloc(char *ptr
, int oldsz
, int len
, int *sizep
)
58 return new char[*sizep
= len
*2];
61 static char *srealloc(char *ptr
, int oldsz
, int oldlen
, int newlen
, int *sizep
)
63 if (oldsz
>= newlen
) {
73 char *p
= new char[*sizep
= newlen
*2];
74 if (oldlen
< newlen
&& oldlen
!= 0)
75 memcpy(p
, ptr
, oldlen
);
81 string::string() : ptr(0), len(0), sz(0)
85 string::string(const char *p
, int n
) : len(n
)
93 string::string(const char *p
)
102 ptr
= salloc(len
, &sz
);
107 string::string(char c
) : len(1)
109 ptr
= salloc(1, &sz
);
113 string::string(const string
&s
) : len(s
.len
)
115 ptr
= salloc(len
, &sz
);
117 memcpy(ptr
, s
.ptr
, len
);
125 string
&string::operator=(const string
&s
)
127 ptr
= sfree_alloc(ptr
, sz
, s
.len
, &sz
);
130 memcpy(ptr
, s
.ptr
, len
);
134 string
&string::operator=(const char *p
)
143 int slen
= strlen(p
);
144 ptr
= sfree_alloc(ptr
, sz
, slen
, &sz
);
151 string
&string::operator=(char c
)
153 ptr
= sfree_alloc(ptr
, sz
, 1, &sz
);
159 void string::move(string
&s
)
172 ptr
= srealloc(ptr
, sz
, len
, len
+ 1, &sz
);
175 string
&string::operator+=(const char *p
)
179 int newlen
= len
+ n
;
181 ptr
= srealloc(ptr
, sz
, len
, newlen
, &sz
);
182 memcpy(ptr
+ len
, p
, n
);
188 string
&string::operator+=(const string
&s
)
191 int newlen
= len
+ s
.len
;
193 ptr
= srealloc(ptr
, sz
, len
, newlen
, &sz
);
194 memcpy(ptr
+ len
, s
.ptr
, s
.len
);
200 void string::append(const char *p
, int n
)
203 int newlen
= len
+ n
;
205 ptr
= srealloc(ptr
, sz
, len
, newlen
, &sz
);
206 memcpy(ptr
+ len
, p
, n
);
211 string::string(const char *s1
, int n1
, const char *s2
, int n2
)
213 assert(n1
>= 0 && n2
>= 0);
220 ptr
= salloc(len
, &sz
);
226 memcpy(ptr
+ n1
, s2
, n2
);
231 int operator<=(const string
&s1
, const string
&s2
)
233 return (s1
.len
<= s2
.len
234 ? s1
.len
== 0 || memcmp(s1
.ptr
, s2
.ptr
, s1
.len
) <= 0
235 : s2
.len
!= 0 && memcmp(s1
.ptr
, s2
.ptr
, s2
.len
) < 0);
238 int operator<(const string
&s1
, const string
&s2
)
240 return (s1
.len
< s2
.len
241 ? s1
.len
== 0 || memcmp(s1
.ptr
, s2
.ptr
, s1
.len
) <= 0
242 : s2
.len
!= 0 && memcmp(s1
.ptr
, s2
.ptr
, s2
.len
) < 0);
245 int operator>=(const string
&s1
, const string
&s2
)
247 return (s1
.len
>= s2
.len
248 ? s2
.len
== 0 || memcmp(s1
.ptr
, s2
.ptr
, s2
.len
) >= 0
249 : s1
.len
!= 0 && memcmp(s1
.ptr
, s2
.ptr
, s1
.len
) > 0);
252 int operator>(const string
&s1
, const string
&s2
)
254 return (s1
.len
> s2
.len
255 ? s2
.len
== 0 || memcmp(s1
.ptr
, s2
.ptr
, s2
.len
) >= 0
256 : s1
.len
!= 0 && memcmp(s1
.ptr
, s2
.ptr
, s1
.len
) > 0);
259 void string::set_length(int i
)
263 ptr
= srealloc(ptr
, sz
, len
, i
, &sz
);
272 int string::search(char c
) const
274 char *p
= ptr
? (char *)memchr(ptr
, c
, len
) : NULL
;
275 return p
? p
- ptr
: -1;
278 // we silently strip nuls
280 char *string::extract() const
286 for (i
= 0; i
< n
; i
++)
289 char *q
= new char[n
+ 1 - nnuls
];
291 for (i
= 0; i
< n
; i
++)
298 void string::remove_spaces()
301 while (l
>= 0 && ptr
[l
] == ' ')
312 char *tmp
= new char[len
];
327 void put_string(const string
&s
, FILE *fp
)
329 int len
= s
.length();
330 const char *ptr
= s
.contents();
331 for (int i
= 0; i
< len
; i
++)
335 string
as_string(int i
)
337 static char buf
[INT_DIGITS
+ 2];
338 sprintf(buf
, "%d", i
);