/*****
 NAME
  	csystem-test.m - test program for CSystem class
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/csystem.h>
#include <coconut/cmessage.h>
#include <coconut/cfile.h>
#include <stdlib.h>

@interface CSystemWrapper : CSystem <PSystem>
{
}

@end

@implementation CSystemWrapper

- (id <PError>) prologue: (int) argc argv: (const char **) argv
{
	jmp_buf env ;

	printf("prologue.\n") ;
	printf("usage:\n") ;
	[self printUsage] ;

	printf("version:\n") ;
	[self printVersion] ;

	printf("help string is \"%s\"\n", [self helpString]) ;

	[super prologue: argc argv:argv] ;

	printf("Oh No, exception is occured in prologue\n") ;
	[CSystem getJump: &env] ;
	longjmp(env, (int) can_not_continue_err) ;

	return no_error ;
}

- (id <PError>) main
{
	id <PError>		err ;
	id <PFile>		stream ;
	const char 		envname[] = "COCONUT_ENV" ;
	const char 		envval[] = "Hello" ;
	jmp_buf env ;

	/* open standart output */
	stream = [[CFile alloc] init] ;
	err = [stream open: write_open name: NULL] ;
	if(err != nil){
		printf("ERROR: can not open standard output\n");
		exit(1) ;
	}

	printf("--- set and get environment variable:\n") ;
	[CSystem setEnv: envname value: envval] ;
	printf("search env var \"%s\" ... result \"%s\"\n", envname,
	  [CSystem getEnv: envname]) ;

	printf("--- print message(1):\n") ;
	[CMessage setErrorStream: stream] ;
	[CMessage message: note_message code: 0 format: "main."] ;
	printf("--- print message(2):\n") ;
	[CMessage message: note_message code: 0 format: 
	  "the application name is \"%s\"", [CSystem applicationName]] ;
	[super main] ;

	printf("--- print message(3):\n") ;
	[CMessage message: note_message code: 0 format: "warning message:"] ;
	printf("--- print message(4):\n") ;
	[CMessage message: error_message code: (int) can_not_happen_err
	  format: "this is %s test", "format"] ;

	printf("--- print message(5):\n") ;
	[CMessage message: note_message code: (int) 0
	  format:"Oh No, exception is occured in main"] ;
	[CSystem getJump: &env] ;
	longjmp(env, (int) can_not_continue_err) ;

	[stream close] ;
	[stream release] ;

	return no_error ;
}

- exitMainLoop: (id <PError>) err
{
	printf("exit main loop: code %x \n", err ? [err code] : 0) ;
	return [super exitMainLoop: err] ;
}

- (u_int) getMainLoopNest
{
	printf("getMainLoopNest:\n");
	return [super getMainLoopNest] ;
}

- retainMainLoop
{
	printf("retainMainLoop:\n");
	return [super retainMainLoop] ;
}

- releaseMainLoop: (id <PError>) err
{
	printf("releaseMainLoop: code %d\n", err ? [err code] : 0);
	return [super releaseMainLoop: err] ;
}

- (id <PError>) epilogue: (id <PError>) preerror
{
	jmp_buf env ;

	printf("epilogue.\n") ;
	[super epilogue: preerror] ;

	printf("Oh No, exception is occured in epilogue\n") ;
	[CSystem getJump: &env] ;
	longjmp(env, (int) can_not_continue_err) ;

	return no_error ;
}

- (const char *) applicationName
{
	printf("applicationName.\n") ;
	return [CSystem applicationName] ;
}

- (id <PError>) setupOption: (id <POptParser>) parser
{
	printf("setup option\n");
	return no_error ;
}

- (id <PError>) decodeOption: (id <POptParser>) parser
{
	printf("decode option\n");
	return no_error ;
}

- (id <PError>) analyzeOption: (id <POptParser>) parser
{
	printf("analyze option\n");
	return no_error ;
}

- (id <PObstack>) systemObstack
{
	printf("systemObstack.\n") ;
	return [super systemObstack] ;
}

- (id <PError>) recoverPrologue: (id <PError>) preerror 
{
	printf("recoverPrologue: %x\n", [preerror code]) ;
	printf(" recovering is succeded.\n") ;
	return no_error ;
}

- (id <PError>) recoverMain: (id <PError>) preerror 
{
	printf("recoverMain: %x\n", [preerror code]) ;
	printf(" recovering is succeded.\n") ;
	return no_error ;
}

- (id <PError>) recoverEpilogue: (id <PError>) preerror 
{
	printf("recoverEpilogue: %x\n", [preerror code]) ;
	printf(" recovering is succeded.\n") ;
	return no_error ;
}

- (const utf8_char *) helpString
{
	return [super helpString] ;
}

- printUsage
{
	printf("this software is useless. (^_^;)\n") ;
	return nil ;
}

- printVersion
{
	printf("this software version is %s\n", COCONUT_VERSION) ;
	return nil ;
}

@end

int main(int argc, const char **argv){
	id system ;
	int status ;
	printf("argv[0] = %s\n", &(argv[0][0])) ;
	system = [[CSystemWrapper alloc] init] ;
	status = start_program(system, argc, argv) ;
	printf("bye (code %d, %s)\n", status, [system applicationName]) ;
	[system release] ;
	return 0 ; /* ignore previous error */
}

