/*
* ***********************************************************************
*	The following functions are stubs or clones for ansi-library 
*   and special Metrowerks functions.
*   Expect the following link warnings:
 
Link Warning : ignored 'exit' (code) in MSL C.PPC.Lib
Previously defined in printf.c

Link Warning : ignored 'getchar' (code) in MSL C.PPC.Lib
Link Warning : ignored 'fgets' (code) in MSL C.PPC.Lib
Link Warning : ignored 'putchar' (code) in MSL C.PPC.Lib
Link Warning : ignored 'puts' (code) in MSL C.PPC.Lib
Link Warning : ignored 'perror' (code) in MSL C.PPC.Lib
Link Warning : ignored 'fprintf' (code) in MSL C.PPC.Lib
Link Warning : ignored 'printf' (code) in MSL C.PPC.Lib
Link Warning : ignored 'scanf' (code) in MSL C.PPC.Lib
....
*/



/********************************************************************************/
/*	Include Header Files   										                */
/********************************************************************************/
#ifndef __CONSOLE__
#include <console.h>
#endif

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <setjmp.h>
#include "ZipGUI.h"				
#include "helpers.h"

#ifdef HAVE_SYSLOG
#include "syslog.h"
int Print2Syslog(UInt8 priority, const char *format, ...);
#endif

/* These functions are defined as a macro instead of a function.
so we have to undefine them for replacing   */
#undef getc
#undef putc
#undef getchar
#undef putchar




/********************************************************************************/
/*	Globale Variablen definieren												*/
/********************************************************************************/

extern ZipGUI_Globals	g;
extern errno;
volatile jmp_buf EnvForExit;



/* printf clone for code in zip.c, etc. */
int printf(const char *format, ...)
{
va_list argptr;
static char buffer[255];
static flag = 0;
int len;

va_start(argptr, format);
len = vsprintf(buffer, format, argptr);
va_end(argptr);

if (g.BeSilent) return len;

len = fprintf(stdout,"%s", buffer);

return len;
}


#ifdef HAVE_SYSLOG
int Print2Syslog(UInt8 priority, const char *format, ...)
{
int len = 0;
va_list argptr;
static char buffer[255];
static flag = 0;


va_start(argptr, format);
len = vsprintf(buffer, format, argptr);
va_end(argptr);

  if (g.gHasSyslog){
    Openlog (&g.myPsn, LOG_USER);
    Syslog (priority, "%s", buffer);
    Closelog();
  }
return len;
}
#endif


/* fprintf clone for code in zip.c, etc. */
int fprintf(FILE *file, const char *format, ...)
{
va_list argptr;
static char buffer[255];
int len;
Str255		myTitle;
WindowRef	myWindow;

va_start(argptr, format);
len = vsprintf(buffer, format, argptr);
va_end(argptr);

if ((file == stdout) || (file == stderr))
	{
	if (g.BeSilent) return len;
    len = PrintMessage(buffer, MessageWindow);
    
	if (file == stderr) 
		{
#ifdef HAVE_SYSLOG
		Print2Syslog(LOG_ERR, "%s", buffer);
#endif
		myWindow = FrontWindow();
		GetWTitle( myWindow, myTitle );
		PToCCpy(myTitle, buffer);
		if (strcmp(&buffer[strlen(buffer)-9]," *error* ") != 0)
			{
			DoAddString( myTitle, "\p *error* " );
			SetWTitle( myWindow, myTitle );
			}
		}
	}
else
	{
	fprintf(stderr,"\nfprintf: file stream not implemented");
	return -1;
	}

return len;
}




int fputs(const char *parm1, FILE *stream)
{
if ((stream == stdout) || (stream == stderr))
	{
	if (g.BeSilent) return 0;
	fprintf(stream, "%s", parm1);
	return 0;
	}
else
	{
	fprintf(stderr,"\n fputs file stream not implemented");
	return -1;
	}
}



int fputc(int c, FILE *stream)
{
if ((stream == stdout) || (stream == stderr))
	{
	return putc(c, stream);
	}
else
	{
	fprintf(stderr,"\n fputc file stream not implemented");
	return -1;
	}
}




int putchar(int c)
{
return putc(c, stdout);
}




int putc(int c, FILE *stream)
{

if ((stream == stdout) || (stream == stderr))
	{
	if (g.BeSilent) return 0;
	fprintf(stream, "%c",(char) c);
	return 0;
	}
else
	{
	fprintf(stderr,"\n putc stream not implemented");
	return -1;
	}
}




int puts(const char *parm1)
{
int num;

if (g.BeSilent) return 0;
num = fprintf(stdout, "%s%s", parm1,g.LineBreak);

return num;
}



int scanf(const char *format, ...)
{
format = format;
fprintf(stderr,"\nscanf");
return 0;
}




char *fgets(char *string, int len, FILE *stream)
{
char 		ch;
WindowRef	myWindow;
DocumentPtr	myDoc;
TEHandle	myTxtH;
char        *myTxtPtr_end = NULL; 
long		myLength;


if (len <= 1) return "";
				 
if (stream == stdin) 
	{
	myWindow = FrontWindow();
	DoUpdate(myWindow);
	((DocumentPtr)myWindow)->ReadOnly = false;
	myTxtH 			= ((DocumentPtr)myWindow)->docTxt;
	myDoc 			= (DocumentPtr)myWindow;
	
    FreeTextEditBuffer(myTxtH, myDoc);
	TESelView(myTxtH);
	
	myLength 		    = (*myTxtH)->teLength;
	g.InputTxtPtr_start = *(**myDoc->docTxt).hText + (*myTxtH)->teLength;

	ch = waitChar();
	while ((ch != 0xd) && (--len > 0))
		{
		ch = waitChar();
		}
	
	myLength 	   = (*myTxtH)->teLength;
	myTxtPtr_end   =  *(**myDoc->docTxt).hText + myLength;
	g.InputLength  = myTxtPtr_end - g.InputTxtPtr_start;
	
	memcpy(string, g.InputTxtPtr_start, g.InputLength); 
    
	string[g.InputLength+1] = 0;    /* make C-string */
	
	((DocumentPtr)myWindow)->ReadOnly = true;
	if (g.SaveMessages) fwrite( string,  g.InputLength, 1L, g.SaveMessages_fp);

	return string;
	}
else
	{
	fprintf(stderr,"\n fgets stream not implemented");
	return NULL;
	}
	
((DocumentPtr)myWindow)->ReadOnly = true;
return NULL;
}




int getchar()
{
char ch[2], chc;
char *chptr;

chptr = fgets(ch, 1, stdin);
chc = chptr[0];

return (int) chc;
}


void perror(const char *parm1)
{
fprintf(stderr, "%s: errno: [%d]", parm1, errno);
}



void abort(void)
{
exit(-1);
}

void exit(int status)
{
g.ExitResult = status;


if (g.is_EnvForExit_valid == true)  /* call longjmp() only if setjmp() was called */
	{
	g.is_EnvForExit_valid = false;
	longjmp(EnvForExit,status);
	}
}




OSErr printerr(const char *msg,int cond,int err,int line,char *file,const char *msg2)
{
if (cond != 0)
	{
	fprintf(stderr,"\nerr: %d: [%s] %d [%d/%s] [%s]\n",clock(),msg,err,line,file,msg2);
	}
	
return cond;
}




