#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 */