text: #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); CPL_MATCH_FN(pca_path_completions);
  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(); if(!pc) exit(1); /* * Scan the user's PATH for executables. */ if(pca_scan_path(pc, getenv("PATH"))) { fprintf(stderr, "%s\n", pca_last_error(pc)); exit(1); } /* * 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.
  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).
  CPL_MATCH_FN(pca_path_completions);
  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 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);
  #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);_path_completions().
  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), cpl_complete_word(3)