#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "gccprefs.hh"
#include "output.hh"
File_Writer cout = File_Writer(stdout);
File_Writer cerr = File_Writer(stderr);
File_Writer::File_Writer(String file_name)
{
char array[FILENAME_MAX];
f = fopen(file_name.to_char_star(array,FILENAME_MAX),"wb");
ours_to_close = true;
}
File_Writer::File_Writer(const char* file_name)
{
f = fopen(file_name,"wb");
ours_to_close = true;
}
File_Writer::File_Writer(FILE* f)
{
this->f = f;
ours_to_close = false;
}
File_Writer::~File_Writer()
{
if (ours_to_close) fclose(f);
}
Writer& File_Writer::operator << (const char* string)
{
fprintf(f,"%s",string);
return *this;
}
Writer& File_Writer::operator<< (char ch)
{
fprintf(f,"%c",ch);
return *this;
}
Writer& File_Writer::operator<< (int i)
{
fprintf(f,"%d",i);
return *this;
}
Writer& File_Writer::operator<< (double d)
{
fprintf(f,"%f",d);
return *this;
}
int
String::number_of_errors;
static int my_strncpy(char* to, const char* from, int mem_size)
{
if (from == null) { *to = '\0';
return 0;
}
int i = 0;
int max = mem_size-1;
while ((*to++ = *from++)) {
if (++i >= max) {
*to++ = '\0';
return max;
}
}
return i;
}
String::String() {
p = new String_Internal();
}
String::String(const String& x) : Writer() {
p = x.p;
p->n++;
}
String::String(const char* s) {
p = new String_Internal();
p->length = my_strncpy(p->array,s,string_internal_mem);
}
String::~String() {
if (--p->n == 0) {
delete p;
}
}
String&
String::operator= (const char* s)
{
if (p->n > 1) { p->n--;
p = new String_Internal();
}
p->length = my_strncpy(p->array, s, string_internal_mem);
return *this;
}
String&
String::operator= (const String& x)
{
x.p->n++; if (--p->n == 0) {
delete p;
}
p = x.p;
return *this;
}
bool
operator== (const String& x, const String& y)
{
return x.p == y.p;
}
bool
operator!= (const String& x, const String& y)
{
return x.p != y.p;
}
bool
String::equals(const String& x) const
{
return strings_equal(p->array,x.p->array);
}
bool
String::equals(const char* s) const
{
return strings_equal(p->array,s);
}
void
String::set_char_at(int index, char ch)
{
ASSERT(0 <= index);
if (index >= p->length) {
cerr << "Called set_char_at with index = " << index
<< " but p->length = " << p->length << endl;
return;
}
p->array[index] = ch;
}
char
String::char_at(int index) const
{
ASSERT(0 <= index);
ASSERT(index < p->length);
return p->array[index];
}
int
String::length() const
{
return p->length;
}
char*
String::to_char_star(char* s, int mem_size) const
{
my_strncpy(s,p->array,MIN(mem_size,string_internal_mem));
return s;
}
Writer&
String::operator<< (char ch)
{
if (p->length < string_internal_max_len) {
p->array[p->length++] = ch;
p->array[p->length] = '\0';
}
else {
cerr << "*** Warning: string too long for char\n";
ASSERT(++number_of_errors < 10);
}
return *this;
}
Writer&
String::operator<< (const char* string)
{
while (*string) {
if (p->length < string_internal_max_len) {
p->array[p->length++] = *string++;
}
else {
cerr << "*** Warning: string too long for char*\n";
ASSERT(++number_of_errors < 10);
p->array[p->length] = '\0';
return *this;
}
}
p->array[p->length] = '\0';
return *this;
}
Writer&
String::operator<< (int i)
{
char tmp[100];
sprintf(tmp,"%d",i);
*this << tmp;
return *this;
}
Writer&
String::operator<< (double d)
{
char tmp[100];
sprintf(tmp,"%f",d);
*this << tmp;
return *this;
}
Writer&
operator<<(Writer& w, const String& x)
{
w << x.p->array;
return w;
}
String
String::to_quoted_string() const
{
int len = length();
String s;
s << '"';
for (int i=0; i<len; i++)
{
char ch = char_at(i);
if (ch == '"') {
s << '\\' << '"';
}
else if (ch == '\\') {
s << '\\' << '\\';
}
else if (ch == '\t') {
s << '\\' << 't';
}
else if (ch == '\n') {
s << '\\' << 'n';
}
else if (ch == '\r') {
s << '\\' << 'r';
}
else {
s << ch;
}
}
s << '"';
return s;
}
String
String::to_substring(int start, int stop) const
{
if (start < 0) start += length();
if (stop < 0) stop += length();
String temp = "";
for (int i=start; i<stop; i++) {
temp << char_at(i);
}
return temp;
}
String
String::to_reverse() const
{
String temp = "";
for (int i=length()-1; i>=0; i--) {
temp << char_at(i);
}
return temp;
}
String
String::to_capitalised() const
{
bool last_was_space = true;
String temp = "";
for (int i=0; i<length(); i++) {
char ch = char_at(i);
if (last_was_space) {
ch = toupper(ch);
}
if (ch == ' ') {
last_was_space = true;
}
else {
last_was_space = false;
}
temp << ch;
}
return temp;
}
String
String::clone() const
{
String x = String();
x.p->length = p->length;
strcpy(x.p->array,p->array);
return x;
}
void io_assert(const char* test, const char* file, int line)
{
cerr << "*** Assertion "
<< "(" << file << ":" << line << ") "
<< "failed: " << test << endl;
exit(EXIT_FAILURE);
}