home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / reactivekbd / part01 / dt_complete.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-16  |  13.6 KB  |  434 lines

  1. #include <alloca.h>        /* JJD: some other alloc may be better to use  */
  2. #include <stdio.h>
  3. #include <sys/file.h>
  4. #include <sys/types.h>
  5. #include <sys/dir.h>
  6. #include <sys/stat.h>  
  7. #include <sys/param.h>        /* JJD 3-89 added to get MAXPATHLEN and CANBSIZ*/
  8. #include "file+rk.h"
  9. #include "functions.h"
  10.  
  11.  
  12. #define FILECOMPLETION 3    /* change if you need to change the binding of
  13.                    filecompletion */
  14.  
  15. /* MAX_FILENAME_LENGTH must be less than MAX_CMD_LINE_LENGTH (CANBSIZ, 256)*/
  16. /*                                       */
  17. /* dir.h MAXNAMLEN is 255 (+1 for char [])       JJD 3-89 #define       */
  18.  
  19. #define MAX_DIR_TO_SEARCH    16        /* WARNING: just a guess!  */
  20. #define MAX_FILES_TO_SAVE    1024        /* WARNING: just a guess!  */
  21. #define MAX_FILENAME_LENGTH     MAXNAMLEN     /*          store bounds   */
  22. #define MAX_PATHNAME_LENGTH     MAXPATHLEN
  23.  
  24. extern num_buffers;
  25. extern char *cursor_left;
  26. extern char output_string[];
  27. extern output_string_length;
  28. extern char pred_mode,pred_on_display;
  29. extern char pred_buff[];
  30. extern (*keymap[128][MAXEXTENSIONS]) ();
  31.  
  32. int run_ruptime (e) ED_STRUCT *e; {
  33.   
  34.       write (1, "\015\n", 2);                    /* JJD 3-89*/
  35.       quietly_run_program_connected_to_standard_tty ("uptime"); /* JJD 3-89*/
  36.       write (1, "Continue: ", 10);
  37.       draw_current_edit_line (e);
  38.       return OK;
  39. }
  40.  
  41. /* AN IDEA: a better way would look ahead a next char, if not this, put     */
  42. /*        in the read buffer and return, else stay here - write (un)getc. */
  43.   
  44. int file_completion (e) ED_STRUCT *e; {
  45.       char *cwd,
  46.            *getcwd(),
  47.            *tdot,
  48.            *tchar,chr,
  49.            *f_name[MAX_FILES_TO_SAVE],        /* JJD 3-89 to ptrs, defines*/
  50.            tstring[MAX_CMD_LINE_LENGTH + 1],
  51.            de_name[MAX_FILENAME_LENGTH + 1],    /* JJD 3-89 dir entry name  */
  52.            full_path[MAXPATHLEN];
  53.  
  54.       DIR  *opendir(),
  55.            *dir_pointer;
  56.  
  57.       struct direct *readdir(),
  58.                     *d_entry;
  59.       int match=0,
  60.           length,
  61.           past_first=0,
  62.           strncmp(),
  63.           ful_path=0,
  64.           count,
  65.           cmatch,
  66.           return_this = OK;                 /* JJD 2-89 added */
  67.             /* now look for start of filename to match */
  68.      for (tdot=e->dot;((*tdot != ' ') && (tdot != e->current_buffer));tdot--);
  69.  
  70.             /* if we aren't at the start of the whole buffer
  71.                then move ahead a char (to skip the space) */
  72.       if (tdot != e->current_buffer) tdot++;
  73.                         /* and save the string to look for */
  74.       strcpy(tstring, tdot);
  75.       for (tchar=tstring;((*tchar != '\/')&&(*tchar!='\0'));tchar++);
  76.       if (*tchar == '\/') {
  77.     ful_path = 1;
  78.     strcpy(full_path,tstring);
  79.     tchar=full_path;
  80.     while (*tchar!='\0') tchar++;
  81.     while ((*tchar!='\/') && (tchar != full_path)) tchar--;
  82.         if (tchar != full_path) {
  83.       *tchar = '\0';
  84.       tchar++;strcpy(tstring,tchar);
  85.     }
  86.       }
  87.       if (ful_path){
  88.     cwd = full_path;
  89.       }
  90.       else {
  91.     void    (*sig)();
  92.     sig=signal(SIGCHLD,SIG_DFL); 
  93.     getcwd(full_path);cwd=full_path;        /* get working directory */
  94.     signal(SIGCHLD,sig); 
  95.       }
  96.       if ((dir_pointer = opendir(cwd)) == NULL){    /* and open it to look */
  97.     write(1, "\07",1);
  98.     return OK;
  99.       }            /* now look for any matching filenames and
  100.                increment match if we find one */
  101.       d_entry=readdir(dir_pointer);
  102.       for (; d_entry != NULL; d_entry = readdir(dir_pointer)){
  103.         strcpy (de_name, d_entry->d_name);
  104.     if (strncmp(tstring, de_name, strlen(tstring)) == 0){
  105.          if ((strcmp(".", de_name) != 0) &&
  106.              (strcmp("..", de_name) != 0)){    /* JJD 3-89 del . .. */
  107.          f_name[match] = (char *) alloca (strlen(de_name) + 1);
  108.          strcpy(f_name[match],de_name);
  109.       if (++match >= MAX_FILES_TO_SAVE) {
  110.           goto tomany;   /* JJD 3-89 forget about the rest of them */
  111.       }
  112.      }
  113.     }
  114.       }
  115. tomany:
  116.       if (match == 0) {
  117.     write(1,"\07",1);
  118.     if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 added if*/
  119.     return OK;
  120.       }
  121.             /* else we found at least 1  match */      
  122.       else {
  123.         ssort (f_name, match); /* JJD 3-89, alpha */
  124.     cmatch = 0;
  125. again:    output_string_length = 0;
  126.     if (!past_first) length=strlen(tstring);
  127.     else {
  128.       if (cmatch == 0) length=strlen(f_name[match-1]);
  129.       else length=strlen(f_name[cmatch-1]);
  130.     }
  131.     if (ful_path) length = length + strlen(full_path)+1;
  132.                               /* so move the cursor to the beginning
  133.                  of the file name */
  134.     for (; length; --length)
  135.       tputs (cursor_left, ONE_LINE,append_to_output_string);
  136.                               /* set current dot to beginning of the
  137.                  file name and copy in the filename*/ 
  138.     e->dot = tdot;
  139.     if (ful_path){
  140.       strcpy(e->dot,full_path);
  141.       strcat(e->dot,"\/");
  142.       strcat(e->dot,f_name[cmatch]);
  143.     }
  144.  
  145. /* JJD: WARNING: prev and next str ops could overflow ed_buff, should test */
  146.  
  147.     else strcpy(e->dot,f_name[cmatch]);
  148.                   /* reset dot to the end of the line */    
  149.         if (e->mark > e->dot) e->mark += strlen (f_name[cmatch]);/*JJD 3-89*/
  150.     e->dot += strlen(f_name[cmatch]);
  151.  
  152. /* JJD: WARNING: prev and next dot resets could overflow ed_buff, as above */
  153.  
  154.     if (ful_path) {
  155.           if (e->mark > e->dot) e->mark += strlen(full_path)+1;
  156.       e->dot += strlen(full_path)+1;
  157.     }
  158.                               /* and concatenate onto output string the
  159.                  filename, write it to screen */
  160.     if (ful_path) {
  161.       display_string_into_output_string(full_path);
  162.       display_string_into_output_string("\/");
  163.     }
  164.     display_string_into_output_string (f_name[cmatch]);
  165.         if (cmatch == 0)length=strlen(f_name[match-1])-strlen(f_name[cmatch]);
  166.     else length=strlen(f_name[cmatch-1])-strlen(f_name[cmatch]);
  167.     for (count=0;count<length;count++){
  168.       display_string_into_output_string(" ");
  169.     }
  170.     for (count=0;count<length;count++){
  171.       tputs (cursor_left, ONE_LINE,append_to_output_string);
  172.     }
  173.     write (1, output_string, output_string_length);
  174.     if (pred_mode) {                 /* JJD 2-89 added */
  175.             make_a_prediction (pred_buff);
  176.         if (pred_buff[0]) display_pred_buffer (e);
  177.     }
  178.     
  179.     READ(0,&chr,1);
  180.     chr &= 127;                     /* JJD 2-89 added */
  181.         if (pred_on_display) erase_pred_buffer (e);      /* JJD 2-89 added */
  182.     if (chr == FILECOMPLETION) {
  183.       past_first = 1;
  184.       if (cmatch < match-1) {
  185.         cmatch++;
  186.         goto again;
  187.       }
  188.       else {cmatch=0;goto again;}
  189.     }
  190.     else {
  191. /* JJD: it would be better to ungetc and return */
  192.           return_this = OK;                 /* JJD 2-89 added */
  193.       e->current_input_char = chr;
  194.       return_this = keymap[(int)chr][0](e); /* JJD 2-89 add return_this */
  195.       if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 add if*/
  196.       return (return_this);               /* JJD 2-89 add return_this */
  197.     }
  198.       }
  199.     }
  200.  
  201.  
  202. int command_completion (e) ED_STRUCT *e;{
  203.   char *path_var,        /* points to the environment variable PATH */
  204.        *tdot,
  205.        *tchar, 
  206.        chr,
  207.        *paths[MAX_DIR_TO_SEARCH],        /* JJD 3-89 changed to ptrs */
  208.            *f_name[MAX_FILES_TO_SAVE],
  209.            tstring[MAX_CMD_LINE_LENGTH + 1],
  210.            d_name[MAX_PATHNAME_LENGTH + 1],
  211.            de_name[MAX_FILENAME_LENGTH + 1],
  212.            t_name[MAX_PATHNAME_LENGTH + MAX_FILENAME_LENGTH + 1],
  213.        *getenv();
  214.   int  count,
  215.        num_dirs=0,        /* number of directories to look in */
  216.        current_search_directory,/* the current directory to look at */
  217.        cmatch,
  218.        match=0,
  219.        length,
  220.        past_first=0,
  221.        return_this = OK;                 /* JJD 2-89 added */
  222.  
  223. DIR  *opendir(),
  224.      *dir_pointer;
  225.  
  226. struct direct *readdir(),
  227.               *d_entry;
  228. struct stat   buf;                 /* JJD 3-89 added */
  229.  
  230.                 /* get the file name to match */  
  231.   for (tdot=e->dot;((*tdot != ' ') && (tdot != e->current_buffer));tdot--);
  232.   if (tdot != e->current_buffer) tdot++;
  233.   strcpy(tstring, tdot);
  234.  
  235.   path_var = getenv("PATH");
  236.   if (path_var == NULL) {              /* JJD 3-89 added test */
  237.     write(1,"\07",1);
  238.     return OK;
  239.   }
  240.   else {
  241.   tchar = path_var;                 /* skip the first :  */
  242. /* JJD: this assumes a "normal" PATH, which it is 99.99% likely to be */
  243.   if (path_var[0] == ':')  tchar++;         /* JJD 3-89 added if */
  244.   while(*tchar != '\0'){
  245.     count=0;                     /* JJD 3-89 stay in bounds*/
  246.     while ((*tchar != ':') && (*tchar != '\0'))  d_name[count++] = *tchar++;
  247.     if (*tchar == ':') tchar++;  
  248.     d_name[count] = '\0';
  249.     paths[num_dirs] = (char *) alloca (strlen(d_name) + 1);
  250.     strcpy (paths[num_dirs], d_name);
  251.     if (++num_dirs >= MAX_DIR_TO_SEARCH) {
  252.       goto tomanydirs; /* JJD 3-89 forget the rest*/
  253.     }
  254.   }
  255. tomanydirs:
  256. /* now have num_dirs directories to search for the command in */
  257. /* JJD 3-89 NOW CHECKS FOR EXECUTE PERMISSION and NOT A DIRECTORY,      */
  258. /*         THEN SORTS IN ALPHA ORDER, LEAVING IN DUPLICATED (are rare) */
  259.  
  260.  current_search_directory = 0;            /* JJD 3-89 changed <= to < */
  261.  for (;current_search_directory<num_dirs;current_search_directory++){
  262.     strcpy (d_name, paths[current_search_directory]); strcat (d_name, "/");
  263.     if ((dir_pointer = opendir(&paths[current_search_directory][0])) != NULL){
  264.       d_entry=readdir(dir_pointer);
  265.       for (;d_entry != NULL;d_entry = readdir(dir_pointer)){
  266.         strcpy (de_name, d_entry->d_name);
  267.         if (strncmp(tstring, de_name, strlen(tstring)) == 0){
  268.          if ((strcmp(".", de_name) != 0) &&
  269.              (strcmp("..", de_name) != 0)) {   /* JJD 3-89 del . .. */
  270.       strcpy (t_name, d_name); strcat (t_name, de_name);
  271.       if (access (t_name, X_OK) == 0) {        /* executable */
  272.         if (stat(t_name,&buf) == 0){
  273.          if ((buf.st_mode & S_IFMT) != S_IFDIR){ /* not a dir */
  274.          f_name[match] = (char *) alloca (strlen(de_name) + 1);
  275.          strcpy(f_name[match],de_name);
  276.          if (++match >= MAX_FILES_TO_SAVE) {
  277.             goto tomanyfiles; /* JJD 3-89 above */
  278.          }
  279.         }
  280.        }
  281.       }
  282.      }
  283.     }
  284.       }
  285.     }
  286. tomanyfiles:
  287.     if (dir_pointer != NULL) closedir(dir_pointer);
  288.   }
  289.   if (match == 0) {
  290.     write(1,"\07",1);
  291.     return OK;
  292.   }
  293.               /* else we found at least 1  match */      
  294.   else {
  295.     ssort (f_name, match); /* JJD 3-89, alpha */
  296.     cmatch = 0;
  297. again:    output_string_length = 0;
  298.     if (!past_first) length=strlen(tstring);
  299.     else {
  300.       if (cmatch == 0) length=strlen(f_name[match-1]);
  301.       else length=strlen(f_name[cmatch-1]);
  302.     }
  303.     for (; length; --length)
  304.       tputs (cursor_left, ONE_LINE,append_to_output_string);
  305. /* set current dot to beginning of the file name and copy in the filename*/ 
  306.     e->dot = tdot;
  307.     strcpy(e->dot,f_name[cmatch]);
  308.  
  309. /* JJD: WARNING: prev strcpy could overflow ed_buff, should test */
  310. /* JJD: WARNING: next dot reset could overflow ed_buff, as above */
  311.                 /* reset dot to the end of the line */    
  312.  
  313.     if (e->mark > e->dot) e->mark += strlen (f_name[cmatch]); /* JJD 3-89 */
  314.     e->dot += strlen(f_name[cmatch]);
  315.     display_string_into_output_string (f_name[cmatch]);
  316.     if (cmatch == 0) length=strlen(f_name[match-1])-strlen(f_name[cmatch]);
  317.     else length=strlen(f_name[cmatch-1])-strlen(f_name[cmatch]);
  318.     for (count=0;count<length;count++){
  319.       display_string_into_output_string(" ");
  320.     }
  321.     for (count=0;count<length;count++){
  322.       tputs (cursor_left, ONE_LINE,append_to_output_string);
  323.     }
  324.     write (1, output_string, output_string_length);
  325.     if (pred_mode) {                 /* JJD 2-89 added */
  326.             make_a_prediction (pred_buff);
  327.         if (pred_buff[0]) display_pred_buffer (e);
  328.     }
  329.     
  330.     READ(0,&chr,1);
  331.     chr &= 127;                     /* JJD 2-89 added */
  332.         if (pred_on_display) erase_pred_buffer (e);      /* JJD 2-89 added */
  333.     if (chr == (char)28) {                 /* JJD 2-89 made ^\*/
  334.       past_first = 1;
  335.       if (cmatch < match-1) {
  336.         cmatch++;
  337.         goto again;
  338.       }
  339.       else {cmatch=0;goto again;}
  340.     }
  341.     else {
  342. /* JJD: it would be better to ungetc and return */
  343.           return_this = OK;                 /* JJD 2-89 added */
  344.       e->current_input_char = chr;
  345.       return_this = keymap[(int)chr][0](e); /* JJD 2-89 add return_this */
  346.       if (dir_pointer != NULL) closedir(dir_pointer); /* JJD 3-89 add if*/
  347.       return (return_this);               /* JJD 2-89 add return_this */
  348.     }
  349.   }
  350.   }
  351. }
  352.  
  353.  
  354. set_mark (e) ED_STRUCT *e; {
  355.   e->mark = e->dot;         /* JJD 3-89 mark intialized in set_up_buffers()*/
  356.   e->current_ed_buff_ptr->mark = e->dot;              /* JJD 3-89 added */
  357. }
  358.  
  359. show_mark (e) ED_STRUCT *e; {
  360.   int num_to_go;
  361.   if (e->mark > e->dot){
  362.     e->universal_argument = num_to_go = e->mark - e->dot;
  363.     forward_char (e);
  364.     sleep(1);                        /* JJD 3-89 change */
  365.     e->universal_argument = num_to_go;
  366.     backward_char (e);
  367.   }
  368.   else if (e->mark < e->dot){
  369.     e->universal_argument = num_to_go = e->dot - e->mark;
  370.     backward_char (e);
  371.     sleep(1);                        /* JJD 3-89 change */
  372.     e->universal_argument = num_to_go;
  373.     forward_char (e);
  374.   }
  375. }
  376.  
  377. delete_region_to_killbuffer (e) ED_STRUCT *e; {
  378.  
  379.   int length;
  380.  
  381.   if (e->dot > e->mark){
  382.     length = e->dot - e->mark;
  383.     strncpy(e->kill_buffer, e->mark, length);
  384.     e->kill_buffer[length] = '\0';
  385.     e->universal_argument = length;
  386.     backward_char(e);
  387.     e->universal_argument = length;
  388.     e->mark = e->dot;
  389.     return delete_char (e);
  390.   }
  391.   if (e->mark > e->dot){
  392.     length = e->mark - e->dot;
  393.     strncpy(e->kill_buffer, e->dot, length);
  394.     e->kill_buffer[length] = '\0';
  395.     e->universal_argument = length;
  396.     e->mark = e->dot;
  397.     return delete_char (e);
  398.   }
  399.   return OK;                        /* JJD 3-89 added */
  400. }
  401.  
  402.  
  403. int strstr(look, lookin) char *look, *lookin;{
  404.     int counter = 0;
  405.     for (counter = 0; (counter < (strlen(lookin) - strlen(look))); counter++){
  406.         if (strncmp(look, &lookin[counter], strlen(look)) == 0)
  407.         return(0);
  408.     }
  409.     return(1);
  410. }
  411.  
  412. /*      
  413. send_message(message)
  414. char *message;
  415. {
  416.      ioctl (0, TIOCGETP, &new_stdin_sgttyb);
  417.      ioctl (0, TIOCSETP, &old_stdin_sgttyb);
  418.      printf ("recvd message:%s\n", message);
  419.      ioctl (0, TIOCSETP, &new_stdin_sgttyb);
  420. }
  421. */
  422.  
  423. ssort (v, n) char *v[]; int n; {  /* JJD: Shell Sort alla p.108 K&R C book */
  424.     int gap, i, j; char *temp;
  425.     for (gap = n/2; gap > 0; gap /= 2)
  426.         for (i= gap; i < n; i++)
  427.             for (j = i-gap; j >= 0; j -= gap) {
  428.                     if (strcmp(v[j], v[j+gap]) <= 0) break;
  429.                 temp = v[j];
  430.                 v[j] = v[j+gap];
  431.                 v[j+gap] = temp;
  432.             }
  433. }
  434.