175584Sru// -*- C++ -*- 2104862Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc. 375584Sru Written by James Clark (jjc@jclark.com) 475584Sru 575584SruThis file is part of groff. 675584Sru 775584Srugroff is free software; you can redistribute it and/or modify it under 875584Sruthe terms of the GNU General Public License as published by the Free 975584SruSoftware Foundation; either version 2, or (at your option) any later 1075584Sruversion. 1175584Sru 1275584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY 1375584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or 1475584SruFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1575584Srufor more details. 1675584Sru 1775584SruYou should have received a copy of the GNU General Public License along 1875584Sruwith groff; see the file COPYING. If not, write to the Free Software 19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 2075584Sru 2175584Sru#include <string.h> 2275584Sru#include <stdio.h> 2375584Sru#include <assert.h> 2475584Sru 2575584Sru// Ensure that the first declaration of functions that are later 2675584Sru// declared as inline declares them as inline. 2775584Sru 2875584Sruclass string; 2975584Sru 3075584Sruinline string operator+(const string &, const string &); 3175584Sruinline string operator+(const string &, const char *); 3275584Sruinline string operator+(const char *, const string &); 3375584Sruinline string operator+(const string &, char); 3475584Sruinline string operator+(char, const string &); 3575584Sruinline int operator==(const string &, const string &); 3675584Sruinline int operator!=(const string &, const string &); 3775584Sru 3875584Sruclass string { 3975584Srupublic: 4075584Sru string(); 4175584Sru string(const string &); 4275584Sru string(const char *); 4375584Sru string(const char *, int); 4475584Sru string(char); 4575584Sru 4675584Sru ~string(); 4775584Sru 4875584Sru string &operator=(const string &); 4975584Sru string &operator=(const char *); 5075584Sru string &operator=(char); 5175584Sru 5275584Sru string &operator+=(const string &); 5375584Sru string &operator+=(const char *); 5475584Sru string &operator+=(char); 5575584Sru void append(const char *, int); 5675584Sru 5775584Sru int length() const; 5875584Sru int empty() const; 5975584Sru int operator*() const; 6075584Sru 6175584Sru string substring(int i, int n) const; 6275584Sru 6375584Sru char &operator[](int); 6475584Sru char operator[](int) const; 6575584Sru 6675584Sru void set_length(int i); 6775584Sru const char *contents() const; 6875584Sru int search(char) const; 6975584Sru char *extract() const; 70104862Sru void remove_spaces(); 7175584Sru void clear(); 7275584Sru void move(string &); 7375584Sru 7475584Sru friend string operator+(const string &, const string &); 7575584Sru friend string operator+(const string &, const char *); 7675584Sru friend string operator+(const char *, const string &); 7775584Sru friend string operator+(const string &, char); 7875584Sru friend string operator+(char, const string &); 7975584Sru 8075584Sru friend int operator==(const string &, const string &); 8175584Sru friend int operator!=(const string &, const string &); 8275584Sru friend int operator<=(const string &, const string &); 8375584Sru friend int operator<(const string &, const string &); 8475584Sru friend int operator>=(const string &, const string &); 8575584Sru friend int operator>(const string &, const string &); 8675584Sru 8775584Sruprivate: 8875584Sru char *ptr; 8975584Sru int len; 9075584Sru int sz; 9175584Sru 9275584Sru string(const char *, int, const char *, int); // for use by operator+ 9375584Sru void grow1(); 9475584Sru}; 9575584Sru 9675584Sru 9775584Sruinline char &string::operator[](int i) 9875584Sru{ 9975584Sru assert(i >= 0 && i < len); 10075584Sru return ptr[i]; 10175584Sru} 10275584Sru 10375584Sruinline char string::operator[](int i) const 10475584Sru{ 10575584Sru assert(i >= 0 && i < len); 10675584Sru return ptr[i]; 10775584Sru} 10875584Sru 10975584Sruinline int string::length() const 11075584Sru{ 11175584Sru return len; 11275584Sru} 11375584Sru 11475584Sruinline int string::empty() const 11575584Sru{ 11675584Sru return len == 0; 11775584Sru} 11875584Sru 11975584Sruinline int string::operator*() const 12075584Sru{ 12175584Sru return len; 12275584Sru} 12375584Sru 12475584Sruinline const char *string::contents() const 12575584Sru{ 126104862Sru return ptr; 12775584Sru} 12875584Sru 12975584Sruinline string operator+(const string &s1, const string &s2) 13075584Sru{ 13175584Sru return string(s1.ptr, s1.len, s2.ptr, s2.len); 13275584Sru} 13375584Sru 13475584Sruinline string operator+(const string &s1, const char *s2) 13575584Sru{ 13675584Sru#ifdef __GNUG__ 13775584Sru if (s2 == 0) 13875584Sru return s1; 13975584Sru else 14075584Sru return string(s1.ptr, s1.len, s2, strlen(s2)); 14175584Sru#else 14275584Sru return s2 == 0 ? s1 : string(s1.ptr, s1.len, s2, strlen(s2)); 14375584Sru#endif 14475584Sru} 14575584Sru 14675584Sruinline string operator+(const char *s1, const string &s2) 14775584Sru{ 14875584Sru#ifdef __GNUG__ 14975584Sru if (s1 == 0) 15075584Sru return s2; 15175584Sru else 15275584Sru return string(s1, strlen(s1), s2.ptr, s2.len); 15375584Sru#else 15475584Sru return s1 == 0 ? s2 : string(s1, strlen(s1), s2.ptr, s2.len); 15575584Sru#endif 15675584Sru} 15775584Sru 15875584Sruinline string operator+(const string &s, char c) 15975584Sru{ 16075584Sru return string(s.ptr, s.len, &c, 1); 16175584Sru} 16275584Sru 16375584Sruinline string operator+(char c, const string &s) 16475584Sru{ 16575584Sru return string(&c, 1, s.ptr, s.len); 16675584Sru} 16775584Sru 16875584Sruinline int operator==(const string &s1, const string &s2) 16975584Sru{ 17075584Sru return (s1.len == s2.len 17175584Sru && (s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) == 0)); 17275584Sru} 17375584Sru 17475584Sruinline int operator!=(const string &s1, const string &s2) 17575584Sru{ 17675584Sru return (s1.len != s2.len 17775584Sru || (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0)); 17875584Sru} 17975584Sru 18075584Sruinline string string::substring(int i, int n) const 18175584Sru{ 18275584Sru assert(i >= 0 && i + n <= len); 18375584Sru return string(ptr + i, n); 18475584Sru} 18575584Sru 18675584Sruinline string &string::operator+=(char c) 18775584Sru{ 18875584Sru if (len >= sz) 18975584Sru grow1(); 19075584Sru ptr[len++] = c; 19175584Sru return *this; 19275584Sru} 19375584Sru 19475584Sruvoid put_string(const string &, FILE *); 19575584Sru 19675584Srustring as_string(int); 197