"Fossies" - the Fresh Open Source Software Archive 
Member "xxgdb-1.12/filemenu.c" (29 Aug 1994, 16003 Bytes) of package /linux/misc/old/xxgdb-1.12.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*****************************************************************************
2 *
3 * xdbx - X Window System interface to the dbx debugger
4 *
5 * Copyright 1989 The University of Texas at Austin
6 * Copyright 1990 Microelectronics and Computer Technology Corporation
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose and without fee is hereby granted,
10 * provided that the above copyright notice appear in all copies and that
11 * both that copyright notice and this permission notice appear in
12 * supporting documentation, and that the name of The University of Texas
13 * and Microelectronics and Computer Technology Corporation (MCC) not be
14 * used in advertising or publicity pertaining to distribution of
15 * the software without specific, written prior permission. The
16 * University of Texas and MCC makes no representations about the
17 * suitability of this software for any purpose. It is provided "as is"
18 * without express or implied warranty.
19 *
20 * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
21 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
23 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
25 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 * Author: Po Cheung
29 * Created: March 10, 1989
30 *
31 *****************************************************************************
32 *
33 * xxgdb - X Window System interface to the gdb debugger
34 *
35 * Copyright 1990,1993 Thomson Consumer Electronics, Inc.
36 *
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation for any purpose and without fee is hereby granted,
39 * provided that the above copyright notice appear in all copies and that
40 * both that copyright notice and this permission notice appear in
41 * supporting documentation, and that the name of Thomson Consumer
42 * Electronics (TCE) not be used in advertising or publicity pertaining
43 * to distribution of the software without specific, written prior
44 * permission. TCE makes no representations about the suitability of
45 * this software for any purpose. It is provided "as is" without express
46 * or implied warranty.
47 *
48 * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
49 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
50 * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
51 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
52 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
53 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
54 * SOFTWARE.
55 *
56 * Adaptation to GDB: Pierre Willard
57 * XXGDB Created: December, 1990
58 *
59 *****************************************************************************/
60
61 /* filemenu.c
62 *
63 * Construct a file menu (directory browser) which allows a user to go
64 * up and down the directory tree, to select text files to display, and
65 * to select executable files to debug. The file menu is popped up by
66 * the 'file' command button.
67 * Duane Voth (duanev@mcc.com) contributed to the layout of the file menu,
68 * plus some code and ideas.
69 *
70 * changeDir(): Record the current working directory.
71 * InList(): Select files to be displayed in the menu.
72 * ScanDir(): Scan the directory and record selected filenames.
73 * DisplayMenuFile(): Callback for the file menu.
74 * CancelFileMenu(): Pop down the file menu.
75 * SetUpFileMenu(): Create the file menu popupshell.
76 * UpdateFileMenu(): Update entries in the file menu.
77 * File(): Command callback for the 'file' command button.
78 */
79
80 #include <ctype.h>
81 #include <X11/Xos.h>
82 #include <sys/stat.h>
83
84 #ifdef SYSV
85 #include <stdio.h>
86 #include <sys/param.h>
87 #include <sys/types.h>
88 #include <dirent.h>
89 #ifdef _POSIX_SOURCE
90 #ifndef S_IFDIR
91 #define S_IFDIR 0040000 /* directory */
92 #endif
93 #ifndef S_IEXEC
94 #define S_IEXEC 00100 /* execute/search permission, owner */
95 #endif
96 #endif /* _POSIX_SOURCE */
97 #else /* SYSV */
98 #ifdef SUNOS4
99 #include <dirent.h>
100 #else
101 #include <sys/dir.h>
102 #endif
103 #endif /* SYSV */
104 #include "global.h"
105
106 #define MAXCOLUMNS 8 /* max number of columns in file menu */
107 #define FILES_PER_COL 10 /* # of files per column in file menu */
108
109 static char fileMenuDir[MAXPATHLEN];/* current directory of file menu */
110 static char **filelist; /* list of file names in fileMenu */
111 static int nfiles = 0; /* number of files in filelist */
112 static Widget popupshell, /* parent of popup */
113 popup, /* vpane widget containing file menu */
114 fileMenu, /* list widget as file menu */
115 fileMenuLabel; /* label widget as file menu label */
116
117 void File();
118 static void UpdateFileMenu();
119
120 /* Change working directory to 'dir'.
121 * For Berkeley dbx, modify static global variable, cwd, to keep track of
122 * current working directory.
123 * For Sun dbx, change working directory of dbx.
124 */
125 static void changeDir(dir)
126 char *dir;
127 {
128 char command[LINESIZ];
129 char store[LINESIZ];
130 int i,j;
131
132 if(!strcmp(dir, "./")) return;
133
134 #if defined(BSD)
135 if (dir[0] == '/' || dir[0] == '~')
136 strcpy(cwd, dir);
137 if (strcmp(dir, "../") == 0) {
138 for (i=strlen(cwd); cwd[i] != '/' && i > 0; i--);
139 cwd[i] = '\0';
140 if (strcmp(cwd, "") == 0)
141 strcpy(cwd, "/");
142 }
143 else {
144 sprintf(cwd, "%s/%s", cwd, dir);
145 LASTCH(cwd) = '\0';
146 }
147 #else /* not BSD */
148 if(!strcmp(dir,"../"))
149 {
150 for(i=0,j=0; cwd[i]; i++) if(cwd[i]=='/')j++;
151 if( j == 1 ) strcpy(store,"/");
152 else
153 strcpy(store,"..");
154 }
155 else
156 {
157 if(!strcmp(cwd, "/"))cwd[0]='\0';
158 sprintf(store,"%s/%s", cwd, dir);
159 LASTCH(store)='\0';
160 }
161 sprintf(command, "cd %s\n", store);
162 #ifdef GDB
163 /* because silly gdb 4.0 displays nothing with cd command when
164 confirm is on (possibly a gdb bug) , I just reset confirm to on
165 just for this command !. */
166
167 if (new_gdb4())
168 query_gdb("set confirm on\n", PARSE_OFF | ECHO_OFF | FILTER_OFF);
169
170 query_gdb(command, PARSE_ON | ECHO_OFF | FILTER_OFF);
171
172 if (new_gdb4()) /* reset confirm to off */
173 query_gdb("set confirm off\n", PARSE_OFF | ECHO_OFF | FILTER_OFF);
174 #else
175 query_dbx(command);
176 #endif /* not GDB */
177 #endif /* BSD */
178 }
179
180
181 /* Determines if a directory entry should appear in the file menu.
182 * The files included in the menu are :
183 * .. (parent directory)
184 * directories
185 * text files
186 * executable files
187 */
188 #ifndef SYSV
189 static int InList(entry)
190 Directory *entry;
191 {
192 char pathname[LINESIZ];
193 struct stat statbuf;
194
195 if (strcmp(entry->d_name, ".") == 0 || /* ignore current directory */
196 LASTCH(entry->d_name) == '~' || /* ignore Emacs backup files */
197 (LASTCH(entry->d_name) == 'o' && SECLASTCH(entry->d_name) == '.'))
198 /* ignore object files */
199 return False;
200 if (entry->d_name[0] == '.' && entry->d_name[1] != '.')
201 return False; /* ignore hidden files */
202 if (strcmp(cwd, "")) /* give full path name */
203 sprintf(pathname, "%s/%s", cwd, entry->d_name);
204 else
205 strcpy(pathname, entry->d_name);
206 if (stat(pathname, &statbuf) == -1)
207 return False;
208 if (statbuf.st_mode & S_IFDIR) { /* is directory */
209 strcat(entry->d_name, "/");
210 ++(entry->d_namlen);
211 return True;
212 }
213 if (statbuf.st_mode & S_IEXEC) { /* is executable */
214 strcat(entry->d_name, "*");
215 ++(entry->d_namlen);
216 return True;
217 }
218 return True;
219 }
220 #endif /* not SYSV */
221
222
223 /* Scans the working directory for files selected by InList(), sorted
224 * alphabetically, and stored in an array of pointers to directory
225 * entries called namelist.
226 * The names of the selected files are stored in filelist.
227 */
228 static void ScanDir(dir)
229 char *dir;
230 {
231 #ifndef SYSV
232 extern alphasort();
233 Directory **namelist;
234 #else
235 struct dirent *WorkingDirEntry;
236 DIR *WorkingDir;
237 char store[LINESIZ];
238 #endif
239 register int i,j;
240
241 #ifdef SYSV
242 if(!(WorkingDir = opendir(dir)))
243 {
244 UpdateMessageWindow("scandir: cannot open %s", dir);
245 return;
246 }
247 nfiles=0;
248 while(readdir(WorkingDir))nfiles++;
249 rewinddir(WorkingDir);
250 #else
251 nfiles = scandir(dir, &namelist, InList, alphasort);
252 if (nfiles == -1) {
253 UpdateMessageWindow("scandir: cannot open %s", dir);
254 return;
255 }
256 #endif
257 if (filelist) {
258 for (i=0; filelist[i]; i++)
259 XtFree(filelist[i]);
260 XtFree((void*)filelist);
261 }
262 filelist = (char **) XtMalloc((nfiles+1) * sizeof(char *));
263 i = 0;
264 for (j=0; j<nfiles; j++) {
265 #ifdef SYSV
266 WorkingDirEntry = readdir(WorkingDir);
267 if(!strcmp(WorkingDirEntry->d_name, "."))
268 strcpy(store, "./");
269 else
270 {
271 if(!strcmp(WorkingDirEntry->d_name, ".."))
272 strcpy(store, "../");
273 else
274 {
275 struct stat statbuf;
276
277 sprintf(store,"%s/%s",cwd,WorkingDirEntry->d_name);
278 if(stat(store, &statbuf) == -1)
279 store[0]='\0';
280 else
281 {
282 if (statbuf.st_mode & S_IFDIR)
283 sprintf(store, "%s/", WorkingDirEntry->d_name);
284 else
285 if (statbuf.st_mode & S_IEXEC)
286 sprintf(store, "%s*", WorkingDirEntry->d_name);
287 else
288 if(LASTCH(WorkingDirEntry->d_name) == '~' ||
289 LASTCH(WorkingDirEntry->d_name) == '#' ||
290 WorkingDirEntry->d_name[0] == '.' ||
291 (LASTCH(WorkingDirEntry->d_name) == 'o' &&
292 SECLASTCH(WorkingDirEntry->d_name) == '.'))
293 store[0]='\0';
294 else
295 strcpy(store, WorkingDirEntry->d_name);
296 }
297 }
298 }
299 if(store[0])
300 filelist[i++] = XtNewString(store);
301 #else /* not SYSV */
302 filelist[i++] = XtNewString(namelist[j]->d_name);
303 XtFree((XtPointer) namelist[j]);
304 #endif
305 }
306 filelist[i++] = NULL;
307
308 #ifdef SYSV
309 closedir(WorkingDir);
310 #else
311 XtFree((XtPointer) namelist);
312 #endif
313 return;
314 }
315
316
317 /* Callback for the fileMenu list widget.
318 * > if the selected item is a directory, display contents of that directory.
319 * > (Sun dbx only) if the selected item is an executable file, issue the
320 * debug command.
321 * > if the selected item is a readable file, display the file.
322 */
323 /* ARGSUSED */
324 static void DisplayMenuFile(w, popupshell, call_data)
325 Widget w;
326 Widget popupshell;
327 XawListReturnStruct *call_data;
328 {
329 char string[LINESIZ], *filename, command[LINESIZ];
330
331 XtPopdown(popupshell);
332 filename = call_data->string;
333 if (filename == NULL) return;
334 if (LASTCH(filename) == '/') {
335 changeDir(filename);
336 XtDestroyWidget(popupshell);
337 UpdateFileMenu(); /* create new menu */
338 File(); /* pop it up */
339 }
340 else if (LASTCH(filename) == '*') {
341 UpdateMessageWindow("",NULL);
342 #ifdef GDB
343 strcpy(string, filename);
344 LASTCH(string) = '\0';
345
346 /* for GDB 4.xx, we send the command : file */
347 if (new_gdb4())
348 sprintf(command, "file %s\n", string);
349 else
350 {
351 /* for GDB 3.xx, we send the commands : exec-file & symbol-file */
352
353 /* (PW)21DEC90 : this button is special because it has to send
354 TWO commands to GDB. */
355
356 sprintf(command, "exec-file %s\n", string);
357 send_command(command);
358 AppendDialogText(command);
359
360 sprintf(command, "symbol-file %s\n", string);
361 }
362 send_command(command);
363 AppendDialogText(command);
364 #else
365 #ifndef BSD
366 strcpy(string, filename);
367 LASTCH(string) = '\0';
368 sprintf(command, "debug %s\n", string);
369 send_command(command);
370 AppendDialogText(command);
371 #endif
372 #endif /* GDB */
373 }
374 else {
375 UpdateMessageWindow("",NULL);
376 #ifdef GDB
377 if (strcmp(filename, "core") == 0)
378 sprintf(command, "core-file %s\n", filename);
379 else
380 sprintf(command, "list %s:1\n", filename);
381 send_command(command);
382 AppendDialogText(command);
383 #else /* not GDB */
384 sprintf(command, "file %s\n", filename);
385 send_command(command);
386 AppendDialogText(command);
387 #endif /* GDB */
388 }
389 }
390
391
392 /* Callback to popdown the file menu
393 */
394 /* ARGSUSED */
395 static void CancelFileMenu(w, popupshell, call_data)
396 Widget w;
397 Widget popupshell;
398 caddr_t call_data;
399 {
400 XtPopdown(popupshell);
401 UpdateMessageWindow("",NULL);
402 }
403
404
405 /* Creates a popup shell with its child being a vpane widget containing
406 * a file menu label, a file menu containing file names returned from
407 * ScanDir(), and a cancel command button.
408 * When an item in the list is selected, DisplayMenuFile is called.
409 */
410 static void SetUpFileMenu(dir)
411 char *dir;
412 {
413 Widget cancelButton;
414 Arg args[MAXARGS];
415 Cardinal n;
416 char menulabel[LINESIZ];
417 int ncolumns;
418
419 n = 0;
420 popupshell = XtCreatePopupShell("File Directory", transientShellWidgetClass,
421 toplevel, args, n);
422
423 n = 0;
424 popup = XtCreateManagedWidget("popup", panedWidgetClass, popupshell,
425 args, n);
426 ScanDir(dir);
427 strcpy(fileMenuDir, dir);
428
429 n = 0;
430 sprintf(menulabel, " %s ", dir);
431 XtSetArg(args[n], XtNlabel, (XtArgVal) menulabel); n++;
432 XtSetArg(args[n], XtNjustify, (XtArgVal) XtJustifyCenter); n++;
433 fileMenuLabel = XtCreateManagedWidget("fileMenuLabel", labelWidgetClass,
434 popup, args, n);
435
436 n = 0;
437 ncolumns = nfiles/FILES_PER_COL + 1;
438 ncolumns = MIN(ncolumns, MAXCOLUMNS);
439 XtSetArg(args[n], XtNlist, filelist); n++;
440 XtSetArg(args[n], XtNverticalList, True); n++;
441 XtSetArg(args[n], XtNdefaultColumns, (XtArgVal) ncolumns); n++;
442 fileMenu = XtCreateManagedWidget("fileMenu", listWidgetClass,
443 popup, args, n);
444 XtAddCallback(fileMenu, XtNcallback, DisplayMenuFile, popupshell);
445
446 n = 0;
447 XtSetArg(args[n], XtNresize, False); n++;
448 XtSetArg(args[n], XtNlabel, "CANCEL"); n++;
449 cancelButton = XtCreateManagedWidget("cancelButton", commandWidgetClass,
450 popup, args, n);
451 XtAddCallback(cancelButton, XtNcallback, CancelFileMenu, popupshell);
452
453 DisableWindowResize(fileMenuLabel);
454 DisableWindowResize(cancelButton);
455 }
456
457
458 /* This routine is called when there is a a change in current directory.
459 * It destroys the existing popup shell and creates a new file menu based
460 * on the new current directory. A new directory list is created.
461 */
462 static void UpdateFileMenu()
463 {
464 SetUpFileMenu(cwd);
465 #ifdef GDB
466 query_gdb_directories(); /* defined in gdb_handler.c */
467 #else
468 query_dbx("use\n");
469 #endif /* GDB */
470 }
471
472
473 /* File command button callback.
474 */
475 /* ARGSUSED */
476 void File(w, client_data, call_data)
477 Widget w;
478 caddr_t client_data;
479 caddr_t call_data;
480 {
481 Arg args[MAXARGS];
482 Cardinal n;
483 Position x, y, x_offset;
484 Dimension fileMenu_width, fileMenuLabel_width, border_width,
485 width, dialog_width;
486
487 XDefineCursor(display, XtWindow(toplevel), watch);
488 XDefineCursor(display, XtWindow(sourceWindow), watch);
489 XDefineCursor(display, XtWindow(dialogWindow), watch);
490 XFlush(display);
491 if (strcmp(fileMenuDir, cwd))
492 UpdateFileMenu();
493
494 n = 0;
495 XtSetArg(args[n], XtNwidth, &fileMenu_width); n++;
496 XtSetArg(args[n], XtNborderWidth, &border_width); n++;
497 XtGetValues(fileMenu, args, n);
498
499 n = 0;
500 XtSetArg(args[n], XtNwidth, &fileMenuLabel_width); n++;
501 XtGetValues(fileMenuLabel, args, n);
502
503 n = 0;
504 XtSetArg(args[n], XtNwidth, &dialog_width); n++;
505 XtGetValues(dialogWindow, args, n);
506
507 width = MAX(fileMenu_width, fileMenuLabel_width);
508 x_offset = (Position) (dialog_width - width - border_width);
509 XtTranslateCoords(dialogWindow, x_offset, 0, &x, &y);
510
511 x = MAX(0, x);
512 y = MAX(0, y);
513
514 n = 0;
515 XtSetArg(args[n], XtNx, x); n++;
516 XtSetArg(args[n], XtNy, y); n++;
517 XtSetValues(popupshell, args, n);
518 XtPopup(popupshell, XtGrabNonexclusive);
519
520 UpdateMessageWindow("Select a file or directory",NULL);
521
522 XUndefineCursor(display, XtWindow(toplevel));
523 XUndefineCursor(display, XtWindow(sourceWindow));
524 XUndefineCursor(display, XtWindow(dialogWindow));
525 }