/*
 *   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __DEJAGNU_H__
#define __DEJAGNU_H__

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

/* If you have problems with dejagnu dropping failed, untested, or
 * unresolved messages generated by a unit testcase,
 */

/* #define _DEJAGNU_WAIT_
 */

#ifdef _DEJAGNU_WAIT_
#      include <sys/time.h>
#      include <sys/types.h>
#      include <unistd.h>
#endif

#define _BUFFER_SIZE_ 512

static int passed;
static int failed;
static int untest;
static int unresolve;

static char buffer[ _BUFFER_SIZE_ ];

#ifdef _DEJAGNU_WAIT_
void
wait(void) {
       fd_set rfds;
       struct timeval tv;

       FD_ZERO(&rfds);
       tv.tv_sec = 0;
       tv.tv_usec = 1;

       select(0, &rfds, NULL, NULL, &tv);
}
#endif

inline void
pass (const char* fmt, ... ) {
	va_list ap;
	
    passed++;
	va_start( ap, fmt );
	vsnprintf( buffer, _BUFFER_SIZE_, fmt, ap );
	va_end( ap );
    printf ("\tPASSED: %s\n", buffer );
#ifdef _DEJAGNU_WAIT_
       wait();
#endif
}

inline void
fail (const char* fmt, ... ) {
	va_list ap;

    failed++;
	va_start( ap, fmt );
	vsnprintf( buffer, _BUFFER_SIZE_, fmt, ap );
	va_end( ap );
    printf ("\tFAILED: %s\n", buffer );
#ifdef _DEJAGNU_WAIT_
       wait();
#endif
}

inline void
untested (const char* fmt, ... ) {
	va_list ap;

    untest++;
	va_start( ap, fmt );
	vsnprintf( buffer, _BUFFER_SIZE_, fmt, ap );
	va_end( ap );
    printf ("\tUNTESTED: %s\n", buffer );
#ifdef _DEJAGNU_WAIT_
       wait();
#endif
}

inline void
unresolved (const char* fmt, ... ) {
	va_list ap;

    unresolve++;
	va_start( ap, fmt );
	vsnprintf( buffer, _BUFFER_SIZE_, fmt, ap );
	va_end( ap );
    printf ("\tUNRESOLVED: %s\n", buffer );
#ifdef _DEJAGNU_WAIT_
       wait();
#endif
}

inline void
note (const char* fmt, ... ) {
	va_list ap;

	va_start( ap, fmt );
	vsnprintf( buffer, _BUFFER_SIZE_, fmt, ap );
	va_end( ap );
    printf ("\tNOTE: %s\n", buffer );
#ifdef _DEJAGNU_WAIT_
       wait();
#endif
}

inline void
totals (void) {
    printf ("\nTotals:\n");
    printf ("\t#passed:\t\t%d\n", passed);
    printf ("\t#failed:\t\t%d\n", failed);
    if (untest)
        printf ("\t#untested:\t\t%d\n", untest);
    if (unresolve)
        printf ("\t#unresolved:\t\t%d\n", unresolved);
}

#ifdef __cplusplus


#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#if 0
#ifdef __STDC___
#include <sstream>
#else
#include <strstream>
#endif
#endif

const char *outstate_list[] = {
    "FAILED: ",
    "PASSED: ",
    "UNTESTED: ",
    "UNRESOLVED: "
};

const char ** outstate = outstate_list;

#if 0
extern ios& __iomanip_testout (ios&, int);
inline smanip<int> testout (int n) {
    return smanip<int> (__iomanip_testout, n);
}
ios & __iomanip_testout (ios& i, int x) {
    return i;
}

template<class T>
class OMANIP {
 private:
    T i;
    ostream &(*f)(ostream&, T);
 public:
    OMANIP(ostream& (*ff)(ostream&, T), T ii) : f(ff), i(ii) {
    }
    friend ostream operator<<(ostream& us, OMANIP& m) {
      return m.f(os,m.i);
    }
};

ostream&
freakout(ostream& os, int x) {
    return os << "FREAKOUT" ;
//    return x << "TESTOUT " << x ;
}

OMANIP<int> testout(int i) {
    return OMANIP<int>(&freakout,i);
}
#endif

enum teststate {FAILED, PASSED,UNTESTED,UNRESOLVED} laststate;

class TestState {
 private:
    teststate laststate;
    std::string lastmsg;
 public:
    TestState(void) {
        passed = 0;
        failed = 0;
        untest = 0;
        unresolve = 0;
    }
    ~TestState(void) {
        totals();
    };

    void testrun (bool b, std::string s) {
        if (b)
            pass (s);
        else
            fail (s);
    }

    void pass (std::string s) {
        passed++;
        laststate = PASSED;
        lastmsg = s;
        std::cout << "\t" << outstate[PASSED] << s << std::endl;
    }
    void pass (const char *c) {
        std::string s = c;
        pass (s);
    }

    void fail (std::string s) {
        failed++;
        laststate = FAILED;
        lastmsg = s;
        std::cout << "\t" << outstate[FAILED] << s << std::endl;
    }
    void fail (const char *c) {
        std::string s = c;
        fail (s);
    }

    void untested (std::string s) {
        untest++;
        laststate = UNTESTED;
        lastmsg = s;
        std::cout << "\t" << outstate[UNTESTED] << s << std::endl;
    }
    void untested (const char *c) {
        std::string s = c;
        untested (s);
    }

    void unresolved (std::string s) {
        unresolve++;
        laststate = UNRESOLVED;
        lastmsg = s;
        std::cout << "\t" << outstate[UNRESOLVED] << s << std::endl;
    }
    void unresolved (const char *c) {
        std::string s = c;
        unresolved (s);
    }

    void totals (void) {
        std::cout << "\t#passed:\t\t" << passed << std::endl;
        std::cout << "\t#failed:\t\t" << failed << std::endl;
        if (untest)
            std::cout << "\t#untested:\t\t" << untest << std::endl;
        if (unresolve)
            std::cout << "\t#unresolved:\t\t" << unresolve << std::endl;
    }

    // This is so this class can be printed in an ostream.
    friend std::ostream & operator << (std::ostream &os, TestState& t) {
        return os << "\t" << outstate[t.laststate] << t.lastmsg ;
    }

    int GetState(void) {
        return laststate;
    }
    std::string GetMsg(void) {
        return lastmsg;
    }
};

#endif		// __cplusplus
#endif          // _DEJAGNU_H_


