|
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"); }