⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirlist.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * I wrote this function because I'm so stupid, I constantly forget *  file names and directory stuff.  The main function prompts for a *  subdirectory name or a search path.  The default search path is the *  cwd (current working directory).  In addition to being stupid, I'm also *  lazy.  If the user types a subdirectory name, I think we can assume he *  wants to list all files w/o having to type *.*   Let's save the cwd on *  whatever drive the user wishes to search, so we can restore it we get *  thru dir'ing.  Use the standard DOS functions to get and set directories. * * The search pattern can contain wild card chars, valid file names, or a *  valid subdirectory name. * * Being that TDE 2.2 now handles binary files, lets make .EXE and .COM files *  autoload in binary mode. * * Before matching files are displayed on the screen, file names are sorted *  using the easy-to-implement and fairly fast Shellsort algorithm. * * See: * *   Donald Lewis Shell, "A High-Speed Sorting Procedure."  _Communications of *     the ACM_ 2 (No. 2): 30-32, 1959. * * See also: * *   Donald Ervin Knuth, _The Art of Computer Programming; Volume 3:  Sorting *     and Searching_, Addison-Wesley, Reading, Mass., 1973, Chapter 5, *     "Sorting", pp 84-95.  ISBN 0-201-03803-X. * *   Robert Sedgewick, _Algorithms in C_, Addison-Wesley, Reading, Mass., *     1990, Chapter 8, "Elementary Sorting Methods", pp 107-111. *     ISBN 0-201-51425-7. * * * New editor name:  TDE, the Thomson-Davis Editor. * Author:           Frank Davis * Date:             June 5, 1991, version 1.0 * Date:             July 29, 1991, version 1.1 * Date:             October 5, 1991, version 1.2 * Date:             January 20, 1992, version 1.3 * Date:             February 17, 1992, version 1.4 * Date:             April 1, 1992, version 1.5 * Date:             June 5, 1992, version 2.0 * Date:             October 31, 1992, version 2.1 * Date:             April 1, 1993, version 2.2 * Date:             June 5, 1993, version 3.0 * Date:             August 29, 1993, version 3.1 * Date:             November 13, 1993, version 3.2 * Date:             June 5, 1994, version 4.0 * Date:             December 5, 1998, version 5.0 (jmh) * * This code is released into the public domain, Frank Davis. *    You may distribute it freely. */#include "tdestr.h"#include "common.h"#include "define.h"#include "tdefunc.h"#include <time.h>static int  row_ofs;                    /* row of first name (jmh 060830) */static int  fofs;                       /* offset in the file list for the */                                        /*  first file (jmh 980523)        */static int  win_cmp( char *, char * );  /* GotoWindow sort function */static int  shl_cmp( char *, char * );  /* SyntaxSelect sort function */static int  name_ofs;                   /* GotoWindow offset to window name *//* * Name:    dir_help * Purpose: To prompt the user and list the directory contents * Date:    February 13, 1992 * Passed:  window:  pointer to current window * * jmh 980528: disable command line language; *             use return code of attempt_edit_display. * jmh 020723: auto-detect binary files (disable command line -b). * jmh 021023: handle command line options in attempt_edit_display(). */int  dir_help( TDE_WIN *window ){char dname[PATH_MAX+2]; /* directory search pattern */int  rc;int  prompt_line;   if (window != NULL) {      if (un_copy_line( window->ll, window, TRUE, TRUE ) == ERROR)         return( ERROR );      prompt_line = window->bottom_line;   } else      prompt_line = g_display.end_line;   /*    * search path or pattern    */   dname[0] = '\0';   rc = get_name( dir1, prompt_line, dname, &h_file );   if (rc != ERROR) {      rc = list_and_pick( dname, window );      /*       * if everything is everything, load in the file selected by user.       */      if (rc == OK)         rc = attempt_edit_display( dname, (window != NULL) ? LOCAL : GLOBAL );   }   return( rc );}/* * Name:    dir_help_name * Purpose: To display name of directory * Date:    February 13, 1992 * Passed:  window:  pointer to current window */int  dir_help_name( TDE_WIN *window, char *name ){char dname[PATH_MAX+2]; /* directory search pattern */int  rc;   rc = OK;   if (window != NULL) {      if (un_copy_line( window->ll, window, TRUE, TRUE ) == ERROR)         return( ERROR );   }   strcpy( dname, name );   rc = list_and_pick( dname, window );   /*    * if everything is everything, load in the file selected by user.    */   if (rc == OK)      rc = attempt_edit_display( dname, (window != NULL) ? LOCAL : GLOBAL );   return( rc );}/* * Name:    list_and_pick * Purpose: To show matching file names and let user pick a file * Date:    February 13, 1992 * Passed:  dname:   directory search pattern *          window:  pointer to current window * Returns: return code from pick.  rc = OK, then edit a new file. * Notes:   real work routine of this function.  save the cwd and let the *           user search upwards or downwards thru the directory structure. *          since we are doing DOS directory functions, we need to check the *           return code after each DOS call for critical errors. * * jmh 020924: made FTYPE.fname a pointer, allocating exactly as much as space *              as required. Tweaked the loop to code the allocation once. * jmh 021019: display the full path, rather than what was initially entered; *             don't actually change directory (use the stem); *             rather than abort, don't allow selection of an empty directory. */int  list_and_pick( char *dname, TDE_WIN *window ){int  rc = OK;FFIND dta;              /* file finding info */DIRECTORY dir;          /* contains all info for dir display */unsigned int cnt;       /* number of matching files */LIST *flist, *pl;       /* pointer to list of matching files */FTYPE *pf, *ffind;char dbuff[PATH_MAX];   /* temporary directory buff */int  stop;int  len;char *n;int  prompt_line;   prompt_line = (window != NULL) ? window->bottom_line : g_display.end_line;   ffind = my_findfirst( dname, &dta, ALL_DIRS );   if (ffind == NULL) {      error( WARNING, prompt_line, dir2 );      return( ERROR );   }   xygoto( -1, -1 );   stop = FALSE;   while (stop == FALSE) {      /*       * Some algorithms alloc the maximum possible number of files in       *  a directory, eg. 256 or 512.  Let's count the number of matching       *  files so we know exactly how much memory to request from malloc.       */      cnt = len = 0;      do {         ++cnt;         len += strlen( ffind->fname ) + 1;         ffind = my_findnext( &dta );      } while (ffind != NULL);      flist = malloc( cnt * (sizeof(LIST) + sizeof(FTYPE)) + len );      if (flist == NULL) {         /*          * out of memory          */         error( WARNING, prompt_line, main4 );         rc = ERROR;         break;      }      /*       * If we had enough memory, find all matching file names.       *       * when we get here, we have already done: 1) my_findfirst and       *  my_findnext, 2) counted the number of matching files, and       *  3) allocated space.       */      pl = flist;      pf = (FTYPE *)(pl + cnt);      n  = (char *)(pf + cnt);      ffind = my_findfirst( dname, &dta, ALL_DIRS );      do {         /*          * pl is pointer that walks down the list info structure.          * pf is pointer that walks down the file info structure.          *  save the file name and file size for each matching          *  file we find. jmh 980527: save attribute as well.          *  jmh 031202: save time.          */         pl->name  = pf->fname = n;         pl->color =#if !defined( __UNIX__ )                     (ffind->fattr & (HIDDEN | SYSTEM)) ? Color( Disabled ) :#endif                      Color( Dialog );         pl->data  = pf;         ++pl;#if defined( __DJGPP__ ) || defined( __TURBOC__ )         n = stpcpy( pf->fname, ffind->fname ) + 1;#else         strcpy( pf->fname, ffind->fname );         n += strlen( pf->fname ) + 1;#endif         pf->fsize = ffind->fsize;         pf->fattr = ffind->fattr;         pf->ftime = ffind->ftime;         ++pf;         ffind = my_findnext( &dta );      } while (ffind != NULL);      shell_sort( flist, cnt );      /*       * figure out number of rows, cols, etc... then display dir list       */      setup_directory_window( &dir, flist, cnt );      write_directory_list( flist, &dir );#if !defined( __UNIX__ )      /*       * If only a drive was specified, append the current directory,       *  to have the trailing slash for get_full_path().       */      if (dta.stem[1] == ':' && dta.stem[2] == '\0')         strcpy( dta.stem + 2, "./" );#endif      /*       * Let user select file name or another search directory.       */      get_full_path( dta.stem, dname );      strcat( dname, dta.pattern );      rc = select_file( flist, dname, &dir );      if (rc == OK) {         assert( strlen(dta.stem)+strlen(flist[dir.select].name) < PATH_MAX );         get_full_path( dta.stem, dbuff );         strcat( dbuff, flist[dir.select].name );      }      /*       *  give memory back.       */      free( flist );      if (rc == ERROR)         stop = TRUE;      else if (rc == TRUE) {         /*          * Prompt for a new path/pattern.          */         strcpy( dbuff, dname );         len = DIR3_COL + strlen( dir3 );         if (get_string( dir.col+len, dir.row+DIR3_ROW,                         dir.wid - len - 2, Color( Dialog ), '_',                         dbuff, &h_file ) == ERROR) {            stop = TRUE;            rc = ERROR;         } else            xygoto( -1, -1 );      }      /*       * If rc is not OK or ERROR, a drive was selected.       */#if !defined( __UNIX__ )      else if (rc != OK) {         dbuff[0] = rc;         dbuff[1] = ':';         strcpy( dbuff + 2, dta.pattern );      }#endif      else {         /*          * If the last character in a file name is '/' then let's          *  do a dir on selected directory.          */         len = strlen( dbuff );         if (dbuff[len-1] == '/')            strcpy( dbuff + len, dta.pattern );         else {            /*             * user selected a file.             */            stop = TRUE;            strcpy( dname, dbuff );         }      }      if (!stop) {         /*          * Ensure there is something to display. If not, redisplay the          *  current directory. (This will probably only happen on floppies.)          */         ffind = my_findfirst( dbuff, &dta, ALL_DIRS );         if (ffind == NULL)            ffind = my_findfirst( dname, &dta, ALL_DIRS );         else            strcpy( dname, dbuff );      }   }   if (window != NULL)      redraw_screen( window );   return( rc );}/* * Name:    setup_directory_window * Purpose: set number of rows and cols in directory window * Date:    February 13, 1992 * Passed:  dir:   pointer to directory structure *          list:  list of names to be displayed *          cnt:   number of files * Notes:   set up stuff we need to know about how to display files. * * jmh 980524: displayed a few more lines. * jmh 991019: custom frame style based on graphic set. * jmh 991025: use 15 lines if display is over 30; *             center. */void setup_directory_window( DIRECTORY *dir, LIST *list, int cnt ){int  i, j;int  cols[5] = { 0, 0, 0, 0, 0 };       /* number of columns to use */int  wid;const char *fc1;const char *fc2;int  DIR8_ROW;int  inner[2];char temp[40];   /*    * setup the fixed vars used in dir display.    *    dir->col =      physical upper left column of dir screen    *    dir->row =      physical upper left row or line of dir screen    *    dir->wid =      width of physical screen    *    dir->hgt =      height of physical screen    *    dir->max_cols   number of columns of files in dir screen    *    dir->max_lines  number of lines of files in each column in dir screen    *    dir->cnt        number of files in list    */   dir->cnt = cnt;   if (g_status.command == GotoWindow) {      /*       * Use at most two-thirds of the screen for the window list.       */      dir->max_lines = g_display.nlines * 2 / 3;      if (cnt < dir->max_lines)         dir->max_lines = cnt;      /*       * Find the longest window name.       */      for (i = 0; i < cnt; ++i) {         j = strlen( list[i].name );         if (j > cols[0])            cols[0] = j;      }      /*       * Determine the number of columns and lines to use.  If they'll all fit       * in only one column, use that.  Otherwise use the smaller of the       * number of columns that fits the lines, or the number of columns that       * fits the width.  Adjust the lines to fit those columns.       */      if (cnt <= dir->max_lines)         dir->max_cols = 1;      else {         cols[1] = (cnt - 1) / dir->max_lines + 1;         cols[2] = (g_display.ncols - 4 - 4 + 3) / (cols[0] + 3);         dir->max_cols =  cols[1] < cols[2] ? cols[1] : cols[2];         dir->max_lines = cnt / dir->max_cols + (cnt % dir->max_cols ? 1 : 0);         if (dir->max_lines > g_display.nlines - 6)            dir->max_lines = g_display.nlines - 6;      }      /*       * Now set the dimensions of the surrounding frame and each column.       */      dir->hgt = dir->max_lines + 2;      dir->wid = dir->max_cols * (cols[0] + 3) - 3 + 4;      dir->len = cols[0];   } else {      dir->max_lines =  g_display.nlines > 30 ? 15 : 10;      dir->hgt = dir->max_lines + (g_status.command == SyntaxSelect ? 6 : 9);      dir->wid = 76;#if defined( __DOS16__ )      dir->len      = 12;      dir->max_cols = 5;#else      /*       * Figure out the width of each column (ie. the highlight bar/filename       * length). We'll make 12 the smallest ("standard" 8.3) for five columns.       * If the overall width is limited to 76, then the longest name can be       * 72 (two characters for the frame, space each side). However, let's try       * and be clever - if the majority of files are "short", use more columns       * and truncate the longer names.       */      for (i = 0; i < cnt; ++i) {         j = strlen( list[i].name );              if (j <= 12) ++cols[4];      /* depending on the length */         else if (j <= 16) ++cols[3];      /* of the name, increase   */         else if (j <= 22) ++cols[2];      /* the appropriate number  */         else if (j <= 35) ++cols[1];      /* of columns              */         else              ++cols[0];      }      /*       * The number of columns used most is the one selected, unless there's       * enough space to display all files without truncation.       */      for (i = 0; cols[i] == 0; ++i) ;     /* assumes cnt > 0 */      dir->max_cols = i+1;      if (cnt > (i+1) * dir->max_lines) {         j = cols[i];         for (++i; i < 5; ++i) {            if (cols[i] > j) j = cols[i], dir->max_cols = i+1;         }      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -