This is tab.c in view mode; [Download] [Up]
/* File selection menu Copyright (C) 1992 Joseph H. Allen This file is part of JOE (Joe's Own Editor) JOE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. JOE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JOE; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include "config.h" #include "scrn.h" #include "kbd.h" #include "vs.h" #include "w.h" #include "bw.h" #include "zstr.h" #include "path.h" #include "va.h" #include "menu.h" #include "tty.h" #include "blocks.h" #include "tab.h" typedef struct tab TAB; extern int smode; struct tab { char *path; /* Current directory */ char *pattern; /* Search pattern */ int len; /* No. entries in files */ char **files; /* Array of file names */ char **list; char *type; /* File type array */ int prv; char *orgpath; char *orgnam; }; /* Type codes for file type array */ #define F_DIR 1 #define F_NORMAL 2 #define F_EXEC 4 /* Read matching files from a directory * Directory is given in tab.path * Pattern is given in tab.pattern * * Returns with -1 if there was an error * Otherwise returns index to file with inode given in prv * len and files are set with the file names * type is set with the file types */ static int get_entries(tab,prv) TAB *tab; { int a; int which=0; char *oldpwd=pwd(); char **files; if(chpwd(tab->path)) return -1; files=(char **)rexpnd(tab->pattern); if(!files) { chpwd(oldpwd); return -1; } if(!aLEN(files)) { chpwd(oldpwd); return -1; } tab->len=aLEN(files); varm(tab->files); tab->files=files; vasort(files,tab->len); if(tab->type) free(tab->type); tab->type=(char *)malloc(tab->len); for(a=0;a!=tab->len;a++) { struct stat buf; mset(&buf,0,sizeof(struct stat)); stat(files[a],&buf); if(buf.st_ino==prv) which=a; if((buf.st_mode&S_IFMT)==S_IFDIR) tab->type[a]=F_DIR; else if(buf.st_mode&(0100|0010|0001)) tab->type[a]=F_EXEC; else tab->type[a]=F_NORMAL; } chpwd(oldpwd); return which; } void insnam(bw,path,nam) BW *bw; char *path, *nam; { P *p=pdup(bw->cursor); pbol(p); peol(bw->cursor); bdel(p,bw->cursor); if(sLEN(path)) { binsm(bw->cursor,sv(path)), peol(bw->cursor); if(path[sLEN(path)-1]!='/') binsm(bw->cursor,sc("/")), peol(bw->cursor); } binsm(bw->cursor,sv(nam)); peol(bw->cursor); prm(p); bw->cursor->xcol=piscol(bw->cursor); } /* Given a menu structure with a tab structure as its object, * a pattern and path set in the tab structure: * * Load the menu with a list of file names and set the file name in * the prompt window to the directory the menu was read in from. * If flg is set, treload attempts to position to the previous directory * which was visited. * * Returns with -1 if there was an error * Returns with 0 for success */ int treload(m,flg) MENU *m; { TAB *tab=(TAB *)m->object; /* The menu */ W *w=m->parent; /* Window menu is in */ BW *bw=(BW *)w->win->object; /* The prompt window */ int x; int which; struct stat buf; if((which=get_entries(tab,tab->prv))<0) return -1; if(tab->path && tab->path[0]) stat(tab->path,&buf); else stat(".",&buf); tab->prv=buf.st_ino; if(!flg) which=0; tab->list=vatrunc(tab->list,aLEN(tab->files)); for(x=0;tab->files[x];++x) { char *s=vsncpy(NULL,0,sv(tab->files[x])); tab->list=vaset(tab->list,x,s); if(tab->type[x]==F_DIR) tab->list[x]=vsadd(tab->list[x],'/'); else if(tab->type[x]==F_EXEC) tab->list[x]=vsadd(tab->list[x],'*'); } ldmenu(m,tab->list,which); insnam(bw,tab->path,tab->pattern); return 0; } void rmtab(tab) TAB *tab; { vsrm(tab->orgpath); vsrm(tab->orgnam); varm(tab->list); vsrm(tab->path); vsrm(tab->pattern); varm(tab->files); if(tab->type) free(tab->type); free(tab); } /* The user hit return */ int tabrtn(m,cursor,tab) MENU *m; TAB *tab; { if(tab->type[cursor]==F_DIR) { /* Switch directories */ char *orgpath=tab->path; char *orgpattern=tab->pattern; char *e=endprt(tab->path); if(!zcmp(tab->files[cursor],"..") && sLEN(e) && !(e[0]=='.' && e[1]=='.' && (!e[2] || e[2]=='/'))) tab->path=begprt(tab->path); else { tab->path=vsncpy(NULL,0,sv(tab->path)); tab->path=vsncpy(sv(tab->path),sv(m->list[cursor])); } vsrm(e); tab->pattern=vsncpy(NULL,0,sc("*")); if(treload(m,0)) { msgnw(m,"Couldn't read directory "); vsrm(tab->pattern); tab->pattern=orgpattern; vsrm(tab->path); tab->path=orgpath; return -1; } else { vsrm(orgpattern); vsrm(orgpath); return 0; } } else { /* Select name */ BW *bw=m->parent->win->object; insnam(bw,tab->path,tab->files[cursor]); rmtab(tab); m->object=0; m->abrt=0; wabort(m->parent); return 0; } } /* The user hit backspace */ int tabbacks(m,cursor,tab) MENU *m; TAB *tab; { char *orgpath=tab->path; char *orgpattern=tab->pattern; char *e=endprt(tab->path); if(sLEN(e)) tab->path=begprt(tab->path); else { wabort(m->parent); return 0; } vsrm(e); tab->pattern=vsncpy(NULL,0,sc("*")); if(treload(m,1)) { msgnw(m,"Couldn't read directory "); vsrm(tab->pattern); tab->pattern=orgpattern; vsrm(tab->path); tab->path=orgpath; return -1; } else { vsrm(orgpattern); vsrm(orgpath); return 0; } } int tababrt(bw,cursor,tab) BW *bw; TAB *tab; { insnam(bw,tab->orgpath,tab->orgnam); rmtab(tab); return -1; } /* Create a tab window */ int cmplt(bw) BW *bw; { MENU *new; TAB *tab; P *p, *q; char *cline, *tmp; long a,b; tab=(TAB *)malloc(sizeof(TAB)); new=mkmenu(bw,NULL,tabrtn,tababrt,tabbacks,0,tab,NULL); if(!new) { free(tab); return -1; } tab->files=0; tab->type=0; tab->list=0; tab->prv=0; tab->len=0; p=pdup(bw->cursor); pbol(p); q=pdup(bw->cursor); peol(q); tmp=brvs(p,(int)(q->byte-p->byte)); cline=parsens(tmp,&a,&b); vsrm(tmp); prm(p); prm(q); tab->pattern=namprt(cline); tab->path=dirprt(cline); tab->orgnam=vsncpy(NULL,0,sv(tab->pattern)); tab->orgpath=vsncpy(NULL,0,sv(tab->path)); tab->pattern=vsadd(tab->pattern,'*'); vsrm(cline); if(treload(new,0)) { wabort(new->parent); ttputc(7); return -1; } else if(sLEN(tab->files)==1) return tabrtn(new,0,tab); else if(smode || isreg(tab->orgnam)) return 0; else { char *com=mcomplete(new); vsrm(tab->orgnam); tab->orgnam=com; wabort(new->parent); smode=2; ttputc(7); return 0; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.