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

📄 fselect.c

📁 数据挖掘中的bridgit算法的例子。 非常经典
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------  File    : fselect.c  Contents: file selector box with Athena widgets  Author  : Christian Borgelt  History : 28.10.1997 file created            29.10.1997 first version completed            30.10.1997 user callback interface programmed            31.10.1997 minor improvements            02.11.1997 shell type changed to transient            04.11.1997 keyboard focus added            09.11.1997 bug in function getdir removed            04.01.1998 match function simplified            06.04.1998 bug in translations removed----------------------------------------------------------------------*/#define _POSIX_SOURCE#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <dirent.h>#include <sys/stat.h>#include <X11/Intrinsic.h>#include <X11/StringDefs.h>#include <X11/Shell.h>#include <X11/Xaw/Form.h>#include <X11/Xaw/Label.h>#include <X11/Xaw/AsciiText.h>#include <X11/Xaw/List.h>#include <X11/Xaw/Viewport.h>#include <X11/Xaw/Command.h>#include "fselect.h"/*----------------------------------------------------------------------  Preprocessor Definitions----------------------------------------------------------------------*/#define LISTWIDTH   250         /* initial width  of list (pixels) */#define LISTHEIGHT    6         /* initial height of list (lines) */#define BLKSIZE     256         /* block size for file name vector */#define FILT_MAX    256         /* maximal length of filter string *//*----------------------------------------------------------------------  Type Definitions----------------------------------------------------------------------*/typedef struct dirent DIRENT;   /* directory entry */typedef struct stat   FSTAT;    /* file status *//*----------------------------------------------------------------------  Global Variables----------------------------------------------------------------------*/static void fs_dclick (Widget w, XEvent *e, String *s, Cardinal *c);static void fs_focus  (Widget w, XEvent *e, String *s, Cardinal *c);static void fs_next   (Widget w, XEvent *e, String *s, Cardinal *c);static void fs_close  (Widget w, XEvent *e, String *s, Cardinal *c);static XtActionsRec actions[] = {  { "fs_dclick", fs_dclick },   /* double click on list entry */  { "fs_focus",  fs_focus  },   /* set focus on input field */  { "fs_next",   fs_next   },   /* switch to next input field */  { "fs_close",  fs_close  } }; /* close file select dialog box *//*----------------------------------------------------------------------  Global Variables----------------------------------------------------------------------*/static Widget w_shell = NULL;   /* file selector shell */static Widget w_path;           /* file name filter */static Widget w_list;           /* file list */static Widget w_file;           /* file selection */static XtCallbackProc cb_user;  /* user callback function */static FSTAT  status;           /* file status buffer */static char   cwd  [PATH_MAX+2];/* current working directory */static char   cpath[PATH_MAX+FILT_MAX+2] = "\0";static char   *cpend = cpath;   /* current path name and its end */static char   cfilt[FILT_MAX+1] = "\0";  /* current file name filter */static int    dclick = 0;       /* whether to process a double click */static char   **fnames = NULL;  /* file name vector */static int    fncnt    = 0;     /* number of names in vector */static int    fnvsz    = 0;     /* size of file name vector *//*----------------------------------------------------------------------  Auxiliary Functions----------------------------------------------------------------------*/static void cleanup (DIR *dir){                               /* --- clean up on error */  char **p = fnames;            /* to traverse file name vector */  if (dir) {                    /* if a directory is opened, */    closedir(dir);              /* close this directory and */    chdir(cwd);                 /* reset current working directory */  }  if (fnames) {                 /* if file name vector allocated */    while (--fncnt >= 0) { free(*p); p++; }    free(fnames);               /* delete all file names */  }                             /* and the file name vector */  fnames = NULL; fncnt = fnvsz = 0;}  /* cleanup() *//*--------------------------------------------------------------------*/static int match (const char *pattern, const char *string){                               /* --- match string to pattern */  switch (*pattern) {           /* evaluate character in pattern */    case '*' : if (match(pattern+1, string)) return 1;               if (*string  == '\0')         return 0;               return match(pattern,   string+1);    case '?' : if (*string  == '\0')         return 0;               return match(pattern+1, string+1);    default  : if (*pattern != *string)      return 0;               if (*pattern == '\0')         return 1;               return match(pattern+1, string+1);  }                             /* recursively match string */}  /* match() *//*--------------------------------------------------------------------*/static int fncmp (const void *p1, const void *p2){                               /* --- compare two file names */  return strcmp(*(const char**)p1, *(const char**)p2);}  /* fncmp() *//*--------------------------------------------------------------------*/static int getlist (const char *path){                               /* --- get file list */  DIR        *dir;              /* directory to read */  DIRENT     *entry;            /* current directory entry */  const char *name;             /* name of current entry */  char       *copy;             /* copy of entry name */  char       **tmp;             /* buffer for new file name vector */  int        isdir;             /* whether entry is a directory */  int        len;               /* length of entry name */  cleanup(NULL);                /* clean up file name vector */  if ((getcwd(cwd, PATH_MAX) == NULL)  ||  (chdir(path) != 0))       /* note current working directory */    return -1;                  /* and change to directory to read */  dir = opendir(path);          /* open the directory */  if (!dir) return -1;          /* named by path */  while (1) {                   /* directory read loop */    entry = readdir(dir);       /* get next directory entry */    if (!entry) break;          /* if all entries read, abort loop */    name = entry->d_name;       /* get name of directory entry */    if ( (name[0] == '.')       /* if current directory link */    &&  ((name[1] != '.')       /* or hidden file */    ||   (name[2] != '\0')))    /* (i.e. not matching \.\.|[^.].*) */      continue;                 /* skip directory entry */    if (stat(name, &status) != 0) {      cleanup(dir); return -1;} /* get file status */    isdir = S_ISDIR(status.st_mode) ? 1 : 0;    if (!isdir && (cfilt[0] != '\0')    &&  !match(cfilt, name))    /* if file does not match filter, */      continue;                 /* skip directory entry */    if (fncnt >= fnvsz) {       /* if file name vector is full, */      fnvsz += BLKSIZE;         /* increase vector size */      tmp = (char**)realloc(fnames, fnvsz *sizeof(char**));      if (!tmp) { cleanup(dir); return -1; }      fnames = tmp;             /* allocate and set */    }                           /* new file name vector */    len = strlen(name);         /* get length of entry name */    fnames[fncnt] = copy = (char*)malloc(len +1 +isdir);    if (!copy) { cleanup(dir); return -1; }    while (*name) *copy++ = *name++;    if (isdir) *copy++ = '/';   /* copy entry name, */    *copy = '\0';               /* add a '/' for directories and */    fncnt++;                    /* insert it into file name vector */  }  closedir(dir);                /* close directory read and */  chdir(cwd);                   /* reset current working directory */  qsort(fnames, fncnt, sizeof(char*), fncmp);  return 0;                     /* sort names and return 'ok' */}  /* getlist() *//*--------------------------------------------------------------------*/static void update (const char *path, int dialog){                               /* --- update filter and file list */  const char *filter;           /* current path and filter */  int        len;               /* length of path name */  char       *dst;              /* to traverse filter */  filter = strrchr(path, '/');  /* get current path */  if (filter) filter++;         /* and file name filter */  else        filter = path;    /* (starts after last '/') */  len = (filter -path < PATH_MAX) ? (filter -path) : PATH_MAX;  for (dst = cfilt; *filter; ) *dst++ = *filter++;  *dst = '\0';                  /* copy filter to buffer */  for (cpend = cpath; --len >= 0; ) *cpend++ = *path++;  if (cpend <= cpath) *cpend++ = '/';  *cpend = '\0';                /* copy (minimal) path to buffer */  if (dialog) {                 /* if to update dialog box */    if (getlist(cpath) != 0)    /* get new list of files */      fprintf(stderr, "cannot open/read %s\n", cpath);    XawListChange(w_list, fnames, fncnt, 0, True);    strcpy(cpend, cfilt);       /* append filter to path */    XtVaSetValues(w_path, XtNstring, cpath, NULL);  }                             /* set new directory/filter */}  /* update() *//*----------------------------------------------------------------------  Callback Functions----------------------------------------------------------------------*/static void cb_update (Widget w, XtPointer client, XtPointer call){                               /* --- callback for filter button */  const char *path;             /* current path in input field */  XtVaGetValues(w_path, XtNstring, &path, NULL);  update(path, 1);              /* set new path and filename filter */}  /* cb_update() *//*--------------------------------------------------------------------*/static void cb_list (Widget w, XtPointer client, XtPointer call){                               /* --- callback for list selection */  char *name;                   /* name of selected entry */  int  len;                     /* name length of selected entry */  name = ((XawListReturnStruct*)call)->string;  len  = strlen(name);          /* get selected entry and its length */  if (len <= 0) return;         /* if entry is empty, abort function */  if (name[len-1] != '/') {     /* if entry is not a directory */    XtVaSetValues(w_file, XtNstring, name, NULL);    dclick = 1; return;         /* set new selection */  }                             /* and abort function */  if (strcmp(name, "../") == 0){/* if no to go up one level */    cpend -= 2;                 /* get pointer to char before '/' */    while ((cpend >= cpath) && (*cpend != '/'))      cpend--;                  /* search for previous '/' */    if (cpend >= cpath)         /* if '/' found, */      cpend++;                  /* shorten path name */    else {                      /* if '/' not found */      cpend = cpath; *cpend++ = '/';    } }                         /* set minimal path */  else {                        /* if to go down one level */    len += cpend -cpath;        /* add lengths of path and entry name */    if (len >= PATH_MAX)        /* if path name would get too long, */      return;                   /* abort function */    while (*name) *cpend++ = *name++;  }                             /* append directory name to path */  *cpend = '\0';                /* terminate path name */  if (getlist(cpath) != 0)      /* get new list of files */    fprintf(stderr, "cannot open %s\n", cpath);  XawListChange(w_list, fnames, fncnt, 0, True);  strcpy(cpend, cfilt);         /* append filter to path */  XtVaSetValues(w_path, XtNstring, cpath, NULL);  dclick = 0;                   /* inhibit double click processing */}  /* cb_list() *//*--------------------------------------------------------------------*/static void cb_button (Widget w, XtPointer client, XtPointer call){                               /* --- callback for button press */  const char *path, *fname;     /* names of path and file */  XtPopdown(w_shell);           /* close dialog box */  if ((int)client) {            /* if 'ok' button pressed */    XtVaGetValues(w_path, XtNstring, &path, NULL);    update(path, 0);            /* set new path and filename filter */    XtVaGetValues(w_file, XtNstring, &fname, NULL);    strncpy(cpend, fname, FILT_MAX);    cpend[FILT_MAX] = '\0';     /* build final selection */  }                             /* (file name including path) */  cleanup(NULL);                /* clean up file name vector */  if (cb_user)                  /* call user callback function */    cb_user(w, client, ((int)client) ? cpath : NULL);

⌨️ 快捷键说明

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