home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 024 / dirlist.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  31KB  |  946 lines

  1. /*
  2.  * I wrote this function because I'm so stupid, I constantly forget
  3.  *  file names and directory stuff.  The main function prompts for a
  4.  *  subdirectory name or a search path.  The default search path is the
  5.  *  cwd (current working directory).  In addition to being stupid, I'm also
  6.  *  lazy.  If the user types a subdirectory name, I think we can assume he
  7.  *  wants to list all files w/o having to type *.*   Let's save the cwd on
  8.  *  whatever drive the user wishes to search, so we can restore it we get
  9.  *  thru dir'ing.  Use the standard DOS functions to get and set directories.
  10.  *
  11.  * The search pattern can contain wild card chars, valid file names, or a
  12.  *  valid subdirectory name.
  13.  *
  14.  * Being that TDE 2.2 now handles binary files, lets make .EXE and .COM files
  15.  *  autoload in binary mode.
  16.  *
  17.  * Before matching files are displayed on the screen, file names are sorted
  18.  *  using the easy-to-implement and fairly fast Shellsort algorithm.
  19.  *
  20.  * See:
  21.  *
  22.  *   Donald Lewis Shell, _Communications of the ACM_ 2 (No. 2): 30-32, 1959.
  23.  *
  24.  * See also:
  25.  *
  26.  *   Donald Ervin Knuth, _The Art of Computer Programming; Volume 3:  Sorting
  27.  *     and Searching_, Addison-Wesley, Reading, Mass., 1973, Chapter 5,
  28.  *     "Sorting", pp 84-95.  ISBN 0-201-03803-X.
  29.  *
  30.  *   Robert Sedgewick, _Algorithms in C_, Addison-Wesley, Reading, Mass.,
  31.  *     1990, Chapter 8, "Elementary Sorting Methods", pp 107-111.
  32.  *     ISBN 0-201-51425-7.
  33.  *
  34.  *
  35.  * New editor name:  TDE, the Thomson-Davis Editor.
  36.  * Author:           Frank Davis
  37.  * Date:             June 5, 1991, version 1.0
  38.  * Date:             July 29, 1991, version 1.1
  39.  * Date:             October 5, 1991, version 1.2
  40.  * Date:             January 20, 1992, version 1.3
  41.  * Date:             February 17, 1992, version 1.4
  42.  * Date:             April 1, 1992, version 1.5
  43.  * Date:             June 5, 1992, version 2.0
  44.  * Date:             October 31, 1992, version 2.1
  45.  * Date:             April 1, 1993, version 2.2
  46.  * Date:             June 5, 1993, version 3.0
  47.  *
  48.  * This code is released into the public domain, Frank Davis.
  49.  *    You may distribute it freely.
  50.  */
  51.  
  52. #include "tdestr.h"
  53. #include "common.h"
  54. #include "define.h"
  55. #include "tdefunc.h"
  56.  
  57.  
  58. /*
  59.  * Name:    dir_help
  60.  * Purpose: To prompt the user and list the directory contents
  61.  * Date:    February 13, 1992
  62.  * Passed:  window:  pointer to current window
  63.  */
  64. int  dir_help( WINDOW *window )
  65. {
  66. char dname[MAX_COLS+2]; /* directory search pattern */
  67. char stem[MAX_COLS+2];  /* directory stem */
  68. char drive[_MAX_DRIVE]; /* splitpath drive buff */
  69. char dir[_MAX_DIR];     /* splitpath dir buff */
  70. char fname[_MAX_FNAME]; /* splitpath fname buff */
  71. char ext[_MAX_EXT];     /* splitpath ext buff */
  72. int  rc;
  73. int  file_mode;
  74. int  bin_length;
  75. int  prompt_line;
  76.  
  77.    if (window != NULL) {
  78.       entab_linebuff( );
  79.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  80.          return( ERROR );
  81.       prompt_line = window->bottom_line;
  82.    } else
  83.       prompt_line = g_display.nlines;
  84.  
  85.    /*
  86.     * search path or pattern
  87.     */
  88.    dname[0] = '\0';
  89.    rc = get_name( dir1, prompt_line, dname, g_display.message_color );
  90.  
  91.    if (rc == OK) {
  92.       if (validate_path( dname, stem ) == OK) {
  93.          rc = list_and_pick( dname, stem, window );
  94.  
  95.          /*
  96.           * if everything is everything, load in the file selected by user.
  97.           */
  98.          if (rc == OK) {
  99.             file_mode = TEXT;
  100.             bin_length = 0;
  101.             _splitpath( dname, drive, dir, fname, ext );
  102.             if (stricmp( ext, ".exe" ) == 0  ||  stricmp( ext, ".com" ) == 0) {
  103.                file_mode = BINARY;
  104.                bin_length = g_status.file_chunk;
  105.             }
  106.             if (window != NULL)
  107.                attempt_edit_display( dname, LOCAL, file_mode, bin_length );
  108.             else
  109.                attempt_edit_display( dname, GLOBAL, file_mode, bin_length );
  110.          }
  111.       } else
  112.          /*
  113.           * invalid path or file name
  114.           */
  115.          error( WARNING,
  116.                 window != NULL ? window->bottom_line : g_display.nlines, dir2 );
  117.    }
  118.    return( rc );
  119. }
  120.  
  121.  
  122. /*
  123.  * Name:    validate_path
  124.  * Purpose: make sure we got a valid search pattern or subdirectory
  125.  * Date:    February 13, 1992
  126.  * Passed:  dname: search path entered by user
  127.  *          stem:  directory stem is returned
  128.  * Returns: successful or not
  129.  * Notes:   we need to validate the search path or pattern.  if the search
  130.  *            pattern is valid, then we need to get the search stem.
  131.  *          the user may enter a subdirectory or some kind of search pattern.
  132.  *             if the user enters a subdirectory, then there are a few things
  133.  *             we need to take care of  1) find out if the subdirectory is
  134.  *             the root, 2) append a '\' to the subdirectory so we can create
  135.  *             a search pattern for the subdirectory, 3) don't append '\' to
  136.  *             the root, it already has a '\'.
  137.  *          if the user enters a search pattern, then we need to dissect the
  138.  *             search path.  we must create a stem from the search pattern.
  139.  */
  140. int  validate_path( char *dname, char *stem )
  141. {
  142. int  rc;
  143. DTA  dta;               /* temp disk transfer struct for findfirst, etc. */
  144. int  fattr;
  145. int  i;
  146. int  len;
  147. char *p;
  148. char temp[MAX_COLS+2];  /* directory stem */
  149.  
  150.    /*
  151.     * if path name is void then the current working directory is implied.
  152.     */
  153.    if (dname[0] == '\0') {
  154.  
  155.       assert( strlen( stardotstar ) < MAX_COLS );
  156.  
  157.       strcpy( dname, stardotstar );
  158.       stem[0] = '\0';
  159.       rc = OK;
  160.    } else {
  161.  
  162.       /*
  163.        * get the attributes of the search pattern, so we can determine if
  164.        * this is a pattern or subdirectory.
  165.        */
  166.       rc = get_fattr( dname, &fattr );
  167.  
  168.       if (rc == OK && (fattr & SUBDIRECTORY)) {
  169.          assert( strlen( dname ) < MAX_COLS );
  170.          strcpy( stem, dname );
  171.  
  172.          /*
  173.           * if this is the root directory ( \ ), don't append '\' to it.
  174.           * user entered a subdirectory - append *.* to get contents of
  175.           * subdirectory.
  176.           */
  177.          len = strlen( stem );
  178.          if (stem[len-1] != '\\') {
  179.             strcat( stem, "\\" );
  180.             strcat( dname, "\\" );
  181.          }
  182.          strcat( dname, stardotstar );
  183.  
  184.       /*
  185.        * not a subdirectory.  let's see if any files match the search
  186.        * pattern.
  187.        */
  188.       } else if (rc != ERROR) {
  189.          if ((rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN |
  190.                               SYSTEM | SUBDIRECTORY | ARCHIVE )) == OK) {
  191.  
  192.             /*
  193.              * copy dname to "temp" so we can use "temp" to find the stem.
  194.              *    we need to search the pattern backwards to figure the stem.
  195.              */
  196.  
  197.             assert( strlen( dname ) < MAX_COLS );
  198.  
  199.             strcpy( temp, dname );
  200.             len = strlen( dname );
  201.             for (i=len,p=temp+len; i>=0; i--) {
  202.                /*
  203.                 *  if we run into the '\' or the ':', then we got a stem.
  204.                 */
  205.                if (*p == '\\' || *p == ':') {
  206.                   p = temp + i;
  207.                   *(p+1) = '\0';
  208.                   break;
  209.                /*
  210.                 * if we're at the beginning of the string, stem == '\0'
  211.                 */
  212.                } else if (i == 0) {
  213.                   *p = '\0';
  214.                   break;
  215.                }
  216.                --p;
  217.             }
  218.  
  219.             assert( strlen( temp ) < MAX_COLS );
  220.  
  221.             strcpy( stem, temp );
  222.          } else
  223.             rc = ERROR;
  224.  
  225.       /*
  226.        * user did not enter a valid subdirectory name or search pattern.
  227.        */
  228.       } else
  229.          rc = ERROR;
  230.    }
  231.    return( rc );
  232. }
  233.  
  234.  
  235. /*
  236.  * Name:    list_and_pick
  237.  * Purpose: To show matching file names and let user pick a file
  238.  * Date:    February 13, 1992
  239.  * Passed:  dname:  directory search pattern
  240.  *          stem:   stem of directory search pattern
  241.  *          window:  pointer to current window
  242.  * Returns: return code from pick.