home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / GNU_ATP_1_40.lzh / EDITLINE / complete.c next >
Text File  |  1993-08-04  |  6KB  |  330 lines

  1. /*  $Revision: 1.3 $
  2. **
  3. **  History and file completion functions for editline library.
  4. */
  5. #include "editline.h"
  6.  
  7. #ifdef __MSDOS__
  8. # ifndef DJD
  9. #  include <stdlib.h>
  10. #  include <dir.h>
  11. #  define FINDFIRST
  12.    STATIC int FindMatches ( char *path , char ***avp );
  13. # else
  14.    STATIC FindMatches(char *dir, char *file, char ***avp) ;
  15. # endif
  16. #else
  17. # ifdef SYS_OS9
  18.    STATIC FindMatches();
  19. # else
  20.    STATIC FindMatches(char *dir, char *file, char ***avp) ;
  21. # endif
  22. #endif
  23.  
  24. #ifdef SYS_OS9
  25.   char  *rl_complete();
  26.   int    rl_list_possible();
  27.   STATIC int SplitPath();
  28. #else
  29.   char *rl_complete ( char *pathname , int *unique );
  30.   int rl_list_possib ( char *pathname , char ***avp );
  31.   STATIC int SplitPath ( char *path , char **dirpart , char **filepart );
  32. #endif
  33.  
  34. #ifdef NEED_STRDUP
  35. /*
  36. **  Return an allocated copy of a string.
  37. */
  38. char *strdup(p)
  39. char *p;
  40. {
  41.     char    *new;
  42.  
  43.     if( ( new = NEW( char, strlen( p ) + 1 ) ) != NULL )
  44.     (void) strcpy( new, p );
  45.     return( new );
  46. }
  47. #endif    /* ifdef NEED_STRDUP */
  48.  
  49. #ifndef SEPCH
  50. #define SEPCH '/'
  51. #endif
  52.  
  53. /*
  54. **  strcmp-like sorting predicate for qsort.
  55. */
  56. STATIC int compare(p1, p2)
  57. void    *p1;
  58. void    *p2;
  59. {
  60.     char **v1;
  61.     char **v2;
  62.  
  63.     v1 = (char **) p1;
  64.     v2 = (char **) p2;
  65.     return( strcmp( *v1, *v2 ) );
  66. }
  67.  
  68. #ifdef FINDFIRST 
  69. STATIC int
  70. FindMatches(path, avp)
  71. char *path;
  72. char ***avp;
  73. {
  74.     char    **av;
  75.     char    **new;
  76.     char    *p;
  77.     SIZE_T    ac;
  78.     int     i=0 ;
  79.     struct ffblk merv ;
  80.  
  81.     av = NULL;
  82.     ac = 0;
  83.     p  = path ;
  84.  
  85.    while(*p) p++, i++ ;  /* find proper wild card to append */
  86.    if( i > 4) 
  87.        i = 4 ;
  88.    if( i==0 )
  89.        i = 1 ;
  90.    else
  91.     p-- ;     
  92.    if( *p != '*')
  93.        strcat(path, "*") ; 
  94.    for( ; i > 0 ; i-- ){
  95.       if( *p == '.' ) 
  96.          i = -1 ;
  97.       else  if ( i == 1 ) 
  98.         strcat(path, ".*") ;
  99.       else
  100.         p-- ;
  101.     }
  102.    if(!findfirst( (char *) path, &merv, 0 )){
  103.     p = merv.ff_name ;
  104.     strlwr(p) ;
  105.     if ((new = NEW(char*, ac + MEM_INC)) == NULL)
  106.         goto myend ;
  107.     *avp = new;
  108.         av = new ;
  109.     if ((av[ac] = strdup(p)) == NULL) {
  110.         DISPOSE(av);
  111.         goto myend ;
  112.     }
  113.     ac++;
  114.     while( !findnext( &merv )){
  115.     p = merv.ff_name ;
  116.     strlwr(p);
  117.     if ((ac % MEM_INC) == 0) { /* allocate bigger array */
  118.         if ((new = NEW(char*, ac + MEM_INC)) == NULL)
  119.         goto myend ;
  120.         if (ac) {
  121.         COPYFROMTO(new, av, ac * sizeof (char **));
  122.         DISPOSE(av);
  123.         }
  124.         *avp = new;
  125.             av = new ;
  126.     }
  127.     if ((av[ac] = strdup(p)) == NULL) 
  128.             goto myend ;
  129.     ac++;
  130.         }
  131.     }
  132. myend:
  133.     if (ac)
  134.     qsort(av, ac, sizeof (char **), compare);
  135.     return ac;
  136. }
  137. #else
  138. /*
  139. **  Fill in *avp with an array of names that match file, up to its length.
  140. **  Ignore . and .. .
  141. */
  142. STATIC FindMatches(dir, file, avp)
  143. char *dir;
  144. char *file;
  145. char ***avp;
  146. {
  147.     char    **av;
  148.     char    **new;
  149.     char    *p;
  150.     DIR        *dp;
  151.     DIRENTRY    *ep;
  152.     SIZE_T    ac;
  153.     SIZE_T    len;
  154.  
  155.     if ((dp = opendir(dir)) == NULL)
  156.     return 0;
  157.  
  158.     av = NULL;
  159.     ac = 0;
  160.     len = strlen(file);
  161.     while ((ep = readdir(dp)) != NULL) {
  162.     p = ep->d_name;
  163.     if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
  164.         continue;
  165.     if (len && strncmp(p, file, len) != 0)
  166.         continue;
  167.  
  168.     if ((ac % MEM_INC) == 0) {
  169.         if ((new = NEW(char*, ac + MEM_INC)) == NULL)
  170.         break;
  171.         if (ac) {
  172.         COPYFROMTO(new, av, ac * sizeof (char **));
  173.         DISPOSE(av);
  174.         }
  175.         *avp = av = new;
  176.     }
  177.  
  178.     if ((av[ac] = strdup(p)) == NULL) {
  179.         if (ac == 0)
  180.         DISPOSE(av);
  181.         break;
  182.     }
  183.     ac++;
  184.     }
  185.  
  186.     /* Clean up and return. */
  187.     (void)closedir(dp);
  188.     if (ac)
  189.     qsort(av, ac, sizeof (char **), compare);
  190.     return ac;
  191. }
  192.  
  193. #endif
  194. /*
  195. **  Split a pathname into allocated directory and trailing filename parts.
  196. */
  197. STATIC int
  198. SplitPath(path, dirpart, filepart)
  199.     char    *path;
  200.     char    **dirpart;
  201.     char    **filepart;
  202. {
  203.     static char    DOT[] = ".";
  204.     char    *dpart;
  205.     char    *fpart;
  206.  
  207.     if ((fpart = strrchr(path, SEPCH )) == NULL) {
  208.     if ((dpart = strdup(DOT)) == NULL)
  209.         return -1;
  210.     if ((fpart = strdup(path)) == NULL) {
  211.         DISPOSE(dpart);
  212.         return -1;
  213.     }
  214.     }
  215.     else {
  216.     if ((dpart = strdup(path)) == NULL)
  217.         return -1;
  218.     dpart[fpart - path] = '\0';
  219.     if ((fpart = strdup(++fpart)) == NULL) {
  220.         DISPOSE(dpart);
  221.         return -1;
  222.     }
  223.     }
  224.     *dirpart = dpart;
  225.     *filepart = fpart;
  226.  return 0;
  227. }
  228.  
  229. /*
  230. **  Attempt to complete the pathname, returning an allocated copy.
  231. **  Fill in *unique if we completed it, or set it to 0 if ambiguous.
  232. */
  233. char *
  234. rl_complete(pathname, unique)
  235.     char    *pathname;
  236.     int        *unique;
  237. {
  238.     char    **av;
  239.     char    *dir;
  240.     char    *file;
  241.     char    *new;
  242.     char    *p;
  243.     SIZE_T    ac;
  244.     SIZE_T    end;
  245.     SIZE_T    i;
  246.     SIZE_T    j;
  247.     SIZE_T    len;
  248.  
  249.     if (SplitPath(pathname, &dir, &file) < 0)
  250.     return NULL;
  251. #ifndef FINDFIRST
  252.     if ((ac = FindMatches(dir, file, &av)) == 0) 
  253. #else
  254.     if ((ac = FindMatches(pathname, &av)) == 0 ) 
  255. #endif
  256.     {
  257.     DISPOSE(dir);
  258.     DISPOSE(file);
  259.     return NULL;
  260.     }
  261.     
  262.     p = NULL;
  263.     len = strlen(file);
  264.     if (ac == 1) {
  265.     /* Exactly one match -- finish it off. */
  266.     *unique = 1;
  267.     j = strlen(av[0]) - len + 2;
  268.     if ((p = NEW(char, j + 1)) != NULL) {
  269.         COPYFROMTO(p, av[0] + len, j);
  270.         if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
  271.         (void)strcpy(new, dir);
  272.         (void)strcat(new, "/");
  273.         (void)strcat(new, av[0]);
  274.         rl_add_slash(new, p);
  275.         DISPOSE(new);
  276.         }
  277.     }
  278.     }
  279.     else {
  280.     *unique = 0;
  281.     if (len) {
  282.         /* Find largest matching substring. */
  283.         for (i = len, end = strlen(av[0]); i < end; i++)
  284.         for (j = 1; j < ac; j++)
  285.             if (av[0][i] != av[j][i])
  286.             goto breakout;
  287.   breakout:
  288.         if (i > len) {
  289.         j = i - len + 1;
  290.         if ((p = NEW(char, j)) != NULL) {
  291.             COPYFROMTO(p, av[0] + len, j);
  292.             p[j - 1] = '\0';
  293.         }
  294.         }
  295.     }
  296.     }
  297.  
  298.     /* Clean up and return. */
  299.     DISPOSE(dir);
  300.     DISPOSE(file);
  301.     for (i = 0; i < ac; i++)
  302.     DISPOSE(av[i]);
  303.     DISPOSE(av);
  304.     return p;
  305. }
  306.  
  307. /*
  308. **  Return all possible completions.
  309. */
  310. int
  311. rl_list_possib(pathname, avp)
  312. char *pathname;
  313. char ***avp;
  314. {
  315.     int        ac;
  316. #ifndef FINDFIRST
  317.     char    *dir;
  318.     char    *file;
  319.  
  320.     if (SplitPath(pathname, &dir, &file) < 0)
  321.     return 0;
  322.     ac = FindMatches(dir, file, avp);
  323.     DISPOSE(dir);
  324.     DISPOSE(file);
  325. #else
  326.     ac = FindMatches(pathname, avp);
  327. #endif
  328.     return ac;
  329. }
  330.