📄 wpickfil.c
字号:
/* CXL - Copyright (c) 1987-1990 by Mike Smedley - All Rights Reserved */
/* WPICKFIL.C - allows user to select a file name */
#include <ctype.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cxldef.h"
#include "cxlstr.h"
#include "cxlwin.h"
#if defined(__TURBOC__) /* Turbo C */
#include <dir.h>
#else /* all others */
#include <direct.h>
#endif
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C/QuickC */
#define findfirst(a,b,c) _dos_findfirst(a,c,b)
#define findnext(a) _dos_findnext(a)
#define ffblk _find_t
#define ff_name name
#define ff_attrib attrib
#define FA_DIREC _A_SUBDIR
static int tnumdrives;
#elif defined(__ZTC__) /* Zortech C/C++ */
#define ffblk FIND
#define ff_name name
#define ff_attrib attribute
#endif
static int compare(char **str1,char **str2);
static void disp_title(void);
static int find_first(char *filespec,struct ffblk *ffblk,int attrib);
static int find_next(struct ffblk *ffblk);
static void free_strings(char **p,int numelems);
static void pre_exit(char **p,int numelems);
static void reset_drive(void);
static char _Near _Cdecl dspec[81];
static char _Near _Cdecl fspec[81];
static char _Near _Cdecl search_path[81];
static char _Near _Cdecl save_path[69];
static char _Near _Cdecl new_path[81];
static int _Near _Cdecl save_drive;
static int _Near _Cdecl gtitle;
static void (*gopen)(void);
char *wpickfile(int srow,int scol,int erow,int ecol,int btype,int bordattr,
int winattr,int barattr,int title,char *filespec,
void (*open)(void))
{
register char **p;
int i;
int num_files,done,match=FALSE,finished;
char *q,*pfs;
struct ffblk ffblk;
/* allocate space to hold array of char pointers */
if((p=malloc((_winfo.maxfiles+1)*sizeof(char *)))==NULL) {
_winfo.errno=W_ALLOCERR;
return(NULL);
}
/* set static variables */
gtitle=title;
gopen=open;
/* find start of unqualified filespec */
if((pfs=strrchr(filespec,'\\'))==NULL) {
pfs=filespec;
if(*(pfs+1)==':') {
pfs++;
pfs++;
}
}
else
pfs++;
/* save current disk drive */
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C/QuickC */
_dos_getdrive(&save_drive);
#else /* all others */
save_drive=getdisk();
#endif
/* if drive was specified, change to it */
if(*(filespec+1)==':') {
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C/QuickC */
_dos_setdrive(toupper(*filespec)-'A'+1,&i);
#else
setdisk(toupper(*filespec)-'A'); /* all others */
#endif
}
/* save current working directory */
getcwd(save_path,68);
/* if a directory was specified, change to it */
if((q=strrchr(strcpy(new_path,filespec),'\\'))!=NULL) {
if(q==(new_path+2))
*(q+1)='\0';
else
*q='\0';
if(chdir(new_path)) {
reset_drive();
free(p);
_winfo.errno=W_INVPATH;
return(NULL);
}
}
/* create initial search path */
getcwd(search_path,68);
if(*(search_path+strlen(search_path)-1)!='\\') strcat(search_path,"\\");
/* go back to original drive */
reset_drive();
/* go back to original path */
chdir(save_path);
do {
/* build file search filespec from search path */
strcpy(fspec,search_path);
strcat(fspec,pfs);
strupr(fspec);
/* build directory search filespec from search path */
strcpy(dspec,search_path);
strcat(dspec,"*.*");
/* find all directories in current directory, */
/* allocating an array element for each of them */
i=0;
done=find_first(dspec,&ffblk,FA_DIREC);
while(!done) {
if(ffblk.ff_attrib&FA_DIREC) {
if(i==_winfo.maxfiles) break;
match=TRUE;
if((p[i]=malloc(14*sizeof(char)))==NULL) {
pre_exit(p,i);
_winfo.errno=W_ALLOCERR;
return(NULL);
}
strncpy(p[i],ffblk.ff_name,13);
strcat(p[i],"\\");
i++;
}
done=find_next(&ffblk);
}
/* find all files matching input filespec in current */
/* directory, allocating an array element for each */
done=find_first(fspec,&ffblk,0);
if(done&&!match) {
pre_exit(p,i);
_winfo.errno=W_NOMATCH;
return(NULL);
}
match=TRUE;
while(!done) {
if(i==_winfo.maxfiles) break;
if((p[i]=malloc(14*sizeof(char)))==NULL) {
pre_exit(p,i);
_winfo.errno=W_ALLOCERR;
return(NULL);
}
strncpy(p[i],ffblk.ff_name,13);
i++;
done=find_next(&ffblk);
}
p[i]=NULL;
num_files=i;
/* sort files in array by swapping their pointers */
qsort(p,num_files,sizeof(char*),
(int (*)(const void *,const void *))compare);
/* let user pick a file or directory */
i=wpickstr(srow,scol,erow,ecol,btype,bordattr,winattr,barattr,p,0,
disp_title);
/* check for error return from wpickstr() */
if(_winfo.errno) {
pre_exit(p,num_files);
return(NULL);
}
/* if a directory was selected, then modify search path. */
/* otherwise, create full pathname of selected file. */
if((q=strrchr(p[i],'\\'))!=NULL) {
finished=NO;
if(*(p[i]+1)=='.') { /* previous directory */
*(strrchr(search_path,'\\'))='\0';
*(strrchr(search_path,'\\')+1)='\0';
}
else if(*(p[i])=='.') { /* same directory */
}
else { /* subdirectory */
strcat(search_path,p[i]);
}
}
else {
finished=YES;
strcat(search_path,p[i]);
}
/* free allocated strings */
free_strings(p,num_files);
} while(!finished);
/* free allocated char pointers */
free(p);
/* return normally */
_winfo.errno=W_NOERROR;
return(search_path);
}
char *wpickfile_criteria(int srow,int scol,int erow,int ecol,int btype,int bordattr,
int winattr,int barattr,int title,char *filespec,
void (*open)(void), int pick_criteria(char *name))
{
char **p;
int i;
int num_files,done,match=FALSE,finished;
char *q,*pfs;
struct ffblk ffblk;
char fname[255];
/* allocate space to hold array of char pointers */
if((p=malloc((_winfo.maxfiles+1)*sizeof(char *)))==NULL) {
_winfo.errno=W_ALLOCERR;
return(NULL);
}
/* set static variables */
gtitle=title;
gopen=open;
/* find start of unqualified filespec */
if((pfs=strrchr(filespec,'\\'))==NULL) {
pfs=filespec;
if(*(pfs+1)==':') {
pfs++;
pfs++;
}
}
else
pfs++;
/* save current disk drive */
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C/QuickC */
_dos_getdrive(&save_drive);
#else /* all others */
save_drive=getdisk();
#endif
/* if drive was specified, change to it */
if(*(filespec+1)==':') {
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C/QuickC */
_dos_setdrive(toupper(*filespec)-'A'+1,&i);
#else
setdisk(toupper(*filespec)-'A'); /* all others */
#endif
}
/* save current working directory */
getcwd(save_path,68);
/* if a directory was specified, change to it */
if((q=strrchr(strcpy(new_path,filespec),'\\'))!=NULL) {
if(q==(new_path+2))
*(q+1)='\0';
else
*q='\0';
if(chdir(new_path)) {
reset_drive();
free(p);
_winfo.errno=W_INVPATH;
return(NULL);
}
}
/* create initial search path */
getcwd(search_path,68);
if(*(search_path+strlen(search_path)-1)!='\\') strcat(search_path,"\\");
/* go back to original drive */
reset_drive();
/* go back to original path */
chdir(save_path);
do {
/* build file search filespec from search path */
strcpy(fspec,search_path);
strcat(fspec,pfs);
strupr(fspec);
/* build directory search filespec from search path */
strcpy(dspec,search_path);
strcat(dspec,"*.*");
/* find all directories in current directory, */
/* allocating an array element for each of them */
i=0;
done=find_first(dspec,&ffblk,_A_SUBDIR);
while(!done) {
if(ffblk.ff_attrib&_A_SUBDIR) {
if(i==_winfo.maxfiles) break;
match=TRUE;
if((p[i]=malloc(14*sizeof(char)))==NULL) {
pre_exit(p,i);
_winfo.errno=W_ALLOCERR;
return(NULL);
}
strncpy(p[i],ffblk.ff_name,13);
strcat(p[i],"\\");
i++;
}
done=find_next(&ffblk);
}
/* find all files matching input filespec in current */
/* directory, allocating an array element for each */
done=find_first(fspec,&ffblk,_A_NORMAL);
if(done&&!match) {
pre_exit(p,i);
_winfo.errno=W_NOMATCH;
return(NULL);
}
match=TRUE;
while(!done) {
if(i==_winfo.maxfiles) break;
strcpy(fname, search_path);
strcat(fname, ffblk.ff_name);
if (pick_criteria(fname)) {
if ((p[i]=malloc(14*sizeof(char)))==NULL) {
pre_exit(p,i);
_winfo.errno=W_ALLOCERR;
return(NULL);
}
strncpy(p[i],ffblk.ff_name,13);
i++;
}
done=find_next(&ffblk);
}
p[i]=NULL;
num_files=i;
/* sort files in array by swapping their pointers */
qsort(p,num_files,sizeof(char*),
(int (*)(const void *,const void *))compare);
/* let user pick a file or directory */
i=wpickstr(srow,scol,erow,ecol,btype,bordattr,winattr,barattr,p,0,
disp_title);
/* check for error return from wpickstr() */
if(_winfo.errno) {
pre_exit(p,num_files);
return(NULL);
}
/* if a directory was selected, then modify search path. */
/* otherwise, create full pathname of selected file. */
if((q=strrchr(p[i],'\\'))!=NULL) {
finished=NO;
if(*(p[i]+1)=='.') { /* previous directory */
*(strrchr(search_path,'\\'))='\0';
*(strrchr(search_path,'\\')+1)='\0';
}
else if(*(p[i])=='.') { /* same directory */
}
else { /* subdirectory */
strcat(search_path,p[i]);
}
}
else {
finished=YES;
strcat(search_path,p[i]);
}
/* free allocated strings */
free_strings(p,num_files);
} while(!finished);
/* free allocated char pointers */
free(p);
/* return normally */
_winfo.errno=W_NOERROR;
return(search_path);
}
/*---------------------------------------------------------------------------*/
/* this function is the compare function for qsort() */
static int compare(char **str1,char **str2)
{
return(strcmp(*str1,*str2));
}
/*---------------------------------------------------------------------------*/
/* this function displays the title on the pick window border */
static void disp_title(void)
{
if(gtitle) wtitle(fspec,TCENTER,_winfo.active->battr);
if(gopen!=NULL) (*gopen)();
}
/*---------------------------------------------------------------------------*/
static int find_first(char *filespec,struct ffblk *ffblk,int attrib)
{
register int done;
#if defined(__ZTC__) /* Zortech C/C++ */
struct ffblk *pffblk;
if((pffblk=findfirst(filespec,attrib))==NULL)
done=YES;
else {
*ffblk=*pffblk;
done=NO;
}
#else /* all others */
done=findfirst(filespec,ffblk,attrib);
#endif
return(done);
}
/*---------------------------------------------------------------------------*/
static int find_next(struct ffblk *ffblk)
{
register int done;
#if defined(__ZTC__) /* Zortech C/C++ */
struct ffblk *pffblk;
pffblk=findnext();
if(pffblk==NULL)
done=YES;
else {
done=NO;
*ffblk=*pffblk;
}
#else /* all others */
done=findnext(ffblk);
#endif
return(done);
}
/*---------------------------------------------------------------------------*/
/* this function frees all allocated strings in the array of pointers */
static void free_strings(char **p,int numelems)
{
register int i;
for(i=0;i<numelems;i++) free(p[i]);
}
/*---------------------------------------------------------------------------*/
static void pre_exit(char **p,int numelems)
{
free_strings(p,numelems);
free(p);
}
/*---------------------------------------------------------------------------*/
/* this function resets the current drive back to the original drive */
static void reset_drive(void)
{
#if defined(_M_IX86) && !defined(__ZTC__) /* Microsoft C, QuickC */
int num_drives;
_dos_setdrive(save_drive,&num_drives);
#else /* all others */
setdisk(save_drive);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -