Provided by: libtecla-dev_1.6.3-2.1build1_amd64 bug


       pca_lookup_file,    del_PathCache,    del_PcaPathConf,   new_PathCache,   new_PcaPathConf,
       pca_last_error,  pca_path_completions,  pca_scan_path,  pca_set_check_fn,  ppc_file_start,
       ppc_literal_escapes - lookup a file in a list of directories


       #include <libtecla.h>

       PathCache *new_PathCache(void);

       PathCache *del_PathCache(PathCache *pc);

       int pca_scan_path(PathCache *pc, const char *path);

       void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn,
                             void *data);

       char *pca_lookup_file(PathCache *pc, const char *name,
                             int name_len, int literal);

       const char *pca_last_error(PathCache *pc);



       The PathCache object is part of the tecla library (see the libtecla(3) man page).

       PathCache  objects allow an application to search for files in any colon separated list of
       directories, such as the unix execution  PATH  environment  variable.  Files  in  absolute
       directories  are cached in a PathCache object, whereas relative directories are scanned as
       needed. Using a PathCache object, you can look up the full pathname of a simple  filename,
       or  you  can  obtain  a  list  of  the possible completions of a given filename prefix. By
       default all files in the list of directories are targets for lookup and completion, but  a
       versatile  mechanism  is  provided for only selecting specific types of files. The obvious
       application of this facility  is  to  provide  Tab-completion  and  lookup  of  executable
       commands in the unix PATH, so an optional callback which rejects all but executable files,
       is provided.


       Under UNIX, the following example program looks up and displays the full pathnames of each
       of the command names on the command line.

         #include <stdio.h>
         #include <stdlib.h>
         #include <libtecla.h>

         int main(int argc, char *argv[])
           int i;
          * Create a cache for executable files.
           PathCache *pc = new_PathCache();
          * Scan the user's PATH for executables.
           if(pca_scan_path(pc, getenv("PATH"))) {
             fprintf(stderr, "%s\n", pca_last_error(pc));
          * Arrange to only report executable files.
          pca_set_check_fn(pc, cpl_check_exe, NULL);
          * Lookup and display the full pathname of each of the
          * commands listed on the command line.
           for(i=1; i<argc; i++) {
             char *cmd = pca_lookup_file(pc, argv[i], -1, 0);
             printf("The full pathname of '%s' is %s\n", argv[i],
                    cmd ? cmd : "unknown");
           pc = del_PathCache(pc);  /* Clean up */
           return 0;

       The following is an example of what this does on my laptop under linux:

         $ ./example less more blob
         The full pathname of 'less' is /usr/bin/less
         The full pathname of 'more' is /bin/more
         The full pathname of 'blob' is unknown


       In  order to use the facilities of this module, you must first allocate a PathCache object
       by calling the new_PathCache() constructor function.

         PathCache *new_PathCache(void)

       This function creates the resources needed  to  cache  and  lookup  files  in  a  list  of
       directories. It returns NULL on error.


       Once  you have created a cache, it needs to be populated with files.  To do this, call the
       pca_scan_path() function.

         int pca_scan_path(PathCache *pc, const char *path);

       Whenever this function is called, it discards the current  contents  of  the  cache,  then
       scans  the list of directories specified in its path argument for files. The path argument
       must  be  a  string  containing  a  colon-separated   list   of   directories,   such   as
       "/usr/bin:/home/mcs/bin:.".  This  can include directories specified by absolute pathnames
       such as "/usr/bin", as well as sub-directories specified by relative pathnames such as "."
       or  "bin".  Files  in  the  absolute  directories  are immediately cached in the specified
       PathCache object, whereas sub-directories, whose identities obviously change whenever  the
       current  working directory is changed, are marked to be scanned on the fly whenever a file
       is looked up.

       On success this function return 0. On error it returns 1, and a description of  the  error
       can be obtained by calling pca_last_error(pc).


       Once the cache has been populated with files, you can look up the full pathname of a file,
       simply by specifying its filename to pca_lookup_file().

         char *pca_lookup_file(PathCache *pc, const char *name,
                               int name_len, int literal);

       To make it possible to pass this function a filename which is actually part  of  a  longer
       string,  the  name_len  argument  can be used to specify the length of the filename at the
       start of the name[] argument. If you pass -1 for this length, the  length  of  the  string
       will  be  determined  with  strlen().  If the name[] string might contain backslashes that
       escape the special meanings of spaces and tabs  within  the  filename,  give  the  literal
       argument,  the  value 0. Otherwise, if backslashes should be treated as normal characters,
       pass 1 for the value of the literal argument.


       Looking up the potential completions of  a  filename-prefix  in  the  filename  cache,  is
       achieved   by  passing  the  provided  pca_path_completions()  callback  function  to  the
       cpl_complete_word() function (see the cpl_complete_word(3) man page).


       This callback requires that its data argument  be  a  pointer  to  a  PcaPathConf  object.
       Configuration objects of this type are allocated by calling new_PcaPathConf().

         PcaPathConf *new_PcaPathConf(PathCache *pc);

       This  function  returns an object initialized with default configuration parameters, which
       determine how the cpl_path_completions() callback function behaves.  The  functions  which
       allow you to individually change these parameters are discussed below.

       By  default, the pca_path_completions() callback function searches backwards for the start
       of the filename being completed, looking for the first un-escaped space or  the  start  of
       the  input  line.  If you wish to specify a different location, call ppc_file_start() with
       the index at which the filename starts in  the  input  line.  Passing  start_index=-1  re-
       enables the default behavior.

         void ppc_file_start(PcaPathConf *ppc, int start_index);

       By  default,  when pca_path_completions() looks at a filename in the input line, each lone
       backslash in the input line is interpreted as being a special character which removes  any
       special  significance  of  the character which follows it, such as a space which should be
       taken as part of the filename rather than delimiting the  start  of  the  filename.  These
       backslashes  are thus ignored while looking for completions, and subsequently added before
       spaces, tabs and literal backslashes  in  the  list  of  completions.  To  have  unescaped
       backslashes treated as normal characters, call ppc_literal_escapes() with a non-zero value
       in its literal argument.

         void ppc_literal_escapes(PcaPathConf *ppc, int literal);

       When  you  have  finished  with  a  PcaPathConf  variable,  you  can  pass   it   to   the
       del_PcaPathConf() destructor function to reclaim its memory.

         PcaPathConf *del_PcaPathConf(PcaPathConf *ppc);


       If  you  are  only  interested in certain types or files, such as, for example, executable
       files, or files whose names end in a particular suffix,  you  can  arrange  for  the  file
       completion  and  lookup functions to be selective in the filenames that they return.  This
       is done by registering  a  callback  function  with  your  PathCache  object.  Thereafter,
       whenever a filename is found which either matches a filename being looked up, or matches a
       prefix which is being completed, your callback function  will  be  called  with  the  full
       pathname  of  the  file,  plus  any application-specific data that you provide, and if the
       callback returns 1 the filename will be reported as a match, and if it returns 0, it  will
       be  ignored.  Suitable callback functions and their prototypes should be declared with the
       following macro. The CplCheckFn typedef is also provided  in  case  you  wish  to  declare
       pointers to such functions.

         #define CPL_CHECK_FN(fn) int (fn)(void *data, \
                                           const char *pathname)
         typedef CPL_CHECK_FN(CplCheckFn);

       Registering  one  of  these functions involves calling the pca_set_check_fn() function. In
       addition to the callback function, passed via  the  check_fn  argument,  you  can  pass  a
       pointer to anything via the data argument. This pointer will be passed on to your callback
       function, via its own data argument, whenever it is called, so this provides a way to pass
       appplication specific data to your callback.

         void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn,
                               void *data);

       Note  that  these  callbacks  are  passed  the full pathname of each matching file, so the
       decision about whether a file is of interest can be based on any property of the file, not
       just  its filename. As an example, the provided cpl_check_exe() callback function looks at
       the executable permissions of the file and the permissions of its parent directories,  and
       only  returns 1 if the user has execute permission to the file. This callback function can
       thus be used to lookup or complete command names found in the directories  listed  in  the
       user's  PATH  environment  variable.  The  example  program given earlier in this man page
       provides a demonstration of this.

       Beware that if somebody tries to complete an empty string, your callback will  get  called
       once  for  every  file in the cache, which could number in the thousands. If your callback
       does anything time consuming, this could result in an unacceptable delay for the user,  so
       callbacks should be kept short.

       To  improve  performance,  whenever  one  of these callbacks is called, the choice that it
       makes is cached, and the next time the corresponding file is looked up, instead of calling
       the callback again, the cached record of whether it was accepted or rejected is used. Thus
       if somebody tries to complete an empty string, and hits tab a  second  time  when  nothing
       appears  to  happen, there will only be one long delay, since the second pass will operate
       entirely from the cached dispositions of the files. These cached dipositions are discarded
       whenever pca_scan_path() is called, and whenever pca_set_check_fn() is called with changed
       callback function or data arguments.


       If pca_scan_path() reports that an error occurred by returning 1, you can obtain  a  terse
       description  of  the  error by calling pca_last_error(pc). This returns an internal string
       containing an error message.

         const char *pca_last_error(PathCache *pc);


       Once you have finished using a PathCache object, you can reclaim its resources by  passing
       it  to  the  del_PathCache()  destructor  function.  This  takes a pointer to one of these
       objects, and always returns NULL.

         PathCache *del_PathCache(PathCache *pc);


       In multi-threaded programs, you should use the libtecla_r.a version of the  library.  This
       uses  POSIX  reentrant  functions  where  available  (hence  the  _r suffix), and disables
       features that rely on non-reentrant system functions. In the case of this module, the only
       disabled    feature    is    username    completion    in   ~username/   expressions,   in

       Using the libtecla_r.a version of the library, it is safe to use the  facilities  of  this
       module  in  multiple  threads,  provided  that  each  thread  uses  a separately allocated
       PathCache object. In other words, if two threads want to do path  searching,  they  should
       each call new_PathCache() to allocate their own caches.


       libtecla.a    -    The tecla library
       libtecla.h    -    The tecla header file.


       libtecla(3), gl_get_line(3), ef_expand_file(3),


       Martin Shepherd  (