/*
 * File: strlib.h
 * --------------
 * This interface defines a general library for dynamically allocated
 * strings.  The major differences between traditional C strings and those
 * defined using this interface are:
 *
 *
 *  The strlib.h interface takes care of memory
 *      allocation, ensuring that there is sufficient space to hold
 *      the result of each string operation.
 *  Clients of the strlib.h interface are expected
 *      to treat all strings as immutable and refrain from writing
 *      into the character array.
 *
 */

/*
 * Cautionary note:
 * ----------------
 * Although this interface provides an extremely convenient abstraction for
 * working with strings, it is not appropriate for all applications.  In
 * this interface, the functions that return string values (such as concat
 * and substring) do so by allocating new memory.  Over time, a program
 * that uses this package will consume increasing amounts of memory and
 * eventually exhaust the available supply.  If you are writing a program
 * that runs for a short time and stops, the fact that the package consumes
 * memory is not a problem.  If, however, you are writing an application
 * that must run for an extended period of time, using this package
 * requires that you make some provision for freeing any allocated storage.
 */

#ifndef _strlib_h
#define _strlib_h

#include <stdarg.h>
#include "cslib.h"
#include "generic.h"

/* Section 1 -- Basic string operations */

/*
 * Function: concat
 * Usage: s = concat(s1, s2);
 * --------------------------
 * Concatenates two strings by joining them end to end.  For example,
 * concat("ABC", "DE") returns the string "ABCDE".
 */

string concat(string s1, string s2);

/*
 * Function: charAt
 * Usage: ch = charAt(s, i);
 * -------------------------
 * Returns the character at position i in the string s.  This function is
 * included in the library to make the type string a true abstract type in
 * the sense that all of the necessary operations can be invoked using
 * functions.  Calling charAt(s, i) is like selecting s[i], except that
 * charAt checks to see if i is within the range of legal index positions,
 * which extend from 0 to stringLength(s).  Calling charAt(s,
 * stringLength(s)) character at the end of the string.
 */

char charAt(string s, int i);

/*
 * Function: substring
 * Usage: t = substring(s, p1, p2);
 * --------------------------------
 * Returns a copy of the substring of s consisting of the characters
 * between index positions p1 and p2, inclusive.  The following special
 * cases apply:
 *
 *
 *   If p1 is less than 0, it is assumed to be 0.
 *   If p2 is greater than or equal to the length of the
 *       string, p2 is set to stringLength(s) - 1.
 *   If p2 < p1, substring returns the
 *       empty string.
 *
 */

string substring(string s, int p1, int p2);

/*
 * Function: charToString
 * Usage: s = charToString(ch);
 * ----------------------------
 * Takes a single character and returns a one-character string consisting
 * of that character.  The charToString function is useful, for example, if
 * you need to concatenate a string and a character.  Since concat requires
 * two strings, you must first convert the character into a string.
 */

string charToString(char ch);

/*
 * Function: stringLength
 * Usage: len = stringLength(s);
 * -----------------------------
 * Returns the length of the string s.
 */

int stringLength(string s);

/*
 * Function: copyString
 * Usage: newstr = copyString(s);
 * ------------------------------
 * Copies the string s into dynamically allocated storage and returns the
 * new string.  This function is not ordinarily required when this package
 * is used on its own but is often necessary when you are working with more
 * than one string package.
 */

string copyString(string s);

/* Section 2 -- String comparison functions */

/*
 * Function: stringEqual
 * Usage: if (stringEqual(s1, s2)) ...
 * -----------------------------------
 * Returns true if the strings s1 and s2 are equal.  For the strings to be
 * considered equal, every character in one string must precisely match the
 * corresponding character in the other.  Uppercase and lowercase
 * characters are considered to be different.
 */

bool stringEqual(string s1, string s2);

/*
 * Function: stringEqualIgnoreCase
 * Usage: if (stringEqualIgnoreCase(s1, s2)) ...
 * ---------------------------------------------
 * Returns true if the strings s1 and s2 are equal, ignoring differences in
 * case.
 */

bool stringEqualIgnoreCase(string s1, string s2);

/*
 * Function: stringCompare
 * Usage: if (stringCompare(s1, s2) < 0) ...
 * -----------------------------------------
 * Returns -1 if string s1 comes before s2 in lexicographic order, 0 if
 * they are equal, and +1 if s1 comes after s2.
 */

int stringCompare(string s1, string s2);

/*
 * Function: startsWith
 * Usage: if (startsWith(s1, s2)) ...
 * ----------------------------------
 * Returns true if s1 starts with s2.
 */

bool startsWith(string s1, string s2);

/*
 * Function: endsWith
 * Usage: if (endsWith(s1, s2)) ...
 * --------------------------------
 * Returns true if s1 ends with s2.
 */

bool endsWith(string s1, string s2);

/* Section 3 -- Search functions */

/*
 * Function: findChar
 * Usage: p = findChar(ch, text, start);
 * -------------------------------------
 * Searches for the character ch beginning at position start in the string
 * text and returns the first index at which it appears or -1 if no match
 * is found.
 */

int findChar(char ch, string text, int start);

/*
 * Function: findString
 * Usage: p = findString(str, text, start);
 * ----------------------------------------
 * Searches for the string str beginning at position start in the string
 * text and returns the first index at which it appears or -1 if no match
 * is found.
 */

int findString(string str, string text, int start);

/*
 * Function: findLastChar
 * Usage: p = findLastChar(ch, text);
 * ----------------------------------
 * Returns the last index of ch in text, or -1 if the search value does not
 * appear.
 */

int findLastChar(char ch, string text);

/*
 * Function: findLastString
 * Usage: p = findLastString(str, text);
 * -------------------------------------
 * Returns the last index of str in text, or -1 if the search value does
 * not appear.
 */

int findLastString(string str, string text);

/* Section 4 -- Conversion functions */

/*
 * Function: toLowerCase
 * Usage: s = toLowerCase(s);
 * --------------------------
 * Returns a new string with all alphabetic characters converted to
 * lowercase.
 */

string toLowerCase(string s);

/*
 * Function: toUpperCase
 * Usage: s = toUpperCase(s);
 * --------------------------
 * Returns a new string with all alphabetic characters converted to
 * uppercase.
 */

string toUpperCase(string s);

/*
 * Function: integerToString
 * Usage: s = integerToString(n);
 * ------------------------------
 * Converts an integer into the corresponding string of digits.  For
 * example, integerToString(123) returns "123" as a string.
 */

string integerToString(int n);

/*
 * Function: stringToInteger
 * Usage: n = stringToInteger(s);
 * ------------------------------
 * Converts a string of digits into an integer.  If the string is not a
 * legal integer or contains extraneous characters, stringToInteger signals
 * an error condition.
 */

int stringToInteger(string s);

/*
 * Function: realToString
 * Usage: string  s = realToString(d);
 * -----------------------------------
 * Converts a floating-point number into the corresponding string form. 
 * For example, calling realToString(23.45) returns "23.45".  The
 * conversion is the same as that used for "%G" format in printf.
 */

string realToString(double d);

/*
 * Function: stringToReal
 * Usage: d = stringToReal(s);
 * ---------------------------
 * Converts a string representing a real number into its corresponding
 * value.  If the string is not a legal floating-point number or if it
 * contains extraneous characters, stringToReal signals an error condition.
 */

double stringToReal(string s);

/* Section 5 - Miscellaneous functions */

/*
 * Function: trim
 * Usage: trimmed = trim(str);
 * ---------------------------
 * Returns a new string after removing any whitespace characters from the
 * beginning and end of the argument.
 */

string trim(string str);

/*
 * Function: quoteString
 * Usage: quoted = quoteString(str);
 * ---------------------------------
 * Returns a quoted string that can be read by the C parser.  This string
 * includes double quotes around the entire value, and uses standard escape
 * sequences to indicate special characters.
 */

string quoteString(string str);

/*
 * Function: quoteHTML
 * Usage: quoted = quoteHTML(str);
 * -------------------------------
 * Returns a string that appears correctly in HTML by changing HTML special
 * characters to character entities.
 */

string quoteHTML(string str);

/*
 * Function: stringArrayLength
 * Usage: len = stringArrayLength(array);
 * --------------------------------------
 * Returns the length of a NULL-terminated string array.
 */

int stringArrayLength(string array[]);

/*
 * Function: searchStringArray
 * Usage: index = searchStringArray(str, array);
 * ---------------------------------------------
 * Finds a string in a NULL-terminated string array and returns the first
 * index at which the string appears, or -1 if it is not found.
 */

int searchStringArray(string str, string array[]);

#endif