1 PCA_LOOKUP_FILE(3TECLA) Interactive Command-line Input Library Functions 2 3 4 5 NAME 6 pca_lookup_file, del_PathCache, del_PcaPathConf, new_PathCache, 7 new_PcaPathConf, pca_last_error, pca_path_completions, pca_scan_path, 8 pca_set_check_fn, ppc_file_start, ppc_literal_escapes - lookup a file 9 in a list of directories 10 11 SYNOPSIS 12 cc [ flag... ] file... -ltecla [ library... ] 13 #include <libtecla.h> 14 15 char *pca_lookup_file(PathCache *pc, const char *name, 16 int name_len, int literal); 17 18 19 PathCache *del_PathCache(PathCache *pc); 20 21 22 PcaPathConf *del_PcaPathConf(PcaPathConf *ppc); 23 24 25 PathCache *new_PathCache(void); 26 27 28 PcaPathConf *new_PcaPathConf(PathCache *pc); 29 30 31 const char *pca_last_error(PathCache *pc); 32 33 34 CPL_MATCH_FN(pca_path_completions); 35 36 37 int pca_scan_path(PathCache *pc, const char *path); 38 39 40 void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn, 41 void *data); 42 43 44 void ppc_file_start(PcaPathConf *ppc, int start_index); 45 46 47 void ppc_literal_escapes(PcaPathConf *ppc, int literal); 48 49 50 DESCRIPTION 51 The PathCache object is part of the libtecla(3LIB) library. PathCache 52 objects allow an application to search for files in any colon separated 53 list of directories, such as the UNIX execution PATH environment 54 variable. Files in absolute directories are cached in a PathCache 55 object, whereas relative directories are scanned as needed. Using a 56 PathCache object, you can look up the full pathname of a simple 57 filename, or you can obtain a list of the possible completions of a 58 given filename prefix. By default all files in the list of directories 59 are targets for lookup and completion, but a versatile mechanism is 60 provided for only selecting specific types of files. The obvious 61 application of this facility is to provide Tab-completion and lookup of 62 executable commands in the UNIX PATH, so an optional callback which 63 rejects all but executable files is provided. 64 65 An Example 66 Under UNIX, the following example program looks up and displays the 67 full pathnames of each of the command names on the command line. 68 69 #include <stdio.h> 70 #include <stdlib.h> 71 #include <libtecla.h> 72 73 int main(int argc, char *argv[]) 74 { 75 int i; 76 /* 77 * Create a cache for executable files. 78 */ 79 PathCache *pc = new_PathCache(); 80 if(!pc) 81 exit(1); 82 /* 83 * Scan the user's PATH for executables. 84 */ 85 if(pca_scan_path(pc, getenv("PATH"))) { 86 fprintf(stderr, "%s\n", pca_last_error(pc)); 87 exit(1); 88 } 89 /* 90 * Arrange to only report executable files. 91 */ 92 pca_set_check_fn(pc, cpl_check_exe, NULL); 93 /* 94 * Lookup and display the full pathname of each of the 95 * commands listed on the command line. 96 */ 97 for(i=1; i<argc; i++) { 98 char *cmd = pca_lookup_file(pc, argv[i], -1, 0); 99 printf("The full pathname of '%s' is %s\\n", argv[i], 100 cmd ? cmd : "unknown"); 101 } 102 pc = del_PathCache(pc); /* Clean up */ 103 return 0; 104 } 105 106 107 108 The following is an example of what this does on a laptop under LINUX: 109 110 $ ./example less more blob 111 The full pathname of 'less' is /usr/bin/less 112 The full pathname of 'more' is /bin/more 113 The full pathname of 'blob' is unknown 114 $ 115 116 117 Function Descriptions 118 To use the facilities of this module, you must first allocate a 119 PathCache object by calling the new_PathCache() constructor function. 120 This function creates the resources needed to cache and lookup files in 121 a list of directories. It returns NULL on error. 122 123 Populating The Cache 124 Once you have created a cache, it needs to be populated with files. To 125 do this, call the pca_scan_path() function. Whenever this function is 126 called, it discards the current contents of the cache, then scans the 127 list of directories specified in its path argument for files. The path 128 argument must be a string containing a colon-separated list of 129 directories, such as "/usr/bin:/home/mcs/bin:". This can include 130 directories specified by absolute pathnames such as "/usr/bin", as well 131 as sub-directories specified by relative pathnames such as "." or 132 "bin". Files in the absolute directories are immediately cached in the 133 specified PathCache object, whereas subdirectories, whose identities 134 obviously change whenever the current working directory is changed, are 135 marked to be scanned on the fly whenever a file is looked up. 136 137 138 On success this function return 0. On error it returns 1, and a 139 description of the error can be obtained by calling pca_last_error(pc). 140 141 Looking Up Files 142 Once the cache has been populated with files, you can look up the full 143 pathname of a file, simply by specifying its filename to 144 pca_lookup_file(). 145 146 147 To make it possible to pass this function a filename which is actually 148 part of a longer string, the name_len argument can be used to specify 149 the length of the filename at the start of the name[] argument. If you 150 pass -1 for this length, the length of the string will be determined 151 with strlen. If the name[] string might contain backslashes that escape 152 the special meanings of spaces and tabs within the filename, give the 153 literal argument the value 0. Otherwise, if backslashes should be 154 treated as normal characters, pass 1 for the value of the literal 155 argument. 156 157 Filename Completion 158 Looking up the potential completions of a filename-prefix in the 159 filename cache is achieved by passing the provided 160 pca_path_completions() callback function to the 161 cpl_complete_word(3TECLA) function. 162 163 164 This callback requires that its data argument be a pointer to a 165 PcaPathConf object. Configuration objects of this type are allocated by 166 calling new_PcaPathConf(). 167 168 169 This function returns an object initialized with default configuration 170 parameters, which determine how the cpl_path_completions() callback 171 function behaves. The functions which allow you to individually change 172 these parameters are discussed below. 173 174 175 By default, the pca_path_completions() callback function searches 176 backwards for the start of the filename being completed, looking for 177 the first un-escaped space or the start of the input line. If you wish 178 to specify a different location, call ppc_file_start() with the index 179 at which the filename starts in the input line. Passing start_index=-1 180 re-enables the default behavior. 181 182 183 By default, when pca_path_completions() looks at a filename in the 184 input line, each lone backslash in the input line is interpreted as 185 being a special character which removes any special significance of the 186 character which follows it, such as a space which should be taken as 187 part of the filename rather than delimiting the start of the filename. 188 These backslashes are thus ignored while looking for completions, and 189 subsequently added before spaces, tabs and literal backslashes in the 190 list of completions. To have unescaped backslashes treated as normal 191 characters, call ppc_literal_escapes() with a non-zero value in its 192 literal argument. 193 194 195 When you have finished with a PcaPathConf variable, you can pass it to 196 the del_PcaPathConf() destructor function to reclaim its memory. 197 198 Being Selective 199 If you are only interested in certain types or files, such as, for 200 example, executable files, or files whose names end in a particular 201 suffix, you can arrange for the file completion and lookup functions to 202 be selective in the filenames that they return. This is done by 203 registering a callback function with your PathCache object. Thereafter, 204 whenever a filename is found which either matches a filename being 205 looked up or matches a prefix which is being completed, your callback 206 function will be called with the full pathname of the file, plus any 207 application-specific data that you provide. If the callback returns 1 208 the filename will be reported as a match. If it returns 0, it will be 209 ignored. Suitable callback functions and their prototypes should be 210 declared with the following macro. The CplCheckFn typedef is also 211 provided in case you wish to declare pointers to such functions. 212 213 #define CPL_CHECK_FN(fn) int (fn)(void *data, const char *pathname) 214 typedef CPL_CHECK_FN(CplCheckFn); 215 216 217 218 Registering one of these functions involves calling the 219 pca_set_check_fn() function. In addition to the callback function 220 passed with the check_fn argument, you can pass a pointer to anything 221 with the data argument. This pointer will be passed on to your callback 222 function by its own data argument whenever it is called, providing a 223 way to pass application-specific data to your callback. Note that these 224 callbacks are passed the full pathname of each matching file, so the 225 decision about whether a file is of interest can be based on any 226 property of the file, not just its filename. As an example, the 227 provided cpl_check_exe() callback function looks at the executable 228 permissions of the file and the permissions of its parent directories, 229 and only returns 1 if the user has execute permission to the file. This 230 callback function can thus be used to lookup or complete command names 231 found in the directories listed in the user's PATH environment 232 variable. The example program above provides a demonstration of this. 233 234 235 Beware that if somebody tries to complete an empty string, your 236 callback will get called once for every file in the cache, which could 237 number in the thousands. If your callback does anything time consuming, 238 this could result in an unacceptable delay for the user, so callbacks 239 should be kept short. 240 241 242 To improve performance, whenever one of these callbacks is called, the 243 choice that it makes is cached, and the next time the corresponding 244 file is looked up, instead of calling the callback again, the cached 245 record of whether it was accepted or rejected is used. Thus if somebody 246 tries to complete an empty string, and hits tab a second time when 247 nothing appears to happen, there will only be one long delay, since the 248 second pass will operate entirely from the cached dispositions of the 249 files. These cached dispositions are discarded whenever pca_scan_path() 250 is called, and whenever pca_set_check_fn() is called with changed 251 callback function or data arguments. 252 253 Error Handling 254 If pca_scan_path() reports that an error occurred by returning 1, you 255 can obtain a terse description of the error by calling 256 pca_last_error(pc). This returns an internal string containing an error 257 message. 258 259 Cleaning Up 260 Once you have finished using a PathCache object, you can reclaim its 261 resources by passing it to the del_PathCache() destructor function. 262 This takes a pointer to one of these objects, and always returns NULL. 263 264 Thread Safety 265 It is safe to use the facilities of this module in multiple threads, 266 provided that each thread uses a separately allocated PathCache object. 267 In other words, if two threads want to do path searching, they should 268 each call new_PathCache() to allocate their own caches. 269 270 ATTRIBUTES 271 See attributes(5) for descriptions of the following attributes: 272 273 274 275 276 +--------------------+-----------------+ 277 | ATTRIBUTE TYPE | ATTRIBUTE VALUE | 278 +--------------------+-----------------+ 279 |Interface Stability | Evolving | 280 +--------------------+-----------------+ 281 |MT-Level | MT-Safe | 282 +--------------------+-----------------+ 283 284 SEE ALSO 285 cpl_complete_word(3TECLA), ef_expand_file(3TECLA), gl_get_line(3TECLA), 286 libtecla(3LIB), attributes(5) 287 288 289 290 January 18, 2020 PCA_LOOKUP_FILE(3TECLA)