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