1*89a07cf8Schristos /* $NetBSD: stringclass.h,v 1.1.1.1 2016/01/13 18:41:48 christos Exp $ */
2*89a07cf8Schristos
3*89a07cf8Schristos // -*- C++ -*-
4*89a07cf8Schristos /* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc.
5*89a07cf8Schristos Written by James Clark (jjc@jclark.com)
6*89a07cf8Schristos
7*89a07cf8Schristos This file is part of groff.
8*89a07cf8Schristos
9*89a07cf8Schristos groff is free software; you can redistribute it and/or modify it under
10*89a07cf8Schristos the terms of the GNU General Public License as published by the Free
11*89a07cf8Schristos Software Foundation; either version 2, or (at your option) any later
12*89a07cf8Schristos version.
13*89a07cf8Schristos
14*89a07cf8Schristos groff is distributed in the hope that it will be useful, but WITHOUT ANY
15*89a07cf8Schristos WARRANTY; without even the implied warranty of MERCHANTABILITY or
16*89a07cf8Schristos FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17*89a07cf8Schristos for more details.
18*89a07cf8Schristos
19*89a07cf8Schristos You should have received a copy of the GNU General Public License along
20*89a07cf8Schristos with groff; see the file COPYING. If not, write to the Free Software
21*89a07cf8Schristos Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
22*89a07cf8Schristos
23*89a07cf8Schristos #include <string.h>
24*89a07cf8Schristos #include <stdio.h>
25*89a07cf8Schristos #include <assert.h>
26*89a07cf8Schristos
27*89a07cf8Schristos // Ensure that the first declaration of functions that are later
28*89a07cf8Schristos // declared as inline declares them as inline.
29*89a07cf8Schristos
30*89a07cf8Schristos class string;
31*89a07cf8Schristos
32*89a07cf8Schristos inline string operator+(const string &, const string &);
33*89a07cf8Schristos inline string operator+(const string &, const char *);
34*89a07cf8Schristos inline string operator+(const char *, const string &);
35*89a07cf8Schristos inline string operator+(const string &, char);
36*89a07cf8Schristos inline string operator+(char, const string &);
37*89a07cf8Schristos inline int operator==(const string &, const string &);
38*89a07cf8Schristos inline int operator!=(const string &, const string &);
39*89a07cf8Schristos
40*89a07cf8Schristos class string {
41*89a07cf8Schristos public:
42*89a07cf8Schristos string();
43*89a07cf8Schristos string(const string &);
44*89a07cf8Schristos string(const char *);
45*89a07cf8Schristos string(const char *, int);
46*89a07cf8Schristos string(char);
47*89a07cf8Schristos
48*89a07cf8Schristos ~string();
49*89a07cf8Schristos
50*89a07cf8Schristos string &operator=(const string &);
51*89a07cf8Schristos string &operator=(const char *);
52*89a07cf8Schristos string &operator=(char);
53*89a07cf8Schristos
54*89a07cf8Schristos string &operator+=(const string &);
55*89a07cf8Schristos string &operator+=(const char *);
56*89a07cf8Schristos string &operator+=(char);
57*89a07cf8Schristos void append(const char *, int);
58*89a07cf8Schristos
59*89a07cf8Schristos int length() const;
60*89a07cf8Schristos int empty() const;
61*89a07cf8Schristos int operator*() const;
62*89a07cf8Schristos
63*89a07cf8Schristos string substring(int i, int n) const;
64*89a07cf8Schristos
65*89a07cf8Schristos char &operator[](int);
66*89a07cf8Schristos char operator[](int) const;
67*89a07cf8Schristos
68*89a07cf8Schristos void set_length(int i);
69*89a07cf8Schristos const char *contents() const;
70*89a07cf8Schristos int search(char) const;
71*89a07cf8Schristos char *extract() const;
72*89a07cf8Schristos void remove_spaces();
73*89a07cf8Schristos void clear();
74*89a07cf8Schristos void move(string &);
75*89a07cf8Schristos
76*89a07cf8Schristos friend string operator+(const string &, const string &);
77*89a07cf8Schristos friend string operator+(const string &, const char *);
78*89a07cf8Schristos friend string operator+(const char *, const string &);
79*89a07cf8Schristos friend string operator+(const string &, char);
80*89a07cf8Schristos friend string operator+(char, const string &);
81*89a07cf8Schristos
82*89a07cf8Schristos friend int operator==(const string &, const string &);
83*89a07cf8Schristos friend int operator!=(const string &, const string &);
84*89a07cf8Schristos friend int operator<=(const string &, const string &);
85*89a07cf8Schristos friend int operator<(const string &, const string &);
86*89a07cf8Schristos friend int operator>=(const string &, const string &);
87*89a07cf8Schristos friend int operator>(const string &, const string &);
88*89a07cf8Schristos
89*89a07cf8Schristos private:
90*89a07cf8Schristos char *ptr;
91*89a07cf8Schristos int len;
92*89a07cf8Schristos int sz;
93*89a07cf8Schristos
94*89a07cf8Schristos string(const char *, int, const char *, int); // for use by operator+
95*89a07cf8Schristos void grow1();
96*89a07cf8Schristos };
97*89a07cf8Schristos
98*89a07cf8Schristos
99*89a07cf8Schristos inline char &string::operator[](int i)
100*89a07cf8Schristos {
101*89a07cf8Schristos assert(i >= 0 && i < len);
102*89a07cf8Schristos return ptr[i];
103*89a07cf8Schristos }
104*89a07cf8Schristos
105*89a07cf8Schristos inline char string::operator[](int i) const
106*89a07cf8Schristos {
107*89a07cf8Schristos assert(i >= 0 && i < len);
108*89a07cf8Schristos return ptr[i];
109*89a07cf8Schristos }
110*89a07cf8Schristos
length()111*89a07cf8Schristos inline int string::length() const
112*89a07cf8Schristos {
113*89a07cf8Schristos return len;
114*89a07cf8Schristos }
115*89a07cf8Schristos
empty()116*89a07cf8Schristos inline int string::empty() const
117*89a07cf8Schristos {
118*89a07cf8Schristos return len == 0;
119*89a07cf8Schristos }
120*89a07cf8Schristos
121*89a07cf8Schristos inline int string::operator*() const
122*89a07cf8Schristos {
123*89a07cf8Schristos return len;
124*89a07cf8Schristos }
125*89a07cf8Schristos
contents()126*89a07cf8Schristos inline const char *string::contents() const
127*89a07cf8Schristos {
128*89a07cf8Schristos return ptr;
129*89a07cf8Schristos }
130*89a07cf8Schristos
131*89a07cf8Schristos inline string operator+(const string &s1, const string &s2)
132*89a07cf8Schristos {
133*89a07cf8Schristos return string(s1.ptr, s1.len, s2.ptr, s2.len);
134*89a07cf8Schristos }
135*89a07cf8Schristos
136*89a07cf8Schristos inline string operator+(const string &s1, const char *s2)
137*89a07cf8Schristos {
138*89a07cf8Schristos #ifdef __GNUG__
139*89a07cf8Schristos if (s2 == 0)
140*89a07cf8Schristos return s1;
141*89a07cf8Schristos else
142*89a07cf8Schristos return string(s1.ptr, s1.len, s2, strlen(s2));
143*89a07cf8Schristos #else
144*89a07cf8Schristos return s2 == 0 ? s1 : string(s1.ptr, s1.len, s2, strlen(s2));
145*89a07cf8Schristos #endif
146*89a07cf8Schristos }
147*89a07cf8Schristos
148*89a07cf8Schristos inline string operator+(const char *s1, const string &s2)
149*89a07cf8Schristos {
150*89a07cf8Schristos #ifdef __GNUG__
151*89a07cf8Schristos if (s1 == 0)
152*89a07cf8Schristos return s2;
153*89a07cf8Schristos else
154*89a07cf8Schristos return string(s1, strlen(s1), s2.ptr, s2.len);
155*89a07cf8Schristos #else
156*89a07cf8Schristos return s1 == 0 ? s2 : string(s1, strlen(s1), s2.ptr, s2.len);
157*89a07cf8Schristos #endif
158*89a07cf8Schristos }
159*89a07cf8Schristos
160*89a07cf8Schristos inline string operator+(const string &s, char c)
161*89a07cf8Schristos {
162*89a07cf8Schristos return string(s.ptr, s.len, &c, 1);
163*89a07cf8Schristos }
164*89a07cf8Schristos
165*89a07cf8Schristos inline string operator+(char c, const string &s)
166*89a07cf8Schristos {
167*89a07cf8Schristos return string(&c, 1, s.ptr, s.len);
168*89a07cf8Schristos }
169*89a07cf8Schristos
170*89a07cf8Schristos inline int operator==(const string &s1, const string &s2)
171*89a07cf8Schristos {
172*89a07cf8Schristos return (s1.len == s2.len
173*89a07cf8Schristos && (s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) == 0));
174*89a07cf8Schristos }
175*89a07cf8Schristos
176*89a07cf8Schristos inline int operator!=(const string &s1, const string &s2)
177*89a07cf8Schristos {
178*89a07cf8Schristos return (s1.len != s2.len
179*89a07cf8Schristos || (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0));
180*89a07cf8Schristos }
181*89a07cf8Schristos
substring(int i,int n)182*89a07cf8Schristos inline string string::substring(int i, int n) const
183*89a07cf8Schristos {
184*89a07cf8Schristos assert(i >= 0 && i + n <= len);
185*89a07cf8Schristos return string(ptr + i, n);
186*89a07cf8Schristos }
187*89a07cf8Schristos
188*89a07cf8Schristos inline string &string::operator+=(char c)
189*89a07cf8Schristos {
190*89a07cf8Schristos if (len >= sz)
191*89a07cf8Schristos grow1();
192*89a07cf8Schristos ptr[len++] = c;
193*89a07cf8Schristos return *this;
194*89a07cf8Schristos }
195*89a07cf8Schristos
196*89a07cf8Schristos void put_string(const string &, FILE *);
197*89a07cf8Schristos
198*89a07cf8Schristos string as_string(int);
199