#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#include "console.h"
#if defined(HAVE_TERMCAP)
#include <curses.h>
#include <term.h>
#if defined(HAVE_TERMCAP_H)
# include <termcap.h>
#elif defined(HAVE_NCURSES_TERMCAP_H)
# include <ncurses/termcap.h>
#endif
#endif
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
#define CLASS_ID 0x434F4E53
#define REPORT_BUFF_SIZE 1024
/*
* Taken from Termcap_Manual.html:
*
* With the Unix version of termcap, you must allocate space for the description yourself and pass
* the address of the space as the argument buffer. There is no way you can tell how much space is
* needed, so the convention is to allocate a buffer 2048 characters long and assume that is
* enough. (Formerly the convention was to allocate 1024 characters and assume that was enough.
* But one day, for one kind of terminal, that was not enough.)
*/
Console_IO_t* open_console ( int debug )
{
Console_IO_t* const mfp = calloc ( 1, sizeof (*mfp) );
#ifdef TERMCAP_AVAILABLE
const char* term_name;
char term_buff [2048];
char* tp;
char tc [10];
int val;
#endif
/* setup basics of brhist I/O channels */
mfp -> disp_width = 80;
mfp -> disp_height = 25;
mfp -> Console_fp = stderr;
mfp -> Error_fp = stderr;
mfp -> Report_fp = debug ? fopen ( "/tmp/lame_reports", "a" ) : NULL;
mfp -> Console_buff = calloc ( 1, REPORT_BUFF_SIZE );
setvbuf ( mfp -> Console_fp, mfp -> Console_buff, _IOFBF, REPORT_BUFF_SIZE );
/* setvbuf ( mfp -> Error_fp , NULL , _IONBF, 0 ); */
#if defined(_WIN32) && !defined(__CYGWIN__)
mfp -> Console_Handle = GetStdHandle (STD_ERROR_HANDLE);
#endif
strcpy ( mfp -> str_up, "\033[A" );
#ifdef TERMCAP_AVAILABLE
/* try to catch additional information about special console sequences */
if ((term_name = getenv("TERM")) == NULL) {
fprintf ( mfp -> Error_fp, "LAME: Can't get \"TERM\" environment string.\n" );
return -1;
}
if ( tgetent (term_buff, term_name) != 1 ) {
fprintf ( mfp -> Error_fp, "LAME: Can't find termcap entry for terminal \"%s\"\n", term_name );
return -1;
}
val = tgetnum ("co");
if ( val >= 40 && val <= 512 )
mfp -> disp_width = val;
val = tgetnum ("li");
if ( val >= 16 && val <= 256 )
mfp -> disp_height = val;
*(tp = tc) = '\0';
tp = tgetstr ("up", &tp);
if (tp != NULL)
strcpy ( mfp -> str_up, tp );
*(tp = tc) = '\0';
tp = tgetstr ("ce", &tp);
if (tp != NULL)
strcpy ( mfp -> str_clreoln, tp );
*(tp = tc) = '\0';
tp = tgetstr ("md", &tp);
if (tp != NULL)
strcpy ( mfp -> str_emph, tp );
*(tp = tc) = '\0';
tp = tgetstr ("me", &tp);
if (tp != NULL)
strcpy ( mfp -> str_norm, tp );
#endif /* TERMCAP_AVAILABLE */
return mfp;
}
/* printf for console */
int Console_printf ( Console_IO_t* const mfp, const char* const format, ... )
{
va_list args;
int ret;
va_start ( args, format );
ret = vfprintf ( mfp -> Console_fp, s, args );
va_end ( args );
return ret;
}
/* printf for errors */
int Error_printf ( Console_IO_t* const mfp, const char* const format, ... )
{
va_list args;
int ret;
va_start ( args, format );
ret = vfprintf ( mfp -> Error_fp, s, args );
va_end ( args );
flush ( mfp -> Error_fp );
return ret;
}
/* printf for additional reporting information */
int Report_printf ( Console_IO_t* const mfp, const char* const format, ... )
{
va_list args;
int ret;
if ( mfp -> Report_fp != NULL ) {
va_start ( args, format );
ret = vfprintf ( mfp -> Report_fp, s, args );
va_end ( args );
return ret;
}
return 0;
}
int close_console ( Console_IO_t* const mfp )
{
if ( mfp == NULL || mfp -> ClassID != CLASS_ID || mfp -> Console_buff == NULL )
return -1;
fflush ( mfp -> Console_fp );
setvbuf ( mfp -> Console_fp, NULL, _IONBF, (size_t)0 );
memset ( mfp -> Console_buff, 0x55, REPORT_BUFF_SIZE );
free ( mfp -> Console_buff );
memset ( mfp, 0x55, sizeof (*mfp) );
free ( mfp );
return 0;
}
/* end of console.c */