00001 #ifdef HAVE_CONFIG_H
00002 # include <config.h>
00003 #endif
00004
00005 #ifdef STDC_HEADERS
00006 # include <stdlib.h>
00007 # include <string.h>
00008 #else
00009 # ifndef HAVE_STRCHR
00010 # define strchr index
00011 # define strrchr rindex
00012 # endif
00013 char *strchr(), *strrchr();
00014 # ifndef HAVE_MEMCPY
00015 # define memcpy(d, s, n) bcopy ((s), (d), (n))
00016 # define memmove(d, s, n) bcopy ((s), (d), (n))
00017 # endif
00018 #endif
00019
00020 #if defined(HAVE_NCURSES_TERMCAP_H)
00021 # include <ncurses/termcap.h>
00022 #elif defined(HAVE_TERMCAP_H)
00023 # include <termcap.h>
00024 #elif defined(HAVE_TERMCAP)
00025 # include <curses.h>
00026 # if !defined(__bsdi__)
00027 # include <term.h>
00028 # endif
00029 #endif
00030
00031 #include <stdio.h>
00032 #include <stdarg.h>
00033 #include "console.h"
00034
00035 #ifdef WITH_DMALLOC
00036 #include <dmalloc.h>
00037 #endif
00038
00039 #define CLASS_ID 0x434F4E53
00040 #define REPORT_BUFF_SIZE 1024
00041
00042 #if defined(_WIN32) && !defined(__CYGWIN__)
00043 # include <windows.h>
00044 #endif
00045
00046
00047
00048 static int
00049 my_console_printing(FILE * fp, const char *format, va_list ap)
00050 {
00051 if (fp != NULL)
00052 return vfprintf(fp, format, ap);
00053 return 0;
00054 }
00055
00056 static int
00057 my_error_printing(FILE * fp, const char *format, va_list ap)
00058 {
00059 if (fp != NULL)
00060 return vfprintf(fp, format, ap);
00061 return 0;
00062 }
00063
00064 static int
00065 my_report_printing(FILE * fp, const char *format, va_list ap)
00066 {
00067 if (fp != NULL)
00068 return vfprintf(fp, format, ap);
00069 return 0;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #ifdef HAVE_TERMCAP
00084 static void
00085 apply_termcap_settings(Console_IO_t * const mfp)
00086 {
00087 const char *term_name;
00088 char term_buff[2048];
00089 char *tp;
00090 char tc[10];
00091 int val;
00092
00093
00094
00095 if ((term_name = getenv("TERM")) == NULL) {
00096
00097
00098
00099
00100 return;
00101
00102
00103
00104
00105 }
00106 if (tgetent(term_buff, term_name) != 1) {
00107
00108
00109
00110
00111 return;
00112
00113
00114
00115
00116 }
00117
00118 val = tgetnum("co");
00119 if (val >= 40 && val <= 512)
00120 mfp->disp_width = val;
00121 val = tgetnum("li");
00122 if (val >= 16 && val <= 256)
00123 mfp->disp_height = val;
00124
00125 *(tp = tc) = '\0';
00126 tp = tgetstr("up", &tp);
00127 if (tp != NULL)
00128 strcpy(mfp->str_up, tp);
00129
00130 *(tp = tc) = '\0';
00131 tp = tgetstr("ce", &tp);
00132 if (tp != NULL)
00133 strcpy(mfp->str_clreoln, tp);
00134
00135 *(tp = tc) = '\0';
00136 tp = tgetstr("md", &tp);
00137 if (tp != NULL)
00138 strcpy(mfp->str_emph, tp);
00139
00140 *(tp = tc) = '\0';
00141 tp = tgetstr("me", &tp);
00142 if (tp != NULL)
00143 strcpy(mfp->str_norm, tp);
00144 }
00145 #endif
00146
00147 static int
00148 init_console(Console_IO_t * const mfp)
00149 {
00150
00151 mfp->disp_width = 80;
00152 mfp->disp_height = 25;
00153 mfp->Console_fp = stderr;
00154 mfp->Error_fp = stderr;
00155 mfp->Report_fp = NULL;
00156
00157
00158 setvbuf(mfp->Console_fp, mfp->Console_buff, _IOFBF, sizeof(mfp->Console_buff));
00159
00160
00161 #if defined(_WIN32) && !defined(__CYGWIN__)
00162 mfp->Console_Handle = GetStdHandle(STD_ERROR_HANDLE);
00163 #endif
00164
00165 strcpy(mfp->str_up, "\033[A");
00166
00167 #ifdef HAVE_TERMCAP
00168 apply_termcap_settings(mfp);
00169 #endif
00170
00171 mfp->ClassID = CLASS_ID;
00172
00173 #if defined(_WIN32) && !defined(__CYGWIN__)
00174 mfp->Console_file_type = GetFileType(Console_IO.Console_Handle);
00175 #else
00176 mfp->Console_file_type = 0;
00177 #endif
00178 return 0;
00179 }
00180
00181 static void
00182 deinit_console(Console_IO_t * const mfp)
00183 {
00184 if (mfp->Report_fp != NULL) {
00185 fclose(mfp->Report_fp);
00186 mfp->Report_fp = NULL;
00187 }
00188 fflush(mfp->Console_fp);
00189 setvbuf(mfp->Console_fp, NULL, _IONBF, (size_t) 0);
00190
00191 memset(mfp->Console_buff, 0x55, REPORT_BUFF_SIZE);
00192 }
00193
00194
00195
00196
00197 Console_IO_t Console_IO;
00198
00199 int
00200 frontend_open_console(void)
00201 {
00202 return init_console(&Console_IO);
00203 }
00204
00205 void
00206 frontend_close_console(void)
00207 {
00208 deinit_console(&Console_IO);
00209 }
00210
00211 void
00212 frontend_debugf(const char *format, va_list ap)
00213 {
00214 (void) my_report_printing(Console_IO.Report_fp, format, ap);
00215 }
00216
00217 void
00218 frontend_msgf(const char *format, va_list ap)
00219 {
00220 (void) my_console_printing(Console_IO.Console_fp, format, ap);
00221 }
00222
00223 void
00224 frontend_errorf(const char *format, va_list ap)
00225 {
00226 (void) my_error_printing(Console_IO.Error_fp, format, ap);
00227 }
00228
00229 int
00230 console_printf(const char *format, ...)
00231 {
00232 va_list args;
00233 int ret;
00234
00235 va_start(args, format);
00236 ret = my_console_printing(Console_IO.Console_fp, format, args);
00237 va_end(args);
00238
00239 return ret;
00240 }
00241
00242 int
00243 error_printf(const char *format, ...)
00244 {
00245 va_list args;
00246 int ret;
00247
00248 va_start(args, format);
00249 ret = my_console_printing(Console_IO.Error_fp, format, args);
00250 va_end(args);
00251
00252 return ret;
00253 }
00254
00255 int
00256 report_printf(const char *format, ...)
00257 {
00258 va_list args;
00259 int ret;
00260
00261 va_start(args, format);
00262 ret = my_console_printing(Console_IO.Report_fp, format, args);
00263 va_end(args);
00264
00265 return ret;
00266 }
00267
00268 void
00269 console_flush()
00270 {
00271 fflush(Console_IO.Console_fp);
00272 }
00273
00274 void
00275 error_flush()
00276 {
00277 fflush(Console_IO.Error_fp);
00278 }
00279
00280 void
00281 report_flush()
00282 {
00283 fflush(Console_IO.Report_fp);
00284 }
00285
00286 void
00287 console_up(int n_lines)
00288 {
00289 #if defined(_WIN32) && !defined(__CYGWIN__)
00290 if (Console_IO.Console_file_type != FILE_TYPE_PIPE) {
00291 COORD Pos;
00292 CONSOLE_SCREEN_BUFFER_INFO CSBI;
00293
00294 console_flush();
00295 GetConsoleScreenBufferInfo(Console_IO.Console_Handle, &CSBI);
00296 Pos.Y = CSBI.dwCursorPosition.Y - n_lines;
00297 Pos.X = 0;
00298 SetConsoleCursorPosition(Console_IO.Console_Handle, Pos);
00299 }
00300 #else
00301 while (n_lines-- > 0)
00302 fputs(Console_IO.str_up, Console_IO.Console_fp);
00303 console_flush();
00304 #endif
00305 }
00306
00307
00308 void
00309 set_debug_file(const char *fn)
00310 {
00311 if (Console_IO.Report_fp == NULL) {
00312 Console_IO.Report_fp = fopen(fn, "a");
00313 if (Console_IO.Report_fp != NULL) {
00314 error_printf("writing debug info into: %s\n", fn);
00315 }
00316 else {
00317 error_printf("Error: can't open for debug info: %s\n", fn);
00318 }
00319 }
00320 }
00321
00322