diff options
Diffstat (limited to 'libtecla-1.6.3/man')
80 files changed, 5391 insertions, 0 deletions
diff --git a/libtecla-1.6.3/man/file/teclarc.in b/libtecla-1.6.3/man/file/teclarc.in new file mode 100644 index 0000000..b5ee705 --- /dev/null +++ b/libtecla-1.6.3/man/file/teclarc.in @@ -0,0 +1 @@ +.so @MISC_MANDIR@/tecla.@MISC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cfc_file_start.in b/libtecla-1.6.3/man/func/cfc_file_start.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cfc_file_start.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cfc_literal_escapes.in b/libtecla-1.6.3/man/func/cfc_literal_escapes.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cfc_literal_escapes.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cfc_set_check_fn.in b/libtecla-1.6.3/man/func/cfc_set_check_fn.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cfc_set_check_fn.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_add_completion.in b/libtecla-1.6.3/man/func/cpl_add_completion.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_add_completion.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_complete_word.in b/libtecla-1.6.3/man/func/cpl_complete_word.in new file mode 100644 index 0000000..2479657 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_complete_word.in @@ -0,0 +1,441 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH cpl_complete_word @FUNC_MANEXT@ +.SH NAME +cpl_complete_word, cfc_file_start, cfc_literal_escapes, cfc_set_check_fn, cpl_add_completion, cpl_file_completions, cpl_last_error, cpl_list_completions, cpl_recall_matches, cpl_record_error, del_CplFileConf, del_WordCompletion, new_CplFileConf, new_WordCompletion \- lookup possible completions for a word +.SH SYNOPSIS +.nf +#include <stdio.h> +#include <libtecla.h> + +WordCompletion *new_WordCompletion(void); + +WordCompletion *del_WordCompletion(WordCompletion *cpl); + + +#define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \\ + void *data, \\ + const char *line, \\ + int word_end) +typedef CPL_MATCH_FN(CplMatchFn); + +CPL_MATCH_FN(cpl_file_completions); + + +CplMatches *cpl_complete_word(WordCompletion *cpl, + const char *line, + int word_end, void *data, + CplMatchFn *match_fn); + +CplMatches *cpl_recall_matches(WordCompletion *cpl); + +int cpl_list_completions(CplMatches *result, FILE *fp, + int term_width); + +int cpl_add_completion(WordCompletion *cpl, + const char *line, int word_start, + int word_end, const char *suffix, + const char *type_suffix, + const char *cont_suffix); + +void cpl_record_error(WordCompletion *cpl, + const char *errmsg); + +const char *cpl_last_error(WordCompletion *cpl); + + +#define CPL_CHECK_FN(fn) int (fn)(void *data, \\ + const char *pathname) + +typedef CPL_CHECK_FN(CplCheckFn); + +CPL_CHECK_FN(cpl_check_exe); + +CplFileConf *new_CplFileConf(void); + +CplFileConf *del_CplFileConf(CplFileConf *cfc); + +void cfc_literal_escapes(CplFileConf *cfc, int literal); + +void cfc_file_start(CplFileConf *cfc, int start_index); + +void cfc_set_check_fn(CplFileConf *cfc, CplCheckFn *chk_fn, + void *chk_data); + +.fi + +.SH DESCRIPTION + +The \f3cpl_complete_word()\f1 function is part of the tecla library +(see the libtecla(@LIBR_MANEXT@) man page). It is usually called behind the scenes +by \f3gl_get_line(@FUNC_MANEXT@)\f1, but can also be called separately. + +Given an input line containing an incomplete word to be completed, it +calls a user-provided callback function (or the provided +file-completion callback function) to look up all possible completion +suffixes for that word. The callback function is expected to look +backward in the line, starting from the specified cursor position, to +find the start of the word to be completed, then to look up all +possible completions of that word and record them, one at a time by +calling \f3cpl_add_completion()\f1. + +.sp +Descriptions of the functions of this module are as follows: +.sp +.nf + WordCompletion *new_WordCompletion(void) +.fi +.sp +This function creates the resources used by the \f3cpl_complete_word()\f1 +function. In particular, it maintains the memory that is used to +return the results of calling \f3cpl_complete_word()\f1. +.sp +.nf + WordCompletion *del_WordCompletion(WordCompletion *cpl) +.fi +.sp +This function deletes the resources that were returned by a previous +call to \f3new_WordCompletion()\f1. It always returns \f3NULL\f1 (ie. a +deleted object). It does nothing if the \f3cpl\f1 argument is +\f3NULL\f1. +.sp +The callback functions which lookup possible completions should be +defined with the following macro (which is defined in libtecla.h). +.sp +.nf + #define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \\ + void *data, \\ + const char *line, \\ + int word_end) +.fi +.sp +Functions of this type are called by \f3cpl_complete_word()\f1, and +all of the arguments of the callback are those that were passed to +said function. In particular, the \f3line\f1 argument contains the +input line containing the word to be completed, and \f3word_end\f1 is +the index of the character that follows the last character of the +incomplete word within this string. The callback is expected to look +backwards from \f3word_end\f1 for the start of the incomplete +word. What constitutes the start of a word clearly depends on the +application, so it makes sense for the callback to take on this +responsibility. For example, the builtin filename completion function +looks backwards until it hits an unescaped space, or the start of the +line. Having found the start of the word, the callback should then +lookup all possible completions of this word, and record each +completion via separate calls to \f3cpl_add_completion()\f1. If the +callback needs access to an application-specific symbol table, it can +pass it and any other data that it needs, via the \f3data\f1 +argument. This removes any need for globals. +.sp +The callback function should return 0 if no errors occur. On failure +it should return 1, and register a terse description of the error by +calling \f3cpl_record_error()\f1. +.sp +.nf + void cpl_record_error(WordCompletion *cpl, + const char *errmsg); +.fi +.sp +The last error message recorded by calling \f3cpl_record_error()\f1, +can subsequently be queried by calling \f3cpl_last_error()\f1, as +described later. +.sp +.nf + int cpl_add_completion(WordCompletion *cpl, + const char *line, int word_start, + int word_end, const char *suffix, + const char *type_suffix, + const char *cont_suffix); +.fi +.sp +The \f3cpl_add_completion()\f1 function is called zero or more times +by the completion callback function to record each possible completion +in the specified \f3WordCompletion\f1 object. These completions are +subsequently returned by \f3cpl_complete_word()\f1, as described +later. The \f3cpl\f1, \f3line\f1, and \f3word_end\f1 arguments should +be those that were passed to the callback function. The +\f3word_start\f1 argument should be the index within the input line +string of the start of the word that is being completed. This should +equal \f3word_end\f1 if a zero-length string is being completed. The +\f3suffix\f1 argument is the string that would have to be appended to +the incomplete word to complete it. If this needs any quoting +(eg. the addition of backslashes before special charaters) to be valid +within the displayed input line, this should be included. A copy of +the suffix string is allocated internally, so there is no need to +maintain your copy of the string after \f3cpl_add_completion()\f1 +returns. +.sp +Note that in the array of possible completions which the +\f3cpl_complete_word()\f1 function returns, the suffix recorded by +\f3cpl_add_completion()\f1 is listed along with the concatentation of +this suffix with the word that lies between \f3word_start\f1 and +\f3word_end\f1 in the input line. +.sp +The \f3type_suffix\f1 argument specifies an optional string to be +appended to the completion if it is displayed as part of a list of +completions by \f3cpl_list_completions()\f1. The intention is that +this indicate to the user the type of each completion. For example, +the file completion function places a directory separator after +completions that are directories, to indicate their nature to the +user. Similary, if the completion were a function, you could indicate +this to the user by setting \f3type_suffix\f1 to "()". Note that the +\f3type_suffix\f1 string isn't copied, so if the argument isn't a +literal string between speech marks, be sure that the string remains +valid for at least as long as the results of \f3cpl_complete_word()\f1 +are needed. +.sp +The \f3cont_suffix\f1 is a continuation suffix to append to the +completed word in the input line if this is the only completion. This +is something that isn't part of the completion itself, but that gives +the user an indication about how they might continue to extend the +token. For example, the file-completion callback function adds a +directory separator if the completed word is a directory. If the +completed word were a function name, you could similarly aid the user +by arranging for an open parenthesis to be appended. +.sp +.nf + CplMatches *cpl_complete_word(WordCompletion *cpl, + const char *line, + int word_end, void *data, + CplMatchFn *match_fn); +.fi +.sp +The \f3cpl_complete_word()\f1 is normally called behind the scenes by +\f3gl_get_line(@FUNC_MANEXT@)\f1, but can also be called separately if you +separately allocate a \f3WordCompletion\f1 object. It performs word +completion, as described at the beginning of this section. Its first +argument is a resource object previously returned by +\f3new_WordCompletion()\f1. The \f3line\f1 argument is the input line +string, containing the word to be completed. The \f3word_end\f1 +argument contains the index of the character in the input line, that +just follows the last character of the word to be completed. When +called by \f3gl_get_line()\f1, this is the character over which the +user pressed \f3TAB\f1. The \f3match_fn\f3 argument is the function +pointer of the callback function which will lookup possible +completions of the word, as described above, and the \f3data\f1 +argument provides a way for the application to pass arbitrary data to +the callback function. +.sp +If no errors occur, the \f3cpl_complete_word()\f1 function returns a +pointer to a \f3CplMatches\f1 container, as defined below. This +container is allocated as part of the \f3cpl\f1 object that was passed +to \f3cpl_complete_word()\f1, and will thus change on each call which +uses the same \f3cpl\f1 argument. +.sp +.nf + typedef struct { + char *completion; /* A matching completion */ + /* string */ + char *suffix; /* The part of the */ + /* completion string which */ + /* would have to be */ + /* appended to complete the */ + /* original word. */ + const char *type_suffix; /* A suffix to be added when */ + /* listing completions, to */ + /* indicate the type of the */ + /* completion. */ + } CplMatch; + + typedef struct { + char *suffix; /* The common initial part */ + /* of all of the completion */ + /* suffixes. */ + const char *cont_suffix; /* Optional continuation */ + /* string to be appended to */ + /* the sole completion when */ + /* nmatch==1. */ + CplMatch *matches; /* The array of possible */ + /* completion strings, */ + /* sorted into lexical */ + /* order. */ + int nmatch; /* The number of elements in */ + /* the above matches[] */ + /* array. */ + } CplMatches; +.fi +.sp +If an error occurs during completion, \f3cpl_complete_word()\f1 +returns NULL. A description of the error can be acquired by calling +the \f3cpl_last_error()\f3 function. +.sp +.nf + const char *cpl_last_error(WordCompletion *cpl); +.fi +.sp +The \f3cpl_last_error()\f3 function returns a terse description of the +error which occurred on the last call to \f3cpl_complete_word()\f1 or +\f3cpl_add_completion()\f1. +.sp +.nf + CplMatches *cpl_recall_matches(WordCompletion *cpl); +.fi +.sp +As a convenience, the return value of the last call to +\f3cpl_complete_word()\f1 can be recalled at a later time by calling +\f3cpl_recall_matches()\f1. If \f3cpl_complete_word()\f1 returned +\f3NULL\f1, so will \f3cpl_recall_matches()\f1. +.sp +.nf + int cpl_list_completions(CplMatches *result, FILE *fp, + int terminal_width); +.fi +.sp +When the \f3cpl_complete_word()\f1 function returns multiple possible +completions, the \f3cpl_list_completions()\f1 function can be called +upon to list them, suitably arranged across the available width of the +terminal. It arranges for the displayed columns of completions to all +have the same width, set by the longest completion. It also appends +the \f3type_suffix\f1 strings that were recorded with each completion, +thus indicating their types to the user. + +.SH THE BUILT-IN FILENAME-COMPLETION CALLBACK + +By default the \f3gl_get_line(@FUNC_MANEXT@)\f1 function, passes the following +completion callback function to \f3cpl_complete_word()\f1. This +function can also be used separately, either by sending it to +\f3cpl_complete_word()\f1, or by calling it directly from your +own completion callback function. +.sp +.nf + CPL_MATCH_FN(cpl_file_completions); +.fi +.sp +Certain aspects of the behavior of this callback can be changed via +its \f3data\f1 argument. If you are happy with its default behavior +you can pass \f3NULL\f1 in this argument. Otherwise it should be a +pointer to a \f3CplFileConf\f1 object, previously allocated by calling +\f3new_CplFileConf()\f1. +.sp +.nf + CplFileConf *new_CplFileConf(void); +.fi +.sp +\f3CplFileConf\f1 objects encapsulate the configuration parameters of +\f3cpl_file_completions()\f1. These parameters, which start out with +default values, can be changed by calling the accessor functions +described below. +.sp +By default, the \f3cpl_file_completions()\f3 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 +\f3cfc_file_start()\f1 with the index at which the filename starts in +the input line. Passing start_index=-1 re-enables the default +behavior. +.sp +.nf + void cfc_file_start(CplFileConf *cfc, int start_index); +.fi +.sp +By default, when \f3cpl_file_completions()\f1 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 \f3cfc_literal_escapes()\f1 with a +non-zero value in its \f3literal\f1 argument. +.sp +.nf + void cfc_literal_escapes(CplFileConf *cfc, int literal); +.fi +.sp +By default, \f3cpl_file_completions()\f1 reports all files who's names +start with the prefix that is being completed. If you only want a +selected subset of these files to be reported in the list of +completions, you can arrange this by providing a callback function +which takes the full pathname of a file, and returns \f30\f1 if the +file should be ignored, or \f31\f1 if the file should be included in +the list of completions. To register such a function for use by +\f3cpl_file_completions()\f1, call \f3cfc_set_check_fn()\f1, and pass +it a pointer to the function, together with a pointer to any data that +you would like passed to this callback whenever it is called. Your +callback can make its decisions based on any property of the file, +such as the filename itself, whether the file is readable, writable or +executable, or even based on what the file contains. +.sp +.nf + #define CPL_CHECK_FN(fn) int (fn)(void *data, \\ + const char *pathname) + typedef CPL_CHECK_FN(CplCheckFn); + + void cfc_set_check_fn(CplFileConf *cfc, + CplCheckFn *chk_fn, void *chk_data); +.fi +.sp +The \f3cpl_check_exe()\f1 function is a provided callback of the above +type, for use with \f3cpl_file_completions()\f1. It returns non-zero +if the filename that it is given represents a normal file that the +user has execute permission to. You could use this to have +\f3cpl_file_completions()\f1 only list completions of executable +files. +.sp +When you have finished with a \f3CplFileConf\f1 variable, you can pass +it to the \f3del_CplFileConf()\f1 destructor function to reclaim its +memory. +.sp +.nf + CplFileConf *del_CplFileConf(CplFileConf *cfc); +.fi +.sp + +.SH THREAD SAFETY + +In multi-threaded programs, you should use the \f3libtecla_r.a\f1 +version of the library. This uses POSIX reentrant functions where +available (hence the \f3_r\f1 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 \f3~username/\f1 +expressions, in \f3cpl_file_completions()\f1. + +Using the \f3libtecla_r.a\f1 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 \f3WordCompletion\f1 object. In +other words, if two threads want to do word completion, they should +each call \f3new_WordCompletion()\f1 to allocate their own completion +objects. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO + +.nf +libtecla(@LIBR_MANEXT@), gl_get_line(@FUNC_MANEXT@), ef_expand_file(@FUNC_MANEXT@), +pca_lookup_file(@FUNC_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/func/cpl_file_completions.in b/libtecla-1.6.3/man/func/cpl_file_completions.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_file_completions.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_last_error.in b/libtecla-1.6.3/man/func/cpl_last_error.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_last_error.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_list_completions.in b/libtecla-1.6.3/man/func/cpl_list_completions.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_list_completions.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_recall_matches.in b/libtecla-1.6.3/man/func/cpl_recall_matches.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_recall_matches.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/cpl_record_error.in b/libtecla-1.6.3/man/func/cpl_record_error.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/cpl_record_error.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_CplFileConf.in b/libtecla-1.6.3/man/func/del_CplFileConf.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_CplFileConf.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_ExpandFile.in b/libtecla-1.6.3/man/func/del_ExpandFile.in new file mode 100644 index 0000000..3d0a884 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_ExpandFile.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/ef_expand_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_GetLine.in b/libtecla-1.6.3/man/func/del_GetLine.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_GetLine.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_PathCache.in b/libtecla-1.6.3/man/func/del_PathCache.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_PathCache.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_PcaPathConf.in b/libtecla-1.6.3/man/func/del_PcaPathConf.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_PcaPathConf.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/del_WordCompletion.in b/libtecla-1.6.3/man/func/del_WordCompletion.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/del_WordCompletion.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/ef_expand_file.in b/libtecla-1.6.3/man/func/ef_expand_file.in new file mode 100644 index 0000000..6637f9f --- /dev/null +++ b/libtecla-1.6.3/man/func/ef_expand_file.in @@ -0,0 +1,248 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH ef_expand_file @FUNC_MANEXT@ +.SH NAME +ef_expand_file, del_ExpandFile, ef_last_error, ef_list_expansions, new_ExpandFile \- expand filenames containing ~user/$envvar and wildcard expressions +.SH SYNOPSIS +.nf +#include <libtecla.h> + +ExpandFile *new_ExpandFile(void); + +ExpandFile *del_ExpandFile(ExpandFile *ef); + +FileExpansion *ef_expand_file(ExpandFile *ef, + const char *path, + int pathlen); + +int ef_list_expansions(FileExpansion *result, FILE *fp, + int term_width); + +const char *ef_last_error(ExpandFile *ef); +.fi + +.SH DESCRIPTION + +The \f3ef_expand_file()\f1 function is part of the tecla library +(see the libtecla(@LIBR_MANEXT@) man page). It expands a specified filename, +converting \f3~user/\f1 and \f3~/\f1 expressions at the start of the +filename to the corresponding home directories, replacing +\f3$envvar\f1 with the value of the corresponding environment +variable, and then, if there are any wildcards, matching these against +existing filenames. Backslashes in the input filename are interpreted +as escaping any special meanings of the characters that follow them. +Only backslahes that are themselves preceded by backslashes are +preserved in the expanded filename. +.sp +In the presence of wildcards, the returned list of filenames only +includes the names of existing files which match the +wildcards. Otherwise, the original filename is returned after +expansion of tilde and dollar expressions, and the result is not +checked against existing files. This mimics the file-globbing behavior +of the unix \f3tcsh\f1 shell. +.sp +The supported wildcards and their meanings are: +.nf + * - Match any sequence of zero or more characters. + ? - Match any single character. + [chars] - Match any single character that appears in + 'chars'. If 'chars' contains an expression of + the form a-b, then any character between a and + b, including a and b, matches. The '-' + character looses its special meaning as a + range specifier when it appears at the start + of the sequence of characters. The ']' + character also looses its significance as the + terminator of the range expression if it + appears immediately after the opening '[', at + which point it is treated one of the + characters of the range. If you want both '-' + and ']' to be part of the range, the '-' + should come first and the ']' second. + + [^chars] - The same as [chars] except that it matches any + single character that doesn't appear in + 'chars'. +.fi + +Note that wildcards never match the initial dot in filenames that +start with '.'. The initial '.' must be explicitly specified in the +filename. This again mimics the globbing behavior of most unix shells, +and its rational is based in the fact that in unix, files with names +that start with '.' are usually hidden configuration files, which are +not listed by default by the ls command. +.sp +The following is a complete example of how to use the file expansion +function. + +.nf + #include <stdio.h> + #include <libtecla.h> + + int main(int argc, char *argv[]) + { + ExpandFile *ef; /* The expansion resource object */ + char *filename; /* The filename being expanded */ + FileExpansion *expn; /* The results of the expansion */ + int i; + + ef = new_ExpandFile(); + if(!ef) + return 1; + + for(arg = *(argv++); arg; arg = *(argv++)) { + if((expn = ef_expand_file(ef, arg, -1)) == NULL) { + fprintf(stderr, "Error expanding %s (%s).\\n", arg, + ef_last_error(ef)); + } else { + printf("%s matches the following files:\\n", arg); + for(i=0; i<expn->nfile; i++) + printf(" %s\\n", expn->files[i]); + } + } + + ef = del_ExpandFile(ef); + return 0; + } +.fi +.sp +Descriptions of the functions used above are as follows: +.sp +.nf + ExpandFile *new_ExpandFile(void) +.fi +.sp +This function creates the resources used by the \f3ef_expand_file()\f1 +function. In particular, it maintains the memory that is used to record the +array of matching filenames that is returned by \f3ef_expand_file()\f1. This +array is expanded as needed, so there is no built in limit to the number of +files that can be matched. +.sp +.nf + ExpandFile *del_ExpandFile(ExpandFile *ef) +.fi +.sp +This function deletes the resources that were returned by a previous call to +\f3new_ExpandFile()\f1. It always returns \f3NULL\f1 (ie a deleted object). It +does nothing if the \f3ef\f1 argument is \f3NULL\f1. +.sp +A container of the following type is returned by \f3ef_expand_file()\f1. +.sp +.nf + typedef struct { + int exists; /* True if the files in files[] exist */ + int nfile; /* The number of files in files[] */ + char **files; /* An array of 'nfile' filenames. */ + } FileExpansion; +.fi +.sp +.nf + FileExpansion *ef_expand_file(ExpandFile *ef, + const char *path, + int pathlen) +.fi +.sp +The \f3ef_expand_file()\f1 function performs filename expansion, as documented +at the start of this section. Its first argument is a resource object returned +by \f3new_ExpandFile()\f1. A pointer to the start of the filename to be matched +is passed via the \f3path\f1 argument. This must be a normal \f3NUL\f1 +terminated string, but unless a length of -1 is passed in \f3pathlen\f1, only +the first \f3pathlen\f1 characters will be used in the filename expansion. If +the length is specified as -1, the whole of the string will be +expanded. +.sp +The function returns a pointer to a container who's contents are the +results of the expansion. If there were no wildcards in the filename, +the \f3nfile\f1 member will be 1, and the \f3exists\f1 member should +be queried if it is important to know if the expanded file currently +exists or not. If there were wildcards, then the contained +\f3files[]\f1 array will contain the names of the \f3nfile\f1 existing +files that matched the wildcarded filename, and the \f3exists\f1 +member will have the value 1. Note that the returned container belongs +to the specified \f3ef\f1 object, and its contents will change on each +call, so if you need to retain the results of more than one call to +\f3ef_expand_file()\f1, you should either make a private copy of the +returned results, or create multiple file-expansion resource objects +via multiple calls to \f3new_ExpandFile()\f1. +.sp +On error, \f3NULL\f1 is returned, and an explanation of the error can +be determined by calling \f3ef_last_error(ef)\f1. +.sp +.nf + const char *ef_last_error(ExpandFile *ef) +.fi +.sp +This function returns the message which describes the error that +occurred on the last call to \f3ef_expand_file()\f1, for the given +\f3(ExpandFile *ef)\f1 resource object. +.sp +.nf + int ef_list_expansions(FileExpansion *result, FILE *fp, + int terminal_width); +.fi +.sp +The \f3ef_list_expansions()\f1 function provides a convenient way to +list the filename expansions returned by \f3ef_expand_file()\f1. Like +the unix \f3ls\f1 command, it arranges the filenames into equal width +columns, each column having the width of the largest file. The number +of columns used is thus determined by the length of the longest +filename, and the specified terminal width. Beware that filenames that +are longer than the specified terminal width are printed without being +truncated, so output longer than the specified terminal width can +occur. The list is written to the stdio stream specified by the +\f3fp\f1 argument. + +.SH THREAD SAFETY + +In multi-threaded programs, you should use the \f3libtecla_r.a\f1 +version of the library. This uses POSIX reentrant functions where +available (hence the \f3_r\f1 suffix), and disables features that rely +on non-reentrant system functions. Currently there are no features +disabled in this module. + +Using the \f3libtecla_r.a\f1 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 \f3ExpandFile\f1 object. In other +words, if two threads want to do file expansion, they should each call +\f3new_ExpandFile()\f1 to allocate their own file-expansion objects. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO +.nf +libtecla(@LIBR_MANEXT@), gl_get_line(@FUNC_MANEXT@), cpl_complete_word(@FUNC_MANEXT@), +pca_lookup_file(@FUNC_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/func/ef_last_error.in b/libtecla-1.6.3/man/func/ef_last_error.in new file mode 100644 index 0000000..3d0a884 --- /dev/null +++ b/libtecla-1.6.3/man/func/ef_last_error.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/ef_expand_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/ef_list_expansions.in b/libtecla-1.6.3/man/func/ef_list_expansions.in new file mode 100644 index 0000000..3d0a884 --- /dev/null +++ b/libtecla-1.6.3/man/func/ef_list_expansions.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/ef_expand_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_abandon_line.in b/libtecla-1.6.3/man/func/gl_abandon_line.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_abandon_line.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_bind_keyseq.in b/libtecla-1.6.3/man/func/gl_bind_keyseq.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_bind_keyseq.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_catch_blocked.in b/libtecla-1.6.3/man/func/gl_catch_blocked.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_catch_blocked.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_change_terminal.in b/libtecla-1.6.3/man/func/gl_change_terminal.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_change_terminal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_clear_history.in b/libtecla-1.6.3/man/func/gl_clear_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_clear_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_completion_action.in b/libtecla-1.6.3/man/func/gl_completion_action.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_completion_action.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_configure_getline.in b/libtecla-1.6.3/man/func/gl_configure_getline.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_configure_getline.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_customize_completion.in b/libtecla-1.6.3/man/func/gl_customize_completion.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_customize_completion.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_display_text.in b/libtecla-1.6.3/man/func/gl_display_text.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_display_text.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_echo_mode.in b/libtecla-1.6.3/man/func/gl_echo_mode.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_echo_mode.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_erase_terminal.in b/libtecla-1.6.3/man/func/gl_erase_terminal.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_erase_terminal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_error_message.in b/libtecla-1.6.3/man/func/gl_error_message.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_error_message.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_get_line.in b/libtecla-1.6.3/man/func/gl_get_line.in new file mode 100644 index 0000000..ba0df8d --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_get_line.in @@ -0,0 +1,2236 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH gl_get_line @FUNC_MANEXT@ +.SH NAME +gl_get_line, new_GetLine, del_GetLine, gl_customize_completion, +gl_change_terminal, gl_configure_getline, gl_load_history, +gl_save_history, gl_group_history, gl_show_history, gl_watch_fd, +gl_inactivity_timeout, gl_terminal_size, gl_set_term_size, +gl_resize_history, gl_limit_history, gl_clear_history, +gl_toggle_history, gl_lookup_history, gl_state_of_history, +gl_range_of_history, gl_size_of_history, gl_echo_mode, +gl_replace_prompt, gl_prompt_style, gl_ignore_signal, gl_trap_signal, +gl_last_signal, gl_completion_action, gl_display_text, +gl_return_status, gl_error_message, gl_catch_blocked, gl_list_signals, +gl_bind_keyseq, gl_erase_terminal, gl_automatic_history, gl_append_history, +gl_query_char, gl_read_char \- allow the user to compose an input line +.SH SYNOPSIS +.nf +#include <stdio.h> +#include <libtecla.h> + +GetLine *new_GetLine(size_t linelen, size_t histlen); + +GetLine *del_GetLine(GetLine *gl); + +char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); + +int gl_query_char(GetLine *gl, const char *prompt, + char defchar); + +int gl_read_char(GetLine *gl); + +int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); + +int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); + +int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); + +int gl_bind_keyseq(GetLine *gl, GlKeyOrigin origin, + const char *keyseq, const char *action); + +int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + +int gl_load_history(GetLine *gl, const char *filename, + const char *comment); + +int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); + +int gl_inactivity_timeout(GetLine *gl, GlTimeoutFn *callback, + void *data, unsigned long sec, + unsigned long nsec); + +int gl_group_history(GetLine *gl, unsigned stream); + +int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, int all_groups, + int max_lines); + +int gl_resize_history(GetLine *gl, size_t bufsize); + +void gl_limit_history(GetLine *gl, int max_lines); + +void gl_clear_history(GetLine *gl, int all_groups); + +void gl_toggle_history(GetLine *gl, int enable); + +GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); + +int gl_set_term_size(GetLine *gl, int ncolumn, int nline); + +int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); + +void gl_state_of_history(GetLine *gl, + GlHistoryState *state); + +void gl_range_of_history(GetLine *gl, + GlHistoryRange *range); + +void gl_size_of_history(GetLine *gl, GlHistorySize *size); + +void gl_echo_mode(GetLine *gl, int enable); + +void gl_replace_prompt(GetLine *gl, const char *prompt); + +void gl_prompt_style(GetLine *gl, GlPromptStyle style); + +int gl_ignore_signal(GetLine *gl, int signo); + +int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); + +int gl_last_signal(GetLine *gl); + +int gl_completion_action(GetLine *gl, + void *data, CplMatchFn *match_fn, + int list_only, const char *name, + const char *keyseq); + +int gl_register_action(GetLine *gl, void *data, + GlActionFn *fn, const char *name, + const char *keyseq); + +int gl_display_text(GetLine *gl, int indentation, + const char *prefix, + const char *suffix, int fill_char, + int def_width, int start, + const char *string); + +GlReturnStatus gl_return_status(GetLine *gl); + +const char *gl_error_message(GetLine *gl, char *buff, + size_t n); + +void gl_catch_blocked(GetLine *gl); + +int gl_list_signals(GetLine *gl, sigset_t *set); + +int gl_append_history(GetLine *gl, const char *line); + +int gl_automatic_history(GetLine *gl, int enable); + +.fi + +.SH DESCRIPTION + +The \f3gl_get_line()\f1 function is part of the tecla library (see the +\f3libtecla(@LIBR_MANEXT@)\f1 man page). If the user is typing at a terminal, each +call prompts them for an line of input, then provides interactive +editing facilities, similar to those of the unix \f3tcsh\f1 shell. In +addition to simple command-line editing, it supports recall of +previously entered command lines, TAB completion of file names, and +in-line wild-card expansion of filenames. Documentation of both the +user-level command-line editing features and all user configuration +options, can be found in the \f3tecla(@MISC_MANEXT@)\f1 man page. This man page +concerns itself with documentation for programmers interested in using +this library in their application. +.sp +.SH AN EXAMPLE + +The following shows a complete example of how to use the +\f3gl_get_line()\f1 function to get input from the user: + +.nf + #include <stdio.h> + #include <locale.h> + #include <libtecla.h> + + int main(int argc, char *argv[]) + { + char *line; /* The line that the user typed */ + GetLine *gl; /* The gl_get_line() resource object */ + + setlocale(LC_CTYPE, ""); /* Adopt the user's choice */ + /* of character set. */ + + gl = new_GetLine(1024, 2048); + if(!gl) + return 1; + + while((line=gl_get_line(gl, "$ ", NULL, -1)) != NULL && + strcmp(line, "exit\\n") != 0) + printf("You typed: %s\\n", line); + + gl = del_GetLine(gl); + return 0; + } +.fi +.sp +In the example, first the resources needed by the \f3gl_get_line()\f1 function +are created by calling \f3new_GetLine()\f1. This allocates the memory used in +subsequent calls to the \f3gl_get_line()\f1 function, including the history +buffer for recording previously entered lines. Then one or more lines are read +from the user, until either an error occurs, or the user types \f3exit\f1. Then +finally the resources that were allocated by \f3new_GetLine()\f1, are returned +to the system by calling \f3del_GetLine()\f1. Note the use of the \f3NULL\f1 +return value of \f3del_GetLine()\f1 to make \f3gl\f1 \f3NULL\f1. This is a +safety precaution. If the program subsequently attempts to pass \f3gl\f1 to +\f3gl_get_line()\f1, said function will complain, and return an error, instead of +attempting to use the deleted resource object. + +.sp +.SH THE FUNCTIONS USED IN THE EXAMPLE +The descriptions of the functions used in the example are as follows: +.sp +.nf + GetLine *new_GetLine(size_t linelen, size_t histlen) +.fi +.sp +This function creates the resources used by the \f3gl_get_line()\f1 +function and returns an opaque pointer to the object that contains +them. The maximum length of an input line is specified via the +\f3linelen\f1 argument, and the number of bytes to allocate for +storing history lines is set by the \f3histlen\f1 argument. History +lines are stored back-to-back in a single buffer of this size. Note +that this means that the number of history lines that can be stored at +any given time, depends on the lengths of the individual lines. If +you want to place an upper limit on the number of lines that can be +stored, see the \f3gl_limit_history()\f1 function described later. If +you don't want history at all, specify \f3histlen\f1 as zero, and no +history buffer will be allocated. +.sp +On error, a message is printed to \f3stderr\f1 and \f3NULL\f1 is returned. +.sp +.nf + GetLine *del_GetLine(GetLine *gl) +.fi +.sp +This function deletes the resources that were returned by a previous +call to \f3new_GetLine()\f1. It always returns \f3NULL\f1 (ie a +deleted object). It does nothing if the \f3gl\f1 argument is +\f3NULL\f1. +.sp +.nf + char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); +.fi +.sp +The \f3gl_get_line()\f1 function can be called any number of +times to read input from the user. The \f3gl\f1 argument +must have been previously returned by a call to +\f3new_GetLine()\f1. The \f3prompt\f1 argument should be a +normal \f3NUL\f1 terminated string, specifying the prompt to +present the user with. By default prompts are displayed +literally, but if enabled with the \f3gl_prompt_style()\f1 +function (see later), prompts can contain directives to do +underlining, switch to and from bold fonts, or turn +highlighting on and off. + +If you want to specify the initial contents of the line, for the user +to edit, pass the desired string via the \f3start_line\f1 +argument. You can then specify which character of this line the cursor +is initially positioned over, using the \f3start_pos\f1 argument. This +should be -1 if you want the cursor to follow the last character of +the start line. If you don't want to preload the line in this manner, +send \f3start_line\f1 as \f3NULL\f1, and set \f3start_pos\f1 to +-1. Note that the line pointer returned by one call to +\f3gl_get_line()\f1 can be passed back to the next call to +\f3gl_get_line()\f1 via the \f3start_line\f1. This allows the +application to take the last entered line, and if it contains an +error, to then present it back to the user for re-editing, with the +cursor initially positioned where the error was encountered. + +The \f3gl_get_line()\f1 function returns a pointer to the line entered +by the user, or \f3NULL\f1 on error or at the end of the input. The +returned pointer is part of the specified \f3gl\f1 resource object, +and thus should not be free'd by the caller, or assumed to be +unchanging from one call to the next. When reading from a user at a +terminal, there will always be a newline character at the end of the +returned line. When standard input is being taken from a pipe or a +file, there will similarly be a newline unless the input line was too +long to store in the internal buffer. In the latter case you should +call \f3gl_get_line()\f1 again to read the rest of the line. Note that +this behavior makes \f3gl_get_line()\f1 similar to \f3fgets()\f1. In +fact when \f3stdin\f1 isn't connected to a terminal,\f3gl_get_line()\f1 +just calls \f3fgets()\f1. + +.SH THE RETURN STATUS OF GL_GET_LINE + +As described above, the \f3gl_get_line()\f1 function has two possible +return values; a pointer to the completed input line, or +\f3NULL\f1. Extra information about what caused \f3gl_get_line()\f1 to +return is available both by inspecting \f3errno\f1, and by calling the +\f3gl_return_status()\f1 function. + +.sp +.nf + GlReturnStatus gl_return_status(GetLine *gl); +.fi +.sp + +The following are the possible enumerated values that this +function returns. + +.sp +.nf + GLR_NEWLINE - The last call to \f3gl_get_line()\f1 + successfully returned a completed + input line. + + GLR_BLOCKED - \f3gl_get_line()\f1 was in non-blocking + server mode, and returned early to + avoid blocking the process while + waiting for terminal I/O. The + \f3gl_pending_io()\f1 function can be + used to see what type of I/O + \f3gl_get_line()\f1 was waiting for. + (see the \f3gl_io_mode(@FUNC_MANEXT@)\f1 man page + for details). + + GLR_SIGNAL - A signal was caught by + \f3gl_get_line()\f1 that had an + after-signal disposition of + \f3GLS_ABORT\f1 (See \f3gl_trap_signal()\f1). + + GLR_TIMEOUT - The inactivity timer expired while + \f3gl_get_line()\f1 was waiting for + input, and the timeout callback + function returned \f3GLTO_ABORT\f1. + See \f3gl_inactivity_timeout()\f1 for + information about timeouts. + + GLR_FDABORT - An application I/O callack returned + \f3GLFD_ABORT\f1 (see \f3gl_watch_fd()\f1). + + GLR_EOF - End of file reached. This can happen + when input is coming from a file or a + pipe, instead of the terminal. It also + occurs if the user invokes the + \f3list-or-eof\f1 or \f3del-char-or-list-or-eof\f1 + actions at the start of a new line. + + GLR_ERROR - An unexpected error caused + \f3gl_get_line()\f1 to abort (consult + \f3errno\f1 and/or + \f3gl_error_message()\f1 for details. +.fi +.sp + +When \f3gl_return_status()\f1 returns \f3GLR_ERROR\f1, and the +value of \f3errno\f1 isn't sufficient to explain what +happened, you can use the \f3gl_error_message()\f1 function +to request a description of the last error that occurred. + +.sp +.nf + const char *gl_error_message(GetLine *gl, char *buff, + size_t n); +.fi +.sp + +The return value is a pointer to the message that +occurred. If the \f3buff\f1 argument is \f3NULL\f1, this +will be a pointer to a buffer within \f3gl\f1, who's value +will probably change on the next call to any function +associated with \f3gl_get_line()\f1. Otherwise, if a +non-\f3NULL\f1 \f3buff\f1 argument is provided, the error +message, including a \f3'\\0'\f1 terminator, will be written +within the first \f3n\f1 elements of this buffer, and the +return value will be a pointer to the first element of this +buffer. If the message won't fit in the provided buffer, it +will be truncated to fit. + +.SH OPTIONAL PROMPT FORMATTING + +Whereas by default the prompt string that you specify is +displayed literally, without any special interpretation of +the characters within it, the \f3gl_prompt_style()\f1 +function can be used to enable optional formatting +directives within the prompt. +.sp +.nf + void gl_prompt_style(GetLine *gl, GlPromptStyle style); +.fi +.sp +The \f3style\f1 argument, which specifies the formatting +style, can take any of the following values: +.sp +.nf + GL_FORMAT_PROMPT - In this style, the formatting + directives described below, when + included in prompt strings, are + interpreted as follows: + + %B - Display subsequent + characters with a bold + font. + %b - Stop displaying characters + with the bold font. + %F - Make subsequent characters + flash. + %f - Turn off flashing + characters. + %U - Underline subsequent + characters. + %u - Stop underlining + characters. + %P - Switch to a pale (half + brightness) font. + %p - Stop using the pale font. + %S - Highlight subsequent + characters (also known as + standout mode). + %s - Stop highlighting + characters. + %V - Turn on reverse video. + %v - Turn off reverse video. + %% - Display a single % + character. + + For example, in this mode, a prompt + string like \f3"%UOK%u$ "\f1 would + display the prompt \f3"OK$ "\f1, + but with the \f3OK\f1 part + underlined. + + Note that although a pair of + characters that starts with a % + character, but doesn't match any of + the above directives is displayed + literally, if a new directive is + subsequently introduced which does + match, the displayed prompt will + change, so it is better to always + use %% to display a literal %. + + Also note that not all terminals + support all of these text + attributes, and that some substitute + a different attribute for missing + ones. + + GL_LITERAL_PROMPT - In this style, the prompt string is + printed literally. This is the + default style. +.fi + +.SH ALTERNATE CONFIGURATION SOURCES + +As mentioned above, by default users have the option of configuring +the behavior of \f3gl_get_line()\f1 via a configuration file called +\f3\&.teclarc\f1 in their home directories. The fact that all +applications share this same configuration file is both an advantage +and a disadvantage. In most cases it is an advantage, since it +encourages uniformity, and frees the user from having to configure +each application separately. In some applications, however, this +single means of configuration is a problem. This is particularly true +of embedded software, where there's no filesystem to read a +configuration file from, and also in applications where a radically +different choice of keybindings is needed to emulate a legacy keyboard +interface. To cater for such cases, the following function allows the +application to control where configuration information is read from. + +.sp +.nf + int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); +.fi +.sp + +It allows the configuration commands that would normally be read from +a user's \f3~/.teclarc\f1 file, to be read from any or none of, a +string, an application specific configuration file, and/or a +user-specific configuration file. If this function is called before +the first call to \f3gl_get_line()\f1, the default behavior of +reading \f3~/.teclarc\f1 on the first call to \f3gl_get_line()\f1 is +disabled, so all configuration must be achieved using the +configuration sources specified with this function. + +If \f3app_string != NULL\f1, then it is interpreted as a string +containing one or more configuration commands, separated from each +other in the string by embedded newline characters. If \f3app_file != +NULL\f1 then it is interpreted as the full pathname of an +application-specific configuration file. If \f3user_file != NULL\f1 +then it is interpreted as the full pathname of a user-specific +configuration file, such as \f3~/.teclarc\f1. For example, in the +following call, + +.sp +.nf + gl_configure_getline(gl, "edit-mode vi \\n nobeep", + "/usr/share/myapp/teclarc", + "~/.teclarc"); +.fi +.sp + +the \f3app_string\f1 argument causes the calling application to start +in vi edit-mode, instead of the default emacs mode, and turns off the +use of the terminal bell by the library. It then attempts to read +system-wide configuration commands from an optional file called +\f3/usr/share/myapp/teclarc\f1, then finally reads user-specific +configuration commands from an optional \f3\&.teclarc\f1 file in the +user's home directory. Note that the arguments are listed in ascending +order of priority, with the contents of \f3app_string\f1 being +potentially overriden by commands in \f3app_file\f1, and commands in +\f3app_file\f1 potentially being overriden by commands in +\f3user_file\f1. +.sp +You can call this function as many times as needed, the results being +cumulative, but note that copies of any filenames specified via the +\f3app_file\f1 and \f3user_file\f1 arguments are recorded internally +for subsequent use by the \f3read-init-files\f1 key-binding function, +so if you plan to call this function multiple times, be sure that the +last call specifies the filenames that you want re-read when the user +requests that the configuration files be re-read. +.sp +Individual key sequences can also be bound and unbound using the +\f3gl_bind_keyseq()\f1 function. + +.sp +.nf + int gl_bind_keyseq(GetLine *gl, GlKeyOrigin origin, + const char *keyseq, + const char *action); +.fi +.sp + +The \f3origin\f1 argument specifies the priority of the binding, +according to who it is being established for, and must be one of +the following two values. +.sp +.nf + GL_USER_KEY - The user requested this key-binding. + GL_APP_KEY - This is a default binding set by the + application. +.fi +.sp +When both user and application bindings for a given key-sequence have +been specified, the user binding takes precedence. The application's +binding is subsequently reinstated if the user's binding is later +unbound via either another to this function, or a call to +\f3gl_configure_getline()\f1. + +The \f3keyseq\f1 argument specifies the key-sequence to be bound or +unbound, and is expressed in the same way as in a \f3~/.teclarc\f1 +configuration file. The \f3action\f1 argument must either be a string +containing the name of the action to bind the key-sequence to, or it +must be \f3NULL\f1 or "" to unbind the key-sequence. + +.SH CUSTOMIZED WORD COMPLETION + +If in your application, you would like to have TAB completion complete +other things in addition to or instead of filenames, you can arrange +this by registering an alternate completion callback function, via a +call to the \f3gl_customize_completion()\f1 function. +.sp +.nf + int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); +.fi +.sp +The \f3data\f1 argument provides a way for your application to pass +arbitrary, application-specific information to the callback +function. This is passed to the callback every time that it is +called. It might for example, point to the symbol table from which +possible completions are to be sought. The \f3match_fn\f1 argument +specifies the callback function to be called. The \f3CplMatchFn\f1 +function type is defined in \f3libtecla.h\f1, as is a +\f3CPL_MATCH_FN()\f1 macro that you can use to declare and prototype +callback functions. The declaration and responsibilities of callback +functions are described in depth in the \f1cpl_complete_word(@FUNC_MANEXT@)\f1 man +page. +.sp +In brief, the callback function is responsible for looking backwards +in the input line, back from the point at which the user pressed TAB, +to find the start of the word being completed. It then must lookup +possible completions of this word, and record them one by one in the +\f3WordCompletion\f1 object that is passed to it as an argument, by +calling the \f3cpl_add_completion()\f1 function. If the callback +function wishes to provide filename completion in addition to its own +specific completions, it has the option of itself calling the builtin +file-name completion callback. This also, is documented in the +\f3cpl_complete_word(@FUNC_MANEXT@)\f1 man page. +.sp +Note that if you would like \f3gl_get_line()\f1 to return the current +input line when a successful completion is been made, you can arrange +this when you call \f3cpl_add_completion()\f1, by making the last +character of the continuation suffix a newline character. If you do +this, the input line will be updated to display the completion, +together with any contiuation suffix up to the newline character, then +\f3gl_get_line()\f1 will return this input line. +.sp + +If, for some reason, your callback function needs to write something +to the terminal, it must call \f3gl_normal_io()\f1 before doing +so. This will start a new line after the input line that is currently +being edited, reinstate normal terminal I/O, and tell +\f3gl_get_line()\f1 that the input line will need to be redrawn when +the callback returns. + +.SH ADDING COMPLETION ACTIONS + +In the previous section the ability to customize the behavior of the +only default completion action, \f3complete-word\f1, was described. +In this section the ability to install additional action functions, so +that different types of word completion can be bound to different +key-sequences, is described. This is achieved by using the +\f3gl_completion_action()\f1 function. + +.sp +.nf + int gl_completion_action(GetLine *gl, + void *data, CplMatchFn *match_fn, + int list_only, const char *name, + const char *keyseq); +.fi +.sp + +The \f3data\f1 and \f3match_fn\f1 arguments are as described +in the \f3cpl_complete_word\f1 man page, and specify the +callback function that should be invoked to identify +possible completions. The \f3list_only\f1 argument +determines whether the action that is being defined should +attempt to complete the word as far as possible in the input +line before displaying any possible ambiguous completions, +or whether it should simply display the list of possible +completions without touching the input line. The former +option is selected by specifying a value of \f30\f1, and the +latter by specifying a value of \f31\f1. The \f3name\f1 +argument specifies the name by which configuration files and +future invokations of this function should refer to the +action. This must either be the name of an existing +completion action to be changed, or be a new unused name for +a new action. Finally, the \f3keyseq\f1 argument specifies +the default key-sequence to bind the action to. If this is +\f3NULL\f1, no new keysequence will be bound to the action. + +Beware that in order for the user to be able to change the +key-sequence that is bound to actions that are installed in +this manner, when you call \f3gl_completion_action()\f1 to +install a given action for the first time, you should do +this between calling \f3new_GetLine()\f1 and the first call +to \f3gl_get_line()\f1. Otherwise, when the user's +configuration file is read on the first call to +\f3gl_get_line()\f1, the name of the your additional action +won't be known, and any reference to it in the configuration +file will generate an error. + +As discussed for \f3gl_customize_completion()\f1, if your callback +function, for some reason, needs to write anything to the terminal, it +must call \f3gl_normal_io()\f1 before doing so. + +.SH DEFINING CUSTOM ACTIONS + +Although the built-in key-binding actions are sufficient for the needs +of most applications, occasionally a specialized application may need +to define one or more custom actions, bound to application-specific +key-sequences. For example, a sales application would benefit from +having a key-sequence that displayed the part name that corresponded +to a part number preceding the cursor. Such a feature is clearly +beyond the scope of the built-in action functions. So for such special +cases, the \f3gl_register_action()\f1 function is provided. + +.sp +.nf + int gl_register_action(GetLine *gl, void *data, + GlActionFn *fn, const char *name, + const char *keyseq); +.fi +.sp + +This function lets the application register an external function, +\f3fn\f1, that will thereafter be called whenever either the specified +key-sequence, \f3keyseq\f1, is entered by the user, or the user enters +any other key-sequence that the user subsequently binds to the +specified action name, \f3name\f1, in their configuration file. The +\f3data\f1 argument can be a pointer to anything that the application +wishes to have passed to the action function, \f3fn\f1, whenever that +function is invoked. + +The action function, \f3fn\f1, should be declared using the following +macro, which is defined in \f3libtecla.h\f1. + +.sp +.nf + #define GL_ACTION_FN(fn) GlAfterAction (fn)(GetLine *gl, \\ + void *data, int count, size_t curpos, \\ + const char *line) +.fi +.sp + +The \f3gl\f1 and \f3data\f1 arguments are those that were previously +passed to \f3gl_register_action()\f1 when the action function was +registered. The \f3count\f1 argument is a numeric argument which the +user has the option of entering using the \f3digit-argument\f1 action, +before invoking the action. If the user doesn't enter a number, then +the \f3count\f1 argument is set to 1. Nominally this argument is +interpreted as a repeat count, meaning that the action should be +repeated that many times. In practice however, for some actions a +repeat count makes little sense. In such cases, actions can either +simply ignore the \f3count\f1 argument, or use its value for a +different purpose. + +A copy of the current input line is passed in the read-only \f3line\f1 +argument. The current cursor position within this string is given by +the index contained in the \f3curpos\f1 argument. Note that direct +manipulation of the input line and the cursor position is not +permitted. This is because the rules dicated by various modes, such as +vi mode versus emacs mode, no-echo mode, and insert mode versus +overstrike mode etc, make it too complex for an application writer to +write a conforming editing action, as well as constrain future changes +to the internals of \f3gl_get_line()\f1. A potential solution to this +dilema would be to allow the action function to edit the line using +the existing editing actions. This is currently under consideration. + +If the action function wishes to write text to the terminal, without +this getting mixed up with the displayed text of the input line, or +read from the terminal without having to handle raw terminal I/O, then +before doing either of these operations, it must temporarily suspend +line editing by calling the \f3gl_normal_io()\f1 function. This +function flushes any pending output to the terminal, moves the cursor +to the start of the line that follows the last terminal line of the +input line, then restores the terminal to a state that is suitable for +use with the C stdio facilities. The latter includes such things as +restoring the normal mapping of \f3\\n\f1 to \f3\\r\\n\f1, and, when +in server mode, restoring the normal blocking form of terminal +I/O. Having called this function, the action function can read from +and write to the terminal without the fear of creating a mess. It +isn't necessary for the action function to restore the original +editing environment before it returns. This is done automatically by +\f3gl_get_line()\f1 after the action function returns. The following +is a simple example of an action function which writes the sentence +"Hello world" on a new terminal line after the line being edited. When +this function returns, the input line is redrawn on the line that +follows the "Hello world" line, and line editing resumes. + +.sp +.nf + static GL_ACTION_FN(say_hello_fn) + { + if(gl_normal_io(gl)) /* Temporarily suspend editing */ + return GLA_ABORT; + printf("Hello world\\n"); + return GLA_CONTINUE; + } +.fi +.sp + +Action functions must return one of the following values, to tell +\f3gl_get_line()\f1 how to procede. + +.sp +.nf + GLA_ABORT - Cause gl_get_line() to return NULL. + GLA_RETURN - Cause gl_get_line() to return the + completed input line. + GLA_CONTINUE - Resume command-line editing. +.fi +.sp + +Note that the \f3name\f1 argument of \f3gl_register_action()\f1 +specifies the name by which a user can refer to the action in their +configuration file. This allows them to re-bind the action to an +alternate key-seqeunce. In order for this to work, it is necessary to +call \f3gl_register_action()\f1 between calling \f3new_GetLine()\f1 +and the first call to \f3gl_get_line()\f1. + +.SH HISTORY FILES + +To save the contents of the history buffer before quitting your +application, and subsequently restore them when you next start the +application, the following functions are provided. + +.sp +.nf + int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + int gl_load_history(GetLine *gl, const char *filename, + const char *comment); +.fi +.sp + +The \f3filename\f1 argument specifies the name to give the history +file when saving, or the name of an existing history file, when +loading. This may contain home-directory and environment variable +expressions, such as "~/.myapp_history" or "$HOME/.myapp_history". +.sp +Along with each history line, extra information about it, such as when +it was entered by the user, and what its nesting level is, is recorded +as a comment preceding the line in the history file. Writing this as a +comment allows the history file to double as a command file, just in +case you wish to replay a whole session using it. Since comment +prefixes differ in different languages, the \f3comment\f1 argument is +provided for specifying the comment prefix. For example, if your +application were a unix shell, such as the bourne shell, you would +specify "#" here. Whatever you choose for the comment character, you +must specify the same prefix to \f3gl_load_history()\f1 that you used +when you called \f3gl_save_history()\f1 to write the history file. +.sp +The \f3max_lines\f1 must be either -1 to specify that all lines in the +history list be saved, or a positive number specifying a ceiling on +how many of the most recent lines should be saved. +.sp +Both fuctions return non-zero on error, after writing an error message +to stderr. Note that \f3gl_load_history()\f1 does not consider the +non-existence of a file to be an error. + +.SH MULTIPLE HISTORY LISTS + +If your application uses a single \f3GetLine\f1 object for entering +many different types of input lines, you may wish \f3gl_get_line()\f1 +to distinguish the different types of lines in the history list, and +only recall lines that match the current type of line. To support this +requirement, \f3gl_get_line()\f1 marks lines being recorded in the +history list with an integer identifier chosen by the application. +Initially this identifier is set to \f10\f3 by \f3new_GetLine()\f1, +but it can be changed subsequently by calling +\f3gl_group_history()\f1. + +.sp +.nf + int gl_group_history(GetLine *gl, unsigned id); +.fi +.sp + +The integer identifier \f3id\f1 can be any number chosen by the +application, but note that \f3gl_save_history()\f1 and +\f3gl_load_history()\f1 preserve the association between identifiers +and historical input lines between program invokations, so you should +choose fixed identifiers for the different types of input line used by +your application. +.sp +Whenever \f3gl_get_line()\f1 appends a new input line to the history +list, the current history identifier is recorded with it, and when it +is asked to recall a historical input line, it only recalls lines that +are marked with the current identifier. + +.SH DISPLAYING HISTORY + +The history list can be displayed by calling \f3gl_show_history()\f1. + +.sp +.nf + int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, + int all_groups, + int max_lines); +.fi +.sp + +This displays the current contents of the history list to the stdio +output stream \f3fp\f1. If the \f3max_lines\f1 argument is greater +than or equal to zero, then no more than this number of the most +recent lines will be displayed. If the \f3all_groups\f1 argument is +non-zero, lines from all history groups are displayed. Otherwise just +those of the currently selected history group are displayed. The +format string argument, \f3fmt\f1, determines how the line is +displayed. This can contain arbitrary characters which are written +verbatim, interleaved with any of the following format directives: + +.nf + %D - The date on which the line was originally + entered, formatted like 2001-11-20. + %T - The time of day when the line was entered, + formatted like 23:59:59. + %N - The sequential entry number of the line in + the history buffer. + %G - The number of the history group which the + line belongs to. + %% - A literal % character. + %H - The history line itself. +.fi + +Thus a format string like \f3"%D %T %H\n"\f1 would output something like: + +.nf + 2001-11-20 10:23:34 Hello world +.fi + +Note the inclusion of an explicit newline character in the format +string. + +.SH LOOKING UP HISTORY + +The \f3gl_lookup_history()\f1 function allows the calling application +to look up lines in the history list. + +.sp +.nf + typedef struct { + const char *line; /* The requested historical */ + /* line. */ + unsigned group; /* The history group to which */ + /* the line belongs. */ + time_t timestamp; /* The date and time at which */ + /* the line was originally */ + /* entered. */ + } GlHistoryLine; + + int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); +.fi +.sp + +The \f3id\f1 argument indicates which line to look up, where the first +line that was entered in the history list after \f3new_GetLine()\f1 +was called, is denoted by 0, and subsequently entered lines are +denoted with successively higher numbers. Note that the range of lines +currently preserved in the history list can be queried by calling the +\f3gl_range_of_history()\f1 function, described later. If the +requested line is in the history list, the details of the line are +recorded in the variable pointed to by the \f3hline\f1 argument, and +\f31\f1 is returned. Otherwise \f30\f1 is returned, and the variable +pointed to by \f3hline\f1 is left unchanged. +.sp +Beware that the string returned in \f3hline->line\f1 is part of the +history buffer, so it must not be modified by the caller, and will be +recycled on the next call to any function that takes \f3gl\f1 as its +argument. Therefore you should make a private copy of this string if +you need to keep it around. + +.SH MANUAL HISTORY ARCHIVAL + +By default, whenever a line is entered by the user, it is +automatically appended to the history list, just before +\f3gl_get_line()\f1 returns the line to the caller. This is convenient +for the majority of applications, but there are also applications that +need finer grained control over what gets added to the history +list. In such cases, the automatic addition of entered lines to the +history list can be turned off by calling the +\f3gl_automatic_history()\f1 function. + +.sp +.nf + int gl_automatic_history(GetLine *gl, int enable); +.fi +.sp + +If this function is called with its \f3enable\f1 argument set to +\f30\f1, \f3gl_get_line()\f1 won't automatically archive subsequently +entered lines. Automatic archiving can be reenabled at a later time, +by calling this function again, with its \f3enable\f1 argument set to +1. While automatic history archiving is disabled, the calling +application can use the \f3gl_append_history()\f1 to append lines to +the history list as needed. + +.sp +.nf + int gl_append_history(GetLine *gl, const char *line); +.fi +.sp + +The \f3line\f1 argument specifies the line to be added to the history +list. This must be a normal \f3'\0'\f1 terminated string. If this +string contains any newline characters, the line that gets archived in +the history list will be terminated by the first of these. Otherwise +it will be terminated by the \f3'\0'\f1 terminator. If the line is +longer than the maximum input line length, that was specified when +\f3new_GetLine()\f1 was called, when the line is recalled, it will get +truncated to the actual \f3gl_get_line()\f1 line length. + +If successful, \f3gl_append_history()\f1 returns 0. Otherwise it +returns non-zero, and sets \f3errno\f1 to one of the following values. + +.sp +.nf + EINVAL - One of the arguments passed to + gl_append_history() was NULL. + ENOMEM - The specified line was longer than the allocated + size of the history buffer (as specified when + new_GetLine() was called), so it couldn't be + archived. +.fi +.sp + +A textual description of the error can optionally be obtained by +calling \f3gl_error_message()\f1. Note that after such an error, the +history list remains in a valid state to receive new history lines, so +there is little harm in simply ignoring the return status of +\f3gl_append_history()\f1. + +.SH MISCELLANEOUS HISTORY CONFIGURATION + +If you wish to change the size of the history buffer that was +originally specified in the call to \f3new_GetLine()\f1, you can do so +with the \f3gl_resize_history()\f1 function. + +.sp +.nf + int gl_resize_history(GetLine *gl, size_t histlen); +.fi +.sp + +The \f3histlen\f1 argument specifies the new size in bytes, and if you +specify this as 0, the buffer will be deleted. +.sp +As mentioned in the discussion of \f3new_GetLine()\f1, the number of +lines that can be stored in the history buffer, depends on the lengths +of the individual lines. For example, a 1000 byte buffer could equally +store 10 lines of average length 100 bytes, or 2 lines of average +length 50 bytes. Although the buffer is never expanded when new lines +are added, a list of pointers into the buffer does get expanded when +needed to accomodate the number of lines currently stored in the +buffer. To place an upper limit on the number of lines in the buffer, +and thus a ceiling on the amount of memory used in this list, you can +call the \f3gl_limit_history()\f1 function. + +.sp +.nf + void gl_limit_history(GetLine *gl, int max_lines); +.fi +.sp + +The \f3max_lines\f1 should either be a positive number \f3>= 0\f1, +specifying an upper limit on the number of lines in the buffer, or be +\f3-1\f1 to cancel any previously specified limit. When a limit is in +effect, only the \f3max_lines\f1 most recently appended lines are kept +in the buffer. Older lines are discarded. +.sp +To discard lines from the history buffer, use the +\f3gl_clear_history()\f1 function. +.sp +.nf + void gl_clear_history(GetLine *gl, int all_groups); +.fi +.sp +The \f3all_groups\f1 argument tells the function whether to delete +just the lines associated with the current history group (see +\f3gl_group_history()\f1), or all historical lines in the buffer. +.sp +The \f3gl_toggle_history()\f1 function allows you to toggle history on +and off without losing the current contents of the history list. + +.sp +.nf + void gl_toggle_history(GetLine *gl, int enable); +.fi +.sp + +Setting the \f3enable\f1 argument to 0 turns off the history +mechanism, and setting it to 1 turns it back on. When history is +turned off, no new lines will be added to the history list, and +history lookup key-bindings will act as though there is nothing in the +history buffer. + +.SH QUERYING HISTORY INFORMATION + +The configured state of the history list can be queried with the +\f3gl_history_state()\f1 function. + +.sp +.nf + typedef struct { + int enabled; /* True if history is enabled */ + unsigned group; /* The current history group */ + int max_lines; /* The current upper limit on the */ + /* number of lines in the history */ + /* list, or -1 if unlimited. */ + } GlHistoryState; + + void gl_state_of_history(GetLine *gl, + GlHistoryState *state); +.fi +.sp +On return, the status information is recorded in the variable pointed +to by the \f3state\f1 argument. +.sp +The \f3gl_range_of_history()\f1 function returns the number and +range of lines in the history list. + +.sp +.nf +typedef struct { + unsigned long oldest; /* The sequential entry number */ + /* of the oldest line in the */ + /* history list. */ + unsigned long newest; /* The sequential entry number */ + /* of the newest line in the */ + /* history list. */ + int nlines; /* The number of lines in the */ + /* history list. */ +} GlHistoryRange; + +void gl_range_of_history(GetLine *gl, GlHistoryRange *range); +.fi +.sp +The return values are recorded in the variable pointed to by the +\f3range\f1 argument. If the \f3nlines\f1 member of this structure is +greater than zero, then the \f3oldest\f1 and \f3newest\f1 members +report the range of lines in the list, and \f3newest=oldest+nlines-1\f1. +Otherwise they are both zero. +.sp +The \f3gl_size_of_history()\f1 function returns the total size of the +history buffer and the amount of the buffer that is currently +occupied. +.sp +.nf + typedef struct { + size_t size; /* The size of the history buffer */ + /* (bytes). */ + size_t used; /* The number of bytes of the */ + /* history buffer that are */ + /* currently occupied. */ + } GlHistorySize; + + void gl_size_of_history(GetLine *gl, GlHistorySize *size); +.fi +.sp +On return, the size information is recorded in the variable pointed to +by the \f3size\f1 argument. + +.SH CHANGING TERMINALS + +The \f3new_GetLine()\f1 constructor function assumes that input is to +be read from \f3stdin\f1, and output written to \f3stdout\f1. The +following function allows you to switch to different input and output +streams. +.sp +.nf + int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); +.fi +.sp +The \f3gl\f1 argument is the object that was returned by +\f3new_GetLine()\f1. The \f3input_fp\f1 argument specifies the stream +to read from, and \f3output_fp\f1 specifies the stream to be written +to. Only if both of these refer to a terminal, will interactive +terminal input be enabled. Otherwise \f3gl_get_line()\f1 will simply +call \f3fgets()\f1 to read command input. If both streams refer to a +terminal, then they must refer to the same terminal, and the type of +this terminal must be specified via the \f3term\f1 argument. The value +of the \f3term\f1 argument is looked up in the terminal information +database (terminfo or termcap), in order to determine which special +control sequences are needed to control various aspects of the +terminal. \f3new_GetLine()\f1 for example, passes the return value of +\f3getenv("TERM")\f1 in this argument. Note that if one or both of +\f3input_fp\f1 and \f3output_fp\f1 don't refer to a terminal, then it +is legal to pass \f3NULL\f1 instead of a terminal type. +.sp +Note that if you want to pass file descriptors to +\f3gl_change_terminal()\f1, you can do this by creating stdio stream +wrappers using the POSIX \f3fdopen()\f1 function. + +.SH EXTERNAL EVENT HANDLING + +By default, \f3gl_get_line()\f1 doesn't return until either a complete +input line has been entered by the user, or an error occurs. In +programs that need to watch for I/O from other sources than the +terminal, there are two options. + +.sp +.nf + 1. Use the functions described in the + \f3gl_io_mode(@FUNC_MANEXT@)\f1 man page to switch + \f3gl_get_line()\f1 into non-blocking server mode. In this mode, + \f3gl_get_line()\f1 becomes a non-blocking, incremental + line-editing function that can safely be called from + an external event loop. Although this is a very + versatile method, it involves taking on some + responsibilities that are normally performed behind + the scenes by \f3gl_get_line()\f1. + + 2. While \f3gl_get_line()\f1 is waiting for keyboard + input from the user, you can ask it to also watch for + activity on arbitrary file descriptors, such as + network sockets, pipes etc, and have it call functions + of your choosing when activity is seen. This works on + any system that has the \f3select()\f1 system call, + which is most, if not all flavors of unix. +.fi +.sp + +Registering a file descriptor to be watched by +\f3gl_get_line()\f1 involves calling the \f3gl_watch_fd()\f1 function. + +.sp +.nf + int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); +.fi +.sp + +If this returns non-zero, then it means that either your arguments are +invalid, or that this facility isn't supported on the host system. +.sp +The \f3fd\f1 argument is the file descriptor to be watched. The +\f3event\f1 argument specifies what type of activity is of interest, +chosen from the following enumerated values: + +.sp +.nf + GLFD_READ - Watch for the arrival of data to be read. + GLFD_WRITE - Watch for the ability to write to the file + descriptor without blocking. + GLFD_URGENT - Watch for the arrival of urgent + out-of-band data on the file descriptor. +.fi +.sp + +The \f3callback\f1 argument is the function to call when the selected +activity is seen. It should be defined with the following macro, which +is defined in libtecla.h. + +.sp +.nf + #define GL_FD_EVENT_FN(fn) GlFdStatus (fn)(GetLine *gl, \\ + void *data, int fd, \\ + GlFdEvent event) +.fi +.sp +The \f3data\f1 argument of the \f3gl_watch_fd()\f1 function is passed +to the callback function for its own use, and can point to anything +you like, including \f3NULL\f1. The file descriptor and the event +argument are also passed to the callback function, and this +potentially allows the same callback function to be registered to more +than one type of event and/or more than one file descriptor. The +return value of the callback function should be one of the following +values. + +.sp +.nf + GLFD_ABORT - Tell gl_get_line() to abort. When this + happens, \f3gl_get_line()\f1 returns + \f3NULL\f1, and a following call to + \f3gl_return_status()\f1 will return + \f3GLR_FDABORT\f1. Note that if the + application needs \f3errno\f1 always to + have a meaningful value when + \f3gl_get_line()\f1 returns \f3NULL\f1, + the callback function should set + \f3errno\f1 appropriately. + GLFD_REFRESH - Redraw the input line then continue + waiting for input. Return this if + your callback wrote to the terminal. + GLFD_CONTINUE - Continue to wait for input, without + redrawing the line. +.fi +.sp +Note that before calling the callback, \f3gl_get_line()\f1 blocks most +signals, and leaves its own signal handlers installed, so if you need +to catch a particular signal you will need to both temporarily install +your own signal handler, and unblock the signal. Be sure to re-block +the signal (if it was originally blocked) and reinstate the original +signal handler, if any, before returning. + +.sp + +If the callback function needs to read or write to the terminal, it +should ideally first call \f3gl_normal_io(gl)\f1 to temporarily +suspend line editing. This will restore the terminal to canonical, +blocking-I/O, mode, and move the cursor to the start of a new terminal +line. Later, when the callback returns, \f3gl_get_line()\f1 will +notice that \f3gl_normal_io()\f1 was called, redisplay the input line +and resume editing. Note that in this case the return values, +\f3GLFD_REFRESH\f1 and \f3GLFD_CONTINUE\f1 are equivalent. + +.sp + +To support cases where the callback function calls a third-party +function which occasionally and unpredictably writes to the terminal, +the automatic conversion of \f3"\n"\f1 to \f3"\r\n"\f1 is re-enabled +before the callback function is called. If the callack knows that the +third-party function wrote to the terminal, it should then return the +\f3GLFD_REFRESH\f1 return value, to tell \f3gl_get_line()\f1 to +redisplay the input line. + +.sp + +To remove a callback function that you previously registered for a +given file descriptor and event, simply call \f3gl_watch_fd()\f1 with +the same file descriptor and \f3event\f1 arguments, but with a +\f3callback\f1 argument of \f30\f1. The \f3data\f1 argument is ignored +in this case. + +.SH SETTING AN INACTIVITY TIMEOUT + +On systems with the \f3select()\f1 system call, the +\f3gl_inactivity_timeout()\f1 function can be used to set or cancel an +inactivity timeout. Inactivity in this case refers both to keyboard +input, and to I/O on any file descriptors registered by prior and +subsequent calls to \f3gl_watch_fd()\f1. On oddball systems that don't +have \f3select()\f1, this call has no effect. + +.sp +.nf + int gl_inactivity_timeout(GetLine *gl, GlTimeoutFn *callback, + void *data, unsigned long sec, + unsigned long nsec); +.fi +.sp + +The timeout is specified in the form of an integral number of seconds +and an integral number of nanoseconds, via the \f3sec\f1 and +\f3nsec\f1 arguments respectively. Subsequently, whenever no activity +is seen for this time period, the function specified via the +\f3callback\f1 argument is called. The \f3data\f1 argument of +\f3gl_inactivity_timeout()\f1 is passed verbatim to this callback function +whenever it is invoked, and can thus be used to pass arbitrary +application-specific information to the callback. The following macro +is provided in \f3libtecla.h\f1 for applications to use to declare and +prototype timeout callback functions. + +.sp +.nf + #define GL_TIMEOUT_FN(fn) \\ + GlAfterTimeout (fn)(GetLine *gl, void *data) +.fi +.sp + +On returning, the application's callback is expected to return one of +the following enumerators to tell \f3gl_get_line()\f1 how to procede +after the timeout has been handled by the callback. + +.sp +.nf + GLTO_ABORT - Tell gl_get_line() to abort. When + this happens, \f3gl_get_line()\f1 will + return \f3NULL\f1, and a following call + to \f3gl_return_status()\f1 will return + \f3GLR_TIMEOUT\f1. Note that if the + application needs \f3errno\f1 always to + have a meaningful value when + \f3gl_get_line()\f1 returns \f3NULL\f1, + the callback function should set + \f3errno\f1 appropriately. + GLTO_REFRESH - Redraw the input line, then continue + waiting for input. You should return + this value if your callback wrote to the + terminal without having first called + \f3gl_normal_io(gl)\f1. + GLTO_CONTINUE - In normal blocking-I/O mode, continue to + wait for input, without redrawing the + user's input line. + In non-blocking server I/O mode (see + gl_io_mode(@FUNC_MANEXT@)), cause \f3gl_get_line()\f1 + to act as though I/O blocked. This means + that \f3gl_get_line()\f1 will immediately + return \f3NULL\f1, and a following call + to \f3gl_return_status()\f1 will return + \f3GLR_BLOCKED\f1. +.fi +.sp + +Note that before calling the callback, \f3gl_get_line()\f1 blocks most +signals, and leaves its own signal handlers installed, so if you need +to catch a particular signal you will need to both temporarily install +your own signal handler, and unblock the signal. Be sure to re-block +the signal (if it was originally blocked) and reinstate the original +signal handler, if any, before returning. + +.sp + +If the callback function needs to read or write to the terminal, it +should ideally first call \f3gl_normal_io(gl)\f1 to temporarily +suspend line editing. This will restore the terminal to canonical, +blocking-I/O, mode, and move the cursor to the start of a new terminal +line. Later, when the callback returns, \f3gl_get_line()\f1 will +notice that \f3gl_normal_io()\f1 was called, redisplay the input line +and resume editing. Note that in this case the return values, +\f3GLTO_REFRESH\f1 and \f3GLTO_CONTINUE\f1 are equivalent. + +.sp + +To support cases where the callback function calls a third-party +function which occasionally and unpredictably writes to the terminal, +the automatic conversion of \f3"\n"\f1 to \f3"\r\n"\f1 is re-enabled +before the callback function is called. If the callack knows that the +third-party function wrote to the terminal, it should then return the +\f3GLTO_REFRESH\f1 return value, to tell \f3gl_get_line()\f1 to +redisplay the input line. + +.sp + +Note that although the timeout argument includes a nano-second +component, few computer clocks presently have resolutions that are +finer than a few milliseconds, so asking for less than a few +milliseconds is equivalent to requesting zero seconds on a lot of +systems. If this would be a problem, you should base your timeout +selection on the actual resolution of the host clock (eg. by calling +\f3sysconf(_SC_CLK_TCK)\f1). + +.sp + +To turn off timeouts, simply call \f3gl_inactivity_timeout()\f1 with a +\f3callback\f1 argument of \f30\f1. The \f3data\f1 argument is ignored +in this case. + +.SH SIGNAL HANDLING DEFAULTS + +By default, the \f3gl_get_line()\f1 function intercepts a +number of signals. This is particularly important for +signals which would by default terminate the process, since +the terminal needs to be restored to a usable state before +this happens. In this section, the signals that are trapped +by default, and how \f3gl_get_line()\f1 responds to them, is +described. Changing these defaults is the topic of the +following section. +.sp +When the following subset of signals are caught, \f3gl_get_line()\f1 +first restores the terminal settings and signal handling to how they +were before \f3gl_get_line()\f1 was called, resends the signal, to +allow the calling application's signal handlers to handle it, then if +the process still exists, \f3gl_get_line()\f1 returns \f3NULL\f1 and +sets \f3errno\f1 as specified below. + +.sp +.nf + SIGINT - This signal is generated both by the keyboard + interrupt key (usually ^C), and the keyboard + break key. + + errno=EINTR + + SIGHUP - This signal is generated when the controlling + terminal exits. + + errno=ENOTTY + + SIGPIPE - This signal is generated when a program attempts + to write to a pipe who's remote end isn't being + read by any process. This can happen for example + if you have called \f3gl_change_terminal()\f1 to + redirect output to a pipe hidden under a pseudo + terminal. + + errno=EPIPE + + SIGQUIT - This signal is generated by the keyboard quit + key (usually ^\\). + + errno=EINTR + + SIGABRT - This signal is generated by the standard C, + abort() function. By default it both + terminates the process and generates a core + dump. + + errno=EINTR + + SIGTERM - This is the default signal that the UN*X + kill command sends to processes. + + errno=EINTR +.fi +.sp +Note that in the case of all of the above signals, POSIX mandates that +by default the process is terminated, with the addition of a core dump +in the case of the \f3SIGQUIT\f1 signal. In other words, if the +calling application doesn't override the default handler by supplying +its own signal handler, receipt of the corresponding signal will +terminate the application before \f3gl_get_line()\f1 returns. +.sp +If gl_get_line() aborts with errno set to EINTR, you can find out what +signal caused it to abort, by calling the following function. +.sp +.nf + int gl_last_signal(const GetLine *gl); +.fi +.sp +This returns the numeric code (eg. \f3SIGINT\f1) of the last signal +that was received during the most recent call to \f3gl_get_line()\f1, +or \f3-1\f1 if no signals were received. +.sp +On systems that support it, when a SIGWINCH (window change) signal is +received, \f3gl_get_line()\f1 queries the terminal to find out its new +size, redraws the current input line to accomodate the new size, then +returns to waiting for keyboard input from the user. Unlike other +signals, this signal isn't resent to the application. +.sp +Finally, the following signals cause \f3gl_get_line()\f1 to first +restore the terminal and signal environment to that which prevailed +before \f3gl_get_line()\f1 was called, then resend the signal to the +application. If the process still exists after the signal has been +delivered, then \f3gl_get_line()\f1 then re-establishes its own signal +handlers, switches the terminal back to raw mode, redisplays the input +line, and goes back to awaiting terminal input from the user. +.sp +.nf + SIGCONT - This signal is generated when a suspended + process is resumed. + + SIGPOLL - On SVR4 systems, this signal notifies the + process of an asynchronous I/O event. Note + that under 4.3+BSD, SIGIO and SIGPOLL are + the same. On other systems, SIGIO is ignored + by default, so \f3gl_get_line()\f1 doesn't + trap it by default. + + SIGPWR - This signal is generated when a power failure + occurs (presumably when the system is on a + UPS). + + SIGALRM - This signal is generated when a timer + expires. + + SIGUSR1 - An application specific signal. + + SIGUSR2 - Another application specific signal. + + SIGVTALRM - This signal is generated when a virtual + timer expires (see man setitimer(2)). + + SIGXCPU - This signal is generated when a process + exceeds its soft CPU time limit. + + SIGXFSZ - This signal is generated when a process + exceeds its soft file-size limit. + + SIGTSTP - This signal is generated by the terminal + suspend key, which is usually ^Z, or the + delayed terminal suspend key, which is + usually ^Y. + + SIGTTIN - This signal is generated if the program + attempts to read from the terminal while the + program is running in the background. + + SIGTTOU - This signal is generated if the program + attempts to write to the terminal while the + program is running in the background. +.fi +.sp + +Obviously not all of the above signals are supported on all systems, +so code to support them is conditionally compiled into the tecla +library. +.sp +Note that if \f3SIGKILL\f1 or \f3SIGPOLL\f1, which by definition can't +be caught, or any of the hardware generated exception signals, such as +\f3SIGSEGV\f1, \f3SIGBUS\f1 and \f3SIGFPE\f1, are received and +unhandled while \f3gl_get_line()\f1 has the terminal in raw mode, the +program will be terminated without the terminal having been restored +to a usable state. In practice, job-control shells usually reset the +terminal settings when a process relinquishes the controlling +terminal, so this is only a problem with older shells. + +.SH CUSTOMIZED SIGNAL HANDLING + +The previous section listed the signals that +\f3gl_get_line()\f1 traps by default, and described how it +responds to them. This section describes how to both add and +remove signals from the list of trapped signals, and how to +specify how \f3gl_get_line()\f1 should respond to a given +signal. +.sp +If you don't need \f3gl_get_line()\f1 to do anything in +response to a signal that it normally traps, you can tell to +\f3gl_get_line()\f1 to ignore that signal by calling +\f3gl_ignore_signal()\f1. +.sp +.nf + int gl_ignore_signal(GetLine *gl, int signo); +.fi +.sp +The \f3signo\f1 argument is the number of the signal +(eg. \f3SIGINT\f1) that you want to have ignored. If the +specified signal isn't currently one of those being trapped, +this function does nothing. +.sp +The \f3gl_trap_signal()\f1 function allows you to either add +a new signal to the list that \f3gl_get_line()\f1 traps, or +modify how it responds to a signal that it already traps. +.sp +.nf + int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); +.fi +.sp +The \f3signo\f1 argument is the number of the signal that +you wish to have trapped. The \f3flags\f1 argument is a set +of flags which determine the environment in which the +application's signal handler is invoked, the \f3after\f1 +argument tells \f3gl_get_line()\f1 what to do after the +application's signal handler returns, and \f3errno_value\f1 +tells \f3gl_get_line()\f1 what to set \f3errno\f1 to if told +to abort. +.sp +The \f3flags\f1 argument is a bitwise OR of zero or more of +the following enumerators: +.sp +.nf + GLS_RESTORE_SIG - Restore the caller's signal + environment while handling the + signal. + + GLS_RESTORE_TTY - Restore the caller's terminal settings + while handling the signal. + + GLS_RESTORE_LINE - Move the cursor to the start of the + line following the input line before + invoking the application's signal + handler. + + GLS_REDRAW_LINE - Redraw the input line when the + application's signal handler returns. + + GLS_UNBLOCK_SIG - Normally, if the calling program has + a signal blocked (man sigprocmask), + gl_get_line() does not trap that + signal. This flag tells gl_get_line() + to trap the signal and unblock it for + the duration of the call to + gl_get_line(). + + GLS_DONT_FORWARD - If this flag is included, the signal + will not be forwarded to the signal + handler of the calling program. +.fi +.sp +Two commonly useful flag combinations are also enumerated as +follows: +.sp +.nf + GLS_RESTORE_ENV = GLS_RESTORE_SIG | GLS_RESTORE_TTY | + GLS_REDRAW_LINE + + GLS_SUSPEND_INPUT = GLS_RESTORE_ENV | GLS_RESTORE_LINE +.fi +.sp + +If your signal handler, or the default system signal +handler for this signal, if you haven't overridden it, never +either writes to the terminal, nor suspends or terminates +the calling program, then you can safely set the \f3flags\f1 +argument to \f30\f1. +.sp +If your signal handler always writes to the terminal, reads +from it, or suspends or terminates the program, you should +specify the \f3flags\f1 argument as \f3GL_SUSPEND_INPUT\f1, +so that: +.sp +.nf +1. The cursor doesn't get left in the middle of the input + line. +2. So that the user can type in input and have it echoed. +3. So that you don't need to end each output line with + \f3\\r\\n\f1, instead of just \f3\\n\f1. +.fi +.sp +The \f3GL_RESTORE_ENV\f1 combination is the same as +\f3GL_SUSPEND_INPUT\f1, except that it doesn't move the +cursor, and if your signal handler doesn't read or write +anything to the terminal, the user won't see any visible +indication that a signal was caught. This can be useful if +you have a signal handler that only occasionally writes to +the terminal, where using \f3GL_SUSPEND_LINE\f1 would cause +the input line to be unnecessarily duplicated when nothing +had been written to the terminal. Such a signal handler, +when it does write to the terminal, should be sure to start +a new line at the start of its first write, by writing a +'\\n' character, and should be sure to leave the cursor on a +new line before returning. If the signal arrives while the +user is entering a line that only occupies a signal terminal +line, or if the cursor is on the last terminal line of a +longer input line, this will have the same effect as +\f3GL_SUSPEND_INPUT\f1. Otherwise it will start writing on a +line that already contains part of the displayed input line. +This doesn't do any harm, but it looks a bit ugly, which is +why the \f3GL_SUSPEND_INPUT\f1 combination is better if you +know that you are always going to be writting to the +terminal. +.sp +The \f3after\f1 argument, which determines what +\f3gl_get_line()\f1 does after the application's signal +handler returns (if it returns), can take any one of the +following values: +.sp +.nf + GLS_RETURN - Return the completed input line, just as + though the user had pressed the return + key. + + GLS_ABORT - Cause \f3gl_get_line()\f1 to abort. When + this happens, \f3gl_get_line()\f1 returns + \f3NULL\f1, and a following call to + \f3gl_return_status()\f1 will return + \f3GLR_SIGNAL\f1. Note that if the + application needs \f3errno\f1 always to + have a meaningful value when + \f3gl_get_line()\f1 returns \f3NULL\f1, + the callback function should set + \f3errno\f1 appropriately. + GLS_CONTINUE - Resume command line editing. +.fi +.sp +The \f3errno_value\f1 argument is intended to be combined +with the \f3GLS_ABORT\f1 option, telling \f3gl_get_line()\f1 +what to set the standard \f3errno\f1 variable to before +returning \f3NULL\f1 to the calling program. It can also, +however, be used with the \f3GL_RETURN\f1 option, in case +you wish to have a way to distinguish between an input line +that was entered using the return key, and one that was +entered by the receipt of a signal. + +.SH RELIABLE SIGNAL HANDLING + +Signal handling is suprisingly hard to do reliably without race +conditions. In \f3gl_get_line()\f1 a lot of care has been taken to +allow applications to perform reliable signal handling around +\f3gl_get_line()\f1. This section explains how to make use of this. + +As an example of the problems that can arise if the application isn't +written correctly, imagine that one's application has a SIGINT signal +handler that sets a global flag. Now suppose that the application +tests this flag just before invoking \f3gl_get_line()\f1. If a SIGINT +signal happens to be received in the small window of time between the +statement that tests the value of this flag, and the statement that +calls \f3gl_get_line()\f1, then \f3gl_get_line()\f1 will not see the +signal, and will not be interrupted. As a result, the application +won't be able to respond to the signal until the user gets around to +finishing entering the input line and \f3gl_get_line()\f1 +returns. Depending on the application, this might or might not be a +disaster, but at the very least it would puzzle the user. + +The way to avoid such problems is to do the following. + +1. If needed, use the \f3gl_trap_signal()\f1 function to + configure \f3gl_get_line()\f1 to abort when important + signals are caught. + +2. Configure \f3gl_get_line()\f1 such that if any of the + signals that it catches are blocked when + \f3gl_get_line()\f1 is called, they will be unblocked + automatically during times when \f3gl_get_line()\f1 is + waiting for I/O. This can be done either + on a per signal basis, by calling the + \f3gl_trap_signal()\f1 function, and specifying the + \f3GLS_UNBLOCK\f1 attribute of the signal, or globally by + calling the \f3gl_catch_blocked()\f1 function. + +.sp +.nf + void gl_catch_blocked(GetLine *gl); +.fi +.sp + + This function simply adds the \f3GLS_UNBLOCK\f1 attribute + to all of the signals that it is currently configured to + trap. + +3. Just before calling \f3gl_get_line()\f1, block delivery + of all of the signals that \f3gl_get_line()\f1 is + configured to trap. This can be done using the POSIX + \f3sigprocmask()\f1 function in conjunction with the + \f3gl_list_signals()\f1 function. + +.sp +.nf + int gl_list_signals(GetLine *gl, sigset_t *set); +.fi +.sp + + This function returns the set of signals that it is + currently configured to catch in the \f3set\f1 argument, + which is in the form required by \f3sigprocmask()\f1. + +4. In the example, one would now test the global flag that + the signal handler sets, knowing that there is now no + danger of this flag being set again until + \f3gl_get_line()\f1 unblocks its signals while performing + I/O. + +5. Eventually \f3gl_get_line()\f1 returns, either because + a signal was caught, an error occurred, or the user + finished entering their input line. + +6. Now one would check the global signal flag again, and if + it is set, respond to it, and zero the flag. + +7. Use \f3sigprocmask()\f1 to unblock the signals that were + blocked in step 3. + +The same technique can be used around certain POSIX +signal-aware functions, such as \f3sigsetjmp()\f1 and +\f3sigsuspend()\f1, and in particular, the former of these +two functions can be used in conjunction with +\f3siglongjmp()\f1 to implement race-condition free signal +handling around other long-running system calls. The way to +do this, is explained next, by showing how +\f3gl_get_line()\f1 manages to reliably trap signals around +calls to functions like \f3read()\f1 and \f3select()\f1 +without race conditions. + +The first thing that \f3gl_get_line()\f1 does, whenever it +is called, is to use the POSIX \f3sigprocmask()\f1 function +to block the delivery of all of the signals that it is +currently configured to catch. This is redundant if the +application has already blocked them, but it does no +harm. It undoes this step just before returning. + +Whenever \f3gl_get_line()\f1 needs to call \f3read()\f1 or +\f3select()\f1 to wait for input from the user, it first +calls the POSIX \f3sigsetjmp()\f1 function, being sure to +specify a non-zero value for its \f3savesigs\f1 argument. +The reason for the latter argument will become clear +shortly. + +If \f3sigsetjmp()\f1 returns zero, \f3gl_get_line()\f1 then +does the following. + +.sp +.nf +a. It uses the POSIX \f3sigaction()\f1 function to register + a temporary signal handler to all of the signals that it + is configured to catch. This signal handler does two + things. + + 1. It records the number of the signal that was received + in a file-scope variable. + + 2. It then calls the POSIX \f3siglongjmp()\f1 + function using the buffer that was passed to + \f3sigsetjmp()\f1 for its first argument, and + a non-zero value for its second argument. + + When this signal handler is registered, the \f3sa_mask\f1 + member of the \f3struct sigaction act\f1 argument of the + call to \f3sigaction()\f1 is configured to contain all of + the signals that \f3gl_get_line()\f1 is catching. This + ensures that only one signal will be caught at once by + our signal handler, which in turn ensures that multiple + instances of our signal handler don't tread on each + other's toes. + +b. Now that the signal handler has been set up, + \f3gl_get_line()\f1 unblocks all of the signals that it + is configured to catch. + +c. It then calls the \f3read()\f1 or \f3select()\f1 system + calls to wait for keyboard input. + +d. If this system call returns (ie. no signal is received), + \f3gl_get_line()\f1 blocks delivery of the signals of + interest again. + +e. It then reinstates the signal handlers that were + displaced by the one that was just installed. +.fi +.sp + +Alternatively, if \f3sigsetjmp()\f1 returns non-zero, this +means that one of the signals being trapped was caught while +the above steps were executing. When this happens, +\f3gl_get_line()\f1 does the following. + +First, note that when a call to \f3siglongjmp()\f1 causes +\f3sigsetjmp()\f1 to return, provided that the +\f3savesigs\f1 argument of \f3sigsetjmp()\f1 was non-zero, +as specified above, the signal process mask is restored to +how it was when \f3sigsetjmp()\f1 was called. This is the +important difference between \f3sigsetjmp()\f1 and the older +problematic \f3setjmp()\f1, and is the essential ingredient +that makes it possible to avoid signal handling race +conditions. Because of this we are guaranteed that all of +the signals that we blocked before calling \f3sigsetjmp()\f1 +are blocked again as soon as any signal is caught. The +following statements, which are then executed, are thus +guaranteed to be executed without any further signals being +caught. + +1. If so instructed by the \f3gl_get_line()\f1 configuration + attributes of the signal that was caught, + \f3gl_get_line()\f1 restores the terminal attributes to + the state that they had when \f3gl_get_line()\f1 was + called. This is particularly important for signals that + suspend or terminate the process, since otherwise the + terminal would be left in an unusable state. + +2. It then reinstates the application's signal handlers. + +3. Then it uses the C standard-library \f3raise()\f1 + function to re-send the application the signal that + was caught. + +3. Next it unblocks delivery of the signal that we just + sent. This results in the signal that was just sent + via \f3raise()\f1, being caught by the application's + original signal handler, which can now handle it as it + sees fit. + +4. If the signal handler returns (ie. it doesn't terminate + the process), \f3gl_get_line()\f1 blocks delivery of the + above signal again. + +5. It then undoes any actions performed in the first of the + above steps, and redisplays the line, if the signal + configuration calls for this. + +6. \f3gl_get_line()\f1 then either resumes trying to + read a character, or aborts, depending on the + configuration of the signal that was caught. + +What the above steps do in essence is to take asynchronously +delivered signals and handle them synchronously, one at a +time, at a point in the code where \f3gl_get_line()\f1 has +complete control over its environment. + +.SH THE TERMINAL SIZE + +On most systems the combination of the \f3TIOCGWINSZ\f1 ioctl and the +\f3SIGWINCH\f1 signal is used to maintain an accurate idea of the +terminal size. The terminal size is newly queried every time that +\f3gl_get_line()\f1 is called and whenever a \f3SIGWINCH\f1 signal is +received. +.sp +On the few systems where this mechanism isn't available, at +startup \f3new_GetLine()\f1 first looks for the \f3LINES\f1 +and \f3COLUMNS\f1 environment variables. If these aren't +found, or they contain unusable values, then if a terminal +information database like terminfo or termcap is available, +the default size of the terminal is looked up in this +database. If this too fails to provide the terminal size, a +default size of 80 columns by 24 lines is used. +.sp +Even on systems that do support \f3ioctl(TIOCGWINSZ)\f1, if the +terminal is on the other end of a serial line, the terminal driver +generally has no way of detecting when a resize occurs or of querying +what the current size is. In such cases no \f3SIGWINCH\f1 is sent to +the process, and the dimensions returned by \f3ioctl(TIOCGWINSZ)\f1 +aren't correct. The only way to handle such instances is to provide a +way for the user to enter a command that tells the remote system what +the new size is. This command would then call the +\f3gl_set_term_size()\f1 function to tell \f3gl_get_line()\f1 about +the change in size. + +.sp +.nf + int gl_set_term_size(GetLine *gl, int ncolumn, int nline); +.fi +.sp + +The \f3ncolumn\f1 and \f3nline\f1 arguments are used to specify the +new dimensions of the terminal, and must not be less than 1. On +systems that do support \f3ioctl(TIOCGWINSZ)\f1, this function first +calls \f3ioctl(TIOCSWINSZ)\f1 to tell the terminal driver about the +change in size. In non-blocking server-I/O mode, if a line is +currently being input, the input line is then redrawn to accomodate +the changed size. Finally the new values are recorded in \f3gl\f1 for +future use by \f3gl_get_line()\f1. +.sp +The \f3gl_terminal_size()\f1 function allows you to query +the current size of the terminal, and install an alternate +fallback size for cases where the size isn't available. +Beware that the terminal size won't be available if reading +from a pipe or a file, so the default values can be +important even on systems that do support ways of finding +out the terminal size. +.sp +.nf + typedef struct { + int nline; /* The terminal has nline lines */ + int ncolumn; /* The terminal has ncolumn columns */ + } GlTerminalSize; + + GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); +.fi +.sp +This function first updates \f3gl_get_line()\f1's fallback terminal +dimensions, then records its findings in the return value. +.sp +The \f3def_ncolumn\f1 and \f3def_nline\f1 specify the +default number of terminal columns and lines to use if the +terminal size can't be determined via \f3ioctl(TIOCGWINSZ)\f1 or +environment variables. + +.SH HIDING WHAT YOU TYPE + +When entering sensitive information, such as passwords, it is best not +to have the text that you are entering echoed on the terminal. +Furthermore, such text should not be recorded in the history list, +since somebody finding your terminal unattended could then recall it, +or somebody snooping through your directories could see it in your +history file. With this in mind, the \f3gl_echo_mode()\f1 +function allows you to toggle on and off the display and archival of +any text that is subsequently entered in calls to \f3gl_get_line()\f1. + +.sp +.nf + int gl_echo_mode(GetLine *gl, int enable); +.fi +.sp + +The \f3enable\f1 argument specifies whether entered text +should be visible or not. If it is \f30\f1, then +subsequently entered lines will not be visible on the +terminal, and will not be recorded in the history list. If +it is \f31\f1, then subsequent input lines will be displayed +as they are entered, and provided that history hasn't been +turned off via a call to \f3gl_toggle_history()\f1, then +they will also be archived in the history list. Finally, if +the \f3enable\f1 argument is \f3-1\f1, then the echoing mode +is left unchanged, which allows you to non-destructively +query the current setting via the return value. In all +cases, the return value of the function is \f30\f1 if +echoing was disabled before the function was called, and +\f31\f1 if it was enabled. +.sp +When echoing is turned off, note that although tab +completion will invisibly complete your prefix as far as +possible, ambiguous completions will not be displayed. + +.SH SINGLE CHARACTER QUERIES + +Using \f3gl_get_line()\f1 to query the user for a single character +reply, is inconvenient for the user, since they must hit the enter or +return key before the character that they typed is returned to the +program. Thus the \f3gl_query_char()\f1 function has been provided for +single character queries like this. + +.sp +.nf + int gl_query_char(GetLine *gl, const char *prompt, + char defchar); +.fi +.sp + +This function displays the specified prompt at the start of a new +line, and waits for the user to type a character. When the user types +a character, \f3gl_query_char()\f1 displays it to the right of the +prompt, starts a newline, then returns the character to the calling +program. The return value of the function is the character that was +typed. If the read had to be aborted for some reason, \f3EOF\f1 is +returned instead. In the latter case, the application can call the +previously documented \f3gl_return_status()\f1, to find out what went +wrong. This could, for example, have been the reception of a signal, +or the optional inactivity timer going off. + +If the user simply hits enter, the value of the \f3defchar\f1 argument +is substituted. This means that when the user hits either newline or +return, the character specified in \f3defchar\f1, is displayed after +the prompt, as though the user had typed it, as well as being returned +to the calling application. If such a replacement is not important, +simply pass \f3'\n'\f1 as the value of \f3defchar\f1. + +If the entered character is an unprintable character, it is displayed +symbolically. For example, control-A is displayed as ^A, and +characters beyond 127 are displayed in octal, preceded by a +backslash. + +As with \f3gl_get_line()\f1, echoing of the entered character can be +disabled using the \f3gl_echo_mode()\f1 function. + +If the calling process is suspended while waiting for the user to type +their response, the cursor is moved to the line following the prompt +line, then when the process resumes, the prompt is redisplayed, and +\f3gl_query_char()\f1 resumes waiting for the user to type a +character. + +Note that in non-blocking server mode, (see +gl_io_mode(@FUNC_MANEXT@)), if an incomplete input line is in the +process of being read when \f3gl_query_char()\f1 is called, the +partial input line is discarded, and erased from the terminal, before +the new prompt is displayed. The next call to \f3gl_get_line()\f1 will +thus start editing a new line. + +.SH READING RAW CHARACTERS + +Whereas the \f3gl_query_char()\f1 function visibly prompts the user +for a character, and displays what they typed, the +\f3gl_read_char()\f1 function reads a signal character from the user, +without writing anything to the terminal, or perturbing any +incompletely entered input line. This means that it can be called not +only from between calls to \f3gl_get_line()\f1, but also from callback +functions that the application has registered to be called by +\f3gl_get_line()\f1. + +.sp +.nf + int gl_read_char(GetLine *gl); +.fi +.sp + +On success, the return value of \f3gl_read_char()\f1 is the character +that was read. On failure, \f3EOF\f1 is returned, and the +\f3gl_return_status()\f1 function can be called to find out what went +wrong. Possibilities include the optional inactivity timer going off, +the receipt of a signal that is configured to abort gl_get_line(), or +terminal I/O blocking, when in non-blocking server-I/O mode. + +Beware that certain keyboard keys, such as function keys, and cursor +keys, usually generate at least 3 characters each, so a single call to +\f3gl_read_char()\f1 won't be enough to identify such keystrokes. + +.SH CLEARING THE TERMINAL + +The calling program can clear the terminal by calling +\f3gl_erase_terminal()\f1. In non-blocking server-I/O mode, this +function also arranges for the current input line to be redrawn from +scratch when \f3gl_get_line()\f1 is next called. + +.sp +.nf + int gl_erase_terminal(GetLine *gl); +.fi +.sp + +.SH DISPLAYING TEXT DYNAMICALLY + +Between calls to \f3gl_get_line()\f1, the \f3gl_display_text()\f1 +function provides a convenient way to display paragraphs of text, +left-justified and split over one or more terminal lines according to +the constraints of the current width of the terminal. Examples of the +use of this function may be found in the demo programs, where it is +used to display introductions. In those examples the advanced use of +optional prefixes, suffixes and filled lines to draw a box around the +text is also illustrated. + +.sp +.nf + int gl_display_text(GetLine *gl, int indentation, + const char *prefix, + const char *suffix, int fill_char, + int def_width, int start, + const char *string); +.fi +.sp +If \f3gl\f1 isn't currently connected to a terminal, for example if +the output of a program that uses \f3gl_get_line()\f1 is being piped +to another program or redirected to a file, then the value of the +\f3def_width\f1 parameter is used as the terminal width. + +The \f3indentation\f1 argument specifies the number of characters to +use to indent each line of ouput. The \f3fill_char\f1 argument +specifies the character that will be used to perform this indentation. + +The \f3prefix\f1 argument can either be \f3NULL\f1, or be a string to +place at the beginning of each new line (after any indentation). +Similarly, the \f3suffix\f1 argument can either be \f3NULL\f1, or be a +string to place at the end of each line. The suffix is placed flush +against the right edge of the terminal, and any space between its +first character and the last word on that line is filled with the +character specified via the \f3fill_char\f1 argument. Normally the +fill-character is a space. + +The \f3start\f1 argument tells \f3gl_display_text()\f1 how many +characters have already been written to the current terminal line, and +thus tells it the starting column index of the cursor. Since the +return value of \f3gl_display_text()\f1 is the ending column index of +the cursor, by passing the return value of one call to the \f3start\f1 +argument of the next call, a paragraph that is broken between more +than one string can be composed by calling \f3gl_display_text()\f1 for +each successive portion of the paragraph. Note that literal newline +characters are necessary at the end of each paragraph to force a new +line to be started. + +On error, \f3gl_display_text()\f1 returns -1. + +.SH CALLBACK FUNCTION FACILITIES + +Unless otherwise stated, callback functions, such as tab +completion callbacks and event callbacks should not call any +functions in this module. The following functions, however, +are designed specifically to be used by callback functions. +.sp +Calling the \f3gl_replace_prompt()\f1 function from a +callback tells \f3gl_get_line()\f1 to display a different +prompt when the callback returns. Except in non-blocking +server mode, it has no effect if used between calls to +\f3gl_get_line()\f1. In non-blocking server mode (see the +\f3gl_io_mode(@FUNC_MANEXT@)\f1 man page, when used between two calls to +\f3gl_get_line()\f1 that are operating on the same input +line, the current input line will be re-drawn with the new +prompt on the following call to \f3gl_get_line()\f1. + +.sp +.nf + void gl_replace_prompt(GetLine *gl, const char *prompt); +.fi +.sp + +.SH INTERNATIONAL CHARACTER SETS + +Since libtecla version 1.4.0, \f3gl_get_line()\f1 has been 8-bit +clean. This means that all 8-bit characters that are printable in the +user's current locale are now displayed verbatim and included in the +returned input line. Assuming that the calling program correctly +contains a call like the following, +.sp +.nf + setlocale(LC_CTYPE, ""); +.fi +.sp +then the current locale is determined by the first of the environment +variables \f3LC_CTYPE\f1, \f3LC_ALL\f1, and \f3LANG\f1, that is found +to contain a valid locale name. If none of these variables are +defined, or the program neglects to call setlocale, then the default +\f3C\f1 locale is used, which is US 7-bit ASCII. On most unix-like +platforms, you can get a list of valid locales by typing the command: +.sp +.nf + locale -a +.fi +.sp +at the shell prompt. Further documentation on how the user can make use +of this to enter international characters can be found in the +\f3tecla(@MISC_MANEXT@)\f1 man page. + +.SH THREAD SAFETY + +In a multi-threaded program, you should use the libtecla_r.a version +of the library. This uses reentrant versions of system functions, +where available. Unfortunately neither terminfo nor termcap were +designed to be reentrant, so you can't safely use the functions of the +getline module in multiple threads (you can use the separate +file-expansion and word-completion modules in multiple threads, see +the corresponding man pages for details). However due to the use of +POSIX reentrant functions for looking up home directories etc, it is +safe to use this module from a single thread of a multi-threaded +program, provided that your other threads don't use any termcap or +terminfo functions. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +~/.teclarc - The personal tecla customization file. +.fi + +.SH SEE ALSO +.nf +libtecla(@LIBR_MANEXT@), gl_io_mode(@FUNC_MANEXT@), tecla(@MISC_MANEXT@), ef_expand_file(@FUNC_MANEXT@), +cpl_complete_word(@FUNC_MANEXT@), pca_lookup_file(@FUNC_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/func/gl_group_history.in b/libtecla-1.6.3/man/func/gl_group_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_group_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_handle_signal.in b/libtecla-1.6.3/man/func/gl_handle_signal.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_handle_signal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_ignore_signal.in b/libtecla-1.6.3/man/func/gl_ignore_signal.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_ignore_signal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_inactivity_timeout.in b/libtecla-1.6.3/man/func/gl_inactivity_timeout.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_inactivity_timeout.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_io_mode.in b/libtecla-1.6.3/man/func/gl_io_mode.in new file mode 100644 index 0000000..0bcca8b --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_io_mode.in @@ -0,0 +1,571 @@ +.\" Copyright (c) 2002, 2003, 2004, 2012 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. +.TH gl_io_mode @FUNC_MANEXT@ +.SH NAME + gl_io_mode, gl_raw_io, gl_normal_io, gl_tty_signals, gl_abandon_line, + gl_handle_signal, gl_pending_io \- How to use gl_get_line() from an external event loop. +.SH SYNOPSIS +.nf +#include <libtecla.h> + +int gl_io_mode(GetLine *gl, GlIOMode mode); + +int gl_raw_io(GetLine *gl); + +int gl_normal_io(GetLine *gl); + +int gl_tty_signals(void (*term_handler)(int), + void (*susp_handler)(int), + void (*cont_handler)(int), + void (*size_handler)(int)); + +void gl_abandon_line(GetLine *gl); + +void gl_handle_signal(int signo, GetLine *gl, int ngl); + +GlPendingIO gl_pending_io(GetLine *gl); + +.fi + +.SH DESCRIPTION + +The \f3gl_get_line()\f1 function, which is documented separately in +the \f3gl_get_line(@FUNC_MANEXT@)\f1 man page, supports two different I/O modes. +These are selected by calling the \f3gl_io_mode()\f1 function. + +.sp +.nf + int gl_io_mode(GetLine *gl, GlIOMode mode); +.fi +.sp + +The \f3mode\f1 argument of this function specifies the new I/O mode, +and must be one of the following. + +.sp +.nf + GL_NORMAL_MODE - Select the normal blocking-I/O mode. + In this mode \f3gl_get_line()\f1 + doesn't return until either an error + occurs of the user finishes entering a + new line. This mode is the focus of + the \f3gl_get_line(@FUNC_MANEXT@)\f1 man page. + + GL_SERVER_MODE - Select non-blocking server I/O mode. + In this mode, since non-blocking + terminal I/O is used, the entry of + each new input line typically requires + many calls to \f3gl_get_line()\f1 from + an external I/O-driven event loop. + This mode is the focus of this man + page. +.fi +.sp + +Newly created \f3GetLine\f1 objects start in normal I/O +mode, so to switch to non-blocking server mode requires an +initial call to \f3gl_io_mode()\f1. + +.SH SERVER I/O MODE + +In non-blocking server I/O mode, the application is required +to have an event loop which calls \f3gl_get_line()\f1 +whenever the terminal file descriptor can do the type I/O +that \f3gl_get_line()\f1 is waiting for. To determine which +type of I/O \f3gl_get_line()\f1 is waiting for, the +application calls the \f3gl_pending_io()\f1 function. + +.sp +.nf + GlPendingIO gl_pending_io(GetLine *gl); +.fi +.sp + +The return value of this function is one of the following two +enumerated values. + +.sp +.nf + GLP_READ - gl_get_line() is waiting to write a + character to the terminal. + + GLP_WRITE - gl_get_line() is waiting to read a + character from the keyboad. +.fi +.sp + +If the application is using either the \f3select()\f1 or \f3poll()\f1 +system calls to watch for I/O on a group of file descriptors, then it +should call the \f3gl_pending_io()\f1 function before each call to +these functions to see which direction of I/O it should tell them to +watch for, and configure their arguments accordingly. In the case of +the \f3select()\f1 system call, this means using the \f3FD_SET()\f1 +macro to add the terminal file descriptor either to the set of file +descriptors to be watched for readability, or the set to be watched +for writability. + +As in normal I/O mode, the return value of \f3gl_get_line()\f1 is +either a pointer to a completed input line, or \f3NULL\f1. However, +whereas in normal I/O mode a \f3NULL\f1 return value always means that +an error occurred, in non-blocking server mode, \f3NULL\f1 is also +returned when \f3gl_get_line()\f1 can't read or write to the terminal +without blocking. Thus in non-blocking server mode, in order to +determine when a \f3NULL\f1 return value signifies that an error +occurred or not, it is necessary to call the \f3gl_return_status()\f1 +function. If this function returns the enumerated value, +\f3GLR_BLOCKED\f1, as documented in the \f3gl_get_line(@FUNC_MANEXT@)\f1 man page, +this means that \f3gl_get_line()\f1 is waiting for I/O, and no error +has occurred. + +When \f3gl_get_line()\f1 returns \f3NULL\f1 and +\f3gl_return_status()\f1 indicates that this is due to blocked +terminal I/O, the application should call \f3gl_get_line()\f1 again +when the type of I/O reported by \f3gl_pending_io()\f1 becomes +possible. The \f3prompt\f1, \f3start_line\f1 and \f3start_pos\f1 +arguments of \f3gl_get_line()\f1 will be ignored on these calls. If +you need to change the prompt of the line that is currently being +edited, then you can call the \f3gl_replace_prompt()\f1 function +(documented in the \f3gl_get_line(@FUNC_MANEXT@) man page) between calls to +\f3gl_get_line()\f1. + +.SH GIVING UP THE TERMINAL + +A complication that is unique to non-blocking server mode is that it +requires that the terminal be left in raw mode between calls to +\f3gl_get_line()\f1. If this weren't the case, the external event loop +wouldn't be able to detect individual key-presses, and the basic line +editing implemented by the terminal driver would clash with the +editing provided by \f3gl_get_line()\f1. What this means is that any +time that the terminal needs to be used for other things than entering +a new input line with \f3gl_get_line()\f1, it needs to be restored to +a usable state. In particular, whenever the process is suspended or +terminated, the terminal must be returned to a normal state. If this +isn't done, then depending on the characteristics of the shell that +was used to invoke the program, the user may end up with a hung +terminal. To this end, the \f3gl_normal_io()\f1 function is provided +for switching the terminal back to the state that it was in when raw +mode was last established. + +.sp +.nf + int gl_normal_io(GetLine *gl); +.fi +.sp + +What this function does is first flush any pending output to the +terminal, then move the cursor to the start of the terminal line which +follows the end of the incompletely entered input line. At this point +it is safe to suspend or terminate the process, and it is safe for the +application to read and write to the terminal. To resume entry of the +input line, the application should call the \f3gl_raw_io()\f1 +function. + +.sp +.nf + int gl_raw_io(GetLine *gl); +.fi +.sp + +This function starts a new line, redisplays the partially completed +input line (if any), restores the cursor position within this line to +where it was when \f3gl_normal_io()\f1 was called, then switches back +to raw, non-blocking terminal mode ready to continue entry of the +input line when \f3gl_get_line()\f1 is next called. + +Note that in non-blocking server mode, if \f3gl_get_line()\f1 is +called after a call to \f3gl_normal_io()\f1, without an intervening +call to \f3gl_raw_io()\f1, \f3gl_get_line()\f1 will call +\f3gl_raw_mode()\f1 itself, and the terminal will remain in this mode +when \f3gl_get_line()\f1 returns. + +.SH SIGNAL HANDLING + +In the previous section it was pointed out that in non-blocking server +mode, the terminal must be restored to a sane state whenever a signal +is received that either suspends or terminates the process. In normal +I/O mode, this is done for you by \f3gl_get_line()\f1, but in +non-blocking server mode, since the terminal is left in raw mode +between calls to \f3gl_get_line()\f1, this signal handling has to be +done by the application. Since there are many signals that can suspend +or terminate a process, as well as other signals that are important to +\f3gl_get_line()\f1, such as the \f3SIGWINCH\f1 signal, which tells it +when the terminal size has changed, the \f3gl_tty_signals()\f1 +function is provided for installing signal handlers for all pertinent +signals. + +.sp +.nf + int gl_tty_signals(void (*term_handler)(int), + void (*susp_handler)(int), + void (*cont_handler)(int), + void (*size_handler)(int)); +.fi +.sp + +What this does is use \f3gl_get_line()\f1's internal list of signals +to assign specified signal handlers to groups of signals. The +arguments of this function are as follows. + +.sp +.nf + term_handler - This is the signal handler that is to be + used to trap signals that by default + terminate any process that receives + them (eg. SIGINT or SIGTERM). + + susp_handler - This is the signal handler that is to be + used to trap signals that by default + suspend any process that receives them, + (eg. SIGTSTP or SIGTTOU). + + cont_handler - This is the signal handler that is to be + used to trap signals that are usually + sent when a process resumes after being + suspended (usually SIGCONT). Beware that there is + nothing to stop a user from sending one of these + signals at other times. + + size_handler - This signal handler is used to trap + signals that are sent to processes when + their controlling terminals are resized + by the user (eg. SIGWINCH). +.fi +.sp + +These arguments can all be the same, if so desired, and you can +specify \f3SIG_IGN\f1 (ignore this signal) or \f3SIG_DFL\f1 (use the +system-provided default signal handler) instead of a function where +pertinent. In particular, it is rarely useful to trap \f3SIGCONT\f1, +so the \f3cont_handler\f1 argument will usually be \f3SIG_DFL\f1 or +\f3SIG_IGN\f1. + +The \f3gl_tty_signals()\f1 function uses the POSIX \f3sigaction()\f1 +function to install these signal handlers, and it is careful to use +the \f3sa_mask\f1 member of each sigaction structure to ensure that +only one of these signals is ever delivered at a time. This guards +against different instances of these signal handlers from +simultaneously trying to write to common global data, such as a shared +\f3sigsetjmp()\f1 buffer or a signal-received flag. + +The signal handlers that are installed by this function, should call +the \f3gl_handle_signal(). + +.sp +.nf + void gl_handle_signal(int signo, GetLine *gl, int ngl); +.fi +.sp + +The \f3signo\f1 argument tells this function which signal it is being +asked to respond to, and the \f3gl\f1 argument should be a pointer to +the first element of an array of \f3ngl\f1 \f3GetLine\f1 objects. If +your application only has one of these objects, just pass its pointer +as the \f3gl\f1 argument and specify \f3ngl\f1 as \f31\f1. + +Depending on the signal that is being handled, this function does +different things. + +.SS Terminal resize signals (SIGWINCH) + +If the signal indicates that the terminal was resized, then it +arranges for the next call to \f3gl_get_line()\f1 to ask the terminal +for its new size and redraw the input line accordingly. In order that +\f3gl_get_line()\f1 be called as soon as possible to do this, +\f3gl_handle_signal()\f1 also arranges that the next call to +\f3gl_pending_io()\f1 will return \f3GLP_WRITE\f1. Thus if the +application waits for I/O in \f3select()\f1 or \f3poll()\f1, then the +application needs to ensure that these functions will be reliably +aborted when a signal is caught and handled by the application. More +on this below. + +.SH Process termination signals. + +If the signal that was caught is one of those that by default +terminates any process that receives it, then \f3gl_handle_signal()\f1 +does the following steps. + +1. First it blocks the delivery of all signals that can be + blocked (ie. \f3SIGKILL\f1 and \f3SIGSTOP\f1 can't be blocked) + +2. Next it calls \f3gl_normal_io()\f1 for each of the \f3ngl\f1 + \f3GetLine\f1 objects. Note that this does nothing to any of the + \f3GetLine\f1 objects that aren't currently in raw mode. + +3. Next it sets the signal handler of the signal to its default, + process-termination disposition. + +4. Next it re-sends the process the signal that was caught. + +5. Finally it unblocks delivery of this signal, which + results in the process being terminated. + +.SH Process suspension signals. + +If the default disposition of the signal is to suspend the process, +the same steps are executed as for process termination signals, except +that when the process is later resumed, \f3gl_handle_signal()\f1 +continues, and does the following steps. + +6. It re-blocks delivery of the signal. + +7. It reinstates the signal handler of the signal to the one + that was displaced when its default disposition was substituted. + +8. For any of the \f3GetLine\f1 objects that were in raw mode when + \f3gl_handle_signal()\f1 was called, \f3gl_handle_signal()\f1 then + calls \f3gl_raw_io()\f1, to resume entry of the input lines on + those terminals. + +9. Finally, it restores the signal process mask to how it + was when \f3gl_handle_signal()\f1 was called. + +Note that the process is suspended or terminated using the original +signal that was caught, rather than using the uncatchable +\f3SIGSTOP\f1 and \f3SIGKILL\f1 signals. This is important, because +when a process is suspended or terminated, the parent of the process +may wish to use the status value returned by the \f3wait()\f1 system +call to figure out which signal was responsible. In particular, most +shells use this information to print a corresponding message to the +terminal. Users would be rightly confused if when their process +received a \f3SIGPIPE\f1 signal, the program responded by sending +itself a \f3SIGKILL\f1 signal, and the shell then printed out the +provocative statement, "Killed!". + +.SH INTERRUPTING THE EVENT LOOP + +If a signal is caught and handled when the application's event loop is +waiting in \f3select()\f1 or \f3poll()\f1, these functions will be +aborted with \f3errno\f1 set to \f3EINTR\f1. When this happens the +event loop should call \f3gl_pending_io()\f1, before calling +\f3select()\f1 or \f3poll()\f1 again. It should then arrange for +\f3select()\f1 or \f3poll()\f1 to wait for the type of I/O that this +reports. This is necessary, because any signal handler which calls +\f3gl_handle_signal()\f1, will frequently change the type of I/O that +\f3gl_get_line()\f1 is waiting for. + +Unfortunately, if a signal arrives between the statements which +configure the arguments of \f3select()\f1 or \f3poll()\f1 and the +calls to these functions, then the signal will not be seen by these +functions, which will then not be aborted. If these functions are +waiting for keyboard input from the user when the signal is received, +and the signal handler arranges to redraw the input line to accomodate +a terminal resize or the resumption of the process, then this +redisplay will be end up being delayed until the user hits the next +key. Apart from puzzling the user, this clearly isn't a serious +problem. However there is a way, albeit complicated, to completely +avoid this race condition. The following steps illustrate this. + +1. Block all of the signals that \f3gl_get_line()\f1 catches, + by passing the signal set returned by \f3gl_list_signals()\f1 to + \f3sigprocmask()\f1. + +2. Call \f3gl_pending_io()\f1 and set up the arguments of + \f3select()\f1 or \f3poll()\f1 accordingly. + +3. Call \f3sigsetjmp()\f1 with a non-zero \f3savesigs\f1 argument. + +4. Initially this \f3sigsetjmp()\f1 statement will return zero, + indicating that control isn't resuming there after a matching + call to \f3siglongjmp()\f1. + +5. Replace all of the handlers of the signals that \f3gl_get_line()\f1 + is configured to catch, with a signal handler that first records + the number of the signal that was caught, in a file-scope variable, + then calls \f3siglongjmp()\f1 with a non-zero value argument, to + return execution to the above \f3sigsetjmp()\f1 + statement. Registering these signal handlers can conveniently be + done using the \f3gl_tty_signals()\f1 function. + +6. Set the file-scope variable that the above signal handler uses to + record any signal that is caught to -1, so that we can check + whether a signal was caught by seeing if it contains a valid signal + number. + +7. Now unblock the signals that were blocked in step 1. Any signal + that was received by the process in between step 1 and now will + now be delivered, and trigger our signal handler, as will any + signal that is received until we block these signals again. + +8. Now call \f3select()\f1 or \f3poll()\f1. + +9. When \f3select()\f1 returns, again block the signals that were + unblocked in step 7. + +If a signal is arrived any time during the above steps, our signal +handler will be triggered and cause control to return to the +\f3sigsetjmp()\f1 statement, where this time, \f3sigsetjmp()\f1 will +return non-zero, indicating that a signal was caught. When this +happens we simply skip the above block of statements, and continue +with the following statements, which are executed regardless of +whether or not a signal is caught. Note that when \f3sigsetjmp()\f1 +returns, regardless of why it returned, the process signal mask is +returned to how it was when \f3sigsetjmp()\f1 was called. Thus the +following statements are always executed with all of our signals +blocked. + +9. Reinstate the signal handlers that were displaced in step 5. + +10. Check wether a signal was caught, by checking the file-scope + variable that the signal handler records signal numbers in. + +11. If a signal was caught, send this signal to the application + again, and unblock just this signal, so that it invokes the + signal handler which we just reinstated in step 10. + +12. Unblock all of the signals that were blocked in step 7. + +Since this is complicated, note that \f3demo3.c\f1 includes a working +example of how to do this. The method used there however, is more +general than the above. What it provides is a wrapper function around +\f3select()\f1 which encompasses steps 3 to 11. In this wrapper, +rather than use \f3gl_list_signals()\f1 to figure out the signals to +block, and and \f3gl_tty_signals()\f1 to assign and revert signal +handlers, one of its arguments is a \f3sigset_t\f1 which specifies +which signals to block and assign signal handlers to. This function +thus doesn't depend on \f3gl_get_line()\f1 and can thus be used in +other situations where race-condition-free signal handling is +required. + +.SH SIGNALS CAUGHT BY GL_GET_LINE + +Since the application is expected to handle signals in non-blocking +server mode, \f3gl_get_line()\f1 doesn't attempt to duplicate this +when it is being called. If one of the signals that it is configured +to catch is sent to the application while \f3gl_get_line()\f1 is being +called, \f3gl_get_line()\f1 reinstates the caller's signal handlers, +then just before returning, re-sends the signal to the process to let +the application's signal handler handle it. If the process isn't +terminated by this signal, \f3gl_get_line()\f1 returns \f3NULL\f1, and +a following call to \f3gl_return_status()\f1 returns the enumerated +value \f3GLR_SIGNAL\f1. + +.SH ABORTING LINE INPUT + +Often, rather than letting it terminate the process, applications +respond to the SIGINT user-interrupt signal by aborting the current +input line. The way to do this in non-blocking server-I/O mode is to +not call \f3gl_handle_signal()\f1 when this signal is caught, but +instead to call the \f3gl_abandon_line()\f1. + +.sp +.nf + void gl_abandon_line(GetLine *gl); +.fi +.sp + +This function arranges that when \f3gl_get_line()\f1 is next called, +it first flushes any pending output to the terminal, then discardes +the current input line, outputs a new prompt on the next line, and +finally starts accepting input of a new input line from the user. + +.SH SIGNAL SAFE FUNCTIONS + +Provided that certain rules are followed, the following functions can +have been written to be safely callable from signal handlers. Other +functions in this library should not be called from signal handlers. + +.sp +.nf + gl_normal_io() + gl_raw_io() + gl_handle_signal() + gl_abandon_line() +.fi +.sp + +In order for this to be true, all signal handlers that call these +functions must be registered in such a way that only one instance of +any one of them can be running at one time. The way to do this is to +use the POSIX \f3sigaction()\f1 function to register all signal +handlers, and when doing this, use the \f3sa_mask\f1 member of the +corresponding sigaction structure, to indicate that all of the signals +who's handlers invoke the above functions, should be blocked when the +current signal is being handled. This prevents two signal handlers +from operating on a \f3GetLine\f1 object at the same time. + +To prevent signal handlers from accessing a \f3GetLine\f1 object while +\f3gl_get_line()\f1 or any of its associated public functions are +operating on it, all public functions associated with +\f3gl_get_line()\f1, including \f3gl_get_line()\f1 itself, temporarily +block the delivery of signals when they are accessing \f3GetLine\f1 +objects. Beware that the only signals that they block are the signals +that \f3gl_get_line()\f1 is currently configured to catch, so be sure +that if you call any of the above functions from signal handlers, that +the signals that these handlers are assigned to are configured to be +caught by \f3gl_get_line()\f1 (see \f3gl_trap_signal()\f1). + +.SH USING TIMEOUTS TO POLL + +If instead of using \f3select()\f1 or \f3poll()\f1 to wait for I/O, +your application just needs to get out of \f3gl_get_line()\f1 +periodically to briefly do something else before returning to accept +input from the user, this can be done in non-blocking server mode by +using the \f3gl_inactivity_timeout()\f1 function (see +\f3gl_get_line(@FUNC_MANEXT@)\f1), to specify that a callback function that +returns \f3GLTO_CONTINUE\f1 should be called whenever +\f3gl_get_line()\f1 has been waiting for I/O for more than a specified +amount of time. + +When this callback is triggered, \f3gl_get_line()\f1 will return +\f3NULL\f1, and a following call to \f3gl_return_status()\f1 will +return \f3GLR_BLOCKED\f1. + +Beware that \f3gl_get_line()\f1 won't return until the user +hasn't typed a key for the specified interval, so if the +interval is long, and the user keeps typing, +\f3gl_get_line()\f1 may not return for a while. In other +words there is no guarantee that it will return in the time +specified. + +.SH THE SERVER DEMO PROGRAM + +The \f3demo3\f1 program that is distributed with the library, provides +a working example of how to use non-blocking server I/O mode in a real +program. As far as the user is concerned, this program operates +identically to the main demo program (called \f3demo\f1), except that +whereas the main demo program uses the normal blocking I/O mode, +\f3demo3\f1 using non-blocking I/O and an external event loop. The +source code can be found in \f3demo3.c\f1, and the comments therein +explain the various steps. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO + +.nf +libtecla(@LIBR_MANEXT@), gl_get_line(@FUNC_MANEXT@), tecla(@MISC_MANEXT@), ef_expand_file(@FUNC_MANEXT@), +cpl_complete_word(@FUNC_MANEXT@), pca_lookup_file(@FUNC_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/func/gl_last_signal.in b/libtecla-1.6.3/man/func/gl_last_signal.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_last_signal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_limit_history.in b/libtecla-1.6.3/man/func/gl_limit_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_limit_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_list_signals.in b/libtecla-1.6.3/man/func/gl_list_signals.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_list_signals.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_load_history.in b/libtecla-1.6.3/man/func/gl_load_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_load_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_lookup_history.in b/libtecla-1.6.3/man/func/gl_lookup_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_lookup_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_normal_io.in b/libtecla-1.6.3/man/func/gl_normal_io.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_normal_io.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_pending_io.in b/libtecla-1.6.3/man/func/gl_pending_io.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_pending_io.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_prompt_style.in b/libtecla-1.6.3/man/func/gl_prompt_style.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_prompt_style.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_query_char.in b/libtecla-1.6.3/man/func/gl_query_char.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_query_char.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_range_of_history.in b/libtecla-1.6.3/man/func/gl_range_of_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_range_of_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_raw_io.in b/libtecla-1.6.3/man/func/gl_raw_io.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_raw_io.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_read_char.in b/libtecla-1.6.3/man/func/gl_read_char.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_read_char.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_register_action.in b/libtecla-1.6.3/man/func/gl_register_action.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_register_action.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_resize_history.in b/libtecla-1.6.3/man/func/gl_resize_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_resize_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_return_status.in b/libtecla-1.6.3/man/func/gl_return_status.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_return_status.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_save_history.in b/libtecla-1.6.3/man/func/gl_save_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_save_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_set_term_size.in b/libtecla-1.6.3/man/func/gl_set_term_size.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_set_term_size.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_show_history.in b/libtecla-1.6.3/man/func/gl_show_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_show_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_size_of_history.in b/libtecla-1.6.3/man/func/gl_size_of_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_size_of_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_state_of_history.in b/libtecla-1.6.3/man/func/gl_state_of_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_state_of_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_terminal_size.in b/libtecla-1.6.3/man/func/gl_terminal_size.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_terminal_size.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_toggle_history.in b/libtecla-1.6.3/man/func/gl_toggle_history.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_toggle_history.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_trap_signal.in b/libtecla-1.6.3/man/func/gl_trap_signal.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_trap_signal.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_tty_signals.in b/libtecla-1.6.3/man/func/gl_tty_signals.in new file mode 100644 index 0000000..24798bc --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_tty_signals.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_io_mode.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/gl_watch_fd.in b/libtecla-1.6.3/man/func/gl_watch_fd.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/gl_watch_fd.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/libtecla_version.in b/libtecla-1.6.3/man/func/libtecla_version.in new file mode 100644 index 0000000..31867c4 --- /dev/null +++ b/libtecla-1.6.3/man/func/libtecla_version.in @@ -0,0 +1 @@ +.so @LIBR_MANDIR@/libtecla.@LIBR_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_CplFileConf.in b/libtecla-1.6.3/man/func/new_CplFileConf.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_CplFileConf.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_ExpandFile.in b/libtecla-1.6.3/man/func/new_ExpandFile.in new file mode 100644 index 0000000..3d0a884 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_ExpandFile.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/ef_expand_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_GetLine.in b/libtecla-1.6.3/man/func/new_GetLine.in new file mode 100644 index 0000000..6e46fc6 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_GetLine.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/gl_get_line.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_PathCache.in b/libtecla-1.6.3/man/func/new_PathCache.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_PathCache.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_PcaPathConf.in b/libtecla-1.6.3/man/func/new_PcaPathConf.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_PcaPathConf.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/new_WordCompletion.in b/libtecla-1.6.3/man/func/new_WordCompletion.in new file mode 100644 index 0000000..734f281 --- /dev/null +++ b/libtecla-1.6.3/man/func/new_WordCompletion.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/cpl_complete_word.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/pca_last_error.in b/libtecla-1.6.3/man/func/pca_last_error.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/pca_last_error.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/pca_lookup_file.in b/libtecla-1.6.3/man/func/pca_lookup_file.in new file mode 100644 index 0000000..e74114a --- /dev/null +++ b/libtecla-1.6.3/man/func/pca_lookup_file.in @@ -0,0 +1,365 @@ +.\" Copyright (c) 2001, 2002, 2003, 2004, 2012 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. +.TH pca_lookup_file @FUNC_MANEXT@ +.SH NAME +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 +.SH SYNOPSIS +.nf +#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); + +.fi + +.SH DESCRIPTION + +The \f3PathCache\f1 object is part of the tecla library (see the +libtecla(@LIBR_MANEXT@) man page). +.sp +\f3PathCache\f1 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 \f3PathCache\f1 object, whereas relative directories are scanned as +needed. Using a \f3PathCache\f1 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. +.sp +.SH AN EXAMPLE + +Under UNIX, the following example program looks up and displays the +full pathnames of each of the command names on the command line. +.sp +.nf + #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; + } +.fi +.sp +The following is an example of what this does on my laptop under +linux: +.sp +.nf + $ ./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 + $ +.fi +.sp +.SH FUNCTION DESCRIPTIONS + +In order to use the facilities of this module, you must first allocate +a \f3PathCache\f1 object by calling the \f3new_PathCache()\f1 +constructor function. +.sp +.nf + PathCache *new_PathCache(void) +.fi +.sp +This function creates the resources needed to cache and lookup files +in a list of directories. It returns \f3NULL\f1 on error. +.sp +.SH POPULATING THE CACHE +Once you have created a cache, it needs to be populated with files. +To do this, call the \f3pca_scan_path()\f1 function. +.sp +.nf + int pca_scan_path(PathCache *pc, const char *path); +.fi +.sp +Whenever this function is called, it discards the current contents of +the cache, then scans the list of directories specified in its +\f3path\f1 argument for files. The \f3path\f1 argument must be a +string containing a colon-separated list of directories, such as +\f3"/usr/bin:/home/mcs/bin:."\f1. This can include directories +specified by absolute pathnames such as \f3"/usr/bin"\f1, as well as +sub-directories specified by relative pathnames such as \f3"."\f1 or +\f3"bin"\f1. Files in the absolute directories are immediately cached +in the specified \f3PathCache\f1 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. +.sp +On success this function return \f30\f1. On error it returns \f31\f1, +and a description of the error can be obtained by calling +\f3pca_last_error(pc)\f1. +.sp +.SH LOOKING UP FILES + +Once the cache has been populated with files, you can look up the full +pathname of a file, simply by specifying its filename to +\f3pca_lookup_file()\f1. +.sp +.nf + char *pca_lookup_file(PathCache *pc, const char *name, + int name_len, int literal); +.fi +.sp +To make it possible to pass this function a filename which is actually +part of a longer string, the \f3name_len\f1 argument can be used to +specify the length of the filename at the start of the \f3name[]\f1 +argument. If you pass \f3-1\f1 for this length, the length of the +string will be determined with \f3strlen()\f1. If the \f3name[]\f1 +string might contain backslashes that escape the special meanings of +spaces and tabs within the filename, give the \f3literal\f1 argument, +the value \f30\f1. Otherwise, if backslashes should be treated as +normal characters, pass \f31\f1 for the value of the \f3literal\f1 +argument. + +.SH FILENAME COMPLETION + +Looking up the potential completions of a filename-prefix in the +filename cache, is achieved by passing the provided +\f3pca_path_completions()\f1 callback function to the +\f3cpl_complete_word()\f1 function (see the \f3cpl_complete_word(@FUNC_MANEXT@)\f1 +man page). +.sp +.nf + CPL_MATCH_FN(pca_path_completions); +.fi +.sp +This callback requires that its \f3data\f1 argument be a pointer to a +\f3PcaPathConf\f1 object. Configuration objects of this type are +allocated by calling \f3new_PcaPathConf()\f1. +.sp +.nf + PcaPathConf *new_PcaPathConf(PathCache *pc); +.fi +.sp +This function returns an object initialized with default configuration +parameters, which determine how the \f3cpl_path_completions()\f1 +callback function behaves. The functions which allow you to +individually change these parameters are discussed below. +.sp +By default, the \f3pca_path_completions()\f1 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 +\f3ppc_file_start()\f1 with the index at which the filename starts in +the input line. Passing \f3start_index=-1\f1 re-enables the default +behavior. +.sp +.nf + void ppc_file_start(PcaPathConf *ppc, int start_index); +.fi +.sp +By default, when \f3pca_path_completions()\f1 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 \f3ppc_literal_escapes()\f1 with a +non-zero value in its \f3literal\f1 argument. +.sp +.nf + void ppc_literal_escapes(PcaPathConf *ppc, int literal); +.fi +.sp +When you have finished with a \f3PcaPathConf\f1 variable, you can pass +it to the \f3del_PcaPathConf()\f1 destructor function to reclaim its +memory. +.sp +.nf + PcaPathConf *del_PcaPathConf(PcaPathConf *ppc); +.fi +.sp + +.SH BEING SELECTIVE +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 \f3PathCache\f1 +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 \f31\f1 the filename will be +reported as a match, and if it returns \f30\f1, it will be ignored. +Suitable callback functions and their prototypes should be declared +with the following macro. The \f3CplCheckFn\f1 \f3typedef\f1 is also +provided in case you wish to declare pointers to such functions. +.sp +.nf + #define CPL_CHECK_FN(fn) int (fn)(void *data, \\ + const char *pathname) + typedef CPL_CHECK_FN(CplCheckFn); +.fi +.sp +Registering one of these functions involves calling the +\f3pca_set_check_fn()\f1 function. In addition to the callback +function, passed via the \f3check_fn\f1 argument, you can pass a +pointer to anything via the \f3data\f1 argument. This pointer will be +passed on to your callback function, via its own \f3data\f1 argument, +whenever it is called, so this provides a way to pass appplication +specific data to your callback. +.sp +.nf + void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn, + void *data); +.fi +.sp +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 \f3cpl_check_exe()\f1 callback function looks at +the executable permissions of the file and the permissions of its +parent directories, and only returns \f31\f1 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 \f3PATH\f1 environment variable. The example program given +earlier in this man page provides a demonstration of this. +.sp +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. +.sp +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 \f3pca_scan_path()\f1 is called, and whenever +\f3pca_set_check_fn()\f1 is called with changed callback function or +data arguments. + +.SH ERROR HANDLING + +If \f3pca_scan_path()\f1 reports that an error occurred by returning +\f31\f1, you can obtain a terse description of the error by calling +\f3pca_last_error(pc)\f1. This returns an internal string containing +an error message. +.sp +.nf + const char *pca_last_error(PathCache *pc); +.fi +.sp + +.SH CLEANING UP + +Once you have finished using a \f3PathCache\f1 object, you can reclaim +its resources by passing it to the \f3del_PathCache()\f1 destructor +function. This takes a pointer to one of these objects, and always +returns \f3NULL\f1. +.sp +.nf + PathCache *del_PathCache(PathCache *pc); +.fi +.sp +.SH THREAD SAFETY + +In multi-threaded programs, you should use the \f3libtecla_r.a\f1 +version of the library. This uses POSIX reentrant functions where +available (hence the \f3_r\f1 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 \f3~username/\f1 +expressions, in \f3cpl_path_completions()\f1. + +Using the \f3libtecla_r.a\f1 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 \f3PathCache\f1 object. In other +words, if two threads want to do path searching, they should each call +\f3new_PathCache()\f1 to allocate their own caches. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO + +.nf +libtecla(@LIBR_MANEXT@), gl_get_line(@FUNC_MANEXT@), ef_expand_file(@FUNC_MANEXT@), +cpl_complete_word(@FUNC_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/func/pca_path_completions.in b/libtecla-1.6.3/man/func/pca_path_completions.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/pca_path_completions.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/pca_scan_path.in b/libtecla-1.6.3/man/func/pca_scan_path.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/pca_scan_path.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/pca_set_check_fn.in b/libtecla-1.6.3/man/func/pca_set_check_fn.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/pca_set_check_fn.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/ppc_file_start.in b/libtecla-1.6.3/man/func/ppc_file_start.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/ppc_file_start.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/func/ppc_literal_escapes.in b/libtecla-1.6.3/man/func/ppc_literal_escapes.in new file mode 100644 index 0000000..dbc4da7 --- /dev/null +++ b/libtecla-1.6.3/man/func/ppc_literal_escapes.in @@ -0,0 +1 @@ +.so @FUNC_MANDIR@/pca_lookup_file.@FUNC_MANEXT@ diff --git a/libtecla-1.6.3/man/libr/libtecla.in b/libtecla-1.6.3/man/libr/libtecla.in new file mode 100644 index 0000000..4c600a8 --- /dev/null +++ b/libtecla-1.6.3/man/libr/libtecla.in @@ -0,0 +1,168 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH libtecla @LIBR_MANEXT@ +.SH NAME +libtecla - An interactive command-line input library. +.SH SYNOPSIS +.nf +@CC@ ... -ltecla -lcurses +.fi + +.SH DESCRIPTION + +The \f3tecla\f1 library provides programs with interactive command +line editing facilities, similar to those of the unix \f3tcsh\f1 +shell. In addition to simple command-line editing, it supports recall +of previously entered command lines, TAB completion of file names or +other tokens, and in-line wild-card expansion of filenames. The +internal functions which perform file-name completion and wild-card +expansion are also available externally for optional use by the +calling program. +.sp +The various parts of the library are documented in the following man +pages: + +.nf + tecla(@MISC_MANEXT@) - Use level documentation of the + command-line editing facilities + provided by \f3gl_get_line()\f1. + gl_get_line(@FUNC_MANEXT@) - The interactive line-input module. + gl_io_mode(@FUNC_MANEXT@) - How to use \f3gl_get_line()\f1 in an + incremental, non-blocking fashion. + cpl_complete_word(@FUNC_MANEXT@) - The word completion module. + ef_expand_file(@FUNC_MANEXT@) - The filename expansion module. + pca_lookup_file(@FUNC_MANEXT@) - A directory-list based filename + lookup and completion module. +.fi + +In addition there is one optional application distributed +with the library: + +.nf + enhance(@PROG_MANEXT@) - Add command-line editing to third + party applications. +.fi + +.SH THREAD SAFETY + +If the library is compiled with -D_POSIX_C_SOURCE=199506L, reentrant +versions of as many functions as possible are used. This includes +using getpwuid_r() and getpwnam_r() instead of getpwuid() and +getpwnam() when looking up the home directories of specific users in +the password file (for ~user/ expansion), and readdir_r() instead of +readdir() for reading directory entries when doing filename +completion. The reentrant version of the library is usually called +libtecla_r.a instead of libtecla.a, so if only the latter is +available, it probably isn't the correct version to link with +threaded programs. + +Reentrant functions for iterating through the password file aren't +available, so when the library is compiled to be reentrant, TAB +completion of incomplete usernames in \f3~username/\f1 expressions is +disabled. This doesn't disable expansion of complete \f3~username\f1 +expressions, which can be done reentrantly, or expansion of the parts +of filenames that follow them, so this doesn't remove much +functionality. + +The terminfo functions setupterm(), tigetstr(), tigetnum() and tputs() +also aren't reentrant, but very few programs will want to interact +with multiple terminals, so this shouldn't prevent this library from +being used in threaded programs. + +.SH LIBRARY VERSION NUMBER + +The version number of the library can be queried using the following +function. +.sp +.nf + void libtecla_version(int *major, int *minor, int *micro); +.fi +.sp + +On return, this function records the three components of the libtecla +version number in \f3*major\f1, \f3*minor\f1, \f3*micro\f1. The formal +meaning of the three components is as follows. + +.sp +.nf + major - Incrementing this number implies that a change has + been made to the library's public interface, which + makes it binary incompatible with programs that + were linked with previous shared versions of the + tecla library. + + minor - This number is incremented by one whenever + additional functionality, such as new functions or + modules, are added to the library. + + micro - This is incremented whenever modifications to the + library are made which make no changes to the + public interface, but which fix bugs and/or improve + the behind-the-scenes implementation. +.fi +.sp + +.SH TRIVIA + +In Spanish, a "tecla" is the key of a keyboard. Since this library +centers on keyboard input, and given that I wrote much of the library +while working in Chile, this seemed like a suitable name. + +.SH FILES +.nf +libtecla.a - The tecla library. +libtecla.h - The tecla header file. +~/.teclarc - The tecla personal customization file. +.fi + +.SH SEE ALSO + +.nf +gl_get_line(@FUNC_MANEXT@), tecla(@MISC_MANEXT@), gl_io_mode(@FUNC_MANEXT@), ef_expand_file(@FUNC_MANEXT@), +cpl_complete_word(@FUNC_MANEXT@), pca_lookup_file(@FUNC_MANEXT@), enhance(@PROG_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) + +.SH ACKNOWLEDGMENTS + +.nf +Markus Gyger - Lots of assistance, including help with + shared libraries, configuration information, + particularly for Solaris; modifications to + support C++ compilers, improvements for ksh + users, faster cursor motion, output + buffering, and changes to make gl_get_line() + 8-bit clean. +Mike MacFaden - Suggestions, feedback and testing that led + to many of the major new functions that were + added in version 1.4.0. +Tim Eliseo - Many vi-mode bindings and fixes. +.fi diff --git a/libtecla-1.6.3/man/misc/tecla.in b/libtecla-1.6.3/man/misc/tecla.in new file mode 100644 index 0000000..567a810 --- /dev/null +++ b/libtecla-1.6.3/man/misc/tecla.in @@ -0,0 +1,1201 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH tecla @MISC_MANEXT@ +.SH NAME +tecla, teclarc \- The user interface provided by the Tecla library. +.SH DESCRIPTION + +This man page describes the command-line editing features that are +available to users of programs that read keyboard input via the Tecla +library. Users of the tcsh shell will find the default key-bindings +very familiar. Users of the bash shell will also find it quite +familiar, but with a few minor differences, most notably in how +forward and backward searches through the list of historical commands +are performed. There are two major editing modes, one with emacs-like +key-bindings and another with vi-like key-bindings. By default emacs +mode is enabled, but vi mode can alternatively be selected via the +user's configuration file. This file can also be used to change the +bindings of individual keys to suit the user's preferences. By +default, tab completion is provided. If the application hasn't +reconfigured this to complete other types of symbols, then tab +completion completes file-names. + +.SH KEY SEQUENCE NOTATION + +In the rest of this man page, and also in all Tecla configuration +files, key-sequences are expressed as follows. + +.sp +.nf +\f3^A\f1 or \f3C-a\f1 + This is a control-A, entered by pressing the control key at + the same time as the \f3A\f1 key. + +\f3\\E\f1 or \f3M-\f1 + In key-sequences, both of these notations can be entered + either by pressing the escape key, then the following key, or by + pressing the Meta key at the same time as the following key. Thus + the key sequence \f3M-p\f1 can be typed in two ways, by pressing + the escape key, followed by pressing \f3p\f1, or by pressing the + Meta key at the same time as \f3p\f1. + +\f3up\f1 + This refers to the up-arrow key. + +\f3down\f1 + This refers to the down-arrow key. + +\f3left\f1 + This refers to the left-arrow key. + +\f3right\f1 + This refers to the right-arrow key. + +\f3a\f1 + This is just a normal A key. +.fi +.sp + +.SH THE TECLA CONFIGURATION FILE + +By default, Tecla looks for a file called \f3\&.teclarc\f1 in your +home directory (ie. \f3~/.teclarc\f1). If it finds this file, it +reads it, interpreting each line as defining a new key binding or an +editing configuration option. Since the emacs keybindings are +installed by default, if you want to use the non-default vi editing +mode, the most important item to go in this file is the following +line: + +.nf + edit-mode vi +.fi + +This will re-configure the default bindings for vi-mode. The +complete set of arguments that this command accepts are: +.sp +.nf + vi - Install key-bindings like those of the vi + editor. + emacs - Install key-bindings like those of the emacs + editor. This is the default. + none - Use just the native line editing facilities + provided by the terminal driver. +.fi +.sp +To prevent the terminal bell from being rung, such as when +an unrecognized control-sequence is typed, place the +following line in the configuration file: + +.nf + nobeep +.fi + +An example of a key binding line in the configuration file is +the following. + +.nf + bind M-[2~ insert-mode +.fi + +On many keyboards, the above key sequence is generated when one +presses the \f3insert\f1 key, so with this keybinding, one can toggle +between the emacs-mode insert and overwrite modes by hitting one +key. One could also do it by typing out the above sequence of +characters one by one. As explained above, the \f3M-\f1 part of this +sequence can be typed either by pressing the escape key before the +following key, or by pressing the Meta key at the same time as the +following key. Thus if you had set the above key binding, and the +insert key on your keyboard didn't generate the above key sequence, +you could still type it in either of the following 2 ways. + +.nf + 1. Hit the escape key momentarily, then press '[', then '2', then + finally '~'. + + 2. Press the meta key at the same time as pressing the '[' key, + then press '2', then '~'. +.fi + +If you set a keybinding for a key-sequence that is already bound to a function, +the new binding overrides the old one. If in the new binding you omit the name +of the new function to bind to the key-sequence, the original binding becomes +undefined. +.sp +Starting with versions of libtecla later than 1.3.3 it is now possible +to bind keysequences that begin with a printable character. Previously +key-sequences were required to start with a control or meta character. +.sp +Note that the special keywords "up", "down", "left" and "right" refer +to the arrow keys, and are thus not treated as keysequences. So, for +example, to rebind the up and down arrow keys to use the history +search mechanism instead of the simple history recall method, you +could place the following in your configuration file: + +.nf + bind up history-search-backwards + bind down history-search-backwards +.fi +.sp +To unbind an existing binding, you can do this with the bind command +by omitting to name any action to rebind the key sequence to. For +example, by not specifying an action function, the following command +unbinds the default beginning-of-line action from the ^A key sequence: + +.nf + bind ^A +.fi + +If you create a \f3~/.teclarc\f1 configuration file, but it appears to +have no effect on the program, check the documentation of the program +to see if the author chose a different name for this file. + +.SH FILENAME AND TILDE COMPLETION + +With the default key bindings, pressing the TAB key (aka. \f3^I\f1) +results in Tecla attempting to complete the incomplete filename that +precedes the cursor. Tecla searches backwards from the cursor, looking +for the start of the filename, stopping when it hits either a space or +the start of the line. If more than one file has the specified prefix, +then Tecla completes the filename up to the point at which the +ambiguous matches start to differ, then lists the possible matches. +.sp +In addition to literally written filenames, Tecla can +complete files that start with \f3~/\f1 and \f3~user/\f1 expressions +and that contain \f3$envvar\f1 expressions. In particular, if you hit +TAB within an incomplete \f3~user\f1, expression, Tecla +will attempt to complete the username, listing any ambiguous matches. +.sp +The completion binding is implemented using the +\f3cpl_word_completions()\f1 function, which is also available +separately to users of this library. See the +\f3cpl_complete_word(@LIBR_MANEXT@)\f1 man page for more details. + +.SH FILENAME EXPANSION + +With the default key bindings, pressing \f3^X*\f1 causes Tecla to +expand the filename that precedes the cursor, replacing \f3~/\f1 and +\f3~user/\f1 expressions with the corresponding home directories, and +replacing \f3$envvar\f1 expressions with the value of the specified +environment variable, then if there are any wildcards, replacing the +so far expanded filename with a space-separated list of the files +which match the wild cards. +.sp +The expansion binding is implemented using the \f3ef_expand_file()\f1 function. +See the \f3ef_expand_file(@LIBR_MANEXT@)\f1 man page for more details. + +.SH RECALLING PREVIOUSLY TYPED LINES + +Every time that a new line is entered by the user, it is appended to a +list of historical input lines maintained within the GetLine resource +object. You can traverse up and down this list using the up and down +arrow keys. Alternatively, you can do the same with the \f3^P\f1, and +\f3^N\f1 keys, and in vi command mode you can alternatively use the k +and j characters. Thus pressing up-arrow once, replaces the current +input line with the previously entered line. Pressing up-arrow again, +replaces this with the line that was entered before it, etc.. Having +gone back one or more lines into the history list, one can return to +newer lines by pressing down-arrow one or more times. If you do this +sufficient times, you will return to the original line that you were +entering when you first hit up-arrow. +.sp +Note that in vi mode, all of the history recall functions switch the +library into command mode. +.sp +In emacs mode the \f3M-p\f1 and \f3M-n\f1 keys work just like the +\f3^P\f1 and \f3^N\f1 keys, except that they skip all but those +historical lines which share the prefix that precedes the cursor. In +vi command mode the upper case \f3K\f1 and \f3J\f1 characters do the +same thing, except that the string that they search for includes the +character under the cursor as well as what precedes it. +.sp +Thus for example, suppose that you were in emacs mode, and you had +just entered the following list of commands in the order shown: + +.nf + ls ~/tecla/ + cd ~/tecla + ls -l getline.c + emacs ~/tecla/getline.c +.fi + +If you next typed: + +.nf + ls +.fi + +and then hit \f3M-p\f1, then rather than returning the previously +typed emacs line, which doesn't start with "ls", Tecla +would recall the "ls -l getline.c" line. Pressing \f3M-p\f1 again +would recall the "ls ~/tecla/" line. + +Note that if the string that you are searching for, contains any of +the special characters, *, ?, or '[', then it is interpretted as a +pattern to be matched. Thus, cotinuing with the above example, after +typing in the list of commands shown, if you then typed: + +.nf + *tecla* +.fi + +and hit \f3M-p\f1, then the "emacs ~/tecla/getline.c" line would be +recalled first, since it contains the word tecla somewhere in the +line, Similarly, hitting \f3M-p\f1 again, would recall the "ls +~/tecla/" line, and hitting it once more would recall the "ls +~/tecla/" line. The pattern syntax is the same as that described for +filename expansion, in the \f3ef_expand_file(@LIBR_MANEXT@\f1 man +page. + +.SH HISTORY FILES + +Authors of programs that use the Tecla library have the option of +saving historical command-lines in a file before exiting, and +subsequently reading them back in from this file when the program is +next started. There is no standard name for this file, since it makes +sense for each application to use its own history file, so that +commands from different applications don't get mixed up. + +.SH INTERNATIONAL CHARACTER SETS + +Since libtecla version 1.4.0, Tecla has been 8-bit clean. This means +that all 8-bit characters that are printable in the user's current +locale are now displayed verbatim and included in the returned input +line. Assuming that the calling program correctly contains a call +like the following, +.sp +.nf + setlocale(LC_CTYPE, ""); +.fi +.sp +then the current locale is determined by the first of the environment +variables \f3LC_CTYPE\f1, \f3LC_ALL\f1, and \f3LANG\f1, that is found +to contain a valid locale name. If none of these variables are +defined, or the program neglects to call setlocale, then the default +\f3C\f1 locale is used, which is US 7-bit ASCII. On most unix-like +platforms, you can get a list of valid locales by typing the command: +.sp +.nf + locale -a +.fi +.sp +at the shell prompt. +.sp +.SS "Meta keys and locales" + +Beware that in most locales other than the default C locale, meta +characters become printable, and they are then no longer considered to +match \f3M-c\f1 style key bindings. This allows international +characters to be entered with the compose key without unexpectedly +triggering meta key bindings. You can still invoke meta bindings, +since there are actually two ways to do this. For example the binding +\f3M-c\f1 can also be invoked by pressing the escape key momentarily, +then pressing the \f3c\f1 key, and this will work regardless of +locale. Moreover, many modern terminal emulators, such as gnome's +gnome-terminal's and KDE's konsole terminals, already generate escape +pairs like this when you use the meta key, rather than a real meta +character, and other emulators usually have a way to request this +behavior, so you can continue to use the meta key on most systems. +.sp +For example, although xterm terminal emulators generate real 8-bit +meta characters by default when you use the meta key, they can be +configured to output the equivalent escape pair by setting their +\f3EightBitInput\f1 X resource to \f3False\f1. You can either do this +by placing a line like the following in your \f3~/.Xdefaults\f1 file, +.sp +.nf + XTerm*EightBitInput: False +.sp +.fi +or by starting an xterm with an \f3-xrm '*EightBitInput: False'\f1 +command-line argument. In recent versions of xterm you can toggle this +feature on and off with the \f3"Meta Sends Escape"\f1 option in the +menu that is displayed when you press the left mouse button and the +control key within an xterm window. In CDE, dtterms can be similarly +coerced to generate escape pairs in place of meta characters, by +setting the \f3Dtterm*KshMode\f1 resource to \f3True\f1. +.sp +.SS "Entering international characters" + +If you don't have a keyboard that generates all of the +international characters that you need, there is usually a +compose key that will allow you to enter special characters, +or a way to create one. For example, under X windows on +unix-like systems, if your keyboard doesn't have a compose +key, you can designate a redundant key to serve this purpose +with the xmodmap command. For example, on many PC keyboards +there is a microsoft-windows key, which is otherwise useless +under Linux. On my laptop the \f3xev\f1 program reports that +pressing this key generates keycode 115, so to turn this key +into a compose key, I do the following: +.sp +.nf + xmodmap -e 'keycode 115 = Multi_key' +.fi +.sp +I can then enter an i with a umlaut over it by typing this key, +followed by \f3"\f1, followed by i. + +.SH THE AVAILABLE KEY BINDING FUNCTIONS + +The following is a list of the editing functions provided by the Tecla +library. The names in the leftmost column of the list can be used in +configuration files to specify which function a given key or +combination of keys should invoke. They are also used in the next two +sections to list the default key-bindings in emacs and vi modes. + +.nf + user-interrupt - Send a SIGINT signal to the + parent process. + abort - Send a SIGABRT signal to the + parent process. + suspend - Suspend the parent process. + stop-output - Pause terminal output. + start-output - Resume paused terminal output. + literal-next - Arrange for the next character + to be treated as a normal + character. This allows control + characters to be entered. + cursor-right - Move the cursor one character + right. + cursor-left - Move the cursor one character + left. + insert-mode - Toggle between insert mode and + overwrite mode. + beginning-of-line - Move the cursor to the + beginning of the line. + end-of-line - Move the cursor to the end of + the line. + delete-line - Delete the contents of the + current line. + kill-line - Delete everything that follows + the cursor. + backward-kill-line - Delete all characters between + the cursor and the start of the + line. + forward-word - Move to the end of the word + which follows the cursor. + forward-to-word - Move the cursor to the start of + the word that follows the + cursor. + backward-word - Move to the start of the word + which precedes the cursor. + goto-column - Move the cursor to the + 1-relative column in the line + specified by any preceding + digit-argument sequences (see + ENTERING REPEAT COUNTS below). + find-parenthesis - If the cursor is currently + over a parenthesis character, + move it to the matching + parenthesis character. If not + over a parenthesis character + move right to the next close + parenthesis. + forward-delete-char - Delete the character under the + cursor. + backward-delete-char - Delete the character which + precedes the cursor. + list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + del-char-or-list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + invokes forward-delete-char. + When invoked at the end of the + line it displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + forward-delete-word - Delete the word which follows + the cursor. + backward-delete-word - Delete the word which precedes + the cursor. + upcase-word - Convert all of the characters + of the word which follows the + cursor, to upper case. + downcase-word - Convert all of the characters + of the word which follows the + cursor, to lower case. + capitalize-word - Capitalize the word which + follows the cursor. + change-case - If the next character is upper + case, toggle it to lower case + and vice versa. + redisplay - Redisplay the line. + clear-screen - Clear the terminal, then + redisplay the current line. + transpose-chars - Swap the character under the + cursor with the character just + before the cursor. + set-mark - Set a mark at the position of + the cursor. + exchange-point-and-mark - Move the cursor to the last + mark that was set, and move + the mark to where the cursor + used to be. + kill-region - Delete the characters that lie + between the last mark that was + set, and the cursor. + copy-region-as-kill - Copy the text between the mark + and the cursor to the cut + buffer, without deleting the + original text. + yank - Insert the text that was last + deleted, just before the + current position of the cursor. + append-yank - Paste the current contents of + the cut buffer, after the + cursor. + up-history - Recall the next oldest line + that was entered. Note that + in vi mode you are left in + command mode. + down-history - Recall the next most recent + line that was entered. If no + history recall session is + currently active, the next + line from a previous recall + session is recalled. Note that + in vi mode you are left in + command mode. + history-search-backward - Recall the next oldest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-search-forward - Recall the next newest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-re-search-backward -Recall the next oldest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + history-re-search-forward - Recall the next newest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + complete-word - Attempt to complete the + incomplete word which + precedes the cursor. Unless + the host program has customized + word completion, filename + completion is attempted. In vi + commmand mode the character + under the cursor is also + included in the word being + completed, and you are left in + vi insert mode. + expand-filename - Within the command line, expand + wild cards, tilde expressions + and dollar expressions in the + filename which immediately + precedes the cursor. In vi + commmand mode the character + under the cursor is also + included in the filename being + expanded, and you are left in + vi insert mode. + list-glob - List any filenames which match + the wild-card, tilde and dollar + expressions in the filename + which immediately precedes the + cursor, then redraw the input + line unchanged. + list-history - Display the contents of the + history list for the current + history group. If a repeat + count of > 1 is specified, + only that many of the most + recent lines are displayed. + See the "ENTERING REPEAT + COUNTS" section. + read-from-file - Temporarily switch to reading + input from the file who's + name precedes the cursor. + read-init-files - Re-read teclarc configuration + files. + beginning-of-history - Move to the oldest line in the + history list. Note that in vi + mode you are left in command + mode. + end-of-history - Move to the newest line in the + history list (ie. the current + line). Note that in vi mode + this leaves you in command + mode. + digit-argument - Enter a repeat count for the + next key-binding function. + For details, see the ENTERING + REPEAT COUNTS section. + newline - Terminate and return the + current contents of the + line, after appending a + newline character. The newline + character is normally '\\n', + but will be the first + character of the key-sequence + that invoked the newline + action, if this happens to be + a printable character. If the + action was invoked by the + '\\n' newline character or the + '\\r' carriage return + character, the line is + appended to the history + buffer. + repeat-history - Return the line that is being + edited, then arrange for the + next most recent entry in the + history buffer to be recalled + when Tecla is next called. + Repeatedly invoking this + action causes successive + historical input lines to be + re-executed. Note that this + action is equivalent to the + 'Operate' action in ksh. + ring-bell - Ring the terminal bell, unless + the bell has been silenced via + the \f3nobeep\f1 configuration + option (see the THE TECLA + CONFIGURATION FILE section). + forward-copy-char - Copy the next character into + the cut buffer (NB. use repeat + counts to copy more than one). + backward-copy-char - Copy the previous character + into the cut buffer. + forward-copy-word - Copy the next word into the cut + buffer. + backward-copy-word - Copy the previous word into the + cut buffer. + forward-find-char - Move the cursor to the next + occurrence of the next + character that you type. + backward-find-char - Move the cursor to the last + occurrence of the next + character that you type. + forward-to-char - Move the cursor to the + character just before the next + occurrence of the next + character that the user types. + backward-to-char - Move the cursor to the + character just after the last + occurrence before the cursor + of the next character that the + user types. + repeat-find-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char or + forward-to-char. + invert-refind-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char, or + forward-to-char in the + opposite direction. + delete-to-column - Delete the characters from the + cursor up to the column that + is specified by the repeat + count. + delete-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis. + forward-delete-find - Delete the characters from the + cursor up to and including the + following occurence of the + next character typed. + backward-delete-find - Delete the characters from the + cursor up to and including the + preceding occurence of the + next character typed. + forward-delete-to - Delete the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed. + backward-delete-to - Delete the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed. + delete-refind - Repeat the last *-delete-find + or *-delete-to action. + delete-invert-refind - Repeat the last *-delete-find + or *-delete-to action, in the + opposite direction. + copy-to-column - Copy the characters from the + cursor up to the column that + is specified by the repeat + count, into the cut buffer. + copy-to-parenthesis - Copy the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, into + the cut buffer. + forward-copy-find - Copy the characters from the + cursor up to and including the + following occurence of the + next character typed, into the + cut buffer. + backward-copy-find - Copy the characters from the + cursor up to and including the + preceding occurence of the + next character typed, into the + cut buffer. + forward-copy-to - Copy the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, into the cut + buffer. + backward-copy-to - Copy the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, into the cut + buffer. + copy-refind - Repeat the last *-copy-find + or *-copy-to action. + copy-invert-refind - Repeat the last *-copy-find + or *-copy-to action, in the + opposite direction. + vi-mode - Switch to vi mode from emacs + mode. + emacs-mode - Switch to emacs mode from vi + mode. + vi-insert - From vi command mode, switch to + insert mode. + vi-overwrite - From vi command mode, switch to + overwrite mode. + vi-insert-at-bol - From vi command mode, move the + cursor to the start of the line + and switch to insert mode. + vi-append-at-eol - From vi command mode, move the + cursor to the end of the line + and switch to append mode. + vi-append - From vi command mode, move the + cursor one position right, and + switch to insert mode. + vi-replace-char - From vi command mode, replace + the character under the cursor + with the the next character + entered. + vi-forward-change-char - From vi command mode, delete + the next character then enter + insert mode. + vi-backward-change-char - From vi command mode, delete + the preceding character then + enter insert mode. + vi-forward-change-word - From vi command mode, delete + the next word then enter + insert mode. + vi-backward-change-word - From vi command mode, delete + the preceding word then + enter insert mode. + vi-change-rest-of-line - From vi command mode, delete + from the cursor to the end of + the line, then enter insert + mode. + vi-change-line - From vi command mode, delete + the current line, then enter + insert mode. + vi-change-to-bol - From vi command mode, delete + all characters between the + cursor and the beginning of + the line, then enter insert + mode. + vi-change-to-column - From vi command mode, delete + the characters from the cursor + up to the column that is + specified by the repeat count, + then enter insert mode. + vi-change-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, then + enter vi insert mode. + vi-forward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + following occurence of the + next character typed, then + enter insert mode. + vi-backward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + preceding occurence of the + next character typed, then + enter insert mode. + vi-forward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, then enter + insert mode. + vi-backward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, then enter + insert mode. + vi-change-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action. + vi-change-invert-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action, in the + opposite direction. + vi-undo - In vi mode, undo the last + editing operation. + vi-repeat-change - In vi command mode, repeat the + last command that modified the + line. +.fi + +.SH DEFAULT KEY BINDINGS IN EMACS MODE + +The following default key bindings, which can be overriden by +the Tecla configuration file, are designed to mimic most of +the bindings of the unix \f3tcsh\f1 shell, when it is in +emacs editing mode. +.sp +This is the default editing mode of the Tecla library. +.sp +Under UNIX the terminal driver sets a number of special keys for certain +functions. The tecla library attempts to use the same keybindings to maintain +consistency. The key sequences shown for the following 6 bindings are thus just +examples of what they will probably be set to. If you have used the \f3stty\f1 +command to change these keys, then the default bindings should match. + +.nf + ^C -> user-interrupt + ^\\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next +.fi + +The cursor keys are refered to by name, as follows. This is necessary +because different types of terminals generate different key sequences +when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + +The remaining bindings don't depend on the terminal setttings. + +.nf + ^F -> cursor-right + ^B -> cursor-left + M-i -> insert-mode + ^A -> beginning-of-line + ^E -> end-of-line + ^U -> delete-line + ^K -> kill-line + M-f -> forward-word + M-b -> backward-word + ^D -> del-char-or-list-or-eof + ^H -> backward-delete-char + ^? -> backward-delete-char + M-d -> forward-delete-word + M-^H -> backward-delete-word + M-^? -> backward-delete-word + M-u -> upcase-word + M-l -> downcase-word + M-c -> capitalize-word + ^R -> redisplay + ^L -> clear-screen + ^T -> transpose-chars + ^@ -> set-mark + ^X^X -> exchange-point-and-mark + ^W -> kill-region + M-w -> copy-region-as-kill + ^Y -> yank + ^P -> up-history + ^N -> down-history + M-p -> history-search-backward + M-n -> history-search-forward + ^I -> complete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^Xg -> list-glob + ^Xh -> list-history + M-< -> beginning-of-history + M-> -> end-of-history + \\n -> newline + \\r -> newline + M-o -> repeat-history + M-^V -> vi-mode + + M-0, M-1, ... M-9 -> digit-argument (see below) +.fi + +Note that \f3^I\f1 is what the TAB key generates, and that \f3^@\f1 +can be generated not only by pressing the control key and the \f3@\f1 +key simultaneously, but also by pressing the control key and the space +bar at the same time. + +.SH DEFAULT KEY BINDINGS IN VI MODE + +The following default key bindings are designed to mimic the +vi style of editing as closely as possible. This means that +very few editing functions are provided in the initial +character input mode, editing functions instead being +provided by the vi command mode. Vi command mode is entered +whenever the escape character is pressed, or whenever a +key-sequence that starts with a meta character is entered. In +addition to mimicing vi, libtecla provides bindings for tab +completion, wild-card expansion of file names, and historical +line recall. +.sp +To learn how to tell the Tecla library to use vi mode instead +of the default emacs editing mode, see the earlier section entitled +THE TECLA CONFIGURATION FILE. +.sp +Under UNIX the terminal driver sets a number of special keys +for certain functions. The Tecla library attempts to use the +same keybindings to maintain consistency, binding them both +in input mode and in command mode. The key sequences shown +for the following 6 bindings are thus just examples of what +they will probably be set to. If you have used the \f3stty\f1 +command to change these keys, then the default bindings +should match. + +.nf + ^C -> user-interrupt + ^\\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next + M-^C -> user-interrupt + M-^\\ -> abort + M-^Z -> suspend + M-^Q -> start-output + M-^S -> stop-output +.fi + +Note that above, most of the bindings are defined twice, once +as a raw control code like \f3^C\f1 and then a second time as +a meta character like \f3M-^C\f1. The former is the binding +for vi input mode, whereas the latter is the binding for vi +command mode. Once in command mode all key-sequences that the +user types that they don't explicitly start with an escape or +a meta key, have their first key secretly converted to a meta +character before the key sequence is looked up in the key +binding table. Thus, once in command mode, when you type the +letter \f3i\f1, for example, the Tecla library actually looks +up the binding for \f3M-i\f1. + +The cursor keys are refered to by name, as follows. This is necessary +because different types of terminals generate different key sequences +when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + +The cursor keys normally generate a keysequence that start +with an escape character, so beware that using the arrow keys +will put you into command mode (if you aren't already in +command mode). +.sp +The following are the terminal-independent key bindings for vi input +mode. + +.nf + ^D -> list-or-eof + ^G -> list-glob + ^H -> backward-delete-char + ^I -> complete-word + \\r -> newline + \\n -> newline + ^L -> clear-screen + ^N -> down-history + ^P -> up-history + ^R -> redisplay + ^U -> backward-kill-line + ^W -> backward-delete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^? -> backward-delete-char +.fi + +The following are the key bindings that are defined in vi +command mode, this being specified by them all starting with +a meta character. As mentioned above, once in command mode +the initial meta character is optional. For example, you +might enter command mode by typing Esc, and then press h +twice to move the cursor two positions to the left. Both h +characters get quietly converted to M-h before being compared +to the key-binding table, the first one because Escape +followed by a character is always converted to the equivalent +meta character, and the second because command mode was +already active. + +.nf + M-\\ -> cursor-right (Meta-space) + M-$ -> end-of-line + M-* -> expand-filename + M-+ -> down-history + M-- -> up-history + M-< -> beginning-of-history + M-> -> end-of-history + M-^ -> beginning-of-line + M-; -> repeat-find-char + M-, -> invert-refind-char + M-| -> goto-column + M-~ -> change-case + M-. -> vi-repeat-change + M-% -> find-parenthesis + M-a -> vi-append + M-A -> vi-append-at-eol + M-b -> backward-word + M-B -> backward-word + M-C -> vi-change-rest-of-line + M-cb -> vi-backward-change-word + M-cB -> vi-backward-change-word + M-cc -> vi-change-line + M-ce -> vi-forward-change-word + M-cE -> vi-forward-change-word + M-cw -> vi-forward-change-word + M-cW -> vi-forward-change-word + M-cF -> vi-backward-change-find + M-cf -> vi-forward-change-find + M-cT -> vi-backward-change-to + M-ct -> vi-forward-change-to + M-c; -> vi-change-refind + M-c, -> vi-change-invert-refind + M-ch -> vi-backward-change-char + M-c^H -> vi-backward-change-char + M-c^? -> vi-backward-change-char + M-cl -> vi-forward-change-char + M-c\\ -> vi-forward-change-char (Meta-c-space) + M-c^ -> vi-change-to-bol + M-c0 -> vi-change-to-bol + M-c$ -> vi-change-rest-of-line + M-c| -> vi-change-to-column + M-c% -> vi-change-to-parenthesis + M-dh -> backward-delete-char + M-d^H -> backward-delete-char + M-d^? -> backward-delete-char + M-dl -> forward-delete-char + M-d -> forward-delete-char (Meta-d-space) + M-dd -> delete-line + M-db -> backward-delete-word + M-dB -> backward-delete-word + M-de -> forward-delete-word + M-dE -> forward-delete-word + M-dw -> forward-delete-word + M-dW -> forward-delete-word + M-dF -> backward-delete-find + M-df -> forward-delete-find + M-dT -> backward-delete-to + M-dt -> forward-delete-to + M-d; -> delete-refind + M-d, -> delete-invert-refind + M-d^ -> backward-kill-line + M-d0 -> backward-kill-line + M-d$ -> kill-line + M-D -> kill-line + M-d| -> delete-to-column + M-d% -> delete-to-parenthesis + M-e -> forward-word + M-E -> forward-word + M-f -> forward-find-char + M-F -> backward-find-char + M-- -> up-history + M-h -> cursor-left + M-H -> beginning-of-history + M-i -> vi-insert + M-I -> vi-insert-at-bol + M-j -> down-history + M-J -> history-search-forward + M-k -> up-history + M-K -> history-search-backward + M-l -> cursor-right + M-L -> end-of-history + M-n -> history-re-search-forward + M-N -> history-re-search-backward + M-p -> append-yank + M-P -> yank + M-r -> vi-replace-char + M-R -> vi-overwrite + M-s -> vi-forward-change-char + M-S -> vi-change-line + M-t -> forward-to-char + M-T -> backward-to-char + M-u -> vi-undo + M-w -> forward-to-word + M-W -> forward-to-word + M-x -> forward-delete-char + M-X -> backward-delete-char + M-yh -> backward-copy-char + M-y^H -> backward-copy-char + M-y^? -> backward-copy-char + M-yl -> forward-copy-char + M-y\\ -> forward-copy-char (Meta-y-space) + M-ye -> forward-copy-word + M-yE -> forward-copy-word + M-yw -> forward-copy-word + M-yW -> forward-copy-word + M-yb -> backward-copy-word + M-yB -> backward-copy-word + M-yf -> forward-copy-find + M-yF -> backward-copy-find + M-yt -> forward-copy-to + M-yT -> backward-copy-to + M-y; -> copy-refind + M-y, -> copy-invert-refind + M-y^ -> copy-to-bol + M-y0 -> copy-to-bol + M-y$ -> copy-rest-of-line + M-yy -> copy-line + M-Y -> copy-line + M-y| -> copy-to-column + M-y% -> copy-to-parenthesis + M-^E -> emacs-mode + M-^H -> cursor-left + M-^? -> cursor-left + M-^L -> clear-screen + M-^N -> down-history + M-^P -> up-history + M-^R -> redisplay + M-^D -> list-or-eof + M-^I -> complete-word + M-\\r -> newline + M-\\n -> newline + M-^X^R -> read-init-files + M-^Xh -> list-history + + M-0, M-1, ... M-9 -> digit-argument (see below) +.fi + +Note that \f3^I\f1 is what the TAB key generates. + +.SH ENTERING REPEAT COUNTS + +Many of the key binding functions described previously, take an +optional count, typed in before the target keysequence. This is +interpreted as a repeat count by most bindings. A notable exception is +the goto-column binding, which interprets the count as a column +number. +.sp +By default you can specify this count argument by pressing the meta +key while typing in the numeric count. This relies on the +\f3digit-argument\f1 action being bound to Meta-0, Meta-1 etc. Once +any one of these bindings has been activated, you can optionally take +your finger off the meta key to type in the rest of the number, since +every numeric digit thereafter is treated as part of the number, +unless it is preceded by the \f3literal-next\f1 binding. As soon as a +non-digit, or literal digit key is pressed the repeat count is +terminated and either causes the just typed character to be added to +the line that many times, or causes the next key-binding function to +be given that argument. +.sp +For example, in emacs mode, typing: +.sp +.nf + M-12a +.fi +.sp +causes the letter 'a' to be added to the line 12 times, +whereas +.sp +.nf + M-4M-c +.fi +.sp +Capitalizes the next 4 words. +.sp +In vi command mode the Meta modifier is automatically added to all +characters typed in, so to enter a count in vi command-mode, just +involves typing in the number, just as it does in the vi editor +itself. So for example, in vi command mode, typing: +.sp +.nf + 4w2x +.fi +.sp +moves the cursor four words to the right, then deletes two characters. +.sp +You can also bind \f3digit-argument\f1 to other key sequences. If +these end in a numeric digit, that digit gets appended to the current +repeat count. If it doesn't end in a numeric digit, a new repeat count +is started with a value of zero, and can be completed by typing in the +number, after letting go of the key which triggered the digit-argument +action. + +.SH FILES +.nf +libtecla.a - The Tecla library +libtecla.h - The Tecla header file. +~/.teclarc - The personal Tecla customization file. +.fi + +.SH SEE ALSO + +.nf +libtecla(@LIBR_MANEXT@), gl_get_line(@LIBR_MANEXT@), gl_io_mode(@LIBR_MANEXT@), ef_expand_file(@LIBR_MANEXT@), +cpl_complete_word(@LIBR_MANEXT@), pca_lookup_file(@LIBR_MANEXT@) +.fi + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.6.3/man/prog/enhance.in b/libtecla-1.6.3/man/prog/enhance.in new file mode 100644 index 0000000..aacd8a0 --- /dev/null +++ b/libtecla-1.6.3/man/prog/enhance.in @@ -0,0 +1,89 @@ +.\" Copyright (c) 2000, 2001, 2002, 2003, 2004, 2012 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. +.TH enhance @PROG_MANEXT@ +.SH NAME +enhance - A program that adds command-line editing to third party programs. +.SH SYNOPSIS +.nf +enhance command [ argument ... ] +.fi + +.SH DESCRIPTION + +The \f3enhance\f1 program provides enhanced command-line editing +facilities to users of third party applications, to which one doesn't +have any source code. It does this by placing a pseudo-terminal +between the application and the real terminal. It uses the tecla +command-line editing library to read input from the real terminal, +then forwards each just completed input line to the application via +the pseudo-terminal. All output from the application is forwarded +back unchanged to the real terminal. +.sp +Whenever the application stops generating output for more than a tenth +of a second, the \f3enhance\f1 program treats the latest incomplete +output line as the prompt, and redisplays any incompleted input line +that the user has typed after it. Note that the small delay, which is +imperceptible to the user, isn't necessary for correct operation of +the program. It is just an optimization, designed to stop the input +line from being redisplayed so often that it slows down output. +.sp +Note that the user-level command-line editing facilities provided by +the Tecla library are documented in the \f3tecla(@MISC_MANEXT@)\f1 man page + +.SH DEFICIENCIES + +The one major problem that hasn't been solved yet, is how to deal with +applications that change whether typed input is echo'd by their +controlling terminal. For example, programs that ask for a password, +such as ftp and telnet, temporarily tell their controlling terminal +not to echo what the user types. Since this request goes to the +application side of the psuedo terminal, the \f3enhance\f1 program has +no way of knowing that this has happened, and continues to echo typed +input to its controlling terminal, while the user types their +password. +.sp +Furthermore, before executing the host application, the \f3enhance\f1 +program initially sets the pseudo terminal to noecho mode, so that +everything that it sends to the program doesn't get redundantly +echoed. If a program that switches to noecho mode explicitly restores +echoing afterwards, rather than restoring the terminal modes that were +previously in force, then subsequently, every time that you enter a +new input line, a duplicate copy will be displayed on the next line. + +.SH FILES +.nf +libtecla.a - The tecla library. +~/.teclarc - The tecla personal customization file. +.fi + +.SH SEE ALSO +tecla(@MISC_MANEXT@), libtecla(@LIBR_MANEXT@) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) |