|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 10137 (0x2799)
Types: TextFile
Names: »chd.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/chd/chd.c«
/************************************************************/
/* */
/* Copyright (c) 1986 */
/* Marc S. Majka - UBC Laboratory for Computational Vision */
/* */
/* Permission is hereby granted to copy all or any part of */
/* this program for free distribution. The author's name */
/* and this copyright notice must be included in any copy. */
/* */
/************************************************************/
#include <stdio.h>
#include <sgtty.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
main(argc,argv)
int argc;
char *argv[];
{
struct sgttyb iobasic; /* Terminal stuff */
char c, *dirs[128], *malloc(), prompt[256], curr[256];
DIR *cwd, *try, *opendir();
struct direct *dent, *readdir();
struct stat sb;
int dn, i, j, comx, rc;
/* cbreak mode, no echo */
ioctl(fileno(stdin),TIOCGETP,&iobasic);
iobasic.sg_flags |= CBREAK;
iobasic.sg_flags &= ~ECHO;
ioctl(fileno(stdin),TIOCSETN,&iobasic);
getwd(curr);
strcat(curr,"/");
sprintf(prompt,"cd %s",curr);
fprintf(stderr,"? for help, ESC to quit\n\n");
fprintf(stderr,"%s",prompt);
comx = 1;
while (comx >= 0) {
/* read current directory, save a list of subdirectories */
cwd = opendir(curr,"r");
dn = 0;
dent = readdir(cwd); /* skip "." */
while ((dent = readdir(cwd)) != NULL) {
stat(dent->d_name,&sb);
if ((sb.st_mode & S_IFMT) == S_IFDIR) { /* subdirectory */
/* Insert directory name in sorted list */
for (i = 0; i < dn && strcmp(dent->d_name,dirs[i]) > 0; i++);
for (j = dn; j >= i; j--) dirs[j+1] = dirs[j];
dirs[i] = malloc(dent->d_namlen + 1);
strcpy(dirs[i],dent->d_name);
dn++;
}
}
closedir(cwd);
/* let user choose a subdirectory */
comx = getcom(dirs,dn,prompt);
if (comx >= 0) {
rc = chdir(dirs[comx]);
if (rc < 0) {
fprintf(stderr,"\n%s: Permission denied\n",dirs[comx]);
fprintf(stderr,"cd %s",curr);
comx = -1;
}
fprintf(stderr,"/");
sprintf(curr,"%s%s/",curr,dirs[comx]);
if (!strcmp(dirs[comx],"..")) {
j = strlen(curr) - 2;
fprintf(stderr,"\b \b");
for (; (j > 0) && (curr[j] != '/'); j--) fprintf(stderr,"\b \b");
if (j > 0) { j--; fprintf(stderr,"\b \b"); }
for (; (j > 0) && (curr[j] != '/'); j--) fprintf(stderr,"\b \b");
curr[++j] = '\0';
}
sprintf(prompt,"cd %s",curr);
}
for (i = 0; i < dn; i++) free(dirs[i]);
}
fprintf(stderr,"\n");
curr[strlen(curr) - 1] = '\0';
printf("%s\n",curr);
/* reset and exit */
ioctl(fileno(stdin),TIOCGETP,&iobasic);
iobasic.sg_flags &= ~CBREAK;
iobasic.sg_flags |= ECHO;
ioctl(fileno(stdin),TIOCSETN,&iobasic);
exit(0);
}
/****************************************************************/
/* */
/* getcom: get a command (character string) from standard input */
/* author: Marc Majka */
/* Copyright (c) Marc Majka 1985 */
/* */
/* getcom takes a list of character strings in the same format */
/* as that used for argv, and a count of the number of strings */
/* in the list, as in argc. It does EMACS-style string */
/* completion. Getcom returns as its value, the index of the */
/* command. -1 is returned if the user aborts the completion. */
/* Note that the command list "clist" must contain its strings */
/* in sorted order. Also note that getcom expects to have the */
/* terminal in raw or cbreak mode, with no character echoing. */
/* */
/* Characters are read and appended to a command string "cmd". */
/* Certain characters have special meanings: */
/* */
/* ? causes getcom to print all possible completions */
/* ^G and ESC abort and return -1 */
/* <space>, <tab>, and <return> cause getcom to complete */
/* <linefeed> causes completion to the first possible string */
/* <backspace> has the expected result */
/* DEL clears the cmd string and restarts completion */
/* */
/* NOTE TO HACKERS */
/* */
/* A print has been commented out in the "case '?'" near */
/* the beginning of the routine. Throw out the following */
/* print and remove the comments. The only difference is */
/* that the first one includes a space. */
/* */
/****************************************************************/
#include <stdio.h>
getcom(clist,ncmd,prompt)
char **clist;
int ncmd;
char *prompt;
{
int cn,first,last,match,endpt,start,i,ref,c;
char *entry,cmd[256];
match = 0;
endpt = 0;
start = 0;
first = 0;
last = ncmd - 1;
cmd[0] = '\0';
while (!match) {
c = getchar();
switch(c) {
case '?':
match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
if (!match) {
fprintf(stderr,"\n\n");
helpcom(clist,first,last);
/* HERE IT IS: fprintf(stderr,"\n%s %s",prompt,cmd); VANILLA */
fprintf(stderr,"\n%s%s",prompt,cmd); /* NON-VANILLA */
}
else {
entry = clist[cn];
for (i = endpt; entry[i] != '\0'; i++)
fprintf(stderr,"%c",entry[i]);
}
break;
case '\07': /* ^G */
case '\033': /* ESC */
case '\04': /* ^D */
return(-1);
case ' ': /* blank */
case '\t': /* tab */
case '\r': /* return */
match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
if (match) {
entry = clist[cn];
for (i = endpt; entry[i] != '\0'; i++)
fprintf(stderr,"%c",entry[i]);
}
else fprintf(stderr,"%c",7);
break;
case '\n': /* newline */
match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
if (!strcmp(clist[first],cmd)) {
cn = first;
match = 1;
}
if (!match) fprintf(stderr,"%c",7);
break;
case '\b': /* backspace */
if (endpt > 0) {
fprintf(stderr,"\b \b");
endpt--;
cmd[endpt] = '\0';
}
start = 0;
first = 0;
last = ncmd - 1;
break;
case '\025': /* ^U */
for (i = 0; i < endpt; i++) fprintf(stderr,"\b \b");
match = 0;
endpt = 0;
start = 0;
first = 0;
last = ncmd - 1;
cmd[0] = '\0';
break;
default: /* anything else */
fprintf(stderr,"%c",c);
cmd[endpt++] = c;
cmd[endpt] = '\0';
break;
}
}
return(cn);
}
try_match(f,l,s,p,n,clist,cmd)
int *f,*l,*s,*p,*n;
char **clist,*cmd;
{
int i,k,tf,tl;
char *fent,*lent;
if (*p == 0) return(0);
tf = *f;
tl = *l;
k = *p + 1;
fent = clist[tf];
lent = clist[tl];
for (i = *s + 1; i < k; i++) {
fent = clist[tf];
while ((tf < tl) && (strncmp(cmd,fent,i) > 0)) {
tf += 1;
fent = clist[tf];
}
lent = clist[tl];
while ((tl > tf) && (strncmp(cmd,lent,i) < 0)) {
tl -= 1;
lent = clist[tl];
}
}
if (tf == tl) {
if (strncmp(cmd,fent,*p) == 0) {
*f = tf; *l = tl; *s = *p; *n = tf;
return(1);
}
else {
i = *s;
while ((i < *p) && (cmd[i] == fent[i])) i++;
cmd[i] = '\0';
k = i;
for (; i < *p; i++) fprintf(stderr,"\b \b");
*p = k;
return(0);
}
}
else {
i = *p;
while (fent[i] == lent[i]) {
cmd[i] = fent[i];
fprintf(stderr,"%c",cmd[i]);
i++;
}
cmd[i] = '\0';
*f = tf; *l = tl; *p = i; *s = *p;
return(0);
}
}
helpcom(w,f,l)
char **w;
int f,l;
{
int max, i, len, cols, j;
max = 0;
for (i = f; i <= l; i++) {
len = strlen(w[i]) + 1;
if (len > max) max = len;
}
cols = 78 / max;
fprintf(stderr,"? choose one of the following\n");
for (i = f; i <= l; i++) {
if (0 == ((i-f) % cols)) fprintf(stderr,"\n ");
len = strlen(w[i]);
fprintf(stderr,"%s",w[i]);
for (j = len; j < max; j++) fprintf(stderr," ");
}
fprintf(stderr,"\n\n");
fprintf(stderr,"? ^D, ^G or ESC to exit, ^U to clear\n");
fprintf(stderr,"? <space>, <tab> or <return> to complete\n");
fprintf(stderr,"? <linefeed> to insist on first choice\n");
}