"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 }