File: | src/gnu/usr.bin/binutils/gdb/tui/tui-source.c |
Warning: | line 127, column 19 Null pointer passed as 1st argument to string length function |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* TUI display source window. | |||
2 | ||||
3 | Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software | |||
4 | Foundation, Inc. | |||
5 | ||||
6 | Contributed by Hewlett-Packard Company. | |||
7 | ||||
8 | This file is part of GDB. | |||
9 | ||||
10 | This program is free software; you can redistribute it and/or modify | |||
11 | it under the terms of the GNU General Public License as published by | |||
12 | the Free Software Foundation; either version 2 of the License, or | |||
13 | (at your option) any later version. | |||
14 | ||||
15 | This program is distributed in the hope that it will be useful, | |||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
18 | GNU General Public License for more details. | |||
19 | ||||
20 | You should have received a copy of the GNU General Public License | |||
21 | along with this program; if not, write to the Free Software | |||
22 | Foundation, Inc., 59 Temple Place - Suite 330, | |||
23 | Boston, MA 02111-1307, USA. */ | |||
24 | ||||
25 | #include "defs.h" | |||
26 | #include <ctype.h> | |||
27 | #include "symtab.h" | |||
28 | #include "frame.h" | |||
29 | #include "breakpoint.h" | |||
30 | #include "source.h" | |||
31 | #include "symtab.h" | |||
32 | ||||
33 | #include "tui/tui.h" | |||
34 | #include "tui/tui-data.h" | |||
35 | #include "tui/tui-stack.h" | |||
36 | #include "tui/tui-winsource.h" | |||
37 | #include "tui/tui-source.h" | |||
38 | ||||
39 | #include "gdb_string.h" | |||
40 | #include "gdb_curses.h" | |||
41 | ||||
42 | /* Function to display source in the source window. */ | |||
43 | enum tui_status | |||
44 | tui_set_source_content (struct symtab *s, int line_no, int noerror) | |||
45 | { | |||
46 | enum tui_status ret = TUI_FAILURE; | |||
47 | ||||
48 | if (s != (struct symtab *) NULL((void*)0) && s->filename != (char *) NULL((void*)0)) | |||
| ||||
49 | { | |||
50 | FILE *stream; | |||
51 | int i, desc, c, line_width, nlines; | |||
52 | char *src_line = 0; | |||
53 | ||||
54 | if ((ret = tui_alloc_source_buffer (TUI_SRC_WINtui_win_list[SRC_WIN])) == TUI_SUCCESS) | |||
55 | { | |||
56 | line_width = TUI_SRC_WINtui_win_list[SRC_WIN]->generic.width - 1; | |||
57 | /* Take hilite (window border) into account, when calculating | |||
58 | the number of lines */ | |||
59 | nlines = (line_no + (TUI_SRC_WINtui_win_list[SRC_WIN]->generic.height - 2)) - line_no; | |||
60 | desc = open_source_file (s); | |||
61 | if (desc < 0) | |||
62 | { | |||
63 | if (!noerror) | |||
64 | { | |||
65 | char *name = alloca (strlen (s->filename) + 100)__builtin_alloca(strlen (s->filename) + 100); | |||
66 | sprintf (name, "%s:%d", s->filename, line_no); | |||
67 | print_sys_errmsg (name, errno(*__errno())); | |||
68 | } | |||
69 | ret = TUI_FAILURE; | |||
70 | } | |||
71 | else | |||
72 | { | |||
73 | if (s->line_charpos == 0) | |||
74 | find_source_lines (s, desc); | |||
75 | ||||
76 | if (line_no < 1 || line_no > s->nlines) | |||
77 | { | |||
78 | close (desc); | |||
79 | printf_unfiltered ( | |||
80 | "Line number %d out of range; %s has %d lines.\n", | |||
81 | line_no, s->filename, s->nlines); | |||
82 | } | |||
83 | else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0) | |||
84 | { | |||
85 | close (desc); | |||
86 | perror_with_name (s->filename); | |||
87 | } | |||
88 | else | |||
89 | { | |||
90 | int offset, cur_line_no, cur_line, cur_len, threshold; | |||
91 | struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); | |||
92 | struct tui_source_info * src = &TUI_SRC_WINtui_win_list[SRC_WIN]->detail.source_info; | |||
93 | ||||
94 | if (TUI_SRC_WINtui_win_list[SRC_WIN]->generic.title) | |||
95 | xfree (TUI_SRC_WINtui_win_list[SRC_WIN]->generic.title); | |||
96 | TUI_SRC_WINtui_win_list[SRC_WIN]->generic.title = xstrdup (s->filename); | |||
97 | ||||
98 | if (src->filename) | |||
99 | xfree (src->filename); | |||
100 | src->filename = xstrdup (s->filename); | |||
101 | ||||
102 | /* Determine the threshold for the length of the line | |||
103 | and the offset to start the display. */ | |||
104 | offset = src->horizontal_offset; | |||
105 | threshold = (line_width - 1) + offset; | |||
106 | stream = fdopen (desc, FOPEN_RT"r"); | |||
107 | clearerr (stream)(!__isthreaded ? ((void)((stream)->_flags &= ~(0x0040| 0x0020))) : (clearerr)(stream)); | |||
108 | cur_line = 0; | |||
109 | cur_line_no = src->start_line_or_addr.line_no = line_no; | |||
110 | if (offset > 0) | |||
111 | src_line = (char *) xmalloc ( | |||
112 | (threshold + 1) * sizeof (char)); | |||
113 | while (cur_line < nlines) | |||
114 | { | |||
115 | struct tui_win_element * element = (struct tui_win_element *) | |||
116 | TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content[cur_line]; | |||
117 | ||||
118 | /* get the first character in the line */ | |||
119 | c = fgetc (stream); | |||
120 | ||||
121 | if (offset == 0) | |||
122 | src_line = ((struct tui_win_element *) | |||
123 | TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content[ | |||
124 | cur_line])->which_element.source.line; | |||
125 | /* Init the line with the line number */ | |||
126 | sprintf (src_line, "%-6d", cur_line_no); | |||
127 | cur_len = strlen (src_line); | |||
| ||||
128 | i = cur_len - | |||
129 | ((cur_len / tui_default_tab_len ()) * tui_default_tab_len ()); | |||
130 | while (i < tui_default_tab_len ()) | |||
131 | { | |||
132 | src_line[cur_len] = ' '; | |||
133 | i++; | |||
134 | cur_len++; | |||
135 | } | |||
136 | src_line[cur_len] = (char) 0; | |||
137 | ||||
138 | /* Set whether element is the execution point and | |||
139 | whether there is a break point on it. */ | |||
140 | element->which_element.source.line_or_addr.line_no = | |||
141 | cur_line_no; | |||
142 | element->which_element.source.is_exec_point = | |||
143 | (strcmp (((struct tui_win_element *) | |||
144 | locator->content[0])->which_element.locator.file_name, | |||
145 | s->filename) == 0 | |||
146 | && cur_line_no == ((struct tui_win_element *) | |||
147 | locator->content[0])->which_element.locator.line_no); | |||
148 | if (c != EOF(-1)) | |||
149 | { | |||
150 | i = strlen (src_line) - 1; | |||
151 | do | |||
152 | { | |||
153 | if ((c != '\n') && | |||
154 | (c != '\r') && (++i < threshold)) | |||
155 | { | |||
156 | if (c < 040 && c != '\t') | |||
157 | { | |||
158 | src_line[i++] = '^'; | |||
159 | src_line[i] = c + 0100; | |||
160 | } | |||
161 | else if (c == 0177) | |||
162 | { | |||
163 | src_line[i++] = '^'; | |||
164 | src_line[i] = '?'; | |||
165 | } | |||
166 | else | |||
167 | { /* Store the charcter in the line | |||
168 | buffer. If it is a tab, then | |||
169 | translate to the correct number of | |||
170 | chars so we don't overwrite our | |||
171 | buffer. */ | |||
172 | if (c == '\t') | |||
173 | { | |||
174 | int j, max_tab_len = tui_default_tab_len (); | |||
175 | ||||
176 | for (j = i - ( | |||
177 | (i / max_tab_len) * max_tab_len); | |||
178 | ((j < max_tab_len) && | |||
179 | i < threshold); | |||
180 | i++, j++) | |||
181 | src_line[i] = ' '; | |||
182 | i--; | |||
183 | } | |||
184 | else | |||
185 | src_line[i] = c; | |||
186 | } | |||
187 | src_line[i + 1] = 0; | |||
188 | } | |||
189 | else | |||
190 | { /* If we have not reached EOL, then eat | |||
191 | chars until we do */ | |||
192 | while (c != EOF(-1) && c != '\n' && c != '\r') | |||
193 | c = fgetc (stream); | |||
194 | } | |||
195 | } | |||
196 | while (c != EOF(-1) && c != '\n' && c != '\r' && | |||
197 | i < threshold && (c = fgetc (stream))); | |||
198 | } | |||
199 | /* Now copy the line taking the offset into account */ | |||
200 | if (strlen (src_line) > offset) | |||
201 | strcpy (((struct tui_win_element *) TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content[ | |||
202 | cur_line])->which_element.source.line, | |||
203 | &src_line[offset]); | |||
204 | else | |||
205 | ((struct tui_win_element *) | |||
206 | TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content[ | |||
207 | cur_line])->which_element.source.line[0] = (char) 0; | |||
208 | cur_line++; | |||
209 | cur_line_no++; | |||
210 | } | |||
211 | if (offset > 0) | |||
212 | xfree (src_line); | |||
213 | fclose (stream); | |||
214 | TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content_size = nlines; | |||
215 | ret = TUI_SUCCESS; | |||
216 | } | |||
217 | } | |||
218 | } | |||
219 | } | |||
220 | return ret; | |||
221 | } | |||
222 | ||||
223 | ||||
224 | /* elz: this function sets the contents of the source window to empty | |||
225 | except for a line in the middle with a warning message about the | |||
226 | source not being available. This function is called by | |||
227 | tui_erase_source_contents(), which in turn is invoked when the | |||
228 | source files cannot be accessed. */ | |||
229 | ||||
230 | void | |||
231 | tui_set_source_content_nil (struct tui_win_info * win_info, char *warning_string) | |||
232 | { | |||
233 | int line_width; | |||
234 | int n_lines; | |||
235 | int curr_line = 0; | |||
236 | ||||
237 | line_width = win_info->generic.width - 1; | |||
238 | n_lines = win_info->generic.height - 2; | |||
239 | ||||
240 | /* set to empty each line in the window, except for the one | |||
241 | which contains the message */ | |||
242 | while (curr_line < win_info->generic.content_size) | |||
243 | { | |||
244 | /* set the information related to each displayed line | |||
245 | to null: i.e. the line number is 0, there is no bp, | |||
246 | it is not where the program is stopped */ | |||
247 | ||||
248 | struct tui_win_element * element = | |||
249 | (struct tui_win_element *) win_info->generic.content[curr_line]; | |||
250 | element->which_element.source.line_or_addr.line_no = 0; | |||
251 | element->which_element.source.is_exec_point = FALSE0; | |||
252 | element->which_element.source.has_break = FALSE0; | |||
253 | ||||
254 | /* set the contents of the line to blank */ | |||
255 | element->which_element.source.line[0] = (char) 0; | |||
256 | ||||
257 | /* if the current line is in the middle of the screen, then we | |||
258 | want to display the 'no source available' message in it. | |||
259 | Note: the 'weird' arithmetic with the line width and height | |||
260 | comes from the function tui_erase_source_content(). We need | |||
261 | to keep the screen and the window's actual contents in synch. */ | |||
262 | ||||
263 | if (curr_line == (n_lines / 2 + 1)) | |||
264 | { | |||
265 | int i; | |||
266 | int xpos; | |||
267 | int warning_length = strlen (warning_string); | |||
268 | char *src_line; | |||
269 | ||||
270 | src_line = element->which_element.source.line; | |||
271 | ||||
272 | if (warning_length >= ((line_width - 1) / 2)) | |||
273 | xpos = 1; | |||
274 | else | |||
275 | xpos = (line_width - 1) / 2 - warning_length; | |||
276 | ||||
277 | for (i = 0; i < xpos; i++) | |||
278 | src_line[i] = ' '; | |||
279 | ||||
280 | sprintf (src_line + i, "%s", warning_string); | |||
281 | ||||
282 | for (i = xpos + warning_length; i < line_width; i++) | |||
283 | src_line[i] = ' '; | |||
284 | ||||
285 | src_line[i] = '\n'; | |||
286 | ||||
287 | } /* end if */ | |||
288 | ||||
289 | curr_line++; | |||
290 | ||||
291 | } /* end while */ | |||
292 | } | |||
293 | ||||
294 | ||||
295 | /* Function to display source in the source window. This function | |||
296 | initializes the horizontal scroll to 0. */ | |||
297 | void | |||
298 | tui_show_symtab_source (struct symtab *s, union tui_line_or_address line, int noerror) | |||
299 | { | |||
300 | TUI_SRC_WINtui_win_list[SRC_WIN]->detail.source_info.horizontal_offset = 0; | |||
301 | tui_update_source_window_as_is (TUI_SRC_WINtui_win_list[SRC_WIN], s, line, noerror); | |||
302 | } | |||
303 | ||||
304 | ||||
305 | /* Answer whether the source is currently displayed in the source | |||
306 | window. */ | |||
307 | int | |||
308 | tui_source_is_displayed (char *fname) | |||
309 | { | |||
310 | return (TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content_in_use && | |||
311 | (strcmp (((struct tui_win_element *) (tui_locator_win_info_ptr ())-> | |||
312 | content[0])->which_element.locator.file_name, fname) == 0)); | |||
313 | } | |||
314 | ||||
315 | ||||
316 | /* Scroll the source forward or backward vertically. */ | |||
317 | void | |||
318 | tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction, | |||
319 | int num_to_scroll) | |||
320 | { | |||
321 | if (TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content != NULL((void*)0)) | |||
322 | { | |||
323 | union tui_line_or_address l; | |||
324 | struct symtab *s; | |||
325 | tui_win_content content = (tui_win_content) TUI_SRC_WINtui_win_list[SRC_WIN]->generic.content; | |||
326 | struct symtab_and_line cursal = get_current_source_symtab_and_line (); | |||
327 | ||||
328 | if (cursal.symtab == (struct symtab *) NULL((void*)0)) | |||
329 | s = find_pc_symtab (get_frame_pc (deprecated_selected_frame)); | |||
330 | else | |||
331 | s = cursal.symtab; | |||
332 | ||||
333 | if (scroll_direction == FORWARD_SCROLL) | |||
334 | { | |||
335 | l.line_no = content[0]->which_element.source.line_or_addr.line_no + | |||
336 | num_to_scroll; | |||
337 | if (l.line_no > s->nlines) | |||
338 | /*line = s->nlines - win_info->generic.content_size + 1; */ | |||
339 | /*elz: fix for dts 23398 */ | |||
340 | l.line_no = content[0]->which_element.source.line_or_addr.line_no; | |||
341 | } | |||
342 | else | |||
343 | { | |||
344 | l.line_no = content[0]->which_element.source.line_or_addr.line_no - | |||
345 | num_to_scroll; | |||
346 | if (l.line_no <= 0) | |||
347 | l.line_no = 1; | |||
348 | } | |||
349 | ||||
350 | print_source_lines (s, l.line_no, l.line_no + 1, 0); | |||
351 | } | |||
352 | } |