diff options
Diffstat (limited to 'libtecla-1.4.1/demo2.c')
-rw-r--r-- | libtecla-1.4.1/demo2.c | 352 |
1 files changed, 0 insertions, 352 deletions
diff --git a/libtecla-1.4.1/demo2.c b/libtecla-1.4.1/demo2.c deleted file mode 100644 index e1e80c6..0000000 --- a/libtecla-1.4.1/demo2.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2000, 2001 by Martin C. Shepherd. - * - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons - * to whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL - * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * of the copyright holder. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <errno.h> -#include <locale.h> - -#include <unistd.h> -#include <sys/stat.h> - -#include "libtecla.h" - -/* - * Encapsulate the resources needed by this demo. - */ -typedef struct { - GetLine *gl; /* The line editor */ - PathCache *pc; /* A cache of executables in the user's path */ - PcaPathConf *ppc; /* The configuration argument of pca_path_completions() */ -} DemoRes; - -/* - * The following functions allocate and free instances of the above - * structure. - */ -static DemoRes *new_DemoRes(void); -static DemoRes *del_DemoRes(DemoRes *res); - -/* - * Search backwards for the start of a pathname. - */ -static char *start_of_path(const char *string, int back_from); - -/* - * Find the array indexes of the first character of the first - * space-delimited word in the specified string, and of the character - * that follows it. - */ -static int get_word_limits(const char *string, int *wa, int *wb); - -/* - * This is the demonstration completion callback function (defined below). - */ -static CPL_MATCH_FN(demo_cpl_fn); - -/*....................................................................... - * This demo takes no arguments. It reads lines of input until the - * word 'exit' is entered, or C-d is pressed. It replaces the default - * tab-completion callback with one which when invoked at the start of - * a line, looks up completions of commands in the user's execution - * path, and when invoked in other parts of the line, reverts to - * normal filename completion. Whenever a new line is entered, it - * extracts the first word on the line, looks it up in the user's - * execution path to see if it corresponds to a known executable file, - * and if so, displays the full pathname of the file, along with the - * remaining arguments. - */ -int main(int argc, char *argv[]) -{ - char *line; /* A line of input */ - DemoRes *res; /* The resources of the demo */ - int wa,wb; /* The delimiting indexes of a word in line[] */ - int major,minor,micro; /* The version number of the library */ -/* - * Allocate the resources needed by this demo. - */ - res = new_DemoRes(); - if(!res) - return 1; -/* - * If the user has the LC_CTYPE or LC_ALL environment variables set, - * enable display of characters corresponding to the specified locale. - */ - (void) setlocale(LC_CTYPE, ""); -/* - * Lookup and display the version number of the library. - */ - libtecla_version(&major, &minor, µ); - printf("Welcome to the demo2 program of libtecla version %d.%d.%d\n", - major, minor, micro); -/* - * Read lines of input from the user and print them to stdout. - */ - do { -/* - * Get a new line from the user. - */ - line = gl_get_line(res->gl, "$ ", NULL, 0); - if(!line) - break; -/* - * Work out the extent of the first word in the input line, and - * try to identify this as a command in the path, displaying the - * full pathname of the match if found. - */ - if(get_word_limits(line, &wa, &wb) == 0) { - char *cmd = pca_lookup_file(res->pc, line + wa, wb-wa, 0); - if(cmd) { - printf("Command=%s\n", cmd); - printf("Arguments=%s", line+wb); - } else { - printf("Command not found\n"); - }; - }; -/* - * If the user types "exit", quit the program. - */ - if(strcmp(line, "exit\n")==0) - break; - } while(1); -/* - * Clean up. - */ - res = del_DemoRes(res); - return 0; -} - -/*....................................................................... - * This completion callback searches for completions of executables in - * the user's path when invoked on a word at the start of the path, and - * performs normal filename completion elsewhere. - */ -static CPL_MATCH_FN(demo_cpl_fn) -{ -/* - * Get the resource object that was passed to gl_customize_completion(). - */ - DemoRes *res = (DemoRes *) data; -/* - * Find the start of the filename prefix to be completed, searching - * backwards for the first unescaped space, or the start of the line. - */ - char *start = start_of_path(line, word_end); -/* - * Skip spaces preceding the start of the prefix. - */ - while(start > line && isspace((int)(unsigned char) start[-1])) - start--; -/* - * If the filename prefix is at the start of the line, attempt - * to complete the filename as a command in the path. Otherwise - * perform normal filename completion. - */ - return (start == line) ? - pca_path_completions(cpl, res->ppc, line, word_end) : - cpl_file_completions(cpl, NULL, line, word_end); -} - -/*....................................................................... - * Search backwards for the potential start of a filename. This - * looks backwards from the specified index in a given string, - * stopping at the first unescaped space or the start of the line. - * - * Input: - * string const char * The string to search backwards in. - * back_from int The index of the first character in string[] - * that follows the pathname. - * Output: - * return char * The pointer to the first character of - * the potential pathname, or NULL on error. - */ -static char *start_of_path(const char *string, int back_from) -{ - int i, j; -/* - * Search backwards from the specified index. - */ - for(i=back_from-1; i>=0; i--) { - int c = string[i]; -/* - * Stop on unescaped spaces. - */ - if(isspace((int)(unsigned char)c)) { -/* - * The space can't be escaped if we are at the start of the line. - */ - if(i==0) - break; -/* - * Find the extent of the escape characters which precedes the space. - */ - for(j=i-1; j>=0 && string[j]=='\\'; j--) - ; -/* - * If there isn't an odd number of escape characters before the space, - * then the space isn't escaped. - */ - if((i - 1 - j) % 2 == 0) - break; - }; - }; - return (char *)string + i + 1; -} - -/*....................................................................... - * Create a new DemoRes object containing the resources needed by the - * demo. - * - * Output: - * return DemoRes * The new object, or NULL on error. - */ -static DemoRes *new_DemoRes(void) -{ - DemoRes *res; /* The object to be returned */ -/* - * Allocate the container. - */ - res = (DemoRes *)malloc(sizeof(DemoRes)); - if(!res) { - fprintf(stderr, "new_DemoRes: Insufficient memory.\n"); - return NULL; - }; -/* - * Before attempting any operation that might fail, initialize the - * container at least up to the point at which it can safely be passed - * to del_DemoRes(). - */ - res->gl = NULL; - res->pc = NULL; - res->ppc = NULL; -/* - * Create the line editor, specifying a max line length of 500 bytes, - * and 10000 bytes to allocate to storage of historical input lines. - */ - res->gl = new_GetLine(500, 10000); - if(!res->gl) - return del_DemoRes(res); -/* - * Enable text attribute formatting directives in prompt strings. - */ - gl_prompt_style(res->gl, GL_FORMAT_PROMPT); -/* - * Allocate a cache of the executable files found in the user's path. - */ - res->pc = new_PathCache(); - if(!res->pc) - return del_DemoRes(res); -/* - * Populate the cache with the contents of the user's path. - */ - if(pca_scan_path(res->pc, getenv("PATH"))) - return del_DemoRes(res); -/* - * Arrange for susequent calls to pca_lookup_file() and pca_path_completions() - * to only report files that are executable by the user. - */ - pca_set_check_fn(res->pc, cpl_check_exe, NULL); -/* - * Allocate a configuration object for use with pca_path_completions(). - */ - res->ppc = new_PcaPathConf(res->pc); - if(!res->ppc) - return del_DemoRes(res); -/* - * Replace the builtin filename completion callback with one which - * searches for completions of executables in the user's path when - * invoked on a word at the start of the path, and completes files - * elsewhere. - */ - if(gl_customize_completion(res->gl, res, demo_cpl_fn)) - return del_DemoRes(res); - return res; -} - -/*....................................................................... - * Delete a DemoRes object. - * - * Input: - * res DemoRes * The object to be deleted. - * Output: - * return DemoRes * The deleted object (always NULL). - */ -static DemoRes *del_DemoRes(DemoRes *res) -{ - if(res) { - res->gl = del_GetLine(res->gl); - res->pc = del_PathCache(res->pc); - res->ppc = del_PcaPathConf(res->ppc); - free(res); - }; - return NULL; -} - -/*....................................................................... - * Return the limits of the word at the start of a given string, ignoring - * leading white-space, and interpretting the first unescaped space, tab or - * the end of the line, as the end of the word. - * - * Input: - * string const char * The string to tokenize. - * Input/Output: - * wa,wb int * The indexes of the first character of the word, - * and the character which follows the last - * character of the word, will be assigned to - * *wa and *wb, respectively. - * Output: - * return int 0 - A word was found. - * 1 - No word was found before the end of the - * string. - */ -static int get_word_limits(const char *string, int *wa, int *wb) -{ - int escaped = 0; /* True if the next character is escaped */ -/* - * Skip leading white-space. - */ - for(*wa=0; isspace((int)(unsigned char)string[*wa]); (*wa)++) - ; -/* - * Find the first unescaped space, stopping early if the end of the - * string is reached. - */ - for(*wb = *wa; ; (*wb)++) { - int c = string[*wb]; - if(c=='\\') - escaped = !escaped; - else if((!escaped && isspace((int)(unsigned char)c)) || c=='\0') - break; - }; - return *wa == *wb; -} |