GDB (API)
|
00001 /* UI_FILE - a generic STDIO like output stream. 00002 Copyright (C) 1999-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 #include "defs.h" 00020 #include "ui-file.h" 00021 #include "tui/tui-file.h" 00022 #include "tui/tui-io.h" 00023 00024 #include "tui.h" 00025 00026 #include "gdb_string.h" 00027 00028 /* A ``struct ui_file'' that is compatible with all the legacy 00029 code. */ 00030 00031 /* new */ 00032 enum streamtype 00033 { 00034 afile, 00035 astring 00036 }; 00037 00038 /* new */ 00039 struct tui_stream 00040 { 00041 int *ts_magic; 00042 enum streamtype ts_streamtype; 00043 FILE *ts_filestream; 00044 char *ts_strbuf; 00045 int ts_buflen; 00046 }; 00047 00048 static ui_file_flush_ftype tui_file_flush; 00049 extern ui_file_fputs_ftype tui_file_fputs; 00050 static ui_file_isatty_ftype tui_file_isatty; 00051 static ui_file_rewind_ftype tui_file_rewind; 00052 static ui_file_put_ftype tui_file_put; 00053 static ui_file_delete_ftype tui_file_delete; 00054 static struct ui_file *tui_file_new (void); 00055 static int tui_file_magic; 00056 00057 static struct ui_file * 00058 tui_file_new (void) 00059 { 00060 struct tui_stream *tui = XMALLOC (struct tui_stream); 00061 struct ui_file *file = ui_file_new (); 00062 00063 set_ui_file_data (file, tui, tui_file_delete); 00064 set_ui_file_flush (file, tui_file_flush); 00065 set_ui_file_fputs (file, tui_file_fputs); 00066 set_ui_file_isatty (file, tui_file_isatty); 00067 set_ui_file_rewind (file, tui_file_rewind); 00068 set_ui_file_put (file, tui_file_put); 00069 tui->ts_magic = &tui_file_magic; 00070 return file; 00071 } 00072 00073 static void 00074 tui_file_delete (struct ui_file *file) 00075 { 00076 struct tui_stream *tmpstream = ui_file_data (file); 00077 00078 if (tmpstream->ts_magic != &tui_file_magic) 00079 internal_error (__FILE__, __LINE__, 00080 _("tui_file_delete: bad magic number")); 00081 if ((tmpstream->ts_streamtype == astring) 00082 && (tmpstream->ts_strbuf != NULL)) 00083 { 00084 xfree (tmpstream->ts_strbuf); 00085 } 00086 xfree (tmpstream); 00087 } 00088 00089 struct ui_file * 00090 tui_fileopen (FILE *stream) 00091 { 00092 struct ui_file *file = tui_file_new (); 00093 struct tui_stream *tmpstream = ui_file_data (file); 00094 00095 tmpstream->ts_streamtype = afile; 00096 tmpstream->ts_filestream = stream; 00097 tmpstream->ts_strbuf = NULL; 00098 tmpstream->ts_buflen = 0; 00099 return file; 00100 } 00101 00102 struct ui_file * 00103 tui_sfileopen (int n) 00104 { 00105 struct ui_file *file = tui_file_new (); 00106 struct tui_stream *tmpstream = ui_file_data (file); 00107 00108 tmpstream->ts_streamtype = astring; 00109 tmpstream->ts_filestream = NULL; 00110 if (n > 0) 00111 { 00112 tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); 00113 tmpstream->ts_strbuf[0] = '\0'; 00114 } 00115 else 00116 /* Do not allocate the buffer now. The first time something is 00117 printed one will be allocated by tui_file_adjust_strbuf(). */ 00118 tmpstream->ts_strbuf = NULL; 00119 tmpstream->ts_buflen = n; 00120 return file; 00121 } 00122 00123 static int 00124 tui_file_isatty (struct ui_file *file) 00125 { 00126 struct tui_stream *stream = ui_file_data (file); 00127 00128 if (stream->ts_magic != &tui_file_magic) 00129 internal_error (__FILE__, __LINE__, 00130 _("tui_file_isatty: bad magic number")); 00131 if (stream->ts_streamtype == afile) 00132 return (isatty (fileno (stream->ts_filestream))); 00133 else 00134 return 0; 00135 } 00136 00137 static void 00138 tui_file_rewind (struct ui_file *file) 00139 { 00140 struct tui_stream *stream = ui_file_data (file); 00141 00142 if (stream->ts_magic != &tui_file_magic) 00143 internal_error (__FILE__, __LINE__, 00144 _("tui_file_rewind: bad magic number")); 00145 stream->ts_strbuf[0] = '\0'; 00146 } 00147 00148 static void 00149 tui_file_put (struct ui_file *file, 00150 ui_file_put_method_ftype *write, 00151 void *dest) 00152 { 00153 struct tui_stream *stream = ui_file_data (file); 00154 00155 if (stream->ts_magic != &tui_file_magic) 00156 internal_error (__FILE__, __LINE__, 00157 _("tui_file_put: bad magic number")); 00158 if (stream->ts_streamtype == astring) 00159 write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf)); 00160 } 00161 00162 /* All TUI I/O sent to the *_filtered and *_unfiltered functions 00163 eventually ends up here. The fputs_unfiltered_hook is primarily 00164 used by GUIs to collect all output and send it to the GUI, instead 00165 of the controlling terminal. Only output to gdb_stdout and 00166 gdb_stderr are sent to the hook. Everything else is sent on to 00167 fputs to allow file I/O to be handled appropriately. */ 00168 00169 /* FIXME: Should be broken up and moved to a TUI specific file. */ 00170 00171 void 00172 tui_file_fputs (const char *linebuffer, struct ui_file *file) 00173 { 00174 struct tui_stream *stream = ui_file_data (file); 00175 00176 if (stream->ts_streamtype == astring) 00177 { 00178 tui_file_adjust_strbuf (strlen (linebuffer), file); 00179 strcat (stream->ts_strbuf, linebuffer); 00180 } 00181 else 00182 { 00183 tui_puts (linebuffer); 00184 } 00185 } 00186 00187 char * 00188 tui_file_get_strbuf (struct ui_file *file) 00189 { 00190 struct tui_stream *stream = ui_file_data (file); 00191 00192 if (stream->ts_magic != &tui_file_magic) 00193 internal_error (__FILE__, __LINE__, 00194 _("tui_file_get_strbuf: bad magic number")); 00195 return (stream->ts_strbuf); 00196 } 00197 00198 /* Adjust the length of the buffer by the amount necessary to 00199 accomodate appending a string of length N to the buffer 00200 contents. */ 00201 void 00202 tui_file_adjust_strbuf (int n, struct ui_file *file) 00203 { 00204 struct tui_stream *stream = ui_file_data (file); 00205 int non_null_chars; 00206 00207 if (stream->ts_magic != &tui_file_magic) 00208 internal_error (__FILE__, __LINE__, 00209 _("tui_file_adjust_strbuf: bad magic number")); 00210 00211 if (stream->ts_streamtype != astring) 00212 return; 00213 00214 if (stream->ts_strbuf) 00215 { 00216 /* There is already a buffer allocated. */ 00217 non_null_chars = strlen (stream->ts_strbuf); 00218 00219 if (n > (stream->ts_buflen - non_null_chars - 1)) 00220 { 00221 stream->ts_buflen = n + non_null_chars + 1; 00222 stream->ts_strbuf = xrealloc (stream->ts_strbuf, stream->ts_buflen); 00223 } 00224 } 00225 else 00226 /* No buffer yet, so allocate one of the desired size. */ 00227 stream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); 00228 } 00229 00230 static void 00231 tui_file_flush (struct ui_file *file) 00232 { 00233 struct tui_stream *stream = ui_file_data (file); 00234 00235 if (stream->ts_magic != &tui_file_magic) 00236 internal_error (__FILE__, __LINE__, 00237 _("tui_file_flush: bad magic number")); 00238 00239 switch (stream->ts_streamtype) 00240 { 00241 case astring: 00242 break; 00243 case afile: 00244 fflush (stream->ts_filestream); 00245 break; 00246 } 00247 }