📄 wildname.c
字号:
/* wildname.c 14.02.04 */
/*
/ --------------------------------------------------------------
/ Copyright (C) 1993: Michael Braun
/ Kaetinger Muehlenweg 103 A
/ D-28816 Stuhr
/ --------------------------------------------------------------
/
/ ausgelagerte functions von mbedit.c
/
/ read files with wildcard names (e.g. "*.c")
/
*/
/************************/
/* include files */
/************************/
#include "config.h"
#include "standard.h"
#include "global.h"
#include "history.h"
#include "disp_hnd.h"
#include "kb_input.h"
#include "mon_outp.h"
#include "file_hnd.h"
#include "err_mess.h"
#include "memo_hnd.h"
#include "commands.h"
#include "directry.h"
#include "wildname.h"
#include "mb_ctype.h"
#include "mousec.h"
#if WILD_NAMES
/* some constants */
#if (ACT_OP_SYSTEM == MS_DOS)
#define DOS_HIGH_SPEED 1 /* <== select here */
#else
#define DOS_HIGH_SPEED 0 /* must always be 0 !! */
#endif
#define TEST_DISPLAY 0
#define TIMING_TEST 0
#define sel_entry de[file_ind].name
/* some local variables */
static int window_length, old_window_length; /* = f (strlen (...text)) */
/* static char file_entry [BUF_256]; */
static int top, left, bot, right;
/* -FF- */
#if (QSORT_FUNC_ANSI)
static int comp_dirs (const void *de1, const void *de2)
#else
static int comp_dirs (de1, de2)
const void *de1;
const void *de2;
#endif
{
return (((struct DIR_ENTRY *) de2)->dir_flag -
((struct DIR_ENTRY *) de1)->dir_flag);
}
#if (QSORT_FUNC_ANSI)
static int comp_names (const void *de1, const void *de2)
#else
static int comp_names (de1, de2)
const void *de1;
const void *de2;
#endif
{
return (strcmp (((struct DIR_ENTRY *) de1)->name,
((struct DIR_ENTRY *) de2)->name));
}
/* -FF- */
static struct DIR_ENTRY *get_directory_buffer (char *path , char *file,
int *dir_num, int *total_num)
{
DIR *act_dir;
struct dirent *act_ent;
int new_ind, found, ii, jj, special, high_speed, dir_flag;
size_t len;
char filter [MAX_FILENAME]; /* without path */
static struct DIR_ENTRY *de;
struct stat buff;
int save_len;
/* get a copy of filename */
strncpy (filter, file, sizeof(filter));
/* step 1.) */
/* check, if directory exists */
if ((act_dir = opendir (path)) == NULL)
return NULL;
/* count no of files */
#if TEST_DISPLAY
show_status_line_2 ("Counting Directory ...", 0, -1, 0);
#endif
*total_num = 0;
while ((act_ent = readdir (act_dir)) != NULL)
{
(*total_num)++; /* count every entry, even those, which are filtered */
} /* out later on. so we are on the safe side. */
closedir (act_dir);
/* free old buffer */
if (de)
free (de);
/* get dynamic memory */
de = (struct DIR_ENTRY *) malloc (*total_num * sizeof (struct DIR_ENTRY));
if (de == NULL) /* NEU ! 29.09.94 */
return NULL;
/* step 2.) */
/* read the filenames into allocated buffer */
if ((act_dir = opendir (path)) == NULL)
return NULL;
#if TEST_DISPLAY
show_status_line_2 ("Reading Directory ...", 0, -1, 0);
#endif
*total_num = 0;
*dir_num = 0;
while ((act_ent = readdir (act_dir)) != NULL)
{
/* look for valid pathname and type (dir or file) */
/* decide, which method is used (stat = slow) */
high_speed = 1;
if ((!DOS_HIGH_SPEED) ||
(strcmp(act_ent->d_name, "..") == 0))
high_speed = 0;
dir_flag = -1; /* invalid */
#if (ACT_OP_SYSTEM == MS_DOS)
if (high_speed)
{
dir_flag = ((act_ent->d_ino & _A_SUBDIR) != 0);
}
else
#endif
{
/* construct full pathname */
save_len = strlen (path);
strncat (path, FILE_SEPARATOR, BUF_256);
strncat (path, act_ent->d_name, BUF_256);
if (!stat (path, &buff))
/* dir_flag = ((buff.st_mode & S_IFMT) == S_IFDIR); bugfix 15.11.96 */
dir_flag = ((buff.st_mode & S_IFDIR) != 0);
/* restore old pathname */
path[save_len] = '\0';
}
/* valid file entry ? */ /* dir_flag = -1 : invalid entry */
/* = 0 : file */
/* = 1 : directory */
if (dir_flag >= 0)
{
if (dir_flag)
{ /* directory */
(*dir_num)++;
de [*total_num].dir_flag = 1;
strncpy (de [*total_num].name, act_ent->d_name, MAX_FILENAME);
(*total_num)++;
}
else
{ /* file */
/* check for special cases "*" and "*.*" */
#if 0
which files do match the filter ?
(all files, with or without extension)
\ filter | "*" | "*.*" |
os \ | | |
------------+---------+---------+
unix + os/9 | all |with ext.|
------------+---------+---------+
ms-dos | w/o ext.| all |
------------+---------+---------+
#endif
special = 0;
if (strcmp (filter, "*" ) == 0) special = 1;
if (strcmp (filter, "*.*") == 0) special = 2;
switch (special)
{
case 1: /* "*" */
#if (ACT_OP_SYSTEM == MS_DOS)
/* use files without extension */
found = (strchr (act_ent->d_name, '.') == NULL);
#else
found = 1; /* use all files */
#endif
break;
case 2: /* "*.*" */
#if (ACT_OP_SYSTEM == MS_DOS)
found = 1; /* use all files */
#else
/* use files with extension */
found = (strchr (act_ent->d_name, '.') != NULL);
#endif
break;
default:
/* check for match */
new_ind = (int) (comm_find ((char FA_HU *)act_ent->d_name, 0L,
(long)strlen (act_ent->d_name), filter,
1, 0, 0,
1, &len));
/* name found ? */
found = (new_ind >= 0);
/* check 1st char */
if ((file[0] != '*') &&
(new_ind != (int) len))
found = 0;
/* check last char */
ii = strlen (file);
jj = strlen (act_ent->d_name);
if ((file[ii-1] != '*') &&
(new_ind != jj))
found = 0;
break;
} /* switch special */
/* use this file ? */
if (found)
{
de [*total_num].dir_flag = 0;
strncpy (de [*total_num].name, act_ent->d_name, MAX_FILENAME);
(*total_num)++;
}
}
}
} /* while act_ent != NULL */
closedir (act_dir);
/* step 3.) */
#if TEST_DISPLAY
show_status_line_2 ("Sorting Directory ...", 0, -1, 0);
#endif
/* sort all entries */
/* sort dirs on top */
qsort (de, *total_num,
sizeof(struct DIR_ENTRY), comp_dirs);
/* sort entries (separate for dirs + files) */
qsort (de, *dir_num,
sizeof(struct DIR_ENTRY), comp_names);
qsort (&de[*dir_num], (*total_num - *dir_num),
sizeof(struct DIR_ENTRY), comp_names);
#if TEST_DISPLAY
show_status_line_2 ("Ready !", 0, -1, 0);
#endif
return de;
} /* get_directory_buffer */
/* -FF- */
static void print_dir_line (char *string , int act_ind ,
int select_flag, int directory_entry)
{
char line_buf [WILD_MAX_LEN+1];
int row, col, ii;
/* print function */
push_cursor ();
row = top + 1 + act_ind;
col = left + 1;
set_cursor_to (row, col);
if (directory_entry)
{
line_buf [0] = '/'; /* 04.03.99, before: 'd' */
set_invers_mode ();
out_1_char (line_buf[0], 0);
set_normal_mode ();
}
else
{
line_buf [0] = ' ';
out_1_char (line_buf[0], 0);
}
/* display 1 line */
if (select_flag) set_invers_mode ();
strncpy (&line_buf[1], string, (window_length-1));
line_buf [window_length] = '\0'; /* forced end of string */
out_string (&line_buf[1]);
#if (!INVERT_WHOLE_LINE)
if (select_flag) set_normal_mode ();
#endif
for (ii = strlen (line_buf) ; ii < window_length ; ii++)
{
out_1_char (' ', 0); /* fill rest of line with blanks */
}
#if (INVERT_WHOLE_LINE)
if (select_flag) set_normal_mode ();
#endif
pop_cursor ();
#if TIMING_TEST
sleep_msec(10); /* @@ */
#endif
return;
} /* print_dir_line */
/* -FF- */
static void plot_dir_content (struct DIR_ENTRY *de,
int top_ind, int row_ind,
int total_num, int plot_new)
{
int entry, row, dir_flag;
char *string;
static int top_old, row_old, refresh_window;
/* window shifted ? */
if ((plot_new) || (top_ind != top_old))
refresh_window = 1;
/* if a key was pressed in between, delay update of window until next time */
if (key_pressed ())
return;
push_cursor ();
/* plot window complete or only 2 lines (old and new one) */
if (refresh_window)
{
refresh_window = 0;
/* loop for all entries up to the selected one */
for (entry = 0 ; entry < HIST_SIZE ; entry++)
{
if (entry < total_num)
{
string = de[entry+top_ind].name;
dir_flag = de[entry+top_ind].dir_flag;
}
else
{
string = "";
dir_flag = 0;
}
print_dir_line (string, entry, (entry == row_ind), dir_flag);
}
}
else
{
/* anything modified at all ? */
if (row_ind != row_old)
{
/* plot old line normal */
entry = row_old;
string = de[entry+top_ind].name;
dir_flag = de[entry+top_ind].dir_flag;
print_dir_line (de[entry+top_ind].name, entry, 0, dir_flag);
/* plot new line invers */
entry = row_ind;
string = de[entry+top_ind].name;
dir_flag = de[entry+top_ind].dir_flag;
print_dir_line (de[entry+top_ind].name, entry, 1, dir_flag);
}
}
/* cursor to end of selected line */
row = top + 1 + row_ind;
set_cursor_to (row, right);
/* save for next turn */
top_old = top_ind;
row_old = row_ind;
pop_cursor ();
return;
} /* plot_dir_content */
/* -FF- */
static void plot_dir_window (struct DIR_ENTRY *de, int total_num)
{
int len, max_len, entry;
static int old_top, old_left, old_bot, old_right;
push_cursor ();
/* bestimme max. laenge aller filenamen dieser directory */
max_len = 0;
for (entry = 0 ; entry < total_num ; entry++)
{
len = strlen (de[entry].name);
max_len = max (max_len, len);
}
/* begrenzen */
max_len = max (max_len, WILD_MIN_LEN);
max_len = min (max_len, WILD_MAX_LEN);
max_len = min (max_len, (COLUMNS - 5));
window_length = max_len + 1 + 1; /* 1 byte for directory flag */
/* 1 byte for optic */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -