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